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 "GFIO.h"
86 : : # include "GSFIO.h"
87 : : # include "GStdIO.h"
88 : :
89 : : # define DebugStackOn true
90 : : # define DebugVarients false
91 : : # define DebugTokPos false
92 : : typedef struct M2Quads__T1_r M2Quads__T1;
93 : :
94 : : typedef M2Quads__T1 *M2Quads_ConstructorFrame;
95 : :
96 : : typedef struct M2Quads__T2_r M2Quads__T2;
97 : :
98 : : typedef M2Quads__T2 *M2Quads_BoolFrame;
99 : :
100 : : typedef struct M2Quads__T3_r M2Quads__T3;
101 : :
102 : : typedef M2Quads__T3 *M2Quads_QuadFrame;
103 : :
104 : : typedef struct M2Quads__T4_r M2Quads__T4;
105 : :
106 : : typedef M2Quads__T4 *M2Quads_WithFrame;
107 : :
108 : : typedef struct M2Quads__T5_r M2Quads__T5;
109 : :
110 : : typedef M2Quads__T5 *M2Quads_ForLoopInfo;
111 : :
112 : : typedef struct M2Quads__T6_r M2Quads__T6;
113 : :
114 : : typedef M2Quads__T6 *M2Quads_LineNote;
115 : :
116 : : # define DebugAsmTokPos false
117 : : struct M2Quads__T1_r {
118 : : unsigned int type;
119 : : unsigned int index;
120 : : };
121 : :
122 : : struct M2Quads__T2_r {
123 : : unsigned int TrueExit;
124 : : unsigned int FalseExit;
125 : : unsigned int Unbounded;
126 : : bool BooleanOp;
127 : : unsigned int Dimension;
128 : : unsigned int ReadWrite;
129 : : unsigned int name;
130 : : unsigned int RangeDep;
131 : : DynamicStrings_String Annotation;
132 : : unsigned int tokenno;
133 : : };
134 : :
135 : : struct M2Quads__T3_r {
136 : : M2Quads_QuadOperator Operator;
137 : : unsigned int Operand1;
138 : : unsigned int Operand2;
139 : : unsigned int Operand3;
140 : : unsigned int Trash;
141 : : unsigned int Next;
142 : : unsigned int LineNo;
143 : : unsigned int TokenNo;
144 : : unsigned int NoOfTimesReferenced;
145 : : bool ConstExpr;
146 : : bool CheckType;
147 : : bool CheckOverflow;
148 : : unsigned int op1pos;
149 : : unsigned int op2pos;
150 : : unsigned int op3pos;
151 : : };
152 : :
153 : : struct M2Quads__T4_r {
154 : : unsigned int RecordSym;
155 : : unsigned int RecordType;
156 : : unsigned int RecordRef;
157 : : unsigned int rw;
158 : : unsigned int RecordTokPos;
159 : : };
160 : :
161 : : struct M2Quads__T5_r {
162 : : unsigned int IncrementQuad;
163 : : unsigned int StartOfForLoop;
164 : : unsigned int EndOfForLoop;
165 : : unsigned int ForLoopIndex;
166 : : unsigned int IndexTok;
167 : : };
168 : :
169 : : struct M2Quads__T6_r {
170 : : unsigned int Line;
171 : : NameKey_Name File;
172 : : M2Quads_LineNote Next;
173 : : };
174 : :
175 : : static M2StackAddress_StackOfAddress ConstructorStack;
176 : : static M2StackAddress_StackOfAddress LineStack;
177 : : static M2StackAddress_StackOfAddress BoolStack;
178 : : static M2StackAddress_StackOfAddress WithStack;
179 : : static M2StackWord_StackOfWord TryStack;
180 : : static M2StackWord_StackOfWord CatchStack;
181 : : static M2StackWord_StackOfWord ExceptStack;
182 : : static M2StackWord_StackOfWord ConstExprStack;
183 : : static M2StackWord_StackOfWord ConstParamStack;
184 : : static M2StackWord_StackOfWord AutoStack;
185 : : static M2StackWord_StackOfWord RepeatStack;
186 : : static M2StackWord_StackOfWord WhileStack;
187 : : static M2StackWord_StackOfWord ForStack;
188 : : static M2StackWord_StackOfWord ExitStack;
189 : : static M2StackWord_StackOfWord ReturnStack;
190 : : static M2StackWord_StackOfWord PriorityStack;
191 : : static bool SuppressWith;
192 : : static Indexing_Index QuadArray;
193 : : static unsigned int NextQuad;
194 : : static unsigned int FreeList;
195 : : static unsigned int CurrentProc;
196 : : static unsigned int InitQuad;
197 : : static unsigned int LastQuadNo;
198 : : static NameKey_Name ArithPlusTok;
199 : : static NameKey_Name LogicalOrTok;
200 : : static NameKey_Name LogicalAndTok;
201 : : static NameKey_Name LogicalXorTok;
202 : : static NameKey_Name LogicalDifferenceTok;
203 : : static bool InConstExpression;
204 : : static bool InConstParameters;
205 : : static bool IsAutoOn;
206 : : static bool MustNotCheckBounds;
207 : : static Indexing_Index ForInfo;
208 : : static unsigned int GrowInitialization;
209 : : static bool BuildingHigh;
210 : : static bool BuildingSize;
211 : : static bool QuadrupleGeneration;
212 : : static M2Quads_LineNote FreeLineList;
213 : : static Lists_List VarientFields;
214 : : static unsigned int VarientFieldNo;
215 : : static unsigned int NoOfQuads;
216 : : static unsigned int Head;
217 : : static unsigned int BreakQuad;
218 : :
219 : : /*
220 : : SetOptionCoding - builds a code quadruple if the profiling
221 : : option was given to the compiler.
222 : : */
223 : :
224 : : extern "C" void M2Quads_SetOptionCoding (bool b);
225 : :
226 : : /*
227 : : SetOptionProfiling - builds a profile quadruple if the profiling
228 : : option was given to the compiler.
229 : : */
230 : :
231 : : extern "C" void M2Quads_SetOptionProfiling (bool b);
232 : :
233 : : /*
234 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
235 : : has been found in a comment.
236 : : */
237 : :
238 : : extern "C" void M2Quads_SetOptionOptimizing (bool b);
239 : :
240 : : /*
241 : : Opposite - returns the opposite comparison operator.
242 : : */
243 : :
244 : : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator);
245 : :
246 : : /*
247 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
248 : : */
249 : :
250 : : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo);
251 : :
252 : : /*
253 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
254 : : */
255 : :
256 : : extern "C" bool M2Quads_IsBackReference (unsigned int q);
257 : :
258 : : /*
259 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
260 : : */
261 : :
262 : : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo);
263 : :
264 : : /*
265 : : IsConditional - returns true if QuadNo is a conditional jump.
266 : : */
267 : :
268 : : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo);
269 : :
270 : : /*
271 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
272 : : a conditional quad further on.
273 : : */
274 : :
275 : : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q);
276 : :
277 : : /*
278 : : IsGoto - returns true if QuadNo is a goto operation.
279 : : */
280 : :
281 : : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo);
282 : :
283 : : /*
284 : : IsCall - returns true if QuadNo is a call operation.
285 : : */
286 : :
287 : : extern "C" bool M2Quads_IsCall (unsigned int QuadNo);
288 : :
289 : : /*
290 : : IsReturn - returns true if QuadNo is a return operation.
291 : : */
292 : :
293 : : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo);
294 : :
295 : : /*
296 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
297 : : */
298 : :
299 : : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo);
300 : :
301 : : /*
302 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
303 : : */
304 : :
305 : : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo);
306 : :
307 : : /*
308 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
309 : : */
310 : :
311 : : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo);
312 : :
313 : : /*
314 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
315 : : */
316 : :
317 : : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo);
318 : :
319 : : /*
320 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
321 : : */
322 : :
323 : : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo);
324 : :
325 : : /*
326 : : IsInitStart - returns true if QuadNo is a init start quad.
327 : : */
328 : :
329 : : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo);
330 : :
331 : : /*
332 : : IsInitEnd - returns true if QuadNo is a init end quad.
333 : : */
334 : :
335 : : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo);
336 : :
337 : : /*
338 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
339 : : */
340 : :
341 : : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo);
342 : :
343 : : /*
344 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
345 : : */
346 : :
347 : : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo);
348 : :
349 : : /*
350 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
351 : : */
352 : :
353 : : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo);
354 : :
355 : : /*
356 : : IsDummy - return TRUE if QuadNo is a DummyOp.
357 : : */
358 : :
359 : : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo);
360 : :
361 : : /*
362 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
363 : : */
364 : :
365 : : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo);
366 : :
367 : : /*
368 : : SetQuadConstExpr - sets the constexpr field to value.
369 : : */
370 : :
371 : : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value);
372 : :
373 : : /*
374 : : GetQuadDest - returns the jump destination associated with quad.
375 : : */
376 : :
377 : : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo);
378 : :
379 : : /*
380 : : GetQuadOp1 - returns the 1st operand associated with quad.
381 : : */
382 : :
383 : : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo);
384 : :
385 : : /*
386 : : GetQuadOp2 - returns the 2nd operand associated with quad.
387 : : */
388 : :
389 : : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo);
390 : :
391 : : /*
392 : : GetQuadOp3 - returns the 3rd operand associated with quad.
393 : : */
394 : :
395 : : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo);
396 : :
397 : : /*
398 : : IsInitialisingConst - returns TRUE if the quadruple is setting
399 : : a const (op1) with a value.
400 : : */
401 : :
402 : : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo);
403 : :
404 : : /*
405 : : IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
406 : : */
407 : :
408 : : extern "C" bool M2Quads_IsConstQuad (unsigned int quad);
409 : :
410 : : /*
411 : : IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
412 : : */
413 : :
414 : : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad);
415 : :
416 : : /*
417 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
418 : : */
419 : :
420 : : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo);
421 : :
422 : : /*
423 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
424 : : */
425 : :
426 : : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo);
427 : :
428 : : /*
429 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
430 : : */
431 : :
432 : : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo);
433 : :
434 : : /*
435 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
436 : : ie code, profile and optimize.
437 : : StartFile, EndFile,
438 : : */
439 : :
440 : : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo);
441 : :
442 : : /*
443 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
444 : : directive.
445 : : */
446 : :
447 : : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo);
448 : :
449 : : /*
450 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
451 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
452 : : command line.
453 : : */
454 : :
455 : : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high);
456 : :
457 : : /*
458 : : DisplayQuadRange - displays all quads in list range, start..end.
459 : : */
460 : :
461 : : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end);
462 : :
463 : : /*
464 : : DisplayQuad - displays a quadruple, QuadNo.
465 : : */
466 : :
467 : : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo);
468 : :
469 : : /*
470 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
471 : : StartModFile quadruple.
472 : : */
473 : :
474 : : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo);
475 : :
476 : : /*
477 : : GetLastQuadNo - returns the last quadruple number referenced
478 : : by a GetQuad.
479 : : */
480 : :
481 : : extern "C" unsigned int M2Quads_GetLastQuadNo (void);
482 : :
483 : : /*
484 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
485 : : source file, the line number is returned.
486 : :
487 : : This may be used to yield an idea where abouts in the
488 : : source file the code generetion is
489 : : processing.
490 : : */
491 : :
492 : : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo);
493 : :
494 : : /*
495 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
496 : : source file, the line number is returned.
497 : :
498 : : This may be used to yield an idea where abouts in the
499 : : source file the code generetion is
500 : : processing.
501 : : */
502 : :
503 : : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo);
504 : :
505 : : /*
506 : : GetQuad - returns the Quadruple QuadNo.
507 : : */
508 : :
509 : : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3);
510 : :
511 : : /*
512 : : GetQuadOp - returns the operator for quad.
513 : : */
514 : :
515 : : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad);
516 : :
517 : : /*
518 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
519 : : (if possible). It returns NIL if no there is not an obvious match
520 : : in Modula-2. It is assummed that the string will be used during
521 : : construction of error messages and therefore keywords are
522 : : wrapped with a format specifier.
523 : : */
524 : :
525 : : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op);
526 : :
527 : : /*
528 : : GetQuadtok - returns the Quadruple QuadNo.
529 : : */
530 : :
531 : : extern "C" void M2Quads_GetQuadtok (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
532 : :
533 : : /*
534 : : GetQuadOtok - returns the Quadruple QuadNo.
535 : : */
536 : :
537 : : extern "C" void M2Quads_GetQuadOtok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
538 : :
539 : : /*
540 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
541 : : */
542 : :
543 : : extern "C" void M2Quads_GetQuadOTypetok (unsigned int QuadNo, unsigned int *tok, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3, bool *overflowChecking, bool *typeChecking, bool *constExpr, unsigned int *Op1Pos, unsigned int *Op2Pos, unsigned int *Op3Pos);
544 : :
545 : : /*
546 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
547 : : sets a boolean to determinine whether overflow should be checked.
548 : : */
549 : :
550 : : extern "C" void M2Quads_PutQuadOtok (unsigned int QuadNo, unsigned int tok, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflowChecking, bool constExpr, unsigned int Op1Pos, unsigned int Op2Pos, unsigned int Op3Pos);
551 : :
552 : : /*
553 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
554 : : */
555 : :
556 : : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
557 : :
558 : : /*
559 : : GetFirstQuad - returns the first quadruple.
560 : : */
561 : :
562 : : extern "C" unsigned int M2Quads_GetFirstQuad (void);
563 : :
564 : : /*
565 : : GetNextQuad - returns the Quadruple number following QuadNo.
566 : : */
567 : :
568 : : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo);
569 : :
570 : : /*
571 : : GetRealQuad - returns the Quadruple number of the real quadruple
572 : : at QuadNo or beyond.
573 : : */
574 : :
575 : : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo);
576 : :
577 : : /*
578 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
579 : : */
580 : :
581 : : extern "C" void M2Quads_SubQuad (unsigned int QuadNo);
582 : :
583 : : /*
584 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
585 : : but wiped clean.
586 : : */
587 : :
588 : : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo);
589 : :
590 : : /*
591 : : CountQuads - returns the number of quadruples.
592 : : */
593 : :
594 : : extern "C" unsigned int M2Quads_CountQuads (void);
595 : :
596 : : /*
597 : : BuildScaffold - generate the main, init, finish functions if
598 : : no -c and this is the application module.
599 : : */
600 : :
601 : : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym);
602 : :
603 : : /*
604 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
605 : : that has produced the subsequent quadruples.
606 : : The code generator uses the StartDefFileOp quadruples
607 : : to relate any error to the appropriate file.
608 : :
609 : :
610 : : Entry Exit
611 : : ===== ====
612 : :
613 : :
614 : : Ptr -> <- Ptr
615 : : +------------+ +------------+
616 : : | ModuleName | | ModuleName |
617 : : |------------| |------------|
618 : :
619 : :
620 : : Quadruples Produced
621 : :
622 : : q StartDefFileOp _ _ ModuleSym
623 : : */
624 : :
625 : : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok);
626 : :
627 : : /*
628 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
629 : : that has produced the subsequent quadruples.
630 : : The code generator uses the StartModFileOp quadruples
631 : : to relate any error to the appropriate file.
632 : :
633 : :
634 : : Entry Exit
635 : : ===== ====
636 : :
637 : :
638 : : Ptr -> <- Ptr
639 : : +------------+ +------------+
640 : : | ModuleName | | ModuleName |
641 : : |------------| |------------|
642 : :
643 : :
644 : : Quadruples Produced
645 : :
646 : : q StartModFileOp lineno filename ModuleSym
647 : : */
648 : :
649 : : extern "C" void M2Quads_StartBuildModFile (unsigned int tok);
650 : :
651 : : /*
652 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
653 : : that has produced the previous quadruples has ended.
654 : :
655 : : Entry Exit
656 : : ===== ====
657 : :
658 : :
659 : : Ptr -> <- Ptr
660 : : +------------+ +------------+
661 : : | ModuleName | | ModuleName |
662 : : |------------| |------------|
663 : :
664 : :
665 : : Quadruples Produced
666 : :
667 : : q EndFileOp _ _ ModuleSym
668 : : */
669 : :
670 : : extern "C" void M2Quads_EndBuildFile (unsigned int tok);
671 : :
672 : : /*
673 : : StartBuildInit - Sets the start of initialization code of the
674 : : current module to the next quadruple.
675 : : */
676 : :
677 : : extern "C" void M2Quads_StartBuildInit (unsigned int tok);
678 : :
679 : : /*
680 : : EndBuildInit - Sets the end initialization code of a module.
681 : : */
682 : :
683 : : extern "C" void M2Quads_EndBuildInit (unsigned int tok);
684 : :
685 : : /*
686 : : StartBuildFinally - Sets the start of finalization code of the
687 : : current module to the next quadruple.
688 : : */
689 : :
690 : : extern "C" void M2Quads_StartBuildFinally (unsigned int tok);
691 : :
692 : : /*
693 : : EndBuildFinally - Sets the end finalization code of a module.
694 : : */
695 : :
696 : : extern "C" void M2Quads_EndBuildFinally (unsigned int tok);
697 : :
698 : : /*
699 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
700 : : in the current block.
701 : : */
702 : :
703 : : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok);
704 : :
705 : : /*
706 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
707 : : finally block.
708 : : */
709 : :
710 : : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok);
711 : :
712 : : /*
713 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
714 : : block.
715 : : */
716 : :
717 : : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok);
718 : :
719 : : /*
720 : : BuildRetry - adds an RetryOp quadruple.
721 : : */
722 : :
723 : : extern "C" void M2Quads_BuildRetry (unsigned int tok);
724 : :
725 : : /*
726 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
727 : : the exception needs to be rethrown. The stack
728 : : is unaltered.
729 : : */
730 : :
731 : : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno);
732 : :
733 : : /*
734 : : StartBuildInnerInit - Sets the start of initialization code of the
735 : : inner module to the next quadruple.
736 : : */
737 : :
738 : : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok);
739 : :
740 : : /*
741 : : EndBuildInnerInit - Sets the end initialization code of a module.
742 : : */
743 : :
744 : : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok);
745 : :
746 : : /*
747 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
748 : :
749 : : Entry Exit
750 : :
751 : : Ptr ->
752 : : +------------+ +------------+
753 : : | Ident | | Sym |
754 : : |------------| |------------|
755 : :
756 : : Quadruple produced:
757 : :
758 : : q Sym BuiltinConstOp Ident
759 : : */
760 : :
761 : : extern "C" void M2Quads_BuildBuiltinConst (void);
762 : :
763 : : /*
764 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
765 : : within gm2.
766 : :
767 : : Entry Exit
768 : :
769 : : Ptr ->
770 : : +-------------+
771 : : | Type |
772 : : |-------------| +------------+
773 : : | Ident | | Sym |
774 : : |-------------| |------------|
775 : :
776 : : Quadruple produced:
777 : :
778 : : q Sym BuiltinTypeInfoOp Type Ident
779 : : */
780 : :
781 : : extern "C" void M2Quads_BuildBuiltinTypeInfo (void);
782 : :
783 : : /*
784 : : BuildAssignment - Builds an assignment from the values given on the
785 : : quad stack. Either an assignment to an
786 : : arithmetic expression or an assignment to a
787 : : boolean expression. This procedure should not
788 : : be called in CONST declarations.
789 : : The Stack is expected to contain:
790 : :
791 : :
792 : : Either
793 : :
794 : : Entry Exit
795 : : ===== ====
796 : :
797 : : Ptr ->
798 : : +------------+
799 : : | Expression |
800 : : |------------|
801 : : | Designator |
802 : : |------------| +------------+
803 : : | | | | <- Ptr
804 : : |------------| |------------|
805 : :
806 : :
807 : : Quadruples Produced
808 : :
809 : : q BecomesOp Designator _ Expression
810 : :
811 : : OR
812 : :
813 : : Entry Exit
814 : : ===== ====
815 : :
816 : : Ptr ->
817 : : +------------+
818 : : | True |False|
819 : : |------------|
820 : : | Designator |
821 : : |------------| +------------+
822 : : | | | | <- Ptr
823 : : |------------| |------------|
824 : :
825 : :
826 : : Quadruples Produced
827 : :
828 : : q BecomesOp Designator _ TRUE
829 : : q+1 GotoOp q+3
830 : : q+2 BecomesOp Designator _ FALSE
831 : :
832 : : */
833 : :
834 : : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo);
835 : :
836 : : /*
837 : : BuildAssignConstant - used to create constant in the CONST declaration.
838 : : The stack is expected to contain:
839 : :
840 : : Either
841 : :
842 : : Entry Exit
843 : : ===== ====
844 : :
845 : : Ptr ->
846 : : +------------+
847 : : | Expression |
848 : : |------------|
849 : : | Designator |
850 : : |------------| +------------+
851 : : | | | | <- Ptr
852 : : |------------| |------------|
853 : :
854 : :
855 : : Quadruples Produced
856 : :
857 : : q BecomesOp Designator _ Expression
858 : :
859 : : OR
860 : :
861 : : Entry Exit
862 : : ===== ====
863 : :
864 : : Ptr ->
865 : : +------------+
866 : : | True |False|
867 : : |------------|
868 : : | Designator |
869 : : |------------| +------------+
870 : : | | | | <- Ptr
871 : : |------------| |------------|
872 : :
873 : :
874 : : Quadruples Produced
875 : :
876 : : q BecomesOp Designator _ TRUE
877 : : q+1 GotoOp q+3
878 : : q+2 BecomesOp Designator _ FALSE
879 : : */
880 : :
881 : : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo);
882 : :
883 : : /*
884 : : BuildAlignment - builds an assignment to an alignment constant.
885 : :
886 : : The Stack is expected to contain:
887 : :
888 : :
889 : : Entry Exit
890 : : ===== ====
891 : :
892 : : Ptr ->
893 : : +---------------+
894 : : | Expression |
895 : : |---------------|
896 : : | bytealignment |
897 : : |---------------| empty
898 : : */
899 : :
900 : : extern "C" void M2Quads_BuildAlignment (unsigned int tokno);
901 : :
902 : : /*
903 : : BuildBitLength - builds an assignment to a bit length constant.
904 : :
905 : : The Stack is expected to contain:
906 : :
907 : :
908 : : Entry Exit
909 : : ===== ====
910 : :
911 : : Ptr ->
912 : : +------------+
913 : : | Expression |
914 : : |------------| empty
915 : : */
916 : :
917 : : extern "C" void M2Quads_BuildBitLength (unsigned int tokno);
918 : :
919 : : /*
920 : : BuildPragmaField - builds an assignment to an alignment constant.
921 : :
922 : : The Stack is expected to contain:
923 : :
924 : :
925 : : Entry Exit
926 : : ===== ====
927 : :
928 : : Ptr ->
929 : : +------------+
930 : : | Expression |
931 : : |------------| empty
932 : : */
933 : :
934 : : extern "C" void M2Quads_BuildPragmaField (void);
935 : :
936 : : /*
937 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
938 : :
939 : : The Stack is expected to contain:
940 : :
941 : :
942 : : Entry Exit
943 : : ===== ====
944 : :
945 : : Ptr ->
946 : : +------------+
947 : : | Expression |
948 : : |------------| empty
949 : : */
950 : :
951 : : extern "C" void M2Quads_BuildDefaultFieldAlignment (void);
952 : :
953 : : /*
954 : : BuildRepeat - Builds the repeat statement from the quad stack.
955 : : The Stack is expected to contain:
956 : :
957 : :
958 : : Entry Exit
959 : : ===== ====
960 : :
961 : :
962 : : Empty
963 : : <- Ptr
964 : : +------------+
965 : : | RepeatQuad |
966 : : |------------|
967 : :
968 : : */
969 : :
970 : : extern "C" void M2Quads_BuildRepeat (void);
971 : :
972 : : /*
973 : : BuildUntil - Builds the until part of the repeat statement
974 : : from the quad stack.
975 : : The Stack is expected to contain:
976 : :
977 : :
978 : : Entry Exit
979 : : ===== ====
980 : :
981 : : Ptr ->
982 : : +------------+
983 : : | t | f |
984 : : |------------|
985 : : | RepeatQuad | Empty
986 : : |------------|
987 : : */
988 : :
989 : : extern "C" void M2Quads_BuildUntil (void);
990 : :
991 : : /*
992 : : BuildWhile - Builds the While part of the While statement
993 : : from the quad stack.
994 : : The Stack is expected to contain:
995 : :
996 : :
997 : : Entry Exit
998 : : ===== ====
999 : :
1000 : : <- Ptr
1001 : : |------------|
1002 : : Empty | WhileQuad |
1003 : : |------------|
1004 : : */
1005 : :
1006 : : extern "C" void M2Quads_BuildWhile (void);
1007 : :
1008 : : /*
1009 : : BuildDoWhile - Builds the Do part of the while statement
1010 : : from the quad stack.
1011 : : The Stack is expected to contain:
1012 : :
1013 : :
1014 : : Entry Exit
1015 : : ===== ====
1016 : :
1017 : : Ptr ->
1018 : : +------------+ +------------+
1019 : : | t | f | | 0 | f |
1020 : : |------------| |------------|
1021 : : | WhileQuad | | WhileQuad |
1022 : : |------------| |------------|
1023 : :
1024 : : Quadruples
1025 : :
1026 : : BackPatch t exit to the NextQuad
1027 : : */
1028 : :
1029 : : extern "C" void M2Quads_BuildDoWhile (void);
1030 : :
1031 : : /*
1032 : : BuildEndWhile - Builds the end part of the while statement
1033 : : from the quad stack.
1034 : : The Stack is expected to contain:
1035 : :
1036 : :
1037 : : Entry Exit
1038 : : ===== ====
1039 : :
1040 : : Ptr ->
1041 : : +------------+
1042 : : | t | f |
1043 : : |------------|
1044 : : | WhileQuad | Empty
1045 : : |------------|
1046 : :
1047 : : Quadruples
1048 : :
1049 : : q GotoOp WhileQuad
1050 : : False exit is backpatched with q+1
1051 : : */
1052 : :
1053 : : extern "C" void M2Quads_BuildEndWhile (int reltokpos);
1054 : :
1055 : : /*
1056 : : BuildLoop - Builds the Loop part of the Loop statement
1057 : : from the quad stack.
1058 : : The Stack is expected to contain:
1059 : :
1060 : :
1061 : : Entry Exit
1062 : : ===== ====
1063 : :
1064 : : <- Ptr
1065 : : Empty +------------+
1066 : : | LoopQuad |
1067 : : |------------|
1068 : : */
1069 : :
1070 : : extern "C" void M2Quads_BuildLoop (void);
1071 : :
1072 : : /*
1073 : : BuildExit - Builds the Exit part of the Loop statement.
1074 : : */
1075 : :
1076 : : extern "C" void M2Quads_BuildExit (void);
1077 : :
1078 : : /*
1079 : : BuildEndLoop - Builds the End part of the Loop statement
1080 : : from the quad stack.
1081 : : The Stack is expected to contain:
1082 : :
1083 : :
1084 : : Entry Exit
1085 : : ===== ====
1086 : :
1087 : : Ptr ->
1088 : : +------------+
1089 : : | LoopQuad | Empty
1090 : : |------------|
1091 : :
1092 : : Quadruples
1093 : :
1094 : : Goto _ _ LoopQuad
1095 : : */
1096 : :
1097 : : extern "C" void M2Quads_BuildEndLoop (void);
1098 : :
1099 : : /*
1100 : : BuildThenIf - Builds the Then part of the If statement
1101 : : from the quad stack.
1102 : : The Stack is expected to contain:
1103 : :
1104 : :
1105 : : Entry Exit
1106 : : ===== ====
1107 : :
1108 : : Ptr -> <- Ptr
1109 : : +------------+ +------------+
1110 : : | t | f | | 0 | f |
1111 : : |------------| |------------|
1112 : :
1113 : : Quadruples
1114 : :
1115 : : The true exit is BackPatched to point to
1116 : : the NextQuad.
1117 : : */
1118 : :
1119 : : extern "C" void M2Quads_BuildThenIf (void);
1120 : :
1121 : : /*
1122 : : BuildElse - Builds the Else part of the If statement
1123 : : from the quad stack.
1124 : : The Stack is expected to contain:
1125 : :
1126 : :
1127 : : Entry Exit
1128 : : ===== ====
1129 : :
1130 : : Ptr ->
1131 : : +------------+ +------------+
1132 : : | t | f | | t+q | 0 |
1133 : : |------------| |------------|
1134 : :
1135 : : Quadruples
1136 : :
1137 : : q GotoOp _ _ 0
1138 : : q+1 <- BackPatched from f
1139 : : */
1140 : :
1141 : : extern "C" void M2Quads_BuildElse (void);
1142 : :
1143 : : /*
1144 : : BuildEndIf - Builds the End part of the If statement
1145 : : from the quad stack.
1146 : : The Stack is expected to contain:
1147 : :
1148 : :
1149 : : Entry Exit
1150 : : ===== ====
1151 : :
1152 : : Ptr ->
1153 : : +------------+
1154 : : | t | f | Empty
1155 : : |------------|
1156 : :
1157 : : Quadruples
1158 : :
1159 : : Both t and f are backpatched to point to the NextQuad
1160 : : */
1161 : :
1162 : : extern "C" void M2Quads_BuildEndIf (void);
1163 : :
1164 : : /*
1165 : : BuildElsif1 - Builds the Elsif part of the If statement
1166 : : from the quad stack.
1167 : : The Stack is expected to contain:
1168 : :
1169 : :
1170 : : Entry Exit
1171 : : ===== ====
1172 : :
1173 : : Ptr ->
1174 : : +------------+ +------------+
1175 : : | t | f | | t+q | 0 |
1176 : : |------------| |------------|
1177 : :
1178 : : Quadruples
1179 : :
1180 : : q GotoOp _ _ 0
1181 : : q+1 <- BackPatched from f
1182 : : */
1183 : :
1184 : : extern "C" void M2Quads_BuildElsif1 (void);
1185 : :
1186 : : /*
1187 : : BuildElsif2 - Builds the Elsif until part of the If statement
1188 : : from the quad stack.
1189 : : The Stack is expected to contain:
1190 : :
1191 : :
1192 : : Entry Exit
1193 : : ===== ====
1194 : :
1195 : : Ptr ->
1196 : : +--------------+
1197 : : | 0 | f1 | <- Ptr
1198 : : |--------------| +---------------+
1199 : : | t2 | f2 | | t2 | f1+f2 |
1200 : : |--------------| |---------------|
1201 : : */
1202 : :
1203 : : extern "C" void M2Quads_BuildElsif2 (void);
1204 : :
1205 : : /*
1206 : : BuildForToByDo - Builds the For To By Do part of the For statement
1207 : : from the quad stack.
1208 : : The Stack is expected to contain:
1209 : :
1210 : :
1211 : : Entry Exit
1212 : : ===== ====
1213 : :
1214 : : <- Ptr
1215 : : +----------------+
1216 : : Ptr -> | RangeId |
1217 : : +----------------+ |----------------|
1218 : : | BySym | ByType | | ForQuad |
1219 : : |----------------| |----------------|
1220 : : | e2 | | LastValue |
1221 : : |----------------| |----------------|
1222 : : | e1 | | BySym | ByType |
1223 : : |----------------| |----------------|
1224 : : | Ident | | IdentSym |
1225 : : |----------------| |----------------|
1226 : :
1227 : :
1228 : : x := e1 ;
1229 : : Note that LASTVALUE is calculated during M2GenGCC
1230 : : after all the types have been resolved.
1231 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
1232 : : IF BySym<0
1233 : : THEN
1234 : : IF e1<e2
1235 : : THEN
1236 : : goto exit
1237 : : END
1238 : : ELSE
1239 : : IF e1>e2
1240 : : THEN
1241 : : goto exit
1242 : : END
1243 : : END ;
1244 : : LOOP
1245 : : body
1246 : : IF x=LASTVALUE
1247 : : THEN
1248 : : goto exit
1249 : : END ;
1250 : : INC(x, BySym)
1251 : : END
1252 : :
1253 : : Quadruples:
1254 : :
1255 : : q BecomesOp IdentSym _ e1
1256 : : q+ LastForIteratorOp LastValue := ((e1-e2) DIV by) * by + e1
1257 : : q+1 if >= by 0 q+..2
1258 : : q+2 GotoOp q+3
1259 : : q+3 If >= e1 e2 q+5
1260 : : q+4 GotoOp exit
1261 : : q+5 ..
1262 : : q+..1 Goto q+..5
1263 : : q+..2 If >= e2 e1 q+..4
1264 : : q+..3 GotoOp exit
1265 : : q+..4 ..
1266 : :
1267 : : The For Loop is regarded:
1268 : :
1269 : : For ident := e1 To e2 By by Do
1270 : :
1271 : : End
1272 : : */
1273 : :
1274 : : extern "C" void M2Quads_BuildForToByDo (void);
1275 : :
1276 : : /*
1277 : : BuildPseudoBy - Builds the Non existant part of the By
1278 : : clause of the For statement
1279 : : from the quad stack.
1280 : : The Stack is expected to contain:
1281 : :
1282 : :
1283 : : Entry Exit
1284 : : ===== ====
1285 : :
1286 : : <- Ptr
1287 : : +------------+
1288 : : Ptr -> | BySym | t |
1289 : : +------------+ |------------|
1290 : : | e | t | | e | t |
1291 : : |------------| |------------|
1292 : : */
1293 : :
1294 : : extern "C" void M2Quads_BuildPseudoBy (void);
1295 : :
1296 : : /*
1297 : : BuildEndFor - Builds the End part of the For statement
1298 : : from the quad stack.
1299 : : The Stack is expected to contain:
1300 : :
1301 : :
1302 : : Entry Exit
1303 : : ===== ====
1304 : :
1305 : : Ptr ->
1306 : : +----------------+
1307 : : | RangeId |
1308 : : |----------------|
1309 : : | ForQuad |
1310 : : |----------------|
1311 : : | LastValue |
1312 : : |----------------|
1313 : : | BySym | ByType |
1314 : : |----------------|
1315 : : | IdSym | Empty
1316 : : |----------------|
1317 : : */
1318 : :
1319 : : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok);
1320 : :
1321 : : /*
1322 : : BuildCaseStart - starts the case statement.
1323 : : It initializes a backpatch list on the compile
1324 : : time stack, the list is used to contain all
1325 : : case break points. The list is later backpatched
1326 : : and contains all positions of the case statement
1327 : : which jump to the end of the case statement.
1328 : : The stack also contains room for a boolean
1329 : : expression, this is needed to allow , operator
1330 : : in the CaseField alternatives.
1331 : :
1332 : : The Stack is expected to contain:
1333 : :
1334 : :
1335 : : Entry Exit
1336 : : ===== ====
1337 : :
1338 : : <- Ptr
1339 : : +------------+
1340 : : | 0 | 0 |
1341 : : |------------|
1342 : : | 0 | 0 |
1343 : : +-------------+ |------------|
1344 : : | Expr | | | Expr | |
1345 : : |-------------| |------------|
1346 : : */
1347 : :
1348 : : extern "C" void M2Quads_BuildCaseStart (void);
1349 : :
1350 : : /*
1351 : : BuildCaseStartStatementSequence - starts the statement sequence
1352 : : inside a case clause.
1353 : : BackPatches the true exit to the
1354 : : NextQuad.
1355 : : The Stack:
1356 : :
1357 : : Entry Exit
1358 : :
1359 : : Ptr -> <- Ptr
1360 : : +-----------+ +------------+
1361 : : | t | f | | 0 | f |
1362 : : |-----------| |------------|
1363 : : */
1364 : :
1365 : : extern "C" void M2Quads_BuildCaseStartStatementSequence (void);
1366 : :
1367 : : /*
1368 : : BuildCaseEndStatementSequence - ends the statement sequence
1369 : : inside a case clause.
1370 : : BackPatches the false exit f1 to the
1371 : : NextQuad.
1372 : : Asserts that t1 and f2 is 0
1373 : : Pushes t2+q and 0
1374 : :
1375 : : Quadruples:
1376 : :
1377 : : q GotoOp _ _ 0
1378 : :
1379 : : The Stack:
1380 : :
1381 : : Entry Exit
1382 : :
1383 : : Ptr -> <- Ptr
1384 : : +-----------+ +------------+
1385 : : | t1 | f1 | | 0 | 0 |
1386 : : |-----------| |------------|
1387 : : | t2 | f2 | | t2+q | 0 |
1388 : : |-----------| |------------|
1389 : : */
1390 : :
1391 : : extern "C" void M2Quads_BuildCaseEndStatementSequence (void);
1392 : :
1393 : : /*
1394 : : BuildCaseRange - builds the range testing quaruples for
1395 : : a case clause.
1396 : :
1397 : : IF (e1>=ce1) AND (e1<=ce2)
1398 : : THEN
1399 : :
1400 : : ELS..
1401 : :
1402 : : The Stack:
1403 : :
1404 : : Entry Exit
1405 : :
1406 : : Ptr ->
1407 : : +-----------+
1408 : : | ce2 | <- Ptr
1409 : : |-----------| +-----------+
1410 : : | ce1 | | t | f |
1411 : : |-----------| |-----------|
1412 : : | t1 | f1 | | t1 | f1 |
1413 : : |-----------| |-----------|
1414 : : | t2 | f2 | | t2 | f2 |
1415 : : |-----------| |-----------|
1416 : : | e1 | | e1 |
1417 : : |-----------| |-----------|
1418 : : */
1419 : :
1420 : : extern "C" void M2Quads_BuildCaseRange (void);
1421 : :
1422 : : /*
1423 : : BuildCaseEquality - builds the range testing quadruples for
1424 : : a case clause.
1425 : :
1426 : : IF e1=ce1
1427 : : THEN
1428 : :
1429 : : ELS..
1430 : :
1431 : : The Stack:
1432 : :
1433 : : Entry Exit
1434 : :
1435 : : Ptr ->
1436 : : +-----------+ +-----------+
1437 : : | ce1 | | t | f |
1438 : : |-----------| |-----------|
1439 : : | t1 | f1 | | t1 | f1 |
1440 : : |-----------| |-----------|
1441 : : | t2 | f2 | | t2 | f2 |
1442 : : |-----------| |-----------|
1443 : : | e1 | | e1 |
1444 : : |-----------| |-----------|
1445 : : */
1446 : :
1447 : : extern "C" void M2Quads_BuildCaseEquality (void);
1448 : :
1449 : : /*
1450 : : BuildCaseList - merges two case tests into one
1451 : :
1452 : : The Stack:
1453 : :
1454 : : Entry Exit
1455 : :
1456 : : Ptr ->
1457 : : +-----------+
1458 : : | t2 | f2 |
1459 : : |-----------| +-------------+
1460 : : | t1 | f1 | | t1+t2| f1+f2|
1461 : : |-----------| |-------------|
1462 : : */
1463 : :
1464 : : extern "C" void M2Quads_BuildCaseList (void);
1465 : :
1466 : : /*
1467 : : BuildCaseOr - builds the , in the case clause.
1468 : :
1469 : : The Stack:
1470 : :
1471 : : Entry Exit
1472 : :
1473 : : Ptr -> <- Ptr
1474 : : +-----------+ +------------+
1475 : : | t | f | | t | 0 |
1476 : : |-----------| |------------|
1477 : : */
1478 : :
1479 : : extern "C" void M2Quads_BuildCaseOr (void);
1480 : :
1481 : : /*
1482 : : BuildCaseElse - builds the else of case clause.
1483 : :
1484 : : The Stack:
1485 : :
1486 : : Entry Exit
1487 : :
1488 : : Ptr -> <- Ptr
1489 : : +-----------+ +------------+
1490 : : | t | f | | t | 0 |
1491 : : |-----------| |------------|
1492 : : */
1493 : :
1494 : : extern "C" void M2Quads_BuildCaseElse (void);
1495 : :
1496 : : /*
1497 : : BuildCaseEnd - builds the end of case clause.
1498 : :
1499 : : The Stack:
1500 : :
1501 : : Entry Exit
1502 : :
1503 : : Ptr ->
1504 : : +-----------+
1505 : : | t1 | f1 |
1506 : : |-----------|
1507 : : | t2 | f2 |
1508 : : |-----------|
1509 : : | e1 |
1510 : : |-----------| Empty
1511 : : */
1512 : :
1513 : : extern "C" void M2Quads_BuildCaseEnd (void);
1514 : :
1515 : : /*
1516 : : BuildCaseCheck - builds the case checking code to ensure that
1517 : : the program does not need an else clause at runtime.
1518 : : The stack is unaltered.
1519 : : */
1520 : :
1521 : : extern "C" void M2Quads_BuildCaseCheck (void);
1522 : :
1523 : : /*
1524 : : BuildNulParam - Builds a nul parameter on the stack.
1525 : : The Stack:
1526 : :
1527 : : Entry Exit
1528 : :
1529 : : <- Ptr
1530 : : Empty +------------+
1531 : : | 0 |
1532 : : |------------|
1533 : : */
1534 : :
1535 : : extern "C" void M2Quads_BuildNulParam (void);
1536 : :
1537 : : /*
1538 : : BuildProcedureCall - builds a procedure call.
1539 : : Although this procedure does not directly
1540 : : destroy the procedure parameters, it calls
1541 : : routine which will manipulate the stack and
1542 : : so the entry and exit states of the stack are shown.
1543 : :
1544 : : The Stack:
1545 : :
1546 : :
1547 : : Entry Exit
1548 : :
1549 : : Ptr ->
1550 : : +----------------+
1551 : : | NoOfParam |
1552 : : |----------------|
1553 : : | Param 1 |
1554 : : |----------------|
1555 : : | Param 2 |
1556 : : |----------------|
1557 : : . .
1558 : : . .
1559 : : . .
1560 : : |----------------|
1561 : : | Param # |
1562 : : |----------------|
1563 : : | ProcSym | Type | Empty
1564 : : |----------------|
1565 : : */
1566 : :
1567 : : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno);
1568 : :
1569 : : /*
1570 : : CheckBuildFunction - checks to see whether ProcSym is a function
1571 : : and if so it adds a TempSym value which will
1572 : : hold the return value once the function finishes.
1573 : : This procedure also generates an error message
1574 : : if the user is calling a function and ignoring
1575 : : the return result. The additional TempSym
1576 : : is not created if ProcSym is a procedure
1577 : : and the stack is unaltered.
1578 : :
1579 : : The Stack:
1580 : :
1581 : :
1582 : : Entry Exit
1583 : :
1584 : : Ptr ->
1585 : :
1586 : : +----------------+
1587 : : | ProcSym | Type |
1588 : : +----------------+ |----------------|
1589 : : | ProcSym | Type | | TempSym | Type |
1590 : : |----------------| |----------------|
1591 : : */
1592 : :
1593 : : extern "C" bool M2Quads_CheckBuildFunction (void);
1594 : :
1595 : : /*
1596 : : BuildFunctionCall - builds a function call.
1597 : : The Stack:
1598 : :
1599 : :
1600 : : Entry Exit
1601 : :
1602 : : Ptr ->
1603 : : +----------------+
1604 : : | NoOfParam |
1605 : : |----------------|
1606 : : | Param 1 |
1607 : : |----------------|
1608 : : | Param 2 |
1609 : : |----------------|
1610 : : . .
1611 : : . .
1612 : : . .
1613 : : |----------------|
1614 : : | Param # | <- Ptr
1615 : : |----------------| +------------+
1616 : : | ProcSym | Type | | ReturnVar |
1617 : : |----------------| |------------|
1618 : : */
1619 : :
1620 : : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr);
1621 : :
1622 : : /*
1623 : : BuildConstFunctionCall - builds a function call and checks that this function can be
1624 : : called inside a ConstExpression.
1625 : :
1626 : : The Stack:
1627 : :
1628 : :
1629 : : Entry Exit
1630 : :
1631 : : Ptr ->
1632 : : +----------------+
1633 : : | NoOfParam |
1634 : : |----------------|
1635 : : | Param 1 |
1636 : : |----------------|
1637 : : | Param 2 |
1638 : : |----------------|
1639 : : . .
1640 : : . .
1641 : : . .
1642 : : |----------------|
1643 : : | Param # | <- Ptr
1644 : : |----------------| +------------+
1645 : : | ProcSym | Type | | ReturnVar |
1646 : : |----------------| |------------|
1647 : :
1648 : : */
1649 : :
1650 : : extern "C" void M2Quads_BuildConstFunctionCall (void);
1651 : :
1652 : : /*
1653 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
1654 : : conditional and if so it converts it into a boolean
1655 : : variable.
1656 : : */
1657 : :
1658 : : extern "C" void M2Quads_BuildBooleanVariable (void);
1659 : :
1660 : : /*
1661 : : BuildModuleStart - starts current module scope.
1662 : : */
1663 : :
1664 : : extern "C" void M2Quads_BuildModuleStart (unsigned int tok);
1665 : :
1666 : : /*
1667 : : BuildProcedureStart - Builds start of the procedure. Generates a
1668 : : quadruple which indicated the start of
1669 : : this procedure declarations scope.
1670 : : The Stack is expected to contain:
1671 : :
1672 : :
1673 : : Entry Exit
1674 : : ===== ====
1675 : :
1676 : : Ptr -> <- Ptr
1677 : : +------------+ +-----------+
1678 : : | ProcSym | | ProcSym |
1679 : : |------------| |-----------|
1680 : : | Name | | Name |
1681 : : |------------| |-----------|
1682 : :
1683 : :
1684 : : Quadruples:
1685 : :
1686 : : q ProcedureScopeOp Line# Scope ProcSym
1687 : : */
1688 : :
1689 : : extern "C" void M2Quads_BuildProcedureStart (void);
1690 : :
1691 : : /*
1692 : : BuildProcedureBegin - determines the start of the BEGIN END block of
1693 : : the procedure.
1694 : : The Stack is expected to contain:
1695 : :
1696 : :
1697 : : Entry Exit
1698 : : ===== ====
1699 : :
1700 : : Ptr -> <- Ptr
1701 : : +------------+ +-----------+
1702 : : | ProcSym | | ProcSym |
1703 : : |------------| |-----------|
1704 : : | Name | | Name |
1705 : : |------------| |-----------|
1706 : :
1707 : :
1708 : : Quadruples:
1709 : :
1710 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
1711 : : */
1712 : :
1713 : : extern "C" void M2Quads_BuildProcedureBegin (void);
1714 : :
1715 : : /*
1716 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
1717 : : the local variables.
1718 : : The Stack is expected to contain:
1719 : :
1720 : :
1721 : : Entry Exit
1722 : : ===== ====
1723 : :
1724 : : Ptr -> <- Ptr
1725 : : +------------+ +-----------+
1726 : : | ProcSym | | ProcSym |
1727 : : |------------| |-----------|
1728 : : | Name | | Name |
1729 : : |------------| |-----------|
1730 : :
1731 : :
1732 : : Quadruples:
1733 : :
1734 : : q KillLocalVarOp TokenNo(END) _ ProcSym
1735 : : */
1736 : :
1737 : : extern "C" void M2Quads_BuildProcedureEnd (void);
1738 : :
1739 : : /*
1740 : : BuildReturn - Builds the Return part of the procedure.
1741 : : tokreturn is the location of the RETURN keyword.
1742 : : The Stack is expected to contain:
1743 : :
1744 : :
1745 : : Entry Exit
1746 : : ===== ====
1747 : :
1748 : : Ptr ->
1749 : : +------------+
1750 : : | e1 | Empty
1751 : : |------------|
1752 : : */
1753 : :
1754 : : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn);
1755 : :
1756 : : /*
1757 : : BuildModulePriority - assigns the current module with a priority
1758 : : from the top of stack.
1759 : :
1760 : : Entry Exit
1761 : : ===== ====
1762 : :
1763 : :
1764 : : Ptr -> Empty
1765 : : +------------+
1766 : : | Priority |
1767 : : |------------|
1768 : : */
1769 : :
1770 : : extern "C" void M2Quads_BuildModulePriority (void);
1771 : :
1772 : : /*
1773 : : StartBuildWith - performs the with statement.
1774 : : The Stack:
1775 : :
1776 : : Entry Exit
1777 : :
1778 : : +------------+
1779 : : | Sym | Type | Empty
1780 : : |------------|
1781 : : */
1782 : :
1783 : : extern "C" void M2Quads_StartBuildWith (unsigned int withTok);
1784 : :
1785 : : /*
1786 : : EndBuildWith - terminates the innermost with scope.
1787 : : */
1788 : :
1789 : : extern "C" void M2Quads_EndBuildWith (void);
1790 : :
1791 : : /*
1792 : : CheckWithReference - performs the with statement.
1793 : : The Stack:
1794 : :
1795 : : Entry Exit
1796 : :
1797 : : +------------+ +------------+
1798 : : | Sym | Type | | Sym | Type |
1799 : : |------------| |------------|
1800 : : */
1801 : :
1802 : : extern "C" void M2Quads_CheckWithReference (void);
1803 : :
1804 : : /*
1805 : : BuildDesignatorRecord - Builds the record referencing.
1806 : : The Stack is expected to contain:
1807 : :
1808 : :
1809 : : Entry Exit
1810 : : ===== ====
1811 : :
1812 : : Ptr ->
1813 : : +--------------+
1814 : : | n |
1815 : : |--------------|
1816 : : | fld1 | type1 |
1817 : : |--------------|
1818 : : . .
1819 : : . .
1820 : : . .
1821 : : |--------------|
1822 : : | fldn | typen | <- Ptr
1823 : : |--------------| +-------------+
1824 : : | Sym | Type | | S | type1|
1825 : : |--------------| |-------------|
1826 : : */
1827 : :
1828 : : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok);
1829 : :
1830 : : /*
1831 : : BuildDesignatorArray - Builds the array referencing.
1832 : : The purpose of this procedure is to work out
1833 : : whether the DesignatorArray is a constant string or
1834 : : dynamic array/static array and to call the appropriate
1835 : : BuildRoutine.
1836 : :
1837 : : The Stack is expected to contain:
1838 : :
1839 : : Entry Exit
1840 : : ===== ====
1841 : :
1842 : : Ptr ->
1843 : : +--------------+
1844 : : | e | <- Ptr
1845 : : |--------------| +------------+
1846 : : | Sym | Type | | S | T |
1847 : : |--------------| |------------|
1848 : : */
1849 : :
1850 : : extern "C" void M2Quads_BuildDesignatorArray (void);
1851 : :
1852 : : /*
1853 : : BuildDesignatorPointer - Builds a pointer reference.
1854 : : The Stack is expected to contain:
1855 : :
1856 : :
1857 : : Entry Exit
1858 : : ===== ====
1859 : :
1860 : : Ptr -> <- Ptr
1861 : : +--------------+ +--------------+
1862 : : | Sym1 | Type1| | Sym2 | Type2|
1863 : : |--------------| |--------------|
1864 : : */
1865 : :
1866 : : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok);
1867 : :
1868 : : /*
1869 : : BuildNulExpression - Builds a nul expression on the stack.
1870 : : The Stack:
1871 : :
1872 : : Entry Exit
1873 : :
1874 : : <- Ptr
1875 : : Empty +------------+
1876 : : | NulSym |
1877 : : |------------|
1878 : : tokpos is the position of the RETURN token.
1879 : : */
1880 : :
1881 : : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos);
1882 : :
1883 : : /*
1884 : : BuildSetStart - Pushes a Bitset type on the stack.
1885 : :
1886 : : The Stack:
1887 : :
1888 : : Entry Exit
1889 : :
1890 : : Ptr -> <- Ptr
1891 : :
1892 : : Empty +--------------+
1893 : : | Bitset |
1894 : : |--------------|
1895 : : */
1896 : :
1897 : : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos);
1898 : :
1899 : : /*
1900 : : BuildSetEnd - pops the set value and type from the stack
1901 : : and pushes the value,type pair.
1902 : :
1903 : : Entry Exit
1904 : :
1905 : : Ptr ->
1906 : : +--------------+
1907 : : | Set Value | <- Ptr
1908 : : |--------------| +--------------+
1909 : : | Set Type | | Value | Type |
1910 : : |--------------| |--------------|
1911 : : */
1912 : :
1913 : : extern "C" void M2Quads_BuildSetEnd (void);
1914 : :
1915 : : /*
1916 : : BuildEmptySet - Builds an empty set on the stack.
1917 : : The Stack:
1918 : :
1919 : : Entry Exit
1920 : :
1921 : : <- Ptr
1922 : : +-------------+
1923 : : Ptr -> | Value |
1924 : : +-----------+ |-------------|
1925 : : | SetType | | SetType |
1926 : : |-----------| |-------------|
1927 : :
1928 : : tokpos points to the opening '{'.
1929 : : */
1930 : :
1931 : : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos);
1932 : :
1933 : : /*
1934 : : BuildInclRange - includes a set range with a set.
1935 : :
1936 : :
1937 : : Entry Exit
1938 : : ===== ====
1939 : :
1940 : :
1941 : : Ptr ->
1942 : : +------------+
1943 : : | El2 |
1944 : : |------------|
1945 : : | El1 | <- Ptr
1946 : : |------------| +-------------------+
1947 : : | Set Value | | Value + {El1..El2}|
1948 : : |------------| |-------------------|
1949 : :
1950 : : No quadruples produced as the range info is contained within
1951 : : the set value.
1952 : : */
1953 : :
1954 : : extern "C" void M2Quads_BuildInclRange (void);
1955 : :
1956 : : /*
1957 : : BuildInclBit - includes a bit into the set.
1958 : :
1959 : : Entry Exit
1960 : : ===== ====
1961 : :
1962 : :
1963 : : Ptr ->
1964 : : +------------+
1965 : : | Element | <- Ptr
1966 : : |------------| +------------+
1967 : : | Value | | Value |
1968 : : |------------| |------------|
1969 : :
1970 : : */
1971 : :
1972 : : extern "C" void M2Quads_BuildInclBit (void);
1973 : :
1974 : : /*
1975 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
1976 : : */
1977 : :
1978 : : extern "C" void M2Quads_SilentBuildConstructor (void);
1979 : :
1980 : : /*
1981 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
1982 : : */
1983 : :
1984 : : extern "C" void M2Quads_SilentBuildConstructorStart (void);
1985 : :
1986 : : /*
1987 : : BuildConstructor - builds a constructor.
1988 : : Stack
1989 : :
1990 : : Entry Exit
1991 : :
1992 : : Ptr ->
1993 : : +------------+
1994 : : | Type | <- Ptr
1995 : : |------------+
1996 : : */
1997 : :
1998 : : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos);
1999 : :
2000 : : /*
2001 : : BuildConstructorStart - builds a constructor.
2002 : : Stack
2003 : :
2004 : : Entry Exit
2005 : :
2006 : : Ptr -> <- Ptr
2007 : : +------------+ +----------------+
2008 : : | Type | | ConstructorSym |
2009 : : |------------+ |----------------|
2010 : : */
2011 : :
2012 : : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos);
2013 : :
2014 : : /*
2015 : : BuildConstructorEnd - removes the current constructor frame from the
2016 : : constructor stack (it does not effect the quad
2017 : : stack)
2018 : :
2019 : : Entry Exit
2020 : :
2021 : : Ptr -> <- Ptr
2022 : : +------------+ +------------+
2023 : : | const | | const |
2024 : : |------------| |------------|
2025 : :
2026 : : startpos is the start of the constructor, either the typename or '{'
2027 : : cbratokpos is the '}'.
2028 : : */
2029 : :
2030 : : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos);
2031 : :
2032 : : /*
2033 : : NextConstructorField - increments the top of constructor stacks index by one.
2034 : : */
2035 : :
2036 : : extern "C" void M2Quads_NextConstructorField (void);
2037 : :
2038 : : /*
2039 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
2040 : : If no constructor is currently being built then
2041 : : it Pushes a Bitset type.
2042 : : */
2043 : :
2044 : : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos);
2045 : :
2046 : : /*
2047 : : BuildComponentValue - builds a component value.
2048 : :
2049 : : Entry Exit
2050 : :
2051 : : Ptr -> <- Ptr
2052 : :
2053 : :
2054 : : +------------+ +------------+
2055 : : | const | | const |
2056 : : |------------| |------------|
2057 : : */
2058 : :
2059 : : extern "C" void M2Quads_BuildComponentValue (void);
2060 : :
2061 : : /*
2062 : : PopConstructor - removes the top constructor from the top of stack.
2063 : : */
2064 : :
2065 : : extern "C" void M2Quads_PopConstructor (void);
2066 : :
2067 : : /*
2068 : : BuildNot - Builds a NOT operation from the quad stack.
2069 : : The Stack is expected to contain:
2070 : :
2071 : :
2072 : : Entry Exit
2073 : : ===== ====
2074 : :
2075 : : Ptr -> <- Ptr
2076 : : +------------+ +------------+
2077 : : | t | f | | f | t |
2078 : : |------------| |------------|
2079 : : */
2080 : :
2081 : : extern "C" void M2Quads_BuildNot (unsigned int notTokPos);
2082 : :
2083 : : /*
2084 : : RecordOp - Records the operator passed on the stack.
2085 : : This is called when a boolean operator is found in an
2086 : : expression. It is called just after the lhs has been built
2087 : : and pushed to the quad stack and prior to the rhs build.
2088 : : It checks to see if AND OR or equality tests are required.
2089 : : It will short circuit AND and OR expressions. It also
2090 : : converts a lhs to a boolean variable if an xor comparison
2091 : : is about to be performed.
2092 : :
2093 : : Checks for AND operator or OR operator
2094 : : if either of these operators are found then BackPatching
2095 : : takes place.
2096 : : The Expected Stack:
2097 : :
2098 : : Entry Exit
2099 : :
2100 : : Ptr -> <- Ptr
2101 : : +-------------+ +-------------+
2102 : : | OperatorTok | | OperatorTok |
2103 : : |-------------| |-------------|
2104 : : | t | f | | t | f |
2105 : : |-------------| |-------------|
2106 : :
2107 : :
2108 : : If OperatorTok=AndTok
2109 : : Then
2110 : : BackPatch(f, NextQuad)
2111 : : Elsif OperatorTok=OrTok
2112 : : Then
2113 : : BackPatch(t, NextQuad)
2114 : : End
2115 : : */
2116 : :
2117 : : extern "C" void M2Quads_RecordOp (void);
2118 : :
2119 : : /*
2120 : : BuildRelOp - Builds a relative operation from the quad stack.
2121 : : The Stack is expected to contain:
2122 : :
2123 : :
2124 : : Entry Exit
2125 : : ===== ====
2126 : :
2127 : : Ptr ->
2128 : : +------------+
2129 : : | e1 |
2130 : : |------------| <- Ptr
2131 : : | Operator |
2132 : : |------------| +------------+
2133 : : | e2 | | t | f |
2134 : : |------------| |------------|
2135 : :
2136 : :
2137 : : Quadruples Produced
2138 : :
2139 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
2140 : : q+1 GotoOp FalseExit ; relation > etc
2141 : : ; requires order.
2142 : : */
2143 : :
2144 : : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos);
2145 : :
2146 : : /*
2147 : : BuildBinaryOp - Builds a binary operation from the quad stack.
2148 : : Be aware that this procedure will check for
2149 : : the overloading of the bitset operators + - \ *.
2150 : : So do NOT call this procedure if you are building
2151 : : a reference to an array which has a bitset type or
2152 : : the address arithmetic will be wrongly coersed into
2153 : : logical ORs.
2154 : :
2155 : : The Stack is expected to contain:
2156 : :
2157 : :
2158 : : Entry Exit
2159 : : ===== ====
2160 : :
2161 : : Ptr ->
2162 : : +------------+
2163 : : | Sym1 |
2164 : : |------------|
2165 : : | Operator | <- Ptr
2166 : : |------------| +------------+
2167 : : | Sym2 | | Temporary |
2168 : : |------------| |------------|
2169 : :
2170 : :
2171 : : Quadruples Produced
2172 : :
2173 : : q Operator Temporary Sym1 Sym2
2174 : :
2175 : :
2176 : : OR
2177 : :
2178 : :
2179 : : Entry Exit
2180 : : ===== ====
2181 : :
2182 : : Ptr ->
2183 : : +------------+
2184 : : | T1 | F1 |
2185 : : |------------|
2186 : : | OrTok | <- Ptr
2187 : : |------------| +------------+
2188 : : | T2 | F2 | | T1+T2| F1 |
2189 : : |------------| |------------|
2190 : :
2191 : :
2192 : : Quadruples Produced
2193 : :
2194 : : */
2195 : :
2196 : : extern "C" void M2Quads_BuildBinaryOp (void);
2197 : :
2198 : : /*
2199 : : BuildUnaryOp - Builds a unary operation from the quad stack.
2200 : : The Stack is expected to contain:
2201 : :
2202 : :
2203 : : Entry Exit
2204 : : ===== ====
2205 : :
2206 : : Ptr ->
2207 : : +------------+
2208 : : | Sym |
2209 : : |------------| +------------+
2210 : : | Operator | | Temporary | <- Ptr
2211 : : |------------| |------------|
2212 : :
2213 : :
2214 : : Quadruples Produced
2215 : :
2216 : : q Operator Temporary _ Sym
2217 : :
2218 : : */
2219 : :
2220 : : extern "C" void M2Quads_BuildUnaryOp (void);
2221 : :
2222 : : /*
2223 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
2224 : : */
2225 : :
2226 : : extern "C" unsigned int M2Quads_OperandT (unsigned int pos);
2227 : :
2228 : : /*
2229 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
2230 : : */
2231 : :
2232 : : extern "C" unsigned int M2Quads_OperandF (unsigned int pos);
2233 : :
2234 : : /*
2235 : : PushTF - Push a True and False numbers onto the True/False stack.
2236 : : True and False are assumed to contain Symbols or Ident etc.
2237 : : */
2238 : :
2239 : : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False);
2240 : :
2241 : : /*
2242 : : PopTF - Pop a True and False number from the True/False stack.
2243 : : True and False are assumed to contain Symbols or Ident etc.
2244 : : */
2245 : :
2246 : : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False);
2247 : :
2248 : : /*
2249 : : PushT - Push an item onto the stack in the T (true) position.
2250 : : */
2251 : :
2252 : : extern "C" void M2Quads_PushT (unsigned int True);
2253 : :
2254 : : /*
2255 : : PopT - Pops the T value from the stack.
2256 : : */
2257 : :
2258 : : extern "C" void M2Quads_PopT (unsigned int *True);
2259 : :
2260 : : /*
2261 : : PushTtok - Push an item onto the stack in the T (true) position,
2262 : : it is assummed to be a token and its token location is recorded.
2263 : : */
2264 : :
2265 : : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno);
2266 : :
2267 : : /*
2268 : : PushTFtok - Push an item onto the stack in the T (true) position,
2269 : : it is assummed to be a token and its token location is recorded.
2270 : : */
2271 : :
2272 : : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno);
2273 : :
2274 : : /*
2275 : : PopTFtok - Pop T/F/tok from the stack.
2276 : : */
2277 : :
2278 : : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno);
2279 : :
2280 : : /*
2281 : : PushTFAtok - Push T/F/A/tok to the stack.
2282 : : */
2283 : :
2284 : : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno);
2285 : :
2286 : : /*
2287 : : PopTtok - Pops the T value from the stack and token position.
2288 : : */
2289 : :
2290 : : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok);
2291 : :
2292 : : /*
2293 : : PushTFn - Push a True and False numbers onto the True/False stack.
2294 : : True and False are assumed to contain Symbols or Ident etc.
2295 : : */
2296 : :
2297 : : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n);
2298 : :
2299 : : /*
2300 : : PushTFntok - Push a True and False numbers onto the True/False stack.
2301 : : True and False are assumed to contain Symbols or Ident etc.
2302 : : */
2303 : :
2304 : : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno);
2305 : :
2306 : : /*
2307 : : PopTFn - Pop a True and False number from the True/False stack.
2308 : : True and False are assumed to contain Symbols or Ident etc.
2309 : : */
2310 : :
2311 : : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n);
2312 : :
2313 : : /*
2314 : : PopNothing - pops the top element on the boolean stack.
2315 : : */
2316 : :
2317 : : extern "C" void M2Quads_PopNothing (void);
2318 : :
2319 : : /*
2320 : : PopN - pops multiple elements from the BoolStack.
2321 : : */
2322 : :
2323 : : extern "C" void M2Quads_PopN (unsigned int n);
2324 : :
2325 : : /*
2326 : : PushTFA - Push True, False, Array, numbers onto the
2327 : : True/False stack. True and False are assumed to
2328 : : contain Symbols or Ident etc.
2329 : : */
2330 : :
2331 : : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array);
2332 : :
2333 : : /*
2334 : : OperandTok - returns the token associated with pos, on the stack.
2335 : : */
2336 : :
2337 : : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos);
2338 : :
2339 : : /*
2340 : : OperandA - returns possible array symbol associated with the ident
2341 : : operand stored on the boolean stack.
2342 : : */
2343 : :
2344 : : extern "C" unsigned int M2Quads_OperandA (unsigned int pos);
2345 : :
2346 : : /*
2347 : : OperandAnno - returns the annotation string associated with the
2348 : : position, n, on the stack.
2349 : : */
2350 : :
2351 : : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n);
2352 : :
2353 : : /*
2354 : : Annotate - annotate the top of stack.
2355 : : */
2356 : :
2357 : : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high);
2358 : :
2359 : : /*
2360 : : DisplayStack - displays the compile time symbol stack.
2361 : : */
2362 : :
2363 : : extern "C" void M2Quads_DisplayStack (void);
2364 : :
2365 : : /*
2366 : : Top - returns the no of items held in the stack.
2367 : : */
2368 : :
2369 : : extern "C" unsigned int M2Quads_Top (void);
2370 : :
2371 : : /*
2372 : : DupFrame - duplicate the top of stack and push the new frame.
2373 : : */
2374 : :
2375 : : extern "C" void M2Quads_DupFrame (void);
2376 : :
2377 : : /*
2378 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
2379 : : */
2380 : :
2381 : : extern "C" void M2Quads_WriteOperand (unsigned int Sym);
2382 : :
2383 : : /*
2384 : : BeginVarient - begin a varient record.
2385 : : */
2386 : :
2387 : : extern "C" void M2Quads_BeginVarient (void);
2388 : :
2389 : : /*
2390 : : EndVarient - end a varient record.
2391 : : */
2392 : :
2393 : : extern "C" void M2Quads_EndVarient (void);
2394 : :
2395 : : /*
2396 : : ElseVarient - associate an ELSE clause with a varient record.
2397 : : */
2398 : :
2399 : : extern "C" void M2Quads_ElseVarient (void);
2400 : :
2401 : : /*
2402 : : BeginVarientList - begin an ident list containing ranges belonging to a
2403 : : varient list.
2404 : : */
2405 : :
2406 : : extern "C" void M2Quads_BeginVarientList (void);
2407 : :
2408 : : /*
2409 : : EndVarientList - end a range list for a varient field.
2410 : : */
2411 : :
2412 : : extern "C" void M2Quads_EndVarientList (void);
2413 : :
2414 : : /*
2415 : : AddRecordToList - adds the record held on the top of stack to the
2416 : : list of records and varient fields.
2417 : : */
2418 : :
2419 : : extern "C" void M2Quads_AddRecordToList (void);
2420 : :
2421 : : /*
2422 : : AddVarientToList - adds varient held on the top of stack to the list.
2423 : : */
2424 : :
2425 : : extern "C" void M2Quads_AddVarientToList (void);
2426 : :
2427 : : /*
2428 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
2429 : : fields created.
2430 : : */
2431 : :
2432 : : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f);
2433 : :
2434 : : /*
2435 : : AddVarientRange - creates a range from the top two contant expressions
2436 : : on the stack which are recorded with the current
2437 : : varient field. The stack is unaltered.
2438 : : */
2439 : :
2440 : : extern "C" void M2Quads_AddVarientRange (void);
2441 : :
2442 : : /*
2443 : : AddVarientEquality - adds the contant expression on the top of the stack
2444 : : to the current varient field being recorded.
2445 : : The stack is unaltered.
2446 : : */
2447 : :
2448 : : extern "C" void M2Quads_AddVarientEquality (void);
2449 : :
2450 : : /*
2451 : : BuildCodeOn - generates a quadruple declaring that code should be
2452 : : emmitted from henceforth.
2453 : :
2454 : : The Stack is unnaffected.
2455 : : */
2456 : :
2457 : : extern "C" void M2Quads_BuildCodeOn (void);
2458 : :
2459 : : /*
2460 : : BuildCodeOff - generates a quadruple declaring that code should not be
2461 : : emmitted from henceforth.
2462 : :
2463 : : The Stack is unnaffected.
2464 : : */
2465 : :
2466 : : extern "C" void M2Quads_BuildCodeOff (void);
2467 : :
2468 : : /*
2469 : : BuildProfileOn - generates a quadruple declaring that profile timings
2470 : : should be emmitted from henceforth.
2471 : :
2472 : : The Stack is unnaffected.
2473 : : */
2474 : :
2475 : : extern "C" void M2Quads_BuildProfileOn (void);
2476 : : extern "C" void M2Quads_BuildProfileOff (void);
2477 : :
2478 : : /*
2479 : : BuildOptimizeOn - generates a quadruple declaring that optimization
2480 : : should occur from henceforth.
2481 : :
2482 : : The Stack is unnaffected.
2483 : : */
2484 : :
2485 : : extern "C" void M2Quads_BuildOptimizeOn (void);
2486 : :
2487 : : /*
2488 : : BuildOptimizeOff - generates a quadruple declaring that optimization
2489 : : should not occur from henceforth.
2490 : :
2491 : : The Stack is unnaffected.
2492 : : */
2493 : :
2494 : : extern "C" void M2Quads_BuildOptimizeOff (void);
2495 : :
2496 : : /*
2497 : : BuildAsm - builds an Inline pseudo quadruple operator.
2498 : : The inline interface, Sym, is stored as the operand
2499 : : to the operator InlineOp.
2500 : :
2501 : : The stack is expected to contain:
2502 : :
2503 : :
2504 : : Entry Exit
2505 : : ===== ====
2506 : :
2507 : : Ptr ->
2508 : : +--------------+
2509 : : | Sym | Empty
2510 : : |--------------|
2511 : : */
2512 : :
2513 : : extern "C" void M2Quads_BuildAsm (unsigned int tok);
2514 : :
2515 : : /*
2516 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
2517 : : This quadruple indicates which source line has been
2518 : : processed, these quadruples are only generated if we
2519 : : are producing runtime debugging information.
2520 : :
2521 : : The stack is not affected, read or altered in any way.
2522 : :
2523 : :
2524 : : Entry Exit
2525 : : ===== ====
2526 : :
2527 : : Ptr -> <- Ptr
2528 : : */
2529 : :
2530 : : extern "C" void M2Quads_BuildLineNo (void);
2531 : :
2532 : : /*
2533 : : PushLineNo - pushes the current file and line number to the stack.
2534 : : */
2535 : :
2536 : : extern "C" void M2Quads_PushLineNo (void);
2537 : :
2538 : : /*
2539 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
2540 : : This quadruple indicates which source line has been
2541 : : processed and it represents the start of a statement
2542 : : sequence.
2543 : : It differs from LineNumberOp in that multiple successive
2544 : : LineNumberOps will be removed and the final one is attached to
2545 : : the next real GCC tree. Whereas a StatementNoteOp is always left
2546 : : alone. Depending upon the debugging level it will issue a nop
2547 : : instruction to ensure that the gdb single step will step into
2548 : : this line. Practically it allows pedalogical debugging to
2549 : : occur when there is syntax sugar such as:
2550 : :
2551 : :
2552 : : END step
2553 : : END step
2554 : : END ; step
2555 : : a := 1 ; step
2556 : :
2557 : : REPEAT step
2558 : : i := 1 step
2559 : :
2560 : : The stack is not affected, read or altered in any way.
2561 : :
2562 : :
2563 : : Entry Exit
2564 : : ===== ====
2565 : :
2566 : : Ptr -> <- Ptr
2567 : : */
2568 : :
2569 : : extern "C" void M2Quads_BuildStmtNote (int offset);
2570 : :
2571 : : /*
2572 : : LoopAnalysis - checks whether an infinite loop exists.
2573 : : */
2574 : :
2575 : : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End);
2576 : :
2577 : : /*
2578 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
2579 : : and dangerous usage outside the loop.
2580 : : */
2581 : :
2582 : : extern "C" void M2Quads_ForLoopAnalysis (void);
2583 : :
2584 : : /*
2585 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
2586 : : is being "called". This should be done as SIZE only requires the
2587 : : actual type of the expression, not its value. Consider the problem of
2588 : : SIZE(UninitializedPointer^) which is quite legal and it must
2589 : : also be safe!
2590 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
2591 : : and there is no need to compute a[0], we just need to follow the
2592 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
2593 : : and, a, is an unbounded array then we turn on quadruple generation.
2594 : :
2595 : : The Stack is expected to contain:
2596 : :
2597 : :
2598 : : Entry Exit
2599 : : ===== ====
2600 : :
2601 : : Ptr -> <- Ptr
2602 : : +----------------------+ +----------------------+
2603 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
2604 : : |----------------------| |----------------------|
2605 : : */
2606 : :
2607 : : extern "C" void M2Quads_BuildSizeCheckStart (void);
2608 : :
2609 : : /*
2610 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
2611 : : quadruples and replaces it by an assignment to the Low or High component
2612 : : of the subrange type.
2613 : :
2614 : : Input:
2615 : : SubrangeLow op1 op3 op3 is a subrange
2616 : :
2617 : : Output:
2618 : : Becomes op1 low
2619 : :
2620 : : Input:
2621 : : SubrangeHigh op1 op3 op3 is a subrange
2622 : :
2623 : : Output:
2624 : : Becomes op1 high
2625 : :
2626 : : Input:
2627 : : OptParam op1 op2 op3
2628 : :
2629 : : Output:
2630 : : Param op1 op2 GetOptArgInit(op3)
2631 : : */
2632 : :
2633 : : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void);
2634 : :
2635 : : /*
2636 : : WriteOperator - writes the name of the quadruple operator.
2637 : : */
2638 : :
2639 : : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator);
2640 : :
2641 : : /*
2642 : : PushAutoOn - push the auto flag and then set it to TRUE.
2643 : : Any call to ident in the parser will result in the token being pushed.
2644 : : */
2645 : :
2646 : : extern "C" void M2Quads_PushAutoOn (void);
2647 : :
2648 : : /*
2649 : : PushAutoOff - push the auto flag and then set it to FALSE.
2650 : : */
2651 : :
2652 : : extern "C" void M2Quads_PushAutoOff (void);
2653 : :
2654 : : /*
2655 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
2656 : : */
2657 : :
2658 : : extern "C" bool M2Quads_IsAutoPushOn (void);
2659 : :
2660 : : /*
2661 : : PopAuto - restores the previous value of the Auto flag.
2662 : : */
2663 : :
2664 : : extern "C" void M2Quads_PopAuto (void);
2665 : :
2666 : : /*
2667 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
2668 : : */
2669 : :
2670 : : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q);
2671 : :
2672 : : /*
2673 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
2674 : : */
2675 : :
2676 : : extern "C" void M2Quads_PushInConstExpression (void);
2677 : :
2678 : : /*
2679 : : PopInConstExpression - restores the previous value of the InConstExpression.
2680 : : */
2681 : :
2682 : : extern "C" void M2Quads_PopInConstExpression (void);
2683 : :
2684 : : /*
2685 : : IsInConstExpression - returns the value of the InConstExpression.
2686 : : */
2687 : :
2688 : : extern "C" bool M2Quads_IsInConstExpression (void);
2689 : :
2690 : : /*
2691 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
2692 : : */
2693 : :
2694 : : extern "C" void M2Quads_PushInConstParameters (void);
2695 : :
2696 : : /*
2697 : : PopInConstParameters - restores the previous value of the InConstParameters.
2698 : : */
2699 : :
2700 : : extern "C" void M2Quads_PopInConstParameters (void);
2701 : :
2702 : : /*
2703 : : IsInConstParameters - returns the value of the InConstParameters.
2704 : : */
2705 : :
2706 : : extern "C" bool M2Quads_IsInConstParameters (void);
2707 : :
2708 : : /*
2709 : : BuildAsmElement - the stack is expected to contain:
2710 : :
2711 : :
2712 : : Entry Exit
2713 : : ===== ====
2714 : :
2715 : : Ptr ->
2716 : : +------------------+
2717 : : | expr | tokpos |
2718 : : |------------------|
2719 : : | str |
2720 : : |------------------|
2721 : : | name |
2722 : : |------------------| +------------------+
2723 : : | CurrentInterface | | CurrentInterface |
2724 : : |------------------| |------------------|
2725 : : | CurrentAsm | | CurrentAsm |
2726 : : |------------------| |------------------|
2727 : : | n | | n |
2728 : : |------------------| |------------------|
2729 : : */
2730 : :
2731 : : extern "C" void M2Quads_BuildAsmElement (bool input, bool output);
2732 : :
2733 : : /*
2734 : : BuildAsmTrash - the stack is expected to contain:
2735 : :
2736 : :
2737 : : Entry Exit
2738 : : ===== ====
2739 : :
2740 : : Ptr ->
2741 : : +------------------+
2742 : : | expr | tokpos |
2743 : : |------------------| +------------------+
2744 : : | CurrentInterface | | CurrentInterface |
2745 : : |------------------| |------------------|
2746 : : | CurrentAsm | | CurrentAsm |
2747 : : |------------------| |------------------|
2748 : : | n | | n |
2749 : : |------------------| |------------------|
2750 : : */
2751 : :
2752 : : extern "C" void M2Quads_BuildAsmTrash (void);
2753 : :
2754 : : /*
2755 : : GetQuadTrash - return the symbol associated with the trashed operand.
2756 : : */
2757 : :
2758 : : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad);
2759 : :
2760 : : /*
2761 : : DSdbEnter -
2762 : : */
2763 : :
2764 : : static void DSdbEnter (void);
2765 : :
2766 : : /*
2767 : : DSdbExit -
2768 : : */
2769 : :
2770 : : static void DSdbExit (void);
2771 : :
2772 : : /*
2773 : : GetQF - returns the QuadFrame associated with, q.
2774 : : */
2775 : :
2776 : : static M2Quads_QuadFrame GetQF (unsigned int q);
2777 : :
2778 : : /*
2779 : : IsQuadA - returns true if QuadNo is a op.
2780 : : */
2781 : :
2782 : : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op);
2783 : :
2784 : : /*
2785 : : OpUsesOp1 - return TRUE if op allows op1.
2786 : : */
2787 : :
2788 : : static bool OpUsesOp1 (M2Quads_QuadOperator op);
2789 : :
2790 : : /*
2791 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
2792 : : */
2793 : :
2794 : : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2795 : :
2796 : : /*
2797 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
2798 : : sets a boolean to determinine whether overflow should be checked.
2799 : : */
2800 : :
2801 : : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow);
2802 : :
2803 : : /*
2804 : : PutQuadOType -
2805 : : */
2806 : :
2807 : : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype);
2808 : :
2809 : : /*
2810 : : UndoReadWriteInfo -
2811 : : */
2812 : :
2813 : : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3);
2814 : :
2815 : : /*
2816 : : CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
2817 : : parameters and if so it then adds them to the quadruple
2818 : : variable list.
2819 : : */
2820 : :
2821 : : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad);
2822 : :
2823 : : /*
2824 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
2825 : : a parameter and if so it then adds this quadruple
2826 : : to the variable list.
2827 : : */
2828 : :
2829 : : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2830 : :
2831 : : /*
2832 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
2833 : : a parameter and if so then it removes the
2834 : : quadruple from the variable list.
2835 : : */
2836 : :
2837 : : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad);
2838 : :
2839 : : /*
2840 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
2841 : : if so it then adds this quadruple to the variable list.
2842 : : */
2843 : :
2844 : : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2845 : :
2846 : : /*
2847 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
2848 : : if so then it removes the quadruple from the
2849 : : variable list.
2850 : : */
2851 : :
2852 : : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad);
2853 : :
2854 : : /*
2855 : : CheckConst -
2856 : : */
2857 : :
2858 : : static void CheckConst (unsigned int sym);
2859 : :
2860 : : /*
2861 : : AlterReference - alters all references from OldQuad, to NewQuad in a
2862 : : quadruple list Head.
2863 : : */
2864 : :
2865 : : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad);
2866 : :
2867 : : /*
2868 : : GrowQuads - grows the list of quadruples to the quadruple, to.
2869 : : */
2870 : :
2871 : : static void GrowQuads (unsigned int to);
2872 : :
2873 : : /*
2874 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
2875 : : */
2876 : :
2877 : : static void ManipulateReference (unsigned int q, unsigned int to);
2878 : :
2879 : : /*
2880 : : RemoveReference - remove the reference by quadruple q to wherever
2881 : : it was pointing.
2882 : : */
2883 : :
2884 : : static void RemoveReference (unsigned int q);
2885 : :
2886 : : /*
2887 : : NewQuad - sets QuadNo to a new quadruple.
2888 : : */
2889 : :
2890 : : static void NewQuad (unsigned int *QuadNo);
2891 : :
2892 : : /*
2893 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
2894 : : */
2895 : :
2896 : : static void CheckVariableAt (unsigned int sym);
2897 : :
2898 : : /*
2899 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
2900 : : which point to variable declared at addresses.
2901 : : */
2902 : :
2903 : : static void CheckVariablesAt (unsigned int scope);
2904 : :
2905 : : /*
2906 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
2907 : : */
2908 : :
2909 : : static unsigned int GetTurnInterrupts (unsigned int tok);
2910 : :
2911 : : /*
2912 : : GetProtection - returns the PROTECTION data type.
2913 : : */
2914 : :
2915 : : static unsigned int GetProtection (unsigned int tok);
2916 : :
2917 : : /*
2918 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
2919 : : module priority and change to another module
2920 : : priority.
2921 : : The current module initialization or procedure
2922 : : being built is defined by, scope. The module whose
2923 : : priority will be used is defined by, module.
2924 : : */
2925 : :
2926 : : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module);
2927 : :
2928 : : /*
2929 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
2930 : : module priority.
2931 : : The current module initialization or procedure
2932 : : being built is defined by, scope.
2933 : : */
2934 : :
2935 : : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module);
2936 : :
2937 : : /*
2938 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
2939 : : */
2940 : :
2941 : : static void BuildRTExceptEnter (unsigned int tok);
2942 : :
2943 : : /*
2944 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
2945 : : If, destroy, is TRUE then pop the ExceptStack.
2946 : : */
2947 : :
2948 : : static void BuildRTExceptLeave (unsigned int tok, bool destroy);
2949 : :
2950 : : /*
2951 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
2952 : : It attempts to get symbol name from the current scope(s) and if
2953 : : it fails then it falls back onto default constants.
2954 : : */
2955 : :
2956 : : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name);
2957 : :
2958 : : /*
2959 : : callRequestDependant - create a call:
2960 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
2961 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
2962 : : */
2963 : :
2964 : : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep);
2965 : :
2966 : : /*
2967 : : ForeachImportInDepDo -
2968 : : */
2969 : :
2970 : : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep);
2971 : :
2972 : : /*
2973 : : ForeachImportedModuleDo -
2974 : : */
2975 : :
2976 : : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep);
2977 : :
2978 : : /*
2979 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
2980 : : static void
2981 : : dependencies (void)
2982 : : {
2983 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
2984 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
2985 : : }
2986 : : */
2987 : :
2988 : : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym);
2989 : :
2990 : : /*
2991 : : BuildM2LinkFunction - creates the _M2_link procedure which will
2992 : : cause the linker to pull in all the module ctors.
2993 : : */
2994 : :
2995 : : static void BuildM2LinkFunction (unsigned int tokno);
2996 : :
2997 : : /*
2998 : : BuildTry - build the try statement for main.
2999 : : */
3000 : :
3001 : : static void BuildTry (unsigned int tokno);
3002 : :
3003 : : /*
3004 : : BuildExcept - build the except block for main.
3005 : : */
3006 : :
3007 : : static void BuildExcept (unsigned int tokno);
3008 : :
3009 : : /*
3010 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
3011 : : */
3012 : :
3013 : : static void BuildM2MainFunction (unsigned int tokno);
3014 : :
3015 : : /*
3016 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
3017 : : */
3018 : :
3019 : : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym);
3020 : :
3021 : : /*
3022 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
3023 : : */
3024 : :
3025 : : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym);
3026 : :
3027 : : /*
3028 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
3029 : : */
3030 : :
3031 : : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name);
3032 : :
3033 : : /*
3034 : : BuildM2InitFunction -
3035 : : */
3036 : :
3037 : : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym);
3038 : :
3039 : : /*
3040 : : BuildM2FiniFunction -
3041 : : */
3042 : :
3043 : : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym);
3044 : :
3045 : : /*
3046 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
3047 : :
3048 : : void
3049 : : ctorFunction ()
3050 : : {
3051 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
3052 : : init, fini, dependencies);
3053 : : }
3054 : : */
3055 : :
3056 : : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym);
3057 : :
3058 : : /*
3059 : : AddForInfo - adds the description of the FOR loop into the record list.
3060 : : This is used if -pedantic is turned on to check index variable
3061 : : usage.
3062 : : */
3063 : :
3064 : : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok);
3065 : :
3066 : : /*
3067 : : CheckForIndex - checks the quadruples: Start..End to see whether a
3068 : : for loop index is manipulated by the programmer.
3069 : : It generates a warning if this is the case.
3070 : : It also checks to see whether the IndexSym is read
3071 : : immediately outside the loop in which case a warning
3072 : : is issued.
3073 : : */
3074 : :
3075 : : static void CheckForIndex (M2Quads_ForLoopInfo forDesc);
3076 : :
3077 : : /*
3078 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
3079 : : */
3080 : :
3081 : : static void BuildRange (unsigned int r);
3082 : :
3083 : : /*
3084 : : BuildError - generates a ErrorOp quad, indicating that if this
3085 : : quadruple is reachable, then a runtime error would
3086 : : occur.
3087 : : */
3088 : :
3089 : : static void BuildError (unsigned int r);
3090 : :
3091 : : /*
3092 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
3093 : : a candidate for checking against NIL.
3094 : : This range quadruple is only expanded into
3095 : : code during the code generation phase
3096 : : thus allowing limited compile time checking.
3097 : : */
3098 : :
3099 : : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym);
3100 : :
3101 : : /*
3102 : : CollectLow - returns the low of the subrange value.
3103 : : */
3104 : :
3105 : : static unsigned int CollectLow (unsigned int sym);
3106 : :
3107 : : /*
3108 : : CollectHigh - returns the high of the subrange value, sym.
3109 : : */
3110 : :
3111 : : static unsigned int CollectHigh (unsigned int sym);
3112 : :
3113 : : /*
3114 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
3115 : : compatible with the := operator.
3116 : : */
3117 : :
3118 : : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok);
3119 : :
3120 : : /*
3121 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
3122 : : check bounds.
3123 : : */
3124 : :
3125 : : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow);
3126 : :
3127 : : /*
3128 : : MarkArrayWritten - marks, Array, as being written.
3129 : : */
3130 : :
3131 : : static void MarkArrayWritten (unsigned int Array);
3132 : :
3133 : : /*
3134 : : MarkAsReadWrite - marks the variable or parameter as being
3135 : : read/write.
3136 : : */
3137 : :
3138 : : static void MarkAsReadWrite (unsigned int sym);
3139 : :
3140 : : /*
3141 : : MarkAsRead - marks the variable or parameter as being read.
3142 : : */
3143 : :
3144 : : static void MarkAsRead (unsigned int sym);
3145 : :
3146 : : /*
3147 : : MarkAsWrite - marks the variable or parameter as being written.
3148 : : */
3149 : :
3150 : : static void MarkAsWrite (unsigned int sym);
3151 : :
3152 : : /*
3153 : : doVal - return an expression which is VAL(type, expr). If
3154 : : expr is a constant then return expr.
3155 : : */
3156 : :
3157 : : static unsigned int doVal (unsigned int type, unsigned int expr);
3158 : :
3159 : : /*
3160 : : MoveWithMode -
3161 : : */
3162 : :
3163 : : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow);
3164 : :
3165 : : /*
3166 : : CheckBecomesMeta - checks to make sure that we are not
3167 : : assigning a variable to a constant.
3168 : : Also check we are not assigning to an
3169 : : unbounded array.
3170 : : */
3171 : :
3172 : : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3173 : :
3174 : : /*
3175 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
3176 : : It builds the assignment and optionally
3177 : : checks the types are compatible.
3178 : : */
3179 : :
3180 : : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow);
3181 : :
3182 : : /*
3183 : : CheckAssignCompatible - checks to see that an assignment is compatible.
3184 : : It performs limited checking - thorough checking
3185 : : is done in pass 3. But we do what we can here
3186 : : given knowledge so far.
3187 : : */
3188 : :
3189 : : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok);
3190 : :
3191 : : /*
3192 : : CheckBooleanId - Checks to see if the top operand is a boolean.
3193 : : If the operand is not a boolean then it is tested
3194 : : with true and a boolean is generated.
3195 : : The Stack:
3196 : :
3197 : :
3198 : : Entry Exit
3199 : : Ptr -> <- Ptr
3200 : : +------------+ +------------+
3201 : : | Sym | | t | f |
3202 : : |------------| |------------|
3203 : :
3204 : : Quadruples
3205 : :
3206 : : q If= Sym True _
3207 : : q+1 GotoOp _ _ _
3208 : : */
3209 : :
3210 : : static void CheckBooleanId (void);
3211 : :
3212 : : /*
3213 : : PushOne - pushes the value one to the stack.
3214 : : The Stack is changed:
3215 : :
3216 : :
3217 : : Entry Exit
3218 : : ===== ====
3219 : :
3220 : : <- Ptr
3221 : : +------------+
3222 : : Ptr -> | 1 | type |
3223 : : |------------|
3224 : : */
3225 : :
3226 : : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high);
3227 : :
3228 : : /*
3229 : : PushZero - pushes the value zero to the stack.
3230 : : The Stack is changed:
3231 : :
3232 : :
3233 : : Entry Exit
3234 : : ===== ====
3235 : :
3236 : : <- Ptr
3237 : : +------------+
3238 : : Ptr -> | 0 | type |
3239 : : |------------|
3240 : : */
3241 : :
3242 : : static void PushZero (unsigned int tok, unsigned int type);
3243 : :
3244 : : /*
3245 : : ForLoopLastIterator - calculate the last iterator value but avoid setting
3246 : : LastIterator twice if it is a constant (in the quads).
3247 : : In the ForLoopLastIteratorVariable case only one
3248 : : path will be chosen but at the time of quadruple
3249 : : generation we do not know the value of BySym.
3250 : : */
3251 : :
3252 : : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok);
3253 : :
3254 : : /*
3255 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
3256 : : If so then we restore quadruple generation.
3257 : : */
3258 : :
3259 : : static void BuildSizeCheckEnd (unsigned int ProcSym);
3260 : :
3261 : : /*
3262 : : BuildRealProcedureCall - builds a real procedure call.
3263 : : The Stack:
3264 : :
3265 : :
3266 : : Entry Exit
3267 : :
3268 : : Ptr ->
3269 : : +----------------+
3270 : : | NoOfParam |
3271 : : |----------------|
3272 : : | Param 1 |
3273 : : |----------------|
3274 : : | Param 2 |
3275 : : |----------------|
3276 : : . .
3277 : : . .
3278 : : . .
3279 : : |----------------|
3280 : : | Param # |
3281 : : |----------------|
3282 : : | ProcSym | Type | Empty
3283 : : |----------------|
3284 : : */
3285 : :
3286 : : static void BuildRealProcedureCall (unsigned int tokno);
3287 : :
3288 : : /*
3289 : : BuildRealFuncProcCall - builds a real procedure or function call.
3290 : : The Stack:
3291 : :
3292 : :
3293 : : Entry Exit
3294 : :
3295 : : Ptr ->
3296 : : +----------------+
3297 : : | NoOfParam |
3298 : : |----------------|
3299 : : | Param 1 |
3300 : : |----------------|
3301 : : | Param 2 |
3302 : : |----------------|
3303 : : . .
3304 : : . .
3305 : : . .
3306 : : |----------------|
3307 : : | Param # |
3308 : : |----------------|
3309 : : | ProcSym | Type | Empty
3310 : : |----------------|
3311 : : */
3312 : :
3313 : : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr);
3314 : :
3315 : : /*
3316 : : CheckProcedureParameters - Checks the parameters which are being passed to
3317 : : procedure ProcSym.
3318 : :
3319 : : The Stack:
3320 : :
3321 : :
3322 : : Entry Exit
3323 : :
3324 : : Ptr -> <- Ptr
3325 : : +----------------+ +----------------+
3326 : : | NoOfParam | | NoOfParam |
3327 : : |----------------| |----------------|
3328 : : | Param 1 | | Param 1 |
3329 : : |----------------| |----------------|
3330 : : | Param 2 | | Param 2 |
3331 : : |----------------| |----------------|
3332 : : . . . .
3333 : : . . . .
3334 : : . . . .
3335 : : |----------------| |----------------|
3336 : : | Param # | | Param # |
3337 : : |----------------| |----------------|
3338 : : | ProcSym | Type | | ProcSym | Type |
3339 : : |----------------| |----------------|
3340 : :
3341 : : */
3342 : :
3343 : : static void CheckProcedureParameters (bool IsForC);
3344 : :
3345 : : /*
3346 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
3347 : : */
3348 : :
3349 : : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId);
3350 : :
3351 : : /*
3352 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
3353 : : as a pointer or address.
3354 : : */
3355 : :
3356 : : static bool IsReallyPointer (unsigned int Sym);
3357 : :
3358 : : /*
3359 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
3360 : : passed to ProcSym, i, the, Formal, parameter.
3361 : : */
3362 : :
3363 : : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal);
3364 : :
3365 : : /*
3366 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
3367 : : passing. ProcSym is the procedure and i is the parameter number.
3368 : :
3369 : : We obey the following rules:
3370 : :
3371 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
3372 : : type.
3373 : : (2) we allow ADDRESS to be compatible with any pointer type.
3374 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
3375 : :
3376 : : Note that type sizes are checked during the code generation pass.
3377 : : */
3378 : :
3379 : : 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);
3380 : :
3381 : : /*
3382 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
3383 : : */
3384 : :
3385 : : static DynamicStrings_String DescribeType (unsigned int Sym);
3386 : :
3387 : : /*
3388 : : FailParameter - generates an error message indicating that a parameter
3389 : : declaration has failed.
3390 : :
3391 : : The parameters are:
3392 : :
3393 : : CurrentState - string describing the current failing state.
3394 : : Actual - actual parameter.
3395 : : ParameterNo - parameter number that has failed.
3396 : : ProcedureSym - procedure symbol where parameter has failed.
3397 : :
3398 : : If any parameter is Nul then it is ignored.
3399 : : */
3400 : :
3401 : : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
3402 : :
3403 : : /*
3404 : : WarnParameter - generates a warning message indicating that a parameter
3405 : : use might cause problems on another target.
3406 : :
3407 : : CurrentState - string describing the current failing state.
3408 : : Actual - actual parameter.
3409 : : ParameterNo - parameter number that has failed.
3410 : : ProcedureSym - procedure symbol where parameter has failed.
3411 : :
3412 : : If any parameter is Nul then it is ignored.
3413 : : */
3414 : :
3415 : : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo);
3416 : :
3417 : : /*
3418 : : doIndrX - perform des = *exp with a conversion if necessary.
3419 : : */
3420 : :
3421 : : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp);
3422 : :
3423 : : /*
3424 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
3425 : : If Sym is a right value and has type, type, then no quadruples are
3426 : : generated and Sym is returned. Otherwise a new temporary is created
3427 : : and an IndrX quadruple is generated.
3428 : : */
3429 : :
3430 : : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type);
3431 : :
3432 : : /*
3433 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
3434 : : symbol, Sym. No quadruple is generated if Sym is already
3435 : : a LeftValue and has the same type.
3436 : : */
3437 : :
3438 : : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type);
3439 : :
3440 : : /*
3441 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
3442 : : procedure. It dereferences all LeftValue parameters
3443 : : and Boolean parameters.
3444 : : The Stack:
3445 : :
3446 : :
3447 : : Entry Exit
3448 : :
3449 : : Ptr -> exactly the same
3450 : : +----------------+
3451 : : | NoOfParameters |
3452 : : |----------------|
3453 : : | Param 1 |
3454 : : |----------------|
3455 : : | Param 2 |
3456 : : |----------------|
3457 : : . .
3458 : : . .
3459 : : . .
3460 : : |----------------|
3461 : : | Param # |
3462 : : |----------------|
3463 : : | ProcSym | Type |
3464 : : |----------------|
3465 : :
3466 : : */
3467 : :
3468 : : static void ManipulatePseudoCallParameters (void);
3469 : :
3470 : : /*
3471 : : ManipulateParameters - manipulates the procedure parameters in
3472 : : preparation for a procedure call.
3473 : : Prepares Boolean, Unbounded and VAR parameters.
3474 : : The Stack:
3475 : :
3476 : :
3477 : : Entry Exit
3478 : :
3479 : : Ptr -> exactly the same
3480 : : +----------------+
3481 : : | NoOfParameters |
3482 : : |----------------|
3483 : : | Param 1 |
3484 : : |----------------|
3485 : : | Param 2 |
3486 : : |----------------|
3487 : : . .
3488 : : . .
3489 : : . .
3490 : : |----------------|
3491 : : | Param # |
3492 : : |----------------|
3493 : : | ProcSym | Type |
3494 : : |----------------|
3495 : : */
3496 : :
3497 : : static void ManipulateParameters (bool IsForC);
3498 : :
3499 : : /*
3500 : : CheckParameterOrdinals - check that ordinal values are within type range.
3501 : : */
3502 : :
3503 : : static void CheckParameterOrdinals (void);
3504 : :
3505 : : /*
3506 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
3507 : : are compatible.
3508 : : */
3509 : :
3510 : : static bool IsSameUnbounded (unsigned int t1, unsigned int t2);
3511 : :
3512 : : /*
3513 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
3514 : : ArrayAddress and ArrayHigh, from an array symbol.
3515 : : UnboundedSym is not a VAR parameter and therefore
3516 : : this procedure can complete both of the fields.
3517 : : Sym can be a Variable with type Unbounded.
3518 : : Sym can be a Variable with type Array.
3519 : : Sym can be a String Constant.
3520 : :
3521 : : ParamType is the TYPE of the parameter
3522 : : */
3523 : :
3524 : : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3525 : :
3526 : : /*
3527 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
3528 : : The difference between this procedure and
3529 : : AssignUnboundedVar is that this procedure cannot
3530 : : set the Unbounded.Address since the data from
3531 : : Sym will be copied because parameter is NOT a VAR
3532 : : parameter.
3533 : : UnboundedSym is not a VAR parameter and therefore
3534 : : this procedure can only complete the HIGH field
3535 : : and not the ADDRESS field.
3536 : : Sym can be a Variable with type Unbounded.
3537 : : Sym can be a Variable with type Array.
3538 : : Sym can be a String Constant.
3539 : :
3540 : : ParamType is the TYPE of the paramater
3541 : : */
3542 : :
3543 : : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3544 : :
3545 : : /*
3546 : : GenHigh - generates a HighOp but it checks if op3 is a
3547 : : L value and if so it dereferences it. This
3548 : : is inefficient, however it is clean and we let the gcc
3549 : : backend detect these as common subexpressions.
3550 : : It will also detect that a R value -> L value -> R value
3551 : : via indirection and eleminate these.
3552 : : */
3553 : :
3554 : : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3);
3555 : :
3556 : : /*
3557 : : AssignHighField -
3558 : : */
3559 : :
3560 : : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali);
3561 : :
3562 : : /*
3563 : : AssignHighFields -
3564 : : */
3565 : :
3566 : : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3567 : :
3568 : : /*
3569 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
3570 : : array, UnboundedSym. The parameter is a
3571 : : NON VAR variety.
3572 : : */
3573 : :
3574 : : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3575 : :
3576 : : /*
3577 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
3578 : : UnboundedSym. The parameter is a VAR variety.
3579 : : */
3580 : :
3581 : : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim);
3582 : :
3583 : : /*
3584 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
3585 : : This procedure does not directly alter the
3586 : : stack, but by calling routines the stack
3587 : : will change in the following way when this
3588 : : procedure returns.
3589 : :
3590 : : The Stack:
3591 : :
3592 : :
3593 : : Entry Exit
3594 : :
3595 : : Ptr ->
3596 : : +----------------+
3597 : : | NoOfParam |
3598 : : |----------------|
3599 : : | Param 1 |
3600 : : |----------------|
3601 : : | Param 2 |
3602 : : |----------------|
3603 : : . .
3604 : : . .
3605 : : . .
3606 : : |----------------|
3607 : : | Param # |
3608 : : |----------------|
3609 : : | ProcSym | Type | Empty
3610 : : |----------------|
3611 : : */
3612 : :
3613 : : static void BuildPseudoProcedureCall (unsigned int tokno);
3614 : :
3615 : : /*
3616 : : GetItemPointedTo - returns the symbol type that is being pointed to
3617 : : by Sym.
3618 : : */
3619 : :
3620 : : static unsigned int GetItemPointedTo (unsigned int Sym);
3621 : :
3622 : : /*
3623 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
3624 : : The Stack:
3625 : :
3626 : :
3627 : : Entry Exit
3628 : :
3629 : : Ptr ->
3630 : : +----------------+
3631 : : | NoOfParam |
3632 : : |----------------|
3633 : : | Param 1 |
3634 : : |----------------|
3635 : : | Param 2 |
3636 : : |----------------|
3637 : : . .
3638 : : . .
3639 : : . .
3640 : : |----------------|
3641 : : | Param # |
3642 : : |----------------|
3643 : : | ProcSym | Type | Empty
3644 : : |----------------|
3645 : : */
3646 : :
3647 : : static void BuildThrowProcedure (unsigned int functok);
3648 : :
3649 : : /*
3650 : : BuildNewProcedure - builds the pseudo procedure call NEW.
3651 : : This procedure is traditionally a "macro" for
3652 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
3653 : : One method of implementation is to emulate a "macro"
3654 : : processor by pushing the relevant input tokens
3655 : : back onto the input stack.
3656 : : However this causes two problems:
3657 : :
3658 : : (i) Unnecessary code is produced for x^
3659 : : (ii) SIZE must be imported from SYSTEM
3660 : : Therefore we chose an alternative method of
3661 : : implementation;
3662 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
3663 : : this, although slightly more efficient,
3664 : : is more complex and circumvents problems (i) and (ii).
3665 : :
3666 : : The Stack:
3667 : :
3668 : :
3669 : : Entry Exit
3670 : :
3671 : : Ptr ->
3672 : : +----------------+
3673 : : | NoOfParam |
3674 : : |----------------|
3675 : : | Param 1 |
3676 : : |----------------|
3677 : : | Param 2 |
3678 : : |----------------|
3679 : : . .
3680 : : . .
3681 : : . .
3682 : : |----------------|
3683 : : | Param # |
3684 : : |----------------|
3685 : : | ProcSym | Type | Empty
3686 : : |----------------|
3687 : : */
3688 : :
3689 : : static void BuildNewProcedure (unsigned int functok);
3690 : :
3691 : : /*
3692 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
3693 : : This procedure is traditionally a "macro" for
3694 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
3695 : : One method of implementation is to emulate a "macro"
3696 : : processor by pushing the relevant input tokens
3697 : : back onto the input stack.
3698 : : However this causes two problems:
3699 : :
3700 : : (i) Unnecessary code is produced for x^
3701 : : (ii) TSIZE must be imported from SYSTEM
3702 : : Therefore we chose an alternative method of
3703 : : implementation;
3704 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
3705 : : this, although slightly more efficient,
3706 : : is more complex and circumvents problems (i)
3707 : : and (ii).
3708 : :
3709 : : The Stack:
3710 : :
3711 : :
3712 : : Entry Exit
3713 : :
3714 : : Ptr ->
3715 : : +----------------+
3716 : : | NoOfParam |
3717 : : |----------------|
3718 : : | Param 1 |
3719 : : |----------------|
3720 : : | Param 2 |
3721 : : |----------------|
3722 : : . .
3723 : : . .
3724 : : . .
3725 : : |----------------|
3726 : : | Param # |
3727 : : |----------------|
3728 : : | ProcSym | Type | Empty
3729 : : |----------------|
3730 : : */
3731 : :
3732 : : static void BuildDisposeProcedure (unsigned int functok);
3733 : :
3734 : : /*
3735 : : CheckRangeIncDec - performs des := des <tok> expr
3736 : : with range checking (if enabled).
3737 : :
3738 : : Stack
3739 : : Entry Exit
3740 : :
3741 : : +------------+
3742 : : empty | des + expr |
3743 : : |------------|
3744 : : */
3745 : :
3746 : : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok);
3747 : :
3748 : : /*
3749 : : BuildIncProcedure - builds the pseudo procedure call INC.
3750 : : INC is a procedure which increments a variable.
3751 : : It takes one or two parameters:
3752 : : INC(a, b) or INC(a)
3753 : : a := a+b or a := a+1
3754 : :
3755 : : The Stack:
3756 : :
3757 : :
3758 : : Entry Exit
3759 : :
3760 : : Ptr ->
3761 : : +----------------+
3762 : : | NoOfParam |
3763 : : |----------------|
3764 : : | Param 1 |
3765 : : |----------------|
3766 : : | Param 2 |
3767 : : |----------------|
3768 : : . .
3769 : : . .
3770 : : . .
3771 : : |----------------|
3772 : : | Param # |
3773 : : |----------------|
3774 : : | ProcSym | Type | Empty
3775 : : |----------------|
3776 : : */
3777 : :
3778 : : static void BuildIncProcedure (unsigned int proctok);
3779 : :
3780 : : /*
3781 : : BuildDecProcedure - builds the pseudo procedure call DEC.
3782 : : DEC is a procedure which decrements a variable.
3783 : : It takes one or two parameters:
3784 : : DEC(a, b) or DEC(a)
3785 : : a := a-b or a := a-1
3786 : :
3787 : : The Stack:
3788 : :
3789 : :
3790 : : Entry Exit
3791 : :
3792 : : Ptr ->
3793 : : +----------------+
3794 : : | NoOfParam |
3795 : : |----------------|
3796 : : | Param 1 |
3797 : : |----------------|
3798 : : | Param 2 |
3799 : : |----------------|
3800 : : . .
3801 : : . .
3802 : : . .
3803 : : |----------------|
3804 : : | Param # |
3805 : : |----------------|
3806 : : | ProcSym | Type | Empty
3807 : : |----------------|
3808 : : */
3809 : :
3810 : : static void BuildDecProcedure (unsigned int proctok);
3811 : :
3812 : : /*
3813 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
3814 : : and if so it dereferences it.
3815 : : */
3816 : :
3817 : : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand);
3818 : :
3819 : : /*
3820 : : BuildInclProcedure - builds the pseudo procedure call INCL.
3821 : : INCL is a procedure which adds bit b into a BITSET a.
3822 : : It takes two parameters:
3823 : : INCL(a, b)
3824 : :
3825 : : a := a + {b}
3826 : :
3827 : : The Stack:
3828 : :
3829 : :
3830 : : Entry Exit
3831 : :
3832 : : Ptr ->
3833 : : +----------------+
3834 : : | NoOfParam |
3835 : : |----------------|
3836 : : | Param 1 |
3837 : : |----------------|
3838 : : | Param 2 |
3839 : : |----------------|
3840 : : | ProcSym | Type | Empty
3841 : : |----------------|
3842 : : */
3843 : :
3844 : : static void BuildInclProcedure (unsigned int proctok);
3845 : :
3846 : : /*
3847 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
3848 : : INCL is a procedure which removes bit b from SET a.
3849 : : It takes two parameters:
3850 : : EXCL(a, b)
3851 : :
3852 : : a := a - {b}
3853 : :
3854 : : The Stack:
3855 : :
3856 : :
3857 : : Entry Exit
3858 : :
3859 : : Ptr ->
3860 : : +----------------+
3861 : : | NoOfParam |
3862 : : |----------------|
3863 : : | Param 1 |
3864 : : |----------------|
3865 : : | Param 2 |
3866 : : |----------------|
3867 : : | ProcSym | Type | Empty
3868 : : |----------------|
3869 : : */
3870 : :
3871 : : static void BuildExclProcedure (unsigned int proctok);
3872 : :
3873 : : /*
3874 : : BuildTypeCoercion - builds the type coersion.
3875 : : Modula-2 allows types to be coersed with no runtime
3876 : : penility.
3877 : : It insists that the TSIZE(t1)=TSIZE(t2) where
3878 : : t2 variable := t2(variable of type t1).
3879 : : The ReturnVar on the stack is of type t2.
3880 : :
3881 : : The Stack:
3882 : :
3883 : :
3884 : : Entry Exit
3885 : :
3886 : : Ptr ->
3887 : : +----------------+
3888 : : | NoOfParam |
3889 : : |----------------|
3890 : : | Param 1 |
3891 : : |----------------|
3892 : : | Param 2 |
3893 : : |----------------|
3894 : : . .
3895 : : . .
3896 : : . .
3897 : : |----------------|
3898 : : | Param # | <- Ptr
3899 : : |----------------| +------------+
3900 : : | ProcSym | Type | | ReturnVar |
3901 : : |----------------| |------------|
3902 : :
3903 : : Quadruples:
3904 : :
3905 : : CoerceOp ReturnVar Type Param1
3906 : :
3907 : : A type coercion will only be legal if the different
3908 : : types have exactly the same size.
3909 : : Since we can only decide this after M2Eval has processed
3910 : : the symbol table then we create a quadruple explaining
3911 : : the coercion taking place, the code generator can test
3912 : : this assertion and report an error if the type sizes
3913 : : differ.
3914 : : */
3915 : :
3916 : : static void BuildTypeCoercion (bool ConstExpr);
3917 : :
3918 : : /*
3919 : : BuildRealFunctionCall - builds a function call.
3920 : : The Stack:
3921 : :
3922 : :
3923 : : Entry Exit
3924 : :
3925 : : Ptr ->
3926 : : +----------------+
3927 : : | NoOfParam |
3928 : : |----------------|
3929 : : | Param 1 |
3930 : : |----------------|
3931 : : | Param 2 |
3932 : : |----------------|
3933 : : . .
3934 : : . .
3935 : : . .
3936 : : |----------------|
3937 : : | Param # | <- Ptr
3938 : : |----------------| +------------+
3939 : : | ProcSym | Type | | ReturnVar |
3940 : : |----------------| |------------|
3941 : : */
3942 : :
3943 : : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr);
3944 : :
3945 : : /*
3946 : : BuildPseudoFunctionCall - builds the pseudo function
3947 : : The Stack:
3948 : :
3949 : :
3950 : : Entry Exit
3951 : :
3952 : : Ptr ->
3953 : : +----------------+
3954 : : | NoOfParam |
3955 : : |----------------|
3956 : : | Param 1 |
3957 : : |----------------|
3958 : : | Param 2 |
3959 : : |----------------|
3960 : : . .
3961 : : . .
3962 : : . .
3963 : : |----------------|
3964 : : | Param # | <- Ptr
3965 : : |----------------| +------------+
3966 : : | ProcSym | Type | | ReturnVar |
3967 : : |----------------| |------------|
3968 : :
3969 : : */
3970 : :
3971 : : static void BuildPseudoFunctionCall (bool ConstExpr);
3972 : :
3973 : : /*
3974 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
3975 : :
3976 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
3977 : :
3978 : : Which returns address given by (addr + offset),
3979 : : [ the standard says that it _may_
3980 : : "raise an exception if this address is not valid."
3981 : : currently we do not generate any exception code ]
3982 : :
3983 : : The Stack:
3984 : :
3985 : : Entry Exit
3986 : :
3987 : : Ptr ->
3988 : : +----------------+
3989 : : | NoOfParam |
3990 : : |----------------|
3991 : : | Param 1 |
3992 : : |----------------|
3993 : : | Param 2 | <- Ptr
3994 : : |----------------| +------------+
3995 : : | ProcSym | Type | | ReturnVar |
3996 : : |----------------| |------------|
3997 : : */
3998 : :
3999 : : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr);
4000 : :
4001 : : /*
4002 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
4003 : :
4004 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
4005 : :
4006 : : Which returns address given by (addr - offset),
4007 : : [ the standard says that it _may_
4008 : : "raise an exception if this address is not valid."
4009 : : currently we do not generate any exception code ]
4010 : :
4011 : : The Stack:
4012 : :
4013 : : Entry Exit
4014 : :
4015 : : Ptr ->
4016 : : +----------------+
4017 : : | NoOfParam |
4018 : : |----------------|
4019 : : | Param 1 |
4020 : : |----------------|
4021 : : | Param 2 | <- Ptr
4022 : : |----------------| +------------+
4023 : : | ProcSym | Type | | ReturnVar |
4024 : : |----------------| |------------|
4025 : : */
4026 : :
4027 : : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr);
4028 : :
4029 : : /*
4030 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
4031 : :
4032 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
4033 : :
4034 : : Which returns address given by (addr1 - addr2),
4035 : : [ the standard says that it _may_
4036 : : "raise an exception if this address is invalid or
4037 : : address space is non-contiguous."
4038 : : currently we do not generate any exception code ]
4039 : :
4040 : : The Stack:
4041 : :
4042 : : Entry Exit
4043 : :
4044 : : Ptr ->
4045 : : +----------------+
4046 : : | NoOfParam |
4047 : : |----------------|
4048 : : | Param 1 |
4049 : : |----------------|
4050 : : | Param 2 | <- Ptr
4051 : : |----------------| +------------+
4052 : : | ProcSym | Type | | ReturnVar |
4053 : : |----------------| |------------|
4054 : : */
4055 : :
4056 : : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr);
4057 : :
4058 : : /*
4059 : : BuildHighFunction - checks the stack in preparation for generating
4060 : : quadruples which perform HIGH.
4061 : : This procedure does not alter the stack but
4062 : : determines whether, a, in HIGH(a) is an ArraySym
4063 : : or UnboundedSym.
4064 : : Both cases are different and appropriate quadruple
4065 : : generating routines are called.
4066 : :
4067 : : The Stack:
4068 : :
4069 : :
4070 : : Entry Exit
4071 : :
4072 : : Ptr ->
4073 : : +----------------+
4074 : : | NoOfParam |
4075 : : |----------------|
4076 : : | Param 1 |
4077 : : |----------------|
4078 : : | Param 2 |
4079 : : |----------------|
4080 : : . .
4081 : : . .
4082 : : . .
4083 : : |----------------|
4084 : : | Param # | <- Ptr
4085 : : |----------------| +------------+
4086 : : | ProcSym | Type | | ReturnVar |
4087 : : |----------------| |------------|
4088 : :
4089 : : */
4090 : :
4091 : : static void BuildHighFunction (void);
4092 : :
4093 : : /*
4094 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
4095 : : Sym is a constant or an array which has constant bounds
4096 : : and therefore it can be calculated at compile time.
4097 : :
4098 : : The Stack:
4099 : :
4100 : :
4101 : : Entry Exit
4102 : :
4103 : : Ptr ->
4104 : : +----------------+
4105 : : | NoOfParam |
4106 : : |----------------|
4107 : : | Param 1 |
4108 : : |----------------|
4109 : : | Param 2 |
4110 : : |----------------|
4111 : : . .
4112 : : . .
4113 : : . .
4114 : : |----------------|
4115 : : | Param # | <- Ptr
4116 : : |----------------| +------------+
4117 : : | ProcSym | Type | | ReturnVar |
4118 : : |----------------| |------------|
4119 : : */
4120 : :
4121 : : static void BuildConstHighFromSym (unsigned int tok);
4122 : :
4123 : : /*
4124 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
4125 : : UnboundedSym.
4126 : :
4127 : : The Stack:
4128 : :
4129 : :
4130 : : Entry Exit
4131 : :
4132 : : Ptr ->
4133 : : +----------------+
4134 : : | NoOfParam |
4135 : : |----------------|
4136 : : | Param # | <- Ptr
4137 : : |----------------| +------------+
4138 : : | ProcSym | Type | | ReturnVar |
4139 : : |----------------| |------------|
4140 : :
4141 : : */
4142 : :
4143 : : static void BuildHighFromUnbounded (unsigned int tok);
4144 : :
4145 : : /*
4146 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
4147 : : This is used to reference runtime support procedures and an
4148 : : error is generated if the symbol cannot be obtained.
4149 : : */
4150 : :
4151 : : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module);
4152 : :
4153 : : /*
4154 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
4155 : : */
4156 : :
4157 : : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr);
4158 : :
4159 : : /*
4160 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
4161 : : */
4162 : :
4163 : : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym);
4164 : :
4165 : : /*
4166 : : BuildLengthFunction - builds the inline standard function LENGTH.
4167 : :
4168 : : The Stack:
4169 : :
4170 : :
4171 : : Entry Exit
4172 : :
4173 : : Ptr ->
4174 : : +----------------+
4175 : : | NoOfParam |
4176 : : |----------------|
4177 : : | Param 1 | <- Ptr
4178 : : |----------------| +------------+
4179 : : | ProcSym | Type | | ReturnVar |
4180 : : |----------------| |------------|
4181 : :
4182 : : */
4183 : :
4184 : : static void BuildLengthFunction (unsigned int Function, bool ConstExpr);
4185 : :
4186 : : /*
4187 : : BuildOddFunction - builds the pseudo procedure call ODD.
4188 : : This procedure is actually a "macro" for
4189 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
4190 : : However we cannot push tokens back onto the input stack
4191 : : because the compiler is currently building a function
4192 : : call and expecting a ReturnVar on the stack.
4193 : : Hence we manipulate the stack and call
4194 : : BuildConvertFunction.
4195 : :
4196 : : The Stack:
4197 : :
4198 : :
4199 : : Entry Exit
4200 : :
4201 : : Ptr ->
4202 : : +----------------+
4203 : : | NoOfParam |
4204 : : |----------------|
4205 : : | Param 1 |
4206 : : |----------------|
4207 : : | Param 2 |
4208 : : |----------------|
4209 : : . .
4210 : : . .
4211 : : . .
4212 : : |----------------|
4213 : : | Param # |
4214 : : |----------------|
4215 : : | ProcSym | Type | Empty
4216 : : |----------------|
4217 : : */
4218 : :
4219 : : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr);
4220 : :
4221 : : /*
4222 : : BuildAbsFunction - builds a call to the standard function ABS.
4223 : :
4224 : : We cannot implement it as a macro or inline an
4225 : : IF THEN statement as the IF THEN ELSE requires
4226 : : we write the value to the same variable (or constant)
4227 : : twice. The macro implementation will fail as
4228 : : the compiler maybe building a function
4229 : : call and expecting a ReturnVar on the stack.
4230 : : The only method to implement this is to pass it to the
4231 : : gcc backend.
4232 : :
4233 : : The Stack:
4234 : :
4235 : :
4236 : : Entry Exit
4237 : :
4238 : : Ptr ->
4239 : : +----------------+
4240 : : | NoOfParam |
4241 : : |----------------|
4242 : : | Param 1 |
4243 : : |----------------|
4244 : : | Param 2 |
4245 : : |----------------|
4246 : : . .
4247 : : . .
4248 : : . .
4249 : : |----------------|
4250 : : | Param # |
4251 : : |----------------|
4252 : : | ProcSym | Type | Empty
4253 : : |----------------|
4254 : : */
4255 : :
4256 : : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr);
4257 : :
4258 : : /*
4259 : : BuildCapFunction - builds the pseudo procedure call CAP.
4260 : : We generate a the following quad:
4261 : :
4262 : :
4263 : : StandardFunctionOp ReturnVal Cap Param1
4264 : :
4265 : : The Stack:
4266 : :
4267 : :
4268 : : Entry Exit
4269 : :
4270 : : Ptr ->
4271 : : +----------------+
4272 : : | NoOfParam = 1 |
4273 : : |----------------|
4274 : : | Param 1 |
4275 : : |----------------| +-------------+
4276 : : | ProcSym | Type | | ReturnVal |
4277 : : |----------------| |-------------|
4278 : : */
4279 : :
4280 : : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr);
4281 : :
4282 : : /*
4283 : : BuildChrFunction - builds the pseudo procedure call CHR.
4284 : : This procedure is actually a "macro" for
4285 : : CHR(x) --> CONVERT(CHAR, x)
4286 : : However we cannot push tokens back onto the input stack
4287 : : because the compiler is currently building a function
4288 : : call and expecting a ReturnVar on the stack.
4289 : : Hence we manipulate the stack and call
4290 : : BuildConvertFunction.
4291 : :
4292 : : The Stack:
4293 : :
4294 : :
4295 : : Entry Exit
4296 : :
4297 : : Ptr ->
4298 : : +----------------+
4299 : : | NoOfParam |
4300 : : |----------------|
4301 : : | Param 1 |
4302 : : |----------------|
4303 : : | Param 2 |
4304 : : |----------------|
4305 : : . .
4306 : : . .
4307 : : . .
4308 : : |----------------|
4309 : : | Param # |
4310 : : |----------------|
4311 : : | ProcSym | Type | Empty
4312 : : |----------------|
4313 : : */
4314 : :
4315 : : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr);
4316 : :
4317 : : /*
4318 : : BuildOrdFunction - builds the pseudo procedure call ORD.
4319 : : This procedure is actually a "macro" for
4320 : : ORD(x) --> CONVERT(GetSType(sym), x)
4321 : : However we cannot push tokens back onto the input stack
4322 : : because the compiler is currently building a function
4323 : : call and expecting a ReturnVar on the stack.
4324 : : Hence we manipulate the stack and call
4325 : : BuildConvertFunction.
4326 : :
4327 : : The Stack:
4328 : :
4329 : :
4330 : : Entry Exit
4331 : :
4332 : : Ptr ->
4333 : : +----------------+
4334 : : | NoOfParam |
4335 : : |----------------|
4336 : : | Param 1 |
4337 : : |----------------|
4338 : : | Param 2 |
4339 : : |----------------|
4340 : : . .
4341 : : . .
4342 : : . .
4343 : : |----------------|
4344 : : | Param # |
4345 : : |----------------|
4346 : : | ProcSym | Type | Empty
4347 : : |----------------|
4348 : : */
4349 : :
4350 : : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr);
4351 : :
4352 : : /*
4353 : : BuildIntFunction - builds the pseudo procedure call INT.
4354 : : This procedure is actually a "macro" for
4355 : : INT(x) --> CONVERT(INTEGER, x)
4356 : : However we cannot push tokens back onto the input stack
4357 : : because the compiler is currently building a function
4358 : : call and expecting a ReturnVar on the stack.
4359 : : Hence we manipulate the stack and call
4360 : : BuildConvertFunction.
4361 : :
4362 : : The Stack:
4363 : :
4364 : :
4365 : : Entry Exit
4366 : :
4367 : : Ptr ->
4368 : : +----------------+
4369 : : | NoOfParam |
4370 : : |----------------|
4371 : : | Param 1 |
4372 : : |----------------|
4373 : : | Param 2 |
4374 : : |----------------|
4375 : : . .
4376 : : . .
4377 : : . .
4378 : : |----------------|
4379 : : | Param # |
4380 : : |----------------|
4381 : : | ProcSym | Type | Empty
4382 : : |----------------|
4383 : : */
4384 : :
4385 : : static void BuildIntFunction (unsigned int Sym, bool ConstExpr);
4386 : :
4387 : : /*
4388 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
4389 : :
4390 : : The Stack:
4391 : :
4392 : :
4393 : : Entry Exit
4394 : :
4395 : : Ptr ->
4396 : : +----------------+
4397 : : | NoOfParam |
4398 : : |----------------|
4399 : : | Param 1 |
4400 : : |----------------|
4401 : : | Param 2 |
4402 : : |----------------|
4403 : : . .
4404 : : . .
4405 : : . .
4406 : : |----------------|
4407 : : | Param # |
4408 : : |----------------|
4409 : : | ProcSym | Type | Empty
4410 : : |----------------|
4411 : : */
4412 : :
4413 : : static void BuildMakeAdrFunction (void);
4414 : :
4415 : : /*
4416 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
4417 : :
4418 : : PROCEDURE SHIFT (val: <any type>;
4419 : : num: INTEGER): <any type> ;
4420 : :
4421 : : "Returns a bit sequence obtained from val by
4422 : : shifting up or down (left or right) by the
4423 : : absolute value of num, introducing
4424 : : zeros as necessary. The direction is down if
4425 : : the sign of num is negative, otherwise the
4426 : : direction is up."
4427 : :
4428 : : The Stack:
4429 : :
4430 : : Entry Exit
4431 : :
4432 : : Ptr ->
4433 : : +----------------+
4434 : : | NoOfParam |
4435 : : |----------------|
4436 : : | Param 1 |
4437 : : |----------------|
4438 : : | Param 2 | <- Ptr
4439 : : |----------------| +------------+
4440 : : | ProcSym | Type | | ReturnVar |
4441 : : |----------------| |------------|
4442 : : */
4443 : :
4444 : : static void BuildShiftFunction (void);
4445 : :
4446 : : /*
4447 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
4448 : :
4449 : : PROCEDURE ROTATE (val: <any type>;
4450 : : num: INTEGER): <any type> ;
4451 : :
4452 : : "Returns a bit sequence obtained from val
4453 : : by rotating up or down (left or right) by
4454 : : the absolute value of num. The direction is
4455 : : down if the sign of num is negative, otherwise
4456 : : the direction is up."
4457 : :
4458 : : The Stack:
4459 : :
4460 : : Entry Exit
4461 : :
4462 : : Ptr ->
4463 : : +----------------+
4464 : : | NoOfParam |
4465 : : |----------------|
4466 : : | Param 1 |
4467 : : |----------------|
4468 : : | Param 2 | <- Ptr
4469 : : |----------------| +------------+
4470 : : | ProcSym | Type | | ReturnVar |
4471 : : |----------------| |------------|
4472 : : */
4473 : :
4474 : : static void BuildRotateFunction (void);
4475 : :
4476 : : /*
4477 : : BuildValFunction - builds the pseudo procedure call VAL.
4478 : : This procedure is actually a "macro" for
4479 : : VAL(Type, x) --> CONVERT(Type, x)
4480 : : However we cannot push tokens back onto the input stack
4481 : : because the compiler is currently building a function
4482 : : call and expecting a ReturnVar on the stack.
4483 : : Hence we manipulate the stack and call
4484 : : BuildConvertFunction.
4485 : :
4486 : : The Stack:
4487 : :
4488 : :
4489 : : Entry Exit
4490 : :
4491 : : Ptr ->
4492 : : +----------------+
4493 : : | NoOfParam |
4494 : : |----------------|
4495 : : | Param 1 |
4496 : : |----------------|
4497 : : | Param 2 |
4498 : : |----------------|
4499 : : . .
4500 : : . .
4501 : : . .
4502 : : |----------------|
4503 : : | Param # |
4504 : : |----------------|
4505 : : | ProcSym | Type | Empty
4506 : : |----------------|
4507 : : */
4508 : :
4509 : : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr);
4510 : :
4511 : : /*
4512 : : BuildCastFunction - builds the pseudo procedure call CAST.
4513 : : This procedure is actually a "macro" for
4514 : : CAST(Type, x) --> Type(x)
4515 : : However we cannot push tokens back onto the input stack
4516 : : because the compiler is currently building a function
4517 : : call and expecting a ReturnVar on the stack.
4518 : : Hence we manipulate the stack and call
4519 : : BuildConvertFunction.
4520 : :
4521 : : The Stack:
4522 : :
4523 : :
4524 : : Entry Exit
4525 : :
4526 : : Ptr ->
4527 : : +----------------+
4528 : : | NoOfParam |
4529 : : |----------------|
4530 : : | Param 1 |
4531 : : |----------------|
4532 : : | Param 2 |
4533 : : |----------------|
4534 : : . .
4535 : : . .
4536 : : . .
4537 : : |----------------|
4538 : : | Param # |
4539 : : |----------------|
4540 : : | ProcSym | Type | Empty
4541 : : |----------------|
4542 : : */
4543 : :
4544 : : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr);
4545 : :
4546 : : /*
4547 : : BuildConvertFunction - builds the pseudo function CONVERT.
4548 : : CONVERT( Type, Variable ) ;
4549 : :
4550 : : The Stack:
4551 : :
4552 : :
4553 : : Entry Exit
4554 : :
4555 : : Ptr ->
4556 : : +----------------+
4557 : : | NoOfParam |
4558 : : |----------------|
4559 : : | Param 1 |
4560 : : |----------------|
4561 : : | Param 2 |
4562 : : |----------------|
4563 : : . .
4564 : : . .
4565 : : . .
4566 : : |----------------|
4567 : : | Param # | <- Ptr
4568 : : |----------------| +---------------------+
4569 : : | ProcSym | Type | | ReturnVar | Param1 |
4570 : : |----------------| |---------------------|
4571 : :
4572 : : Quadruples:
4573 : :
4574 : : ConvertOp ReturnVar Param1 Param2
4575 : :
4576 : : Converts variable Param2 into a variable Param1
4577 : : with a type Param1.
4578 : : */
4579 : :
4580 : : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr);
4581 : :
4582 : : /*
4583 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
4584 : : */
4585 : :
4586 : : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func);
4587 : :
4588 : : /*
4589 : : GetTypeMin - returns the minimium value of type and generate an error
4590 : : if this is unavailable.
4591 : : */
4592 : :
4593 : : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type);
4594 : :
4595 : : /*
4596 : : GetTypeMinLower - obtain the maximum value for type.
4597 : : */
4598 : :
4599 : : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type);
4600 : :
4601 : : /*
4602 : : GetTypeMax - returns the maximum value of type and generate an error
4603 : : if this is unavailable.
4604 : : */
4605 : :
4606 : : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type);
4607 : :
4608 : : /*
4609 : : GetTypeMaxLower - obtain the maximum value for type.
4610 : : */
4611 : :
4612 : : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type);
4613 : :
4614 : : /*
4615 : : BuildMinFunction - builds the pseudo function call Min.
4616 : :
4617 : : The Stack:
4618 : :
4619 : : Entry Exit
4620 : :
4621 : : Ptr ->
4622 : : +----------------+
4623 : : | NoOfParam=1 |
4624 : : |----------------|
4625 : : | Param 1 |
4626 : : |----------------|
4627 : : | ProcSym | Type | Empty
4628 : : |----------------|
4629 : : */
4630 : :
4631 : : static void BuildMinFunction (void);
4632 : :
4633 : : /*
4634 : : BuildMaxFunction - builds the pseudo function call Max.
4635 : :
4636 : : The Stack:
4637 : :
4638 : : Entry Exit
4639 : :
4640 : : Ptr ->
4641 : : +----------------+
4642 : : | NoOfParam=1 |
4643 : : |----------------|
4644 : : | Param 1 |
4645 : : |----------------|
4646 : : | ProcSym | Type | Empty
4647 : : |----------------|
4648 : : */
4649 : :
4650 : : static void BuildMaxFunction (void);
4651 : :
4652 : : /*
4653 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
4654 : : This procedure is actually a "macro" for
4655 : : TRUNC(x) --> CONVERT(INTEGER, x)
4656 : : However we cannot push tokens back onto the input stack
4657 : : because the compiler is currently building a function
4658 : : call and expecting a ReturnVar on the stack.
4659 : : Hence we manipulate the stack and call
4660 : : BuildConvertFunction.
4661 : :
4662 : : The Stack:
4663 : :
4664 : :
4665 : : Entry Exit
4666 : :
4667 : : Ptr ->
4668 : : +----------------+
4669 : : | NoOfParam |
4670 : : |----------------|
4671 : : | Param 1 |
4672 : : |----------------|
4673 : : | Param 2 |
4674 : : |----------------|
4675 : : . .
4676 : : . .
4677 : : . .
4678 : : |----------------|
4679 : : | Param # |
4680 : : |----------------|
4681 : : | ProcSym | Type | Empty
4682 : : |----------------|
4683 : : */
4684 : :
4685 : : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr);
4686 : :
4687 : : /*
4688 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
4689 : : This procedure is actually a "macro" for
4690 : : FLOAT(x) --> CONVERT(REAL, x)
4691 : : However we cannot push tokens back onto the input stack
4692 : : because the compiler is currently building a function
4693 : : call and expecting a ReturnVar on the stack.
4694 : : Hence we manipulate the stack and call
4695 : : BuildConvertFunction.
4696 : :
4697 : : The Stack:
4698 : :
4699 : :
4700 : : Entry Exit
4701 : :
4702 : : Ptr ->
4703 : : +----------------+
4704 : : | NoOfParam |
4705 : : |----------------|
4706 : : | Param 1 |
4707 : : |----------------|
4708 : : | Param 2 |
4709 : : |----------------|
4710 : : . .
4711 : : . .
4712 : : . .
4713 : : |----------------|
4714 : : | Param # |
4715 : : |----------------|
4716 : : | ProcSym | Type | Empty
4717 : : |----------------|
4718 : : */
4719 : :
4720 : : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr);
4721 : :
4722 : : /*
4723 : : BuildReFunction - builds the pseudo procedure call RE.
4724 : :
4725 : : The Stack:
4726 : :
4727 : :
4728 : : Entry Exit
4729 : :
4730 : : Ptr ->
4731 : : +----------------+
4732 : : | NoOfParam |
4733 : : |----------------|
4734 : : | Param 1 |
4735 : : |----------------|
4736 : : | Param 2 |
4737 : : |----------------|
4738 : : . .
4739 : : . .
4740 : : . .
4741 : : |----------------|
4742 : : | Param # |
4743 : : |----------------|
4744 : : | ProcSym | Type | Empty
4745 : : |----------------|
4746 : : */
4747 : :
4748 : : static void BuildReFunction (unsigned int Sym, bool ConstExpr);
4749 : :
4750 : : /*
4751 : : BuildImFunction - builds the pseudo procedure call IM.
4752 : :
4753 : : The Stack:
4754 : :
4755 : :
4756 : : Entry Exit
4757 : :
4758 : : Ptr ->
4759 : : +----------------+
4760 : : | NoOfParam |
4761 : : |----------------|
4762 : : | Param 1 |
4763 : : |----------------|
4764 : : | Param 2 |
4765 : : |----------------|
4766 : : . .
4767 : : . .
4768 : : . .
4769 : : |----------------|
4770 : : | Param # |
4771 : : |----------------|
4772 : : | ProcSym | Type | Empty
4773 : : |----------------|
4774 : : */
4775 : :
4776 : : static void BuildImFunction (unsigned int Sym, bool ConstExpr);
4777 : :
4778 : : /*
4779 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
4780 : :
4781 : : The Stack:
4782 : :
4783 : :
4784 : : Entry Exit
4785 : :
4786 : : Ptr ->
4787 : : +----------------+
4788 : : | NoOfParam |
4789 : : |----------------|
4790 : : | Param 1 |
4791 : : |----------------|
4792 : : | Param 2 |
4793 : : |----------------|
4794 : : . .
4795 : : . .
4796 : : . .
4797 : : |----------------|
4798 : : | Param # |
4799 : : |----------------|
4800 : : | ProcSym | Type | Empty
4801 : : |----------------|
4802 : : */
4803 : :
4804 : : static void BuildCmplxFunction (unsigned int func, bool ConstExpr);
4805 : :
4806 : : /*
4807 : : BuildAdrFunction - builds the pseudo function ADR
4808 : : The Stack:
4809 : :
4810 : :
4811 : : Entry Exit
4812 : :
4813 : : Ptr ->
4814 : : +----------------+
4815 : : | NoOfParam |
4816 : : |----------------|
4817 : : | Param 1 |
4818 : : |----------------|
4819 : : | Param 2 |
4820 : : |----------------|
4821 : : . .
4822 : : . .
4823 : : . .
4824 : : |----------------|
4825 : : | Param # | <- Ptr
4826 : : |----------------| +------------+
4827 : : | ProcSym | Type | | ReturnVar |
4828 : : |----------------| |------------|
4829 : :
4830 : : */
4831 : :
4832 : : static void BuildAdrFunction (void);
4833 : :
4834 : : /*
4835 : : BuildSizeFunction - builds the pseudo function SIZE
4836 : : The Stack:
4837 : :
4838 : :
4839 : : Entry Exit
4840 : :
4841 : : Ptr ->
4842 : : +----------------+
4843 : : | NoOfParam |
4844 : : |----------------|
4845 : : | Param 1 |
4846 : : |----------------|
4847 : : | Param 2 |
4848 : : |----------------|
4849 : : . .
4850 : : . .
4851 : : . .
4852 : : |----------------|
4853 : : | Param # | <- Ptr
4854 : : |----------------| +------------+
4855 : : | ProcSym | Type | | ReturnVar |
4856 : : |----------------| |------------|
4857 : : */
4858 : :
4859 : : static void BuildSizeFunction (void);
4860 : :
4861 : : /*
4862 : : BuildTSizeFunction - builds the pseudo function TSIZE
4863 : : The Stack:
4864 : :
4865 : :
4866 : : Entry Exit
4867 : :
4868 : : Ptr ->
4869 : : +----------------+
4870 : : | NoOfParam |
4871 : : |----------------|
4872 : : | Param 1 |
4873 : : |----------------|
4874 : : | Param 2 |
4875 : : |----------------|
4876 : : . .
4877 : : . .
4878 : : . .
4879 : : |----------------|
4880 : : | Param # | <- Ptr
4881 : : |----------------| +------------+
4882 : : | ProcSym | Type | | ReturnVar |
4883 : : |----------------| |------------|
4884 : :
4885 : : */
4886 : :
4887 : : static void BuildTSizeFunction (void);
4888 : :
4889 : : /*
4890 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
4891 : : The Stack:
4892 : :
4893 : :
4894 : : Entry Exit
4895 : :
4896 : : Ptr ->
4897 : : +----------------+
4898 : : | NoOfParam |
4899 : : |----------------|
4900 : : | Param 1 |
4901 : : |----------------|
4902 : : | Param 2 |
4903 : : |----------------|
4904 : : . .
4905 : : . .
4906 : : . .
4907 : : |----------------|
4908 : : | Param # | <- Ptr
4909 : : |----------------| +------------+
4910 : : | ProcSym | Type | | ReturnVar |
4911 : : |----------------| |------------|
4912 : :
4913 : : */
4914 : :
4915 : : static void BuildTBitSizeFunction (void);
4916 : :
4917 : : /*
4918 : : ExpectingParameterType -
4919 : : */
4920 : :
4921 : : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type);
4922 : :
4923 : : /*
4924 : : ExpectingVariableType -
4925 : : */
4926 : :
4927 : : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type);
4928 : :
4929 : : /*
4930 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
4931 : : parameters types and variable types which are legal.
4932 : : */
4933 : :
4934 : : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym);
4935 : :
4936 : : /*
4937 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
4938 : : between quadruples: Start..End
4939 : : */
4940 : :
4941 : : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End);
4942 : :
4943 : : /*
4944 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
4945 : : */
4946 : :
4947 : : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End);
4948 : :
4949 : : /*
4950 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
4951 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
4952 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
4953 : : to pass over, End, the condition is tested for global variables, procedure variables and
4954 : : constants.
4955 : :
4956 : : constant - ignored
4957 : : variables - tested to see whether they are altered inside the loop
4958 : : global variable - the procedure tests to see whether it is altered as above
4959 : : but will also test to see whether this loop calls a procedure
4960 : : in which case it believes the loop NOT to be infinite
4961 : : (as this procedure call might alter the global variable)
4962 : :
4963 : : Note that this procedure can easily be fooled by the user altering variables
4964 : : with pointers.
4965 : : */
4966 : :
4967 : : static bool IsInfiniteLoop (unsigned int End);
4968 : :
4969 : : /*
4970 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
4971 : : */
4972 : :
4973 : : static void CheckVariablesInBlock (unsigned int BlockSym);
4974 : :
4975 : : /*
4976 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
4977 : : */
4978 : :
4979 : : static void CheckFunctionReturn (unsigned int ProcSym);
4980 : :
4981 : : /*
4982 : : CheckReturnType - checks to see that the return type from currentProc is
4983 : : assignment compatible with actualType.
4984 : : */
4985 : :
4986 : : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType);
4987 : :
4988 : : /*
4989 : : BuildReturnLower - check the return type and value to ensure type
4990 : : compatibility and no range overflow will occur.
4991 : : */
4992 : :
4993 : : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1);
4994 : :
4995 : : /*
4996 : : IsReadOnly - a helper procedure function to detect constants.
4997 : : */
4998 : :
4999 : : static bool IsReadOnly (unsigned int sym);
5000 : :
5001 : : /*
5002 : : BuildDesignatorError - removes the designator from the stack and replaces
5003 : : it with an error symbol.
5004 : : */
5005 : :
5006 : : static void BuildDesignatorError (const char *message_, unsigned int _message_high);
5007 : :
5008 : : /*
5009 : : BuildDesignatorPointerError - removes the designator from the stack and replaces
5010 : : it with an error symbol.
5011 : : */
5012 : :
5013 : : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high);
5014 : :
5015 : : /*
5016 : : BuildDesignatorArrayStaticDynamic - Builds the array referencing.
5017 : : The purpose of this procedure is to work out
5018 : : whether the DesignatorArray is a static or
5019 : : dynamic array and to call the appropriate
5020 : : BuildRoutine.
5021 : :
5022 : : The Stack is expected to contain:
5023 : :
5024 : :
5025 : : Entry Exit
5026 : : ===== ====
5027 : :
5028 : : Ptr ->
5029 : : +--------------+
5030 : : | e | <- Ptr
5031 : : |--------------| +------------+
5032 : : | Sym | Type | | S | T |
5033 : : |--------------| |------------|
5034 : : */
5035 : :
5036 : : static void BuildDesignatorArrayStaticDynamic (void);
5037 : :
5038 : : /*
5039 : : BuildStaticArray - Builds the array referencing for static arrays.
5040 : : The Stack is expected to contain:
5041 : :
5042 : :
5043 : : Entry Exit
5044 : : ===== ====
5045 : :
5046 : : Ptr ->
5047 : : +--------------+
5048 : : | e | <- Ptr
5049 : : |--------------| +------------+
5050 : : | Sym | Type | | S | T |
5051 : : |--------------| |------------|
5052 : : */
5053 : :
5054 : : static void BuildStaticArray (void);
5055 : :
5056 : : /*
5057 : : calculateMultipicand - generates quadruples which calculate the
5058 : : multiplicand for the array at dimension, dim.
5059 : : */
5060 : :
5061 : : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim);
5062 : :
5063 : : /*
5064 : : ConvertToAddress - convert sym to an address.
5065 : : */
5066 : :
5067 : : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym);
5068 : :
5069 : : /*
5070 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
5071 : : The Stack is expected to contain:
5072 : :
5073 : :
5074 : : Entry Exit
5075 : : ===== ====
5076 : :
5077 : : Ptr ->
5078 : : +-----------------------+
5079 : : | Index | <- Ptr
5080 : : |-----------------------| +---------------------------+
5081 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
5082 : : |-----------------------| |---------------------------|
5083 : :
5084 : :
5085 : : if Dim=1
5086 : : then
5087 : : S := base of ArraySym + TSIZE(Type)*Index
5088 : : else
5089 : : S := S + TSIZE(Type)*Index
5090 : : fi
5091 : : */
5092 : :
5093 : : static void BuildDynamicArray (void);
5094 : :
5095 : : /*
5096 : : DebugLocation -
5097 : : */
5098 : :
5099 : : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high);
5100 : :
5101 : : /*
5102 : : PushWith - pushes sym and type onto the with stack. It checks for
5103 : : previous declaration of this record type.
5104 : : */
5105 : :
5106 : : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok);
5107 : : static void PopWith (void);
5108 : :
5109 : : /*
5110 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
5111 : : does not perform the address operation.
5112 : : The address will have been computed at the
5113 : : beginning of the WITH statement.
5114 : : It also stops the GenQuad procedure from examining the
5115 : : with stack.
5116 : :
5117 : : The Stack
5118 : :
5119 : : Entry
5120 : :
5121 : : Ptr ->
5122 : : +--------------+
5123 : : | Field | Type1| <- Ptr
5124 : : |-------|------| +-------------+
5125 : : | Adr | Type2| | Sym | Type1|
5126 : : |--------------| |-------------|
5127 : : */
5128 : :
5129 : : static void BuildAccessWithField (void);
5130 : :
5131 : : /*
5132 : : PushConstructor -
5133 : : */
5134 : :
5135 : : static void PushConstructor (unsigned int sym);
5136 : :
5137 : : /*
5138 : : AddFieldTo - adds field, e, to, value.
5139 : : */
5140 : :
5141 : : static unsigned int AddFieldTo (unsigned int value, unsigned int e);
5142 : :
5143 : : /*
5144 : : CheckLogicalOperator - returns a logical operator if the operands imply
5145 : : a logical operation should be performed.
5146 : : */
5147 : :
5148 : : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype);
5149 : :
5150 : : /*
5151 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
5152 : : expressions.
5153 : : */
5154 : :
5155 : : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e);
5156 : :
5157 : : /*
5158 : : doConvert - convert, sym, to a new symbol with, type.
5159 : : Return the new symbol.
5160 : : */
5161 : :
5162 : : static unsigned int doConvert (unsigned int type, unsigned int sym);
5163 : :
5164 : : /*
5165 : : doBuildBinaryOp - build the binary op, with or without type
5166 : : checking.
5167 : : */
5168 : :
5169 : : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow);
5170 : :
5171 : : /*
5172 : : AreConstant - returns immediate addressing mode if b is true else
5173 : : offset mode is returned. b determines whether the
5174 : : operands are all constant - in which case we can use
5175 : : a constant temporary variable.
5176 : : */
5177 : :
5178 : : static SymbolTable_ModeOfAddr AreConstant (bool b);
5179 : :
5180 : : /*
5181 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
5182 : : exit pair into a variable containing the value TRUE or
5183 : : FALSE. The parameter i is relative to the top
5184 : : of the stack.
5185 : : */
5186 : :
5187 : : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i);
5188 : :
5189 : : /*
5190 : : DumpQuadSummary -
5191 : : */
5192 : :
5193 : : static void DumpQuadSummary (unsigned int quad);
5194 : :
5195 : : /*
5196 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
5197 : : instead of using a temporary boolean variable.
5198 : : This function can only be used when we perform
5199 : : the following translation:
5200 : :
5201 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
5202 : : ^ ^
5203 : :
5204 : : it only allows # = to be used as >= <= > < all
5205 : : assume a particular value for TRUE and FALSE.
5206 : : (In which case the user should specify ORD)
5207 : :
5208 : :
5209 : : before
5210 : :
5211 : : q if r1 op1 op2 t2
5212 : : q+1 Goto f2
5213 : : ...
5214 : : q+n if r2 op3 op4 t1
5215 : : q+n+1 Goto f1
5216 : :
5217 : : after (in case of =)
5218 : :
5219 : : q if r1 op1 op2 q+2
5220 : : q+1 Goto q+4
5221 : : q+2 if r2 op3 op4 t
5222 : : q+3 Goto f
5223 : : q+4 if r2 op3 op4 f
5224 : : q+5 Goto t
5225 : :
5226 : : after (in case of #)
5227 : :
5228 : : q if r1 op1 op2 q+2
5229 : : q+1 Goto q+n+2
5230 : : q+2 ...
5231 : : ... ...
5232 : : q+n if r2 op3 op4 f
5233 : : q+n+1 Goto t
5234 : : q+n+2 if r2 op3 op4 t
5235 : : q+n+3 Goto f
5236 : :
5237 : : The Stack is expected to contain:
5238 : :
5239 : :
5240 : : Entry Exit
5241 : : ===== ====
5242 : :
5243 : : Ptr ->
5244 : : +------------+
5245 : : | t1 | f1 |
5246 : : |------------|
5247 : : | Operator | <- Ptr
5248 : : |------------| +------------+
5249 : : | t2 | f2 | | t | f |
5250 : : |------------| |------------|
5251 : :
5252 : :
5253 : : */
5254 : :
5255 : : static void BuildRelOpFromBoolean (unsigned int tokpos);
5256 : :
5257 : : /*
5258 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
5259 : : */
5260 : :
5261 : : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym);
5262 : :
5263 : : /*
5264 : : MakeOp - returns the equalent quadruple operator to a token, t.
5265 : : */
5266 : :
5267 : : static M2Quads_QuadOperator MakeOp (NameKey_Name t);
5268 : :
5269 : : /*
5270 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5271 : : */
5272 : :
5273 : : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow);
5274 : :
5275 : : /*
5276 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5277 : : */
5278 : :
5279 : : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash);
5280 : :
5281 : : /*
5282 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
5283 : : */
5284 : :
5285 : : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3);
5286 : :
5287 : : /*
5288 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
5289 : : */
5290 : :
5291 : : 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);
5292 : :
5293 : : /*
5294 : : GenQuadOTypetok - assigns the fields of the quadruple with
5295 : : the parameters.
5296 : : */
5297 : :
5298 : : 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);
5299 : :
5300 : : /*
5301 : : DumpUntil - dump all quadruples until we seen the ending quadruple
5302 : : with procsym in the third operand.
5303 : : Return the quad number containing the match.
5304 : : */
5305 : :
5306 : : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad);
5307 : :
5308 : : /*
5309 : : GetCtorInit - return the init procedure for the module.
5310 : : */
5311 : :
5312 : : static unsigned int GetCtorInit (unsigned int sym);
5313 : :
5314 : : /*
5315 : : GetCtorFini - return the fini procedure for the module.
5316 : : */
5317 : :
5318 : : static unsigned int GetCtorFini (unsigned int sym);
5319 : :
5320 : : /*
5321 : : DumpQuadrupleFilter -
5322 : : */
5323 : :
5324 : : static void DumpQuadrupleFilter (void);
5325 : :
5326 : : /*
5327 : : DumpQuadrupleAll - dump all quadruples.
5328 : : */
5329 : :
5330 : : static void DumpQuadrupleAll (void);
5331 : :
5332 : : /*
5333 : : BackPatch - Makes each of the quadruples on the list pointed to by
5334 : : QuadNo take quadruple Value as a target.
5335 : : */
5336 : :
5337 : : static void BackPatch (unsigned int QuadNo, unsigned int Value);
5338 : :
5339 : : /*
5340 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
5341 : : A QuadList of value zero is a nul list.
5342 : : */
5343 : :
5344 : : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2);
5345 : :
5346 : : /*
5347 : : DisplayProcedureAttributes -
5348 : : */
5349 : :
5350 : : static void DisplayProcedureAttributes (unsigned int proc);
5351 : :
5352 : : /*
5353 : : WriteQuad - Writes out the Quad BufferQuad.
5354 : : */
5355 : :
5356 : : static void WriteQuad (unsigned int BufferQuad);
5357 : :
5358 : : /*
5359 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
5360 : : */
5361 : :
5362 : : static void WriteMode (SymbolTable_ModeOfAddr Mode);
5363 : :
5364 : : /*
5365 : : PushExit - pushes the exit value onto the EXIT stack.
5366 : : */
5367 : :
5368 : : static void PushExit (unsigned int Exit);
5369 : :
5370 : : /*
5371 : : PopExit - pops the exit value from the EXIT stack.
5372 : : */
5373 : :
5374 : : static unsigned int PopExit (void);
5375 : :
5376 : : /*
5377 : : PushFor - pushes the exit value onto the FOR stack.
5378 : : */
5379 : :
5380 : : static void PushFor (unsigned int Exit);
5381 : :
5382 : : /*
5383 : : PopFor - pops the exit value from the FOR stack.
5384 : : */
5385 : :
5386 : : static unsigned int PopFor (void);
5387 : :
5388 : : /*
5389 : : OperandTno - returns the ident operand stored in the true position
5390 : : on the boolean stack. This is exactly the same as
5391 : : OperandT but it has no IsBoolean checking.
5392 : : */
5393 : :
5394 : : static unsigned int OperandTno (unsigned int pos);
5395 : :
5396 : : /*
5397 : : OperandFno - returns the ident operand stored in the false position
5398 : : on the boolean stack. This is exactly the same as
5399 : : OperandF but it has no IsBoolean checking.
5400 : : */
5401 : :
5402 : : static unsigned int OperandFno (unsigned int pos);
5403 : :
5404 : : /*
5405 : : OperandTtok - returns the token associated with the position, pos
5406 : : on the boolean stack.
5407 : : */
5408 : :
5409 : : static unsigned int OperandTtok (unsigned int pos);
5410 : :
5411 : : /*
5412 : : PopBooltok - Pops a True and a False exit quad number from the True/False
5413 : : stack.
5414 : : */
5415 : :
5416 : : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno);
5417 : :
5418 : : /*
5419 : : PushBooltok - Push a True and a False exit quad numbers onto the
5420 : : True/False stack.
5421 : : */
5422 : :
5423 : : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno);
5424 : :
5425 : : /*
5426 : : PopBool - Pops a True and a False exit quad number from the True/False
5427 : : stack.
5428 : : */
5429 : :
5430 : : static void PopBool (unsigned int *True, unsigned int *False);
5431 : :
5432 : : /*
5433 : : PushBool - Push a True and a False exit quad numbers onto the
5434 : : True/False stack.
5435 : : */
5436 : :
5437 : : static void PushBool (unsigned int True, unsigned int False);
5438 : :
5439 : : /*
5440 : : IsBoolean - returns true is the Stack position pos contains a Boolean
5441 : : Exit. False is returned if an Ident is stored.
5442 : : */
5443 : :
5444 : : static bool IsBoolean (unsigned int pos);
5445 : :
5446 : : /*
5447 : : OperandD - returns possible array dimension associated with the ident
5448 : : operand stored on the boolean stack.
5449 : : */
5450 : :
5451 : : static unsigned int OperandD (unsigned int pos);
5452 : :
5453 : : /*
5454 : : OperandRW - returns the rw operand stored on the boolean stack.
5455 : : */
5456 : :
5457 : : static unsigned int OperandRW (unsigned int pos);
5458 : :
5459 : : /*
5460 : : OperandMergeRW - returns the rw operand if not NulSym else it
5461 : : returns True.
5462 : : */
5463 : :
5464 : : static unsigned int OperandMergeRW (unsigned int pos);
5465 : :
5466 : : /*
5467 : : OperandRangeDep - return the range dependant associated with the quad stack.
5468 : : */
5469 : :
5470 : : static unsigned int OperandRangeDep (unsigned int pos);
5471 : :
5472 : : /*
5473 : : PutRangeDep - assigns the quad stack pos RangeDep to dep.
5474 : : */
5475 : :
5476 : : static void PutRangeDep (unsigned int pos, unsigned int dep);
5477 : :
5478 : : /*
5479 : : UseLineNote - uses the line note and returns it to the free list.
5480 : : */
5481 : :
5482 : : static void UseLineNote (M2Quads_LineNote l);
5483 : :
5484 : : /*
5485 : : PopLineNo - pops a line note from the line stack.
5486 : : */
5487 : :
5488 : : static M2Quads_LineNote PopLineNo (void);
5489 : :
5490 : : /*
5491 : : InitLineNote - creates a line note and initializes it to
5492 : : contain, file, line.
5493 : : */
5494 : :
5495 : : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line);
5496 : :
5497 : : /*
5498 : : PushLineNote -
5499 : : */
5500 : :
5501 : : static void PushLineNote (M2Quads_LineNote l);
5502 : :
5503 : : /*
5504 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
5505 : : */
5506 : :
5507 : : static void BuildStmtNoteTok (unsigned int tokenno);
5508 : :
5509 : : /*
5510 : : GetRecordOrField -
5511 : : */
5512 : :
5513 : : static unsigned int GetRecordOrField (void);
5514 : :
5515 : : /*
5516 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
5517 : : True/False stack. True and False are assumed to
5518 : : contain Symbols or Ident etc.
5519 : : */
5520 : :
5521 : : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim);
5522 : :
5523 : : /*
5524 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
5525 : : True/False stack. True and False are assumed to
5526 : : contain Symbols or Ident etc.
5527 : : */
5528 : :
5529 : : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno);
5530 : :
5531 : : /*
5532 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
5533 : : True/False stack. True and False are assumed to
5534 : : contain Symbols or Ident etc.
5535 : : */
5536 : :
5537 : : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok);
5538 : :
5539 : : /*
5540 : : PopTFrwtok - Pop a True and False number from the True/False stack.
5541 : : True and False are assumed to contain Symbols or Ident etc.
5542 : : */
5543 : :
5544 : : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno);
5545 : :
5546 : : /*
5547 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
5548 : : it is assummed to be a token and its token location is recorded.
5549 : : */
5550 : :
5551 : : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno);
5552 : :
5553 : : /*
5554 : : PushTFDtok - Push True, False, Dim, numbers onto the
5555 : : True/False stack. True and False are assumed to
5556 : : contain Symbols or Ident etc.
5557 : : */
5558 : :
5559 : : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok);
5560 : :
5561 : : /*
5562 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
5563 : : True and False are assumed to contain Symbols or Ident etc.
5564 : : */
5565 : :
5566 : : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok);
5567 : :
5568 : : /*
5569 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
5570 : : True/False stack. True and False are assumed to
5571 : : contain Symbols or Ident etc.
5572 : : */
5573 : :
5574 : : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok);
5575 : :
5576 : : /*
5577 : : PushTFrw - Push a True and False numbers onto the True/False stack.
5578 : : True and False are assumed to contain Symbols or Ident etc.
5579 : : It also pushes the higher level symbol which is associated
5580 : : with the True symbol. Eg record variable or array variable.
5581 : : */
5582 : :
5583 : : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw);
5584 : :
5585 : : /*
5586 : : PopTFrw - Pop a True and False number from the True/False stack.
5587 : : True and False are assumed to contain Symbols or Ident etc.
5588 : : */
5589 : :
5590 : : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw);
5591 : :
5592 : : /*
5593 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
5594 : : */
5595 : :
5596 : : static M2Quads_BoolFrame newBoolFrame (void);
5597 : :
5598 : : /*
5599 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
5600 : : */
5601 : :
5602 : : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok);
5603 : :
5604 : : /*
5605 : : PopTrw - Pop a True field and rw symbol from the stack.
5606 : : */
5607 : :
5608 : : static void PopTrw (unsigned int *True, unsigned int *rw);
5609 : :
5610 : : /*
5611 : : PopTrwtok - Pop a True field and rw symbol from the stack.
5612 : : */
5613 : :
5614 : : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok);
5615 : :
5616 : : /*
5617 : : gdbhook - a debugger convenience hook.
5618 : : */
5619 : :
5620 : : static void gdbhook (void);
5621 : :
5622 : : /*
5623 : : BreakWhenQuadCreated - to be called interactively by gdb.
5624 : : */
5625 : :
5626 : : static void BreakWhenQuadCreated (unsigned int quad);
5627 : :
5628 : : /*
5629 : : CheckBreak - if quad = BreakQuad then call gdbhook.
5630 : : */
5631 : :
5632 : : static void CheckBreak (unsigned int quad);
5633 : :
5634 : : /*
5635 : : Init - initialize the M2Quads module, all the stacks, all the lists
5636 : : and the quads list.
5637 : : */
5638 : :
5639 : : static void Init (void);
5640 : :
5641 : :
5642 : : /*
5643 : : DSdbEnter -
5644 : : */
5645 : :
5646 : 0 : static void DSdbEnter (void)
5647 : : {
5648 : 0 : }
5649 : :
5650 : :
5651 : : /*
5652 : : DSdbExit -
5653 : : */
5654 : :
5655 : 0 : static void DSdbExit (void)
5656 : : {
5657 : 0 : }
5658 : :
5659 : :
5660 : : /*
5661 : : GetQF - returns the QuadFrame associated with, q.
5662 : : */
5663 : :
5664 : 5984093069 : static M2Quads_QuadFrame GetQF (unsigned int q)
5665 : : {
5666 : 0 : return (M2Quads_QuadFrame) (Indexing_GetIndice (QuadArray, q));
5667 : : /* static analysis guarentees a RETURN statement will be used before here. */
5668 : : __builtin_unreachable ();
5669 : : }
5670 : :
5671 : :
5672 : : /*
5673 : : IsQuadA - returns true if QuadNo is a op.
5674 : : */
5675 : :
5676 : 655205322 : static bool IsQuadA (unsigned int QuadNo, M2Quads_QuadOperator op)
5677 : : {
5678 : 655205322 : M2Quads_QuadFrame f;
5679 : :
5680 : 0 : f = GetQF (QuadNo);
5681 : 655205322 : return f->Operator == op;
5682 : : /* static analysis guarentees a RETURN statement will be used before here. */
5683 : : __builtin_unreachable ();
5684 : : }
5685 : :
5686 : :
5687 : : /*
5688 : : OpUsesOp1 - return TRUE if op allows op1.
5689 : : */
5690 : :
5691 : 318370 : static bool OpUsesOp1 (M2Quads_QuadOperator op)
5692 : : {
5693 : 318370 : switch (op)
5694 : : {
5695 : : case M2Quads_StringConvertCnulOp:
5696 : : case M2Quads_StringConvertM2nulOp:
5697 : : case M2Quads_StringLengthOp:
5698 : : case M2Quads_InclOp:
5699 : : case M2Quads_ExclOp:
5700 : : case M2Quads_UnboundedOp:
5701 : : case M2Quads_FunctValueOp:
5702 : : case M2Quads_NegateOp:
5703 : : case M2Quads_BecomesOp:
5704 : : case M2Quads_HighOp:
5705 : : case M2Quads_SizeOp:
5706 : : case M2Quads_AddrOp:
5707 : : case M2Quads_RecordFieldOp:
5708 : : case M2Quads_ArrayOp:
5709 : : case M2Quads_LogicalShiftOp:
5710 : : case M2Quads_LogicalRotateOp:
5711 : : case M2Quads_LogicalOrOp:
5712 : : case M2Quads_LogicalAndOp:
5713 : : case M2Quads_LogicalXorOp:
5714 : : case M2Quads_CoerceOp:
5715 : : case M2Quads_ConvertOp:
5716 : : case M2Quads_CastOp:
5717 : : case M2Quads_AddOp:
5718 : : case M2Quads_SubOp:
5719 : : case M2Quads_MultOp:
5720 : : case M2Quads_ModFloorOp:
5721 : : case M2Quads_DivCeilOp:
5722 : : case M2Quads_ModCeilOp:
5723 : : case M2Quads_DivFloorOp:
5724 : : case M2Quads_ModTruncOp:
5725 : : case M2Quads_DivTruncOp:
5726 : : case M2Quads_DivM2Op:
5727 : : case M2Quads_ModM2Op:
5728 : : case M2Quads_XIndrOp:
5729 : : case M2Quads_IndrXOp:
5730 : : case M2Quads_SaveExceptionOp:
5731 : : case M2Quads_RestoreExceptionOp:
5732 : : return true;
5733 : 59140 : break;
5734 : :
5735 : :
5736 : 59140 : default:
5737 : 59140 : return false;
5738 : : break;
5739 : : }
5740 : : /* static analysis guarentees a RETURN statement will be used before here. */
5741 : : __builtin_unreachable ();
5742 : : }
5743 : :
5744 : :
5745 : : /*
5746 : : AddQuadInformation - adds variable analysis and jump analysis to the new quadruple.
5747 : : */
5748 : :
5749 : 5317580 : static void AddQuadInformation (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5750 : : {
5751 : 5317580 : switch (Op)
5752 : : {
5753 : 143663 : case M2Quads_IfInOp:
5754 : 143663 : case M2Quads_IfNotInOp:
5755 : 143663 : case M2Quads_IfEquOp:
5756 : 143663 : case M2Quads_IfNotEquOp:
5757 : 143663 : case M2Quads_IfLessOp:
5758 : 143663 : case M2Quads_IfLessEquOp:
5759 : 143663 : case M2Quads_IfGreOp:
5760 : 143663 : case M2Quads_IfGreEquOp:
5761 : 143663 : ManipulateReference (QuadNo, Oper3);
5762 : 143663 : CheckAddVariableRead (Oper1, false, QuadNo);
5763 : 143663 : CheckAddVariableRead (Oper2, false, QuadNo);
5764 : 143663 : break;
5765 : :
5766 : 2086 : case M2Quads_LastForIteratorOp:
5767 : 2086 : CheckAddVariableWrite (Oper1, false, QuadNo);
5768 : 2086 : CheckAddTuple2Read (Oper2, false, QuadNo);
5769 : 2086 : CheckAddVariableRead (Oper3, false, QuadNo);
5770 : 2086 : break;
5771 : :
5772 : 147928 : case M2Quads_TryOp:
5773 : 147928 : case M2Quads_RetryOp:
5774 : 147928 : case M2Quads_GotoOp:
5775 : 147928 : ManipulateReference (QuadNo, Oper3);
5776 : 147928 : break;
5777 : :
5778 : 1256 : case M2Quads_InclOp:
5779 : 1256 : case M2Quads_ExclOp:
5780 : : /* variable references */
5781 : 1256 : CheckConst (Oper1);
5782 : 1256 : CheckAddVariableRead (Oper3, false, QuadNo);
5783 : 1256 : CheckAddVariableWrite (Oper1, true, QuadNo);
5784 : 1256 : break;
5785 : :
5786 : 558780 : case M2Quads_UnboundedOp:
5787 : 558780 : case M2Quads_FunctValueOp:
5788 : 558780 : case M2Quads_NegateOp:
5789 : 558780 : case M2Quads_BecomesOp:
5790 : 558780 : case M2Quads_HighOp:
5791 : 558780 : case M2Quads_SizeOp:
5792 : 558780 : CheckConst (Oper1);
5793 : 558780 : CheckAddVariableWrite (Oper1, false, QuadNo);
5794 : 558780 : CheckAddVariableRead (Oper3, false, QuadNo);
5795 : 558780 : break;
5796 : :
5797 : 185341 : case M2Quads_AddrOp:
5798 : 185341 : CheckConst (Oper1);
5799 : 185341 : CheckAddVariableWrite (Oper1, false, QuadNo);
5800 : : /* the next line is a kludge and assumes we _will_
5801 : : write to the variable as we have taken its address */
5802 : 185341 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5803 : 185341 : break;
5804 : :
5805 : 19005 : case M2Quads_ReturnValueOp:
5806 : 19005 : CheckAddVariableRead (Oper1, false, QuadNo);
5807 : 19005 : break;
5808 : :
5809 : : case M2Quads_ReturnOp:
5810 : : case M2Quads_NewLocalVarOp:
5811 : : case M2Quads_KillLocalVarOp:
5812 : : break;
5813 : :
5814 : 187538 : case M2Quads_CallOp:
5815 : 187538 : CheckAddVariableRead (Oper3, true, QuadNo);
5816 : 187538 : break;
5817 : :
5818 : 533421 : case M2Quads_ParamOp:
5819 : 533421 : CheckAddVariableRead (Oper2, false, QuadNo);
5820 : 533421 : CheckAddVariableRead (Oper3, false, QuadNo);
5821 : 533421 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
5822 : : {
5823 : : /* _may_ also write to a var parameter, although we dont know */
5824 : 18282 : CheckAddVariableWrite (Oper3, true, QuadNo);
5825 : : }
5826 : : break;
5827 : :
5828 : 291888 : case M2Quads_RecordFieldOp:
5829 : 291888 : case M2Quads_ArrayOp:
5830 : 291888 : case M2Quads_LogicalShiftOp:
5831 : 291888 : case M2Quads_LogicalRotateOp:
5832 : 291888 : case M2Quads_LogicalOrOp:
5833 : 291888 : case M2Quads_LogicalAndOp:
5834 : 291888 : case M2Quads_LogicalXorOp:
5835 : 291888 : case M2Quads_CoerceOp:
5836 : 291888 : case M2Quads_ConvertOp:
5837 : 291888 : case M2Quads_CastOp:
5838 : 291888 : case M2Quads_AddOp:
5839 : 291888 : case M2Quads_SubOp:
5840 : 291888 : case M2Quads_MultOp:
5841 : 291888 : case M2Quads_DivM2Op:
5842 : 291888 : case M2Quads_ModM2Op:
5843 : 291888 : case M2Quads_ModFloorOp:
5844 : 291888 : case M2Quads_DivCeilOp:
5845 : 291888 : case M2Quads_ModCeilOp:
5846 : 291888 : case M2Quads_DivFloorOp:
5847 : 291888 : case M2Quads_ModTruncOp:
5848 : 291888 : case M2Quads_DivTruncOp:
5849 : 291888 : CheckConst (Oper1);
5850 : 291888 : CheckAddVariableWrite (Oper1, false, QuadNo);
5851 : 291888 : CheckAddVariableRead (Oper2, false, QuadNo);
5852 : 291888 : CheckAddVariableRead (Oper3, false, QuadNo);
5853 : 291888 : break;
5854 : :
5855 : 36352 : case M2Quads_XIndrOp:
5856 : 36352 : CheckConst (Oper1);
5857 : 36352 : CheckAddVariableWrite (Oper1, true, QuadNo);
5858 : 36352 : CheckAddVariableRead (Oper3, false, QuadNo);
5859 : 36352 : break;
5860 : :
5861 : 14883 : case M2Quads_IndrXOp:
5862 : 14883 : CheckConst (Oper1);
5863 : 14883 : CheckAddVariableWrite (Oper1, false, QuadNo);
5864 : 14883 : CheckAddVariableRead (Oper3, true, QuadNo);
5865 : 14883 : break;
5866 : :
5867 : 2814 : case M2Quads_SaveExceptionOp:
5868 : : /* RangeCheckOp : CheckRangeAddVariableRead(Oper3, QuadNo) | */
5869 : 2814 : CheckConst (Oper1);
5870 : 2814 : CheckAddVariableWrite (Oper1, false, QuadNo);
5871 : 2814 : break;
5872 : :
5873 : 2976 : case M2Quads_RestoreExceptionOp:
5874 : 2976 : CheckAddVariableRead (Oper1, false, QuadNo);
5875 : 2976 : break;
5876 : :
5877 : :
5878 : : default:
5879 : : break;
5880 : : }
5881 : 5317580 : }
5882 : :
5883 : :
5884 : : /*
5885 : : PutQuadO - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
5886 : : sets a boolean to determinine whether overflow should be checked.
5887 : : */
5888 : :
5889 : 4515438 : static void PutQuadO (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow)
5890 : : {
5891 : 0 : PutQuadOType (QuadNo, Op, Oper1, Oper2, Oper3, overflow, true);
5892 : 0 : }
5893 : :
5894 : :
5895 : : /*
5896 : : PutQuadOType -
5897 : : */
5898 : :
5899 : 5251629 : static void PutQuadOType (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3, bool overflow, bool checktype)
5900 : : {
5901 : 5251629 : M2Quads_QuadFrame f;
5902 : :
5903 : 5251629 : if (QuadrupleGeneration)
5904 : : {
5905 : 5251629 : M2Quads_EraseQuad (QuadNo);
5906 : 5251629 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
5907 : 5251629 : f = GetQF (QuadNo);
5908 : 5251629 : f->Operator = Op;
5909 : 5251629 : f->Operand1 = Oper1;
5910 : 5251629 : f->Operand2 = Oper2;
5911 : 5251629 : f->Operand3 = Oper3;
5912 : 5251629 : f->CheckOverflow = overflow;
5913 : 5251629 : f->CheckType = checktype;
5914 : 5251629 : f->ConstExpr = false; /* IsInConstExpression () */
5915 : : }
5916 : : /* IsInConstExpression () */
5917 : 5251629 : }
5918 : :
5919 : :
5920 : : /*
5921 : : UndoReadWriteInfo -
5922 : : */
5923 : :
5924 : 6886118 : static void UndoReadWriteInfo (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
5925 : : {
5926 : 6886118 : switch (Op)
5927 : : {
5928 : 77546 : case M2Quads_IfInOp:
5929 : 77546 : case M2Quads_IfNotInOp:
5930 : 77546 : case M2Quads_IfEquOp:
5931 : 77546 : case M2Quads_IfNotEquOp:
5932 : 77546 : case M2Quads_IfLessOp:
5933 : 77546 : case M2Quads_IfLessEquOp:
5934 : 77546 : case M2Quads_IfGreOp:
5935 : 77546 : case M2Quads_IfGreEquOp:
5936 : : /* jumps, calls and branches */
5937 : 77546 : RemoveReference (QuadNo);
5938 : 77546 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5939 : 77546 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5940 : 77546 : break;
5941 : :
5942 : 106717 : case M2Quads_TryOp:
5943 : 106717 : case M2Quads_RetryOp:
5944 : 106717 : case M2Quads_GotoOp:
5945 : 106717 : RemoveReference (QuadNo);
5946 : 106717 : break;
5947 : :
5948 : 0 : case M2Quads_InclOp:
5949 : 0 : case M2Quads_ExclOp:
5950 : : /* variable references */
5951 : 0 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5952 : 0 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5953 : 0 : break;
5954 : :
5955 : 276502 : case M2Quads_UnboundedOp:
5956 : 276502 : case M2Quads_FunctValueOp:
5957 : 276502 : case M2Quads_NegateOp:
5958 : 276502 : case M2Quads_BecomesOp:
5959 : 276502 : case M2Quads_HighOp:
5960 : 276502 : case M2Quads_SizeOp:
5961 : 276502 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5962 : 276502 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5963 : 276502 : break;
5964 : :
5965 : 842 : case M2Quads_AddrOp:
5966 : 842 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
5967 : : /* the next line is a kludge and assumes we _will_
5968 : : write to the variable as we have taken its address */
5969 : 842 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
5970 : 842 : break;
5971 : :
5972 : 72 : case M2Quads_ReturnValueOp:
5973 : 72 : CheckRemoveVariableRead (Oper1, false, QuadNo);
5974 : 72 : break;
5975 : :
5976 : : case M2Quads_ReturnOp:
5977 : : case M2Quads_CallOp:
5978 : : case M2Quads_NewLocalVarOp:
5979 : : case M2Quads_KillLocalVarOp:
5980 : : break;
5981 : :
5982 : 4870 : case M2Quads_ParamOp:
5983 : 4870 : CheckRemoveVariableRead (Oper2, false, QuadNo);
5984 : 4870 : CheckRemoveVariableRead (Oper3, false, QuadNo);
5985 : 4870 : if (((Oper1 > 0) && (Oper1 <= (SymbolTable_NoOfParamAny (Oper2)))) && (SymbolTable_IsVarParamAny (Oper2, Oper1)))
5986 : : {
5987 : : /* _may_ also write to a var parameter, although we dont know */
5988 : 88 : CheckRemoveVariableWrite (Oper3, true, QuadNo);
5989 : : }
5990 : : break;
5991 : :
5992 : 29006 : case M2Quads_RecordFieldOp:
5993 : 29006 : case M2Quads_ArrayOp:
5994 : 29006 : case M2Quads_LogicalShiftOp:
5995 : 29006 : case M2Quads_LogicalRotateOp:
5996 : 29006 : case M2Quads_LogicalOrOp:
5997 : 29006 : case M2Quads_LogicalAndOp:
5998 : 29006 : case M2Quads_LogicalXorOp:
5999 : 29006 : case M2Quads_CoerceOp:
6000 : 29006 : case M2Quads_ConvertOp:
6001 : 29006 : case M2Quads_CastOp:
6002 : 29006 : case M2Quads_AddOp:
6003 : 29006 : case M2Quads_SubOp:
6004 : 29006 : case M2Quads_MultOp:
6005 : 29006 : case M2Quads_DivM2Op:
6006 : 29006 : case M2Quads_ModM2Op:
6007 : 29006 : case M2Quads_ModFloorOp:
6008 : 29006 : case M2Quads_DivCeilOp:
6009 : 29006 : case M2Quads_ModCeilOp:
6010 : 29006 : case M2Quads_DivFloorOp:
6011 : 29006 : case M2Quads_ModTruncOp:
6012 : 29006 : case M2Quads_DivTruncOp:
6013 : 29006 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
6014 : 29006 : CheckRemoveVariableRead (Oper2, false, QuadNo);
6015 : 29006 : CheckRemoveVariableRead (Oper3, false, QuadNo);
6016 : 29006 : break;
6017 : :
6018 : 4 : case M2Quads_XIndrOp:
6019 : 4 : CheckRemoveVariableWrite (Oper1, true, QuadNo);
6020 : 4 : CheckRemoveVariableRead (Oper3, false, QuadNo);
6021 : 4 : break;
6022 : :
6023 : 366 : case M2Quads_IndrXOp:
6024 : 366 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
6025 : 366 : CheckRemoveVariableRead (Oper3, true, QuadNo);
6026 : 366 : break;
6027 : :
6028 : 0 : case M2Quads_SaveExceptionOp:
6029 : : /* RangeCheckOp : CheckRangeRemoveVariableRead(Oper3, QuadNo) | */
6030 : 0 : CheckRemoveVariableWrite (Oper1, false, QuadNo);
6031 : 0 : break;
6032 : :
6033 : 216 : case M2Quads_RestoreExceptionOp:
6034 : 216 : CheckRemoveVariableRead (Oper1, false, QuadNo);
6035 : 216 : break;
6036 : :
6037 : :
6038 : : default:
6039 : : break;
6040 : : }
6041 : 6886118 : }
6042 : :
6043 : :
6044 : : /*
6045 : : CheckAddTuple2Read - checks to see whether symbol tuple contains variables or
6046 : : parameters and if so it then adds them to the quadruple
6047 : : variable list.
6048 : : */
6049 : :
6050 : 2086 : static void CheckAddTuple2Read (unsigned int tuple, bool canDereference, unsigned int Quad)
6051 : : {
6052 : 2086 : if (SymbolTable_IsTuple (tuple))
6053 : : {
6054 : 2086 : CheckAddVariableRead (SymbolTable_GetNth (tuple, 1), canDereference, Quad);
6055 : 2086 : CheckAddVariableRead (SymbolTable_GetNth (tuple, 2), canDereference, Quad);
6056 : : }
6057 : 2086 : }
6058 : :
6059 : :
6060 : : /*
6061 : : CheckAddVariableRead - checks to see whether symbol, Sym, is a variable or
6062 : : a parameter and if so it then adds this quadruple
6063 : : to the variable list.
6064 : : */
6065 : :
6066 : 2764992 : static void CheckAddVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
6067 : : {
6068 : 2764992 : if (SymbolTable_IsVar (Sym))
6069 : : {
6070 : 994671 : SymbolTable_PutReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6071 : 994671 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6072 : : {
6073 : 14951 : SymbolTable_PutReadQuad (Sym, SymbolTable_RightValue, Quad);
6074 : : }
6075 : : }
6076 : 2764992 : }
6077 : :
6078 : :
6079 : : /*
6080 : : CheckRemoveVariableRead - checks to see whether, Sym, is a variable or
6081 : : a parameter and if so then it removes the
6082 : : quadruple from the variable list.
6083 : : */
6084 : :
6085 : 500004 : static void CheckRemoveVariableRead (unsigned int Sym, bool canDereference, unsigned int Quad)
6086 : : {
6087 : 500004 : if (SymbolTable_IsVar (Sym))
6088 : : {
6089 : 91510 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6090 : 91510 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6091 : : {
6092 : 366 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_RightValue, Quad);
6093 : : }
6094 : : }
6095 : 500004 : }
6096 : :
6097 : :
6098 : : /*
6099 : : CheckAddVariableWrite - checks to see whether symbol, Sym, is a variable and
6100 : : if so it then adds this quadruple to the variable list.
6101 : : */
6102 : :
6103 : 1111682 : static void CheckAddVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
6104 : : {
6105 : 1111682 : if (SymbolTable_IsVar (Sym))
6106 : : {
6107 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6108 : 810028 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6109 : : {
6110 : 50686 : SymbolTable_PutReadQuad (Sym, SymbolTable_LeftValue, Quad);
6111 : 50686 : SymbolTable_PutWriteQuad (Sym, SymbolTable_RightValue, Quad);
6112 : : }
6113 : : else
6114 : : {
6115 : 759342 : SymbolTable_PutWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6116 : : }
6117 : : }
6118 : 1111682 : }
6119 : :
6120 : :
6121 : : /*
6122 : : CheckRemoveVariableWrite - checks to see whether, Sym, is a variable and
6123 : : if so then it removes the quadruple from the
6124 : : variable list.
6125 : : */
6126 : :
6127 : 492991 : static void CheckRemoveVariableWrite (unsigned int Sym, bool canDereference, unsigned int Quad)
6128 : : {
6129 : 492991 : if (SymbolTable_IsVar (Sym))
6130 : : {
6131 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6132 : 192507 : if (((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue) && canDereference)
6133 : : {
6134 : 9468 : SymbolTable_RemoveReadQuad (Sym, SymbolTable_LeftValue, Quad);
6135 : 9468 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_RightValue, Quad);
6136 : : }
6137 : : else
6138 : : {
6139 : 183039 : SymbolTable_RemoveWriteQuad (Sym, SymbolTable_GetMode (Sym), Quad);
6140 : : }
6141 : : }
6142 : 492991 : }
6143 : :
6144 : :
6145 : : /*
6146 : : CheckConst -
6147 : : */
6148 : :
6149 : 1091314 : static void CheckConst (unsigned int sym)
6150 : : {
6151 : 1091314 : if (SymbolTable_IsConst (sym))
6152 : : {
6153 : 300080 : M2GCCDeclare_PutToBeSolvedByQuads (sym);
6154 : : }
6155 : 1091314 : }
6156 : :
6157 : :
6158 : : /*
6159 : : AlterReference - alters all references from OldQuad, to NewQuad in a
6160 : : quadruple list Head.
6161 : : */
6162 : :
6163 : 1568538 : static void AlterReference (unsigned int Head, unsigned int OldQuad, unsigned int NewQuad)
6164 : : {
6165 : 1568538 : M2Quads_QuadFrame f;
6166 : 1568538 : M2Quads_QuadFrame g;
6167 : 1568538 : unsigned int i;
6168 : :
6169 : 1568538 : f = GetQF (OldQuad);
6170 : 9977384 : while ((f->NoOfTimesReferenced > 0) && (Head != 0))
6171 : : {
6172 : 6840308 : g = GetQF (Head);
6173 : 6840308 : switch (g->Operator)
6174 : : {
6175 : 307498 : case M2Quads_IfInOp:
6176 : 307498 : case M2Quads_IfNotInOp:
6177 : 307498 : case M2Quads_IfEquOp:
6178 : 307498 : case M2Quads_IfNotEquOp:
6179 : 307498 : case M2Quads_IfLessOp:
6180 : 307498 : case M2Quads_IfLessEquOp:
6181 : 307498 : case M2Quads_IfGreOp:
6182 : 307498 : case M2Quads_IfGreEquOp:
6183 : 307498 : case M2Quads_TryOp:
6184 : 307498 : case M2Quads_RetryOp:
6185 : 307498 : case M2Quads_GotoOp:
6186 : 307498 : if (g->Operand3 == OldQuad)
6187 : : {
6188 : 8446 : ManipulateReference (Head, NewQuad);
6189 : : }
6190 : : break;
6191 : :
6192 : :
6193 : : default:
6194 : : break;
6195 : : }
6196 : 6840308 : i = g->Next;
6197 : 6840308 : Head = i;
6198 : : }
6199 : 1568538 : }
6200 : :
6201 : :
6202 : : /*
6203 : : GrowQuads - grows the list of quadruples to the quadruple, to.
6204 : : */
6205 : :
6206 : 516304 : static void GrowQuads (unsigned int to)
6207 : : {
6208 : 516304 : unsigned int i;
6209 : 516304 : M2Quads_QuadFrame f;
6210 : :
6211 : 516304 : if ((to != 0) && (to > GrowInitialization))
6212 : : {
6213 : 8928 : i = GrowInitialization+1;
6214 : 17856 : while (i <= to)
6215 : : {
6216 : 8928 : if (Indexing_InBounds (QuadArray, i))
6217 : : {
6218 : 0 : M2Debug_Assert ((Indexing_GetIndice (QuadArray, i)) != NULL);
6219 : : }
6220 : : else
6221 : : {
6222 : 8928 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6223 : 8928 : if (f == NULL)
6224 : : {
6225 : 0 : M2Error_InternalError ((const char *) "out of memory error when trying to allocate a quadruple", 55);
6226 : : }
6227 : 8928 : Indexing_PutIndice (QuadArray, i, reinterpret_cast <void *> (f));
6228 : 8928 : f->NoOfTimesReferenced = 0;
6229 : : }
6230 : 8928 : i += 1;
6231 : : }
6232 : 8928 : GrowInitialization = to;
6233 : : }
6234 : 516304 : }
6235 : :
6236 : :
6237 : : /*
6238 : : ManipulateReference - manipulates the quadruple, q, so that it now points to quad, to.
6239 : : */
6240 : :
6241 : 516304 : static void ManipulateReference (unsigned int q, unsigned int to)
6242 : : {
6243 : 516304 : M2Quads_QuadFrame f;
6244 : :
6245 : 1032608 : M2Debug_Assert ((GrowInitialization >= q) || (to == 0));
6246 : 516304 : GrowQuads (to);
6247 : 516304 : RemoveReference (q);
6248 : 516304 : f = GetQF (q);
6249 : 516304 : f->Operand3 = to;
6250 : 516304 : if (to != 0)
6251 : : {
6252 : 329183 : f = GetQF (to);
6253 : 329183 : f->NoOfTimesReferenced += 1;
6254 : : }
6255 : 516304 : }
6256 : :
6257 : :
6258 : : /*
6259 : : RemoveReference - remove the reference by quadruple q to wherever
6260 : : it was pointing.
6261 : : */
6262 : :
6263 : 700567 : static void RemoveReference (unsigned int q)
6264 : : {
6265 : 700567 : M2Quads_QuadFrame f;
6266 : 700567 : M2Quads_QuadFrame g;
6267 : :
6268 : 700567 : f = GetQF (q);
6269 : 700567 : if ((f->Operand3 != 0) && (f->Operand3 < NextQuad))
6270 : : {
6271 : 221855 : CheckBreak (f->Operand3);
6272 : 221855 : g = GetQF (f->Operand3);
6273 : 221855 : M2Debug_Assert (g->NoOfTimesReferenced != 0);
6274 : 221855 : g->NoOfTimesReferenced -= 1;
6275 : : }
6276 : 700567 : }
6277 : :
6278 : :
6279 : : /*
6280 : : NewQuad - sets QuadNo to a new quadruple.
6281 : : */
6282 : :
6283 : 5255684 : static void NewQuad (unsigned int *QuadNo)
6284 : : {
6285 : 5255684 : M2Quads_QuadFrame f;
6286 : :
6287 : 5255684 : (*QuadNo) = FreeList;
6288 : 5255684 : if ((Indexing_InBounds (QuadArray, (*QuadNo))) && ((Indexing_GetIndice (QuadArray, (*QuadNo))) != NULL))
6289 : : {
6290 : 8928 : f = static_cast<M2Quads_QuadFrame> (Indexing_GetIndice (QuadArray, (*QuadNo)));
6291 : : }
6292 : : else
6293 : : {
6294 : 5246756 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T3));
6295 : 5246756 : if (f == NULL)
6296 : : {
6297 : 0 : M2Error_InternalError ((const char *) "out of memory error trying to allocate a quadruple", 50);
6298 : : }
6299 : : else
6300 : : {
6301 : 5246756 : NoOfQuads += 1;
6302 : 5246756 : Indexing_PutIndice (QuadArray, (*QuadNo), reinterpret_cast <void *> (f));
6303 : 5246756 : f->NoOfTimesReferenced = 0;
6304 : : }
6305 : : }
6306 : 5255684 : f->Operator = M2Quads_DummyOp;
6307 : 5255684 : f->Operand3 = 0;
6308 : 5255684 : f->Next = 0;
6309 : 5255684 : FreeList += 1;
6310 : 5255684 : if (GrowInitialization < FreeList)
6311 : : {
6312 : 5246756 : GrowInitialization = FreeList;
6313 : : }
6314 : 5255684 : }
6315 : :
6316 : :
6317 : : /*
6318 : : CheckVariableAt - checks to see whether, sym, was declared at a particular address.
6319 : : */
6320 : :
6321 : 2665702 : static void CheckVariableAt (unsigned int sym)
6322 : : {
6323 : 2665702 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVariableAtAddress (sym)))
6324 : : {
6325 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6326 : 54 : if ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)
6327 : : {
6328 : 54 : GenQuad (M2Quads_InitAddressOp, sym, SymbolTable_NulSym, SymbolTable_GetVariableAtAddress (sym));
6329 : : }
6330 : : else
6331 : : {
6332 : 0 : M2Error_InternalError ((const char *) "expecting lvalue for this variable which is declared at an explicit address", 75);
6333 : : }
6334 : : }
6335 : 2665702 : }
6336 : :
6337 : :
6338 : : /*
6339 : : CheckVariablesAt - checks to see whether we need to initialize any pointers
6340 : : which point to variable declared at addresses.
6341 : : */
6342 : :
6343 : 137001 : static void CheckVariablesAt (unsigned int scope)
6344 : : {
6345 : 0 : SymbolTable_ForeachLocalSymDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) CheckVariableAt});
6346 : 0 : }
6347 : :
6348 : :
6349 : : /*
6350 : : GetTurnInterrupts - returns the TurnInterrupts procedure function.
6351 : : */
6352 : :
6353 : 840 : static unsigned int GetTurnInterrupts (unsigned int tok)
6354 : : {
6355 : 840 : if (M2Options_Iso)
6356 : : {
6357 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6358 : : }
6359 : : else
6360 : : {
6361 : 840 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "TurnInterrupts", 14), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6362 : : }
6363 : : /* static analysis guarentees a RETURN statement will be used before here. */
6364 : : __builtin_unreachable ();
6365 : : }
6366 : :
6367 : :
6368 : : /*
6369 : : GetProtection - returns the PROTECTION data type.
6370 : : */
6371 : :
6372 : 420 : static unsigned int GetProtection (unsigned int tok)
6373 : : {
6374 : 420 : if (M2Options_Iso)
6375 : : {
6376 : 0 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "COROUTINES", 10));
6377 : : }
6378 : : else
6379 : : {
6380 : 420 : return GetQualidentImport (tok, NameKey_MakeKey ((const char *) "PROTECTION", 10), NameKey_MakeKey ((const char *) "SYSTEM", 6));
6381 : : }
6382 : : /* static analysis guarentees a RETURN statement will be used before here. */
6383 : : __builtin_unreachable ();
6384 : : }
6385 : :
6386 : :
6387 : : /*
6388 : : CheckNeedPriorityBegin - checks to see whether we need to save the old
6389 : : module priority and change to another module
6390 : : priority.
6391 : : The current module initialization or procedure
6392 : : being built is defined by, scope. The module whose
6393 : : priority will be used is defined by, module.
6394 : : */
6395 : :
6396 : 152501 : static void CheckNeedPriorityBegin (unsigned int tok, unsigned int scope, unsigned int module)
6397 : : {
6398 : 152501 : unsigned int ProcSym;
6399 : 152501 : unsigned int old;
6400 : :
6401 : 152501 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6402 : : {
6403 : : /* module has been given a priority */
6404 : 420 : ProcSym = GetTurnInterrupts (tok);
6405 : 420 : if (ProcSym != SymbolTable_NulSym)
6406 : : {
6407 : 420 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6408 : 420 : SymbolTable_PutVar (old, GetProtection (tok));
6409 : 840 : GenQuadO (tok, M2Quads_SavePriorityOp, old, scope, ProcSym, false);
6410 : 420 : M2StackWord_PushWord (PriorityStack, old);
6411 : : }
6412 : : }
6413 : 152501 : }
6414 : :
6415 : :
6416 : : /*
6417 : : CheckNeedPriorityEnd - checks to see whether we need to restore the old
6418 : : module priority.
6419 : : The current module initialization or procedure
6420 : : being built is defined by, scope.
6421 : : */
6422 : :
6423 : 152332 : static void CheckNeedPriorityEnd (unsigned int tok, unsigned int scope, unsigned int module)
6424 : : {
6425 : 152332 : unsigned int ProcSym;
6426 : 152332 : unsigned int old;
6427 : :
6428 : 152332 : if ((SymbolTable_GetPriority (module)) != SymbolTable_NulSym)
6429 : : {
6430 : : /* module has been given a priority */
6431 : 420 : ProcSym = GetTurnInterrupts (tok);
6432 : 420 : if (ProcSym != SymbolTable_NulSym)
6433 : : {
6434 : 420 : old = static_cast<unsigned int> (M2StackWord_PopWord (PriorityStack));
6435 : 420 : GenQuad (M2Quads_RestorePriorityOp, old, scope, ProcSym);
6436 : : }
6437 : : }
6438 : 152332 : }
6439 : :
6440 : :
6441 : : /*
6442 : : BuildRTExceptEnter - informs RTExceptions that we are about to enter the except state.
6443 : : */
6444 : :
6445 : 2814 : static void BuildRTExceptEnter (unsigned int tok)
6446 : : {
6447 : 2814 : unsigned int old;
6448 : 2814 : unsigned int ProcSym;
6449 : :
6450 : 2814 : if (M2Options_Exceptions)
6451 : : {
6452 : : /* now inform the Modula-2 runtime we are in the exception state */
6453 : 2814 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6454 : 2814 : if (ProcSym == SymbolTable_NulSym)
6455 : : {
6456 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%W}no procedure SetExceptionState found in RTExceptions which is needed to implement exception handling", 104);
6457 : : }
6458 : : else
6459 : : {
6460 : 2814 : old = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
6461 : 2814 : SymbolTable_PutVar (old, M2Base_Boolean);
6462 : 5628 : GenQuadO (tok, M2Quads_SaveExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6463 : 2814 : M2StackWord_PushWord (ExceptStack, old);
6464 : : }
6465 : : }
6466 : : else
6467 : : {
6468 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}cannot use {%kEXCEPT} blocks with the -fno-exceptions flag", 62);
6469 : : }
6470 : 2814 : }
6471 : :
6472 : :
6473 : : /*
6474 : : BuildRTExceptLeave - informs RTExceptions that we are about to leave the except state.
6475 : : If, destroy, is TRUE then pop the ExceptStack.
6476 : : */
6477 : :
6478 : 2976 : static void BuildRTExceptLeave (unsigned int tok, bool destroy)
6479 : : {
6480 : 2976 : unsigned int old;
6481 : 2976 : unsigned int ProcSym;
6482 : :
6483 : 2976 : if (M2Options_Exceptions)
6484 : : {
6485 : : /* avoid dangling else. */
6486 : : /* now inform the Modula-2 runtime we are in the exception state */
6487 : 2976 : ProcSym = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "SetExceptionState", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6488 : 2976 : if (ProcSym != SymbolTable_NulSym)
6489 : : {
6490 : 2976 : if (destroy)
6491 : : {
6492 : 2814 : old = static_cast<unsigned int> (M2StackWord_PopWord (ExceptStack));
6493 : : }
6494 : : else
6495 : : {
6496 : 162 : old = static_cast<unsigned int> (M2StackWord_PeepWord (ExceptStack, 1));
6497 : : }
6498 : 2976 : GenQuadO (tok, M2Quads_RestoreExceptionOp, old, SymbolTable_NulSym, ProcSym, false);
6499 : : }
6500 : : }
6501 : : /* no need for an error message here as it will be generated in the Enter procedure above */
6502 : 2976 : }
6503 : :
6504 : :
6505 : : /*
6506 : : SafeRequestSym - only used during scaffold to get argc, argv, envp.
6507 : : It attempts to get symbol name from the current scope(s) and if
6508 : : it fails then it falls back onto default constants.
6509 : : */
6510 : :
6511 : 15552 : static unsigned int SafeRequestSym (unsigned int tok, NameKey_Name name)
6512 : : {
6513 : 15552 : unsigned int sym;
6514 : :
6515 : 15552 : sym = SymbolTable_GetSym (name);
6516 : 15552 : if (sym == SymbolTable_NulSym)
6517 : : {
6518 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
6519 : 0 : if (name == (NameKey_MakeKey ((const char *) "argc", 4)))
6520 : : {
6521 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
6522 : : }
6523 : 0 : else if ((name == (NameKey_MakeKey ((const char *) "argv", 4))) || (name == (NameKey_MakeKey ((const char *) "envp", 4))))
6524 : : {
6525 : : /* avoid dangling else. */
6526 : 0 : return M2Base_Nil;
6527 : : }
6528 : : else
6529 : : {
6530 : : /* avoid dangling else. */
6531 : 0 : M2Error_InternalError ((const char *) "not expecting this parameter name", 33);
6532 : : return M2Base_Nil;
6533 : : }
6534 : : }
6535 : : return sym;
6536 : : /* static analysis guarentees a RETURN statement will be used before here. */
6537 : : __builtin_unreachable ();
6538 : : }
6539 : :
6540 : :
6541 : : /*
6542 : : callRequestDependant - create a call:
6543 : : RequestDependant (GetSymName (modulesym), GetLibName (modulesym),
6544 : : GetSymName (depModuleSym), GetLibName (depModuleSym));
6545 : : */
6546 : :
6547 : 36934 : static void callRequestDependant (unsigned int tokno, unsigned int moduleSym, unsigned int depModuleSym, unsigned int requestDep)
6548 : : {
6549 : 36934 : M2Debug_Assert (requestDep != SymbolTable_NulSym);
6550 : 36934 : M2Quads_PushTtok (requestDep, tokno);
6551 : 36934 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6552 : 36934 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (moduleSym)), tokno);
6553 : 36934 : M2Quads_PushT (static_cast<unsigned int> (1));
6554 : 36934 : BuildAdrFunction ();
6555 : 36934 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6556 : 36934 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (moduleSym)), tokno);
6557 : 36934 : M2Quads_PushT (static_cast<unsigned int> (1));
6558 : 36934 : BuildAdrFunction ();
6559 : 36934 : if (depModuleSym == SymbolTable_NulSym)
6560 : : {
6561 : 15247 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6562 : 15247 : M2Quads_PushTF (M2Base_Nil, M2System_Address);
6563 : : }
6564 : : else
6565 : : {
6566 : 21687 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6567 : 21687 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetSymName (depModuleSym)), tokno);
6568 : 21687 : M2Quads_PushT (static_cast<unsigned int> (1));
6569 : 21687 : BuildAdrFunction ();
6570 : 21687 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tokno);
6571 : 21687 : M2Quads_PushTtok (SymbolTable_MakeConstString (tokno, SymbolTable_GetLibName (depModuleSym)), tokno);
6572 : 21687 : M2Quads_PushT (static_cast<unsigned int> (1));
6573 : 21687 : BuildAdrFunction ();
6574 : : }
6575 : 36934 : M2Quads_PushT (static_cast<unsigned int> (4));
6576 : 36934 : M2Quads_BuildProcedureCall (tokno);
6577 : 36934 : }
6578 : :
6579 : :
6580 : : /*
6581 : : ForeachImportInDepDo -
6582 : : */
6583 : :
6584 : 30494 : static void ForeachImportInDepDo (Lists_List importStatements, unsigned int moduleSym, unsigned int requestDep)
6585 : : {
6586 : 30494 : unsigned int i;
6587 : 30494 : unsigned int j;
6588 : 30494 : unsigned int m;
6589 : 30494 : unsigned int n;
6590 : 30494 : unsigned int imported;
6591 : 30494 : unsigned int stmt;
6592 : 30494 : Lists_List l;
6593 : :
6594 : 30494 : if (importStatements != NULL)
6595 : : {
6596 : 19156 : i = 1;
6597 : 19156 : n = Lists_NoOfItemsInList (importStatements);
6598 : 59505 : while (i <= n)
6599 : : {
6600 : 21193 : stmt = static_cast<unsigned int> (Lists_GetItemFromList (importStatements, i));
6601 : 21193 : M2Debug_Assert (SymbolTable_IsImportStatement (stmt));
6602 : 21193 : l = SymbolTable_GetImportStatementList (stmt);
6603 : 21193 : j = 1;
6604 : 21193 : m = Lists_NoOfItemsInList (l);
6605 : 64073 : while (j <= m)
6606 : : {
6607 : 21687 : imported = static_cast<unsigned int> (Lists_GetItemFromList (l, j));
6608 : 21687 : M2Debug_Assert (SymbolTable_IsImport (imported));
6609 : 21687 : callRequestDependant (SymbolTable_GetImportDeclared (imported), moduleSym, SymbolTable_GetImportModule (imported), requestDep);
6610 : 21687 : j += 1;
6611 : : }
6612 : 21193 : i += 1;
6613 : : }
6614 : : }
6615 : 30494 : }
6616 : :
6617 : :
6618 : : /*
6619 : : ForeachImportedModuleDo -
6620 : : */
6621 : :
6622 : 15247 : static void ForeachImportedModuleDo (unsigned int moduleSym, unsigned int requestDep)
6623 : : {
6624 : 15247 : Lists_List importStatements;
6625 : :
6626 : 15247 : importStatements = SymbolTable_GetModuleModImportStatementList (moduleSym);
6627 : 15247 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6628 : 15247 : importStatements = SymbolTable_GetModuleDefImportStatementList (moduleSym);
6629 : 15247 : ForeachImportInDepDo (importStatements, moduleSym, requestDep);
6630 : 15247 : }
6631 : :
6632 : :
6633 : : /*
6634 : : BuildM2DepFunction - creates the dependency graph procedure using IR:
6635 : : static void
6636 : : dependencies (void)
6637 : : {
6638 : : M2RTS_RequestDependant (module_name, libname, "b", "b libname");
6639 : : M2RTS_RequestDependant (module_name, libname, NULL, NULL);
6640 : : }
6641 : : */
6642 : :
6643 : 15291 : static void BuildM2DepFunction (unsigned int tokno, unsigned int moduleSym)
6644 : : {
6645 : 15291 : unsigned int requestDep;
6646 : 15291 : unsigned int ctor;
6647 : 15291 : unsigned int init;
6648 : 15291 : unsigned int fini;
6649 : 15291 : unsigned int dep;
6650 : :
6651 : 15291 : if (M2Options_ScaffoldDynamic)
6652 : : {
6653 : : /* Scaffold required and dynamic dependency graph should be produced. */
6654 : 15247 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6655 : 15247 : M2Quads_PushT (dep);
6656 : 15247 : M2Quads_BuildProcedureStart ();
6657 : 15247 : M2Quads_BuildProcedureBegin ();
6658 : 15247 : SymbolTable_StartScope (dep);
6659 : 15247 : requestDep = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "RequestDependant", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6660 : 15247 : if (requestDep != SymbolTable_NulSym)
6661 : : {
6662 : 15247 : ForeachImportedModuleDo (moduleSym, requestDep);
6663 : 15247 : callRequestDependant (tokno, moduleSym, SymbolTable_NulSym, requestDep);
6664 : : }
6665 : 15247 : SymbolTable_EndScope ();
6666 : 15247 : M2Quads_BuildProcedureEnd ();
6667 : 15247 : M2Quads_PopN (1);
6668 : : }
6669 : 15291 : }
6670 : :
6671 : :
6672 : : /*
6673 : : BuildM2LinkFunction - creates the _M2_link procedure which will
6674 : : cause the linker to pull in all the module ctors.
6675 : : */
6676 : :
6677 : 2628 : static void BuildM2LinkFunction (unsigned int tokno)
6678 : : {
6679 : 2628 : if (M2Options_ScaffoldDynamic)
6680 : : {
6681 : 2592 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6682 : : {
6683 : : /* void
6684 : : _M2_link (void)
6685 : : {
6686 : : for each module in uselist do
6687 : : PROC foo_%d = _M2_module_ctor
6688 : : done
6689 : : }. */
6690 : 2588 : M2Quads_PushT (M2Scaffold_linkFunction);
6691 : 2588 : M2Quads_BuildProcedureStart ();
6692 : 2588 : M2Quads_BuildProcedureBegin ();
6693 : 2588 : SymbolTable_StartScope (M2Scaffold_linkFunction);
6694 : 2588 : M2Scaffold_PopulateCtorArray (tokno);
6695 : 2588 : SymbolTable_EndScope ();
6696 : 2588 : M2Quads_BuildProcedureEnd ();
6697 : 2588 : M2Quads_PopN (1);
6698 : : }
6699 : : }
6700 : 2628 : }
6701 : :
6702 : :
6703 : : /*
6704 : : BuildTry - build the try statement for main.
6705 : : */
6706 : :
6707 : 2592 : static void BuildTry (unsigned int tokno)
6708 : : {
6709 : 2592 : if (M2Options_Exceptions)
6710 : : {
6711 : 2592 : M2StackWord_PushWord (TryStack, NextQuad);
6712 : 2592 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
6713 : 2592 : GenQuadO (tokno, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
6714 : : }
6715 : 2592 : }
6716 : :
6717 : :
6718 : : /*
6719 : : BuildExcept - build the except block for main.
6720 : : */
6721 : :
6722 : 2592 : static void BuildExcept (unsigned int tokno)
6723 : : {
6724 : 2592 : unsigned int catchProcedure;
6725 : :
6726 : 2592 : if (M2Options_Exceptions)
6727 : : {
6728 : 2592 : M2Quads_BuildExceptInitial (tokno);
6729 : 2592 : catchProcedure = GetQualidentImport (tokno, NameKey_MakeKey ((const char *) "DefaultErrorCatch", 17), NameKey_MakeKey ((const char *) "RTExceptions", 12));
6730 : 2592 : if (catchProcedure != SymbolTable_NulSym)
6731 : : {
6732 : 2592 : M2Quads_PushTtok (catchProcedure, tokno);
6733 : 2592 : M2Quads_PushT (static_cast<unsigned int> (0));
6734 : 2592 : M2Quads_BuildProcedureCall (tokno);
6735 : : }
6736 : 2592 : BuildRTExceptLeave (tokno, true);
6737 : 2592 : GenQuadO (tokno, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
6738 : : }
6739 : 2592 : }
6740 : :
6741 : :
6742 : : /*
6743 : : BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
6744 : : */
6745 : :
6746 : 2628 : static void BuildM2MainFunction (unsigned int tokno)
6747 : : {
6748 : 2628 : if ((M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic) && ! M2Options_SharedFlag)
6749 : : {
6750 : : /*
6751 : : int
6752 : : main (int argc, char *argv[], char *envp[])
6753 : : {
6754 : : try {
6755 : : _M2_init (argc, argv, envp);
6756 : : _M2_fini (argc, argv, envp);
6757 : : return 0;
6758 : : }
6759 : : catch (...) {
6760 : : RTExceptions_DefaultErrorCatch ();
6761 : : return 0;
6762 : : }
6763 : : }
6764 : : */
6765 : 2592 : M2Quads_PushT (M2Scaffold_mainFunction);
6766 : 2592 : M2Quads_BuildProcedureStart ();
6767 : 2592 : M2Quads_BuildProcedureBegin ();
6768 : 2592 : SymbolTable_StartScope (M2Scaffold_mainFunction);
6769 : 2592 : BuildTry (tokno);
6770 : : /* _M2_init (argc, argv, envp); */
6771 : 2592 : M2Quads_PushTtok (M2Scaffold_initFunction, tokno);
6772 : 2592 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6773 : 2592 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6774 : 2592 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6775 : 2592 : M2Quads_PushT (static_cast<unsigned int> (3));
6776 : 2592 : M2Quads_BuildProcedureCall (tokno);
6777 : : /* _M2_fini (argc, argv, envp); */
6778 : 2592 : M2Quads_PushTtok (M2Scaffold_finiFunction, tokno);
6779 : 2592 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argc", 4)), tokno);
6780 : 2592 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "argv", 4)), tokno);
6781 : 2592 : M2Quads_PushTtok (SymbolTable_RequestSym (tokno, NameKey_MakeKey ((const char *) "envp", 4)), tokno);
6782 : 2592 : M2Quads_PushT (static_cast<unsigned int> (3));
6783 : 2592 : M2Quads_BuildProcedureCall (tokno);
6784 : 2592 : PushZero (tokno, M2Base_Integer);
6785 : 2592 : M2Quads_BuildReturn (tokno);
6786 : 2592 : BuildExcept (tokno);
6787 : 2592 : PushZero (tokno, M2Base_Integer);
6788 : 2592 : M2Quads_BuildReturn (tokno);
6789 : 2592 : SymbolTable_EndScope ();
6790 : 2592 : M2Quads_BuildProcedureEnd ();
6791 : 2592 : M2Quads_PopN (1);
6792 : : }
6793 : 2628 : }
6794 : :
6795 : :
6796 : : /*
6797 : : DeferMakeConstStringCnul - return a C const string which will be nul terminated.
6798 : : */
6799 : :
6800 : 8001 : static unsigned int DeferMakeConstStringCnul (unsigned int tok, unsigned int sym)
6801 : : {
6802 : 8001 : unsigned int const_;
6803 : :
6804 : 8001 : const_ = SymbolTable_MakeConstStringCnul (tok, NameKey_NulName, false);
6805 : 16002 : GenQuadO (tok, M2Quads_StringConvertCnulOp, const_, 0, sym, false);
6806 : 8001 : return const_;
6807 : : /* static analysis guarentees a RETURN statement will be used before here. */
6808 : : __builtin_unreachable ();
6809 : : }
6810 : :
6811 : :
6812 : : /*
6813 : : DeferMakeConstStringM2nul - return a const string which will be nul terminated.
6814 : : */
6815 : :
6816 : 31647 : static unsigned int DeferMakeConstStringM2nul (unsigned int tok, unsigned int sym)
6817 : : {
6818 : 31647 : unsigned int const_;
6819 : :
6820 : 31647 : const_ = SymbolTable_MakeConstStringM2nul (tok, NameKey_NulName, false);
6821 : 63294 : GenQuadO (tok, M2Quads_StringConvertM2nulOp, const_, 0, sym, false);
6822 : 31647 : return const_;
6823 : : /* static analysis guarentees a RETURN statement will be used before here. */
6824 : : __builtin_unreachable ();
6825 : : }
6826 : :
6827 : :
6828 : : /*
6829 : : BuildStringAdrParam - push the address of a nul terminated string onto the quad stack.
6830 : : */
6831 : :
6832 : 7776 : static void BuildStringAdrParam (unsigned int tok, NameKey_Name name)
6833 : : {
6834 : 7776 : unsigned int str;
6835 : 7776 : unsigned int m2strnul;
6836 : :
6837 : 7776 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6838 : 7776 : str = SymbolTable_MakeConstString (tok, name);
6839 : 7776 : SymbolTable_PutConstStringKnown (tok, str, name, false, true);
6840 : 7776 : m2strnul = DeferMakeConstStringM2nul (tok, str);
6841 : 7776 : M2Quads_PushTtok (m2strnul, tok);
6842 : 7776 : M2Quads_PushT (static_cast<unsigned int> (1));
6843 : 7776 : BuildAdrFunction ();
6844 : 7776 : }
6845 : :
6846 : :
6847 : : /*
6848 : : BuildM2InitFunction -
6849 : : */
6850 : :
6851 : 2628 : static void BuildM2InitFunction (unsigned int tok, unsigned int moduleSym)
6852 : : {
6853 : 2628 : unsigned int constructModules;
6854 : :
6855 : 2628 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6856 : : {
6857 : : /* int
6858 : : _M2_init (int argc, char *argv[], char *envp[])
6859 : : {
6860 : : M2RTS_ConstructModules (module_name, libname,
6861 : : overrideliborder, argc, argv, envp);
6862 : : } */
6863 : 2592 : M2Quads_PushT (M2Scaffold_initFunction);
6864 : 2592 : M2Quads_BuildProcedureStart ();
6865 : 2592 : M2Quads_BuildProcedureBegin ();
6866 : 2592 : SymbolTable_StartScope (M2Scaffold_initFunction);
6867 : 2592 : if (M2Options_ScaffoldDynamic)
6868 : : {
6869 : : /* avoid dangling else. */
6870 : 2592 : if (M2Scaffold_linkFunction != SymbolTable_NulSym)
6871 : : {
6872 : : /* _M2_link (); */
6873 : 2588 : M2Quads_PushTtok (M2Scaffold_linkFunction, tok);
6874 : 2588 : M2Quads_PushT (static_cast<unsigned int> (0));
6875 : 2588 : M2Quads_BuildProcedureCall (tok);
6876 : : }
6877 : : /* Lookup ConstructModules and call it. */
6878 : 2592 : constructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "ConstructModules", 16), NameKey_MakeKey ((const char *) "M2RTS", 5));
6879 : 2592 : if (constructModules != SymbolTable_NulSym)
6880 : : {
6881 : : /* ConstructModules (module_name, argc, argv, envp); */
6882 : 2592 : M2Quads_PushTtok (constructModules, tok);
6883 : 2592 : BuildStringAdrParam (tok, SymbolTable_GetSymName (moduleSym));
6884 : 2592 : BuildStringAdrParam (tok, SymbolTable_GetLibName (moduleSym));
6885 : 2592 : BuildStringAdrParam (tok, NameKey_makekey (M2Options_GetRuntimeModuleOverride ()));
6886 : 2592 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6887 : 2592 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6888 : 2592 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6889 : 2592 : M2Quads_PushT (static_cast<unsigned int> (6));
6890 : 2592 : M2Quads_BuildProcedureCall (tok);
6891 : : }
6892 : : }
6893 : 0 : else if (M2Options_ScaffoldStatic)
6894 : : {
6895 : : /* avoid dangling else. */
6896 : 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)));
6897 : : }
6898 : 2592 : SymbolTable_EndScope ();
6899 : 2592 : M2Quads_BuildProcedureEnd ();
6900 : 2592 : M2Quads_PopN (1);
6901 : : }
6902 : 2628 : }
6903 : :
6904 : :
6905 : : /*
6906 : : BuildM2FiniFunction -
6907 : : */
6908 : :
6909 : 2628 : static void BuildM2FiniFunction (unsigned int tok, unsigned int moduleSym)
6910 : : {
6911 : 2628 : unsigned int deconstructModules;
6912 : :
6913 : 2628 : if (M2Options_ScaffoldDynamic || M2Options_ScaffoldStatic)
6914 : : {
6915 : : /* Scaffold required and main should be produced. */
6916 : 2592 : M2Quads_PushT (M2Scaffold_finiFunction);
6917 : 2592 : M2Quads_BuildProcedureStart ();
6918 : 2592 : M2Quads_BuildProcedureBegin ();
6919 : 2592 : SymbolTable_StartScope (M2Scaffold_finiFunction);
6920 : 2592 : if (M2Options_ScaffoldDynamic)
6921 : : {
6922 : : /* avoid dangling else. */
6923 : : /* static void
6924 : : _M2_finish (int argc, char *argv[], char *envp[])
6925 : : {
6926 : : M2RTS_DeconstructModules (module_name, argc, argv, envp);
6927 : : } */
6928 : 2592 : deconstructModules = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "DeconstructModules", 18), NameKey_MakeKey ((const char *) "M2RTS", 5));
6929 : 2592 : if (deconstructModules != SymbolTable_NulSym)
6930 : : {
6931 : : /* DeconstructModules (module_name, argc, argv, envp); */
6932 : 2592 : M2Quads_PushTtok (deconstructModules, tok);
6933 : 2592 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6934 : 2592 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6935 : 2592 : M2Quads_PushT (static_cast<unsigned int> (1));
6936 : 2592 : BuildAdrFunction ();
6937 : 2592 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6938 : 2592 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
6939 : 2592 : M2Quads_PushT (static_cast<unsigned int> (1));
6940 : 2592 : BuildAdrFunction ();
6941 : 2592 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argc", 4)), tok);
6942 : 2592 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "argv", 4)), tok);
6943 : 2592 : M2Quads_PushTtok (SafeRequestSym (tok, NameKey_MakeKey ((const char *) "envp", 4)), tok);
6944 : 2592 : M2Quads_PushT (static_cast<unsigned int> (5));
6945 : 2592 : M2Quads_BuildProcedureCall (tok);
6946 : : }
6947 : : }
6948 : 0 : else if (M2Options_ScaffoldStatic)
6949 : : {
6950 : : /* avoid dangling else. */
6951 : 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)));
6952 : : }
6953 : 2592 : SymbolTable_EndScope ();
6954 : 2592 : M2Quads_BuildProcedureEnd ();
6955 : 2592 : M2Quads_PopN (1);
6956 : : }
6957 : 2628 : }
6958 : :
6959 : :
6960 : : /*
6961 : : BuildM2CtorFunction - create a constructor function associated with moduleSym.
6962 : :
6963 : : void
6964 : : ctorFunction ()
6965 : : {
6966 : : M2RTS_RegisterModule (GetSymName (moduleSym), GetLibName (moduleSym),
6967 : : init, fini, dependencies);
6968 : : }
6969 : : */
6970 : :
6971 : 15291 : static void BuildM2CtorFunction (unsigned int tok, unsigned int moduleSym)
6972 : : {
6973 : 15291 : unsigned int RegisterModule;
6974 : 15291 : unsigned int ctor;
6975 : 15291 : unsigned int init;
6976 : 15291 : unsigned int fini;
6977 : 15291 : unsigned int dep;
6978 : :
6979 : 15291 : if (M2Options_ScaffoldDynamic)
6980 : : {
6981 : 15247 : SymbolTable_GetModuleCtors (moduleSym, &ctor, &init, &fini, &dep);
6982 : 15247 : if (ctor != SymbolTable_NulSym)
6983 : : {
6984 : 15247 : M2Debug_Assert (SymbolTable_IsProcedure (ctor));
6985 : 15247 : M2Quads_PushT (ctor);
6986 : 15247 : M2Quads_BuildProcedureStart ();
6987 : 15247 : M2Quads_BuildProcedureBegin ();
6988 : 15247 : SymbolTable_StartScope (ctor);
6989 : 15247 : RegisterModule = GetQualidentImport (tok, NameKey_MakeKey ((const char *) "RegisterModule", 14), NameKey_MakeKey ((const char *) "M2RTS", 5));
6990 : 15247 : if (RegisterModule != SymbolTable_NulSym)
6991 : : {
6992 : : /* RegisterModule (module_name, init, fini, dependencies); */
6993 : 15247 : M2Quads_PushTtok (RegisterModule, tok);
6994 : 15247 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6995 : 15247 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetSymName (moduleSym)), tok);
6996 : 15247 : M2Quads_PushT (static_cast<unsigned int> (1));
6997 : 15247 : BuildAdrFunction ();
6998 : 15247 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok);
6999 : 15247 : M2Quads_PushTtok (SymbolTable_MakeConstString (tok, SymbolTable_GetLibName (moduleSym)), tok);
7000 : 15247 : M2Quads_PushT (static_cast<unsigned int> (1));
7001 : 15247 : BuildAdrFunction ();
7002 : 15247 : M2Quads_PushTtok (init, tok);
7003 : 15247 : M2Quads_PushTtok (fini, tok);
7004 : 15247 : M2Quads_PushTtok (dep, tok);
7005 : 15247 : M2Quads_PushT (static_cast<unsigned int> (5));
7006 : 15247 : M2Quads_BuildProcedureCall (tok);
7007 : : }
7008 : 15247 : SymbolTable_EndScope ();
7009 : 15247 : M2Quads_BuildProcedureEnd ();
7010 : 15247 : M2Quads_PopN (1);
7011 : : }
7012 : : }
7013 : 15291 : }
7014 : :
7015 : :
7016 : : /*
7017 : : AddForInfo - adds the description of the FOR loop into the record list.
7018 : : This is used if -pedantic is turned on to check index variable
7019 : : usage.
7020 : : */
7021 : :
7022 : 2104 : static void AddForInfo (unsigned int Start, unsigned int End, unsigned int IncQuad, unsigned int Sym, unsigned int idtok)
7023 : : {
7024 : 2104 : M2Quads_ForLoopInfo forDesc;
7025 : :
7026 : 2104 : if (M2Options_Pedantic)
7027 : : {
7028 : 0 : Storage_ALLOCATE ((void **) &forDesc, sizeof (M2Quads__T5));
7029 : 0 : forDesc->IncrementQuad = IncQuad;
7030 : 0 : forDesc->StartOfForLoop = Start;
7031 : 0 : forDesc->EndOfForLoop = End;
7032 : 0 : forDesc->ForLoopIndex = Sym;
7033 : 0 : forDesc->IndexTok = idtok;
7034 : 0 : Indexing_IncludeIndiceIntoIndex (ForInfo, reinterpret_cast <void *> (forDesc));
7035 : : }
7036 : 2104 : }
7037 : :
7038 : :
7039 : : /*
7040 : : CheckForIndex - checks the quadruples: Start..End to see whether a
7041 : : for loop index is manipulated by the programmer.
7042 : : It generates a warning if this is the case.
7043 : : It also checks to see whether the IndexSym is read
7044 : : immediately outside the loop in which case a warning
7045 : : is issued.
7046 : : */
7047 : :
7048 : 0 : static void CheckForIndex (M2Quads_ForLoopInfo forDesc)
7049 : : {
7050 : 0 : unsigned int ReadStart;
7051 : 0 : unsigned int ReadEnd;
7052 : 0 : unsigned int WriteStart;
7053 : 0 : unsigned int WriteEnd;
7054 : :
7055 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->StartOfForLoop, forDesc->EndOfForLoop, &WriteStart, &WriteEnd);
7056 : 0 : if ((WriteStart < forDesc->IncrementQuad) && (WriteStart > forDesc->StartOfForLoop))
7057 : : {
7058 : 0 : M2MetaError_MetaErrorT1 (forDesc->IndexTok, (const char *) "{%kFOR} loop index variable {%1Wad} is being manipulated inside the loop", 72, forDesc->ForLoopIndex);
7059 : 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);
7060 : : }
7061 : 0 : SymbolTable_GetWriteLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &WriteStart, &WriteEnd);
7062 : 0 : SymbolTable_GetReadLimitQuads (forDesc->ForLoopIndex, SymbolTable_RightValue, forDesc->EndOfForLoop, 0, &ReadStart, &ReadEnd);
7063 : 0 : if ((ReadStart != 0) && ((ReadStart < WriteStart) || (WriteStart == 0)))
7064 : : {
7065 : 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);
7066 : 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);
7067 : : }
7068 : 0 : }
7069 : :
7070 : :
7071 : : /*
7072 : : BuildRange - generates a RangeCheckOp quad with, r, as its operand.
7073 : : */
7074 : :
7075 : 1756868 : static void BuildRange (unsigned int r)
7076 : : {
7077 : 1756868 : GenQuad (M2Quads_RangeCheckOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
7078 : 1756868 : }
7079 : :
7080 : :
7081 : : /*
7082 : : BuildError - generates a ErrorOp quad, indicating that if this
7083 : : quadruple is reachable, then a runtime error would
7084 : : occur.
7085 : : */
7086 : :
7087 : 12581 : static void BuildError (unsigned int r)
7088 : : {
7089 : 12581 : GenQuad (M2Quads_ErrorOp, (unsigned int ) (M2LexBuf_GetLineNo ()), SymbolTable_NulSym, r);
7090 : 12581 : }
7091 : :
7092 : :
7093 : : /*
7094 : : CheckPointerThroughNil - builds a range quadruple, providing, sym, is
7095 : : a candidate for checking against NIL.
7096 : : This range quadruple is only expanded into
7097 : : code during the code generation phase
7098 : : thus allowing limited compile time checking.
7099 : : */
7100 : :
7101 : 64741 : static void CheckPointerThroughNil (unsigned int tokpos, unsigned int sym)
7102 : : {
7103 : 64741 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_GetVarPointerCheck (sym)))
7104 : : {
7105 : : /* PutVarPointerCheck(sym, FALSE) ; so we do not detect this again */
7106 : 17262 : BuildRange (M2Range_InitPointerRangeCheck (tokpos, sym, (SymbolTable_GetMode (sym)) == SymbolTable_LeftValue));
7107 : : }
7108 : 64741 : }
7109 : :
7110 : :
7111 : : /*
7112 : : CollectLow - returns the low of the subrange value.
7113 : : */
7114 : :
7115 : 234 : static unsigned int CollectLow (unsigned int sym)
7116 : : {
7117 : 234 : unsigned int low;
7118 : 234 : unsigned int high;
7119 : :
7120 : 234 : if (SymbolTable_IsSubrange (sym))
7121 : : {
7122 : 234 : SymbolTable_GetSubrange (sym, &high, &low);
7123 : 234 : return low;
7124 : : }
7125 : : else
7126 : : {
7127 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
7128 : : }
7129 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
7130 : : __builtin_unreachable ();
7131 : : }
7132 : :
7133 : :
7134 : : /*
7135 : : CollectHigh - returns the high of the subrange value, sym.
7136 : : */
7137 : :
7138 : 3116 : static unsigned int CollectHigh (unsigned int sym)
7139 : : {
7140 : 3116 : unsigned int low;
7141 : 3116 : unsigned int high;
7142 : :
7143 : 3116 : if (SymbolTable_IsSubrange (sym))
7144 : : {
7145 : 3116 : SymbolTable_GetSubrange (sym, &high, &low);
7146 : 3116 : return high;
7147 : : }
7148 : : else
7149 : : {
7150 : 0 : M2Error_InternalError ((const char *) "expecting Subrange symbol", 25);
7151 : : }
7152 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
7153 : : __builtin_unreachable ();
7154 : : }
7155 : :
7156 : :
7157 : : /*
7158 : : CheckCompatibleWithBecomes - checks to see that symbol, sym, is
7159 : : compatible with the := operator.
7160 : : */
7161 : :
7162 : 417759 : static void CheckCompatibleWithBecomes (unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
7163 : : {
7164 : 417759 : if (SymbolTable_IsType (des))
7165 : : {
7166 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a type {%1a}", 51, des);
7167 : : }
7168 : 417759 : else if (SymbolTable_IsProcedure (des))
7169 : : {
7170 : : /* avoid dangling else. */
7171 : 6 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to a procedure {%1a}", 56, des);
7172 : : }
7173 : 417753 : else if (SymbolTable_IsFieldEnumeration (des))
7174 : : {
7175 : : /* avoid dangling else. */
7176 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "an assignment cannot assign a value to an enumeration field {%1a}", 65, des);
7177 : : }
7178 : 417759 : if ((M2Base_IsPseudoBaseProcedure (expr)) || (M2Base_IsPseudoBaseFunction (expr)))
7179 : : {
7180 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "an assignment cannot assign a {%1d} {%1a}", 41, expr);
7181 : : }
7182 : 417759 : }
7183 : :
7184 : :
7185 : : /*
7186 : : BuildAssignmentWithoutBounds - calls BuildAssignment but makes sure we do not
7187 : : check bounds.
7188 : : */
7189 : :
7190 : 74067 : static void BuildAssignmentWithoutBounds (unsigned int tok, bool checkTypes, bool checkOverflow)
7191 : : {
7192 : 74067 : bool old;
7193 : :
7194 : 74067 : old = MustNotCheckBounds;
7195 : 74067 : MustNotCheckBounds = true;
7196 : 0 : doBuildAssignment (tok, checkTypes, checkOverflow);
7197 : 74067 : MustNotCheckBounds = old;
7198 : 17352 : }
7199 : :
7200 : :
7201 : : /*
7202 : : MarkArrayWritten - marks, Array, as being written.
7203 : : */
7204 : :
7205 : 89532 : static void MarkArrayWritten (unsigned int Array)
7206 : : {
7207 : 89532 : if ((Array != SymbolTable_NulSym) && (SymbolTable_IsVarAParam (Array)))
7208 : : {
7209 : 12024 : SymbolTable_PutVarWritten (Array, true);
7210 : : }
7211 : 89532 : }
7212 : :
7213 : :
7214 : : /*
7215 : : MarkAsReadWrite - marks the variable or parameter as being
7216 : : read/write.
7217 : : */
7218 : :
7219 : 27227 : static void MarkAsReadWrite (unsigned int sym)
7220 : : {
7221 : 27227 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7222 : : {
7223 : 19226 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7224 : 19226 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7225 : : }
7226 : 27227 : }
7227 : :
7228 : :
7229 : : /*
7230 : : MarkAsRead - marks the variable or parameter as being read.
7231 : : */
7232 : :
7233 : 1066206 : static void MarkAsRead (unsigned int sym)
7234 : : {
7235 : 1066206 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7236 : : {
7237 : 313794 : SymbolTable_PutReadQuad (sym, SymbolTable_RightValue, NextQuad);
7238 : : }
7239 : 1066206 : }
7240 : :
7241 : :
7242 : : /*
7243 : : MarkAsWrite - marks the variable or parameter as being written.
7244 : : */
7245 : :
7246 : 417759 : static void MarkAsWrite (unsigned int sym)
7247 : : {
7248 : 417759 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym)))
7249 : : {
7250 : 73809 : SymbolTable_PutWriteQuad (sym, SymbolTable_RightValue, NextQuad);
7251 : : }
7252 : 417759 : }
7253 : :
7254 : :
7255 : : /*
7256 : : doVal - return an expression which is VAL(type, expr). If
7257 : : expr is a constant then return expr.
7258 : : */
7259 : :
7260 : 36420 : static unsigned int doVal (unsigned int type, unsigned int expr)
7261 : : {
7262 : 36420 : if ((! (SymbolTable_IsConst (expr))) && ((SymbolTable_SkipType (type)) != (SymbolTable_GetDType (expr))))
7263 : : {
7264 : 26446 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
7265 : 26446 : M2Quads_PushT (SymbolTable_SkipType (type));
7266 : 26446 : M2Quads_PushT (expr);
7267 : 26446 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7268 : 26446 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
7269 : 26446 : M2Quads_PopT (&expr);
7270 : : }
7271 : 36420 : return expr;
7272 : : /* static analysis guarentees a RETURN statement will be used before here. */
7273 : : __builtin_unreachable ();
7274 : : }
7275 : :
7276 : :
7277 : : /*
7278 : : MoveWithMode -
7279 : : */
7280 : :
7281 : 417753 : static void MoveWithMode (unsigned int tokno, unsigned int Des, unsigned int Exp, unsigned int Array, unsigned int destok, unsigned int exptok, bool checkOverflow)
7282 : : {
7283 : 417753 : unsigned int t;
7284 : :
7285 : 417753 : if ((SymbolTable_IsConstString (Exp)) && (SymbolTable_IsConst (Des)))
7286 : : {
7287 : 1414 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7288 : : }
7289 : : else
7290 : : {
7291 : 416339 : if ((SymbolTable_GetMode (Des)) == SymbolTable_RightValue)
7292 : : {
7293 : 134827 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7294 : : {
7295 : 2110 : CheckPointerThroughNil (tokno, Exp); /* Des = *Exp */
7296 : 2110 : doIndrX (tokno, Des, Exp); /* Des = *Exp */
7297 : : }
7298 : : else
7299 : : {
7300 : 132717 : GenQuadOtok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7301 : : }
7302 : : }
7303 : 281512 : else if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7304 : : {
7305 : : /* avoid dangling else. */
7306 : 36272 : MarkArrayWritten (Array);
7307 : 36272 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
7308 : : {
7309 : 922 : t = SymbolTable_MakeTemporary (tokno, SymbolTable_RightValue);
7310 : 922 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
7311 : 922 : CheckPointerThroughNil (tokno, Exp);
7312 : 922 : doIndrX (tokno, t, Exp);
7313 : 922 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7314 : 922 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), t), checkOverflow); /* *Des = Exp */
7315 : : }
7316 : : else
7317 : : {
7318 : 35350 : CheckPointerThroughNil (tokno, Des); /* *Des = Exp */
7319 : 35350 : GenQuadO (tokno, M2Quads_XIndrOp, Des, SymbolTable_GetSType (Des), doVal (SymbolTable_GetSType (Des), Exp), checkOverflow); /* *Des = Exp */
7320 : : }
7321 : : }
7322 : : else
7323 : : {
7324 : : /* avoid dangling else. */
7325 : : /* This might be inside a const expression. */
7326 : 245240 : GenQuadOTypetok (tokno, M2Quads_BecomesOp, Des, SymbolTable_NulSym, Exp, true, true, destok, M2LexBuf_UnknownTokenNo, exptok);
7327 : : }
7328 : : }
7329 : 417753 : }
7330 : :
7331 : :
7332 : : /*
7333 : : CheckBecomesMeta - checks to make sure that we are not
7334 : : assigning a variable to a constant.
7335 : : Also check we are not assigning to an
7336 : : unbounded array.
7337 : : */
7338 : :
7339 : 354114 : static void CheckBecomesMeta (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7340 : : {
7341 : 354114 : if ((SymbolTable_IsConst (Des)) && (SymbolTable_IsVar (Exp)))
7342 : : {
7343 : 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);
7344 : : }
7345 : 354114 : if ((((SymbolTable_GetDType (Des)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Des))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Des))))
7346 : : {
7347 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "in assignment, cannot assign to an unbounded array {%1ad}", 57, Des);
7348 : : }
7349 : 354114 : if ((((SymbolTable_GetDType (Exp)) != SymbolTable_NulSym) && (SymbolTable_IsVar (Exp))) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (Exp))))
7350 : : {
7351 : 0 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "in assignment, cannot assign from an unbounded array {%1ad}", 59, Exp);
7352 : : }
7353 : 354114 : }
7354 : :
7355 : :
7356 : : /*
7357 : : doBuildAssignment - subsiduary procedure of BuildAssignment.
7358 : : It builds the assignment and optionally
7359 : : checks the types are compatible.
7360 : : */
7361 : :
7362 : 426687 : static void doBuildAssignment (unsigned int becomesTokNo, bool checkTypes, bool checkOverflow)
7363 : : {
7364 : 426687 : unsigned int r;
7365 : 426687 : unsigned int w;
7366 : 426687 : unsigned int t;
7367 : 426687 : unsigned int f;
7368 : 426687 : unsigned int Array;
7369 : 426687 : unsigned int Des;
7370 : 426687 : unsigned int Exp;
7371 : 426687 : unsigned int combinedtok;
7372 : 426687 : unsigned int destok;
7373 : 426687 : unsigned int exptok;
7374 : :
7375 : 426687 : M2Quads_DisplayStack ();
7376 : 426687 : if (IsBoolean (1))
7377 : : {
7378 : 17856 : PopBool (&t, &f);
7379 : 8928 : M2Quads_PopTtok (&Des, &destok);
7380 : 8928 : SymbolTable_PutVarConditional (Des, true); /* Des will contain the result of a boolean relop. */
7381 : : /* Conditional Boolean Assignment. */
7382 : 8928 : BackPatch (t, NextQuad);
7383 : 8928 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7384 : : {
7385 : 40 : CheckPointerThroughNil (destok, Des);
7386 : 80 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_True, checkOverflow);
7387 : 40 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
7388 : : }
7389 : : else
7390 : : {
7391 : : /* This might be inside a const expression. */
7392 : 17776 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_True, checkOverflow);
7393 : 8888 : GenQuadO (destok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, NextQuad+2, false);
7394 : : }
7395 : 8928 : BackPatch (f, NextQuad);
7396 : 8928 : if ((SymbolTable_GetMode (Des)) == SymbolTable_LeftValue)
7397 : : {
7398 : 40 : CheckPointerThroughNil (destok, Des);
7399 : 40 : GenQuadO (destok, M2Quads_XIndrOp, Des, M2Base_Boolean, M2Base_False, checkOverflow);
7400 : : }
7401 : : else
7402 : : {
7403 : 8888 : GenQuadO (becomesTokNo, M2Quads_BecomesOp, Des, SymbolTable_NulSym, M2Base_False, checkOverflow);
7404 : : }
7405 : : }
7406 : : else
7407 : : {
7408 : 417759 : PopTrwtok (&Exp, &r, &exptok);
7409 : 417759 : MarkAsRead (r);
7410 : 417759 : if (Exp == SymbolTable_NulSym)
7411 : : {
7412 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}unknown expression found during assignment", 46);
7413 : 0 : M2Error_FlushErrors ();
7414 : : }
7415 : 417759 : Array = static_cast<unsigned int> (M2Quads_OperandA (1));
7416 : 417759 : PopTrwtok (&Des, &w, &destok);
7417 : 417759 : MarkAsWrite (w);
7418 : 417759 : CheckCompatibleWithBecomes (Des, Exp, destok, exptok);
7419 : 417759 : if (DebugTokPos)
7420 : : {
7421 : : M2MetaError_MetaErrorT1 (becomesTokNo, (const char *) "becomestok {%1Oad}", 18, Des);
7422 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Oad}", 14, Des);
7423 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Oad}", 14, Exp);
7424 : : }
7425 : 417759 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
7426 : 417759 : if (DebugTokPos)
7427 : : {
7428 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Oad}", 16, Des);
7429 : : }
7430 : 417759 : if (M2Options_StrictTypeAssignment)
7431 : : {
7432 : 417759 : BuildRange (M2Range_InitTypesAssignmentCheck (combinedtok, Des, Exp));
7433 : : }
7434 : 417759 : if (((SymbolTable_GetSType (Des)) != SymbolTable_NulSym) && (! (SymbolTable_IsSet (SymbolTable_GetDType (Des)))))
7435 : : {
7436 : : /* Tell code generator to test runtime values of assignment so ensure we
7437 : : catch overflow and underflow. */
7438 : 409093 : BuildRange (M2Range_InitAssignmentRangeCheck (combinedtok, Des, Exp, destok, exptok));
7439 : : }
7440 : 417753 : if (checkTypes)
7441 : : {
7442 : 354114 : CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok);
7443 : : }
7444 : : /* Simple assignment. */
7445 : 417753 : MoveWithMode (combinedtok, Des, Exp, Array, destok, exptok, checkOverflow);
7446 : 417753 : if (checkTypes)
7447 : : {
7448 : 354114 : CheckAssignCompatible (Des, Exp, combinedtok, destok, exptok);
7449 : : }
7450 : : }
7451 : 426681 : M2Quads_DisplayStack ();
7452 : 426681 : }
7453 : :
7454 : :
7455 : : /*
7456 : : CheckAssignCompatible - checks to see that an assignment is compatible.
7457 : : It performs limited checking - thorough checking
7458 : : is done in pass 3. But we do what we can here
7459 : : given knowledge so far.
7460 : : */
7461 : :
7462 : 354114 : static void CheckAssignCompatible (unsigned int Des, unsigned int Exp, unsigned int combinedtok, unsigned int destok, unsigned int exprtok)
7463 : : {
7464 : 354114 : unsigned int DesT;
7465 : 354114 : unsigned int ExpT;
7466 : 354114 : unsigned int DesL;
7467 : :
7468 : 354114 : DesT = SymbolTable_GetSType (Des);
7469 : 354114 : ExpT = SymbolTable_GetSType (Exp);
7470 : 354114 : DesL = SymbolTable_GetLType (Des);
7471 : 354114 : if (((SymbolTable_IsProcedure (Exp)) && ((DesT != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesT))))) && ((DesL != SymbolTable_NulSym) && (! (SymbolTable_IsProcType (DesL)))))
7472 : : {
7473 : 0 : M2MetaError_MetaErrorT1 (destok, (const char *) "incorrectly assigning a procedure to a designator {%1Ead} (designator is not a procedure type, {%1ast})", 103, Des);
7474 : : }
7475 : : /* We ignore checking of these types in pass 3 - but we do check them thoroughly post pass 3 */
7476 : 354114 : else if ((SymbolTable_IsProcedure (Exp)) && (SymbolTable_IsProcedureNested (Exp)))
7477 : : {
7478 : : /* avoid dangling else. */
7479 : 6 : M2MetaError_MetaErrorT1 (exprtok, (const char *) "cannot call nested procedure {%1Ead} indirectly as the outer scope will not be known", 84, Exp);
7480 : : }
7481 : 354108 : else if (SymbolTable_IsConstString (Exp))
7482 : : {
7483 : : /* avoid dangling else. */
7484 : : }
7485 : 351040 : else if ((DesT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (DesT)))
7486 : : {
7487 : : /* avoid dangling else. */
7488 : : }
7489 : 351040 : else if ((ExpT != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (ExpT)))
7490 : : {
7491 : : /* avoid dangling else. */
7492 : : }
7493 : 351040 : else if ((DesL != SymbolTable_NulSym) && (SymbolTable_IsArray (DesL)))
7494 : : {
7495 : : /* avoid dangling else. */
7496 : : }
7497 : 350192 : else if (SymbolTable_IsConstructor (Exp))
7498 : : {
7499 : : /* avoid dangling else. */
7500 : 6066 : if (ExpT == SymbolTable_NulSym)
7501 : : {} /* empty. */
7502 : 6026 : else if (((DesT == SymbolTable_NulSym) && (SymbolTable_IsConst (Des))) && ((SymbolTable_IsConstructor (Des)) || (SymbolTable_IsConstSet (Des))))
7503 : : {
7504 : : /* avoid dangling else. */
7505 : 0 : SymbolTable_PutConst (Des, ExpT);
7506 : : }
7507 : 6026 : else if (! (M2Base_IsAssignmentCompatible (DesT, ExpT)))
7508 : : {
7509 : : /* avoid dangling else. */
7510 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "constructor expression is not compatible during assignment to {%1Ead}", 69, Des);
7511 : : }
7512 : : }
7513 : 344126 : else if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsSet (DesT))) && (SymbolTable_IsConst (Exp)))
7514 : : {
7515 : : /* avoid dangling else. */
7516 : : }
7517 : 344108 : else if ((((((SymbolTable_IsConst (Exp)) && (ExpT != M2System_Address)) && (! (SymbolTable_IsConst (Des)))) && (DesL != SymbolTable_NulSym)) && ((DesL == M2Base_Cardinal) || (! (SymbolTable_IsSubrange (DesL))))) && (! (SymbolTable_IsEnumeration (DesL))))
7518 : : {
7519 : : /* avoid dangling else. */
7520 : 22244 : if ((M2Base_IsBaseType (DesL)) || (M2System_IsSystemType (DesL)))
7521 : : {
7522 : 22244 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7523 : : }
7524 : : else
7525 : : {
7526 : 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);
7527 : : }
7528 : : }
7529 : : else
7530 : : {
7531 : : /* avoid dangling else. */
7532 : 321864 : if (((DesT != SymbolTable_NulSym) && (SymbolTable_IsProcType (DesT))) && (SymbolTable_IsProcedure (Exp)))
7533 : : {
7534 : 26742 : DesT = SymbolTable_GetSType (DesT); /* we can at least check RETURN values of procedure variables */
7535 : : /* remember that thorough assignment checking is done post pass 3 */
7536 : 26742 : M2Base_CheckAssignmentCompatible (combinedtok, ExpT, DesT);
7537 : : }
7538 : : }
7539 : 354114 : }
7540 : :
7541 : :
7542 : : /*
7543 : : CheckBooleanId - Checks to see if the top operand is a boolean.
7544 : : If the operand is not a boolean then it is tested
7545 : : with true and a boolean is generated.
7546 : : The Stack:
7547 : :
7548 : :
7549 : : Entry Exit
7550 : : Ptr -> <- Ptr
7551 : : +------------+ +------------+
7552 : : | Sym | | t | f |
7553 : : |------------| |------------|
7554 : :
7555 : : Quadruples
7556 : :
7557 : : q If= Sym True _
7558 : : q+1 GotoOp _ _ _
7559 : : */
7560 : :
7561 : 69771 : static void CheckBooleanId (void)
7562 : : {
7563 : 69771 : unsigned int tok;
7564 : :
7565 : 69771 : if (! (IsBoolean (1)))
7566 : : {
7567 : 13819 : tok = static_cast<unsigned int> (M2Quads_OperandTok (1));
7568 : 13819 : if (SymbolTable_IsVar (M2Quads_OperandT (1)))
7569 : : {
7570 : 12499 : if ((SymbolTable_GetSType (M2Quads_OperandT (1))) != M2Base_Boolean)
7571 : : {
7572 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua:is not a boolean expression}''{!%1Ua:boolean expression expected}", 71, M2Quads_OperandT (1));
7573 : : }
7574 : : }
7575 : 13819 : M2Quads_PushT (M2Reserved_EqualTok);
7576 : 13819 : M2Quads_PushT (M2Base_True);
7577 : 13819 : M2Quads_BuildRelOp (tok);
7578 : : }
7579 : 69771 : }
7580 : :
7581 : :
7582 : : /*
7583 : : PushOne - pushes the value one to the stack.
7584 : : The Stack is changed:
7585 : :
7586 : :
7587 : : Entry Exit
7588 : : ===== ====
7589 : :
7590 : : <- Ptr
7591 : : +------------+
7592 : : Ptr -> | 1 | type |
7593 : : |------------|
7594 : : */
7595 : :
7596 : 14228 : static void PushOne (unsigned int tok, unsigned int type, const char *message_, unsigned int _message_high)
7597 : : {
7598 : 14228 : unsigned int const_;
7599 : 14228 : char message[_message_high+1];
7600 : :
7601 : : /* make a local copy of each unbounded array. */
7602 : 14228 : memcpy (message, message_, _message_high+1);
7603 : :
7604 : 14228 : if (type == SymbolTable_NulSym)
7605 : : {
7606 : 112 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), SymbolTable_NulSym);
7607 : 112 : SymbolTable_PutConstLitInternal (const_, true);
7608 : 112 : M2Quads_PushTFtok (const_, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7609 : : }
7610 : 14116 : else if (SymbolTable_IsEnumeration (type))
7611 : : {
7612 : : /* avoid dangling else. */
7613 : 238 : if ((SymbolTable_NoOfElements (type)) == 0)
7614 : : {
7615 : 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);
7616 : 0 : PushZero (tok, type);
7617 : : }
7618 : : else
7619 : : {
7620 : 238 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7621 : 238 : M2Quads_PushT (type);
7622 : 238 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType), M2Base_ZType, tok);
7623 : 238 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7624 : 238 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7625 : : }
7626 : : }
7627 : : else
7628 : : {
7629 : : /* avoid dangling else. */
7630 : 13878 : const_ = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), type);
7631 : 13878 : SymbolTable_PutConstLitInternal (const_, true);
7632 : 13878 : M2Quads_PushTFtok (const_, type, tok);
7633 : : }
7634 : 14228 : }
7635 : :
7636 : :
7637 : : /*
7638 : : PushZero - pushes the value zero to the stack.
7639 : : The Stack is changed:
7640 : :
7641 : :
7642 : : Entry Exit
7643 : : ===== ====
7644 : :
7645 : : <- Ptr
7646 : : +------------+
7647 : : Ptr -> | 0 | type |
7648 : : |------------|
7649 : : */
7650 : :
7651 : 7288 : static void PushZero (unsigned int tok, unsigned int type)
7652 : : {
7653 : 7288 : if (type == SymbolTable_NulSym)
7654 : : {
7655 : 316 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tok);
7656 : : }
7657 : 6972 : else if (SymbolTable_IsEnumeration (type))
7658 : : {
7659 : : /* avoid dangling else. */
7660 : 196 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
7661 : 196 : M2Quads_PushTtok (type, tok);
7662 : 196 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), tok);
7663 : 196 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
7664 : 196 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters */
7665 : : }
7666 : : else
7667 : : {
7668 : : /* avoid dangling else. */
7669 : 6776 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "0", 1), type), type, tok);
7670 : : }
7671 : 7288 : }
7672 : :
7673 : :
7674 : : /*
7675 : : ForLoopLastIterator - calculate the last iterator value but avoid setting
7676 : : LastIterator twice if it is a constant (in the quads).
7677 : : In the ForLoopLastIteratorVariable case only one
7678 : : path will be chosen but at the time of quadruple
7679 : : generation we do not know the value of BySym.
7680 : : */
7681 : :
7682 : 2104 : static void ForLoopLastIterator (unsigned int LastIterator, unsigned int e1, unsigned int e2, unsigned int BySym, unsigned int e1tok, unsigned int e2tok, unsigned int bytok)
7683 : : {
7684 : 2104 : if (! (SymbolTable_IsConst (BySym)))
7685 : : {
7686 : 18 : M2MetaError_MetaErrorT1 (bytok, (const char *) "{%E}the {%kFOR} loop {%kBY} expression must be constant, the expression {%1a} is variable", 89, BySym);
7687 : 18 : M2MetaError_MetaErrorDecl (BySym, true);
7688 : : }
7689 : : else
7690 : : {
7691 : 2086 : e1 = DereferenceLValue (e1tok, e1);
7692 : 2086 : e2 = DereferenceLValue (e2tok, e2);
7693 : 2086 : GenQuadOTypetok (bytok, M2Quads_LastForIteratorOp, LastIterator, SymbolTable_Make2Tuple (e1, e2), BySym, false, false, bytok, M2LexBuf_MakeVirtual2Tok (e1tok, e2tok), bytok);
7694 : : }
7695 : 2104 : }
7696 : :
7697 : :
7698 : : /*
7699 : : BuildSizeCheckEnd - checks to see whether the function "called" was in fact SIZE.
7700 : : If so then we restore quadruple generation.
7701 : : */
7702 : :
7703 : 8196 : static void BuildSizeCheckEnd (unsigned int ProcSym)
7704 : : {
7705 : 8196 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
7706 : : {
7707 : 5868 : QuadrupleGeneration = true;
7708 : 5868 : BuildingSize = false;
7709 : : }
7710 : 2328 : else if (ProcSym == M2Base_High)
7711 : : {
7712 : : /* avoid dangling else. */
7713 : 2328 : QuadrupleGeneration = true;
7714 : 2328 : BuildingHigh = false;
7715 : : }
7716 : 8196 : }
7717 : :
7718 : :
7719 : : /*
7720 : : BuildRealProcedureCall - builds a real procedure call.
7721 : : The Stack:
7722 : :
7723 : :
7724 : : Entry Exit
7725 : :
7726 : : Ptr ->
7727 : : +----------------+
7728 : : | NoOfParam |
7729 : : |----------------|
7730 : : | Param 1 |
7731 : : |----------------|
7732 : : | Param 2 |
7733 : : |----------------|
7734 : : . .
7735 : : . .
7736 : : . .
7737 : : |----------------|
7738 : : | Param # |
7739 : : |----------------|
7740 : : | ProcSym | Type | Empty
7741 : : |----------------|
7742 : : */
7743 : :
7744 : 146444 : static void BuildRealProcedureCall (unsigned int tokno)
7745 : : {
7746 : 146444 : unsigned int NoOfParam;
7747 : 146444 : unsigned int ProcSym;
7748 : :
7749 : 146444 : M2Quads_PopT (&NoOfParam);
7750 : 146444 : M2Quads_PushT (NoOfParam);
7751 : 146444 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
7752 : 146444 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7753 : : /* --checkme-- */
7754 : 146444 : if (SymbolTable_IsVar (ProcSym))
7755 : : {
7756 : : /* Procedure Variable ? */
7757 : 644 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
7758 : : }
7759 : 146444 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
7760 : : {
7761 : 12742 : BuildRealFuncProcCall (tokno, false, true, false);
7762 : : }
7763 : : else
7764 : : {
7765 : 133702 : BuildRealFuncProcCall (tokno, false, false, false);
7766 : : }
7767 : 146438 : }
7768 : :
7769 : :
7770 : : /*
7771 : : BuildRealFuncProcCall - builds a real procedure or function call.
7772 : : The Stack:
7773 : :
7774 : :
7775 : : Entry Exit
7776 : :
7777 : : Ptr ->
7778 : : +----------------+
7779 : : | NoOfParam |
7780 : : |----------------|
7781 : : | Param 1 |
7782 : : |----------------|
7783 : : | Param 2 |
7784 : : |----------------|
7785 : : . .
7786 : : . .
7787 : : . .
7788 : : |----------------|
7789 : : | Param # |
7790 : : |----------------|
7791 : : | ProcSym | Type | Empty
7792 : : |----------------|
7793 : : */
7794 : :
7795 : 187550 : static void BuildRealFuncProcCall (unsigned int tokno, bool IsFunc, bool IsForC, bool ConstExpr)
7796 : : {
7797 : 187550 : bool AllocateProc;
7798 : 187550 : bool DeallocateProc;
7799 : 187550 : bool ForcedFunc;
7800 : 187550 : bool ParamConstant;
7801 : 187550 : unsigned int trash;
7802 : 187550 : unsigned int resulttok;
7803 : 187550 : unsigned int paramtok;
7804 : 187550 : unsigned int proctok;
7805 : 187550 : unsigned int NoOfParameters;
7806 : 187550 : unsigned int i;
7807 : 187550 : unsigned int pi;
7808 : 187550 : unsigned int ParamType;
7809 : 187550 : unsigned int Param1;
7810 : 187550 : unsigned int ReturnVar;
7811 : 187550 : unsigned int ProcSym;
7812 : 187550 : unsigned int Proc;
7813 : :
7814 : 187550 : Param1 = SymbolTable_NulSym; /* Used to remember first param for allocate/deallocate. */
7815 : 187550 : ParamType = SymbolTable_NulSym;
7816 : 187550 : CheckProcedureParameters (IsForC);
7817 : 187538 : M2Quads_PopT (&NoOfParameters);
7818 : 187538 : M2Quads_PushT (NoOfParameters); /* Restore stack to original state. */
7819 : 187538 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+2)); /* Restore stack to original state. */
7820 : 187538 : proctok = tokno; /* OperandTtok (NoOfParameters+2) ; */
7821 : 187538 : if (proctok == M2LexBuf_UnknownTokenNo) /* OperandTtok (NoOfParameters+2) ; */
7822 : : {
7823 : 0 : proctok = M2LexBuf_GetTokenNo ();
7824 : : }
7825 : 187538 : paramtok = proctok;
7826 : 187538 : ProcSym = PCSymBuild_SkipConst (ProcSym);
7827 : 187538 : ForcedFunc = false;
7828 : 187538 : AllocateProc = false;
7829 : 187538 : DeallocateProc = false;
7830 : 187538 : if (SymbolTable_IsVar (ProcSym))
7831 : : {
7832 : : /* Procedure Variable ? */
7833 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+2));
7834 : 720 : ParamConstant = false;
7835 : : }
7836 : : else
7837 : : {
7838 : 186818 : Proc = ProcSym;
7839 : 186818 : ParamConstant = true;
7840 : 186818 : AllocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8));
7841 : 186818 : DeallocateProc = (SymbolTable_GetSymName (Proc)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
7842 : : }
7843 : 187538 : if (IsFunc)
7844 : : {
7845 : : /* avoid dangling else. */
7846 : 41100 : if ((SymbolTable_GetSType (Proc)) == SymbolTable_NulSym)
7847 : : {
7848 : 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);
7849 : : }
7850 : : }
7851 : : else
7852 : : {
7853 : : /* is being called as a procedure */
7854 : 146438 : if ((SymbolTable_GetSType (Proc)) != SymbolTable_NulSym)
7855 : : {
7856 : : /* however it was declared as a procedure function */
7857 : 7041 : if (! (SymbolTable_IsReturnOptionalAny (Proc)))
7858 : : {
7859 : 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);
7860 : : }
7861 : : IsFunc = true;
7862 : : ForcedFunc = true;
7863 : : }
7864 : : }
7865 : 187538 : if (AllocateProc || DeallocateProc)
7866 : : {
7867 : 1422 : Param1 = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1)); /* Remember this before manipulating. */
7868 : : }
7869 : 187538 : ManipulateParameters (IsForC);
7870 : 187538 : CheckParameterOrdinals ();
7871 : 187538 : M2Quads_PopT (&NoOfParameters);
7872 : 187538 : if (IsFunc)
7873 : : {
7874 : 48141 : GenQuad (M2Quads_ParamOp, 0, Proc, ProcSym); /* Space for return value */
7875 : : }
7876 : 187538 : if (((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc))) && (SymbolTable_UsesOptArgAny (Proc)))
7877 : : {
7878 : 2886 : GenQuad (M2Quads_OptParamOp, SymbolTable_NoOfParamAny (Proc), Proc, Proc);
7879 : : }
7880 : 187538 : i = NoOfParameters;
7881 : 187538 : pi = 1; /* stack index referencing stacked parameter, i */
7882 : 672794 : while (i > 0) /* stack index referencing stacked parameter, i */
7883 : : {
7884 : 485256 : paramtok = OperandTtok (pi);
7885 : 485256 : if (((AllocateProc || DeallocateProc) && (i == 1)) && (Param1 != SymbolTable_NulSym))
7886 : : {
7887 : 1422 : ParamType = GetItemPointedTo (Param1);
7888 : 1422 : if (ParamType == SymbolTable_NulSym)
7889 : : {
7890 : 0 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7891 : : }
7892 : : else
7893 : : {
7894 : 1422 : if (AllocateProc)
7895 : : {
7896 : 954 : trash = SymbolTable_MakeTemporary (paramtok, SymbolTable_RightValue);
7897 : 954 : SymbolTable_PutVar (trash, ParamType);
7898 : 954 : SymbolTable_PutVarHeap (trash, true);
7899 : : }
7900 : : else
7901 : : {
7902 : 468 : M2Debug_Assert (DeallocateProc);
7903 : 468 : trash = M2Base_Nil;
7904 : : }
7905 : 1422 : GenQuadOTrash (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true, trash);
7906 : : }
7907 : : }
7908 : : else
7909 : : {
7910 : 483834 : GenQuadO (paramtok, M2Quads_ParamOp, i, Proc, M2Quads_OperandT (pi), true);
7911 : : }
7912 : 485256 : if (! (SymbolTable_IsConst (M2Quads_OperandT (pi))))
7913 : : {
7914 : 408157 : ParamConstant = false;
7915 : : }
7916 : 485256 : i -= 1;
7917 : 485256 : pi += 1;
7918 : : }
7919 : 375076 : GenQuadO (proctok, M2Quads_CallOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym, true);
7920 : 187538 : M2Quads_PopN (NoOfParameters+1); /* Destroy arguments and procedure call */
7921 : 187538 : if (IsFunc)
7922 : : {
7923 : : /* ReturnVar has the type of the procedure. */
7924 : 48141 : resulttok = M2LexBuf_MakeVirtualTok (proctok, proctok, paramtok);
7925 : 48141 : if (ConstExpr && (! (SymbolTable_IsProcedureBuiltinAvailable (Proc))))
7926 : : {
7927 : 0 : M2MetaError_MetaError1 ((const char *) "{%1d} {%1ad} cannot be used in a constant expression", 52, Proc);
7928 : 0 : ParamConstant = false;
7929 : : }
7930 : 48141 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (ParamConstant && ConstExpr));
7931 : 48141 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (Proc));
7932 : 96282 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, Proc, true);
7933 : 48141 : if (! ForcedFunc)
7934 : : {
7935 : 41100 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (Proc), resulttok);
7936 : : }
7937 : : }
7938 : 187538 : }
7939 : :
7940 : :
7941 : : /*
7942 : : CheckProcedureParameters - Checks the parameters which are being passed to
7943 : : procedure ProcSym.
7944 : :
7945 : : The Stack:
7946 : :
7947 : :
7948 : : Entry Exit
7949 : :
7950 : : Ptr -> <- Ptr
7951 : : +----------------+ +----------------+
7952 : : | NoOfParam | | NoOfParam |
7953 : : |----------------| |----------------|
7954 : : | Param 1 | | Param 1 |
7955 : : |----------------| |----------------|
7956 : : | Param 2 | | Param 2 |
7957 : : |----------------| |----------------|
7958 : : . . . .
7959 : : . . . .
7960 : : . . . .
7961 : : |----------------| |----------------|
7962 : : | Param # | | Param # |
7963 : : |----------------| |----------------|
7964 : : | ProcSym | Type | | ProcSym | Type |
7965 : : |----------------| |----------------|
7966 : :
7967 : : */
7968 : :
7969 : 187550 : static void CheckProcedureParameters (bool IsForC)
7970 : : {
7971 : 187550 : unsigned int proctok;
7972 : 187550 : unsigned int paramtok;
7973 : 187550 : NameKey_Name n1;
7974 : 187550 : NameKey_Name n2;
7975 : 187550 : unsigned int ParamCheckId;
7976 : 187550 : unsigned int Dim;
7977 : 187550 : unsigned int Actual;
7978 : 187550 : unsigned int FormalI;
7979 : 187550 : unsigned int ParamTotal;
7980 : 187550 : unsigned int pi;
7981 : 187550 : unsigned int Proc;
7982 : 187550 : unsigned int ProcSym;
7983 : 187550 : unsigned int i;
7984 : 187550 : DynamicStrings_String s;
7985 : :
7986 : 187550 : M2Quads_PopT (&ParamTotal);
7987 : 187550 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
7988 : 187550 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
7989 : 187550 : proctok = OperandTtok ((ParamTotal+1)+1);
7990 : 187550 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
7991 : : {
7992 : : /* Procedure Variable ? */
7993 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
7994 : : }
7995 : : else
7996 : : {
7997 : 186830 : Proc = PCSymBuild_SkipConst (ProcSym);
7998 : : }
7999 : 187550 : if (! ((SymbolTable_IsProcedure (Proc)) || (SymbolTable_IsProcType (Proc))))
8000 : : {
8001 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8002 : 12 : if (SymbolTable_IsUnknown (Proc))
8003 : : {
8004 : 0 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
8005 : : }
8006 : : else
8007 : : {
8008 : 12 : M2MetaError_MetaErrors1 ((const char *) "{%1a} is not recognised as a procedure, check declaration or import", 67, (const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, Proc);
8009 : : }
8010 : : }
8011 : 187550 : if (M2Options_CompilerDebugging)
8012 : : {
8013 : 0 : n1 = SymbolTable_GetSymName (Proc);
8014 : 0 : M2Printf_printf1 ((const char *) " %a ( ", 7, (const unsigned char *) &n1, (sizeof (n1)-1));
8015 : : }
8016 : 187550 : if (DebugTokPos)
8017 : : {
8018 : : s = DynamicStrings_InitString ((const char *) "procedure", 9);
8019 : : M2Error_WarnStringAt (s, proctok);
8020 : : }
8021 : 187550 : i = 1;
8022 : 187550 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
8023 : 670020 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
8024 : : {
8025 : 482482 : if (i <= (SymbolTable_NoOfParamAny (Proc)))
8026 : : {
8027 : : /* FormalI := GetParam(Proc, i) ; */
8028 : 477960 : FormalI = SymbolTable_GetNthParamAnyClosest (Proc, i, SymbolTable_GetCurrentModule ());
8029 : 477960 : if (M2Options_CompilerDebugging)
8030 : : {
8031 : 0 : n1 = SymbolTable_GetSymName (FormalI);
8032 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (FormalI));
8033 : 0 : M2Printf_printf2 ((const char *) "%a: %a", 6, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
8034 : : }
8035 : 477960 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
8036 : 477960 : Dim = static_cast<unsigned int> (OperandD (pi));
8037 : 477960 : paramtok = OperandTtok (pi);
8038 : 477960 : if (DebugTokPos)
8039 : : {
8040 : : s = DynamicStrings_InitString ((const char *) "actual", 6);
8041 : : M2Error_WarnStringAt (s, paramtok);
8042 : : }
8043 : 477960 : ParamCheckId = M2Range_InitTypesParameterCheck (paramtok, Proc, i, FormalI, Actual, 0);
8044 : 477960 : BuildRange (ParamCheckId);
8045 : : /* Store the ParamCheckId on the quad stack so that any dependant checks
8046 : : can be cancelled if the type check above detects an error. */
8047 : 477960 : PutRangeDep (pi, ParamCheckId);
8048 : 477960 : if (SymbolTable_IsConst (Actual))
8049 : : {
8050 : : /* avoid dangling else. */
8051 : 108127 : if (SymbolTable_IsVarParamAny (Proc, i))
8052 : : {
8053 : 0 : FailParameter (paramtok, (const char *) "trying to pass a constant to a VAR parameter", 44, Actual, Proc, i);
8054 : : }
8055 : 108127 : else if (SymbolTable_IsConstString (Actual))
8056 : : {
8057 : : /* avoid dangling else. */
8058 : 33516 : if (! (SymbolTable_IsConstStringKnown (Actual)))
8059 : : {} /* empty. */
8060 : 33282 : else if ((SymbolTable_IsArray (SymbolTable_GetDType (FormalI))) && ((SymbolTable_GetSType (SymbolTable_GetDType (FormalI))) == M2Base_Char))
8061 : : {
8062 : : /* avoid dangling else. */
8063 : : }
8064 : 33258 : else if ((SymbolTable_GetStringLength (paramtok, Actual)) == 1)
8065 : : {
8066 : : /* avoid dangling else. */
8067 : 3368 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
8068 : : }
8069 : 29890 : else if (! (SymbolTable_IsUnboundedParamAny (Proc, i)))
8070 : : {
8071 : : /* avoid dangling else. */
8072 : 0 : if (IsForC && ((SymbolTable_GetSType (FormalI)) == M2System_Address))
8073 : : {
8074 : 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);
8075 : : }
8076 : : else
8077 : : {
8078 : 0 : FailParameter (paramtok, (const char *) "cannot pass a string constant to a non unbounded array parameter", 64, Actual, Proc, i);
8079 : : }
8080 : : }
8081 : : }
8082 : : }
8083 : : else
8084 : : {
8085 : 369833 : CheckParameter (paramtok, Actual, Dim, FormalI, Proc, i, static_cast<Lists_List> (NULL), ParamCheckId);
8086 : : }
8087 : : }
8088 : : else
8089 : : {
8090 : 4510 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8091 : : {
8092 : : /* these are varargs, therefore we don't check them */
8093 : 4510 : i = ParamTotal;
8094 : : }
8095 : : else
8096 : : {
8097 : 0 : M2MetaError_MetaErrorT2 (proctok, (const char *) "too many parameters, {%2n} passed to {%1a} ", 43, Proc, i);
8098 : : }
8099 : : }
8100 : 482470 : i += 1;
8101 : 482470 : pi -= 1;
8102 : 482470 : if (M2Options_CompilerDebugging)
8103 : : {
8104 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8105 : 0 : if (i <= ParamTotal)
8106 : : {
8107 : 0 : M2Printf_printf0 ((const char *) "; ", 2);
8108 : : }
8109 : : else
8110 : : {
8111 : 0 : M2Printf_printf0 ((const char *) " ) ; \\n", 7);
8112 : : }
8113 : : }
8114 : : }
8115 : 187538 : }
8116 : :
8117 : :
8118 : : /*
8119 : : CheckProcTypeAndProcedure - checks the ProcType with the call.
8120 : : */
8121 : :
8122 : 47581 : static void CheckProcTypeAndProcedure (unsigned int tokno, unsigned int ProcType, unsigned int call, unsigned int ParamCheckId)
8123 : : {
8124 : 47581 : NameKey_Name n1;
8125 : 47581 : NameKey_Name n2;
8126 : 47581 : unsigned int i;
8127 : 47581 : unsigned int n;
8128 : 47581 : unsigned int t;
8129 : 47581 : unsigned int CheckedProcedure;
8130 : 47581 : M2Error_Error e;
8131 : :
8132 : 47581 : if (((SymbolTable_IsVar (call)) || (SymbolTable_IsTemporary (call))) || (SymbolTable_IsParameter (call)))
8133 : : {
8134 : 580 : CheckedProcedure = SymbolTable_GetDType (call);
8135 : : }
8136 : : else
8137 : : {
8138 : : CheckedProcedure = call;
8139 : : }
8140 : 47581 : if (ProcType != CheckedProcedure)
8141 : : {
8142 : 47071 : n = SymbolTable_NoOfParamAny (ProcType);
8143 : : /* We need to check the formal parameters between the procedure and proc type. */
8144 : 47071 : if (n != (SymbolTable_NoOfParamAny (CheckedProcedure)))
8145 : : {
8146 : 0 : e = M2Error_NewError (SymbolTable_GetDeclaredMod (ProcType));
8147 : 0 : n1 = SymbolTable_GetSymName (call);
8148 : 0 : n2 = SymbolTable_GetSymName (ProcType);
8149 : 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));
8150 : 0 : e = M2Error_ChainError (SymbolTable_GetDeclaredMod (call), e);
8151 : 0 : t = SymbolTable_NoOfParamAny (CheckedProcedure);
8152 : 0 : if (n < 2)
8153 : : {
8154 : 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));
8155 : : }
8156 : : else
8157 : : {
8158 : 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));
8159 : : }
8160 : : }
8161 : : else
8162 : : {
8163 : : i = 1;
8164 : 140303 : while (i <= n)
8165 : : {
8166 : 93232 : if ((SymbolTable_IsVarParamAny (ProcType, i)) != (SymbolTable_IsVarParamAny (CheckedProcedure, i)))
8167 : : {
8168 : 0 : M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2d}", 70, ProcType, SymbolTable_GetNth (ProcType, i), i);
8169 : 0 : M2MetaError_MetaError3 ((const char *) "parameter {%3n} in {%1dD} causes a mismatch it was declared as a {%2d}", 70, call, SymbolTable_GetNth (call, i), i);
8170 : : }
8171 : 93232 : BuildRange (M2Range_InitTypesParameterCheck (tokno, CheckedProcedure, i, SymbolTable_GetNthParamAnyClosest (CheckedProcedure, i, SymbolTable_GetCurrentModule ()), SymbolTable_GetParam (ProcType, i), ParamCheckId));
8172 : 93232 : i += 1;
8173 : : }
8174 : : }
8175 : : }
8176 : 47581 : }
8177 : :
8178 : :
8179 : : /*
8180 : : IsReallyPointer - returns TRUE is sym is a pointer, address or a type declared
8181 : : as a pointer or address.
8182 : : */
8183 : :
8184 : 964 : static bool IsReallyPointer (unsigned int Sym)
8185 : : {
8186 : 964 : if (SymbolTable_IsVar (Sym))
8187 : : {
8188 : 964 : Sym = SymbolTable_GetSType (Sym);
8189 : : }
8190 : 964 : Sym = SymbolTable_SkipType (Sym);
8191 : 964 : return (SymbolTable_IsPointer (Sym)) || (Sym == M2System_Address);
8192 : : /* static analysis guarentees a RETURN statement will be used before here. */
8193 : : __builtin_unreachable ();
8194 : : }
8195 : :
8196 : :
8197 : : /*
8198 : : LegalUnboundedParam - returns TRUE if the parameter, Actual, can legitimately be
8199 : : passed to ProcSym, i, the, Formal, parameter.
8200 : : */
8201 : :
8202 : 9086 : static bool LegalUnboundedParam (unsigned int tokpos, unsigned int ProcSym, unsigned int i, unsigned int ActualType, unsigned int Actual, unsigned int Dimension, unsigned int Formal)
8203 : : {
8204 : 9086 : unsigned int FormalType;
8205 : 9086 : unsigned int n;
8206 : 9086 : unsigned int m;
8207 : :
8208 : 9086 : ActualType = SymbolTable_SkipType (ActualType);
8209 : 9086 : FormalType = SymbolTable_GetDType (Formal);
8210 : 9086 : FormalType = SymbolTable_GetSType (FormalType); /* type of the unbounded ARRAY */
8211 : 9086 : if (SymbolTable_IsArray (ActualType)) /* type of the unbounded ARRAY */
8212 : : {
8213 : 6636 : m = SymbolTable_GetDimension (Formal);
8214 : 6636 : n = 0;
8215 : 13518 : while (SymbolTable_IsArray (ActualType))
8216 : : {
8217 : 6804 : n += 1;
8218 : 6804 : ActualType = SymbolTable_GetDType (ActualType);
8219 : 6804 : if ((m == n) && (ActualType == FormalType))
8220 : : {
8221 : : return true;
8222 : : }
8223 : : }
8224 : 78 : if (n == m)
8225 : : {} /* empty. */
8226 : : else
8227 : : {
8228 : : /* now we fall though and test ActualType against FormalType */
8229 : 24 : if (M2System_IsGenericSystemType (FormalType))
8230 : : {
8231 : : return true;
8232 : : }
8233 : : else
8234 : : {
8235 : 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);
8236 : 12 : return false;
8237 : : }
8238 : : }
8239 : : }
8240 : 2450 : else if (SymbolTable_IsUnbounded (ActualType))
8241 : : {
8242 : : /* avoid dangling else. */
8243 : 36 : if ((Dimension == 0) && ((SymbolTable_GetDimension (Formal)) == (SymbolTable_GetDimension (Actual))))
8244 : : {
8245 : : /* now we fall though and test ActualType against FormalType */
8246 : 0 : ActualType = SymbolTable_GetSType (ActualType);
8247 : : }
8248 : : else
8249 : : {
8250 : 36 : if (M2System_IsGenericSystemType (FormalType))
8251 : : {
8252 : : return true;
8253 : : }
8254 : : else
8255 : : {
8256 : 12 : if (((SymbolTable_GetDimension (Actual))-Dimension) == (SymbolTable_GetDimension (Formal)))
8257 : : {
8258 : 12 : ActualType = SymbolTable_GetSType (ActualType);
8259 : : }
8260 : : else
8261 : : {
8262 : 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);
8263 : 0 : return false;
8264 : : }
8265 : : }
8266 : : }
8267 : : }
8268 : 2480 : if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (FormalType, ActualType)))
8269 : : {
8270 : : /* we think it is legal, but we ask post pass 3 to check as
8271 : : not all types are known at this point */
8272 : 2474 : return true;
8273 : : }
8274 : : else
8275 : : {
8276 : 6 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
8277 : 6 : return false;
8278 : : }
8279 : : /* static analysis guarentees a RETURN statement will be used before here. */
8280 : : __builtin_unreachable ();
8281 : : }
8282 : :
8283 : :
8284 : : /*
8285 : : CheckParameter - checks that types ActualType and FormalType are compatible for parameter
8286 : : passing. ProcSym is the procedure and i is the parameter number.
8287 : :
8288 : : We obey the following rules:
8289 : :
8290 : : (1) we allow WORD, BYTE, LOC to be compitable with any like sized
8291 : : type.
8292 : : (2) we allow ADDRESS to be compatible with any pointer type.
8293 : : (3) we relax INTEGER and CARDINAL checking for Temporary variables.
8294 : :
8295 : : Note that type sizes are checked during the code generation pass.
8296 : : */
8297 : :
8298 : 373201 : 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)
8299 : : {
8300 : 373201 : bool NewList;
8301 : 373201 : unsigned int ActualType;
8302 : 373201 : unsigned int FormalType;
8303 : :
8304 : 373201 : if ((SymbolTable_IsConstString (Actual)) && (! (SymbolTable_IsConstStringKnown (Actual))))
8305 : : {
8306 : : /* Cannot check if the string content is not yet known. */
8307 : : return;
8308 : : }
8309 : 373201 : FormalType = SymbolTable_GetDType (Formal);
8310 : 373201 : if ((SymbolTable_IsConstString (Actual)) && ((SymbolTable_GetStringLength (tokpos, Actual)) == 1)) /* if = 1 then it maybe treated as a char */
8311 : : {
8312 : 3368 : ActualType = M2Base_Char;
8313 : : }
8314 : 369833 : else if (Actual == M2Base_Boolean)
8315 : : {
8316 : : /* avoid dangling else. */
8317 : : ActualType = Actual;
8318 : : }
8319 : : else
8320 : : {
8321 : : /* avoid dangling else. */
8322 : 369833 : ActualType = SymbolTable_GetDType (Actual);
8323 : : }
8324 : 373201 : if (TypeList == NULL)
8325 : : {
8326 : 373201 : NewList = true;
8327 : 373201 : Lists_InitList (&TypeList);
8328 : : }
8329 : : else
8330 : : {
8331 : : NewList = false;
8332 : : }
8333 : 373201 : if (Lists_IsItemInList (TypeList, ActualType))
8334 : : {
8335 : : /* no need to check */
8336 : : return;
8337 : : }
8338 : 373201 : Lists_IncludeItemIntoList (TypeList, ActualType);
8339 : 373201 : if (SymbolTable_IsProcType (FormalType))
8340 : : {
8341 : 47581 : if ((! (SymbolTable_IsProcedure (Actual))) && ((ActualType == SymbolTable_NulSym) || (! (SymbolTable_IsProcType (SymbolTable_SkipType (ActualType))))))
8342 : : {
8343 : 0 : FailParameter (tokpos, (const char *) "expecting a procedure or procedure variable as a parameter", 58, Actual, ProcSym, i);
8344 : 0 : return;
8345 : : }
8346 : 47581 : if ((SymbolTable_IsProcedure (Actual)) && (SymbolTable_IsProcedureNested (Actual)))
8347 : : {
8348 : 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);
8349 : : }
8350 : : /* we can check the return type of both proc types */
8351 : 47581 : if ((ActualType != SymbolTable_NulSym) && (SymbolTable_IsProcType (ActualType)))
8352 : : {
8353 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
8354 : 580 : if (((SymbolTable_GetSType (ActualType)) != SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) == SymbolTable_NulSym))
8355 : : {
8356 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a function whereas the formal procedure parameter is a procedure", 89, Actual, ProcSym, i);
8357 : 0 : return;
8358 : : }
8359 : 580 : else if (((SymbolTable_GetSType (ActualType)) == SymbolTable_NulSym) && ((SymbolTable_GetSType (FormalType)) != SymbolTable_NulSym))
8360 : : {
8361 : : /* avoid dangling else. */
8362 : 0 : FailParameter (tokpos, (const char *) "the item being passed is a procedure whereas the formal procedure parameter is a function", 89, Actual, ProcSym, i);
8363 : 0 : return;
8364 : : }
8365 : 580 : else if (M2Base_AssignmentRequiresWarning (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType)))
8366 : : {
8367 : : /* avoid dangling else. */
8368 : 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);
8369 : 0 : return;
8370 : : }
8371 : 580 : else if (((M2System_IsGenericSystemType (SymbolTable_GetSType (FormalType))) || (M2System_IsGenericSystemType (SymbolTable_GetSType (ActualType)))) || (M2Base_IsAssignmentCompatible (SymbolTable_GetSType (ActualType), SymbolTable_GetSType (FormalType))))
8372 : : {
8373 : : /* avoid dangling else. */
8374 : : }
8375 : : else
8376 : : {
8377 : : /* avoid dangling else. */
8378 : : /* pass */
8379 : 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);
8380 : 0 : return;
8381 : : }
8382 : : }
8383 : : /* now to check each parameter of the proc type */
8384 : 47581 : CheckProcTypeAndProcedure (tokpos, FormalType, Actual, ParamCheckId);
8385 : : }
8386 : 325620 : else if ((ActualType != FormalType) && (ActualType != SymbolTable_NulSym))
8387 : : {
8388 : : /* avoid dangling else. */
8389 : 15320 : if (SymbolTable_IsUnknown (FormalType))
8390 : : {
8391 : 0 : FailParameter (tokpos, (const char *) "procedure parameter type is undeclared", 38, Actual, ProcSym, i);
8392 : 0 : return;
8393 : : }
8394 : 15320 : if ((SymbolTable_IsUnbounded (ActualType)) && (! (SymbolTable_IsUnboundedParamAny (ProcSym, i))))
8395 : : {
8396 : 0 : FailParameter (tokpos, (const char *) "attempting to pass an unbounded array to a NON unbounded parameter", 66, Actual, ProcSym, i);
8397 : 0 : return;
8398 : : }
8399 : 15320 : else if (SymbolTable_IsUnboundedParamAny (ProcSym, i))
8400 : : {
8401 : : /* avoid dangling else. */
8402 : 9086 : if (! (LegalUnboundedParam (tokpos, ProcSym, i, ActualType, Actual, Dimension, Formal)))
8403 : : {
8404 : : return;
8405 : : }
8406 : : }
8407 : 6234 : else if (ActualType != FormalType)
8408 : : {
8409 : : /* avoid dangling else. */
8410 : 6234 : if (M2Base_AssignmentRequiresWarning (FormalType, ActualType))
8411 : : {
8412 : 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);
8413 : : }
8414 : 6234 : else if (((M2System_IsGenericSystemType (FormalType)) || (M2System_IsGenericSystemType (ActualType))) || (M2Base_IsAssignmentCompatible (ActualType, FormalType)))
8415 : : {
8416 : : /* avoid dangling else. */
8417 : : }
8418 : : else
8419 : : {
8420 : : /* avoid dangling else. */
8421 : : /* so far we know it is legal, but not all types have been resolved
8422 : : and so this is checked later on in another pass. */
8423 : 24 : FailParameter (tokpos, (const char *) "identifier with an incompatible type is being passed to this procedure", 70, Actual, ProcSym, i);
8424 : : }
8425 : : }
8426 : : }
8427 : 373183 : if (NewList)
8428 : : {
8429 : 373183 : Lists_KillList (&TypeList);
8430 : : }
8431 : : }
8432 : :
8433 : :
8434 : : /*
8435 : : DescribeType - returns a String describing a symbol, Sym, name and its type.
8436 : : */
8437 : :
8438 : 0 : static DynamicStrings_String DescribeType (unsigned int Sym)
8439 : : {
8440 : 0 : DynamicStrings_String s;
8441 : 0 : DynamicStrings_String s1;
8442 : 0 : DynamicStrings_String s2;
8443 : 0 : unsigned int Low;
8444 : 0 : unsigned int High;
8445 : 0 : unsigned int Subrange;
8446 : 0 : unsigned int Subscript;
8447 : 0 : unsigned int Type;
8448 : :
8449 : 0 : s = static_cast<DynamicStrings_String> (NULL);
8450 : 0 : if (SymbolTable_IsConstString (Sym))
8451 : : {
8452 : : /* If = 1 then it maybe treated as a char. */
8453 : 0 : if ((SymbolTable_IsConstStringKnown (Sym)) && ((SymbolTable_GetStringLength (SymbolTable_GetDeclaredMod (Sym), Sym)) == 1))
8454 : : {
8455 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string) or {%kCHAR}", 29);
8456 : : }
8457 : : else
8458 : : {
8459 : 0 : s = DynamicStrings_InitString ((const char *) "(constant string)", 17);
8460 : : }
8461 : : }
8462 : 0 : else if (SymbolTable_IsConst (Sym))
8463 : : {
8464 : : /* avoid dangling else. */
8465 : 0 : s = DynamicStrings_InitString ((const char *) "(constant)", 10);
8466 : : }
8467 : 0 : else if (SymbolTable_IsUnknown (Sym))
8468 : : {
8469 : : /* avoid dangling else. */
8470 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8471 : : }
8472 : : else
8473 : : {
8474 : : /* avoid dangling else. */
8475 : 0 : Type = SymbolTable_GetSType (Sym);
8476 : 0 : if (Type == SymbolTable_NulSym)
8477 : : {
8478 : 0 : s = DynamicStrings_InitString ((const char *) "(unknown)", 9);
8479 : : }
8480 : 0 : else if (SymbolTable_IsUnbounded (Type))
8481 : : {
8482 : : /* avoid dangling else. */
8483 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetSType (Type)))));
8484 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%%kARRAY} {%%kOF} %s", 21)), (const unsigned char *) &s1, (sizeof (s1)-1));
8485 : : }
8486 : 0 : else if (SymbolTable_IsArray (Type))
8487 : : {
8488 : : /* avoid dangling else. */
8489 : 0 : s = DynamicStrings_InitString ((const char *) "{%kARRAY} [", 11);
8490 : 0 : Subscript = SymbolTable_GetArraySubscript (Type);
8491 : 0 : if (Subscript != SymbolTable_NulSym)
8492 : : {
8493 : 0 : M2Debug_Assert (SymbolTable_IsSubscript (Subscript));
8494 : 0 : Subrange = SymbolTable_GetSType (Subscript);
8495 : 0 : if (! (SymbolTable_IsSubrange (Subrange)))
8496 : : {
8497 : 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);
8498 : : }
8499 : 0 : M2Debug_Assert (SymbolTable_IsSubrange (Subrange));
8500 : 0 : SymbolTable_GetSubrange (Subrange, &High, &Low);
8501 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Low))));
8502 : 0 : s2 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (High))));
8503 : 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))));
8504 : : }
8505 : 0 : s1 = DynamicStrings_Mark (DescribeType (Type));
8506 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "] OF ", 5))), s1);
8507 : : }
8508 : : else
8509 : : {
8510 : : /* avoid dangling else. */
8511 : 0 : if (SymbolTable_IsUnknown (Type))
8512 : : {
8513 : 0 : s1 = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type))));
8514 : 0 : s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%s (currently unknown, check declaration or import)", 51)), (const unsigned char *) &s1, (sizeof (s1)-1));
8515 : : }
8516 : : else
8517 : : {
8518 : 0 : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Type)));
8519 : : }
8520 : : }
8521 : : }
8522 : 0 : return s;
8523 : : /* static analysis guarentees a RETURN statement will be used before here. */
8524 : : __builtin_unreachable ();
8525 : : }
8526 : :
8527 : :
8528 : : /*
8529 : : FailParameter - generates an error message indicating that a parameter
8530 : : declaration has failed.
8531 : :
8532 : : The parameters are:
8533 : :
8534 : : CurrentState - string describing the current failing state.
8535 : : Actual - actual parameter.
8536 : : ParameterNo - parameter number that has failed.
8537 : : ProcedureSym - procedure symbol where parameter has failed.
8538 : :
8539 : : If any parameter is Nul then it is ignored.
8540 : : */
8541 : :
8542 : 42 : static void FailParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
8543 : : {
8544 : 42 : unsigned int FormalParam;
8545 : 42 : DynamicStrings_String Msg;
8546 : 42 : char CurrentState[_CurrentState_high+1];
8547 : :
8548 : : /* make a local copy of each unbounded array. */
8549 : 42 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8550 : :
8551 : 84 : Msg = DynamicStrings_InitString ((const char *) "parameter mismatch between the {%2N} parameter of procedure {%1Ead}, ", 69);
8552 : 42 : Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
8553 : 42 : M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
8554 : 42 : if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
8555 : : {
8556 : 42 : FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
8557 : 42 : if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
8558 : : {
8559 : 18 : M2MetaError_MetaErrorT2 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has an open array type {%2tad}", 54, FormalParam, SymbolTable_GetSType (SymbolTable_GetSType (FormalParam)));
8560 : : }
8561 : : else
8562 : : {
8563 : 24 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "formal parameter {%1ad} has type {%1tad}", 40, FormalParam);
8564 : : }
8565 : : }
8566 : : else
8567 : : {
8568 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "procedure declaration", 21, ProcedureSym);
8569 : : }
8570 : 42 : if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
8571 : : {
8572 : 0 : M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Eda} {%1ad}", 47, Actual);
8573 : : }
8574 : : else
8575 : : {
8576 : 42 : if (SymbolTable_IsVar (Actual))
8577 : : {
8578 : 36 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 87, Actual);
8579 : : }
8580 : : else
8581 : : {
8582 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Eda} {%1ad} of an incompatible type {%1ts}", 78, Actual);
8583 : : }
8584 : : }
8585 : 42 : }
8586 : :
8587 : :
8588 : : /*
8589 : : WarnParameter - generates a warning message indicating that a parameter
8590 : : use might cause problems on another target.
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 : 0 : static void WarnParameter (unsigned int tokpos, const char *CurrentState_, unsigned int _CurrentState_high, unsigned int Actual, unsigned int ProcedureSym, unsigned int ParameterNo)
8601 : : {
8602 : 0 : unsigned int FormalParam;
8603 : 0 : DynamicStrings_String Msg;
8604 : 0 : char CurrentState[_CurrentState_high+1];
8605 : :
8606 : : /* make a local copy of each unbounded array. */
8607 : 0 : memcpy (CurrentState, CurrentState_, _CurrentState_high+1);
8608 : :
8609 : 0 : Msg = DynamicStrings_InitString ((const char *) "{%W}parameter mismatch between the {%2N} parameter of procedure {%1ad}, ", 72);
8610 : 0 : Msg = DynamicStrings_ConCat (Msg, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) CurrentState, _CurrentState_high)));
8611 : 0 : M2MetaError_MetaErrorStringT2 (tokpos, Msg, ProcedureSym, ParameterNo);
8612 : 0 : if ((SymbolTable_NoOfParamAny (ProcedureSym)) >= ParameterNo)
8613 : : {
8614 : 0 : FormalParam = SymbolTable_GetNthParamAnyClosest (ProcedureSym, ParameterNo, SymbolTable_GetCurrentModule ());
8615 : 0 : if (SymbolTable_IsUnboundedParamAny (ProcedureSym, ParameterNo))
8616 : : {
8617 : 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)));
8618 : : }
8619 : : else
8620 : : {
8621 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (FormalParam), (const char *) "{%W}formal parameter {%1ad} has type {%1tad}", 44, FormalParam);
8622 : : }
8623 : : }
8624 : : else
8625 : : {
8626 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetDeclaredMod (ProcedureSym), (const char *) "{%W}procedure declaration", 25, ProcedureSym);
8627 : : }
8628 : 0 : if ((SymbolTable_GetLType (Actual)) == SymbolTable_NulSym)
8629 : : {
8630 : 0 : M2MetaError_MetaError1 ((const char *) "actual parameter being passed is {%1Wda} {%1ad}", 47, Actual);
8631 : : }
8632 : : else
8633 : : {
8634 : 0 : if (SymbolTable_IsVar (Actual))
8635 : : {
8636 : 0 : M2MetaError_MetaErrorT1 (SymbolTable_GetVarDeclFullTok (Actual), (const char *) "actual parameter variable being passed is {%1Wda} {%1ad} of type {%1ts}", 71, Actual);
8637 : : }
8638 : : else
8639 : : {
8640 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "actual parameter being passed is {%1Wda} {%1ad} of type {%1ts}", 62, Actual);
8641 : : }
8642 : : }
8643 : 0 : }
8644 : :
8645 : :
8646 : : /*
8647 : : doIndrX - perform des = *exp with a conversion if necessary.
8648 : : */
8649 : :
8650 : 14433 : static void doIndrX (unsigned int tok, unsigned int des, unsigned int exp)
8651 : : {
8652 : 14433 : unsigned int t;
8653 : :
8654 : 14433 : if ((SymbolTable_GetDType (des)) == (SymbolTable_GetDType (exp)))
8655 : : {
8656 : 14285 : GenQuadOtok (tok, M2Quads_IndrXOp, des, SymbolTable_GetSType (des), exp, true, tok, tok, tok);
8657 : : }
8658 : : else
8659 : : {
8660 : 148 : if (M2Options_StrictTypeAssignment)
8661 : : {
8662 : 148 : BuildRange (M2Range_InitTypesIndrXCheck (tok, des, exp));
8663 : : }
8664 : 148 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8665 : 148 : SymbolTable_PutVar (t, SymbolTable_GetSType (exp));
8666 : 148 : GenQuadOtok (tok, M2Quads_IndrXOp, t, SymbolTable_GetSType (exp), exp, true, tok, tok, tok);
8667 : 148 : GenQuadOtok (tok, M2Quads_BecomesOp, des, SymbolTable_NulSym, doVal (SymbolTable_GetSType (des), t), true, tok, M2LexBuf_UnknownTokenNo, tok);
8668 : : }
8669 : 14433 : }
8670 : :
8671 : :
8672 : : /*
8673 : : MakeRightValue - returns a temporary which will have the RightValue of symbol, Sym.
8674 : : If Sym is a right value and has type, type, then no quadruples are
8675 : : generated and Sym is returned. Otherwise a new temporary is created
8676 : : and an IndrX quadruple is generated.
8677 : : */
8678 : :
8679 : 1060 : static unsigned int MakeRightValue (unsigned int tok, unsigned int Sym, unsigned int type)
8680 : : {
8681 : 1060 : unsigned int t;
8682 : :
8683 : 1060 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_RightValue)
8684 : : {
8685 : 0 : if ((SymbolTable_GetSType (Sym)) == type)
8686 : : {
8687 : : return Sym;
8688 : : }
8689 : : else
8690 : : {
8691 : : /*
8692 : : type change or mode change, type changes are a pain, but I've
8693 : : left them here as it is perhaps easier to remove them later.
8694 : : */
8695 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8696 : 0 : SymbolTable_PutVar (t, type);
8697 : 0 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, doVal (type, Sym), true, tok, tok, tok);
8698 : 0 : return t;
8699 : : }
8700 : : }
8701 : : else
8702 : : {
8703 : 1060 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
8704 : 1060 : SymbolTable_PutVar (t, type);
8705 : 1060 : CheckPointerThroughNil (tok, Sym);
8706 : 1060 : doIndrX (tok, t, Sym);
8707 : 1060 : return t;
8708 : : }
8709 : : /* static analysis guarentees a RETURN statement will be used before here. */
8710 : : __builtin_unreachable ();
8711 : : }
8712 : :
8713 : :
8714 : : /*
8715 : : MakeLeftValue - returns a temporary coresponding to the LeftValue of
8716 : : symbol, Sym. No quadruple is generated if Sym is already
8717 : : a LeftValue and has the same type.
8718 : : */
8719 : :
8720 : 185253 : static unsigned int MakeLeftValue (unsigned int tok, unsigned int Sym, SymbolTable_ModeOfAddr with, unsigned int type)
8721 : : {
8722 : 185253 : unsigned int t;
8723 : :
8724 : 185253 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
8725 : : {
8726 : 4954 : if ((SymbolTable_GetSType (Sym)) == type)
8727 : : {
8728 : : return Sym;
8729 : : }
8730 : : else
8731 : : {
8732 : : /*
8733 : : type change or mode change, type changes are a pain, but I've
8734 : : left them here as it is perhaps easier to remove them later
8735 : : */
8736 : 92 : t = SymbolTable_MakeTemporary (tok, with);
8737 : 92 : SymbolTable_PutVar (t, type);
8738 : 92 : GenQuadOtok (tok, M2Quads_BecomesOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8739 : 92 : return t;
8740 : : }
8741 : : }
8742 : : else
8743 : : {
8744 : 180299 : t = SymbolTable_MakeTemporary (tok, with);
8745 : 180299 : SymbolTable_PutVar (t, type);
8746 : 180299 : GenQuadOtok (tok, M2Quads_AddrOp, t, SymbolTable_NulSym, Sym, true, tok, M2LexBuf_UnknownTokenNo, tok);
8747 : 180299 : return t;
8748 : : }
8749 : : /* static analysis guarentees a RETURN statement will be used before here. */
8750 : : __builtin_unreachable ();
8751 : : }
8752 : :
8753 : :
8754 : : /*
8755 : : ManipulatePseudoCallParameters - manipulates the parameters to a pseudo function or
8756 : : procedure. It dereferences all LeftValue parameters
8757 : : and Boolean parameters.
8758 : : The Stack:
8759 : :
8760 : :
8761 : : Entry Exit
8762 : :
8763 : : Ptr -> exactly the same
8764 : : +----------------+
8765 : : | NoOfParameters |
8766 : : |----------------|
8767 : : | Param 1 |
8768 : : |----------------|
8769 : : | Param 2 |
8770 : : |----------------|
8771 : : . .
8772 : : . .
8773 : : . .
8774 : : |----------------|
8775 : : | Param # |
8776 : : |----------------|
8777 : : | ProcSym | Type |
8778 : : |----------------|
8779 : :
8780 : : */
8781 : :
8782 : 52786 : static void ManipulatePseudoCallParameters (void)
8783 : : {
8784 : 52786 : unsigned int NoOfParameters;
8785 : 52786 : unsigned int ProcSym;
8786 : 52786 : unsigned int Proc;
8787 : 52786 : unsigned int i;
8788 : 52786 : unsigned int pi;
8789 : 52786 : M2Quads_BoolFrame f;
8790 : :
8791 : 52786 : M2Quads_PopT (&NoOfParameters);
8792 : 52786 : M2Quads_PushT (NoOfParameters); /* restored to original state */
8793 : : /* Ptr points to the ProcSym */
8794 : 52786 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((NoOfParameters+1)+1));
8795 : 52786 : if (SymbolTable_IsVar (ProcSym))
8796 : : {
8797 : 0 : M2Error_InternalError ((const char *) "expecting a pseudo procedure or a type", 38);
8798 : : }
8799 : : else
8800 : : {
8801 : 52786 : Proc = ProcSym;
8802 : : }
8803 : 52786 : i = 1;
8804 : 52786 : pi = NoOfParameters+1;
8805 : 115514 : while (i <= NoOfParameters)
8806 : : {
8807 : 62734 : 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)))
8808 : : {
8809 : : /* must dereference LeftValue */
8810 : 884 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8811 : 884 : f->TrueExit = MakeRightValue (M2LexBuf_GetTokenNo (), M2Quads_OperandT (pi), SymbolTable_GetSType (M2Quads_OperandT (pi)));
8812 : : }
8813 : 62728 : i += 1;
8814 : 62728 : pi -= 1;
8815 : : }
8816 : 52780 : }
8817 : :
8818 : :
8819 : : /*
8820 : : ManipulateParameters - manipulates the procedure parameters in
8821 : : preparation for a procedure call.
8822 : : Prepares Boolean, Unbounded and VAR parameters.
8823 : : The Stack:
8824 : :
8825 : :
8826 : : Entry Exit
8827 : :
8828 : : Ptr -> exactly the same
8829 : : +----------------+
8830 : : | NoOfParameters |
8831 : : |----------------|
8832 : : | Param 1 |
8833 : : |----------------|
8834 : : | Param 2 |
8835 : : |----------------|
8836 : : . .
8837 : : . .
8838 : : . .
8839 : : |----------------|
8840 : : | Param # |
8841 : : |----------------|
8842 : : | ProcSym | Type |
8843 : : |----------------|
8844 : : */
8845 : :
8846 : 187538 : static void ManipulateParameters (bool IsForC)
8847 : : {
8848 : 187538 : unsigned int tokpos;
8849 : 187538 : unsigned int np;
8850 : 187538 : DynamicStrings_String s;
8851 : 187538 : unsigned int ArraySym;
8852 : 187538 : unsigned int UnboundedType;
8853 : 187538 : unsigned int ParamType;
8854 : 187538 : unsigned int NoOfParameters;
8855 : 187538 : unsigned int i;
8856 : 187538 : unsigned int pi;
8857 : 187538 : unsigned int ProcSym;
8858 : 187538 : unsigned int rw;
8859 : 187538 : unsigned int Proc;
8860 : 187538 : unsigned int t;
8861 : 187538 : M2Quads_BoolFrame f;
8862 : :
8863 : 187538 : M2Quads_PopT (&NoOfParameters);
8864 : 187538 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParameters+1));
8865 : 187538 : tokpos = OperandTtok (NoOfParameters+1);
8866 : 187538 : if (SymbolTable_IsVar (ProcSym))
8867 : : {
8868 : : /* Procedure Variable ? */
8869 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF (NoOfParameters+1));
8870 : : }
8871 : : else
8872 : : {
8873 : 186818 : Proc = PCSymBuild_SkipConst (ProcSym);
8874 : : }
8875 : 187538 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8876 : : {
8877 : : /* avoid dangling else. */
8878 : 8077 : if (NoOfParameters < (SymbolTable_NoOfParamAny (Proc)))
8879 : : {
8880 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8881 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8882 : 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));
8883 : : }
8884 : : }
8885 : 179461 : else if (SymbolTable_UsesOptArgAny (Proc))
8886 : : {
8887 : : /* avoid dangling else. */
8888 : 3066 : if (! ((NoOfParameters == (SymbolTable_NoOfParamAny (Proc))) || ((NoOfParameters+1) == (SymbolTable_NoOfParamAny (Proc)))))
8889 : : {
8890 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8891 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8892 : 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));
8893 : : }
8894 : : }
8895 : 176395 : else if (NoOfParameters != (SymbolTable_NoOfParamAny (Proc)))
8896 : : {
8897 : : /* avoid dangling else. */
8898 : 0 : s = DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (Proc))));
8899 : 0 : np = SymbolTable_NoOfParamAny (Proc);
8900 : 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));
8901 : : }
8902 : 187538 : i = 1;
8903 : 187538 : pi = NoOfParameters;
8904 : 672794 : while (i <= NoOfParameters)
8905 : : {
8906 : 485256 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pi));
8907 : 485256 : rw = static_cast<unsigned int> (OperandMergeRW (pi));
8908 : 485256 : M2Debug_Assert (SymbolTable_IsLegal (rw));
8909 : 485256 : if (i > (SymbolTable_NoOfParamAny (Proc)))
8910 : : {
8911 : 7296 : if (IsForC && (SymbolTable_UsesVarArgs (Proc)))
8912 : : {
8913 : : /* avoid dangling else. */
8914 : 7296 : if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8915 : : {
8916 : 156 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8917 : 156 : MarkAsReadWrite (rw);
8918 : : }
8919 : 7140 : else if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8920 : : {
8921 : : /* avoid dangling else. */
8922 : 236 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8923 : 236 : MarkAsReadWrite (rw);
8924 : : }
8925 : 6904 : else if (((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (M2Quads_OperandT (pi)))))
8926 : : {
8927 : : /* avoid dangling else. */
8928 : 200 : MarkAsReadWrite (rw);
8929 : : /* pass the address field of an unbounded variable */
8930 : 200 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8931 : 200 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8932 : 200 : M2Quads_PushT (static_cast<unsigned int> (1));
8933 : 200 : BuildAdrFunction ();
8934 : 200 : M2Quads_PopT (&f->TrueExit);
8935 : : }
8936 : 6704 : else if ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue)
8937 : : {
8938 : : /* avoid dangling else. */
8939 : 380 : MarkAsReadWrite (rw);
8940 : : /* must dereference LeftValue (even if we are passing variable as a vararg) */
8941 : 380 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8942 : 380 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
8943 : 380 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
8944 : 380 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
8945 : 380 : f->TrueExit = t;
8946 : : }
8947 : : }
8948 : : else
8949 : : {
8950 : 0 : M2MetaError_MetaErrorT2 (tokpos, (const char *) "attempting to pass too many parameters to procedure {%1a}, the {%2N} parameter does not exist", 93, Proc, i);
8951 : : }
8952 : : }
8953 : 477960 : else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsArray (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8954 : : {
8955 : : /* avoid dangling else. */
8956 : 24 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_RightValue, M2System_Address);
8957 : 24 : MarkAsReadWrite (rw);
8958 : : }
8959 : 477936 : else if (((IsForC && (SymbolTable_IsUnboundedParamAny (Proc, i))) && ((SymbolTable_GetSType (M2Quads_OperandT (pi))) != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetDType (M2Quads_OperandT (pi)))))
8960 : : {
8961 : : /* avoid dangling else. */
8962 : 184 : MarkAsReadWrite (rw);
8963 : : /* pass the address field of an unbounded variable */
8964 : 184 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, M2Quads_OperandTok (pi));
8965 : 184 : PushTFAD (f->TrueExit, f->FalseExit, f->Unbounded, f->Dimension);
8966 : 184 : M2Quads_PushT (static_cast<unsigned int> (1));
8967 : 184 : BuildAdrFunction ();
8968 : 184 : M2Quads_PopT (&f->TrueExit);
8969 : : }
8970 : 477752 : else if ((IsForC && (SymbolTable_IsConstString (M2Quads_OperandT (pi)))) && ((SymbolTable_IsUnboundedParamAny (Proc, i)) || ((SymbolTable_GetDType (SymbolTable_GetParam (Proc, i))) == M2System_Address)))
8971 : : {
8972 : : /* avoid dangling else. */
8973 : 7765 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), DeferMakeConstStringCnul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi)), SymbolTable_RightValue, M2System_Address);
8974 : 7765 : MarkAsReadWrite (rw);
8975 : : }
8976 : 469987 : else if (SymbolTable_IsUnboundedParamAny (Proc, i))
8977 : : {
8978 : : /* avoid dangling else. */
8979 : : /* always pass constant strings with a nul terminator, but leave the HIGH as before. */
8980 : 36077 : if (SymbolTable_IsConstString (M2Quads_OperandT (pi)))
8981 : : {
8982 : : /* this is a Modula-2 string which must be nul terminated. */
8983 : 23871 : f->TrueExit = DeferMakeConstStringM2nul (M2Quads_OperandTok (pi), M2Quads_OperandT (pi));
8984 : : }
8985 : 36077 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
8986 : 36077 : UnboundedType = SymbolTable_GetSType (SymbolTable_GetParam (Proc, i));
8987 : 36077 : SymbolTable_PutVar (t, UnboundedType);
8988 : 36077 : ParamType = SymbolTable_GetSType (UnboundedType);
8989 : 36077 : if ((OperandD (pi)) == 0)
8990 : : {
8991 : 36029 : ArraySym = static_cast<unsigned int> (M2Quads_OperandT (pi));
8992 : : }
8993 : : else
8994 : : {
8995 : 48 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (pi));
8996 : : }
8997 : 36077 : if (SymbolTable_IsVarParamAny (Proc, i))
8998 : : {
8999 : 4214 : MarkArrayWritten (M2Quads_OperandT (pi));
9000 : 4214 : MarkArrayWritten (M2Quads_OperandA (pi));
9001 : 4214 : MarkAsReadWrite (rw);
9002 : 4214 : AssignUnboundedVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
9003 : : }
9004 : : else
9005 : : {
9006 : 31863 : MarkAsRead (rw);
9007 : 31863 : AssignUnboundedNonVar (OperandTtok (pi), M2Quads_OperandT (pi), ArraySym, t, ParamType, OperandD (pi));
9008 : : }
9009 : 36077 : f->TrueExit = t;
9010 : : }
9011 : 433910 : else if (SymbolTable_IsVarParamAny (Proc, i))
9012 : : {
9013 : : /* avoid dangling else. */
9014 : : /* must reference by address, but we contain the type of the referenced entity */
9015 : 14068 : MarkArrayWritten (M2Quads_OperandT (pi));
9016 : 14068 : MarkArrayWritten (M2Quads_OperandA (pi));
9017 : 14068 : MarkAsReadWrite (rw);
9018 : 14068 : f->TrueExit = MakeLeftValue (M2Quads_OperandTok (pi), M2Quads_OperandT (pi), SymbolTable_LeftValue, SymbolTable_GetSType (SymbolTable_GetParam (Proc, i)));
9019 : : }
9020 : 419842 : else if ((! (SymbolTable_IsVarParamAny (Proc, i))) && ((SymbolTable_GetMode (M2Quads_OperandT (pi))) == SymbolTable_LeftValue))
9021 : : {
9022 : : /* avoid dangling else. */
9023 : : /* must dereference LeftValue */
9024 : 1334 : t = SymbolTable_MakeTemporary (M2Quads_OperandTok (pi), SymbolTable_RightValue);
9025 : 1334 : SymbolTable_PutVar (t, SymbolTable_GetSType (M2Quads_OperandT (pi)));
9026 : 1334 : CheckPointerThroughNil (tokpos, M2Quads_OperandT (pi));
9027 : 1334 : doIndrX (M2Quads_OperandTok (pi), t, M2Quads_OperandT (pi));
9028 : 1334 : f->TrueExit = t;
9029 : 1334 : MarkAsRead (rw);
9030 : : }
9031 : : else
9032 : : {
9033 : : /* avoid dangling else. */
9034 : 418508 : MarkAsRead (rw);
9035 : : }
9036 : 485256 : i += 1;
9037 : 485256 : pi -= 1;
9038 : : }
9039 : 187538 : M2Quads_PushT (NoOfParameters);
9040 : 187538 : }
9041 : :
9042 : :
9043 : : /*
9044 : : CheckParameterOrdinals - check that ordinal values are within type range.
9045 : : */
9046 : :
9047 : 187538 : static void CheckParameterOrdinals (void)
9048 : : {
9049 : 187538 : unsigned int tokno;
9050 : 187538 : unsigned int Proc;
9051 : 187538 : unsigned int ProcSym;
9052 : 187538 : unsigned int Actual;
9053 : 187538 : unsigned int FormalI;
9054 : 187538 : unsigned int ParamTotal;
9055 : 187538 : unsigned int pi;
9056 : 187538 : unsigned int i;
9057 : :
9058 : 187538 : M2Quads_PopT (&ParamTotal);
9059 : 187538 : M2Quads_PushT (ParamTotal); /* Restore stack to origional state */
9060 : 187538 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT ((ParamTotal+1)+1)); /* Restore stack to origional state */
9061 : 187538 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (SymbolTable_GetDType (ProcSym))))
9062 : : {
9063 : : /* Indirect procedure call. */
9064 : 720 : Proc = SymbolTable_SkipType (M2Quads_OperandF ((ParamTotal+1)+1));
9065 : : }
9066 : : else
9067 : : {
9068 : 186818 : Proc = PCSymBuild_SkipConst (ProcSym);
9069 : : }
9070 : 187538 : i = 1;
9071 : 187538 : pi = ParamTotal+1; /* stack index referencing stacked parameter, i */
9072 : 672794 : while (i <= ParamTotal) /* stack index referencing stacked parameter, i */
9073 : : {
9074 : 485256 : if (i <= (SymbolTable_NoOfParamAny (Proc)))
9075 : : {
9076 : 477960 : FormalI = SymbolTable_GetParam (Proc, i);
9077 : 477960 : Actual = static_cast<unsigned int> (M2Quads_OperandT (pi));
9078 : 477960 : tokno = static_cast<unsigned int> (M2Quads_OperandTok (pi));
9079 : 477960 : if (M2Base_IsOrdinalType (SymbolTable_GetLType (FormalI)))
9080 : : {
9081 : 123415 : if (! (SymbolTable_IsSet (SymbolTable_GetDType (FormalI))))
9082 : : {
9083 : : /* Tell the code generator to test the runtime values of the assignment
9084 : : so ensure we catch overflow and underflow. */
9085 : 123415 : BuildRange (M2Range_InitParameterRangeCheck (tokno, Proc, i, FormalI, Actual, OperandRangeDep (pi)));
9086 : : }
9087 : : }
9088 : : }
9089 : 485256 : i += 1;
9090 : 485256 : pi -= 1;
9091 : : }
9092 : 187538 : }
9093 : :
9094 : :
9095 : : /*
9096 : : IsSameUnbounded - returns TRUE if unbounded types, t1, and, t2,
9097 : : are compatible.
9098 : : */
9099 : :
9100 : 36 : static bool IsSameUnbounded (unsigned int t1, unsigned int t2)
9101 : : {
9102 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t1));
9103 : 36 : M2Debug_Assert (SymbolTable_IsUnbounded (t2));
9104 : 36 : return (SymbolTable_GetDType (t1)) == (SymbolTable_GetDType (t2));
9105 : : /* static analysis guarentees a RETURN statement will be used before here. */
9106 : : __builtin_unreachable ();
9107 : : }
9108 : :
9109 : :
9110 : : /*
9111 : : AssignUnboundedVar - assigns an Unbounded symbol fields,
9112 : : ArrayAddress and ArrayHigh, from an array symbol.
9113 : : UnboundedSym is not a VAR parameter and therefore
9114 : : this procedure can complete both of the fields.
9115 : : Sym can be a Variable with type Unbounded.
9116 : : Sym can be a Variable with type Array.
9117 : : Sym can be a String Constant.
9118 : :
9119 : : ParamType is the TYPE of the parameter
9120 : : */
9121 : :
9122 : 4214 : static void AssignUnboundedVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9123 : : {
9124 : 4214 : unsigned int Type;
9125 : :
9126 : 4214 : if (SymbolTable_IsConst (Sym))
9127 : : {
9128 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9129 : : }
9130 : 4214 : else if (SymbolTable_IsVar (Sym))
9131 : : {
9132 : : /* avoid dangling else. */
9133 : 4214 : Type = SymbolTable_GetDType (Sym);
9134 : 4214 : if (Type == SymbolTable_NulSym)
9135 : : {
9136 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a VAR formal parameter", 65, Sym);
9137 : : }
9138 : 4214 : else if (SymbolTable_IsUnbounded (Type))
9139 : : {
9140 : : /* avoid dangling else. */
9141 : 1274 : if (Type == (SymbolTable_GetSType (UnboundedSym)))
9142 : : {
9143 : : /* Copy Unbounded Symbol ie. UnboundedSym := Sym */
9144 : 1238 : M2Quads_PushT (UnboundedSym);
9145 : 1238 : M2Quads_PushT (Sym);
9146 : 1238 : BuildAssignmentWithoutBounds (tok, false, true);
9147 : : }
9148 : 36 : else if ((IsSameUnbounded (Type, SymbolTable_GetSType (UnboundedSym))) || (M2System_IsGenericSystemType (ParamType)))
9149 : : {
9150 : : /* avoid dangling else. */
9151 : 36 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9152 : : }
9153 : : else
9154 : : {
9155 : : /* avoid dangling else. */
9156 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9157 : : }
9158 : : }
9159 : 2940 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9160 : : {
9161 : : /* avoid dangling else. */
9162 : 2940 : UnboundedVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9163 : : }
9164 : : else
9165 : : {
9166 : : /* avoid dangling else. */
9167 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9168 : : }
9169 : : }
9170 : : else
9171 : : {
9172 : : /* avoid dangling else. */
9173 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} cannot be passed to a VAR formal parameter", 49, Sym);
9174 : : }
9175 : 4214 : }
9176 : :
9177 : :
9178 : : /*
9179 : : AssignUnboundedNonVar - assigns an Unbounded symbol fields,
9180 : : The difference between this procedure and
9181 : : AssignUnboundedVar is that this procedure cannot
9182 : : set the Unbounded.Address since the data from
9183 : : Sym will be copied because parameter is NOT a VAR
9184 : : parameter.
9185 : : UnboundedSym is not a VAR parameter and therefore
9186 : : this procedure can only complete the HIGH field
9187 : : and not the ADDRESS field.
9188 : : Sym can be a Variable with type Unbounded.
9189 : : Sym can be a Variable with type Array.
9190 : : Sym can be a String Constant.
9191 : :
9192 : : ParamType is the TYPE of the paramater
9193 : : */
9194 : :
9195 : 31863 : static void AssignUnboundedNonVar (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9196 : : {
9197 : 31863 : unsigned int Type;
9198 : :
9199 : 31863 : if (SymbolTable_IsConst (Sym)) /* was IsConstString(Sym) */
9200 : : {
9201 : 23925 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9202 : : }
9203 : 7938 : else if (SymbolTable_IsVar (Sym))
9204 : : {
9205 : : /* avoid dangling else. */
9206 : 7938 : Type = SymbolTable_GetDType (Sym);
9207 : 7938 : if (Type == SymbolTable_NulSym)
9208 : : {
9209 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "{%1ad} has no type and cannot be passed to a non VAR formal parameter", 69, Sym);
9210 : : }
9211 : 7938 : else if (SymbolTable_IsUnbounded (Type))
9212 : : {
9213 : : /* avoid dangling else. */
9214 : 3396 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9215 : : }
9216 : 4542 : else if ((SymbolTable_IsArray (Type)) || (M2System_IsGenericSystemType (ParamType)))
9217 : : {
9218 : : /* avoid dangling else. */
9219 : 4530 : UnboundedNonVarLinkToArray (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9220 : : }
9221 : : else
9222 : : {
9223 : : /* avoid dangling else. */
9224 : 12 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal type parameter {%1Ead} expecting array or dynamic array", 63, Sym);
9225 : : }
9226 : : }
9227 : : else
9228 : : {
9229 : : /* avoid dangling else. */
9230 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "illegal parameter {%1Ead} which cannot be passed as {%kVAR} {%kARRAY} {%kOF} {%1tsad}", 85, Sym);
9231 : : }
9232 : 31863 : }
9233 : :
9234 : :
9235 : : /*
9236 : : GenHigh - generates a HighOp but it checks if op3 is a
9237 : : L value and if so it dereferences it. This
9238 : : is inefficient, however it is clean and we let the gcc
9239 : : backend detect these as common subexpressions.
9240 : : It will also detect that a R value -> L value -> R value
9241 : : via indirection and eleminate these.
9242 : : */
9243 : :
9244 : 37095 : static void GenHigh (unsigned int tok, unsigned int op1, unsigned int op2, unsigned int op3)
9245 : : {
9246 : 37095 : unsigned int sym;
9247 : :
9248 : 37095 : if (((SymbolTable_GetMode (op3)) == SymbolTable_LeftValue) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (op3))))
9249 : : {
9250 : 48 : sym = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9251 : 48 : SymbolTable_PutVar (sym, SymbolTable_GetSType (op3));
9252 : 48 : doIndrX (tok, sym, op3);
9253 : 48 : GenQuadO (tok, M2Quads_HighOp, op1, op2, sym, true);
9254 : : }
9255 : : else
9256 : : {
9257 : 37047 : GenQuadO (tok, M2Quads_HighOp, op1, op2, op3, true);
9258 : : }
9259 : 37095 : }
9260 : :
9261 : :
9262 : : /*
9263 : : AssignHighField -
9264 : : */
9265 : :
9266 : 34983 : static void AssignHighField (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int actuali, unsigned int formali)
9267 : : {
9268 : 34983 : unsigned int ReturnVar;
9269 : 34983 : unsigned int ArrayType;
9270 : 34983 : unsigned int Field;
9271 : :
9272 : : /* Unbounded.ArrayHigh := HIGH(ArraySym) */
9273 : 34983 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9274 : 34983 : Field = SymbolTable_GetUnboundedHighOffset (SymbolTable_GetSType (UnboundedSym), formali);
9275 : 34983 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9276 : 34983 : M2Quads_PushT (static_cast<unsigned int> (1));
9277 : 34983 : M2Quads_BuildDesignatorRecord (tok);
9278 : 34983 : if (M2System_IsGenericSystemType (ParamType))
9279 : : {
9280 : 1188 : if (SymbolTable_IsConstString (Sym))
9281 : : {
9282 : 18 : M2Quads_PushTtok (DeferMakeLengthConst (tok, Sym), tok);
9283 : : }
9284 : : else
9285 : : {
9286 : 1170 : ArrayType = SymbolTable_GetSType (Sym);
9287 : 1170 : if (SymbolTable_IsUnbounded (ArrayType))
9288 : : {
9289 : : /*
9290 : : * SIZE(parameter) DIV TSIZE(ParamType)
9291 : : * however in this case parameter
9292 : : * is an unbounded symbol and therefore we must use
9293 : : * (HIGH(parameter)+1)*SIZE(unbounded type) DIV TSIZE(ParamType)
9294 : : *
9295 : : * we call upon the function SIZE(ArraySym)
9296 : : * remember SIZE doubles as
9297 : : * (HIGH(a)+1) * SIZE(ArrayType) for unbounded symbols
9298 : : */
9299 : 294 : M2Quads_PushTFtok (calculateMultipicand (tok, ArraySym, ArrayType, actuali-1), M2Base_Cardinal, tok);
9300 : 294 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9301 : 294 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9302 : 294 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9303 : 294 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9304 : 294 : M2Quads_BuildFunctionCall (false); /* 1 parameter for TSIZE() */
9305 : 294 : M2Quads_BuildBinaryOp ();
9306 : : }
9307 : : else
9308 : : {
9309 : : /* SIZE(parameter) DIV TSIZE(ParamType) */
9310 : 876 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ArrayType) */
9311 : 876 : M2Quads_PushTtok (ArrayType, tok); /* TSIZE(ArrayType) */
9312 : 876 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9313 : 876 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9314 : 876 : M2Quads_PushT (M2Reserved_DivideTok); /* Divide by */
9315 : 876 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, tok); /* TSIZE(ParamType) */
9316 : 876 : M2Quads_PushTtok (ParamType, tok); /* TSIZE(ParamType) */
9317 : 876 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for TSIZE() */
9318 : 876 : M2Quads_BuildFunctionCall (true); /* 1 parameter for TSIZE() */
9319 : 876 : M2Quads_BuildBinaryOp ();
9320 : : }
9321 : : /* now convert from no of elements into HIGH by subtracting 1 */
9322 : 1170 : M2Quads_PushT (M2Reserved_MinusTok); /* -1 */
9323 : 1170 : M2Quads_PushTtok (SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), tok); /* -1 */
9324 : 1170 : M2Quads_BuildBinaryOp ();
9325 : : }
9326 : : }
9327 : : else
9328 : : {
9329 : 33795 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
9330 : 33795 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
9331 : 33795 : if (((actuali != formali) && (ArraySym != SymbolTable_NulSym)) && (SymbolTable_IsUnbounded (SymbolTable_GetSType (ArraySym))))
9332 : : {
9333 : 12 : GenHigh (tok, ReturnVar, actuali, ArraySym);
9334 : : }
9335 : : else
9336 : : {
9337 : 33783 : GenHigh (tok, ReturnVar, formali, Sym);
9338 : : }
9339 : 33795 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
9340 : : }
9341 : 34983 : BuildAssignmentWithoutBounds (tok, false, true);
9342 : 34983 : }
9343 : :
9344 : :
9345 : : /*
9346 : : AssignHighFields -
9347 : : */
9348 : :
9349 : 34827 : static void AssignHighFields (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9350 : : {
9351 : 34827 : unsigned int type;
9352 : 34827 : unsigned int actuali;
9353 : 34827 : unsigned int formali;
9354 : 34827 : unsigned int actualn;
9355 : 34827 : unsigned int formaln;
9356 : :
9357 : 34827 : type = SymbolTable_GetDType (Sym);
9358 : 34827 : actualn = 1;
9359 : 34827 : if ((type != SymbolTable_NulSym) && ((SymbolTable_IsUnbounded (type)) || (SymbolTable_IsArray (type))))
9360 : : {
9361 : 10056 : actualn = SymbolTable_GetDimension (type);
9362 : : }
9363 : 34827 : actuali = dim+1;
9364 : 34827 : formali = 1;
9365 : 34827 : formaln = SymbolTable_GetDimension (SymbolTable_GetDType (UnboundedSym));
9366 : 69810 : while ((actuali < actualn) && (formali < formaln))
9367 : : {
9368 : 156 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, SymbolTable_NulSym, actuali, formali);
9369 : 156 : actuali += 1;
9370 : 156 : formali += 1;
9371 : : }
9372 : 34827 : AssignHighField (tok, Sym, ArraySym, UnboundedSym, ParamType, actuali, formali);
9373 : 34827 : }
9374 : :
9375 : :
9376 : : /*
9377 : : UnboundedNonVarLinkToArray - links an array, ArraySym, to an unbounded
9378 : : array, UnboundedSym. The parameter is a
9379 : : NON VAR variety.
9380 : : */
9381 : :
9382 : 31851 : static void UnboundedNonVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9383 : : {
9384 : 31851 : unsigned int Field;
9385 : 31851 : unsigned int AddressField;
9386 : :
9387 : : /* Unbounded.ArrayAddress := to be assigned at runtime. */
9388 : 31851 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9389 : 31851 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9390 : 31851 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9391 : 31851 : M2Quads_PushT (static_cast<unsigned int> (1));
9392 : 31851 : M2Quads_BuildDesignatorRecord (tok);
9393 : 31851 : M2Quads_PopT (&AddressField);
9394 : : /* caller saves non var unbounded array contents. */
9395 : 63702 : GenQuadO (tok, M2Quads_UnboundedOp, AddressField, SymbolTable_NulSym, Sym, false);
9396 : 31851 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9397 : 31851 : }
9398 : :
9399 : :
9400 : : /*
9401 : : UnboundedVarLinkToArray - links an array, ArraySym, to an unbounded array,
9402 : : UnboundedSym. The parameter is a VAR variety.
9403 : : */
9404 : :
9405 : 2976 : static void UnboundedVarLinkToArray (unsigned int tok, unsigned int Sym, unsigned int ArraySym, unsigned int UnboundedSym, unsigned int ParamType, unsigned int dim)
9406 : : {
9407 : 2976 : unsigned int SymType;
9408 : 2976 : unsigned int Field;
9409 : :
9410 : 2976 : SymType = SymbolTable_GetSType (Sym);
9411 : : /* Unbounded.ArrayAddress := ADR(Sym) */
9412 : 2976 : M2Quads_PushTFtok (UnboundedSym, SymbolTable_GetSType (UnboundedSym), tok);
9413 : 2976 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
9414 : 2976 : M2Quads_PushTFtok (Field, SymbolTable_GetSType (Field), tok);
9415 : 2976 : M2Quads_PushT (static_cast<unsigned int> (1));
9416 : 2976 : M2Quads_BuildDesignatorRecord (tok);
9417 : 2976 : M2Quads_PushTFtok (M2System_Adr, M2System_Address, tok); /* ADR (Sym). */
9418 : 2976 : if ((SymbolTable_IsUnbounded (SymType)) && (dim == 0)) /* ADR (Sym). */
9419 : : {
9420 : 12 : PushTFADtok (Sym, SymType, UnboundedSym, dim, tok);
9421 : : }
9422 : : else
9423 : : {
9424 : 2964 : PushTFADtok (Sym, SymType, ArraySym, dim, tok);
9425 : : }
9426 : 2976 : M2Quads_PushT (static_cast<unsigned int> (1)); /* 1 parameter for ADR(). */
9427 : 2976 : M2Quads_BuildFunctionCall (false); /* 1 parameter for ADR(). */
9428 : 2976 : BuildAssignmentWithoutBounds (tok, false, true);
9429 : 2976 : AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim);
9430 : 2976 : }
9431 : :
9432 : :
9433 : : /*
9434 : : BuildPseudoProcedureCall - builds a pseudo procedure call.
9435 : : This procedure does not directly alter the
9436 : : stack, but by calling routines the stack
9437 : : will change in the following way when this
9438 : : procedure returns.
9439 : :
9440 : : The Stack:
9441 : :
9442 : :
9443 : : Entry Exit
9444 : :
9445 : : Ptr ->
9446 : : +----------------+
9447 : : | NoOfParam |
9448 : : |----------------|
9449 : : | Param 1 |
9450 : : |----------------|
9451 : : | Param 2 |
9452 : : |----------------|
9453 : : . .
9454 : : . .
9455 : : . .
9456 : : |----------------|
9457 : : | Param # |
9458 : : |----------------|
9459 : : | ProcSym | Type | Empty
9460 : : |----------------|
9461 : : */
9462 : :
9463 : 18330 : static void BuildPseudoProcedureCall (unsigned int tokno)
9464 : : {
9465 : 18330 : unsigned int NoOfParam;
9466 : 18330 : unsigned int ProcSym;
9467 : :
9468 : 18330 : M2Quads_PopT (&NoOfParam);
9469 : 18330 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
9470 : 18330 : M2Quads_PushT (NoOfParam);
9471 : : /* Compile time stack restored to entry state */
9472 : 18330 : if (ProcSym == M2Base_New)
9473 : : {
9474 : 616 : BuildNewProcedure (tokno);
9475 : : }
9476 : 17714 : else if (ProcSym == M2Base_Dispose)
9477 : : {
9478 : : /* avoid dangling else. */
9479 : 276 : BuildDisposeProcedure (tokno);
9480 : : }
9481 : 17438 : else if (ProcSym == M2Base_Inc)
9482 : : {
9483 : : /* avoid dangling else. */
9484 : 12596 : BuildIncProcedure (tokno);
9485 : : }
9486 : 4842 : else if (ProcSym == M2Base_Dec)
9487 : : {
9488 : : /* avoid dangling else. */
9489 : 3518 : BuildDecProcedure (tokno);
9490 : : }
9491 : 1324 : else if (ProcSym == M2Base_Incl)
9492 : : {
9493 : : /* avoid dangling else. */
9494 : 762 : BuildInclProcedure (tokno);
9495 : : }
9496 : 562 : else if (ProcSym == M2Base_Excl)
9497 : : {
9498 : : /* avoid dangling else. */
9499 : 450 : BuildExclProcedure (tokno);
9500 : : }
9501 : 112 : else if (ProcSym == M2System_Throw)
9502 : : {
9503 : : /* avoid dangling else. */
9504 : 112 : BuildThrowProcedure (tokno);
9505 : : }
9506 : : else
9507 : : {
9508 : : /* avoid dangling else. */
9509 : 0 : M2Error_InternalError ((const char *) "pseudo procedure not implemented yet", 36);
9510 : : }
9511 : 18330 : }
9512 : :
9513 : :
9514 : : /*
9515 : : GetItemPointedTo - returns the symbol type that is being pointed to
9516 : : by Sym.
9517 : : */
9518 : :
9519 : 2314 : static unsigned int GetItemPointedTo (unsigned int Sym)
9520 : : {
9521 : 4636 : if (SymbolTable_IsPointer (Sym))
9522 : : {
9523 : 2314 : return SymbolTable_GetSType (Sym);
9524 : : }
9525 : 2322 : else if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsType (Sym)))
9526 : : {
9527 : : /* avoid dangling else. */
9528 : 2322 : return GetItemPointedTo (SymbolTable_GetSType (Sym));
9529 : : }
9530 : : else
9531 : : {
9532 : : /* avoid dangling else. */
9533 : : return SymbolTable_NulSym;
9534 : : }
9535 : : /* static analysis guarentees a RETURN statement will be used before here. */
9536 : : __builtin_unreachable ();
9537 : : }
9538 : :
9539 : :
9540 : : /*
9541 : : BuildThrowProcedure - builds the pseudo procedure call M2RTS.Throw.
9542 : : The Stack:
9543 : :
9544 : :
9545 : : Entry Exit
9546 : :
9547 : : Ptr ->
9548 : : +----------------+
9549 : : | NoOfParam |
9550 : : |----------------|
9551 : : | Param 1 |
9552 : : |----------------|
9553 : : | Param 2 |
9554 : : |----------------|
9555 : : . .
9556 : : . .
9557 : : . .
9558 : : |----------------|
9559 : : | Param # |
9560 : : |----------------|
9561 : : | ProcSym | Type | Empty
9562 : : |----------------|
9563 : : */
9564 : :
9565 : 112 : static void BuildThrowProcedure (unsigned int functok)
9566 : : {
9567 : 112 : unsigned int op;
9568 : 112 : unsigned int NoOfParam;
9569 : :
9570 : 112 : M2Quads_PopT (&NoOfParam);
9571 : 112 : if (NoOfParam == 1)
9572 : : {
9573 : 112 : op = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9574 : 112 : GenQuadO (functok, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, op, false);
9575 : : }
9576 : : else
9577 : : {
9578 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure %{1Ea} takes one INTEGER parameter", 55, M2System_Throw);
9579 : : }
9580 : 112 : M2Quads_PopN (NoOfParam+1);
9581 : 112 : }
9582 : :
9583 : :
9584 : : /*
9585 : : BuildNewProcedure - builds the pseudo procedure call NEW.
9586 : : This procedure is traditionally a "macro" for
9587 : : NEW(x, ...) --> ALLOCATE(x, TSIZE(x^, ...))
9588 : : One method of implementation is to emulate a "macro"
9589 : : processor by pushing the relevant input tokens
9590 : : back onto the input stack.
9591 : : However this causes two problems:
9592 : :
9593 : : (i) Unnecessary code is produced for x^
9594 : : (ii) SIZE must be imported from SYSTEM
9595 : : Therefore we chose an alternative method of
9596 : : implementation;
9597 : : generate quadruples for ALLOCATE(x, TSIZE(x^, ...))
9598 : : this, although slightly more efficient,
9599 : : is more complex and circumvents problems (i) and (ii).
9600 : :
9601 : : The Stack:
9602 : :
9603 : :
9604 : : Entry Exit
9605 : :
9606 : : Ptr ->
9607 : : +----------------+
9608 : : | NoOfParam |
9609 : : |----------------|
9610 : : | Param 1 |
9611 : : |----------------|
9612 : : | Param 2 |
9613 : : |----------------|
9614 : : . .
9615 : : . .
9616 : : . .
9617 : : |----------------|
9618 : : | Param # |
9619 : : |----------------|
9620 : : | ProcSym | Type | Empty
9621 : : |----------------|
9622 : : */
9623 : :
9624 : 616 : static void BuildNewProcedure (unsigned int functok)
9625 : : {
9626 : 616 : unsigned int NoOfParam;
9627 : 616 : unsigned int SizeSym;
9628 : 616 : unsigned int PtrSym;
9629 : 616 : unsigned int ProcSym;
9630 : 616 : unsigned int paramtok;
9631 : 616 : unsigned int combinedtok;
9632 : :
9633 : 616 : M2Quads_PopT (&NoOfParam);
9634 : 616 : if (NoOfParam >= 1)
9635 : : {
9636 : 616 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "ALLOCATE", 8));
9637 : 616 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9638 : : {
9639 : 616 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9640 : 616 : paramtok = OperandTtok (1);
9641 : 616 : if (IsReallyPointer (PtrSym))
9642 : : {
9643 : 616 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9644 : : /*
9645 : : Build macro: ALLOCATE( PtrSym, SIZE(PtrSym^) )
9646 : : */
9647 : 616 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9648 : : /* x^ */
9649 : 616 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9650 : 616 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9651 : 616 : M2Quads_BuildFunctionCall (false); /* One parameter */
9652 : 616 : M2Quads_PopT (&SizeSym);
9653 : 616 : M2Quads_PushTtok (ProcSym, combinedtok); /* ALLOCATE */
9654 : 616 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9655 : 616 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9656 : 616 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9657 : 616 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9658 : : }
9659 : : else
9660 : : {
9661 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "parameter to {%EkNEW} must be a pointer", 39);
9662 : : }
9663 : : }
9664 : : else
9665 : : {
9666 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}ALLOCATE procedure not found for NEW substitution", 53);
9667 : : }
9668 : : }
9669 : : else
9670 : : {
9671 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkNEW} has one or more parameters", 56);
9672 : : }
9673 : 616 : M2Quads_PopN (NoOfParam+1);
9674 : 616 : }
9675 : :
9676 : :
9677 : : /*
9678 : : BuildDisposeProcedure - builds the pseudo procedure call DISPOSE.
9679 : : This procedure is traditionally a "macro" for
9680 : : DISPOSE(x) --> DEALLOCATE(x, TSIZE(x^))
9681 : : One method of implementation is to emulate a "macro"
9682 : : processor by pushing the relevant input tokens
9683 : : back onto the input stack.
9684 : : However this causes two problems:
9685 : :
9686 : : (i) Unnecessary code is produced for x^
9687 : : (ii) TSIZE must be imported from SYSTEM
9688 : : Therefore we chose an alternative method of
9689 : : implementation;
9690 : : generate quadruples for DEALLOCATE(x, TSIZE(x^))
9691 : : this, although slightly more efficient,
9692 : : is more complex and circumvents problems (i)
9693 : : and (ii).
9694 : :
9695 : : The Stack:
9696 : :
9697 : :
9698 : : Entry Exit
9699 : :
9700 : : Ptr ->
9701 : : +----------------+
9702 : : | NoOfParam |
9703 : : |----------------|
9704 : : | Param 1 |
9705 : : |----------------|
9706 : : | Param 2 |
9707 : : |----------------|
9708 : : . .
9709 : : . .
9710 : : . .
9711 : : |----------------|
9712 : : | Param # |
9713 : : |----------------|
9714 : : | ProcSym | Type | Empty
9715 : : |----------------|
9716 : : */
9717 : :
9718 : 276 : static void BuildDisposeProcedure (unsigned int functok)
9719 : : {
9720 : 276 : unsigned int NoOfParam;
9721 : 276 : unsigned int SizeSym;
9722 : 276 : unsigned int PtrSym;
9723 : 276 : unsigned int ProcSym;
9724 : 276 : unsigned int combinedtok;
9725 : 276 : unsigned int paramtok;
9726 : :
9727 : 276 : M2Quads_PopT (&NoOfParam);
9728 : 276 : if (NoOfParam >= 1)
9729 : : {
9730 : 276 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "DEALLOCATE", 10));
9731 : 276 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
9732 : : {
9733 : 276 : PtrSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
9734 : 276 : paramtok = OperandTtok (1);
9735 : 276 : if (IsReallyPointer (PtrSym))
9736 : : {
9737 : 276 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
9738 : : /*
9739 : : Build macro: DEALLOCATE( PtrSym, TSIZE(PtrSym^) )
9740 : : */
9741 : 276 : M2Quads_PushTFtok (M2System_TSize, M2Base_Cardinal, paramtok); /* Procedure */
9742 : : /* x^ */
9743 : 276 : M2Quads_PushTtok (GetItemPointedTo (PtrSym), paramtok);
9744 : 276 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One parameter */
9745 : 276 : M2Quads_BuildFunctionCall (false); /* One parameter */
9746 : 276 : M2Quads_PopT (&SizeSym);
9747 : 276 : M2Quads_PushTtok (ProcSym, combinedtok); /* DEALLOCATE */
9748 : 276 : M2Quads_PushTtok (PtrSym, paramtok); /* x */
9749 : 276 : M2Quads_PushTtok (SizeSym, paramtok); /* TSIZE(x^) */
9750 : 276 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9751 : 276 : M2Quads_BuildProcedureCall (combinedtok); /* Two parameters */
9752 : : }
9753 : : else
9754 : : {
9755 : 0 : M2MetaError_MetaErrorT0 (paramtok, (const char *) "argument to {%EkDISPOSE} must be a pointer", 42);
9756 : : }
9757 : : }
9758 : : else
9759 : : {
9760 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}DEALLOCATE procedure not found for DISPOSE substitution", 59);
9761 : : }
9762 : : }
9763 : : else
9764 : : {
9765 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the pseudo procedure {%EkDISPOSE} has one or more parameters", 60);
9766 : : }
9767 : 276 : M2Quads_PopN (NoOfParam+1);
9768 : 276 : }
9769 : :
9770 : :
9771 : : /*
9772 : : CheckRangeIncDec - performs des := des <tok> expr
9773 : : with range checking (if enabled).
9774 : :
9775 : : Stack
9776 : : Entry Exit
9777 : :
9778 : : +------------+
9779 : : empty | des + expr |
9780 : : |------------|
9781 : : */
9782 : :
9783 : 16114 : static void CheckRangeIncDec (unsigned int tokenpos, unsigned int des, unsigned int expr, NameKey_Name tok)
9784 : : {
9785 : 16114 : unsigned int dtype;
9786 : 16114 : unsigned int etype;
9787 : :
9788 : 16114 : dtype = SymbolTable_GetDType (des);
9789 : 16114 : etype = SymbolTable_GetDType (expr);
9790 : 16114 : if ((etype == SymbolTable_NulSym) && (SymbolTable_IsPointer (SymbolTable_GetTypeMode (des))))
9791 : : {
9792 : 24 : expr = ConvertToAddress (tokenpos, expr);
9793 : 24 : etype = M2System_Address;
9794 : : }
9795 : 16114 : if (M2Options_WholeValueChecking && ! MustNotCheckBounds)
9796 : : {
9797 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
9798 : 1476 : if (tok == M2Reserved_PlusTok)
9799 : : {
9800 : 792 : BuildRange (M2Range_InitIncRangeCheck (des, expr));
9801 : : }
9802 : : else
9803 : : {
9804 : 684 : BuildRange (M2Range_InitDecRangeCheck (des, expr));
9805 : : }
9806 : : }
9807 : 16114 : if (M2Base_IsExpressionCompatible (dtype, etype))
9808 : : {
9809 : : /* the easy case simulate a straightforward macro */
9810 : 14692 : M2Quads_PushTFtok (des, dtype, tokenpos);
9811 : 14692 : M2Quads_PushT (tok);
9812 : 14692 : M2Quads_PushTFtok (expr, etype, tokenpos);
9813 : 14692 : doBuildBinaryOp (false, true);
9814 : : }
9815 : : else
9816 : : {
9817 : 1422 : if ((((M2Base_IsOrdinalType (dtype)) || (dtype == M2System_Address)) || (SymbolTable_IsPointer (dtype))) && (((M2Base_IsOrdinalType (etype)) || (etype == M2System_Address)) || (SymbolTable_IsPointer (etype))))
9818 : : {
9819 : 1422 : M2Quads_PushTFtok (des, dtype, tokenpos);
9820 : 1422 : M2Quads_PushT (tok);
9821 : 1422 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
9822 : 1422 : M2Quads_PushTtok (dtype, tokenpos);
9823 : 1422 : M2Quads_PushTtok (expr, tokenpos);
9824 : 1422 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
9825 : 1422 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
9826 : 1422 : doBuildBinaryOp (false, true);
9827 : : }
9828 : : else
9829 : : {
9830 : 0 : if (tok == M2Reserved_PlusTok)
9831 : : {
9832 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkINC} using non ordinal types", 47);
9833 : : }
9834 : : else
9835 : : {
9836 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkDEC} using non ordinal types", 47);
9837 : : }
9838 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (tokenpos, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym), static_cast<unsigned int> (SymbolTable_NulSym), tokenpos);
9839 : : }
9840 : : }
9841 : 16114 : }
9842 : :
9843 : :
9844 : : /*
9845 : : BuildIncProcedure - builds the pseudo procedure call INC.
9846 : : INC is a procedure which increments a variable.
9847 : : It takes one or two parameters:
9848 : : INC(a, b) or INC(a)
9849 : : a := a+b or a := a+1
9850 : :
9851 : : The Stack:
9852 : :
9853 : :
9854 : : Entry Exit
9855 : :
9856 : : Ptr ->
9857 : : +----------------+
9858 : : | NoOfParam |
9859 : : |----------------|
9860 : : | Param 1 |
9861 : : |----------------|
9862 : : | Param 2 |
9863 : : |----------------|
9864 : : . .
9865 : : . .
9866 : : . .
9867 : : |----------------|
9868 : : | Param # |
9869 : : |----------------|
9870 : : | ProcSym | Type | Empty
9871 : : |----------------|
9872 : : */
9873 : :
9874 : 12596 : static void BuildIncProcedure (unsigned int proctok)
9875 : : {
9876 : 12596 : unsigned int NoOfParam;
9877 : 12596 : unsigned int dtype;
9878 : 12596 : unsigned int OperandSym;
9879 : 12596 : unsigned int VarSym;
9880 : 12596 : unsigned int TempSym;
9881 : :
9882 : 12596 : M2Quads_PopT (&NoOfParam);
9883 : 12596 : if ((NoOfParam == 1) || (NoOfParam == 2))
9884 : : {
9885 : 12596 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* Bottom/first parameter. */
9886 : 12596 : if (SymbolTable_IsVar (VarSym)) /* Bottom/first parameter. */
9887 : : {
9888 : 12596 : dtype = SymbolTable_GetDType (VarSym);
9889 : 12596 : if (NoOfParam == 2)
9890 : : {
9891 : 2454 : OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
9892 : : }
9893 : : else
9894 : : {
9895 : 10142 : PushOne (proctok, dtype, (const char *) "the {%EkINC} will cause an overflow {%1ad}", 42);
9896 : 10142 : M2Quads_PopT (&OperandSym);
9897 : : }
9898 : 12596 : M2Quads_PushTtok (VarSym, proctok);
9899 : 12596 : TempSym = DereferenceLValue (proctok, VarSym);
9900 : 12596 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_PlusTok); /* TempSym + OperandSym. */
9901 : 12596 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym + OperandSym. */
9902 : : }
9903 : : else
9904 : : {
9905 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9906 : : }
9907 : : }
9908 : : else
9909 : : {
9910 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINC} expects 1 or 2 parameters", 53);
9911 : : }
9912 : 12596 : M2Quads_PopN (NoOfParam+1);
9913 : 12596 : }
9914 : :
9915 : :
9916 : : /*
9917 : : BuildDecProcedure - builds the pseudo procedure call DEC.
9918 : : DEC is a procedure which decrements a variable.
9919 : : It takes one or two parameters:
9920 : : DEC(a, b) or DEC(a)
9921 : : a := a-b or a := a-1
9922 : :
9923 : : The Stack:
9924 : :
9925 : :
9926 : : Entry Exit
9927 : :
9928 : : Ptr ->
9929 : : +----------------+
9930 : : | NoOfParam |
9931 : : |----------------|
9932 : : | Param 1 |
9933 : : |----------------|
9934 : : | Param 2 |
9935 : : |----------------|
9936 : : . .
9937 : : . .
9938 : : . .
9939 : : |----------------|
9940 : : | Param # |
9941 : : |----------------|
9942 : : | ProcSym | Type | Empty
9943 : : |----------------|
9944 : : */
9945 : :
9946 : 3518 : static void BuildDecProcedure (unsigned int proctok)
9947 : : {
9948 : 3518 : unsigned int NoOfParam;
9949 : 3518 : unsigned int dtype;
9950 : 3518 : unsigned int OperandSym;
9951 : 3518 : unsigned int VarSym;
9952 : 3518 : unsigned int TempSym;
9953 : :
9954 : 3518 : M2Quads_PopT (&NoOfParam);
9955 : 3518 : if ((NoOfParam == 1) || (NoOfParam == 2))
9956 : : {
9957 : 3518 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam)); /* Bottom/first parameter. */
9958 : 3518 : if (SymbolTable_IsVar (VarSym)) /* Bottom/first parameter. */
9959 : : {
9960 : 3518 : dtype = SymbolTable_GetDType (VarSym);
9961 : 3518 : if (NoOfParam == 2)
9962 : : {
9963 : 1200 : OperandSym = DereferenceLValue (proctok, M2Quads_OperandT (1));
9964 : : }
9965 : : else
9966 : : {
9967 : 2318 : PushOne (proctok, dtype, (const char *) "the {%EkDEC} will cause an overflow {%1ad}", 42);
9968 : 2318 : M2Quads_PopT (&OperandSym);
9969 : : }
9970 : 3518 : M2Quads_PushTtok (VarSym, proctok);
9971 : 3518 : TempSym = DereferenceLValue (M2Quads_OperandTok (NoOfParam), VarSym);
9972 : 3518 : CheckRangeIncDec (proctok, TempSym, OperandSym, M2Reserved_MinusTok); /* TempSym - OperandSym. */
9973 : 3518 : BuildAssignmentWithoutBounds (proctok, false, true); /* VarSym := TempSym - OperandSym. */
9974 : : }
9975 : : else
9976 : : {
9977 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkDEC} expects a variable as a parameter but was given {%1Ed}", 78, VarSym);
9978 : : }
9979 : : }
9980 : : else
9981 : : {
9982 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkDEC} expects 1 or 2 parameters", 53);
9983 : : }
9984 : 3518 : M2Quads_PopN (NoOfParam+1);
9985 : 3518 : }
9986 : :
9987 : :
9988 : : /*
9989 : : DereferenceLValue - checks to see whether, operand, is declare as an LValue
9990 : : and if so it dereferences it.
9991 : : */
9992 : :
9993 : 26290 : static unsigned int DereferenceLValue (unsigned int tok, unsigned int operand)
9994 : : {
9995 : 26290 : unsigned int sym;
9996 : :
9997 : 26290 : if ((SymbolTable_GetMode (operand)) == SymbolTable_LeftValue)
9998 : : {
9999 : : /* dereference the pointer */
10000 : 1380 : sym = SymbolTable_MakeTemporary (tok, AreConstant (SymbolTable_IsConst (operand)));
10001 : 690 : SymbolTable_PutVar (sym, SymbolTable_GetSType (operand));
10002 : 690 : M2Quads_PushTtok (sym, tok);
10003 : 690 : M2Quads_PushTtok (operand, tok);
10004 : 690 : BuildAssignmentWithoutBounds (tok, false, true);
10005 : 690 : return sym;
10006 : : }
10007 : : else
10008 : : {
10009 : : return operand;
10010 : : }
10011 : : /* static analysis guarentees a RETURN statement will be used before here. */
10012 : : __builtin_unreachable ();
10013 : : }
10014 : :
10015 : :
10016 : : /*
10017 : : BuildInclProcedure - builds the pseudo procedure call INCL.
10018 : : INCL is a procedure which adds bit b into a BITSET a.
10019 : : It takes two parameters:
10020 : : INCL(a, b)
10021 : :
10022 : : a := a + {b}
10023 : :
10024 : : The Stack:
10025 : :
10026 : :
10027 : : Entry Exit
10028 : :
10029 : : Ptr ->
10030 : : +----------------+
10031 : : | NoOfParam |
10032 : : |----------------|
10033 : : | Param 1 |
10034 : : |----------------|
10035 : : | Param 2 |
10036 : : |----------------|
10037 : : | ProcSym | Type | Empty
10038 : : |----------------|
10039 : : */
10040 : :
10041 : 762 : static void BuildInclProcedure (unsigned int proctok)
10042 : : {
10043 : 762 : unsigned int optok;
10044 : 762 : unsigned int NoOfParam;
10045 : 762 : unsigned int DerefSym;
10046 : 762 : unsigned int OperandSym;
10047 : 762 : unsigned int VarSym;
10048 : :
10049 : 762 : M2Quads_PopT (&NoOfParam);
10050 : 762 : if (NoOfParam == 2)
10051 : : {
10052 : 762 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10053 : 762 : MarkArrayWritten (M2Quads_OperandA (2));
10054 : 762 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10055 : 762 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10056 : 762 : if (SymbolTable_IsVar (VarSym))
10057 : : {
10058 : 756 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
10059 : : {
10060 : 756 : DerefSym = DereferenceLValue (optok, OperandSym);
10061 : 756 : BuildRange (M2Range_InitInclCheck (VarSym, DerefSym));
10062 : 756 : GenQuadO (proctok, M2Quads_InclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
10063 : : }
10064 : : else
10065 : : {
10066 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkINCL} must be a set variable but is {%1Ed}", 69, VarSym);
10067 : : }
10068 : : }
10069 : : else
10070 : : {
10071 : 6 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkINCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
10072 : : }
10073 : : }
10074 : : else
10075 : : {
10076 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkINCL} expects 1 or 2 parameters", 54);
10077 : : }
10078 : 762 : M2Quads_PopN (NoOfParam+1);
10079 : 762 : }
10080 : :
10081 : :
10082 : : /*
10083 : : BuildExclProcedure - builds the pseudo procedure call EXCL.
10084 : : INCL is a procedure which removes bit b from SET a.
10085 : : It takes two parameters:
10086 : : EXCL(a, b)
10087 : :
10088 : : a := a - {b}
10089 : :
10090 : : The Stack:
10091 : :
10092 : :
10093 : : Entry Exit
10094 : :
10095 : : Ptr ->
10096 : : +----------------+
10097 : : | NoOfParam |
10098 : : |----------------|
10099 : : | Param 1 |
10100 : : |----------------|
10101 : : | Param 2 |
10102 : : |----------------|
10103 : : | ProcSym | Type | Empty
10104 : : |----------------|
10105 : : */
10106 : :
10107 : 450 : static void BuildExclProcedure (unsigned int proctok)
10108 : : {
10109 : 450 : unsigned int optok;
10110 : 450 : unsigned int NoOfParam;
10111 : 450 : unsigned int DerefSym;
10112 : 450 : unsigned int OperandSym;
10113 : 450 : unsigned int VarSym;
10114 : :
10115 : 450 : M2Quads_PopT (&NoOfParam);
10116 : 450 : if (NoOfParam == 2)
10117 : : {
10118 : 450 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10119 : 450 : MarkArrayWritten (M2Quads_OperandA (2));
10120 : 450 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10121 : 450 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10122 : 450 : if (SymbolTable_IsVar (VarSym))
10123 : : {
10124 : 450 : if (SymbolTable_IsSet (SymbolTable_GetDType (VarSym)))
10125 : : {
10126 : 450 : DerefSym = DereferenceLValue (optok, OperandSym);
10127 : 450 : BuildRange (M2Range_InitExclCheck (VarSym, DerefSym));
10128 : 450 : GenQuadO (proctok, M2Quads_ExclOp, VarSym, SymbolTable_NulSym, DerefSym, false);
10129 : : }
10130 : : else
10131 : : {
10132 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "the first parameter to {%EkEXCL} must be a set variable but is {%1Ed}", 69, VarSym);
10133 : : }
10134 : : }
10135 : : else
10136 : : {
10137 : 0 : M2MetaError_MetaErrorT1 (proctok, (const char *) "base procedure {%EkEXCL} expects a variable as a parameter but is {%1Ed}", 72, VarSym);
10138 : : }
10139 : : }
10140 : : else
10141 : : {
10142 : 0 : M2MetaError_MetaErrorT0 (proctok, (const char *) "the base procedure {%EkEXCL} expects 1 or 2 parameters", 54);
10143 : : }
10144 : 450 : M2Quads_PopN (NoOfParam+1);
10145 : 450 : }
10146 : :
10147 : :
10148 : : /*
10149 : : BuildTypeCoercion - builds the type coersion.
10150 : : Modula-2 allows types to be coersed with no runtime
10151 : : penility.
10152 : : It insists that the TSIZE(t1)=TSIZE(t2) where
10153 : : t2 variable := t2(variable of type t1).
10154 : : The ReturnVar on the stack is of type t2.
10155 : :
10156 : : The Stack:
10157 : :
10158 : :
10159 : : Entry Exit
10160 : :
10161 : : Ptr ->
10162 : : +----------------+
10163 : : | NoOfParam |
10164 : : |----------------|
10165 : : | Param 1 |
10166 : : |----------------|
10167 : : | Param 2 |
10168 : : |----------------|
10169 : : . .
10170 : : . .
10171 : : . .
10172 : : |----------------|
10173 : : | Param # | <- Ptr
10174 : : |----------------| +------------+
10175 : : | ProcSym | Type | | ReturnVar |
10176 : : |----------------| |------------|
10177 : :
10178 : : Quadruples:
10179 : :
10180 : : CoerceOp ReturnVar Type Param1
10181 : :
10182 : : A type coercion will only be legal if the different
10183 : : types have exactly the same size.
10184 : : Since we can only decide this after M2Eval has processed
10185 : : the symbol table then we create a quadruple explaining
10186 : : the coercion taking place, the code generator can test
10187 : : this assertion and report an error if the type sizes
10188 : : differ.
10189 : : */
10190 : :
10191 : 1478 : static void BuildTypeCoercion (bool ConstExpr)
10192 : : {
10193 : 1478 : unsigned int resulttok;
10194 : 1478 : unsigned int proctok;
10195 : 1478 : unsigned int exptok;
10196 : 1478 : unsigned int r;
10197 : 1478 : unsigned int exp;
10198 : 1478 : unsigned int NoOfParam;
10199 : 1478 : unsigned int ReturnVar;
10200 : 1478 : unsigned int ProcSym;
10201 : :
10202 : 1478 : M2Quads_PopT (&NoOfParam);
10203 : 1478 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10204 : 1478 : proctok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10205 : 1478 : if (! (SymbolTable_IsAModula2Type (ProcSym)))
10206 : : {
10207 : 0 : M2MetaError_MetaError1 ((const char *) "coersion expecting a type, seen {%1Ea} which is {%1Ed}", 54, ProcSym);
10208 : : }
10209 : 1478 : if (NoOfParam == 1)
10210 : : {
10211 : 1478 : PopTrwtok (&exp, &r, &exptok);
10212 : 1478 : MarkAsRead (r);
10213 : 1478 : resulttok = M2LexBuf_MakeVirtual2Tok (proctok, exptok);
10214 : 1478 : M2Quads_PopN (1); /* Pop procedure. */
10215 : 1478 : if (ConstExprError (ProcSym, exp, exptok, ConstExpr)) /* Pop procedure. */
10216 : : {
10217 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
10218 : 0 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10219 : : }
10220 : : /* Set ReturnVar's TYPE. */
10221 : 1478 : else if ((SymbolTable_IsConst (exp)) || (SymbolTable_IsVar (exp)))
10222 : : {
10223 : : /* avoid dangling else. */
10224 : 2956 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (SymbolTable_IsConst (exp)));
10225 : 1478 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10226 : 1478 : GenQuad (M2Quads_CoerceOp, ReturnVar, ProcSym, exp); /* Set ReturnVar's TYPE. */
10227 : : }
10228 : : else
10229 : : {
10230 : : /* avoid dangling else. */
10231 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1EMRad} which is not a variable or constant into {%2ad}", 74, exp, ProcSym);
10232 : 0 : M2MetaError_MetaError2 ((const char *) "trying to coerse {%1ECad} which is not a variable or constant into {%2ad}", 73, exp, ProcSym);
10233 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_RightValue);
10234 : 0 : SymbolTable_PutVar (ReturnVar, ProcSym); /* Set ReturnVar's TYPE. */
10235 : : }
10236 : 1478 : M2Quads_PushTFtok (ReturnVar, ProcSym, resulttok);
10237 : : }
10238 : : else
10239 : : {
10240 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only one parameter expected in a TYPE coersion", 50);
10241 : : }
10242 : 1478 : }
10243 : :
10244 : :
10245 : : /*
10246 : : BuildRealFunctionCall - builds a function call.
10247 : : The Stack:
10248 : :
10249 : :
10250 : : Entry Exit
10251 : :
10252 : : Ptr ->
10253 : : +----------------+
10254 : : | NoOfParam |
10255 : : |----------------|
10256 : : | Param 1 |
10257 : : |----------------|
10258 : : | Param 2 |
10259 : : |----------------|
10260 : : . .
10261 : : . .
10262 : : . .
10263 : : |----------------|
10264 : : | Param # | <- Ptr
10265 : : |----------------| +------------+
10266 : : | ProcSym | Type | | ReturnVar |
10267 : : |----------------| |------------|
10268 : : */
10269 : :
10270 : 41106 : static void BuildRealFunctionCall (unsigned int tokno, bool ConstExpr)
10271 : : {
10272 : 41106 : unsigned int NoOfParam;
10273 : 41106 : unsigned int ProcSym;
10274 : :
10275 : 41106 : M2Quads_PopT (&NoOfParam);
10276 : 41106 : M2Quads_PushT (NoOfParam);
10277 : 41106 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+2));
10278 : 41106 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10279 : 41106 : if (SymbolTable_IsVar (ProcSym))
10280 : : {
10281 : : /* Procedure Variable therefore get its type to see if it is a FOR "C" call. */
10282 : 82 : ProcSym = SymbolTable_SkipType (M2Quads_OperandF (NoOfParam+2));
10283 : : }
10284 : 41106 : if ((SymbolTable_IsDefImp (SymbolTable_GetScope (ProcSym))) && (SymbolTable_IsDefinitionForC (SymbolTable_GetScope (ProcSym))))
10285 : : {
10286 : 4954 : BuildRealFuncProcCall (tokno, true, true, ConstExpr);
10287 : : }
10288 : : else
10289 : : {
10290 : 36152 : BuildRealFuncProcCall (tokno, true, false, ConstExpr);
10291 : : }
10292 : 41100 : }
10293 : :
10294 : :
10295 : : /*
10296 : : BuildPseudoFunctionCall - builds the pseudo function
10297 : : The Stack:
10298 : :
10299 : :
10300 : : Entry Exit
10301 : :
10302 : : Ptr ->
10303 : : +----------------+
10304 : : | NoOfParam |
10305 : : |----------------|
10306 : : | Param 1 |
10307 : : |----------------|
10308 : : | Param 2 |
10309 : : |----------------|
10310 : : . .
10311 : : . .
10312 : : . .
10313 : : |----------------|
10314 : : | Param # | <- Ptr
10315 : : |----------------| +------------+
10316 : : | ProcSym | Type | | ReturnVar |
10317 : : |----------------| |------------|
10318 : :
10319 : : */
10320 : :
10321 : 33002 : static void BuildPseudoFunctionCall (bool ConstExpr)
10322 : : {
10323 : 33002 : unsigned int NoOfParam;
10324 : 33002 : unsigned int ProcSym;
10325 : :
10326 : 33002 : M2Quads_PopT (&NoOfParam);
10327 : 33002 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10328 : 33002 : ProcSym = PCSymBuild_SkipConst (ProcSym);
10329 : 33002 : M2Quads_PushT (NoOfParam);
10330 : : /* Compile time stack restored to entry state. */
10331 : 33002 : if (ProcSym == M2Base_High)
10332 : : {
10333 : 2328 : BuildHighFunction ();
10334 : : }
10335 : 30674 : else if (ProcSym == M2Base_LengthS)
10336 : : {
10337 : : /* avoid dangling else. */
10338 : 346 : BuildLengthFunction (ProcSym, ConstExpr);
10339 : : }
10340 : 30328 : else if (ProcSym == M2System_Adr)
10341 : : {
10342 : : /* avoid dangling else. */
10343 : 9666 : BuildAdrFunction ();
10344 : : }
10345 : 20662 : else if (ProcSym == M2Size_Size)
10346 : : {
10347 : : /* avoid dangling else. */
10348 : 2242 : BuildSizeFunction ();
10349 : : }
10350 : 18420 : else if (ProcSym == M2System_TSize)
10351 : : {
10352 : : /* avoid dangling else. */
10353 : 3572 : BuildTSizeFunction ();
10354 : : }
10355 : 14848 : else if (ProcSym == M2System_TBitSize)
10356 : : {
10357 : : /* avoid dangling else. */
10358 : 60 : BuildTBitSizeFunction ();
10359 : : }
10360 : 14788 : else if (ProcSym == M2Base_Convert)
10361 : : {
10362 : : /* avoid dangling else. */
10363 : 12 : BuildConvertFunction (ProcSym, ConstExpr);
10364 : : }
10365 : 14776 : else if (ProcSym == M2Base_Odd)
10366 : : {
10367 : : /* avoid dangling else. */
10368 : 46 : BuildOddFunction (ProcSym, ConstExpr);
10369 : : }
10370 : 14730 : else if (ProcSym == M2Base_Abs)
10371 : : {
10372 : : /* avoid dangling else. */
10373 : 128 : BuildAbsFunction (ProcSym, ConstExpr);
10374 : : }
10375 : 14602 : else if (ProcSym == M2Base_Cap)
10376 : : {
10377 : : /* avoid dangling else. */
10378 : 124 : BuildCapFunction (ProcSym, ConstExpr);
10379 : : }
10380 : 14478 : else if (ProcSym == M2Base_Val)
10381 : : {
10382 : : /* avoid dangling else. */
10383 : 3278 : BuildValFunction (ProcSym, ConstExpr);
10384 : : }
10385 : 11200 : else if (ProcSym == M2Base_Chr)
10386 : : {
10387 : : /* avoid dangling else. */
10388 : 446 : BuildChrFunction (ProcSym, ConstExpr);
10389 : : }
10390 : 10754 : else if (M2Base_IsOrd (ProcSym))
10391 : : {
10392 : : /* avoid dangling else. */
10393 : 3152 : BuildOrdFunction (ProcSym, ConstExpr);
10394 : : }
10395 : 7602 : else if (M2Base_IsInt (ProcSym))
10396 : : {
10397 : : /* avoid dangling else. */
10398 : 6 : BuildIntFunction (ProcSym, ConstExpr);
10399 : : }
10400 : 7596 : else if (M2Base_IsTrunc (ProcSym))
10401 : : {
10402 : : /* avoid dangling else. */
10403 : 60 : BuildTruncFunction (ProcSym, ConstExpr);
10404 : : }
10405 : 7536 : else if (M2Base_IsFloat (ProcSym))
10406 : : {
10407 : : /* avoid dangling else. */
10408 : 64 : BuildFloatFunction (ProcSym, ConstExpr);
10409 : : }
10410 : 7472 : else if (ProcSym == M2Base_Min)
10411 : : {
10412 : : /* avoid dangling else. */
10413 : 1106 : BuildMinFunction ();
10414 : : }
10415 : 6366 : else if (ProcSym == M2Base_Max)
10416 : : {
10417 : : /* avoid dangling else. */
10418 : 4442 : BuildMaxFunction ();
10419 : : }
10420 : 1924 : else if (ProcSym == M2System_AddAdr)
10421 : : {
10422 : : /* avoid dangling else. */
10423 : 36 : BuildAddAdrFunction (ProcSym, ConstExpr);
10424 : : }
10425 : 1888 : else if (ProcSym == M2System_SubAdr)
10426 : : {
10427 : : /* avoid dangling else. */
10428 : 12 : BuildSubAdrFunction (ProcSym, ConstExpr);
10429 : : }
10430 : 1876 : else if (ProcSym == M2System_DifAdr)
10431 : : {
10432 : : /* avoid dangling else. */
10433 : 12 : BuildDifAdrFunction (ProcSym, ConstExpr);
10434 : : }
10435 : 1864 : else if (ProcSym == M2System_Cast)
10436 : : {
10437 : : /* avoid dangling else. */
10438 : 156 : BuildCastFunction (ProcSym, ConstExpr);
10439 : : }
10440 : 1708 : else if (ProcSym == M2System_Shift)
10441 : : {
10442 : : /* avoid dangling else. */
10443 : 702 : BuildShiftFunction ();
10444 : : }
10445 : 1006 : else if (ProcSym == M2System_Rotate)
10446 : : {
10447 : : /* avoid dangling else. */
10448 : 382 : BuildRotateFunction ();
10449 : : }
10450 : 624 : else if (ProcSym == M2System_MakeAdr)
10451 : : {
10452 : : /* avoid dangling else. */
10453 : 12 : BuildMakeAdrFunction ();
10454 : : }
10455 : 612 : else if (ProcSym == M2Base_Re)
10456 : : {
10457 : : /* avoid dangling else. */
10458 : 60 : BuildReFunction (ProcSym, ConstExpr);
10459 : : }
10460 : 552 : else if (ProcSym == M2Base_Im)
10461 : : {
10462 : : /* avoid dangling else. */
10463 : 60 : BuildImFunction (ProcSym, ConstExpr);
10464 : : }
10465 : 492 : else if (ProcSym == M2Base_Cmplx)
10466 : : {
10467 : : /* avoid dangling else. */
10468 : 492 : BuildCmplxFunction (ProcSym, ConstExpr);
10469 : : }
10470 : : else
10471 : : {
10472 : : /* avoid dangling else. */
10473 : 0 : M2Error_InternalError ((const char *) "pseudo function not implemented yet", 35);
10474 : : }
10475 : 32990 : }
10476 : :
10477 : :
10478 : : /*
10479 : : BuildAddAdrFunction - builds the pseudo procedure call ADDADR.
10480 : :
10481 : : PROCEDURE ADDADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10482 : :
10483 : : Which returns address given by (addr + offset),
10484 : : [ the standard says that it _may_
10485 : : "raise an exception if this address is not valid."
10486 : : currently we do not generate any exception code ]
10487 : :
10488 : : The Stack:
10489 : :
10490 : : Entry Exit
10491 : :
10492 : : Ptr ->
10493 : : +----------------+
10494 : : | NoOfParam |
10495 : : |----------------|
10496 : : | Param 1 |
10497 : : |----------------|
10498 : : | Param 2 | <- Ptr
10499 : : |----------------| +------------+
10500 : : | ProcSym | Type | | ReturnVar |
10501 : : |----------------| |------------|
10502 : : */
10503 : :
10504 : 36 : static void BuildAddAdrFunction (unsigned int ProcSym, bool ConstExpr)
10505 : : {
10506 : 36 : unsigned int combinedtok;
10507 : 36 : unsigned int functok;
10508 : 36 : unsigned int vartok;
10509 : 36 : unsigned int optok;
10510 : 36 : unsigned int opa;
10511 : 36 : unsigned int ReturnVar;
10512 : 36 : unsigned int NoOfParam;
10513 : 36 : unsigned int OperandSym;
10514 : 36 : unsigned int VarSym;
10515 : :
10516 : 36 : M2Quads_PopT (&NoOfParam);
10517 : 36 : functok = OperandTtok (NoOfParam+1);
10518 : 36 : if (NoOfParam == 2)
10519 : : {
10520 : 36 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10521 : 36 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10522 : 36 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10523 : 36 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10524 : 36 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10525 : 36 : M2Quads_PopN (NoOfParam+1);
10526 : 36 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10527 : : {
10528 : : /* Fake return result. */
10529 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10530 : : }
10531 : 36 : else if (SymbolTable_IsVar (VarSym))
10532 : : {
10533 : : /* avoid dangling else. */
10534 : 36 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10535 : : {
10536 : 36 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10537 : 36 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10538 : 36 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10539 : 72 : GenQuadOtok (combinedtok, M2Quads_AddOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10540 : 36 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10541 : : }
10542 : : else
10543 : : {
10544 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the first parameter to ADDADR {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}", 113, VarSym);
10545 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10546 : : }
10547 : : }
10548 : : else
10549 : : {
10550 : : /* avoid dangling else. */
10551 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure ADDADR expects a variable of type ADDRESS or POINTER as its first parameter", 96);
10552 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10553 : : }
10554 : : }
10555 : : else
10556 : : {
10557 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkADDADR} expects 2 parameters", 53);
10558 : 0 : M2Quads_PopN (NoOfParam+1);
10559 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10560 : : }
10561 : 36 : }
10562 : :
10563 : :
10564 : : /*
10565 : : BuildSubAdrFunction - builds the pseudo procedure call ADDADR.
10566 : :
10567 : : PROCEDURE SUBADR (addr: ADDRESS; offset: CARDINAL): ADDRESS ;
10568 : :
10569 : : Which returns address given by (addr - offset),
10570 : : [ the standard says that it _may_
10571 : : "raise an exception if this address is not valid."
10572 : : currently we do not generate any exception code ]
10573 : :
10574 : : The Stack:
10575 : :
10576 : : Entry Exit
10577 : :
10578 : : Ptr ->
10579 : : +----------------+
10580 : : | NoOfParam |
10581 : : |----------------|
10582 : : | Param 1 |
10583 : : |----------------|
10584 : : | Param 2 | <- Ptr
10585 : : |----------------| +------------+
10586 : : | ProcSym | Type | | ReturnVar |
10587 : : |----------------| |------------|
10588 : : */
10589 : :
10590 : 12 : static void BuildSubAdrFunction (unsigned int ProcSym, bool ConstExpr)
10591 : : {
10592 : 12 : unsigned int functok;
10593 : 12 : unsigned int combinedtok;
10594 : 12 : unsigned int optok;
10595 : 12 : unsigned int vartok;
10596 : 12 : unsigned int ReturnVar;
10597 : 12 : unsigned int NoOfParam;
10598 : 12 : unsigned int OperandSym;
10599 : 12 : unsigned int opa;
10600 : 12 : unsigned int VarSym;
10601 : :
10602 : 12 : M2Quads_PopT (&NoOfParam);
10603 : 12 : functok = OperandTtok (NoOfParam+1);
10604 : 12 : if (NoOfParam == 2)
10605 : : {
10606 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10607 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10608 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10609 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10610 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10611 : 12 : M2Quads_PopN (NoOfParam+1);
10612 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10613 : : {
10614 : : /* Fake return result. */
10615 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10616 : : }
10617 : 12 : else if (SymbolTable_IsVar (VarSym))
10618 : : {
10619 : : /* avoid dangling else. */
10620 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10621 : : {
10622 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
10623 : 12 : SymbolTable_PutVar (ReturnVar, M2System_Address);
10624 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10625 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, ReturnVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10626 : 12 : M2Quads_PushTFtok (ReturnVar, M2System_Address, combinedtok);
10627 : : }
10628 : : else
10629 : : {
10630 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the first parameter to {%EkSUBADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}", 118, VarSym);
10631 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (vartok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, vartok);
10632 : : }
10633 : : }
10634 : : else
10635 : : {
10636 : : /* avoid dangling else. */
10637 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10638 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10639 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, combinedtok);
10640 : : }
10641 : : }
10642 : : else
10643 : : {
10644 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure {%EkSUBADR} expects 2 parameters", 53);
10645 : 0 : M2Quads_PopN (NoOfParam+1);
10646 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2System_Address), M2System_Address, functok);
10647 : : }
10648 : 12 : }
10649 : :
10650 : :
10651 : : /*
10652 : : BuildDifAdrFunction - builds the pseudo procedure call DIFADR.
10653 : :
10654 : : PROCEDURE DIFADR (addr1, addr2: ADDRESS): INTEGER ;
10655 : :
10656 : : Which returns address given by (addr1 - addr2),
10657 : : [ the standard says that it _may_
10658 : : "raise an exception if this address is invalid or
10659 : : address space is non-contiguous."
10660 : : currently we do not generate any exception code ]
10661 : :
10662 : : The Stack:
10663 : :
10664 : : Entry Exit
10665 : :
10666 : : Ptr ->
10667 : : +----------------+
10668 : : | NoOfParam |
10669 : : |----------------|
10670 : : | Param 1 |
10671 : : |----------------|
10672 : : | Param 2 | <- Ptr
10673 : : |----------------| +------------+
10674 : : | ProcSym | Type | | ReturnVar |
10675 : : |----------------| |------------|
10676 : : */
10677 : :
10678 : 12 : static void BuildDifAdrFunction (unsigned int ProcSym, bool ConstExpr)
10679 : : {
10680 : 12 : unsigned int functok;
10681 : 12 : unsigned int optok;
10682 : 12 : unsigned int vartok;
10683 : 12 : unsigned int combinedtok;
10684 : 12 : unsigned int TempVar;
10685 : 12 : unsigned int NoOfParam;
10686 : 12 : unsigned int OperandSym;
10687 : 12 : unsigned int opa;
10688 : 12 : unsigned int VarSym;
10689 : :
10690 : 12 : M2Quads_PopT (&NoOfParam);
10691 : 12 : functok = OperandTtok (NoOfParam+1);
10692 : 12 : if (NoOfParam >= 1)
10693 : : {
10694 : 12 : OperandSym = static_cast<unsigned int> (M2Quads_OperandT (1));
10695 : 12 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10696 : : }
10697 : : else
10698 : : {
10699 : : optok = functok;
10700 : : }
10701 : 12 : if (NoOfParam == 2)
10702 : : {
10703 : 12 : VarSym = static_cast<unsigned int> (M2Quads_OperandT (2));
10704 : 12 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (2));
10705 : 12 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
10706 : 12 : M2Quads_PopN (NoOfParam+1);
10707 : 12 : if ((ConstExprError (ProcSym, VarSym, vartok, ConstExpr)) || (ConstExprError (ProcSym, OperandSym, optok, ConstExpr)))
10708 : : {
10709 : : /* Fake return result. */
10710 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10711 : : }
10712 : 12 : else if (SymbolTable_IsVar (VarSym))
10713 : : {
10714 : : /* avoid dangling else. */
10715 : 12 : if ((IsReallyPointer (VarSym)) || ((SymbolTable_GetSType (VarSym)) == M2System_Address))
10716 : : {
10717 : 12 : if ((IsReallyPointer (OperandSym)) || ((SymbolTable_GetSType (OperandSym)) == M2System_Address))
10718 : : {
10719 : 12 : TempVar = SymbolTable_MakeTemporary (vartok, SymbolTable_RightValue);
10720 : 12 : SymbolTable_PutVar (TempVar, M2System_Address);
10721 : 12 : opa = ConvertToAddress (optok, DereferenceLValue (optok, OperandSym));
10722 : 24 : GenQuadOtok (combinedtok, M2Quads_SubOp, TempVar, VarSym, opa, true, combinedtok, combinedtok, combinedtok);
10723 : : /*
10724 : : Build macro: CONVERT( INTEGER, TempVar )
10725 : : */
10726 : 12 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
10727 : 12 : M2Quads_PushTtok (M2Base_Integer, functok);
10728 : 12 : M2Quads_PushTtok (TempVar, vartok);
10729 : 12 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
10730 : 12 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
10731 : : }
10732 : : else
10733 : : {
10734 : 0 : M2MetaError_MetaError1 ((const char *) "the second parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}", 119, OperandSym);
10735 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10736 : : }
10737 : : }
10738 : : else
10739 : : {
10740 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "the first parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}", 118, VarSym);
10741 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10742 : : }
10743 : : }
10744 : : else
10745 : : {
10746 : : /* avoid dangling else. */
10747 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter", 101);
10748 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10749 : : }
10750 : : }
10751 : : else
10752 : : {
10753 : 0 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
10754 : 0 : M2MetaError_MetaErrorT0 (combinedtok, (const char *) "{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters", 53);
10755 : 0 : M2Quads_PopN (NoOfParam+1);
10756 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Integer), M2Base_Integer, combinedtok);
10757 : : }
10758 : 12 : }
10759 : :
10760 : :
10761 : : /*
10762 : : BuildHighFunction - checks the stack in preparation for generating
10763 : : quadruples which perform HIGH.
10764 : : This procedure does not alter the stack but
10765 : : determines whether, a, in HIGH(a) is an ArraySym
10766 : : or UnboundedSym.
10767 : : Both cases are different and appropriate quadruple
10768 : : generating routines are called.
10769 : :
10770 : : The Stack:
10771 : :
10772 : :
10773 : : Entry Exit
10774 : :
10775 : : Ptr ->
10776 : : +----------------+
10777 : : | NoOfParam |
10778 : : |----------------|
10779 : : | Param 1 |
10780 : : |----------------|
10781 : : | Param 2 |
10782 : : |----------------|
10783 : : . .
10784 : : . .
10785 : : . .
10786 : : |----------------|
10787 : : | Param # | <- Ptr
10788 : : |----------------| +------------+
10789 : : | ProcSym | Type | | ReturnVar |
10790 : : |----------------| |------------|
10791 : :
10792 : : */
10793 : :
10794 : 2328 : static void BuildHighFunction (void)
10795 : : {
10796 : 2328 : unsigned int functok;
10797 : 2328 : unsigned int combinedtok;
10798 : 2328 : unsigned int paramtok;
10799 : 2328 : unsigned int ProcSym;
10800 : 2328 : unsigned int Type;
10801 : 2328 : unsigned int NoOfParam;
10802 : 2328 : unsigned int Param;
10803 : :
10804 : 2328 : M2Quads_PopT (&NoOfParam);
10805 : 2328 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
10806 : 2328 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
10807 : 2328 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
10808 : 2328 : if (NoOfParam == 1) /* quadruple generation now on */
10809 : : {
10810 : 2328 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
10811 : 2328 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
10812 : 2328 : combinedtok = M2LexBuf_MakeVirtualTok (paramtok, functok, paramtok);
10813 : 2328 : Type = SymbolTable_GetDType (Param);
10814 : : /* Restore stack to original form */
10815 : 2328 : M2Quads_PushT (NoOfParam);
10816 : 2328 : if (((! (SymbolTable_IsVar (Param))) && (! (SymbolTable_IsConstString (Param)))) && (! (SymbolTable_IsConst (Param))))
10817 : : {
10818 : : /* we cannot test for IsConst(Param) AND (GetSType(Param)=Char) as the type might not be assigned yet */
10819 : 0 : M2MetaError_MetaError1 ((const char *) "base procedure {%EkHIGH} expects a variable or string constant as its parameter {%1d:rather than {%1d}} {%1asa}", 111, Param);
10820 : : }
10821 : 2328 : else if ((Type != SymbolTable_NulSym) && (SymbolTable_IsUnbounded (Type)))
10822 : : {
10823 : : /* avoid dangling else. */
10824 : 2202 : BuildHighFromUnbounded (combinedtok);
10825 : : }
10826 : : else
10827 : : {
10828 : : /* avoid dangling else. */
10829 : 126 : BuildConstHighFromSym (combinedtok);
10830 : : }
10831 : : }
10832 : : else
10833 : : {
10834 : 0 : M2MetaError_MetaError0 ((const char *) "base procedure {%EkHIGH} requires one parameter", 47);
10835 : 0 : M2Quads_PopN (2);
10836 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
10837 : : }
10838 : 2328 : }
10839 : :
10840 : :
10841 : : /*
10842 : : BuildConstHighFromSym - builds the pseudo function HIGH from an Sym.
10843 : : Sym is a constant or an array which has constant bounds
10844 : : and therefore it can be calculated at compile time.
10845 : :
10846 : : The Stack:
10847 : :
10848 : :
10849 : : Entry Exit
10850 : :
10851 : : Ptr ->
10852 : : +----------------+
10853 : : | NoOfParam |
10854 : : |----------------|
10855 : : | Param 1 |
10856 : : |----------------|
10857 : : | Param 2 |
10858 : : |----------------|
10859 : : . .
10860 : : . .
10861 : : . .
10862 : : |----------------|
10863 : : | Param # | <- Ptr
10864 : : |----------------| +------------+
10865 : : | ProcSym | Type | | ReturnVar |
10866 : : |----------------| |------------|
10867 : : */
10868 : :
10869 : 126 : static void BuildConstHighFromSym (unsigned int tok)
10870 : : {
10871 : 126 : unsigned int NoOfParam;
10872 : 126 : unsigned int ReturnVar;
10873 : :
10874 : 126 : M2Quads_PopT (&NoOfParam);
10875 : 126 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10876 : 126 : SymbolTable_PutConst (ReturnVar, M2Base_Cardinal);
10877 : 126 : GenHigh (tok, ReturnVar, 1, M2Quads_OperandT (1));
10878 : 126 : M2Quads_PopN (NoOfParam+1);
10879 : 126 : M2Quads_PushTtok (ReturnVar, tok);
10880 : 126 : }
10881 : :
10882 : :
10883 : : /*
10884 : : BuildHighFromUnbounded - builds the pseudo function HIGH from an
10885 : : UnboundedSym.
10886 : :
10887 : : The Stack:
10888 : :
10889 : :
10890 : : Entry Exit
10891 : :
10892 : : Ptr ->
10893 : : +----------------+
10894 : : | NoOfParam |
10895 : : |----------------|
10896 : : | Param # | <- Ptr
10897 : : |----------------| +------------+
10898 : : | ProcSym | Type | | ReturnVar |
10899 : : |----------------| |------------|
10900 : :
10901 : : */
10902 : :
10903 : 2202 : static void BuildHighFromUnbounded (unsigned int tok)
10904 : : {
10905 : 2202 : unsigned int Dim;
10906 : 2202 : unsigned int NoOfParam;
10907 : 2202 : unsigned int ReturnVar;
10908 : :
10909 : 2202 : M2Quads_PopT (&NoOfParam);
10910 : 2202 : M2Debug_Assert (NoOfParam == 1);
10911 : 2202 : ReturnVar = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
10912 : 2202 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
10913 : 2202 : Dim = static_cast<unsigned int> (OperandD (1));
10914 : 2202 : Dim += 1;
10915 : 2202 : if (Dim > 1)
10916 : : {
10917 : 36 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandA (1));
10918 : : }
10919 : : else
10920 : : {
10921 : 2166 : GenHigh (tok, ReturnVar, Dim, M2Quads_OperandT (1));
10922 : : }
10923 : 2202 : M2Quads_PopN (2);
10924 : 2202 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), tok);
10925 : 2202 : }
10926 : :
10927 : :
10928 : : /*
10929 : : GetQualidentImport - returns the symbol as if it were qualified from, module.n.
10930 : : This is used to reference runtime support procedures and an
10931 : : error is generated if the symbol cannot be obtained.
10932 : : */
10933 : :
10934 : 45612 : static unsigned int GetQualidentImport (unsigned int tokno, NameKey_Name n, NameKey_Name module)
10935 : : {
10936 : 45612 : unsigned int ModSym;
10937 : :
10938 : 45612 : ModSym = M2Batch_MakeDefinitionSource (tokno, module);
10939 : 45612 : if (ModSym == SymbolTable_NulSym)
10940 : : {
10941 : 0 : M2MetaError_MetaErrorNT2 (tokno, (const char *) "module %a cannot be found and is needed to import %a", 52, module, n);
10942 : 0 : M2Error_FlushErrors ();
10943 : 0 : return SymbolTable_NulSym;
10944 : : }
10945 : 45612 : M2Debug_Assert (SymbolTable_IsDefImp (ModSym));
10946 : 45612 : if (((SymbolTable_GetExported (tokno, ModSym, n)) == SymbolTable_NulSym) || (SymbolTable_IsUnknown (SymbolTable_GetExported (tokno, ModSym, n))))
10947 : : {
10948 : 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);
10949 : 0 : M2Error_FlushErrors ();
10950 : 0 : return SymbolTable_NulSym;
10951 : : }
10952 : 45612 : return SymbolTable_GetExported (tokno, M2Batch_MakeDefinitionSource (tokno, module), n);
10953 : : /* static analysis guarentees a RETURN statement will be used before here. */
10954 : : __builtin_unreachable ();
10955 : : }
10956 : :
10957 : :
10958 : : /*
10959 : : ConstExprError - return TRUE if a constant expression is being built and Var is a variable.
10960 : : */
10961 : :
10962 : 54974 : static bool ConstExprError (unsigned int Func, unsigned int Var, unsigned int optok, bool ConstExpr)
10963 : : {
10964 : 54974 : if (ConstExpr && (SymbolTable_IsVar (Var)))
10965 : : {
10966 : 108 : M2MetaError_MetaErrorT2 (optok, (const char *) "the procedure function {%1Ea} is being called from within a constant expression and therefore the parameter {%2a} must be a constant, seen a {%2da}", 147, Func, Var);
10967 : 108 : return true;
10968 : : }
10969 : : else
10970 : : {
10971 : 54866 : return false;
10972 : : }
10973 : : /* static analysis guarentees a RETURN statement will be used before here. */
10974 : : __builtin_unreachable ();
10975 : : }
10976 : :
10977 : :
10978 : : /*
10979 : : DeferMakeLengthConst - creates a constant which contains the length of string, sym.
10980 : : */
10981 : :
10982 : 66 : static unsigned int DeferMakeLengthConst (unsigned int tok, unsigned int sym)
10983 : : {
10984 : 66 : unsigned int const_;
10985 : :
10986 : 66 : const_ = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
10987 : 66 : SymbolTable_PutVar (const_, M2Base_ZType);
10988 : 132 : GenQuadO (tok, M2Quads_StringLengthOp, const_, 0, sym, false);
10989 : 66 : return const_;
10990 : : /* static analysis guarentees a RETURN statement will be used before here. */
10991 : : __builtin_unreachable ();
10992 : : }
10993 : :
10994 : :
10995 : : /*
10996 : : BuildLengthFunction - builds the inline standard function LENGTH.
10997 : :
10998 : : The Stack:
10999 : :
11000 : :
11001 : : Entry Exit
11002 : :
11003 : : Ptr ->
11004 : : +----------------+
11005 : : | NoOfParam |
11006 : : |----------------|
11007 : : | Param 1 | <- Ptr
11008 : : |----------------| +------------+
11009 : : | ProcSym | Type | | ReturnVar |
11010 : : |----------------| |------------|
11011 : :
11012 : : */
11013 : :
11014 : 346 : static void BuildLengthFunction (unsigned int Function, bool ConstExpr)
11015 : : {
11016 : 346 : unsigned int combinedtok;
11017 : 346 : unsigned int paramtok;
11018 : 346 : unsigned int functok;
11019 : 346 : unsigned int ProcSym;
11020 : 346 : unsigned int Type;
11021 : 346 : unsigned int NoOfParam;
11022 : 346 : unsigned int Param;
11023 : 346 : unsigned int ReturnVar;
11024 : :
11025 : 346 : M2Quads_PopT (&NoOfParam);
11026 : 346 : Param = static_cast<unsigned int> (M2Quads_OperandT (1));
11027 : 346 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11028 : 346 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11029 : : /* Restore stack to origional form. */
11030 : 346 : M2Quads_PushT (NoOfParam);
11031 : 346 : Type = SymbolTable_GetSType (Param); /* Get the type from the symbol, not the stack. */
11032 : 346 : if (NoOfParam != 1) /* Get the type from the symbol, not the stack. */
11033 : : {
11034 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "base procedure {%1EkLENGTH} expects 1 parameter, seen {%1n} parameters", 70, NoOfParam);
11035 : : }
11036 : 346 : if (NoOfParam >= 1)
11037 : : {
11038 : 346 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
11039 : 346 : if ((SymbolTable_IsConst (Param)) && ((SymbolTable_GetSType (Param)) == M2Base_Char))
11040 : : {
11041 : 6 : M2Quads_PopT (&NoOfParam);
11042 : 6 : M2Quads_PopN (NoOfParam+1);
11043 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
11044 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
11045 : : }
11046 : 340 : else if (SymbolTable_IsConstString (Param))
11047 : : {
11048 : : /* avoid dangling else. */
11049 : 48 : M2Quads_PopT (&NoOfParam);
11050 : 48 : ReturnVar = DeferMakeLengthConst (combinedtok, M2Quads_OperandT (1));
11051 : 48 : M2Quads_PopN (NoOfParam+1);
11052 : 48 : M2Quads_PushTtok (ReturnVar, combinedtok);
11053 : : }
11054 : : else
11055 : : {
11056 : : /* avoid dangling else. */
11057 : 292 : ProcSym = GetQualidentImport (functok, NameKey_MakeKey ((const char *) "Length", 6), NameKey_MakeKey ((const char *) "M2RTS", 5));
11058 : 292 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
11059 : : {
11060 : 292 : M2Quads_PopT (&NoOfParam);
11061 : 292 : if (SymbolTable_IsConst (Param))
11062 : : {
11063 : : /* This can be folded in M2GenGCC. */
11064 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_ImmediateValue);
11065 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11066 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, Param);
11067 : 0 : M2Quads_PopN (NoOfParam+1);
11068 : 0 : M2Quads_PushTtok (ReturnVar, combinedtok);
11069 : : }
11070 : 292 : else if (ConstExprError (Function, Param, paramtok, ConstExpr))
11071 : : {
11072 : : /* avoid dangling else. */
11073 : : /* Fake a result as we have detected and reported an error. */
11074 : 6 : M2Quads_PopN (NoOfParam+1);
11075 : 6 : ReturnVar = SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal);
11076 : 6 : M2Quads_PushTtok (ReturnVar, combinedtok);
11077 : : }
11078 : : else
11079 : : {
11080 : : /* avoid dangling else. */
11081 : : /* We must resolve this at runtime or in the GCC optimizer. */
11082 : 286 : M2Quads_PopTF (&Param, &Type);
11083 : 286 : M2Quads_PopN (NoOfParam);
11084 : 286 : M2Quads_PushTtok (ProcSym, functok);
11085 : 286 : M2Quads_PushTFtok (Param, Type, paramtok);
11086 : 286 : M2Quads_PushT (NoOfParam);
11087 : 286 : BuildRealFunctionCall (functok, false);
11088 : : }
11089 : : }
11090 : : else
11091 : : {
11092 : 0 : M2Quads_PopT (&NoOfParam);
11093 : 0 : M2Quads_PopN (NoOfParam+1);
11094 : 0 : M2Quads_PushTtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), combinedtok);
11095 : 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);
11096 : : }
11097 : : }
11098 : : }
11099 : : else
11100 : : {
11101 : : /* NoOfParam is _very_ wrong, we flush all outstanding errors */
11102 : 0 : M2Error_FlushErrors ();
11103 : : }
11104 : 346 : }
11105 : :
11106 : :
11107 : : /*
11108 : : BuildOddFunction - builds the pseudo procedure call ODD.
11109 : : This procedure is actually a "macro" for
11110 : : ORD(x) --> VAL(BOOLEAN, x MOD 2)
11111 : : However we cannot push tokens back onto the input stack
11112 : : because the compiler is currently building a function
11113 : : call and expecting a ReturnVar on the stack.
11114 : : Hence we manipulate the stack and call
11115 : : BuildConvertFunction.
11116 : :
11117 : : The Stack:
11118 : :
11119 : :
11120 : : Entry Exit
11121 : :
11122 : : Ptr ->
11123 : : +----------------+
11124 : : | NoOfParam |
11125 : : |----------------|
11126 : : | Param 1 |
11127 : : |----------------|
11128 : : | Param 2 |
11129 : : |----------------|
11130 : : . .
11131 : : . .
11132 : : . .
11133 : : |----------------|
11134 : : | Param # |
11135 : : |----------------|
11136 : : | ProcSym | Type | Empty
11137 : : |----------------|
11138 : : */
11139 : :
11140 : 46 : static void BuildOddFunction (unsigned int ProcSym, bool ConstExpr)
11141 : : {
11142 : 46 : unsigned int combinedtok;
11143 : 46 : unsigned int optok;
11144 : 46 : unsigned int functok;
11145 : 46 : unsigned int NoOfParam;
11146 : 46 : unsigned int Res;
11147 : 46 : unsigned int Var;
11148 : :
11149 : 46 : M2Quads_PopT (&NoOfParam);
11150 : 46 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11151 : 46 : if (NoOfParam == 1)
11152 : : {
11153 : 46 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11154 : 46 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11155 : 46 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, optok);
11156 : 46 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11157 : : {
11158 : : /* Nothing to do. */
11159 : 6 : M2Quads_PushTtok (M2Base_False, combinedtok);
11160 : : }
11161 : 40 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11162 : : {
11163 : : /* avoid dangling else. */
11164 : 40 : M2Quads_PopN (NoOfParam+1);
11165 : : /* compute (x MOD 2) */
11166 : 40 : M2Quads_PushTFtok (Var, SymbolTable_GetSType (Var), optok);
11167 : 40 : M2Quads_PushT (M2Reserved_ModTok);
11168 : 40 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "2", 1), M2Base_ZType), M2Base_ZType, optok);
11169 : 40 : M2Quads_BuildBinaryOp ();
11170 : 40 : M2Quads_PopT (&Res);
11171 : : /* compute IF ...=0 */
11172 : 40 : M2Quads_PushTtok (Res, optok);
11173 : 40 : M2Quads_PushT (M2Reserved_EqualTok);
11174 : 40 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (optok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType), M2Base_ZType, optok);
11175 : 40 : M2Quads_BuildRelOp (combinedtok);
11176 : 40 : M2Quads_BuildThenIf ();
11177 : 40 : Res = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11178 : 40 : SymbolTable_PutVar (Res, M2Base_Boolean);
11179 : 40 : M2Quads_PushTtok (Res, combinedtok);
11180 : 40 : M2Quads_PushTtok (M2Base_False, combinedtok);
11181 : 40 : M2Quads_BuildAssignment (combinedtok);
11182 : 40 : M2Quads_BuildElse ();
11183 : 40 : M2Quads_PushTtok (Res, combinedtok);
11184 : 40 : M2Quads_PushTtok (M2Base_True, combinedtok);
11185 : 40 : M2Quads_BuildAssignment (combinedtok);
11186 : 40 : M2Quads_BuildEndIf ();
11187 : 40 : M2Quads_PushTtok (Res, combinedtok);
11188 : : }
11189 : : else
11190 : : {
11191 : : /* avoid dangling else. */
11192 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%1EkODD} must be a variable or constant, seen {%1ad}", 70, Var);
11193 : 0 : M2Quads_PushTtok (M2Base_False, combinedtok);
11194 : : }
11195 : : }
11196 : : else
11197 : : {
11198 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters", 76, NoOfParam);
11199 : 0 : M2Quads_PushTtok (M2Base_False, functok);
11200 : : }
11201 : 46 : }
11202 : :
11203 : :
11204 : : /*
11205 : : BuildAbsFunction - builds a call to the standard function ABS.
11206 : :
11207 : : We cannot implement it as a macro or inline an
11208 : : IF THEN statement as the IF THEN ELSE requires
11209 : : we write the value to the same variable (or constant)
11210 : : twice. The macro implementation will fail as
11211 : : the compiler maybe building a function
11212 : : call and expecting a ReturnVar on the stack.
11213 : : The only method to implement this is to pass it to the
11214 : : gcc backend.
11215 : :
11216 : : The Stack:
11217 : :
11218 : :
11219 : : Entry Exit
11220 : :
11221 : : Ptr ->
11222 : : +----------------+
11223 : : | NoOfParam |
11224 : : |----------------|
11225 : : | Param 1 |
11226 : : |----------------|
11227 : : | Param 2 |
11228 : : |----------------|
11229 : : . .
11230 : : . .
11231 : : . .
11232 : : |----------------|
11233 : : | Param # |
11234 : : |----------------|
11235 : : | ProcSym | Type | Empty
11236 : : |----------------|
11237 : : */
11238 : :
11239 : 128 : static void BuildAbsFunction (unsigned int ProcSym, bool ConstExpr)
11240 : : {
11241 : 128 : unsigned int vartok;
11242 : 128 : unsigned int functok;
11243 : 128 : unsigned int combinedtok;
11244 : 128 : unsigned int NoOfParam;
11245 : 128 : unsigned int Res;
11246 : 128 : unsigned int Var;
11247 : :
11248 : 128 : M2Quads_PopT (&NoOfParam);
11249 : 128 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11250 : 128 : if (NoOfParam == 1)
11251 : : {
11252 : 128 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11253 : 128 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11254 : 128 : M2Quads_PopN (NoOfParam+1);
11255 : 128 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
11256 : 128 : if (ConstExprError (ProcSym, Var, vartok, ConstExpr))
11257 : : {
11258 : : /* Create fake result. */
11259 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11260 : 12 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11261 : 12 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11262 : : }
11263 : 116 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11264 : : {
11265 : : /* avoid dangling else. */
11266 : 220 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11267 : 110 : SymbolTable_PutVar (Res, SymbolTable_GetSType (Var));
11268 : 220 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11269 : 110 : M2Quads_PushTFtok (Res, SymbolTable_GetSType (Var), combinedtok);
11270 : : }
11271 : : else
11272 : : {
11273 : : /* avoid dangling else. */
11274 : 6 : M2MetaError_MetaErrorT1 (vartok, (const char *) "the parameter to {%AkABS} must be a variable or constant, seen {%1ad}", 69, Var);
11275 : : }
11276 : : }
11277 : : else
11278 : : {
11279 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkABS} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11280 : : }
11281 : 122 : }
11282 : :
11283 : :
11284 : : /*
11285 : : BuildCapFunction - builds the pseudo procedure call CAP.
11286 : : We generate a the following quad:
11287 : :
11288 : :
11289 : : StandardFunctionOp ReturnVal Cap Param1
11290 : :
11291 : : The Stack:
11292 : :
11293 : :
11294 : : Entry Exit
11295 : :
11296 : : Ptr ->
11297 : : +----------------+
11298 : : | NoOfParam = 1 |
11299 : : |----------------|
11300 : : | Param 1 |
11301 : : |----------------| +-------------+
11302 : : | ProcSym | Type | | ReturnVal |
11303 : : |----------------| |-------------|
11304 : : */
11305 : :
11306 : 124 : static void BuildCapFunction (unsigned int ProcSym, bool ConstExpr)
11307 : : {
11308 : 124 : unsigned int optok;
11309 : 124 : unsigned int functok;
11310 : 124 : unsigned int combinedtok;
11311 : 124 : unsigned int NoOfParam;
11312 : 124 : unsigned int Res;
11313 : 124 : unsigned int Var;
11314 : :
11315 : 124 : M2Quads_PopT (&NoOfParam);
11316 : 124 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11317 : 124 : if (NoOfParam == 1)
11318 : : {
11319 : 124 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11320 : 124 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11321 : 124 : M2Quads_PopN (NoOfParam+1);
11322 : 124 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11323 : : {
11324 : : /* Create fake result. */
11325 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11326 : 24 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11327 : 12 : SymbolTable_PutVar (Res, M2Base_Char);
11328 : 12 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11329 : : }
11330 : 112 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11331 : : {
11332 : : /* avoid dangling else. */
11333 : 112 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11334 : 224 : Res = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11335 : 112 : SymbolTable_PutVar (Res, M2Base_Char);
11336 : 224 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, Res, ProcSym, Var, false);
11337 : 112 : M2Quads_PushTFtok (Res, M2Base_Char, combinedtok);
11338 : : }
11339 : : else
11340 : : {
11341 : : /* avoid dangling else. */
11342 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCAP} must be a variable or constant, seen {%1ad}", 69, Var);
11343 : : }
11344 : : }
11345 : : else
11346 : : {
11347 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCAP} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11348 : : }
11349 : 124 : }
11350 : :
11351 : :
11352 : : /*
11353 : : BuildChrFunction - builds the pseudo procedure call CHR.
11354 : : This procedure is actually a "macro" for
11355 : : CHR(x) --> CONVERT(CHAR, x)
11356 : : However we cannot push tokens back onto the input stack
11357 : : because the compiler is currently building a function
11358 : : call and expecting a ReturnVar on the stack.
11359 : : Hence we manipulate the stack and call
11360 : : BuildConvertFunction.
11361 : :
11362 : : The Stack:
11363 : :
11364 : :
11365 : : Entry Exit
11366 : :
11367 : : Ptr ->
11368 : : +----------------+
11369 : : | NoOfParam |
11370 : : |----------------|
11371 : : | Param 1 |
11372 : : |----------------|
11373 : : | Param 2 |
11374 : : |----------------|
11375 : : . .
11376 : : . .
11377 : : . .
11378 : : |----------------|
11379 : : | Param # |
11380 : : |----------------|
11381 : : | ProcSym | Type | Empty
11382 : : |----------------|
11383 : : */
11384 : :
11385 : 446 : static void BuildChrFunction (unsigned int ProcSym, bool ConstExpr)
11386 : : {
11387 : 446 : unsigned int functok;
11388 : 446 : unsigned int combinedtok;
11389 : 446 : unsigned int optok;
11390 : 446 : unsigned int ReturnVar;
11391 : 446 : unsigned int NoOfParam;
11392 : 446 : unsigned int Var;
11393 : :
11394 : 446 : M2Quads_PopT (&NoOfParam);
11395 : 446 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11396 : 446 : if (NoOfParam == 1)
11397 : : {
11398 : 446 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11399 : 446 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11400 : 446 : M2Quads_PopN (NoOfParam+1);
11401 : 446 : if (ConstExprError (ProcSym, Var, optok, ConstExpr))
11402 : : {
11403 : : /* Generate fake result. */
11404 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11405 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11406 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Char);
11407 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Char, combinedtok);
11408 : : }
11409 : 434 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11410 : : {
11411 : : /* avoid dangling else. */
11412 : : /*
11413 : : Build macro: CONVERT( CHAR, Var )
11414 : : */
11415 : 434 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11416 : 434 : M2Quads_PushTtok (M2Base_Char, functok);
11417 : 434 : M2Quads_PushTtok (Var, optok);
11418 : 434 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11419 : 434 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11420 : : }
11421 : : else
11422 : : {
11423 : : /* avoid dangling else. */
11424 : 0 : M2MetaError_MetaErrorT1 (optok, (const char *) "the parameter to {%AkCHR} must be a variable or constant, seen {%1ad}", 69, Var);
11425 : : }
11426 : : }
11427 : : else
11428 : : {
11429 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%AkCHR} only has one parameter, seen {%1n} parameters", 75, NoOfParam);
11430 : : }
11431 : 446 : }
11432 : :
11433 : :
11434 : : /*
11435 : : BuildOrdFunction - builds the pseudo procedure call ORD.
11436 : : This procedure is actually a "macro" for
11437 : : ORD(x) --> CONVERT(GetSType(sym), x)
11438 : : However we cannot push tokens back onto the input stack
11439 : : because the compiler is currently building a function
11440 : : call and expecting a ReturnVar on the stack.
11441 : : Hence we manipulate the stack and call
11442 : : BuildConvertFunction.
11443 : :
11444 : : The Stack:
11445 : :
11446 : :
11447 : : Entry Exit
11448 : :
11449 : : Ptr ->
11450 : : +----------------+
11451 : : | NoOfParam |
11452 : : |----------------|
11453 : : | Param 1 |
11454 : : |----------------|
11455 : : | Param 2 |
11456 : : |----------------|
11457 : : . .
11458 : : . .
11459 : : . .
11460 : : |----------------|
11461 : : | Param # |
11462 : : |----------------|
11463 : : | ProcSym | Type | Empty
11464 : : |----------------|
11465 : : */
11466 : :
11467 : 3152 : static void BuildOrdFunction (unsigned int Sym, bool ConstExpr)
11468 : : {
11469 : 3152 : unsigned int combinedtok;
11470 : 3152 : unsigned int functok;
11471 : 3152 : unsigned int optok;
11472 : 3152 : unsigned int ReturnVar;
11473 : 3152 : unsigned int NoOfParam;
11474 : 3152 : unsigned int Type;
11475 : 3152 : unsigned int Var;
11476 : :
11477 : 3152 : M2Quads_PopT (&NoOfParam);
11478 : 3152 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11479 : 3152 : if (NoOfParam == 1)
11480 : : {
11481 : 3152 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11482 : 3152 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11483 : 3152 : M2Quads_PopN (NoOfParam+1);
11484 : 3152 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11485 : : {
11486 : : /* Generate fake result. */
11487 : 12 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11488 : 24 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11489 : 12 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
11490 : 12 : M2Quads_PushTFtok (ReturnVar, M2Base_Cardinal, combinedtok);
11491 : : }
11492 : 3140 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11493 : : {
11494 : : /* avoid dangling else. */
11495 : 3140 : Type = SymbolTable_GetSType (Sym);
11496 : : /*
11497 : : Build macro: CONVERT( CARDINAL, Var )
11498 : : */
11499 : 3140 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11500 : 3140 : M2Quads_PushTtok (Type, optok);
11501 : 3140 : M2Quads_PushTtok (Var, optok);
11502 : 3140 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11503 : 3140 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11504 : : }
11505 : : else
11506 : : {
11507 : : /* avoid dangling else. */
11508 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Aa} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11509 : : }
11510 : : }
11511 : : else
11512 : : {
11513 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11514 : : }
11515 : 3152 : }
11516 : :
11517 : :
11518 : : /*
11519 : : BuildIntFunction - builds the pseudo procedure call INT.
11520 : : This procedure is actually a "macro" for
11521 : : INT(x) --> CONVERT(INTEGER, x)
11522 : : However we cannot push tokens back onto the input stack
11523 : : because the compiler is currently building a function
11524 : : call and expecting a ReturnVar on the stack.
11525 : : Hence we manipulate the stack and call
11526 : : BuildConvertFunction.
11527 : :
11528 : : The Stack:
11529 : :
11530 : :
11531 : : Entry Exit
11532 : :
11533 : : Ptr ->
11534 : : +----------------+
11535 : : | NoOfParam |
11536 : : |----------------|
11537 : : | Param 1 |
11538 : : |----------------|
11539 : : | Param 2 |
11540 : : |----------------|
11541 : : . .
11542 : : . .
11543 : : . .
11544 : : |----------------|
11545 : : | Param # |
11546 : : |----------------|
11547 : : | ProcSym | Type | Empty
11548 : : |----------------|
11549 : : */
11550 : :
11551 : 6 : static void BuildIntFunction (unsigned int Sym, bool ConstExpr)
11552 : : {
11553 : 6 : unsigned int combinedtok;
11554 : 6 : unsigned int functok;
11555 : 6 : unsigned int optok;
11556 : 6 : unsigned int ReturnVar;
11557 : 6 : unsigned int NoOfParam;
11558 : 6 : unsigned int Type;
11559 : 6 : unsigned int Var;
11560 : :
11561 : 6 : M2Quads_PopT (&NoOfParam);
11562 : 6 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11563 : 6 : if (NoOfParam == 1)
11564 : : {
11565 : 6 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
11566 : 6 : optok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11567 : 6 : M2Quads_PopN (NoOfParam+1);
11568 : 6 : if (ConstExprError (Sym, Var, optok, ConstExpr))
11569 : : {
11570 : : /* Generate fake result. */
11571 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, optok);
11572 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
11573 : 6 : SymbolTable_PutVar (ReturnVar, M2Base_Integer);
11574 : 6 : M2Quads_PushTFtok (ReturnVar, M2Base_Integer, combinedtok);
11575 : : }
11576 : 0 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
11577 : : {
11578 : : /* avoid dangling else. */
11579 : 0 : Type = SymbolTable_GetSType (Sym); /* return type of function */
11580 : : /* Build macro: CONVERT( CARDINAL, Var ). */
11581 : 0 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
11582 : 0 : M2Quads_PushTtok (Type, functok);
11583 : 0 : M2Quads_PushTtok (Var, optok);
11584 : 0 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11585 : 0 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* Two parameters */
11586 : : }
11587 : : else
11588 : : {
11589 : : /* avoid dangling else. */
11590 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, optok, optok);
11591 : 0 : M2MetaError_MetaErrorT2 (optok, (const char *) "the parameter to {%1Ea} must be a variable or constant, seen {%2ad}", 67, Sym, Var);
11592 : 0 : M2Quads_PushTtok (combinedtok, SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11593 : : }
11594 : : }
11595 : : else
11596 : : {
11597 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters", 73, Sym, NoOfParam);
11598 : 0 : M2Quads_PushTtok (functok, SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType));
11599 : : }
11600 : 6 : }
11601 : :
11602 : :
11603 : : /*
11604 : : BuildMakeAdrFunction - builds the pseudo procedure call MAKEADR.
11605 : :
11606 : : The Stack:
11607 : :
11608 : :
11609 : : Entry Exit
11610 : :
11611 : : Ptr ->
11612 : : +----------------+
11613 : : | NoOfParam |
11614 : : |----------------|
11615 : : | Param 1 |
11616 : : |----------------|
11617 : : | Param 2 |
11618 : : |----------------|
11619 : : . .
11620 : : . .
11621 : : . .
11622 : : |----------------|
11623 : : | Param # |
11624 : : |----------------|
11625 : : | ProcSym | Type | Empty
11626 : : |----------------|
11627 : : */
11628 : :
11629 : 12 : static void BuildMakeAdrFunction (void)
11630 : : {
11631 : 12 : unsigned int functok;
11632 : 12 : unsigned int starttok;
11633 : 12 : unsigned int endtok;
11634 : 12 : unsigned int resulttok;
11635 : 12 : bool AreConst;
11636 : 12 : unsigned int i;
11637 : 12 : unsigned int pi;
11638 : 12 : unsigned int NoOfParameters;
11639 : 12 : unsigned int ReturnVar;
11640 : :
11641 : 12 : M2Quads_PopT (&NoOfParameters);
11642 : 12 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1));
11643 : 12 : if (NoOfParameters > 0)
11644 : : {
11645 : 12 : starttok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParameters+1)); /* ADR token. */
11646 : 12 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
11647 : 24 : GenQuad (M2Quads_ParamOp, 0, M2System_MakeAdr, M2System_MakeAdr); /* last parameter. */
11648 : 12 : i = NoOfParameters;
11649 : : /* stack index referencing stacked parameter, i */
11650 : 12 : pi = 1;
11651 : 24 : while (i > 0)
11652 : : {
11653 : 12 : GenQuadO (M2Quads_OperandTok (pi), M2Quads_ParamOp, i, M2System_MakeAdr, M2Quads_OperandT (pi), true);
11654 : 12 : i -= 1;
11655 : 12 : pi += 1;
11656 : : }
11657 : : AreConst = true;
11658 : : i = 1;
11659 : 24 : while (i <= NoOfParameters)
11660 : : {
11661 : 12 : if (SymbolTable_IsVar (M2Quads_OperandT (i)))
11662 : : {
11663 : : AreConst = false;
11664 : : }
11665 : 12 : else if (! (SymbolTable_IsConst (M2Quads_OperandT (i))))
11666 : : {
11667 : : /* avoid dangling else. */
11668 : 0 : M2MetaError_MetaError1 ((const char *) "problem in the {%1EN} argument for {%kMAKEADR}, all arguments to {%kMAKEADR} must be either variables or constants", 114, i);
11669 : : }
11670 : 12 : i += 1;
11671 : : }
11672 : : /* ReturnVar - will have the type of the procedure */
11673 : 12 : resulttok = M2LexBuf_MakeVirtualTok (starttok, starttok, endtok);
11674 : 12 : ReturnVar = SymbolTable_MakeTemporary (resulttok, AreConstant (AreConst));
11675 : 12 : SymbolTable_PutVar (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr));
11676 : 24 : GenQuadO (resulttok, M2Quads_FunctValueOp, ReturnVar, SymbolTable_NulSym, M2System_MakeAdr, true);
11677 : 12 : M2Quads_PopN (NoOfParameters+1);
11678 : 12 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (M2System_MakeAdr), resulttok);
11679 : : }
11680 : : else
11681 : : {
11682 : 0 : M2MetaError_MetaError1 ((const char *) "the pseudo procedure {%EkMAKEADR} requires at least one parameter, seen {%1n}", 77, NoOfParameters);
11683 : 0 : M2Quads_PopN (1);
11684 : 0 : M2Quads_PushTFtok (M2Base_Nil, SymbolTable_GetSType (M2System_MakeAdr), functok);
11685 : : }
11686 : 12 : }
11687 : :
11688 : :
11689 : : /*
11690 : : BuildShiftFunction - builds the pseudo procedure call SHIFT.
11691 : :
11692 : : PROCEDURE SHIFT (val: <any type>;
11693 : : num: INTEGER): <any type> ;
11694 : :
11695 : : "Returns a bit sequence obtained from val by
11696 : : shifting up or down (left or right) by the
11697 : : absolute value of num, introducing
11698 : : zeros as necessary. The direction is down if
11699 : : the sign of num is negative, otherwise the
11700 : : direction is up."
11701 : :
11702 : : The Stack:
11703 : :
11704 : : Entry Exit
11705 : :
11706 : : Ptr ->
11707 : : +----------------+
11708 : : | NoOfParam |
11709 : : |----------------|
11710 : : | Param 1 |
11711 : : |----------------|
11712 : : | Param 2 | <- Ptr
11713 : : |----------------| +------------+
11714 : : | ProcSym | Type | | ReturnVar |
11715 : : |----------------| |------------|
11716 : : */
11717 : :
11718 : 702 : static void BuildShiftFunction (void)
11719 : : {
11720 : 702 : unsigned int combinedtok;
11721 : 702 : unsigned int paramtok;
11722 : 702 : unsigned int functok;
11723 : 702 : unsigned int vartok;
11724 : 702 : unsigned int exptok;
11725 : 702 : unsigned int r;
11726 : 702 : unsigned int procSym;
11727 : 702 : unsigned int returnVar;
11728 : 702 : unsigned int NoOfParam;
11729 : 702 : unsigned int derefExp;
11730 : 702 : unsigned int Exp;
11731 : 702 : unsigned int varSet;
11732 : :
11733 : 702 : M2Quads_PopT (&NoOfParam);
11734 : 702 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11735 : 702 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11736 : 702 : if (NoOfParam == 2)
11737 : : {
11738 : 702 : PopTrwtok (&Exp, &r, &exptok);
11739 : 702 : MarkAsRead (r);
11740 : 702 : M2Quads_PopTtok (&varSet, &vartok);
11741 : 702 : M2Quads_PopT (&procSym);
11742 : 702 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11743 : 702 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_GetDType (varSet))))
11744 : : {
11745 : 702 : derefExp = DereferenceLValue (exptok, Exp);
11746 : 702 : BuildRange (M2Range_InitShiftCheck (varSet, derefExp));
11747 : 702 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11748 : 702 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11749 : 1404 : GenQuadO (combinedtok, M2Quads_LogicalShiftOp, returnVar, varSet, derefExp, true);
11750 : 702 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11751 : : }
11752 : : else
11753 : : {
11754 : 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);
11755 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11756 : : }
11757 : : }
11758 : : else
11759 : : {
11760 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
11761 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo procedure {%kSHIFT} requires at least two parameters, seen {%1En}", 76, NoOfParam);
11762 : 0 : M2Quads_PopN (NoOfParam+1);
11763 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, combinedtok);
11764 : : }
11765 : 702 : }
11766 : :
11767 : :
11768 : : /*
11769 : : BuildRotateFunction - builds the pseudo procedure call ROTATE.
11770 : :
11771 : : PROCEDURE ROTATE (val: <any type>;
11772 : : num: INTEGER): <any type> ;
11773 : :
11774 : : "Returns a bit sequence obtained from val
11775 : : by rotating up or down (left or right) by
11776 : : the absolute value of num. The direction is
11777 : : down if the sign of num is negative, otherwise
11778 : : the direction is up."
11779 : :
11780 : : The Stack:
11781 : :
11782 : : Entry Exit
11783 : :
11784 : : Ptr ->
11785 : : +----------------+
11786 : : | NoOfParam |
11787 : : |----------------|
11788 : : | Param 1 |
11789 : : |----------------|
11790 : : | Param 2 | <- Ptr
11791 : : |----------------| +------------+
11792 : : | ProcSym | Type | | ReturnVar |
11793 : : |----------------| |------------|
11794 : : */
11795 : :
11796 : 382 : static void BuildRotateFunction (void)
11797 : : {
11798 : 382 : unsigned int combinedtok;
11799 : 382 : unsigned int functok;
11800 : 382 : unsigned int vartok;
11801 : 382 : unsigned int exptok;
11802 : 382 : unsigned int r;
11803 : 382 : unsigned int procSym;
11804 : 382 : unsigned int returnVar;
11805 : 382 : unsigned int NoOfParam;
11806 : 382 : unsigned int derefExp;
11807 : 382 : unsigned int Exp;
11808 : 382 : unsigned int varSet;
11809 : :
11810 : 382 : M2Quads_PopT (&NoOfParam);
11811 : 382 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11812 : 382 : if (NoOfParam == 2)
11813 : : {
11814 : 382 : PopTrwtok (&Exp, &r, &exptok);
11815 : 382 : MarkAsRead (r);
11816 : 382 : M2Quads_PopTtok (&varSet, &vartok);
11817 : 382 : M2Quads_PopT (&procSym);
11818 : 382 : if (((SymbolTable_GetSType (varSet)) != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_GetDType (varSet))))
11819 : : {
11820 : 382 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11821 : 382 : derefExp = DereferenceLValue (exptok, Exp);
11822 : 382 : BuildRange (M2Range_InitRotateCheck (varSet, derefExp));
11823 : 382 : returnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
11824 : 382 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (varSet));
11825 : 764 : GenQuadO (combinedtok, M2Quads_LogicalRotateOp, returnVar, varSet, derefExp, true);
11826 : 382 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (varSet), combinedtok);
11827 : : }
11828 : : else
11829 : : {
11830 : 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);
11831 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11832 : : }
11833 : : }
11834 : : else
11835 : : {
11836 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "SYSTEM procedure {%EkROTATE} expects 2 parameters and was given {%1n} parameters", 80, NoOfParam);
11837 : 0 : M2Quads_PopN (NoOfParam+1);
11838 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal), M2Base_Cardinal, functok);
11839 : : }
11840 : 382 : }
11841 : :
11842 : :
11843 : : /*
11844 : : BuildValFunction - builds the pseudo procedure call VAL.
11845 : : This procedure is actually a "macro" for
11846 : : VAL(Type, x) --> CONVERT(Type, x)
11847 : : However we cannot push tokens back onto the input stack
11848 : : because the compiler is currently building a function
11849 : : call and expecting a ReturnVar on the stack.
11850 : : Hence we manipulate the stack and call
11851 : : BuildConvertFunction.
11852 : :
11853 : : The Stack:
11854 : :
11855 : :
11856 : : Entry Exit
11857 : :
11858 : : Ptr ->
11859 : : +----------------+
11860 : : | NoOfParam |
11861 : : |----------------|
11862 : : | Param 1 |
11863 : : |----------------|
11864 : : | Param 2 |
11865 : : |----------------|
11866 : : . .
11867 : : . .
11868 : : . .
11869 : : |----------------|
11870 : : | Param # |
11871 : : |----------------|
11872 : : | ProcSym | Type | Empty
11873 : : |----------------|
11874 : : */
11875 : :
11876 : 3278 : static void BuildValFunction (unsigned int ProcSym, bool ConstExpr)
11877 : : {
11878 : 3278 : unsigned int combinedtok;
11879 : 3278 : unsigned int functok;
11880 : 3278 : unsigned int ReturnVar;
11881 : 3278 : unsigned int NoOfParam;
11882 : 3278 : unsigned int Exp;
11883 : 3278 : unsigned int Type;
11884 : 3278 : unsigned int tok;
11885 : 3278 : unsigned int r;
11886 : 3278 : unsigned int typetok;
11887 : 3278 : unsigned int exptok;
11888 : :
11889 : 3278 : M2Quads_PopT (&NoOfParam);
11890 : 3278 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11891 : 3278 : if (NoOfParam == 2)
11892 : : {
11893 : 3278 : PopTrwtok (&Exp, &r, &exptok);
11894 : 3278 : MarkAsRead (r);
11895 : 3278 : M2Quads_PopTtok (&Type, &typetok);
11896 : 3278 : M2Quads_PopTtok (&ProcSym, &tok);
11897 : 3278 : if (SymbolTable_IsUnknown (Type))
11898 : : {
11899 : : /* non recoverable error. */
11900 : 6 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type found in builtin procedure function {%AkVAL} {%1ad}", 67, Type);
11901 : : }
11902 : 3272 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11903 : : {
11904 : : /* avoid dangling else. */
11905 : : /* Generate fake result. */
11906 : 6 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
11907 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
11908 : 6 : SymbolTable_PutVar (ReturnVar, Type);
11909 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
11910 : : }
11911 : 3266 : 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))))
11912 : : {
11913 : : /* avoid dangling else. */
11914 : : /*
11915 : : Build macro: CONVERT( Type, Var )
11916 : : */
11917 : 3266 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), tok);
11918 : 3266 : M2Quads_PushTtok (Type, typetok);
11919 : 3266 : M2Quads_PushTtok (Exp, exptok);
11920 : 3266 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
11921 : 3266 : BuildConvertFunction (M2Base_Convert, ConstExpr);
11922 : : }
11923 : : else
11924 : : {
11925 : : /* avoid dangling else. */
11926 : : /* non recoverable error. */
11927 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkVAL} has the following formal parameter declaration {%kVAL} (type, expression)", 104);
11928 : : }
11929 : : }
11930 : : else
11931 : : {
11932 : : /* non recoverable error. */
11933 : 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);
11934 : : }
11935 : 3272 : }
11936 : :
11937 : :
11938 : : /*
11939 : : BuildCastFunction - builds the pseudo procedure call CAST.
11940 : : This procedure is actually a "macro" for
11941 : : CAST(Type, x) --> Type(x)
11942 : : However we cannot push tokens back onto the input stack
11943 : : because the compiler is currently building a function
11944 : : call and expecting a ReturnVar on the stack.
11945 : : Hence we manipulate the stack and call
11946 : : BuildConvertFunction.
11947 : :
11948 : : The Stack:
11949 : :
11950 : :
11951 : : Entry Exit
11952 : :
11953 : : Ptr ->
11954 : : +----------------+
11955 : : | NoOfParam |
11956 : : |----------------|
11957 : : | Param 1 |
11958 : : |----------------|
11959 : : | Param 2 |
11960 : : |----------------|
11961 : : . .
11962 : : . .
11963 : : . .
11964 : : |----------------|
11965 : : | Param # |
11966 : : |----------------|
11967 : : | ProcSym | Type | Empty
11968 : : |----------------|
11969 : : */
11970 : :
11971 : 156 : static void BuildCastFunction (unsigned int ProcSym, bool ConstExpr)
11972 : : {
11973 : 156 : unsigned int combinedtok;
11974 : 156 : unsigned int exptok;
11975 : 156 : unsigned int typetok;
11976 : 156 : unsigned int functok;
11977 : 156 : unsigned int ReturnVar;
11978 : 156 : unsigned int NoOfParam;
11979 : 156 : unsigned int Exp;
11980 : 156 : unsigned int Type;
11981 : :
11982 : 156 : M2Quads_PopT (&NoOfParam);
11983 : 156 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
11984 : 156 : if (NoOfParam == 2)
11985 : : {
11986 : 156 : Type = static_cast<unsigned int> (M2Quads_OperandT (2));
11987 : 156 : typetok = static_cast<unsigned int> (M2Quads_OperandTok (2));
11988 : 156 : Exp = static_cast<unsigned int> (M2Quads_OperandT (1));
11989 : 156 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
11990 : 156 : if (SymbolTable_IsUnknown (Type))
11991 : : {
11992 : : /* non recoverable error. */
11993 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCAST}", 41, Type);
11994 : : }
11995 : 156 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
11996 : : {
11997 : : /* avoid dangling else. */
11998 : : /* Generate fake result. */
11999 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12000 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12001 : 0 : SymbolTable_PutVar (ReturnVar, Type);
12002 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12003 : : }
12004 : 156 : else if (((((((SymbolTable_IsSet (Type)) || (SymbolTable_IsEnumeration (Type))) || (SymbolTable_IsSubrange (Type))) || (SymbolTable_IsType (Type))) || (SymbolTable_IsPointer (Type))) || (SymbolTable_IsArray (Type))) || (SymbolTable_IsProcType (Type)))
12005 : : {
12006 : : /* avoid dangling else. */
12007 : 156 : if (SymbolTable_IsConst (Exp))
12008 : : {
12009 : 30 : M2Quads_PopN (NoOfParam+1);
12010 : : /*
12011 : : Build macro: Type( Var )
12012 : : */
12013 : 30 : M2Quads_PushTFtok (Type, static_cast<unsigned int> (SymbolTable_NulSym), typetok);
12014 : 30 : M2Quads_PushTtok (Exp, exptok);
12015 : 30 : M2Quads_PushT (static_cast<unsigned int> (1)); /* one parameter */
12016 : 30 : BuildTypeCoercion (ConstExpr); /* one parameter */
12017 : : }
12018 : 126 : else if ((SymbolTable_IsVar (Exp)) || (SymbolTable_IsProcedure (Exp)))
12019 : : {
12020 : : /* avoid dangling else. */
12021 : 126 : M2Quads_PopN (NoOfParam+1);
12022 : 126 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, exptok);
12023 : 126 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, SymbolTable_RightValue);
12024 : 126 : SymbolTable_PutVar (ReturnVar, Type);
12025 : 252 : GenQuadO (combinedtok, M2Quads_CastOp, ReturnVar, Type, Exp, false);
12026 : 126 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12027 : : }
12028 : : else
12029 : : {
12030 : : /* avoid dangling else. */
12031 : : /* non recoverable error. */
12032 : 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);
12033 : : }
12034 : : }
12035 : : else
12036 : : {
12037 : : /* avoid dangling else. */
12038 : : /* non recoverable error. */
12039 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCAST} has the following formal parameter declaration {%kCAST} (type, expression)", 106);
12040 : : }
12041 : : }
12042 : : else
12043 : : {
12044 : : /* non recoverable error. */
12045 : 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);
12046 : : }
12047 : 156 : }
12048 : :
12049 : :
12050 : : /*
12051 : : BuildConvertFunction - builds the pseudo function CONVERT.
12052 : : CONVERT( Type, Variable ) ;
12053 : :
12054 : : The Stack:
12055 : :
12056 : :
12057 : : Entry Exit
12058 : :
12059 : : Ptr ->
12060 : : +----------------+
12061 : : | NoOfParam |
12062 : : |----------------|
12063 : : | Param 1 |
12064 : : |----------------|
12065 : : | Param 2 |
12066 : : |----------------|
12067 : : . .
12068 : : . .
12069 : : . .
12070 : : |----------------|
12071 : : | Param # | <- Ptr
12072 : : |----------------| +---------------------+
12073 : : | ProcSym | Type | | ReturnVar | Param1 |
12074 : : |----------------| |---------------------|
12075 : :
12076 : : Quadruples:
12077 : :
12078 : : ConvertOp ReturnVar Param1 Param2
12079 : :
12080 : : Converts variable Param2 into a variable Param1
12081 : : with a type Param1.
12082 : : */
12083 : :
12084 : 44526 : static void BuildConvertFunction (unsigned int ProcSym, bool ConstExpr)
12085 : : {
12086 : 44526 : unsigned int combinedtok;
12087 : 44526 : unsigned int functok;
12088 : 44526 : unsigned int typetok;
12089 : 44526 : unsigned int exptok;
12090 : 44526 : unsigned int t;
12091 : 44526 : unsigned int r;
12092 : 44526 : unsigned int Exp;
12093 : 44526 : unsigned int Type;
12094 : 44526 : unsigned int NoOfParam;
12095 : 44526 : unsigned int ReturnVar;
12096 : :
12097 : 44526 : M2Quads_PopT (&NoOfParam);
12098 : 44526 : functok = static_cast<unsigned int> (M2Quads_OperandTok (NoOfParam+1));
12099 : 44526 : if (NoOfParam == 2)
12100 : : {
12101 : 44526 : PopTrwtok (&Exp, &r, &exptok);
12102 : 44526 : MarkAsRead (r);
12103 : 44526 : M2Quads_PopTtok (&Type, &typetok);
12104 : 44526 : M2Quads_PopT (&ProcSym);
12105 : 44526 : if (SymbolTable_IsUnknown (Type))
12106 : : {
12107 : : /* non recoverable error. */
12108 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "undeclared type {%1Aad} found in {%kCONVERT}", 44, Type);
12109 : : }
12110 : 44526 : else if (SymbolTable_IsUnknown (Exp))
12111 : : {
12112 : : /* avoid dangling else. */
12113 : : /* non recoverable error. */
12114 : 0 : M2MetaError_MetaErrorT1 (typetok, (const char *) "unknown {%1Ad} {%1ad} found in {%kCONVERT}", 42, Exp);
12115 : : }
12116 : 44526 : else if (ConstExprError (ProcSym, Exp, exptok, ConstExpr))
12117 : : {
12118 : : /* avoid dangling else. */
12119 : : /* Generate fake result. */
12120 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12121 : 0 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12122 : 0 : SymbolTable_PutVar (ReturnVar, Type);
12123 : 0 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12124 : : }
12125 : 44526 : 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))))
12126 : : {
12127 : : /* avoid dangling else. */
12128 : : /* firstly dereference Var */
12129 : 44520 : if ((SymbolTable_GetMode (Exp)) == SymbolTable_LeftValue)
12130 : : {
12131 : 0 : t = SymbolTable_MakeTemporary (exptok, SymbolTable_RightValue);
12132 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (Exp));
12133 : 0 : CheckPointerThroughNil (exptok, Exp);
12134 : 0 : doIndrX (exptok, t, Exp);
12135 : 0 : Exp = t;
12136 : : }
12137 : 44520 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, exptok);
12138 : 89040 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Exp)));
12139 : 44520 : SymbolTable_PutVar (ReturnVar, Type);
12140 : 89040 : GenQuadO (combinedtok, M2Quads_ConvertOp, ReturnVar, Type, Exp, true);
12141 : 44520 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12142 : : }
12143 : : else
12144 : : {
12145 : : /* avoid dangling else. */
12146 : : /* non recoverable error. */
12147 : 6 : M2MetaError_MetaErrorT0 (functok, (const char *) "the builtin procedure {%AkCONVERT} has the following formal parameter declaration {%kCONVERT} (type, expression)", 112);
12148 : : }
12149 : : }
12150 : : else
12151 : : {
12152 : : /* non recoverable error. */
12153 : 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);
12154 : : }
12155 : 44520 : }
12156 : :
12157 : :
12158 : : /*
12159 : : CheckBaseTypeValue - checks to see whether the value, min, really exists.
12160 : : */
12161 : :
12162 : 1810 : static unsigned int CheckBaseTypeValue (unsigned int tok, unsigned int type, unsigned int min, unsigned int func)
12163 : : {
12164 : 1810 : if (((type == M2Base_Real) || (type == M2Base_LongReal)) || (type == M2Base_ShortReal))
12165 : : {
12166 : 102 : SymbolTable_PushValue (min);
12167 : 102 : if (! (M2ALU_IsValueAndTreeKnown ()))
12168 : : {
12169 : 0 : M2MetaError_MetaErrorT2 (tok, (const char *) "{%1Ead} ({%2ad}) cannot be calculated at compile time for the target architecture", 81, func, type);
12170 : 0 : return SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType);
12171 : : }
12172 : : }
12173 : : return min;
12174 : : /* static analysis guarentees a RETURN statement will be used before here. */
12175 : : __builtin_unreachable ();
12176 : : }
12177 : :
12178 : :
12179 : : /*
12180 : : GetTypeMin - returns the minimium value of type and generate an error
12181 : : if this is unavailable.
12182 : : */
12183 : :
12184 : 1170 : static unsigned int GetTypeMin (unsigned int tok, unsigned int func, unsigned int type)
12185 : : {
12186 : 1170 : unsigned int min;
12187 : :
12188 : 1170 : min = GetTypeMinLower (tok, func, type);
12189 : 1170 : if (min == SymbolTable_NulSym)
12190 : : {
12191 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMIN} value for type {%1ad}", 51, type);
12192 : : }
12193 : 1170 : return min;
12194 : : /* static analysis guarentees a RETURN statement will be used before here. */
12195 : : __builtin_unreachable ();
12196 : : }
12197 : :
12198 : :
12199 : : /*
12200 : : GetTypeMinLower - obtain the maximum value for type.
12201 : : */
12202 : :
12203 : 1170 : static unsigned int GetTypeMinLower (unsigned int tok, unsigned int func, unsigned int type)
12204 : : {
12205 : 1170 : unsigned int min;
12206 : 1170 : unsigned int max;
12207 : :
12208 : 1170 : if (SymbolTable_IsSubrange (type))
12209 : : {
12210 : 234 : min = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12211 : 234 : SymbolTable_PutVar (min, type);
12212 : 468 : GenQuad (M2Quads_SubrangeLowOp, min, SymbolTable_NulSym, type);
12213 : 234 : return min;
12214 : : }
12215 : 936 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12216 : : {
12217 : : /* avoid dangling else. */
12218 : 48 : return GetTypeMin (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12219 : : }
12220 : 888 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12221 : : {
12222 : : /* avoid dangling else. */
12223 : 686 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12224 : 686 : min = CheckBaseTypeValue (tok, type, min, func);
12225 : 686 : return min;
12226 : : }
12227 : 202 : else if (M2System_IsSystemType (type))
12228 : : {
12229 : : /* avoid dangling else. */
12230 : 186 : M2System_GetSystemTypeMinMax (type, &min, &max);
12231 : 186 : return min;
12232 : : }
12233 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12234 : : {
12235 : : /* avoid dangling else. */
12236 : : return SymbolTable_NulSym;
12237 : : }
12238 : : else
12239 : : {
12240 : : /* avoid dangling else. */
12241 : 16 : return GetTypeMin (tok, func, SymbolTable_GetSType (type));
12242 : : }
12243 : : /* static analysis guarentees a RETURN statement will be used before here. */
12244 : : __builtin_unreachable ();
12245 : : }
12246 : :
12247 : :
12248 : : /*
12249 : : GetTypeMax - returns the maximum value of type and generate an error
12250 : : if this is unavailable.
12251 : : */
12252 : :
12253 : 7258 : static unsigned int GetTypeMax (unsigned int tok, unsigned int func, unsigned int type)
12254 : : {
12255 : 7258 : unsigned int max;
12256 : :
12257 : 7258 : max = GetTypeMaxLower (tok, func, type);
12258 : 7258 : if (max == SymbolTable_NulSym)
12259 : : {
12260 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "unable to obtain the {%AkMAX} value for type {%1ad}", 51, type);
12261 : : }
12262 : 7258 : return max;
12263 : : /* static analysis guarentees a RETURN statement will be used before here. */
12264 : : __builtin_unreachable ();
12265 : : }
12266 : :
12267 : :
12268 : : /*
12269 : : GetTypeMaxLower - obtain the maximum value for type.
12270 : : */
12271 : :
12272 : 7258 : static unsigned int GetTypeMaxLower (unsigned int tok, unsigned int func, unsigned int type)
12273 : : {
12274 : 7258 : unsigned int min;
12275 : 7258 : unsigned int max;
12276 : :
12277 : 7258 : if (SymbolTable_IsSubrange (type))
12278 : : {
12279 : 3116 : max = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
12280 : 3116 : SymbolTable_PutVar (max, type);
12281 : 6232 : GenQuad (M2Quads_SubrangeHighOp, max, SymbolTable_NulSym, type);
12282 : 3116 : return max;
12283 : : }
12284 : 4142 : else if (SymbolTable_IsSet (SymbolTable_SkipType (type)))
12285 : : {
12286 : : /* avoid dangling else. */
12287 : 2800 : return GetTypeMax (tok, func, SymbolTable_GetSType (SymbolTable_SkipType (type)));
12288 : : }
12289 : 1342 : else if ((M2Base_IsBaseType (type)) || (SymbolTable_IsEnumeration (type)))
12290 : : {
12291 : : /* avoid dangling else. */
12292 : 1124 : M2Base_GetBaseTypeMinMax (type, &min, &max);
12293 : 1124 : min = CheckBaseTypeValue (tok, type, min, func);
12294 : 1124 : return max;
12295 : : }
12296 : 218 : else if (M2System_IsSystemType (type))
12297 : : {
12298 : : /* avoid dangling else. */
12299 : 202 : M2System_GetSystemTypeMinMax (type, &min, &max);
12300 : 202 : return max;
12301 : : }
12302 : 16 : else if ((SymbolTable_GetSType (type)) == SymbolTable_NulSym)
12303 : : {
12304 : : /* avoid dangling else. */
12305 : : return SymbolTable_NulSym;
12306 : : }
12307 : : else
12308 : : {
12309 : : /* avoid dangling else. */
12310 : 16 : return GetTypeMax (tok, func, SymbolTable_GetSType (type));
12311 : : }
12312 : : /* static analysis guarentees a RETURN statement will be used before here. */
12313 : : __builtin_unreachable ();
12314 : : }
12315 : :
12316 : :
12317 : : /*
12318 : : BuildMinFunction - builds the pseudo function call Min.
12319 : :
12320 : : The Stack:
12321 : :
12322 : : Entry Exit
12323 : :
12324 : : Ptr ->
12325 : : +----------------+
12326 : : | NoOfParam=1 |
12327 : : |----------------|
12328 : : | Param 1 |
12329 : : |----------------|
12330 : : | ProcSym | Type | Empty
12331 : : |----------------|
12332 : : */
12333 : :
12334 : 1106 : static void BuildMinFunction (void)
12335 : : {
12336 : 1106 : unsigned int combinedtok;
12337 : 1106 : unsigned int functok;
12338 : 1106 : unsigned int vartok;
12339 : 1106 : unsigned int func;
12340 : 1106 : unsigned int min;
12341 : 1106 : unsigned int NoOfParam;
12342 : 1106 : unsigned int Var;
12343 : :
12344 : 1106 : M2Quads_PopT (&NoOfParam);
12345 : 1106 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12346 : 1106 : functok = OperandTtok (NoOfParam+1);
12347 : 1106 : if (NoOfParam == 1)
12348 : : {
12349 : 1106 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12350 : 1106 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12351 : 1106 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12352 : 1106 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12353 : 1106 : if (SymbolTable_IsAModula2Type (Var))
12354 : : {
12355 : 1106 : min = GetTypeMin (vartok, func, Var);
12356 : 1106 : M2Quads_PushTFtok (min, SymbolTable_GetSType (min), combinedtok);
12357 : : }
12358 : 0 : else if (SymbolTable_IsVar (Var))
12359 : : {
12360 : : /* avoid dangling else. */
12361 : 0 : min = GetTypeMin (vartok, func, SymbolTable_GetSType (Var));
12362 : 0 : M2Quads_PushTFtok (min, SymbolTable_GetSType (Var), combinedtok);
12363 : : }
12364 : : else
12365 : : {
12366 : : /* avoid dangling else. */
12367 : : /* non recoverable error. */
12368 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMIN} must be a type or a variable, seen {%1ad}", 63, Var);
12369 : : }
12370 : : }
12371 : : else
12372 : : {
12373 : : /* non recoverable error. */
12374 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMIN} only has one parameter, seen {%1n}", 82, NoOfParam);
12375 : : }
12376 : 1106 : }
12377 : :
12378 : :
12379 : : /*
12380 : : BuildMaxFunction - builds the pseudo function call Max.
12381 : :
12382 : : The Stack:
12383 : :
12384 : : Entry Exit
12385 : :
12386 : : Ptr ->
12387 : : +----------------+
12388 : : | NoOfParam=1 |
12389 : : |----------------|
12390 : : | Param 1 |
12391 : : |----------------|
12392 : : | ProcSym | Type | Empty
12393 : : |----------------|
12394 : : */
12395 : :
12396 : 4442 : static void BuildMaxFunction (void)
12397 : : {
12398 : 4442 : unsigned int combinedtok;
12399 : 4442 : unsigned int functok;
12400 : 4442 : unsigned int vartok;
12401 : 4442 : unsigned int func;
12402 : 4442 : unsigned int max;
12403 : 4442 : unsigned int NoOfParam;
12404 : 4442 : unsigned int Var;
12405 : :
12406 : 4442 : M2Quads_PopT (&NoOfParam);
12407 : 4442 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12408 : 4442 : functok = OperandTtok (NoOfParam+1);
12409 : 4442 : if (NoOfParam == 1)
12410 : : {
12411 : 4442 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12412 : 4442 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12413 : 4442 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12414 : 4442 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok); /* destroy arguments to this function */
12415 : 4442 : if (SymbolTable_IsAModula2Type (Var))
12416 : : {
12417 : 4442 : max = GetTypeMax (vartok, func, Var);
12418 : 4442 : M2Quads_PushTFtok (max, SymbolTable_GetSType (max), combinedtok);
12419 : : }
12420 : 0 : else if (SymbolTable_IsVar (Var))
12421 : : {
12422 : : /* avoid dangling else. */
12423 : 0 : max = GetTypeMax (vartok, func, SymbolTable_GetSType (Var));
12424 : 0 : M2Quads_PushTFtok (max, SymbolTable_GetSType (Var), combinedtok);
12425 : : }
12426 : : else
12427 : : {
12428 : : /* avoid dangling else. */
12429 : : /* non recoverable error. */
12430 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "parameter to {%AkMAX} must be a type or a variable, seen {%1ad}", 63, Var);
12431 : : }
12432 : : }
12433 : : else
12434 : : {
12435 : : /* non recoverable error. */
12436 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkMAX} only has one parameter, seen {%1n}", 81, NoOfParam);
12437 : : }
12438 : 4442 : }
12439 : :
12440 : :
12441 : : /*
12442 : : BuildTruncFunction - builds the pseudo procedure call TRUNC.
12443 : : This procedure is actually a "macro" for
12444 : : TRUNC(x) --> CONVERT(INTEGER, x)
12445 : : However we cannot push tokens back onto the input stack
12446 : : because the compiler is currently building a function
12447 : : call and expecting a ReturnVar on the stack.
12448 : : Hence we manipulate the stack and call
12449 : : BuildConvertFunction.
12450 : :
12451 : : The Stack:
12452 : :
12453 : :
12454 : : Entry Exit
12455 : :
12456 : : Ptr ->
12457 : : +----------------+
12458 : : | NoOfParam |
12459 : : |----------------|
12460 : : | Param 1 |
12461 : : |----------------|
12462 : : | Param 2 |
12463 : : |----------------|
12464 : : . .
12465 : : . .
12466 : : . .
12467 : : |----------------|
12468 : : | Param # |
12469 : : |----------------|
12470 : : | ProcSym | Type | Empty
12471 : : |----------------|
12472 : : */
12473 : :
12474 : 60 : static void BuildTruncFunction (unsigned int Sym, bool ConstExpr)
12475 : : {
12476 : 60 : unsigned int combinedtok;
12477 : 60 : unsigned int vartok;
12478 : 60 : unsigned int functok;
12479 : 60 : unsigned int NoOfParam;
12480 : 60 : unsigned int ReturnVar;
12481 : 60 : unsigned int ProcSym;
12482 : 60 : unsigned int Type;
12483 : 60 : unsigned int Var;
12484 : :
12485 : 60 : M2Quads_PopT (&NoOfParam);
12486 : 60 : M2Debug_Assert (M2Base_IsTrunc (M2Quads_OperandT (NoOfParam+1)));
12487 : 60 : functok = OperandTtok (NoOfParam+1);
12488 : 60 : if (NoOfParam == 1)
12489 : : {
12490 : 60 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12491 : 60 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12492 : : {
12493 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12494 : 60 : vartok = OperandTtok (1);
12495 : 60 : Type = SymbolTable_GetSType (Sym);
12496 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12497 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12498 : : {
12499 : : /* Generate fake result. */
12500 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12501 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12502 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12503 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12504 : : }
12505 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12506 : : {
12507 : : /* avoid dangling else. */
12508 : 54 : if (M2Base_IsRealType (SymbolTable_GetSType (Var)))
12509 : : {
12510 : : /* build macro: CONVERT( INTEGER, Var ). */
12511 : 54 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12512 : 54 : M2Quads_PushTtok (Type, functok);
12513 : 54 : M2Quads_PushTtok (Var, vartok);
12514 : 54 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters */
12515 : 54 : BuildConvertFunction (M2Base_Convert, ConstExpr); /* two parameters */
12516 : : }
12517 : : else
12518 : : {
12519 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "argument to {%1Ead} must be a float point type", 46, Sym);
12520 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12521 : : }
12522 : : }
12523 : : else
12524 : : {
12525 : : /* avoid dangling else. */
12526 : 0 : M2MetaError_MetaErrorT2 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant, seen {%2ad}", 63, Sym, Var);
12527 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), Type), Type, functok);
12528 : : }
12529 : : }
12530 : : else
12531 : : {
12532 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for TRUNC substitution", 50);
12533 : : }
12534 : : }
12535 : : else
12536 : : {
12537 : : /* non recoverable error. */
12538 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the pseudo builtin procedure function {%AkTRUNC} only has one parameter, seen {%1n}", 84, NoOfParam);
12539 : : }
12540 : 60 : }
12541 : :
12542 : :
12543 : : /*
12544 : : BuildFloatFunction - builds the pseudo procedure call FLOAT.
12545 : : This procedure is actually a "macro" for
12546 : : FLOAT(x) --> CONVERT(REAL, x)
12547 : : However we cannot push tokens back onto the input stack
12548 : : because the compiler is currently building a function
12549 : : call and expecting a ReturnVar on the stack.
12550 : : Hence we manipulate the stack and call
12551 : : BuildConvertFunction.
12552 : :
12553 : : The Stack:
12554 : :
12555 : :
12556 : : Entry Exit
12557 : :
12558 : : Ptr ->
12559 : : +----------------+
12560 : : | NoOfParam |
12561 : : |----------------|
12562 : : | Param 1 |
12563 : : |----------------|
12564 : : | Param 2 |
12565 : : |----------------|
12566 : : . .
12567 : : . .
12568 : : . .
12569 : : |----------------|
12570 : : | Param # |
12571 : : |----------------|
12572 : : | ProcSym | Type | Empty
12573 : : |----------------|
12574 : : */
12575 : :
12576 : 64 : static void BuildFloatFunction (unsigned int Sym, bool ConstExpr)
12577 : : {
12578 : 64 : unsigned int combinedtok;
12579 : 64 : unsigned int vartok;
12580 : 64 : unsigned int functok;
12581 : 64 : unsigned int NoOfParam;
12582 : 64 : unsigned int ReturnVar;
12583 : 64 : unsigned int Type;
12584 : 64 : unsigned int Var;
12585 : 64 : unsigned int ProcSym;
12586 : :
12587 : 64 : M2Quads_PopT (&NoOfParam);
12588 : 64 : functok = OperandTtok (NoOfParam+1);
12589 : 64 : Type = SymbolTable_GetSType (Sym);
12590 : 64 : if (NoOfParam == 1)
12591 : : {
12592 : 64 : ProcSym = SymbolTable_RequestSym (functok, NameKey_MakeKey ((const char *) "CONVERT", 7));
12593 : 64 : if ((ProcSym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (ProcSym)))
12594 : : {
12595 : 64 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12596 : 64 : vartok = OperandTtok (1);
12597 : 64 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12598 : 64 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12599 : : {
12600 : : /* Generate fake result. */
12601 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12602 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12603 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12604 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12605 : : }
12606 : 58 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12607 : : {
12608 : : /* avoid dangling else. */
12609 : : /* build macro: CONVERT (REAL, Var). */
12610 : 58 : M2Quads_PushTFtok (ProcSym, static_cast<unsigned int> (SymbolTable_NulSym), functok);
12611 : 58 : M2Quads_PushTtok (Type, functok);
12612 : 58 : M2Quads_PushTtok (Var, vartok);
12613 : 58 : M2Quads_PushT (static_cast<unsigned int> (2)); /* two parameters. */
12614 : 58 : BuildConvertFunction (ProcSym, ConstExpr); /* two parameters. */
12615 : : }
12616 : : else
12617 : : {
12618 : : /* avoid dangling else. */
12619 : 0 : M2MetaError_MetaErrorT1 (vartok, (const char *) "argument to {%1Ead} must be a variable or constant", 50, ProcSym);
12620 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12621 : : }
12622 : : }
12623 : : else
12624 : : {
12625 : 0 : M2Error_InternalError ((const char *) "CONVERT procedure not found for FLOAT substitution", 50);
12626 : : }
12627 : : }
12628 : : else
12629 : : {
12630 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function. */
12631 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter", 61, Sym); /* destroy arguments to this function. */
12632 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0.0", 3), Type), Type, functok);
12633 : : }
12634 : 64 : }
12635 : :
12636 : :
12637 : : /*
12638 : : BuildReFunction - builds the pseudo procedure call RE.
12639 : :
12640 : : The Stack:
12641 : :
12642 : :
12643 : : Entry Exit
12644 : :
12645 : : Ptr ->
12646 : : +----------------+
12647 : : | NoOfParam |
12648 : : |----------------|
12649 : : | Param 1 |
12650 : : |----------------|
12651 : : | Param 2 |
12652 : : |----------------|
12653 : : . .
12654 : : . .
12655 : : . .
12656 : : |----------------|
12657 : : | Param # |
12658 : : |----------------|
12659 : : | ProcSym | Type | Empty
12660 : : |----------------|
12661 : : */
12662 : :
12663 : 60 : static void BuildReFunction (unsigned int Sym, bool ConstExpr)
12664 : : {
12665 : 60 : unsigned int func;
12666 : 60 : unsigned int combinedtok;
12667 : 60 : unsigned int vartok;
12668 : 60 : unsigned int functok;
12669 : 60 : unsigned int NoOfParam;
12670 : 60 : unsigned int ReturnVar;
12671 : 60 : unsigned int Type;
12672 : 60 : unsigned int Var;
12673 : :
12674 : 60 : M2Quads_PopT (&NoOfParam);
12675 : 60 : functok = OperandTtok (NoOfParam+1);
12676 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12677 : 60 : if (NoOfParam == 1)
12678 : : {
12679 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12680 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12681 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12682 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12683 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12684 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12685 : : {
12686 : : /* Generate fake result. */
12687 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12688 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12689 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12690 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12691 : : }
12692 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12693 : : {
12694 : : /* avoid dangling else. */
12695 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12696 : 54 : SymbolTable_PutVar (ReturnVar, Type);
12697 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Re, Var, false);
12698 : 54 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12699 : : }
12700 : : else
12701 : : {
12702 : : /* avoid dangling else. */
12703 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12704 : 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);
12705 : : }
12706 : : }
12707 : : else
12708 : : {
12709 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12710 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12711 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12712 : : }
12713 : 60 : }
12714 : :
12715 : :
12716 : : /*
12717 : : BuildImFunction - builds the pseudo procedure call IM.
12718 : :
12719 : : The Stack:
12720 : :
12721 : :
12722 : : Entry Exit
12723 : :
12724 : : Ptr ->
12725 : : +----------------+
12726 : : | NoOfParam |
12727 : : |----------------|
12728 : : | Param 1 |
12729 : : |----------------|
12730 : : | Param 2 |
12731 : : |----------------|
12732 : : . .
12733 : : . .
12734 : : . .
12735 : : |----------------|
12736 : : | Param # |
12737 : : |----------------|
12738 : : | ProcSym | Type | Empty
12739 : : |----------------|
12740 : : */
12741 : :
12742 : 60 : static void BuildImFunction (unsigned int Sym, bool ConstExpr)
12743 : : {
12744 : 60 : unsigned int func;
12745 : 60 : unsigned int combinedtok;
12746 : 60 : unsigned int vartok;
12747 : 60 : unsigned int functok;
12748 : 60 : unsigned int NoOfParam;
12749 : 60 : unsigned int ReturnVar;
12750 : 60 : unsigned int Type;
12751 : 60 : unsigned int Var;
12752 : :
12753 : 60 : M2Quads_PopT (&NoOfParam);
12754 : 60 : functok = OperandTtok (NoOfParam+1);
12755 : 60 : func = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
12756 : 60 : if (NoOfParam == 1)
12757 : : {
12758 : 60 : Var = static_cast<unsigned int> (M2Quads_OperandT (1));
12759 : 60 : vartok = static_cast<unsigned int> (M2Quads_OperandTok (1));
12760 : 60 : Type = M2Base_ComplexToScalar (SymbolTable_GetDType (Var));
12761 : 60 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, vartok);
12762 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12763 : 60 : if (ConstExprError (Sym, Var, vartok, ConstExpr))
12764 : : {
12765 : : /* Generate fake result. */
12766 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, vartok);
12767 : 12 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12768 : 6 : SymbolTable_PutVar (ReturnVar, Type);
12769 : 6 : M2Quads_PushTFtok (ReturnVar, Type, combinedtok);
12770 : : }
12771 : 54 : else if ((SymbolTable_IsVar (Var)) || (SymbolTable_IsConst (Var)))
12772 : : {
12773 : : /* avoid dangling else. */
12774 : 108 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant (SymbolTable_IsConst (Var)));
12775 : 54 : SymbolTable_PutVar (ReturnVar, M2Base_ComplexToScalar (SymbolTable_GetDType (Var)));
12776 : 108 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Im, Var, false);
12777 : 54 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ReturnVar), combinedtok);
12778 : : }
12779 : : else
12780 : : {
12781 : : /* avoid dangling else. */
12782 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, combinedtok);
12783 : 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);
12784 : : }
12785 : : }
12786 : : else
12787 : : {
12788 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12789 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_RType), M2Base_RType, functok); /* destroy arguments to this function */
12790 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure function {%1Ead} only has one parameter, seen {%2n}", 73, func, NoOfParam);
12791 : : }
12792 : 60 : }
12793 : :
12794 : :
12795 : : /*
12796 : : BuildCmplxFunction - builds the pseudo procedure call CMPLX.
12797 : :
12798 : : The Stack:
12799 : :
12800 : :
12801 : : Entry Exit
12802 : :
12803 : : Ptr ->
12804 : : +----------------+
12805 : : | NoOfParam |
12806 : : |----------------|
12807 : : | Param 1 |
12808 : : |----------------|
12809 : : | Param 2 |
12810 : : |----------------|
12811 : : . .
12812 : : . .
12813 : : . .
12814 : : |----------------|
12815 : : | Param # |
12816 : : |----------------|
12817 : : | ProcSym | Type | Empty
12818 : : |----------------|
12819 : : */
12820 : :
12821 : 492 : static void BuildCmplxFunction (unsigned int func, bool ConstExpr)
12822 : : {
12823 : 492 : bool failure;
12824 : 492 : unsigned int functok;
12825 : 492 : unsigned int rtok;
12826 : 492 : unsigned int ltok;
12827 : 492 : unsigned int combinedtok;
12828 : 492 : unsigned int NoOfParam;
12829 : 492 : unsigned int type;
12830 : 492 : unsigned int ReturnVar;
12831 : 492 : unsigned int l;
12832 : 492 : unsigned int r;
12833 : :
12834 : 492 : M2Quads_PopT (&NoOfParam);
12835 : 492 : functok = OperandTtok (NoOfParam+1);
12836 : 492 : if (NoOfParam == 2)
12837 : : {
12838 : 492 : l = static_cast<unsigned int> (M2Quads_OperandT (2));
12839 : 492 : ltok = OperandTtok (2);
12840 : 492 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
12841 : 492 : rtok = OperandTtok (1);
12842 : 492 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, rtok);
12843 : 492 : M2Quads_PopN (NoOfParam+1); /* Destroy arguments to this function. */
12844 : 492 : type = M2Base_GetCmplxReturnType (SymbolTable_GetDType (l), SymbolTable_GetDType (r)); /* Destroy arguments to this function. */
12845 : 570 : ReturnVar = SymbolTable_MakeTemporary (combinedtok, AreConstant ((SymbolTable_IsConst (l)) && (SymbolTable_IsConst (r))));
12846 : 492 : SymbolTable_PutVar (ReturnVar, type);
12847 : 492 : failure = false;
12848 : 492 : if (ConstExprError (func, l, ltok, ConstExpr))
12849 : : {
12850 : : /* ConstExprError has generated an error message we will fall through
12851 : : and check the right operand. */
12852 : : failure = true;
12853 : : }
12854 : 492 : if (ConstExprError (func, r, rtok, ConstExpr))
12855 : : {
12856 : : /* Right operand is in error as a variable. */
12857 : : failure = true;
12858 : : }
12859 : 486 : if (failure)
12860 : : {
12861 : : /* Generate a fake result if either operand was a variable (and we
12862 : : are in a const expression). */
12863 : 6 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12864 : : }
12865 : 486 : else if (((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l))) && ((SymbolTable_IsVar (r)) || (SymbolTable_IsConst (r))))
12866 : : {
12867 : : /* avoid dangling else. */
12868 : 486 : M2Base_CheckExpressionCompatible (combinedtok, SymbolTable_GetSType (l), SymbolTable_GetSType (r));
12869 : 486 : GenQuadO (combinedtok, M2Quads_StandardFunctionOp, ReturnVar, M2Base_Cmplx, SymbolTable_Make2Tuple (l, r), true);
12870 : 486 : M2Quads_PushTFtok (ReturnVar, type, combinedtok);
12871 : : }
12872 : : else
12873 : : {
12874 : : /* avoid dangling else. */
12875 : 0 : if ((SymbolTable_IsVar (l)) || (SymbolTable_IsConst (l)))
12876 : : {
12877 : 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);
12878 : : }
12879 : : else
12880 : : {
12881 : 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);
12882 : : }
12883 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, combinedtok);
12884 : : }
12885 : : }
12886 : : else
12887 : : {
12888 : 0 : M2MetaError_MetaErrorT2 (functok, (const char *) "the builtin procedure {%1Ead} requires two parameters, seen {%2n}", 65, func, NoOfParam);
12889 : 0 : M2Quads_PopN (NoOfParam+1); /* destroy arguments to this function */
12890 : 0 : M2Quads_PushTFtok (SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "1.0", 3), M2Base_CType), M2Base_CType, functok); /* destroy arguments to this function */
12891 : : }
12892 : 492 : }
12893 : :
12894 : :
12895 : : /*
12896 : : BuildAdrFunction - builds the pseudo function ADR
12897 : : The Stack:
12898 : :
12899 : :
12900 : : Entry Exit
12901 : :
12902 : : Ptr ->
12903 : : +----------------+
12904 : : | NoOfParam |
12905 : : |----------------|
12906 : : | Param 1 |
12907 : : |----------------|
12908 : : | Param 2 |
12909 : : |----------------|
12910 : : . .
12911 : : . .
12912 : : . .
12913 : : |----------------|
12914 : : | Param # | <- Ptr
12915 : : |----------------| +------------+
12916 : : | ProcSym | Type | | ReturnVar |
12917 : : |----------------| |------------|
12918 : :
12919 : : */
12920 : :
12921 : 170746 : static void BuildAdrFunction (void)
12922 : : {
12923 : 170746 : unsigned int endtok;
12924 : 170746 : unsigned int combinedTok;
12925 : 170746 : unsigned int procTok;
12926 : 170746 : unsigned int t;
12927 : 170746 : unsigned int UnboundedSym;
12928 : 170746 : unsigned int Dim;
12929 : 170746 : unsigned int Field;
12930 : 170746 : unsigned int noOfParameters;
12931 : 170746 : unsigned int procSym;
12932 : 170746 : unsigned int returnVar;
12933 : 170746 : unsigned int Type;
12934 : 170746 : unsigned int rw;
12935 : :
12936 : 170746 : M2Quads_DisplayStack ();
12937 : 170746 : M2Quads_PopT (&noOfParameters);
12938 : 170746 : procSym = static_cast<unsigned int> (M2Quads_OperandT (noOfParameters+1));
12939 : 170746 : procTok = static_cast<unsigned int> (M2Quads_OperandTok (noOfParameters+1)); /* token of procedure ADR. */
12940 : 170746 : endtok = static_cast<unsigned int> (M2Quads_OperandTok (1)); /* last parameter. */
12941 : 170746 : combinedTok = M2LexBuf_MakeVirtualTok (procTok, procTok, endtok); /* last parameter. */
12942 : 170746 : if (noOfParameters != 1)
12943 : : {
12944 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects 1 parameter", 40);
12945 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12946 : 0 : M2Quads_PushTF (M2Base_Nil, M2System_Address); /* destroy the arguments and function */
12947 : : }
12948 : 170746 : else if (SymbolTable_IsConstString (M2Quads_OperandT (1)))
12949 : : {
12950 : : /* avoid dangling else. */
12951 : 162980 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
12952 : 162980 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12953 : 162980 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
12954 : : }
12955 : 7766 : else if ((! (SymbolTable_IsVar (M2Quads_OperandT (1)))) && (! (SymbolTable_IsProcedure (M2Quads_OperandT (1)))))
12956 : : {
12957 : : /* avoid dangling else. */
12958 : 0 : M2MetaError_MetaErrorNT0 (combinedTok, (const char *) "SYSTEM procedure ADR expects a variable, procedure or a constant string as its parameter", 88);
12959 : 0 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12960 : 0 : M2Quads_PushTFtok (M2Base_Nil, M2System_Address, combinedTok); /* destroy the arguments and function */
12961 : : }
12962 : 7766 : else if (SymbolTable_IsProcedure (M2Quads_OperandT (1)))
12963 : : {
12964 : : /* avoid dangling else. */
12965 : 24 : returnVar = MakeLeftValue (combinedTok, M2Quads_OperandT (1), SymbolTable_RightValue, SymbolTable_GetSType (procSym));
12966 : 24 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
12967 : 24 : M2Quads_PushTFtok (returnVar, SymbolTable_GetSType (returnVar), combinedTok); /* destroy the arguments and function */
12968 : : }
12969 : : else
12970 : : {
12971 : : /* avoid dangling else. */
12972 : 7742 : Type = SymbolTable_GetSType (M2Quads_OperandT (1));
12973 : 7742 : Dim = static_cast<unsigned int> (OperandD (1));
12974 : 7742 : MarkArrayWritten (M2Quads_OperandT (1));
12975 : 7742 : MarkArrayWritten (M2Quads_OperandA (1));
12976 : : /* if the operand is an unbounded which has not been indexed
12977 : : then we will lookup its address from the unbounded record.
12978 : : Otherwise we obtain the address of the operand.
12979 : : */
12980 : 7742 : if ((SymbolTable_IsUnbounded (Type)) && (Dim == 0))
12981 : : {
12982 : : /* we will reference the address field of the unbounded structure */
12983 : 2412 : UnboundedSym = static_cast<unsigned int> (M2Quads_OperandT (1));
12984 : 2412 : rw = static_cast<unsigned int> (OperandRW (1));
12985 : 2412 : PushTFrw (UnboundedSym, SymbolTable_GetSType (UnboundedSym), rw);
12986 : 2412 : Field = SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (UnboundedSym));
12987 : 2412 : M2Quads_PushTF (Field, SymbolTable_GetSType (Field));
12988 : 2412 : M2Quads_PushT (static_cast<unsigned int> (1));
12989 : 2412 : M2Quads_BuildDesignatorRecord (combinedTok);
12990 : 2412 : PopTrw (&returnVar, &rw);
12991 : 2412 : if ((SymbolTable_GetMode (returnVar)) == SymbolTable_LeftValue)
12992 : : {
12993 : 0 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
12994 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
12995 : 0 : doIndrX (combinedTok, t, returnVar);
12996 : 0 : returnVar = t;
12997 : : }
12998 : : else
12999 : : {
13000 : : /* we need to cast returnVar into ADDRESS */
13001 : 2412 : t = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
13002 : 2412 : SymbolTable_PutVar (t, SymbolTable_GetSType (procSym));
13003 : 2412 : GenQuadO (combinedTok, M2Quads_ConvertOp, t, SymbolTable_GetSType (procSym), returnVar, false);
13004 : 2412 : returnVar = t;
13005 : : }
13006 : : }
13007 : : else
13008 : : {
13009 : 5330 : returnVar = SymbolTable_MakeTemporary (combinedTok, SymbolTable_RightValue);
13010 : 5330 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
13011 : 5330 : if ((SymbolTable_GetMode (M2Quads_OperandT (1))) == SymbolTable_LeftValue)
13012 : : {
13013 : 522 : SymbolTable_PutVar (returnVar, SymbolTable_GetSType (procSym));
13014 : 522 : GenQuadO (combinedTok, M2Quads_ConvertOp, returnVar, SymbolTable_GetSType (procSym), M2Quads_OperandT (1), false);
13015 : : }
13016 : : else
13017 : : {
13018 : 4808 : GenQuadO (combinedTok, M2Quads_AddrOp, returnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
13019 : : }
13020 : 5330 : SymbolTable_PutWriteQuad (M2Quads_OperandT (1), SymbolTable_GetMode (M2Quads_OperandT (1)), NextQuad-1);
13021 : 5330 : rw = static_cast<unsigned int> (OperandMergeRW (1));
13022 : 5330 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13023 : : }
13024 : 7742 : M2Quads_PopN (noOfParameters+1); /* destroy the arguments and function */
13025 : 7742 : PushTFrwtok (returnVar, SymbolTable_GetSType (returnVar), rw, combinedTok); /* destroy the arguments and function */
13026 : : }
13027 : 170746 : }
13028 : :
13029 : :
13030 : : /*
13031 : : BuildSizeFunction - builds the pseudo function SIZE
13032 : : The Stack:
13033 : :
13034 : :
13035 : : Entry Exit
13036 : :
13037 : : Ptr ->
13038 : : +----------------+
13039 : : | NoOfParam |
13040 : : |----------------|
13041 : : | Param 1 |
13042 : : |----------------|
13043 : : | Param 2 |
13044 : : |----------------|
13045 : : . .
13046 : : . .
13047 : : . .
13048 : : |----------------|
13049 : : | Param # | <- Ptr
13050 : : |----------------| +------------+
13051 : : | ProcSym | Type | | ReturnVar |
13052 : : |----------------| |------------|
13053 : : */
13054 : :
13055 : 2242 : static void BuildSizeFunction (void)
13056 : : {
13057 : 2242 : unsigned int resulttok;
13058 : 2242 : unsigned int paramtok;
13059 : 2242 : unsigned int functok;
13060 : 2242 : unsigned int dim;
13061 : 2242 : unsigned int Type;
13062 : 2242 : unsigned int NoOfParam;
13063 : 2242 : unsigned int ProcSym;
13064 : 2242 : unsigned int ReturnVar;
13065 : :
13066 : 2242 : M2Quads_PopT (&NoOfParam);
13067 : 2242 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13068 : 2242 : functok = OperandTtok (NoOfParam+1);
13069 : 2242 : if (NoOfParam != 1)
13070 : : {
13071 : 0 : M2MetaError_MetaErrorT1 (functok, (const char *) "{%E} SYSTEM procedure function {%kSIZE} requires one parameter, seen {%1n}", 74, NoOfParam);
13072 : 0 : resulttok = functok;
13073 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13074 : : }
13075 : 2242 : else if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13076 : : {
13077 : : /* avoid dangling else. */
13078 : 1184 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
13079 : 1184 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13080 : 1184 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
13081 : 1184 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue); /* Quadruple generation now on. */
13082 : 1184 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), true);
13083 : : }
13084 : 1058 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13085 : : {
13086 : : /* avoid dangling else. */
13087 : 1052 : BuildSizeCheckEnd (ProcSym); /* Quadruple generation now on. */
13088 : 1052 : Type = SymbolTable_GetSType (M2Quads_OperandT (1)); /* Quadruple generation now on. */
13089 : 1052 : paramtok = static_cast<unsigned int> (M2Quads_OperandTok (1));
13090 : 1052 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13091 : 1052 : if (SymbolTable_IsUnbounded (Type))
13092 : : {
13093 : : /* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE. */
13094 : 168 : dim = static_cast<unsigned int> (OperandD (1));
13095 : 168 : if (dim == 0)
13096 : : {
13097 : 72 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandT (1), Type, dim);
13098 : : }
13099 : : else
13100 : : {
13101 : 96 : ReturnVar = calculateMultipicand (resulttok, M2Quads_OperandA (1), Type, dim);
13102 : : }
13103 : : }
13104 : : else
13105 : : {
13106 : 884 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13107 : 884 : if (Type == SymbolTable_NulSym)
13108 : : {
13109 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "cannot get the type and size of {%1Ead}", 39, M2Quads_OperandT (1));
13110 : : }
13111 : 884 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Type, true);
13112 : : }
13113 : : }
13114 : : else
13115 : : {
13116 : : /* avoid dangling else. */
13117 : 6 : resulttok = functok;
13118 : 6 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure {%kSIZE} expects a variable as its parameter, seen {%1Ed}", 78, M2Quads_OperandT (1));
13119 : 6 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13120 : : }
13121 : 2242 : M2Quads_PopN (NoOfParam+1); /* Destroy the arguments and function. */
13122 : 2242 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* Destroy the arguments and function. */
13123 : 2242 : }
13124 : :
13125 : :
13126 : : /*
13127 : : BuildTSizeFunction - builds the pseudo function TSIZE
13128 : : The Stack:
13129 : :
13130 : :
13131 : : Entry Exit
13132 : :
13133 : : Ptr ->
13134 : : +----------------+
13135 : : | NoOfParam |
13136 : : |----------------|
13137 : : | Param 1 |
13138 : : |----------------|
13139 : : | Param 2 |
13140 : : |----------------|
13141 : : . .
13142 : : . .
13143 : : . .
13144 : : |----------------|
13145 : : | Param # | <- Ptr
13146 : : |----------------| +------------+
13147 : : | ProcSym | Type | | ReturnVar |
13148 : : |----------------| |------------|
13149 : :
13150 : : */
13151 : :
13152 : 3572 : static void BuildTSizeFunction (void)
13153 : : {
13154 : 3572 : unsigned int resulttok;
13155 : 3572 : unsigned int paramtok;
13156 : 3572 : unsigned int functok;
13157 : 3572 : unsigned int NoOfParam;
13158 : 3572 : unsigned int ProcSym;
13159 : 3572 : unsigned int Record;
13160 : 3572 : unsigned int ReturnVar;
13161 : :
13162 : 3572 : M2Quads_PopT (&NoOfParam);
13163 : 3572 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13164 : 3572 : functok = OperandTtok (NoOfParam);
13165 : 3572 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13166 : 3572 : if (NoOfParam == 1) /* quadruple generation now on */
13167 : : {
13168 : 3572 : paramtok = OperandTtok (1);
13169 : 3572 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13170 : 3572 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13171 : : {
13172 : 3544 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13173 : 3544 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13174 : 3544 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, M2Quads_OperandT (1), false);
13175 : : }
13176 : 28 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13177 : : {
13178 : : /* avoid dangling else. */
13179 : 28 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13180 : 28 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13181 : 28 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, SymbolTable_GetSType (M2Quads_OperandT (1)), false);
13182 : : }
13183 : : else
13184 : : {
13185 : : /* avoid dangling else. */
13186 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects a variable as its first parameter, seen {%1Ed}", 94, M2Quads_OperandT (1));
13187 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13188 : : }
13189 : : }
13190 : 0 : else if (NoOfParam == 0)
13191 : : {
13192 : : /* avoid dangling else. */
13193 : 0 : resulttok = functok;
13194 : 0 : M2MetaError_MetaErrorT0 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects either one or two parameters, seen none", 87);
13195 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13196 : : }
13197 : : else
13198 : : {
13199 : : /* avoid dangling else. */
13200 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13201 : 0 : paramtok = OperandTtok (1);
13202 : 0 : resulttok = OperandTtok (NoOfParam);
13203 : 0 : if (SymbolTable_IsRecord (Record))
13204 : : {
13205 : 0 : paramtok = OperandTtok (1);
13206 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13207 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13208 : 0 : SymbolTable_PutVar (ReturnVar, M2Base_Cardinal);
13209 : 0 : GenQuadO (resulttok, M2Quads_SizeOp, ReturnVar, SymbolTable_NulSym, Record, false);
13210 : : }
13211 : : else
13212 : : {
13213 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13214 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTSIZE} expects the first parameter to be a record type, seen {%1d}", 99, Record);
13215 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13216 : : }
13217 : : }
13218 : 3572 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13219 : 3572 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13220 : 3572 : }
13221 : :
13222 : :
13223 : : /*
13224 : : BuildTBitSizeFunction - builds the pseudo function TBITSIZE
13225 : : The Stack:
13226 : :
13227 : :
13228 : : Entry Exit
13229 : :
13230 : : Ptr ->
13231 : : +----------------+
13232 : : | NoOfParam |
13233 : : |----------------|
13234 : : | Param 1 |
13235 : : |----------------|
13236 : : | Param 2 |
13237 : : |----------------|
13238 : : . .
13239 : : . .
13240 : : . .
13241 : : |----------------|
13242 : : | Param # | <- Ptr
13243 : : |----------------| +------------+
13244 : : | ProcSym | Type | | ReturnVar |
13245 : : |----------------| |------------|
13246 : :
13247 : : */
13248 : :
13249 : 60 : static void BuildTBitSizeFunction (void)
13250 : : {
13251 : 60 : unsigned int resulttok;
13252 : 60 : unsigned int paramtok;
13253 : 60 : unsigned int functok;
13254 : 60 : unsigned int NoOfParam;
13255 : 60 : unsigned int ProcSym;
13256 : 60 : unsigned int Record;
13257 : 60 : unsigned int ReturnVar;
13258 : :
13259 : 60 : M2Quads_PopT (&NoOfParam);
13260 : 60 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
13261 : 60 : functok = OperandTtok (NoOfParam);
13262 : 60 : BuildSizeCheckEnd (ProcSym); /* quadruple generation now on */
13263 : 60 : if (NoOfParam == 1) /* quadruple generation now on */
13264 : : {
13265 : 60 : paramtok = OperandTtok (1);
13266 : 60 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13267 : 60 : if (SymbolTable_IsAModula2Type (M2Quads_OperandT (1)))
13268 : : {
13269 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13270 : 0 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13271 : : }
13272 : 60 : else if (SymbolTable_IsVar (M2Quads_OperandT (1)))
13273 : : {
13274 : : /* avoid dangling else. */
13275 : 60 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13276 : 60 : GenQuadO (resulttok, M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1), false);
13277 : : }
13278 : : else
13279 : : {
13280 : : /* avoid dangling else. */
13281 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects a variable as its first parameter, seen {%1d}", 96, M2Quads_OperandT (1));
13282 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13283 : : }
13284 : : }
13285 : 0 : else if (NoOfParam == 0)
13286 : : {
13287 : : /* avoid dangling else. */
13288 : 0 : resulttok = functok;
13289 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects either one or two parameters, seen none", 90);
13290 : 0 : ReturnVar = SymbolTable_MakeConstLit (functok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13291 : : }
13292 : : else
13293 : : {
13294 : : /* avoid dangling else. */
13295 : 0 : Record = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam));
13296 : 0 : paramtok = OperandTtok (1);
13297 : 0 : resulttok = OperandTtok (NoOfParam);
13298 : 0 : if (SymbolTable_IsRecord (Record))
13299 : : {
13300 : 0 : paramtok = OperandTtok (1);
13301 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13302 : 0 : ReturnVar = SymbolTable_MakeTemporary (resulttok, SymbolTable_ImmediateValue);
13303 : 0 : GenQuad (M2Quads_StandardFunctionOp, ReturnVar, ProcSym, M2Quads_OperandT (1));
13304 : : }
13305 : : else
13306 : : {
13307 : 0 : resulttok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
13308 : 0 : M2MetaError_MetaErrorT1 (resulttok, (const char *) "{%E}SYSTEM procedure function {%kTBITSIZE} expects the first parameter to be a record type, seen {%1d}", 102, Record);
13309 : 0 : ReturnVar = SymbolTable_MakeConstLit (resulttok, NameKey_MakeKey ((const char *) "0", 1), M2Base_Cardinal);
13310 : : }
13311 : : }
13312 : 60 : M2Quads_PopN (NoOfParam+1); /* destroy the arguments and function */
13313 : 60 : M2Quads_PushTFtok (ReturnVar, SymbolTable_GetSType (ProcSym), resulttok); /* destroy the arguments and function */
13314 : 60 : }
13315 : :
13316 : :
13317 : : /*
13318 : : ExpectingParameterType -
13319 : : */
13320 : :
13321 : 75527 : static void ExpectingParameterType (unsigned int BlockSym, unsigned int Type)
13322 : : {
13323 : 75527 : if (! (SymbolTable_IsAModula2Type (Type)))
13324 : : {
13325 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13326 : 6 : if (((Type == SymbolTable_NulSym) || (SymbolTable_IsPartialUnbounded (Type))) || (SymbolTable_IsUnknown (Type)))
13327 : : {
13328 : 0 : M2MetaError_MetaError1 ((const char *) "the type used in the formal parameter declaration in {%1Md} {%1a} is unknown", 76, BlockSym);
13329 : : }
13330 : : else
13331 : : {
13332 : 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);
13333 : : }
13334 : : }
13335 : 75527 : }
13336 : :
13337 : :
13338 : : /*
13339 : : ExpectingVariableType -
13340 : : */
13341 : :
13342 : 75336 : static void ExpectingVariableType (unsigned int BlockSym, unsigned int Type)
13343 : : {
13344 : 75336 : if (! (SymbolTable_IsAModula2Type (Type)))
13345 : : {
13346 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13347 : 0 : if (Type == SymbolTable_NulSym)
13348 : : {
13349 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1EMad} is unknown", 86, BlockSym);
13350 : 0 : M2MetaError_MetaError1 ((const char *) "the type used during the variable declaration section in procedure {%1Ead} is unknown", 85, BlockSym);
13351 : : }
13352 : 0 : else if ((SymbolTable_IsPartialUnbounded (Type)) || (SymbolTable_IsUnknown (Type)))
13353 : : {
13354 : : /* avoid dangling else. */
13355 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1EMad} used during variable declaration section in procedure {%2ad} is unknown", 89, Type, BlockSym);
13356 : 0 : M2MetaError_MetaError2 ((const char *) "the type {%1Ead} used during variable declaration section in procedure {%2Mad} is unknown", 89, Type, BlockSym);
13357 : : }
13358 : : else
13359 : : {
13360 : : /* avoid dangling else. */
13361 : 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);
13362 : : }
13363 : : }
13364 : 75336 : }
13365 : :
13366 : :
13367 : : /*
13368 : : CheckVariablesAndParameterTypesInBlock - checks to make sure that block, BlockSym, has
13369 : : parameters types and variable types which are legal.
13370 : : */
13371 : :
13372 : 152332 : static void CheckVariablesAndParameterTypesInBlock (unsigned int BlockSym)
13373 : : {
13374 : 152332 : unsigned int i;
13375 : 152332 : unsigned int n;
13376 : 152332 : unsigned int ParamNo;
13377 : :
13378 : 152332 : if (SymbolTable_IsProcedure (BlockSym))
13379 : : {
13380 : 71108 : ParamNo = SymbolTable_NoOfParamAny (BlockSym);
13381 : : }
13382 : : else
13383 : : {
13384 : : ParamNo = 0;
13385 : : }
13386 : 152332 : i = 1;
13387 : 1116938 : do {
13388 : 1116938 : n = SymbolTable_GetNth (BlockSym, i);
13389 : 1116938 : if (((n != SymbolTable_NulSym) && (! (SymbolTable_IsTemporary (n)))) && ((SymbolTable_IsProcedure (BlockSym)) || (((SymbolTable_IsDefImp (BlockSym)) && ((SymbolTable_GetMainModule ()) == BlockSym)) || (SymbolTable_IsModule (BlockSym)))))
13390 : : {
13391 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13392 : 150863 : if (i <= ParamNo)
13393 : : {
13394 : : /* n is a parameter */
13395 : 75527 : ExpectingParameterType (BlockSym, SymbolTable_GetSType (n));
13396 : : }
13397 : : else
13398 : : {
13399 : : /* n is a local variable */
13400 : 75336 : ExpectingVariableType (BlockSym, SymbolTable_GetSType (n));
13401 : : }
13402 : : }
13403 : 1116938 : i += 1;
13404 : 1116938 : } while (! (n == SymbolTable_NulSym));
13405 : 152332 : }
13406 : :
13407 : :
13408 : : /*
13409 : : IsNeverAltered - returns TRUE if variable, sym, is never altered
13410 : : between quadruples: Start..End
13411 : : */
13412 : :
13413 : 30 : static bool IsNeverAltered (unsigned int sym, unsigned int Start, unsigned int End)
13414 : : {
13415 : 30 : unsigned int WriteStart;
13416 : 30 : unsigned int WriteEnd;
13417 : :
13418 : 30 : SymbolTable_GetWriteLimitQuads (sym, SymbolTable_GetMode (sym), Start, End, &WriteStart, &WriteEnd);
13419 : 30 : return (WriteStart == 0) && (WriteEnd == 0);
13420 : : /* static analysis guarentees a RETURN statement will be used before here. */
13421 : : __builtin_unreachable ();
13422 : : }
13423 : :
13424 : :
13425 : : /*
13426 : : IsConditionVariable - returns TRUE if the condition at quadruple, q, is variable.
13427 : : */
13428 : :
13429 : 24 : static bool IsConditionVariable (unsigned int q, unsigned int Start, unsigned int End)
13430 : : {
13431 : 24 : M2Quads_QuadOperator op;
13432 : 24 : unsigned int op1;
13433 : 24 : unsigned int op2;
13434 : 24 : unsigned int op3;
13435 : 24 : bool LeftFixed;
13436 : 24 : bool RightFixed;
13437 : :
13438 : 24 : M2Quads_GetQuad (q, &op, &op1, &op2, &op3);
13439 : 24 : if (op == M2Quads_GotoOp)
13440 : : {
13441 : : return false;
13442 : : }
13443 : : else
13444 : : {
13445 : 24 : LeftFixed = SymbolTable_IsConst (op1);
13446 : 24 : RightFixed = SymbolTable_IsConst (op2);
13447 : 24 : if (! LeftFixed)
13448 : : {
13449 : 24 : LeftFixed = IsNeverAltered (op1, Start, End);
13450 : : }
13451 : 24 : if (! RightFixed)
13452 : : {
13453 : 6 : RightFixed = IsNeverAltered (op2, Start, End);
13454 : : }
13455 : 24 : return ! (LeftFixed && RightFixed);
13456 : : }
13457 : : /* static analysis guarentees a RETURN statement will be used before here. */
13458 : : __builtin_unreachable ();
13459 : : }
13460 : :
13461 : :
13462 : : /*
13463 : : IsInfiniteLoop - returns TRUE if an infinite loop is found.
13464 : : Given a backwards jump at, End, it returns a BOOLEAN which depends on
13465 : : whether a jump is found to jump beyond, End. If a conditonal jump is found
13466 : : to pass over, End, the condition is tested for global variables, procedure variables and
13467 : : constants.
13468 : :
13469 : : constant - ignored
13470 : : variables - tested to see whether they are altered inside the loop
13471 : : global variable - the procedure tests to see whether it is altered as above
13472 : : but will also test to see whether this loop calls a procedure
13473 : : in which case it believes the loop NOT to be infinite
13474 : : (as this procedure call might alter the global variable)
13475 : :
13476 : : Note that this procedure can easily be fooled by the user altering variables
13477 : : with pointers.
13478 : : */
13479 : :
13480 : 24 : static bool IsInfiniteLoop (unsigned int End)
13481 : : {
13482 : 24 : bool SeenCall;
13483 : 24 : bool IsGlobal;
13484 : 24 : unsigned int Current;
13485 : 24 : unsigned int Start;
13486 : 24 : M2Quads_QuadOperator op;
13487 : 24 : unsigned int op1;
13488 : 24 : unsigned int op2;
13489 : 24 : unsigned int op3;
13490 : :
13491 : 24 : SeenCall = false;
13492 : 24 : IsGlobal = false;
13493 : 24 : M2Quads_GetQuad (End, &op, &op1, &op2, &Start);
13494 : 24 : Current = Start;
13495 : 216 : while (Current != End)
13496 : : {
13497 : 216 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
13498 : : /* remember that this function is only called once we have optimized the redundant gotos and conditionals */
13499 : 216 : if ((M2Quads_IsConditional (Current)) && ! IsGlobal)
13500 : : {
13501 : 24 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13502 : : }
13503 : 216 : if (op == M2Quads_CallOp)
13504 : : {
13505 : 12 : SeenCall = true;
13506 : : }
13507 : 216 : if ((op == M2Quads_GotoOp) || ((M2Quads_IsConditional (Current)) && (IsConditionVariable (Current, Start, End))))
13508 : : {
13509 : 24 : if ((op3 > End) || (op3 < Start))
13510 : : {
13511 : : return false; /* may jump out of this loop, good */
13512 : : }
13513 : : }
13514 : 192 : Current = M2Quads_GetNextQuad (Current);
13515 : : }
13516 : 0 : M2Quads_GetQuad (End, &op, &op1, &op2, &op3);
13517 : 0 : if (M2Quads_IsConditional (End))
13518 : : {
13519 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
13520 : 0 : if (IsConditionVariable (End, Start, End))
13521 : : {
13522 : : return false;
13523 : : }
13524 : : else
13525 : : {
13526 : 0 : if (! IsGlobal)
13527 : : {
13528 : 0 : IsGlobal = ((SymbolTable_IsVar (op1)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op1))))) || ((SymbolTable_IsVar (op2)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (op2)))));
13529 : : }
13530 : : }
13531 : : }
13532 : : /* we have found a likely infinite loop if no conditional uses a global and no procedure call was seen */
13533 : 0 : return ! (IsGlobal && SeenCall);
13534 : : /* static analysis guarentees a RETURN statement will be used before here. */
13535 : : __builtin_unreachable ();
13536 : : }
13537 : :
13538 : :
13539 : : /*
13540 : : CheckVariablesInBlock - given a block, BlockSym, check whether all variables are used.
13541 : : */
13542 : :
13543 : 152332 : static void CheckVariablesInBlock (unsigned int BlockSym)
13544 : : {
13545 : 0 : CheckVariablesAndParameterTypesInBlock (BlockSym);
13546 : 0 : }
13547 : :
13548 : :
13549 : : /*
13550 : : CheckFunctionReturn - checks to see that a RETURN statement was present in a function.
13551 : : */
13552 : :
13553 : 71108 : static void CheckFunctionReturn (unsigned int ProcSym)
13554 : : {
13555 : 71108 : M2Quads_QuadOperator Op;
13556 : 71108 : unsigned int Op1;
13557 : 71108 : unsigned int Op2;
13558 : 71108 : unsigned int Op3;
13559 : 71108 : unsigned int Scope;
13560 : 71108 : unsigned int Start;
13561 : 71108 : unsigned int End;
13562 : :
13563 : 71108 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
13564 : : {
13565 : : /* yes it is a function */
13566 : 12239 : SymbolTable_GetProcedureQuads (ProcSym, &Scope, &Start, &End);
13567 : 12239 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13568 : 12239 : if (Start == 0)
13569 : : {
13570 : 0 : M2Error_InternalError ((const char *) "incorrect start quad", 20);
13571 : : }
13572 : 478513 : while (((Start != End) && (Op != M2Quads_ReturnValueOp)) && (Op != M2Quads_InlineOp))
13573 : : {
13574 : 466274 : Start = M2Quads_GetNextQuad (Start);
13575 : 466274 : M2Quads_GetQuad (Start, &Op, &Op1, &Op2, &Op3);
13576 : : }
13577 : 12239 : if ((Op != M2Quads_ReturnValueOp) && (Op != M2Quads_InlineOp))
13578 : : {
13579 : : /* an InlineOp can always be used to emulate a RETURN */
13580 : 6 : M2MetaError_MetaError1 ((const char *) "procedure function {%1Ea} does not RETURN a value", 49, ProcSym);
13581 : : }
13582 : : }
13583 : 71108 : }
13584 : :
13585 : :
13586 : : /*
13587 : : CheckReturnType - checks to see that the return type from currentProc is
13588 : : assignment compatible with actualType.
13589 : : */
13590 : :
13591 : 19005 : static void CheckReturnType (unsigned int tokno, unsigned int currentProc, unsigned int actualVal, unsigned int actualType)
13592 : : {
13593 : 19005 : unsigned int procType;
13594 : 19005 : DynamicStrings_String s1;
13595 : 19005 : DynamicStrings_String s2;
13596 : 19005 : NameKey_Name n1;
13597 : 19005 : NameKey_Name n2;
13598 : :
13599 : 19005 : procType = SymbolTable_GetSType (currentProc);
13600 : 19005 : if (procType == SymbolTable_NulSym)
13601 : : {
13602 : 0 : M2MetaError_MetaError1 ((const char *) "attempting to RETURN a value from procedure {%1Ea} which was not a declared as a procedure function", 99, currentProc);
13603 : : }
13604 : 19005 : else if (M2Base_AssignmentRequiresWarning (actualType, SymbolTable_GetSType (currentProc)))
13605 : : {
13606 : : /* avoid dangling else. */
13607 : 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);
13608 : : }
13609 : 19005 : else if (! (M2Base_IsAssignmentCompatible (actualType, procType)))
13610 : : {
13611 : : /* avoid dangling else. */
13612 : 0 : n1 = SymbolTable_GetSymName (actualType);
13613 : 0 : n2 = SymbolTable_GetSymName (procType);
13614 : 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));
13615 : : }
13616 : 19005 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, procType))))
13617 : : {
13618 : : /* avoid dangling else. */
13619 : : /*
13620 : : MetaWarnings2('attempting to RETURN a value with an incompatible type {%1ad} from function {%2a} which returns {%2ta}',
13621 : : actualVal, currentProc)
13622 : :
13623 : : --fixme-- introduce MetaWarning, MetaWarning2, MetaWarning3 into M2MetaError
13624 : : */
13625 : 0 : s1 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (actualVal)));
13626 : 0 : s2 = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (procType)));
13627 : 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)));
13628 : : }
13629 : 19005 : else if ((SymbolTable_IsProcedure (actualVal)) && (! (M2Base_IsAssignmentCompatible (actualVal, SymbolTable_GetSType (CurrentProc)))))
13630 : : {
13631 : : /* avoid dangling else. */
13632 : 0 : n1 = SymbolTable_GetSymName (actualVal);
13633 : 0 : n2 = SymbolTable_GetSymName (SymbolTable_GetSType (currentProc));
13634 : 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));
13635 : : }
13636 : : else
13637 : : {
13638 : : /* avoid dangling else. */
13639 : : /* this checks the types are compatible, not the data contents. */
13640 : 19005 : BuildRange (M2Range_InitTypesReturnTypeCheck (tokno, currentProc, actualVal));
13641 : : }
13642 : 19005 : }
13643 : :
13644 : :
13645 : : /*
13646 : : BuildReturnLower - check the return type and value to ensure type
13647 : : compatibility and no range overflow will occur.
13648 : : */
13649 : :
13650 : 19005 : static void BuildReturnLower (unsigned int tokcombined, unsigned int tokexpr, unsigned int e1, unsigned int t1)
13651 : : {
13652 : 19005 : unsigned int e2;
13653 : 19005 : unsigned int t2;
13654 : :
13655 : : /* This will check that the type returned is compatible with
13656 : : the formal return type of the procedure. */
13657 : 19005 : CheckReturnType (tokcombined, CurrentProc, e1, t1);
13658 : : /* Dereference LeftValue if necessary. */
13659 : 19005 : if ((SymbolTable_GetMode (e1)) == SymbolTable_LeftValue)
13660 : : {
13661 : 120 : t2 = SymbolTable_GetSType (CurrentProc);
13662 : 120 : e2 = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
13663 : 120 : SymbolTable_PutVar (e2, t2);
13664 : 120 : CheckPointerThroughNil (tokexpr, e1);
13665 : 120 : doIndrX (tokexpr, e2, e1);
13666 : 120 : e1 = e2;
13667 : : }
13668 : : /* Here we check the data contents to ensure no overflow. */
13669 : 19005 : BuildRange (M2Range_InitReturnRangeCheck (tokcombined, CurrentProc, e1));
13670 : 19005 : GenQuadOtok (tokcombined, M2Quads_ReturnValueOp, e1, SymbolTable_NulSym, CurrentProc, false, tokcombined, M2LexBuf_UnknownTokenNo, SymbolTable_GetDeclaredMod (CurrentProc));
13671 : 19005 : }
13672 : :
13673 : :
13674 : : /*
13675 : : IsReadOnly - a helper procedure function to detect constants.
13676 : : */
13677 : :
13678 : 233151 : static bool IsReadOnly (unsigned int sym)
13679 : : {
13680 : 233151 : return (SymbolTable_IsConst (sym)) || ((SymbolTable_IsVar (sym)) && (SymbolTable_IsVarConst (sym)));
13681 : : /* static analysis guarentees a RETURN statement will be used before here. */
13682 : : __builtin_unreachable ();
13683 : : }
13684 : :
13685 : :
13686 : : /*
13687 : : BuildDesignatorError - removes the designator from the stack and replaces
13688 : : it with an error symbol.
13689 : : */
13690 : :
13691 : 54 : static void BuildDesignatorError (const char *message_, unsigned int _message_high)
13692 : : {
13693 : 54 : unsigned int combinedTok;
13694 : 54 : unsigned int arrayTok;
13695 : 54 : unsigned int exprTok;
13696 : 54 : unsigned int e;
13697 : 54 : unsigned int d;
13698 : 54 : unsigned int error;
13699 : 54 : unsigned int Sym;
13700 : 54 : unsigned int Type;
13701 : 54 : char message[_message_high+1];
13702 : :
13703 : : /* make a local copy of each unbounded array. */
13704 : 54 : memcpy (message, message_, _message_high+1);
13705 : :
13706 : 54 : M2Quads_PopTtok (&e, &exprTok);
13707 : 54 : PopTFDtok (&Sym, &Type, &d, &arrayTok);
13708 : 54 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
13709 : 54 : error = SymbolTable_MakeError (combinedTok, NameKey_MakeKey ((const char *) message, _message_high));
13710 : 54 : PushTFDtok (error, Type, d, arrayTok);
13711 : 54 : }
13712 : :
13713 : :
13714 : : /*
13715 : : BuildDesignatorPointerError - removes the designator from the stack and replaces
13716 : : it with an error symbol.
13717 : : */
13718 : :
13719 : 2 : static void BuildDesignatorPointerError (unsigned int type, unsigned int rw, unsigned int tokpos, const char *message_, unsigned int _message_high)
13720 : : {
13721 : 2 : unsigned int error;
13722 : 2 : char message[_message_high+1];
13723 : :
13724 : : /* make a local copy of each unbounded array. */
13725 : 2 : memcpy (message, message_, _message_high+1);
13726 : :
13727 : 2 : error = SymbolTable_MakeError (tokpos, NameKey_MakeKey ((const char *) message, _message_high));
13728 : 2 : if ((SymbolTable_GetSType (type)) != SymbolTable_NulSym)
13729 : : {
13730 : 2 : type = SymbolTable_GetSType (type);
13731 : : }
13732 : 2 : PushTFrwtok (error, type, rw, tokpos);
13733 : 2 : }
13734 : :
13735 : :
13736 : : /*
13737 : : BuildDesignatorArrayStaticDynamic - Builds the array referencing.
13738 : : The purpose of this procedure is to work out
13739 : : whether the DesignatorArray is a static or
13740 : : dynamic array and to call the appropriate
13741 : : BuildRoutine.
13742 : :
13743 : : The Stack is expected to contain:
13744 : :
13745 : :
13746 : : Entry Exit
13747 : : ===== ====
13748 : :
13749 : : Ptr ->
13750 : : +--------------+
13751 : : | e | <- Ptr
13752 : : |--------------| +------------+
13753 : : | Sym | Type | | S | T |
13754 : : |--------------| |------------|
13755 : : */
13756 : :
13757 : 48660 : static void BuildDesignatorArrayStaticDynamic (void)
13758 : : {
13759 : 48660 : unsigned int combinedTok;
13760 : 48660 : unsigned int arrayTok;
13761 : 48660 : unsigned int exprTok;
13762 : 48660 : unsigned int e;
13763 : 48660 : unsigned int type;
13764 : 48660 : unsigned int dim;
13765 : 48660 : unsigned int result;
13766 : 48660 : unsigned int Sym;
13767 : 48660 : unsigned int Type;
13768 : :
13769 : 48660 : if (SymbolTable_IsConst (M2Quads_OperandT (2)))
13770 : : {
13771 : 204 : type = SymbolTable_GetDType (M2Quads_OperandT (2));
13772 : 204 : if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
13773 : : {
13774 : 204 : M2Quads_PopTtok (&e, &exprTok);
13775 : 204 : PopTFDtok (&Sym, &Type, &dim, &arrayTok);
13776 : 204 : result = SymbolTable_MakeTemporary (exprTok, SymbolTable_RightValue);
13777 : 204 : SymbolTable_PutVar (result, Type);
13778 : 204 : M2Quads_PushTFtok (result, SymbolTable_GetSType (result), exprTok);
13779 : 204 : M2Quads_PushTtok (Sym, arrayTok);
13780 : 204 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, exprTok);
13781 : 204 : SymbolTable_PutVarConst (result, true);
13782 : 204 : M2Quads_BuildAssignConstant (combinedTok);
13783 : 204 : PushTFDtok (result, SymbolTable_GetDType (result), dim, arrayTok);
13784 : 204 : M2Quads_PushTtok (e, exprTok);
13785 : : }
13786 : : }
13787 : 48660 : if ((! (SymbolTable_IsVar (M2Quads_OperandT (2)))) && (! (SymbolTable_IsTemporary (M2Quads_OperandT (2)))))
13788 : : {
13789 : 18 : M2MetaError_MetaErrorT1 (OperandTtok (2), (const char *) "can only access arrays using constants, variables or formal parameters not {%1Ead}", 82, M2Quads_OperandT (2));
13790 : 18 : BuildDesignatorError ((const char *) "bad array access", 16);
13791 : : }
13792 : 48660 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
13793 : 48660 : Type = SymbolTable_GetDType (Sym);
13794 : 48660 : arrayTok = OperandTtok (2);
13795 : 48660 : if (Type == SymbolTable_NulSym)
13796 : : {
13797 : 6 : if ((arrayTok == M2LexBuf_UnknownTokenNo) || (arrayTok == M2LexBuf_BuiltinTokenNo))
13798 : : {
13799 : 6 : arrayTok = M2LexBuf_GetTokenNo ();
13800 : : }
13801 : 6 : M2MetaError_MetaErrorT0 (arrayTok, (const char *) "type of array is undefined", 26);
13802 : 6 : BuildDesignatorError ((const char *) "bad array access", 16);
13803 : : }
13804 : 48654 : else if (SymbolTable_IsUnbounded (Type))
13805 : : {
13806 : : /* avoid dangling else. */
13807 : 7638 : BuildDynamicArray ();
13808 : : }
13809 : 41016 : else if (SymbolTable_IsArray (Type))
13810 : : {
13811 : : /* avoid dangling else. */
13812 : 40992 : BuildStaticArray ();
13813 : : }
13814 : : else
13815 : : {
13816 : : /* avoid dangling else. */
13817 : 24 : M2MetaError_MetaErrorT1 (arrayTok, (const char *) "can only index static or dynamic arrays, {%1Ead} is not an array but a {%tad}", 77, Sym);
13818 : 24 : BuildDesignatorError ((const char *) "bad array access", 16);
13819 : : }
13820 : 48654 : }
13821 : :
13822 : :
13823 : : /*
13824 : : BuildStaticArray - Builds the array referencing for static arrays.
13825 : : The Stack is expected to contain:
13826 : :
13827 : :
13828 : : Entry Exit
13829 : : ===== ====
13830 : :
13831 : : Ptr ->
13832 : : +--------------+
13833 : : | e | <- Ptr
13834 : : |--------------| +------------+
13835 : : | Sym | Type | | S | T |
13836 : : |--------------| |------------|
13837 : : */
13838 : :
13839 : 40992 : static void BuildStaticArray (void)
13840 : : {
13841 : 40992 : unsigned int combinedTok;
13842 : 40992 : unsigned int indexTok;
13843 : 40992 : unsigned int arrayTok;
13844 : 40992 : unsigned int rw;
13845 : 40992 : unsigned int Dim;
13846 : 40992 : unsigned int Array;
13847 : 40992 : unsigned int Index;
13848 : 40992 : unsigned int BackEndType;
13849 : 40992 : unsigned int Type;
13850 : 40992 : unsigned int Adr;
13851 : :
13852 : 40992 : Index = static_cast<unsigned int> (M2Quads_OperandT (1));
13853 : 40992 : indexTok = OperandTtok (1);
13854 : 40992 : Array = static_cast<unsigned int> (M2Quads_OperandT (2));
13855 : 40992 : arrayTok = OperandTtok (2);
13856 : 40992 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
13857 : 40992 : rw = static_cast<unsigned int> (OperandMergeRW (2));
13858 : 40992 : M2Debug_Assert (SymbolTable_IsLegal (rw));
13859 : 40992 : Dim = static_cast<unsigned int> (OperandD (2));
13860 : 40992 : Dim += 1;
13861 : 40992 : if ((SymbolTable_GetMode (Index)) == SymbolTable_LeftValue)
13862 : : {
13863 : 176 : Index = MakeRightValue (indexTok, Index, SymbolTable_GetSType (Index));
13864 : : }
13865 : 40986 : BuildRange (M2Range_InitStaticArraySubscriptRangeCheck (SymbolTable_GetArraySubscript (Type), Index, Dim));
13866 : : /* now make Adr point to the address of the indexed element */
13867 : 40986 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
13868 : 40986 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
13869 : 40986 : if (SymbolTable_IsVar (Array))
13870 : : {
13871 : : /* BuildDesignatorArray may have detected des is a constant. */
13872 : 40986 : SymbolTable_PutVarConst (Adr, SymbolTable_IsVarConst (Array));
13873 : : }
13874 : 40986 : SymbolTable_PutVarArrayRef (Adr, true);
13875 : : /*
13876 : : From now on it must reference the array element by its lvalue
13877 : : - so we create the type of the referenced entity
13878 : : */
13879 : 40986 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
13880 : 40986 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetDType (Type));
13881 : : /* PutVar(Adr, BackEndType) ; */
13882 : 40986 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetDType (Type), BackEndType);
13883 : 81972 : GenQuadO (combinedTok, M2Quads_ArrayOp, Adr, Index, Array, true);
13884 : 40986 : M2Quads_PopN (2); /* remove all parameters to this procedure */
13885 : 40986 : PushTFDrwtok (Adr, SymbolTable_GetSType (Adr), Dim, rw, combinedTok); /* remove all parameters to this procedure */
13886 : 40986 : }
13887 : :
13888 : :
13889 : : /*
13890 : : calculateMultipicand - generates quadruples which calculate the
13891 : : multiplicand for the array at dimension, dim.
13892 : : */
13893 : :
13894 : 9072 : static unsigned int calculateMultipicand (unsigned int tok, unsigned int arraySym, unsigned int arrayType, unsigned int dim)
13895 : : {
13896 : 9072 : unsigned int ti;
13897 : 9072 : unsigned int tj;
13898 : 9072 : unsigned int tk;
13899 : 9072 : unsigned int tl;
13900 : :
13901 : 9072 : if (dim == (SymbolTable_GetDimension (arrayType)))
13902 : : {
13903 : : /* ti has no type since constant */
13904 : 8100 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
13905 : 8100 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13906 : 8100 : GenQuadO (tok, M2Quads_ElementSizeOp, ti, arrayType, 1, true);
13907 : : }
13908 : : else
13909 : : {
13910 : 972 : dim += 1;
13911 : 972 : tk = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13912 : 972 : SymbolTable_PutVar (tk, M2Base_Cardinal);
13913 : 972 : GenHigh (tok, tk, dim, arraySym);
13914 : 972 : tl = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13915 : 972 : SymbolTable_PutVar (tl, M2Base_Cardinal);
13916 : 972 : GenQuadOtok (tok, M2Quads_AddOp, tl, tk, SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_Cardinal), true, tok, tok, tok);
13917 : 972 : tj = calculateMultipicand (tok, arraySym, arrayType, dim);
13918 : 972 : ti = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
13919 : 972 : SymbolTable_PutVar (ti, M2Base_Cardinal);
13920 : 972 : GenQuadO (tok, M2Quads_MultOp, ti, tj, tl, true);
13921 : : }
13922 : 9072 : return ti;
13923 : : /* static analysis guarentees a RETURN statement will be used before here. */
13924 : : __builtin_unreachable ();
13925 : : }
13926 : :
13927 : :
13928 : : /*
13929 : : ConvertToAddress - convert sym to an address.
13930 : : */
13931 : :
13932 : 7722 : static unsigned int ConvertToAddress (unsigned int tokpos, unsigned int sym)
13933 : : {
13934 : 7722 : unsigned int adr;
13935 : :
13936 : 7722 : if ((SymbolTable_GetSType (sym)) == M2System_Address)
13937 : : {
13938 : : return sym;
13939 : : }
13940 : : else
13941 : : {
13942 : 7710 : M2Quads_PushTF (SymbolTable_RequestSym (tokpos, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
13943 : 7710 : M2Quads_PushT (M2System_Address);
13944 : 7710 : M2Quads_PushTtok (sym, tokpos);
13945 : 7710 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
13946 : 7710 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
13947 : 7710 : M2Quads_PopT (&adr);
13948 : 7710 : return adr;
13949 : : }
13950 : : /* static analysis guarentees a RETURN statement will be used before here. */
13951 : : __builtin_unreachable ();
13952 : : }
13953 : :
13954 : :
13955 : : /*
13956 : : BuildDynamicArray - Builds the array referencing for dynamic arrays.
13957 : : The Stack is expected to contain:
13958 : :
13959 : :
13960 : : Entry Exit
13961 : : ===== ====
13962 : :
13963 : : Ptr ->
13964 : : +-----------------------+
13965 : : | Index | <- Ptr
13966 : : |-----------------------| +---------------------------+
13967 : : | ArraySym | Type | Dim | | S | T | ArraySym | Dim+1 |
13968 : : |-----------------------| |---------------------------|
13969 : :
13970 : :
13971 : : if Dim=1
13972 : : then
13973 : : S := base of ArraySym + TSIZE(Type)*Index
13974 : : else
13975 : : S := S + TSIZE(Type)*Index
13976 : : fi
13977 : : */
13978 : :
13979 : 7638 : static void BuildDynamicArray (void)
13980 : : {
13981 : 7638 : unsigned int combinedTok;
13982 : 7638 : unsigned int arrayTok;
13983 : 7638 : unsigned int indexTok;
13984 : 7638 : unsigned int Sym;
13985 : 7638 : unsigned int idx;
13986 : 7638 : unsigned int Type;
13987 : 7638 : unsigned int Adr;
13988 : 7638 : unsigned int ArraySym;
13989 : 7638 : unsigned int BackEndType;
13990 : 7638 : unsigned int UnboundedType;
13991 : 7638 : unsigned int PtrToBase;
13992 : 7638 : unsigned int Base;
13993 : 7638 : unsigned int Dim;
13994 : 7638 : unsigned int rw;
13995 : 7638 : unsigned int ti;
13996 : 7638 : unsigned int tj;
13997 : 7638 : unsigned int tk;
13998 : 7638 : unsigned int tka;
13999 : :
14000 : 7638 : M2Quads_DisplayStack ();
14001 : 7638 : Sym = static_cast<unsigned int> (M2Quads_OperandT (2));
14002 : 7638 : Type = SymbolTable_SkipType (M2Quads_OperandF (2));
14003 : 7638 : arrayTok = static_cast<unsigned int> (M2Quads_OperandTok (2));
14004 : 7638 : indexTok = static_cast<unsigned int> (M2Quads_OperandTok (1));
14005 : 7638 : combinedTok = M2LexBuf_MakeVirtualTok (arrayTok, arrayTok, indexTok);
14006 : 7638 : Dim = static_cast<unsigned int> (OperandD (2));
14007 : 7638 : rw = static_cast<unsigned int> (OperandMergeRW (2));
14008 : 7638 : M2Debug_Assert (SymbolTable_IsLegal (rw));
14009 : 7638 : Dim += 1;
14010 : 7638 : if (Dim == 1)
14011 : : {
14012 : : /*
14013 : : Base has type address since
14014 : : BuildDesignatorRecord references by address.
14015 : :
14016 : : Build a record for retrieving the address of dynamic array.
14017 : : BuildDesignatorRecord will generate the required quadruples,
14018 : : therefore build sets up the stack for BuildDesignatorRecord
14019 : : which will generate the quads to access the record.
14020 : : */
14021 : 7500 : ArraySym = Sym;
14022 : 7500 : UnboundedType = SymbolTable_GetUnboundedRecordType (SymbolTable_GetSType (Sym));
14023 : 7500 : PushTFrwtok (Sym, UnboundedType, rw, arrayTok);
14024 : 7500 : M2Quads_PushTF (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym)), SymbolTable_GetSType (SymbolTable_GetUnboundedAddressOffset (SymbolTable_GetSType (Sym))));
14025 : 7500 : M2Quads_PushT (static_cast<unsigned int> (1)); /* One record field to dereference */
14026 : 7500 : M2Quads_BuildDesignatorRecord (combinedTok); /* One record field to dereference */
14027 : 7500 : M2Quads_PopT (&PtrToBase);
14028 : 7500 : M2Quads_DisplayStack ();
14029 : : /* Now actually copy Unbounded.ArrayAddress into base */
14030 : 7500 : if ((SymbolTable_GetMode (PtrToBase)) == SymbolTable_LeftValue)
14031 : : {
14032 : 0 : Base = SymbolTable_MakeTemporary (arrayTok, SymbolTable_RightValue);
14033 : 0 : SymbolTable_PutVar (Base, M2System_Address); /* has type ADDRESS */
14034 : 0 : CheckPointerThroughNil (arrayTok, PtrToBase); /* has type ADDRESS */
14035 : 0 : GenQuad (M2Quads_IndrXOp, Base, M2System_Address, PtrToBase); /* Base = *PtrToBase */
14036 : : }
14037 : : else
14038 : : {
14039 : 7500 : M2Debug_Assert ((SymbolTable_GetMode (PtrToBase)) != SymbolTable_ImmediateValue);
14040 : 7500 : Base = PtrToBase;
14041 : : }
14042 : : }
14043 : : else
14044 : : {
14045 : : /* Base already calculated previously and pushed to stack */
14046 : 138 : UnboundedType = SymbolTable_SkipType (M2Quads_OperandF (2));
14047 : 138 : Base = Sym;
14048 : 138 : ArraySym = static_cast<unsigned int> (M2Quads_OperandA (2));
14049 : : }
14050 : 7638 : M2Debug_Assert ((SymbolTable_GetSType (Sym)) == Type);
14051 : 7638 : ti = calculateMultipicand (indexTok, Sym, Type, Dim);
14052 : 7638 : idx = static_cast<unsigned int> (M2Quads_OperandT (1));
14053 : 7638 : if ((SymbolTable_IsConst (idx)) && (SymbolTable_IsConst (ti)))
14054 : : {
14055 : : /* tj has no type since constant */
14056 : 376 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
14057 : 376 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_ImmediateValue);
14058 : 376 : SymbolTable_PutVar (tj, M2Base_Cardinal);
14059 : 376 : SymbolTable_PutVar (tk, M2Base_Cardinal);
14060 : : }
14061 : : else
14062 : : {
14063 : : /* tj has Cardinal type since we have multiplied array indices */
14064 : 7262 : tj = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
14065 : 7262 : if ((SymbolTable_GetSType (idx)) != M2Base_Cardinal)
14066 : : {
14067 : 756 : M2Quads_PushTF (SymbolTable_RequestSym (indexTok, NameKey_MakeKey ((const char *) "CONVERT", 7)), static_cast<unsigned int> (SymbolTable_NulSym));
14068 : 756 : M2Quads_PushT (M2Base_Cardinal);
14069 : 756 : M2Quads_PushTtok (idx, indexTok);
14070 : 756 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14071 : 756 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14072 : 756 : M2Quads_PopT (&idx);
14073 : : }
14074 : 7262 : SymbolTable_PutVar (tj, M2Base_Cardinal);
14075 : 7262 : tk = SymbolTable_MakeTemporary (indexTok, SymbolTable_RightValue);
14076 : 7262 : SymbolTable_PutVar (tk, M2Base_Cardinal);
14077 : : }
14078 : 7638 : BuildRange (M2Range_InitDynamicArraySubscriptRangeCheck (ArraySym, idx, Dim));
14079 : 7638 : M2Quads_PushTtok (tj, indexTok);
14080 : 7638 : M2Quads_PushTtok (idx, indexTok);
14081 : 7638 : BuildAssignmentWithoutBounds (indexTok, false, true);
14082 : 15276 : GenQuad (M2Quads_MultOp, tk, ti, tj);
14083 : 15276 : Adr = SymbolTable_MakeTemporary (combinedTok, SymbolTable_LeftValue);
14084 : 7638 : SymbolTable_PutVarArrayRef (Adr, true);
14085 : : /*
14086 : : Ok must reference by address
14087 : : - but we contain the type of the referenced entity
14088 : : */
14089 : 7638 : BackEndType = SymbolTable_MakePointer (combinedTok, NameKey_NulName);
14090 : 7638 : SymbolTable_PutPointer (BackEndType, SymbolTable_GetSType (Type));
14091 : : /* Create a temporary pointer for addition. */
14092 : 7638 : tka = ConvertToAddress (combinedTok, tk);
14093 : 7638 : if (Dim == (SymbolTable_GetDimension (Type)))
14094 : : {
14095 : 7320 : SymbolTable_PutLeftValueFrontBackType (Adr, SymbolTable_GetSType (Type), BackEndType);
14096 : 14640 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
14097 : 7320 : M2Quads_PopN (2);
14098 : 7320 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
14099 : : }
14100 : : else
14101 : : {
14102 : : /* more to index */
14103 : 318 : SymbolTable_PutLeftValueFrontBackType (Adr, Type, BackEndType);
14104 : 636 : GenQuadOtok (combinedTok, M2Quads_AddOp, Adr, Base, tka, false, combinedTok, combinedTok, combinedTok);
14105 : 318 : M2Quads_PopN (2);
14106 : 318 : PushTFADrwtok (Adr, SymbolTable_GetSType (Adr), ArraySym, Dim, rw, combinedTok);
14107 : : }
14108 : 7638 : }
14109 : :
14110 : :
14111 : : /*
14112 : : DebugLocation -
14113 : : */
14114 : :
14115 : 44798 : static void DebugLocation (unsigned int tok, const char *message_, unsigned int _message_high)
14116 : : {
14117 : 44798 : char message[_message_high+1];
14118 : :
14119 : : /* make a local copy of each unbounded array. */
14120 : 44798 : memcpy (message, message_, _message_high+1);
14121 : :
14122 : 44798 : if (DebugTokPos)
14123 : : {
14124 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) message, _message_high), tok);
14125 : : }
14126 : 44798 : }
14127 : :
14128 : :
14129 : : /*
14130 : : PushWith - pushes sym and type onto the with stack. It checks for
14131 : : previous declaration of this record type.
14132 : : */
14133 : :
14134 : 5592 : static void PushWith (unsigned int Sym, unsigned int Type, unsigned int Ref, unsigned int Tok)
14135 : : {
14136 : 5592 : unsigned int i;
14137 : 5592 : unsigned int n;
14138 : 5592 : M2Quads_WithFrame f;
14139 : :
14140 : 5592 : if (M2Options_Pedantic)
14141 : : {
14142 : 0 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
14143 : 0 : i = 1; /* Top of the stack. */
14144 : : /* Search for other declarations of the with using Type. */
14145 : 0 : while (i <= n)
14146 : : {
14147 : 0 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
14148 : 0 : if (f->RecordSym == Type)
14149 : : {
14150 : 0 : M2MetaError_MetaErrorT1 (Tok, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, Sym);
14151 : 0 : M2MetaError_MetaErrorT1 (f->RecordTokPos, (const char *) "cannot have nested {%kWITH} statements referencing the same {%kRECORD} {%1Ead}", 78, f->RecordSym);
14152 : : }
14153 : 0 : i += 1;
14154 : : }
14155 : : }
14156 : 5592 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T4));
14157 : 5592 : f->RecordSym = Sym;
14158 : 5592 : f->RecordType = Type;
14159 : 5592 : f->RecordRef = Ref;
14160 : 5592 : f->rw = Sym;
14161 : 5592 : f->RecordTokPos = Tok;
14162 : 5592 : M2StackAddress_PushAddress (WithStack, reinterpret_cast <void *> (f));
14163 : 5592 : }
14164 : :
14165 : 5592 : static void PopWith (void)
14166 : : {
14167 : 5592 : M2Quads_WithFrame f;
14168 : :
14169 : 5592 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PopAddress (WithStack));
14170 : 5592 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T4));
14171 : 5592 : }
14172 : :
14173 : :
14174 : : /*
14175 : : BuildAccessWithField - similar to BuildDesignatorRecord except it
14176 : : does not perform the address operation.
14177 : : The address will have been computed at the
14178 : : beginning of the WITH statement.
14179 : : It also stops the GenQuad procedure from examining the
14180 : : with stack.
14181 : :
14182 : : The Stack
14183 : :
14184 : : Entry
14185 : :
14186 : : Ptr ->
14187 : : +--------------+
14188 : : | Field | Type1| <- Ptr
14189 : : |-------|------| +-------------+
14190 : : | Adr | Type2| | Sym | Type1|
14191 : : |--------------| |-------------|
14192 : : */
14193 : :
14194 : 28604 : static void BuildAccessWithField (void)
14195 : : {
14196 : 28604 : unsigned int rectok;
14197 : 28604 : unsigned int fieldtok;
14198 : 28604 : bool OldSuppressWith;
14199 : 28604 : unsigned int rw;
14200 : 28604 : unsigned int Field;
14201 : 28604 : unsigned int FieldType;
14202 : 28604 : unsigned int Record;
14203 : 28604 : unsigned int RecordType;
14204 : 28604 : unsigned int Ref;
14205 : :
14206 : 28604 : OldSuppressWith = SuppressWith;
14207 : 28604 : SuppressWith = true;
14208 : : /*
14209 : : now the WITH cannot look at the stack of outstanding WITH records.
14210 : : */
14211 : 28604 : M2Quads_PopTFtok (&Field, &FieldType, &fieldtok);
14212 : 28604 : PopTFrwtok (&Record, &RecordType, &rw, &rectok);
14213 : 28604 : Ref = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (fieldtok, SymbolTable_RightValue, Record), Field);
14214 : 28604 : SymbolTable_PutVarConst (Ref, IsReadOnly (Record));
14215 : 57208 : GenQuadO (fieldtok, M2Quads_RecordFieldOp, Ref, Record, Field, true);
14216 : 28604 : PushTFrwtok (Ref, FieldType, rw, fieldtok);
14217 : 28604 : SuppressWith = OldSuppressWith;
14218 : 28604 : }
14219 : :
14220 : :
14221 : : /*
14222 : : PushConstructor -
14223 : : */
14224 : :
14225 : 32520 : static void PushConstructor (unsigned int sym)
14226 : : {
14227 : 32520 : M2Quads_ConstructorFrame c;
14228 : :
14229 : 32520 : Storage_ALLOCATE ((void **) &c, sizeof (M2Quads__T1));
14230 : 32520 : c->type = SymbolTable_SkipType (sym);
14231 : 32520 : c->index = 1;
14232 : 32520 : M2StackAddress_PushAddress (ConstructorStack, reinterpret_cast <void *> (c));
14233 : 32520 : }
14234 : :
14235 : :
14236 : : /*
14237 : : AddFieldTo - adds field, e, to, value.
14238 : : */
14239 : :
14240 : 24536 : static unsigned int AddFieldTo (unsigned int value, unsigned int e)
14241 : : {
14242 : 24536 : if (SymbolTable_IsSet (SymbolTable_GetDType (value)))
14243 : : {
14244 : 10866 : SymbolTable_PutConstSet (value);
14245 : 10866 : M2Quads_PushT (value);
14246 : 10866 : M2Quads_PushT (e);
14247 : 10866 : M2Quads_BuildInclBit ();
14248 : 10866 : M2Quads_PopT (&value);
14249 : : }
14250 : : else
14251 : : {
14252 : 13670 : SymbolTable_PushValue (value);
14253 : 13670 : M2ALU_AddField (M2LexBuf_GetTokenNo (), e);
14254 : 13670 : SymbolTable_PopValue (value);
14255 : : }
14256 : 24536 : return value;
14257 : : /* static analysis guarentees a RETURN statement will be used before here. */
14258 : : __builtin_unreachable ();
14259 : : }
14260 : :
14261 : :
14262 : : /*
14263 : : CheckLogicalOperator - returns a logical operator if the operands imply
14264 : : a logical operation should be performed.
14265 : : */
14266 : :
14267 : 56030 : static NameKey_Name CheckLogicalOperator (NameKey_Name Tok, unsigned int left, unsigned int lefttype)
14268 : : {
14269 : 56030 : if ((((Tok == M2Reserved_PlusTok) || (Tok == M2Reserved_TimesTok)) || (Tok == M2Reserved_DivideTok)) || (Tok == M2Reserved_MinusTok))
14270 : : {
14271 : : /* --fixme-- when we add complex arithmetic, we must check constructor is not a complex constant. */
14272 : 47696 : if ((((lefttype != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (lefttype)))) || (SymbolTable_IsConstSet (left))) || (SymbolTable_IsConstructor (left)))
14273 : : {
14274 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
14275 : 1198 : if (Tok == M2Reserved_PlusTok)
14276 : : {
14277 : 1060 : return LogicalOrTok;
14278 : : }
14279 : 138 : else if (Tok == M2Reserved_DivideTok)
14280 : : {
14281 : : /* avoid dangling else. */
14282 : 12 : return LogicalXorTok;
14283 : : }
14284 : 126 : else if (Tok == M2Reserved_TimesTok)
14285 : : {
14286 : : /* avoid dangling else. */
14287 : 60 : return LogicalAndTok;
14288 : : }
14289 : 66 : else if (Tok == M2Reserved_MinusTok)
14290 : : {
14291 : : /* avoid dangling else. */
14292 : 66 : return LogicalDifferenceTok;
14293 : : }
14294 : : }
14295 : : }
14296 : : return Tok;
14297 : : /* static analysis guarentees a RETURN statement will be used before here. */
14298 : : __builtin_unreachable ();
14299 : : }
14300 : :
14301 : :
14302 : : /*
14303 : : CheckDivModRem - initiates calls to check the divisor for DIV, MOD, REM
14304 : : expressions.
14305 : : */
14306 : :
14307 : 55430 : static void CheckDivModRem (unsigned int TokPos, NameKey_Name tok, unsigned int d, unsigned int e)
14308 : : {
14309 : 55430 : if (tok == M2Reserved_DivTok)
14310 : : {
14311 : 6156 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
14312 : : }
14313 : 49274 : else if (tok == M2Reserved_ModTok)
14314 : : {
14315 : : /* avoid dangling else. */
14316 : 2082 : BuildRange (M2Range_InitWholeZeroDivisionCheck (TokPos, d, e));
14317 : : }
14318 : 47192 : else if (tok == M2Reserved_RemTok)
14319 : : {
14320 : : /* avoid dangling else. */
14321 : 96 : BuildRange (M2Range_InitWholeZeroRemainderCheck (TokPos, d, e));
14322 : : }
14323 : 55430 : }
14324 : :
14325 : :
14326 : : /*
14327 : : doConvert - convert, sym, to a new symbol with, type.
14328 : : Return the new symbol.
14329 : : */
14330 : :
14331 : 4220 : static unsigned int doConvert (unsigned int type, unsigned int sym)
14332 : : {
14333 : 4220 : if ((SymbolTable_GetSType (sym)) != type)
14334 : : {
14335 : 650 : M2Quads_PushTF (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym));
14336 : 650 : M2Quads_PushT (type);
14337 : 650 : M2Quads_PushT (sym);
14338 : 650 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters */
14339 : 650 : BuildConvertFunction (M2Base_Convert, false); /* Two parameters */
14340 : 644 : M2Quads_PopT (&sym);
14341 : : }
14342 : 4214 : return sym;
14343 : : /* static analysis guarentees a RETURN statement will be used before here. */
14344 : : __builtin_unreachable ();
14345 : : }
14346 : :
14347 : :
14348 : : /*
14349 : : doBuildBinaryOp - build the binary op, with or without type
14350 : : checking.
14351 : : */
14352 : :
14353 : 67096 : static void doBuildBinaryOp (bool checkTypes, bool checkOverflow)
14354 : : {
14355 : 67096 : DynamicStrings_String s;
14356 : 67096 : NameKey_Name NewOp;
14357 : 67096 : NameKey_Name Operator;
14358 : 67096 : unsigned int OperatorPos;
14359 : 67096 : unsigned int OldPos;
14360 : 67096 : unsigned int leftrw;
14361 : 67096 : unsigned int rightrw;
14362 : 67096 : unsigned int t1;
14363 : 67096 : unsigned int f1;
14364 : 67096 : unsigned int t2;
14365 : 67096 : unsigned int f2;
14366 : 67096 : unsigned int lefttype;
14367 : 67096 : unsigned int righttype;
14368 : 67096 : unsigned int left;
14369 : 67096 : unsigned int right;
14370 : 67096 : unsigned int leftpos;
14371 : 67096 : unsigned int rightpos;
14372 : 67096 : unsigned int value;
14373 : :
14374 : 67096 : Operator = static_cast<NameKey_Name> (M2Quads_OperandT (2));
14375 : 67096 : if (Operator == M2Reserved_OrTok)
14376 : : {
14377 : 3206 : CheckBooleanId ();
14378 : 3206 : PopBooltok (&t1, &f1, &rightpos);
14379 : 3206 : M2Quads_PopTtok (&Operator, &OperatorPos);
14380 : 3206 : PopBooltok (&t2, &f2, &leftpos);
14381 : 3206 : M2Debug_Assert (f2 == 0);
14382 : 3206 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14383 : 3206 : PushBooltok (Merge (t1, t2), f1, OperatorPos);
14384 : : }
14385 : 63890 : else if ((Operator == M2Reserved_AndTok) || (Operator == M2Reserved_AmbersandTok))
14386 : : {
14387 : : /* avoid dangling else. */
14388 : 7860 : CheckBooleanId ();
14389 : 7860 : PopBooltok (&t1, &f1, &rightpos);
14390 : 7860 : M2Quads_PopTtok (&Operator, &OperatorPos);
14391 : 7860 : PopBooltok (&t2, &f2, &leftpos);
14392 : 7860 : M2Debug_Assert (t2 == 0);
14393 : 7860 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14394 : 7860 : PushBooltok (t1, Merge (f1, f2), OperatorPos);
14395 : : }
14396 : : else
14397 : : {
14398 : : /* avoid dangling else. */
14399 : 56030 : PopTFrwtok (&right, &righttype, &rightrw, &rightpos);
14400 : 56030 : M2Quads_PopTtok (&Operator, &OperatorPos);
14401 : 56030 : PopTFrwtok (&left, &lefttype, &leftrw, &leftpos);
14402 : 56030 : MarkAsRead (rightrw);
14403 : 56030 : MarkAsRead (leftrw);
14404 : 56030 : NewOp = CheckLogicalOperator (Operator, left, lefttype); /* right, righttype, */
14405 : 56030 : if (NewOp == Operator)
14406 : : {
14407 : : /* avoid dangling else. */
14408 : : /*
14409 : : BinaryOps and UnaryOps only work with immediate and
14410 : : offset addressing. This is fine for calculating
14411 : : array and record offsets but we need to get the real
14412 : : values to perform normal arithmetic. Not address
14413 : : arithmetic.
14414 : :
14415 : : However the set operators will dereference LValues
14416 : : (to optimize large set arithemetic)
14417 : : */
14418 : 54832 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
14419 : : {
14420 : 298 : value = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
14421 : 298 : SymbolTable_PutVar (value, righttype);
14422 : 298 : CheckPointerThroughNil (rightpos, right);
14423 : 298 : doIndrX (rightpos, value, right);
14424 : 298 : right = value;
14425 : : }
14426 : 54832 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
14427 : : {
14428 : 636 : value = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
14429 : 636 : SymbolTable_PutVar (value, lefttype);
14430 : 636 : CheckPointerThroughNil (leftpos, left);
14431 : 636 : doIndrX (leftpos, value, left);
14432 : 636 : left = value;
14433 : : }
14434 : : }
14435 : : /* CheckForGenericNulSet(e1, e2, t1, t2) */
14436 : 56030 : OldPos = OperatorPos;
14437 : 56030 : OperatorPos = M2LexBuf_MakeVirtualTok (OperatorPos, leftpos, rightpos);
14438 : 56030 : if (((Operator == M2Reserved_PlusTok) && (SymbolTable_IsConstString (left))) && (SymbolTable_IsConstString (right)))
14439 : : {
14440 : 492 : value = SymbolTable_MakeConstString (OperatorPos, NameKey_NulName);
14441 : 492 : SymbolTable_PutConstStringKnown (OperatorPos, value, NameKey_NulName, false, false);
14442 : 492 : GenQuadOtok (OperatorPos, MakeOp (M2Reserved_PlusTok), value, left, right, false, OperatorPos, leftpos, rightpos);
14443 : : }
14444 : : else
14445 : : {
14446 : 55538 : if (checkTypes)
14447 : : {
14448 : 39424 : BuildRange (M2Range_InitTypesExpressionCheck (OperatorPos, left, right, false, false));
14449 : : }
14450 : 90490 : value = SymbolTable_MakeTemporaryFromExpressions (OperatorPos, right, left, AreConstant ((SymbolTable_IsConst (left)) && (SymbolTable_IsConst (right))));
14451 : 55430 : CheckDivModRem (OperatorPos, NewOp, value, right);
14452 : 55430 : if (DebugTokPos)
14453 : : {
14454 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Operator)));
14455 : : M2Error_WarnStringAt (s, OldPos);
14456 : : s = DynamicStrings_InitString ((const char *) "left", 4);
14457 : : M2Error_WarnStringAt (s, leftpos);
14458 : : s = DynamicStrings_InitString ((const char *) "right", 5);
14459 : : M2Error_WarnStringAt (s, rightpos);
14460 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
14461 : : M2Error_WarnStringAt (s, OldPos);
14462 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
14463 : : M2Error_WarnStringAt (s, OperatorPos);
14464 : : }
14465 : : /* MetaErrorT1 (GetDeclaredMod (t), 'in binary with a {%1a}', t) */
14466 : 55430 : GenQuadOtok (OperatorPos, MakeOp (NewOp), value, left, right, checkOverflow, OperatorPos, leftpos, rightpos);
14467 : : }
14468 : 55922 : M2Quads_PushTFtok (value, SymbolTable_GetSType (value), OperatorPos);
14469 : : }
14470 : 66988 : }
14471 : :
14472 : :
14473 : : /*
14474 : : AreConstant - returns immediate addressing mode if b is true else
14475 : : offset mode is returned. b determines whether the
14476 : : operands are all constant - in which case we can use
14477 : : a constant temporary variable.
14478 : : */
14479 : :
14480 : 122319 : static SymbolTable_ModeOfAddr AreConstant (bool b)
14481 : : {
14482 : 122319 : if (b)
14483 : : {
14484 : : return SymbolTable_ImmediateValue;
14485 : : }
14486 : : else
14487 : : {
14488 : 47804 : return SymbolTable_RightValue;
14489 : : }
14490 : : /* static analysis guarentees a RETURN statement will be used before here. */
14491 : : __builtin_unreachable ();
14492 : : }
14493 : :
14494 : :
14495 : : /*
14496 : : ConvertBooleanToVariable - converts a BoolStack(i) from a Boolean True|False
14497 : : exit pair into a variable containing the value TRUE or
14498 : : FALSE. The parameter i is relative to the top
14499 : : of the stack.
14500 : : */
14501 : :
14502 : 6754 : static void ConvertBooleanToVariable (unsigned int tok, unsigned int i)
14503 : : {
14504 : 6754 : unsigned int Des;
14505 : 6754 : M2Quads_BoolFrame f;
14506 : :
14507 : 6754 : M2Debug_Assert (IsBoolean (i));
14508 : : /* We need to convert the boolean top of stack into a variable or
14509 : : constant boolean. */
14510 : 13508 : Des = SymbolTable_MakeTemporary (tok, AreConstant (M2Quads_IsInConstExpression ()));
14511 : 6754 : SymbolTable_PutVar (Des, M2Base_Boolean);
14512 : 6754 : SymbolTable_PutVarConditional (Des, true);
14513 : 6754 : M2Quads_PushTtok (Des, tok); /* we have just increased the stack so we must use i+1 */
14514 : 6754 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i+1)); /* we have just increased the stack so we must use i+1 */
14515 : 13508 : PushBool (f->TrueExit, f->FalseExit);
14516 : 6754 : BuildAssignmentWithoutBounds (tok, false, true);
14517 : : /* Restored stack after the BuildAssign... above. */
14518 : 6754 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, i));
14519 : 6754 : f->TrueExit = Des; /* Alter Stack(i) to contain the variable. */
14520 : 6754 : f->FalseExit = M2Base_Boolean; /* Alter Stack(i) to contain the variable. */
14521 : 6754 : f->BooleanOp = false; /* No longer a Boolean True|False pair. */
14522 : 6754 : f->Unbounded = SymbolTable_NulSym; /* No longer a Boolean True|False pair. */
14523 : 6754 : f->Dimension = 0;
14524 : 6754 : f->ReadWrite = SymbolTable_NulSym;
14525 : 6754 : f->tokenno = tok;
14526 : 6754 : f->Annotation = DynamicStrings_KillString (f->Annotation);
14527 : 6754 : f->Annotation = DynamicStrings_InitString ((const char *) "%1s(%1d)|%2s(%2d)||boolean var|type", 35);
14528 : 6754 : f->RangeDep = 0;
14529 : 6754 : }
14530 : :
14531 : :
14532 : : /*
14533 : : DumpQuadSummary -
14534 : : */
14535 : :
14536 : 0 : static void DumpQuadSummary (unsigned int quad)
14537 : : {
14538 : 0 : M2Quads_QuadFrame f;
14539 : :
14540 : 0 : if (quad != 0)
14541 : : {
14542 : 0 : f = GetQF (quad);
14543 : 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));
14544 : : }
14545 : 0 : }
14546 : :
14547 : :
14548 : : /*
14549 : : BuildRelOpFromBoolean - builds a relational operator sequence of quadruples
14550 : : instead of using a temporary boolean variable.
14551 : : This function can only be used when we perform
14552 : : the following translation:
14553 : :
14554 : : (a=b) # (c=d) alternatively (a=b) = (c=d)
14555 : : ^ ^
14556 : :
14557 : : it only allows # = to be used as >= <= > < all
14558 : : assume a particular value for TRUE and FALSE.
14559 : : (In which case the user should specify ORD)
14560 : :
14561 : :
14562 : : before
14563 : :
14564 : : q if r1 op1 op2 t2
14565 : : q+1 Goto f2
14566 : : ...
14567 : : q+n if r2 op3 op4 t1
14568 : : q+n+1 Goto f1
14569 : :
14570 : : after (in case of =)
14571 : :
14572 : : q if r1 op1 op2 q+2
14573 : : q+1 Goto q+4
14574 : : q+2 if r2 op3 op4 t
14575 : : q+3 Goto f
14576 : : q+4 if r2 op3 op4 f
14577 : : q+5 Goto t
14578 : :
14579 : : after (in case of #)
14580 : :
14581 : : q if r1 op1 op2 q+2
14582 : : q+1 Goto q+n+2
14583 : : q+2 ...
14584 : : ... ...
14585 : : q+n if r2 op3 op4 f
14586 : : q+n+1 Goto t
14587 : : q+n+2 if r2 op3 op4 t
14588 : : q+n+3 Goto f
14589 : :
14590 : : The Stack is expected to contain:
14591 : :
14592 : :
14593 : : Entry Exit
14594 : : ===== ====
14595 : :
14596 : : Ptr ->
14597 : : +------------+
14598 : : | t1 | f1 |
14599 : : |------------|
14600 : : | Operator | <- Ptr
14601 : : |------------| +------------+
14602 : : | t2 | f2 | | t | f |
14603 : : |------------| |------------|
14604 : :
14605 : :
14606 : : */
14607 : :
14608 : 0 : static void BuildRelOpFromBoolean (unsigned int tokpos)
14609 : : {
14610 : 0 : unsigned int Tok;
14611 : 0 : unsigned int t1;
14612 : 0 : unsigned int f1;
14613 : 0 : unsigned int t2;
14614 : 0 : unsigned int f2;
14615 : 0 : M2Quads_QuadFrame f;
14616 : :
14617 : 0 : M2Debug_Assert ((IsBoolean (1)) && (IsBoolean (3)));
14618 : 0 : if ((M2Quads_OperandT (2)) == M2Reserved_EqualTok)
14619 : : {
14620 : : /* Are the two boolean expressions the same? */
14621 : 0 : PopBool (&t1, &f1);
14622 : 0 : M2Quads_PopT (&Tok);
14623 : 0 : PopBool (&t2, &f2);
14624 : : /* Give the false exit a second chance. */
14625 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14626 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14627 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14628 : 0 : f = GetQF (t1);
14629 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14630 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14631 : 0 : PushBooltok (Merge (NextQuad-1, t1), Merge (NextQuad-2, f1), tokpos);
14632 : : }
14633 : 0 : else if (((M2Quads_OperandT (2)) == M2Reserved_HashTok) || ((M2Quads_OperandT (2)) == M2Reserved_LessGreaterTok))
14634 : : {
14635 : : /* avoid dangling else. */
14636 : 0 : if (M2Options_CompilerDebugging)
14637 : : {
14638 : 0 : M2Printf_printf0 ((const char *) "BuildRelOpFromBoolean (NotEqualTok)\\n", 37);
14639 : 0 : M2Quads_DisplayStack ();
14640 : : }
14641 : : /* Are the two boolean expressions different? */
14642 : 0 : PopBool (&t1, &f1);
14643 : 0 : M2Quads_PopT (&Tok);
14644 : 0 : PopBool (&t2, &f2);
14645 : 0 : if (M2Options_CompilerDebugging)
14646 : : {
14647 : 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));
14648 : 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));
14649 : 0 : DumpQuadSummary (t1);
14650 : 0 : DumpQuadSummary (f1);
14651 : 0 : DumpQuadSummary (t2);
14652 : 0 : DumpQuadSummary (f2);
14653 : : }
14654 : : /* Give the false exit a second chance. */
14655 : 0 : BackPatch (t2, t1); /* q if _ _ q+2 */
14656 : 0 : BackPatch (f2, NextQuad); /* q+1 if _ _ q+4 */
14657 : 0 : M2Debug_Assert (NextQuad == (f1+1)); /* q+1 if _ _ q+4 */
14658 : 0 : f = GetQF (t1);
14659 : 0 : GenQuadO (tokpos, f->Operator, f->Operand1, f->Operand2, 0, false);
14660 : 0 : GenQuadO (tokpos, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
14661 : 0 : PushBooltok (Merge (NextQuad-2, f1), Merge (NextQuad-1, t1), tokpos);
14662 : : }
14663 : : else
14664 : : {
14665 : : /* avoid dangling else. */
14666 : 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);
14667 : : }
14668 : 0 : }
14669 : :
14670 : :
14671 : : /*
14672 : : CheckVariableOrConstantOrProcedure - checks to make sure sym is a variable, constant or procedure.
14673 : : */
14674 : :
14675 : 149502 : static void CheckVariableOrConstantOrProcedure (unsigned int tokpos, unsigned int sym)
14676 : : {
14677 : 149502 : unsigned int type;
14678 : :
14679 : 149502 : type = SymbolTable_GetSType (sym);
14680 : 149502 : if (SymbolTable_IsUnknown (sym))
14681 : : {
14682 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EUad} has not been declared", 30, sym);
14683 : 6 : SymbolTable_UnknownReported (sym);
14684 : : }
14685 : 149496 : else if ((M2System_IsPseudoSystemFunction (sym)) || (M2Base_IsPseudoBaseFunction (sym)))
14686 : : {
14687 : : /* avoid dangling else. */
14688 : 6 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression, not an intrinsic procedure function", 99, sym);
14689 : : }
14690 : 149490 : else if (((((! (SymbolTable_IsConst (sym))) && (! (SymbolTable_IsVar (sym)))) && (! (SymbolTable_IsProcedure (sym)))) && (! (SymbolTable_IsTemporary (sym)))) && ! MustNotCheckBounds)
14691 : : {
14692 : : /* avoid dangling else. */
14693 : 0 : M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1Ead} expected a variable, procedure, constant or expression", 62, (const char *) "and it was declared as a {%1Dd}", 31, sym);
14694 : : }
14695 : 149490 : else if ((type != SymbolTable_NulSym) && (SymbolTable_IsArray (type)))
14696 : : {
14697 : : /* avoid dangling else. */
14698 : 0 : M2MetaError_MetaErrorsT1 (tokpos, (const char *) "{%1EU} not expecting an array variable as an operand for either comparison or binary operation", 94, (const char *) "it was declared as a {%1Dd}", 27, sym);
14699 : : }
14700 : 149490 : else if (((SymbolTable_IsConstString (sym)) && (SymbolTable_IsConstStringKnown (sym))) && ((SymbolTable_GetStringLength (tokpos, sym)) > 1))
14701 : : {
14702 : : /* avoid dangling else. */
14703 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "{%1EU} not expecting a string constant as an operand for either comparison or binary operation", 94, sym);
14704 : : }
14705 : 149502 : }
14706 : :
14707 : :
14708 : : /*
14709 : : MakeOp - returns the equalent quadruple operator to a token, t.
14710 : : */
14711 : :
14712 : 130673 : static M2Quads_QuadOperator MakeOp (NameKey_Name t)
14713 : : {
14714 : 130673 : if (t == ArithPlusTok)
14715 : : {
14716 : : return M2Quads_ArithAddOp;
14717 : : }
14718 : 130673 : else if (t == M2Reserved_PlusTok)
14719 : : {
14720 : : /* avoid dangling else. */
14721 : : return M2Quads_AddOp;
14722 : : }
14723 : 107217 : else if (t == M2Reserved_MinusTok)
14724 : : {
14725 : : /* avoid dangling else. */
14726 : : return M2Quads_SubOp;
14727 : : }
14728 : 95029 : else if (t == M2Reserved_DivTok)
14729 : : {
14730 : : /* avoid dangling else. */
14731 : : return M2Quads_DivM2Op;
14732 : : }
14733 : 88873 : else if (t == M2Reserved_DivideTok)
14734 : : {
14735 : : /* avoid dangling else. */
14736 : : return M2Quads_DivTruncOp;
14737 : : }
14738 : 87287 : else if (t == M2Reserved_RemTok)
14739 : : {
14740 : : /* avoid dangling else. */
14741 : : return M2Quads_ModTruncOp;
14742 : : }
14743 : 87191 : else if (t == M2Reserved_ModTok)
14744 : : {
14745 : : /* avoid dangling else. */
14746 : : return M2Quads_ModM2Op;
14747 : : }
14748 : 85109 : else if (t == M2Reserved_TimesTok)
14749 : : {
14750 : : /* avoid dangling else. */
14751 : : return M2Quads_MultOp;
14752 : : }
14753 : 75931 : else if (t == M2Reserved_HashTok)
14754 : : {
14755 : : /* avoid dangling else. */
14756 : : return M2Quads_IfNotEquOp;
14757 : : }
14758 : 65203 : else if (t == M2Reserved_LessGreaterTok)
14759 : : {
14760 : : /* avoid dangling else. */
14761 : : return M2Quads_IfNotEquOp;
14762 : : }
14763 : 65119 : else if (t == M2Reserved_GreaterEqualTok)
14764 : : {
14765 : : /* avoid dangling else. */
14766 : : return M2Quads_IfGreEquOp;
14767 : : }
14768 : 56485 : else if (t == M2Reserved_LessEqualTok)
14769 : : {
14770 : : /* avoid dangling else. */
14771 : : return M2Quads_IfLessEquOp;
14772 : : }
14773 : 52319 : else if (t == M2Reserved_EqualTok)
14774 : : {
14775 : : /* avoid dangling else. */
14776 : : return M2Quads_IfEquOp;
14777 : : }
14778 : 13394 : else if (t == M2Reserved_LessTok)
14779 : : {
14780 : : /* avoid dangling else. */
14781 : : return M2Quads_IfLessOp;
14782 : : }
14783 : 7822 : else if (t == M2Reserved_GreaterTok)
14784 : : {
14785 : : /* avoid dangling else. */
14786 : : return M2Quads_IfGreOp;
14787 : : }
14788 : 2724 : else if (t == M2Reserved_InTok)
14789 : : {
14790 : : /* avoid dangling else. */
14791 : : return M2Quads_IfInOp;
14792 : : }
14793 : 1180 : else if (t == LogicalOrTok)
14794 : : {
14795 : : /* avoid dangling else. */
14796 : : return M2Quads_LogicalOrOp;
14797 : : }
14798 : 138 : else if (t == LogicalAndTok)
14799 : : {
14800 : : /* avoid dangling else. */
14801 : : return M2Quads_LogicalAndOp;
14802 : : }
14803 : 78 : else if (t == LogicalXorTok)
14804 : : {
14805 : : /* avoid dangling else. */
14806 : : return M2Quads_LogicalXorOp;
14807 : : }
14808 : 66 : else if (t == LogicalDifferenceTok)
14809 : : {
14810 : : /* avoid dangling else. */
14811 : : return M2Quads_LogicalDiffOp;
14812 : : }
14813 : : else
14814 : : {
14815 : : /* avoid dangling else. */
14816 : 0 : M2Error_InternalError ((const char *) "binary operation not implemented yet", 36);
14817 : : }
14818 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
14819 : : __builtin_unreachable ();
14820 : : }
14821 : :
14822 : :
14823 : : /*
14824 : : GenQuadO - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14825 : : */
14826 : :
14827 : 4505047 : static void GenQuadO (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow)
14828 : : {
14829 : 1033687 : GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, SymbolTable_NulSym);
14830 : 624449 : }
14831 : :
14832 : :
14833 : : /*
14834 : : GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14835 : : */
14836 : :
14837 : 4506469 : static void GenQuadOTrash (unsigned int TokPos, M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3, bool overflow, unsigned int trash)
14838 : : {
14839 : 4506469 : M2Quads_QuadFrame f;
14840 : :
14841 : : /* WriteString('Potential Quad: ') ; */
14842 : 4506469 : if (QuadrupleGeneration)
14843 : : {
14844 : 4504233 : if (NextQuad != Head)
14845 : : {
14846 : 4489326 : f = GetQF (NextQuad-1);
14847 : 4489326 : f->Next = NextQuad;
14848 : : }
14849 : 4504233 : PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow);
14850 : 4504233 : f = GetQF (NextQuad);
14851 : 4504233 : f->Trash = trash;
14852 : 4504233 : f->Next = 0;
14853 : 4504233 : f->LineNo = M2LexBuf_GetLineNo ();
14854 : 4504233 : if (TokPos == M2LexBuf_UnknownTokenNo)
14855 : : {
14856 : 2708813 : f->TokenNo = M2LexBuf_GetTokenNo ();
14857 : : }
14858 : : else
14859 : : {
14860 : 1795420 : f->TokenNo = TokPos;
14861 : : }
14862 : 4504233 : if (M2Options_GetDebugTraceQuad ())
14863 : : {
14864 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14865 : 0 : M2Quads_DisplayQuad (NextQuad);
14866 : : }
14867 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14868 : 4504233 : CheckBreak (NextQuad);
14869 : 4504233 : NewQuad (&NextQuad);
14870 : : }
14871 : 4506469 : }
14872 : :
14873 : :
14874 : : /*
14875 : : GenQuad - Generate a quadruple with Operation, Op1, Op2, Op3.
14876 : : */
14877 : :
14878 : 2651925 : static void GenQuad (M2Quads_QuadOperator Operation, unsigned int Op1, unsigned int Op2, unsigned int Op3)
14879 : : {
14880 : 1833428 : GenQuadO (M2LexBuf_UnknownTokenNo, Operation, Op1, Op2, Op3, true);
14881 : 498657 : }
14882 : :
14883 : :
14884 : : /*
14885 : : GenQuadOtok - generate a quadruple with Operation, Op1, Op2, Op3, overflow.
14886 : : */
14887 : :
14888 : 487451 : 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)
14889 : : {
14890 : 412700 : GenQuadOTypetok (TokPos, Operation, Op1, Op2, Op3, overflow, true, Op1Pos, Op2Pos, Op3Pos);
14891 : 204486 : }
14892 : :
14893 : :
14894 : : /*
14895 : : GenQuadOTypetok - assigns the fields of the quadruple with
14896 : : the parameters.
14897 : : */
14898 : :
14899 : 736881 : 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)
14900 : : {
14901 : 736881 : M2Quads_QuadFrame f;
14902 : :
14903 : : /* WriteString('Potential Quad: ') ; */
14904 : 736881 : if (QuadrupleGeneration)
14905 : : {
14906 : 736191 : if (NextQuad != Head)
14907 : : {
14908 : 736191 : f = GetQF (NextQuad-1);
14909 : 736191 : f->Next = NextQuad;
14910 : : }
14911 : 736191 : PutQuadOType (NextQuad, Operation, Op1, Op2, Op3, overflow, typecheck);
14912 : 736191 : f = GetQF (NextQuad);
14913 : 736191 : f->Next = 0;
14914 : 736191 : f->LineNo = M2LexBuf_GetLineNo ();
14915 : 736191 : if (TokPos == M2LexBuf_UnknownTokenNo)
14916 : : {
14917 : 0 : f->TokenNo = M2LexBuf_GetTokenNo ();
14918 : : }
14919 : : else
14920 : : {
14921 : 736191 : f->TokenNo = TokPos;
14922 : : }
14923 : 736191 : f->op1pos = Op1Pos;
14924 : 736191 : f->op2pos = Op2Pos;
14925 : 736191 : f->op3pos = Op3Pos;
14926 : 736191 : if (M2Options_GetDebugTraceQuad ())
14927 : : {
14928 : 0 : M2Printf_printf0 ((const char *) "generating: ", 12);
14929 : 0 : M2Quads_DisplayQuad (NextQuad);
14930 : : }
14931 : : /* MetaErrorT1 (TokenNo, '{%1On}', NextQuad) */
14932 : 736191 : CheckBreak (NextQuad);
14933 : 736191 : NewQuad (&NextQuad);
14934 : : }
14935 : 736881 : }
14936 : :
14937 : :
14938 : : /*
14939 : : DumpUntil - dump all quadruples until we seen the ending quadruple
14940 : : with procsym in the third operand.
14941 : : Return the quad number containing the match.
14942 : : */
14943 : :
14944 : 0 : static unsigned int DumpUntil (M2Quads_QuadOperator ending, unsigned int procsym, unsigned int quad)
14945 : : {
14946 : 0 : M2Quads_QuadOperator op;
14947 : 0 : unsigned int op1;
14948 : 0 : unsigned int op2;
14949 : 0 : unsigned int op3;
14950 : 0 : M2Quads_QuadFrame f;
14951 : :
14952 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n...\\n\\n", 9);
14953 : 0 : do {
14954 : 0 : M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
14955 : 0 : M2Quads_DisplayQuad (quad);
14956 : 0 : f = GetQF (quad);
14957 : 0 : quad = f->Next;
14958 : 0 : } while (! ((op == ending) && (op3 == procsym)));
14959 : 0 : return quad;
14960 : : /* static analysis guarentees a RETURN statement will be used before here. */
14961 : : __builtin_unreachable ();
14962 : : }
14963 : :
14964 : :
14965 : : /*
14966 : : GetCtorInit - return the init procedure for the module.
14967 : : */
14968 : :
14969 : 0 : static unsigned int GetCtorInit (unsigned int sym)
14970 : : {
14971 : 0 : unsigned int ctor;
14972 : 0 : unsigned int init;
14973 : 0 : unsigned int fini;
14974 : 0 : unsigned int dep;
14975 : :
14976 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
14977 : 0 : return init;
14978 : : /* static analysis guarentees a RETURN statement will be used before here. */
14979 : : __builtin_unreachable ();
14980 : : }
14981 : :
14982 : :
14983 : : /*
14984 : : GetCtorFini - return the fini procedure for the module.
14985 : : */
14986 : :
14987 : 0 : static unsigned int GetCtorFini (unsigned int sym)
14988 : : {
14989 : 0 : unsigned int ctor;
14990 : 0 : unsigned int init;
14991 : 0 : unsigned int fini;
14992 : 0 : unsigned int dep;
14993 : :
14994 : 0 : SymbolTable_GetModuleCtors (sym, &ctor, &init, &fini, &dep);
14995 : 0 : return fini;
14996 : : /* static analysis guarentees a RETURN statement will be used before here. */
14997 : : __builtin_unreachable ();
14998 : : }
14999 : :
15000 : :
15001 : : /*
15002 : : DumpQuadrupleFilter -
15003 : : */
15004 : :
15005 : 0 : static void DumpQuadrupleFilter (void)
15006 : : {
15007 : 0 : M2Quads_QuadFrame f;
15008 : 0 : unsigned int i;
15009 : 0 : M2Quads_QuadOperator op;
15010 : 0 : unsigned int op1;
15011 : 0 : unsigned int op2;
15012 : 0 : unsigned int op3;
15013 : :
15014 : 0 : i = Head;
15015 : 0 : while (i != 0)
15016 : : {
15017 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
15018 : 0 : if ((op == M2Quads_ProcedureScopeOp) && (M2LangDump_IsDumpRequired (op3, true)))
15019 : : {
15020 : 0 : i = DumpUntil (M2Quads_KillLocalVarOp, op3, i);
15021 : : }
15022 : 0 : else if ((op == M2Quads_InitStartOp) && (M2LangDump_IsDumpRequired (GetCtorInit (op3), true)))
15023 : : {
15024 : : /* avoid dangling else. */
15025 : 0 : i = DumpUntil (M2Quads_InitEndOp, op3, i);
15026 : : }
15027 : 0 : else if ((op == M2Quads_FinallyStartOp) && (M2LangDump_IsDumpRequired (GetCtorFini (op3), true)))
15028 : : {
15029 : : /* avoid dangling else. */
15030 : 0 : i = DumpUntil (M2Quads_FinallyEndOp, op3, i);
15031 : : }
15032 : : else
15033 : : {
15034 : : /* avoid dangling else. */
15035 : 0 : f = GetQF (i);
15036 : 0 : i = f->Next;
15037 : : }
15038 : : }
15039 : 0 : }
15040 : :
15041 : :
15042 : : /*
15043 : : DumpQuadrupleAll - dump all quadruples.
15044 : : */
15045 : :
15046 : 0 : static void DumpQuadrupleAll (void)
15047 : : {
15048 : 0 : M2Quads_QuadFrame f;
15049 : 0 : unsigned int i;
15050 : :
15051 : 0 : i = Head;
15052 : 0 : while (i != 0)
15053 : : {
15054 : 0 : M2Quads_DisplayQuad (i);
15055 : 0 : f = GetQF (i);
15056 : 0 : i = f->Next;
15057 : : }
15058 : 0 : }
15059 : :
15060 : :
15061 : : /*
15062 : : BackPatch - Makes each of the quadruples on the list pointed to by
15063 : : QuadNo take quadruple Value as a target.
15064 : : */
15065 : :
15066 : 342141 : static void BackPatch (unsigned int QuadNo, unsigned int Value)
15067 : : {
15068 : 342141 : unsigned int i;
15069 : 342141 : M2Quads_QuadFrame f;
15070 : :
15071 : 342141 : if (QuadrupleGeneration)
15072 : : {
15073 : 538918 : while (QuadNo != 0)
15074 : : {
15075 : 196789 : f = GetQF (QuadNo);
15076 : 196789 : i = f->Operand3; /* Next Link along the BackPatch */
15077 : 196789 : ManipulateReference (QuadNo, Value); /* Filling in the BackPatch. */
15078 : 196789 : QuadNo = i;
15079 : : }
15080 : : }
15081 : 342141 : }
15082 : :
15083 : :
15084 : : /*
15085 : : Merge - joins two quad lists, QuadList2 to the end of QuadList1.
15086 : : A QuadList of value zero is a nul list.
15087 : : */
15088 : :
15089 : 43728 : static unsigned int Merge (unsigned int QuadList1, unsigned int QuadList2)
15090 : : {
15091 : 43728 : unsigned int i;
15092 : 43728 : unsigned int j;
15093 : 43728 : M2Quads_QuadFrame f;
15094 : :
15095 : 43728 : if (QuadList1 == 0)
15096 : : {
15097 : : return QuadList2;
15098 : : }
15099 : 22346 : else if (QuadList2 == 0)
15100 : : {
15101 : : /* avoid dangling else. */
15102 : : return QuadList1;
15103 : : }
15104 : : else
15105 : : {
15106 : : /* avoid dangling else. */
15107 : : i = QuadList1;
15108 : 46998 : do {
15109 : 46998 : j = i;
15110 : 46998 : f = GetQF (i);
15111 : 46998 : i = f->Operand3;
15112 : 46998 : } while (! (i == 0));
15113 : 19478 : ManipulateReference (j, QuadList2);
15114 : 19478 : return QuadList1;
15115 : : }
15116 : : /* static analysis guarentees a RETURN statement will be used before here. */
15117 : : __builtin_unreachable ();
15118 : : }
15119 : :
15120 : :
15121 : : /*
15122 : : DisplayProcedureAttributes -
15123 : : */
15124 : :
15125 : 0 : static void DisplayProcedureAttributes (unsigned int proc)
15126 : : {
15127 : 0 : if (SymbolTable_IsCtor (proc))
15128 : : {
15129 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (ctor)", 7);
15130 : : }
15131 : 0 : if (SymbolTable_IsPublic (proc))
15132 : : {
15133 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (public)", 9);
15134 : : }
15135 : 0 : if (SymbolTable_IsExtern (proc))
15136 : : {
15137 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (extern)", 9);
15138 : : }
15139 : 0 : if (SymbolTable_IsMonoName (proc))
15140 : : {
15141 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " (mononame)", 11);
15142 : : }
15143 : 0 : }
15144 : :
15145 : :
15146 : : /*
15147 : : WriteQuad - Writes out the Quad BufferQuad.
15148 : : */
15149 : :
15150 : 0 : static void WriteQuad (unsigned int BufferQuad)
15151 : : {
15152 : 0 : NameKey_Name n1;
15153 : 0 : NameKey_Name n2;
15154 : 0 : M2Quads_QuadFrame f;
15155 : 0 : NameKey_Name n;
15156 : 0 : unsigned int l;
15157 : :
15158 : 0 : f = GetQF (BufferQuad);
15159 : 0 : M2Quads_WriteOperator (f->Operator);
15160 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " [%d]", 5, (const unsigned char *) &f->NoOfTimesReferenced, (sizeof (f->NoOfTimesReferenced)-1));
15161 : 0 : if (f->ConstExpr)
15162 : : {
15163 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " const ", 7);
15164 : : }
15165 : : else
15166 : : {
15167 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 7);
15168 : : }
15169 : 0 : switch (f->Operator)
15170 : : {
15171 : 0 : case M2Quads_LastForIteratorOp:
15172 : 0 : M2Quads_WriteOperand (f->Operand1);
15173 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15174 : 0 : M2Quads_WriteOperand (f->Operand2);
15175 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15176 : 0 : M2Quads_WriteOperand (f->Operand3);
15177 : 0 : break;
15178 : :
15179 : 0 : case M2Quads_HighOp:
15180 : 0 : M2Quads_WriteOperand (f->Operand1);
15181 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d ", 7, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
15182 : 0 : M2Quads_WriteOperand (f->Operand3);
15183 : 0 : break;
15184 : :
15185 : 0 : case M2Quads_InitAddressOp:
15186 : 0 : case M2Quads_SavePriorityOp:
15187 : 0 : case M2Quads_RestorePriorityOp:
15188 : 0 : case M2Quads_SubrangeLowOp:
15189 : 0 : case M2Quads_SubrangeHighOp:
15190 : 0 : case M2Quads_BecomesOp:
15191 : 0 : case M2Quads_InclOp:
15192 : 0 : case M2Quads_ExclOp:
15193 : 0 : case M2Quads_UnboundedOp:
15194 : 0 : case M2Quads_ReturnValueOp:
15195 : 0 : case M2Quads_FunctValueOp:
15196 : 0 : case M2Quads_NegateOp:
15197 : 0 : case M2Quads_AddrOp:
15198 : 0 : case M2Quads_StringConvertCnulOp:
15199 : 0 : case M2Quads_StringConvertM2nulOp:
15200 : 0 : case M2Quads_StringLengthOp:
15201 : 0 : M2Quads_WriteOperand (f->Operand1);
15202 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15203 : 0 : M2Quads_WriteOperand (f->Operand3);
15204 : 0 : break;
15205 : :
15206 : 0 : case M2Quads_ElementSizeOp:
15207 : 0 : case M2Quads_IfInOp:
15208 : 0 : case M2Quads_IfNotInOp:
15209 : 0 : case M2Quads_IfNotEquOp:
15210 : 0 : case M2Quads_IfEquOp:
15211 : 0 : case M2Quads_IfLessOp:
15212 : 0 : case M2Quads_IfGreOp:
15213 : 0 : case M2Quads_IfLessEquOp:
15214 : 0 : case M2Quads_IfGreEquOp:
15215 : 0 : M2Quads_WriteOperand (f->Operand1);
15216 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15217 : 0 : M2Quads_WriteOperand (f->Operand2);
15218 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %4d", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15219 : 0 : break;
15220 : :
15221 : 0 : case M2Quads_InlineOp:
15222 : 0 : case M2Quads_RetryOp:
15223 : 0 : case M2Quads_TryOp:
15224 : 0 : case M2Quads_GotoOp:
15225 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d", 3, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15226 : 0 : break;
15227 : :
15228 : 0 : case M2Quads_StatementNoteOp:
15229 : 0 : l = M2LexBuf_TokenToLineNo (f->Operand3, 0);
15230 : 0 : n = M2LexBuf_GetTokenName (f->Operand3);
15231 : 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));
15232 : 0 : break;
15233 : :
15234 : 0 : case M2Quads_LineNumberOp:
15235 : 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));
15236 : 0 : break;
15237 : :
15238 : 0 : case M2Quads_EndFileOp:
15239 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15240 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n1, (sizeof (n1)-1));
15241 : 0 : break;
15242 : :
15243 : 0 : case M2Quads_ThrowOp:
15244 : 0 : case M2Quads_ReturnOp:
15245 : 0 : case M2Quads_CallOp:
15246 : 0 : case M2Quads_KillLocalVarOp:
15247 : 0 : M2Quads_WriteOperand (f->Operand3);
15248 : 0 : break;
15249 : :
15250 : 0 : case M2Quads_ProcedureScopeOp:
15251 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
15252 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
15253 : 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));
15254 : 0 : DisplayProcedureAttributes (f->Operand3);
15255 : 0 : break;
15256 : :
15257 : 0 : case M2Quads_NewLocalVarOp:
15258 : 0 : case M2Quads_FinallyStartOp:
15259 : 0 : case M2Quads_FinallyEndOp:
15260 : 0 : case M2Quads_InitEndOp:
15261 : 0 : case M2Quads_InitStartOp:
15262 : 0 : n1 = SymbolTable_GetSymName (f->Operand2);
15263 : 0 : n2 = SymbolTable_GetSymName (f->Operand3);
15264 : 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));
15265 : 0 : break;
15266 : :
15267 : 0 : case M2Quads_ModuleScopeOp:
15268 : 0 : case M2Quads_StartModFileOp:
15269 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15270 : 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));
15271 : 0 : break;
15272 : :
15273 : 0 : case M2Quads_StartDefFileOp:
15274 : 0 : n1 = SymbolTable_GetSymName (f->Operand3);
15275 : 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));
15276 : 0 : break;
15277 : :
15278 : 0 : case M2Quads_OptParamOp:
15279 : 0 : case M2Quads_ParamOp:
15280 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &f->Operand1, (sizeof (f->Operand1)-1));
15281 : 0 : M2Quads_WriteOperand (f->Operand2);
15282 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15283 : 0 : M2Quads_WriteOperand (f->Operand3);
15284 : 0 : break;
15285 : :
15286 : 0 : case M2Quads_SizeOp:
15287 : 0 : case M2Quads_RecordFieldOp:
15288 : 0 : case M2Quads_IndrXOp:
15289 : 0 : case M2Quads_XIndrOp:
15290 : 0 : case M2Quads_ArrayOp:
15291 : 0 : case M2Quads_LogicalShiftOp:
15292 : 0 : case M2Quads_LogicalRotateOp:
15293 : 0 : case M2Quads_LogicalOrOp:
15294 : 0 : case M2Quads_LogicalAndOp:
15295 : 0 : case M2Quads_LogicalXorOp:
15296 : 0 : case M2Quads_LogicalDiffOp:
15297 : 0 : case M2Quads_ArithAddOp:
15298 : 0 : case M2Quads_CoerceOp:
15299 : 0 : case M2Quads_ConvertOp:
15300 : 0 : case M2Quads_CastOp:
15301 : 0 : case M2Quads_AddOp:
15302 : 0 : case M2Quads_SubOp:
15303 : 0 : case M2Quads_MultOp:
15304 : 0 : case M2Quads_DivM2Op:
15305 : 0 : case M2Quads_ModM2Op:
15306 : 0 : case M2Quads_ModFloorOp:
15307 : 0 : case M2Quads_DivCeilOp:
15308 : 0 : case M2Quads_ModCeilOp:
15309 : 0 : case M2Quads_DivFloorOp:
15310 : 0 : case M2Quads_ModTruncOp:
15311 : 0 : case M2Quads_DivTruncOp:
15312 : 0 : M2Quads_WriteOperand (f->Operand1);
15313 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15314 : 0 : M2Quads_WriteOperand (f->Operand2);
15315 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15316 : 0 : M2Quads_WriteOperand (f->Operand3);
15317 : 0 : break;
15318 : :
15319 : : case M2Quads_DummyOp:
15320 : : case M2Quads_CodeOnOp:
15321 : : case M2Quads_CodeOffOp:
15322 : : case M2Quads_ProfileOnOp:
15323 : : case M2Quads_ProfileOffOp:
15324 : : case M2Quads_OptimizeOnOp:
15325 : : case M2Quads_OptimizeOffOp:
15326 : : break;
15327 : :
15328 : 0 : case M2Quads_BuiltinConstOp:
15329 : 0 : M2Quads_WriteOperand (f->Operand1);
15330 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15331 : 0 : break;
15332 : :
15333 : 0 : case M2Quads_BuiltinTypeInfoOp:
15334 : 0 : M2Quads_WriteOperand (f->Operand1);
15335 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand2, (sizeof (f->Operand2)-1));
15336 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) " %a", 5, (const unsigned char *) &f->Operand3, (sizeof (f->Operand3)-1));
15337 : 0 : break;
15338 : :
15339 : 0 : case M2Quads_StandardFunctionOp:
15340 : 0 : M2Quads_WriteOperand (f->Operand1);
15341 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15342 : 0 : M2Quads_WriteOperand (f->Operand2);
15343 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15344 : 0 : M2Quads_WriteOperand (f->Operand3);
15345 : 0 : break;
15346 : :
15347 : : case M2Quads_CatchBeginOp:
15348 : : case M2Quads_CatchEndOp:
15349 : : break;
15350 : :
15351 : 0 : case M2Quads_RangeCheckOp:
15352 : 0 : case M2Quads_ErrorOp:
15353 : 0 : M2Range_WriteRangeCheck (f->Operand3);
15354 : 0 : break;
15355 : :
15356 : 0 : case M2Quads_SaveExceptionOp:
15357 : 0 : case M2Quads_RestoreExceptionOp:
15358 : 0 : M2Quads_WriteOperand (f->Operand1);
15359 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) " ", 2);
15360 : 0 : M2Quads_WriteOperand (f->Operand3);
15361 : 0 : break;
15362 : :
15363 : :
15364 : 0 : default:
15365 : 0 : M2Error_InternalError ((const char *) "quadruple not recognised", 24);
15366 : 0 : break;
15367 : : }
15368 : 0 : }
15369 : :
15370 : :
15371 : : /*
15372 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
15373 : : */
15374 : :
15375 : 0 : static void WriteMode (SymbolTable_ModeOfAddr Mode)
15376 : : {
15377 : 0 : switch (Mode)
15378 : : {
15379 : 0 : case SymbolTable_ImmediateValue:
15380 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "i", 1);
15381 : 0 : break;
15382 : :
15383 : 0 : case SymbolTable_NoValue:
15384 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "n", 1);
15385 : 0 : break;
15386 : :
15387 : 0 : case SymbolTable_RightValue:
15388 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "r", 1);
15389 : 0 : break;
15390 : :
15391 : 0 : case SymbolTable_LeftValue:
15392 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "l", 1);
15393 : 0 : break;
15394 : :
15395 : :
15396 : 0 : default:
15397 : 0 : M2Error_InternalError ((const char *) "unrecognised mode", 17);
15398 : 0 : break;
15399 : : }
15400 : 0 : }
15401 : :
15402 : :
15403 : : /*
15404 : : PushExit - pushes the exit value onto the EXIT stack.
15405 : : */
15406 : :
15407 : 610 : static void PushExit (unsigned int Exit)
15408 : : {
15409 : 0 : M2StackWord_PushWord (ExitStack, Exit);
15410 : 94 : }
15411 : :
15412 : :
15413 : : /*
15414 : : PopExit - pops the exit value from the EXIT stack.
15415 : : */
15416 : :
15417 : 610 : static unsigned int PopExit (void)
15418 : : {
15419 : 0 : return M2StackWord_PopWord (ExitStack);
15420 : : /* static analysis guarentees a RETURN statement will be used before here. */
15421 : : __builtin_unreachable ();
15422 : : }
15423 : :
15424 : :
15425 : : /*
15426 : : PushFor - pushes the exit value onto the FOR stack.
15427 : : */
15428 : :
15429 : 8422 : static void PushFor (unsigned int Exit)
15430 : : {
15431 : 0 : M2StackWord_PushWord (ForStack, Exit);
15432 : 0 : }
15433 : :
15434 : :
15435 : : /*
15436 : : PopFor - pops the exit value from the FOR stack.
15437 : : */
15438 : :
15439 : 8416 : static unsigned int PopFor (void)
15440 : : {
15441 : 0 : return M2StackWord_PopWord (ForStack);
15442 : : /* static analysis guarentees a RETURN statement will be used before here. */
15443 : : __builtin_unreachable ();
15444 : : }
15445 : :
15446 : :
15447 : : /*
15448 : : OperandTno - returns the ident operand stored in the true position
15449 : : on the boolean stack. This is exactly the same as
15450 : : OperandT but it has no IsBoolean checking.
15451 : : */
15452 : :
15453 : 129313327 : static unsigned int OperandTno (unsigned int pos)
15454 : : {
15455 : 129313327 : M2Quads_BoolFrame f;
15456 : :
15457 : 129313327 : M2Debug_Assert (pos > 0);
15458 : 129313327 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15459 : 129313327 : return static_cast<unsigned int> (f->TrueExit);
15460 : : /* static analysis guarentees a RETURN statement will be used before here. */
15461 : : __builtin_unreachable ();
15462 : : }
15463 : :
15464 : :
15465 : : /*
15466 : : OperandFno - returns the ident operand stored in the false position
15467 : : on the boolean stack. This is exactly the same as
15468 : : OperandF but it has no IsBoolean checking.
15469 : : */
15470 : :
15471 : 150710 : static unsigned int OperandFno (unsigned int pos)
15472 : : {
15473 : 150710 : M2Quads_BoolFrame f;
15474 : :
15475 : 150710 : M2Debug_Assert (pos > 0);
15476 : 150710 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15477 : 150710 : return static_cast<unsigned int> (f->FalseExit);
15478 : : /* static analysis guarentees a RETURN statement will be used before here. */
15479 : : __builtin_unreachable ();
15480 : : }
15481 : :
15482 : :
15483 : : /*
15484 : : OperandTtok - returns the token associated with the position, pos
15485 : : on the boolean stack.
15486 : : */
15487 : :
15488 : 37465873 : static unsigned int OperandTtok (unsigned int pos)
15489 : : {
15490 : 37465873 : M2Quads_BoolFrame f;
15491 : :
15492 : 37465873 : M2Debug_Assert (pos > 0);
15493 : 37465873 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15494 : 37465873 : return f->tokenno;
15495 : : /* static analysis guarentees a RETURN statement will be used before here. */
15496 : : __builtin_unreachable ();
15497 : : }
15498 : :
15499 : :
15500 : : /*
15501 : : PopBooltok - Pops a True and a False exit quad number from the True/False
15502 : : stack.
15503 : : */
15504 : :
15505 : 181542 : static void PopBooltok (unsigned int *True, unsigned int *False, unsigned int *tokno)
15506 : : {
15507 : 181542 : M2Quads_BoolFrame f;
15508 : :
15509 : 181542 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15510 : 181542 : (*True) = f->TrueExit;
15511 : 181542 : (*False) = f->FalseExit;
15512 : 181542 : (*tokno) = f->tokenno;
15513 : 181542 : M2Debug_Assert (f->BooleanOp);
15514 : 181542 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15515 : 181542 : }
15516 : :
15517 : :
15518 : : /*
15519 : : PushBooltok - Push a True and a False exit quad numbers onto the
15520 : : True/False stack.
15521 : : */
15522 : :
15523 : 188296 : static void PushBooltok (unsigned int True, unsigned int False, unsigned int tokno)
15524 : : {
15525 : 188296 : M2Quads_BoolFrame f;
15526 : :
15527 : 188296 : M2Debug_Assert (True <= NextQuad);
15528 : 188296 : M2Debug_Assert (False <= NextQuad);
15529 : 188296 : f = newBoolFrame ();
15530 : 188296 : f->TrueExit = True;
15531 : 188296 : f->FalseExit = False;
15532 : 188296 : f->BooleanOp = true;
15533 : 188296 : f->tokenno = tokno;
15534 : 188296 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
15535 : 188296 : f->RangeDep = 0;
15536 : 188296 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15537 : 188296 : M2Quads_Annotate ((const char *) "<q%1d>|<q%2d>||true quad|false quad", 35);
15538 : 188296 : }
15539 : :
15540 : :
15541 : : /*
15542 : : PopBool - Pops a True and a False exit quad number from the True/False
15543 : : stack.
15544 : : */
15545 : :
15546 : 153646 : static void PopBool (unsigned int *True, unsigned int *False)
15547 : : {
15548 : 153646 : unsigned int tokno;
15549 : :
15550 : 8928 : PopBooltok (True, False, &tokno);
15551 : 0 : }
15552 : :
15553 : :
15554 : : /*
15555 : : PushBool - Push a True and a False exit quad numbers onto the
15556 : : True/False stack.
15557 : : */
15558 : :
15559 : 96715 : static void PushBool (unsigned int True, unsigned int False)
15560 : : {
15561 : 6754 : PushBooltok (True, False, M2LexBuf_UnknownTokenNo);
15562 : 11066 : }
15563 : :
15564 : :
15565 : : /*
15566 : : IsBoolean - returns true is the Stack position pos contains a Boolean
15567 : : Exit. False is returned if an Ident is stored.
15568 : : */
15569 : :
15570 : 169633647 : static bool IsBoolean (unsigned int pos)
15571 : : {
15572 : 169633647 : M2Quads_BoolFrame f;
15573 : :
15574 : 169633647 : M2Debug_Assert (pos > 0);
15575 : 169633647 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15576 : 169633647 : return f->BooleanOp;
15577 : : /* static analysis guarentees a RETURN statement will be used before here. */
15578 : : __builtin_unreachable ();
15579 : : }
15580 : :
15581 : :
15582 : : /*
15583 : : OperandD - returns possible array dimension associated with the ident
15584 : : operand stored on the boolean stack.
15585 : : */
15586 : :
15587 : 608856 : static unsigned int OperandD (unsigned int pos)
15588 : : {
15589 : 608856 : M2Quads_BoolFrame f;
15590 : :
15591 : 608856 : M2Debug_Assert (pos > 0);
15592 : 608856 : M2Debug_Assert (! (IsBoolean (pos)));
15593 : 608856 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15594 : 608856 : return static_cast<unsigned int> (f->Dimension);
15595 : : /* static analysis guarentees a RETURN statement will be used before here. */
15596 : : __builtin_unreachable ();
15597 : : }
15598 : :
15599 : :
15600 : : /*
15601 : : OperandRW - returns the rw operand stored on the boolean stack.
15602 : : */
15603 : :
15604 : 658042 : static unsigned int OperandRW (unsigned int pos)
15605 : : {
15606 : 658042 : M2Quads_BoolFrame f;
15607 : :
15608 : 658042 : M2Debug_Assert (pos > 0);
15609 : 658042 : M2Debug_Assert (! (IsBoolean (pos)));
15610 : 658042 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15611 : 658042 : return static_cast<unsigned int> (f->ReadWrite);
15612 : : /* static analysis guarentees a RETURN statement will be used before here. */
15613 : : __builtin_unreachable ();
15614 : : }
15615 : :
15616 : :
15617 : : /*
15618 : : OperandMergeRW - returns the rw operand if not NulSym else it
15619 : : returns True.
15620 : : */
15621 : :
15622 : 637552 : static unsigned int OperandMergeRW (unsigned int pos)
15623 : : {
15624 : 637552 : if ((OperandRW (pos)) == SymbolTable_NulSym)
15625 : : {
15626 : 619474 : return M2Quads_OperandT (pos);
15627 : : }
15628 : : else
15629 : : {
15630 : 18078 : return OperandRW (pos);
15631 : : }
15632 : : /* static analysis guarentees a RETURN statement will be used before here. */
15633 : : __builtin_unreachable ();
15634 : : }
15635 : :
15636 : :
15637 : : /*
15638 : : OperandRangeDep - return the range dependant associated with the quad stack.
15639 : : */
15640 : :
15641 : 123415 : static unsigned int OperandRangeDep (unsigned int pos)
15642 : : {
15643 : 123415 : M2Quads_BoolFrame f;
15644 : :
15645 : 123415 : M2Debug_Assert (! (IsBoolean (pos)));
15646 : 123415 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15647 : 123415 : return f->RangeDep;
15648 : : /* static analysis guarentees a RETURN statement will be used before here. */
15649 : : __builtin_unreachable ();
15650 : : }
15651 : :
15652 : :
15653 : : /*
15654 : : PutRangeDep - assigns the quad stack pos RangeDep to dep.
15655 : : */
15656 : :
15657 : 477960 : static void PutRangeDep (unsigned int pos, unsigned int dep)
15658 : : {
15659 : 477960 : M2Quads_BoolFrame f;
15660 : :
15661 : 477960 : M2Debug_Assert (! (IsBoolean (pos)));
15662 : 477960 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
15663 : 477960 : f->RangeDep = dep;
15664 : 477960 : }
15665 : :
15666 : :
15667 : : /*
15668 : : UseLineNote - uses the line note and returns it to the free list.
15669 : : */
15670 : :
15671 : 4220 : static void UseLineNote (M2Quads_LineNote l)
15672 : : {
15673 : 4220 : M2Quads_QuadFrame f;
15674 : :
15675 : 4220 : f = GetQF (NextQuad-1);
15676 : 4220 : if ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (l->File))))
15677 : : {} /* empty. */
15678 : : else
15679 : : {
15680 : : /* do nothing */
15681 : : if (false)
15682 : : {
15683 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (l->File), SymbolTable_NulSym, (unsigned int ) (l->Line));
15684 : : }
15685 : : }
15686 : 4220 : l->Next = FreeLineList;
15687 : 4220 : FreeLineList = l;
15688 : 4220 : }
15689 : :
15690 : :
15691 : : /*
15692 : : PopLineNo - pops a line note from the line stack.
15693 : : */
15694 : :
15695 : 4220 : static M2Quads_LineNote PopLineNo (void)
15696 : : {
15697 : 4220 : M2Quads_LineNote l;
15698 : :
15699 : 4220 : l = static_cast<M2Quads_LineNote> (M2StackAddress_PopAddress (LineStack));
15700 : 4220 : if (l == NULL)
15701 : : {
15702 : 0 : M2Error_InternalError ((const char *) "no line note available", 22);
15703 : : }
15704 : 4220 : return l;
15705 : : /* static analysis guarentees a RETURN statement will be used before here. */
15706 : : __builtin_unreachable ();
15707 : : }
15708 : :
15709 : :
15710 : : /*
15711 : : InitLineNote - creates a line note and initializes it to
15712 : : contain, file, line.
15713 : : */
15714 : :
15715 : 4220 : static M2Quads_LineNote InitLineNote (NameKey_Name file, unsigned int line)
15716 : : {
15717 : 4220 : M2Quads_LineNote l;
15718 : :
15719 : 4220 : if (FreeLineList == NULL)
15720 : : {
15721 : 2228 : Storage_ALLOCATE ((void **) &l, sizeof (M2Quads__T6));
15722 : : }
15723 : : else
15724 : : {
15725 : 1992 : l = FreeLineList;
15726 : 1992 : FreeLineList = FreeLineList->Next;
15727 : : }
15728 : 4220 : l->File = file;
15729 : 4220 : l->Line = line;
15730 : 4220 : return l;
15731 : : /* static analysis guarentees a RETURN statement will be used before here. */
15732 : : __builtin_unreachable ();
15733 : : }
15734 : :
15735 : :
15736 : : /*
15737 : : PushLineNote -
15738 : : */
15739 : :
15740 : 4220 : static void PushLineNote (M2Quads_LineNote l)
15741 : : {
15742 : 0 : M2StackAddress_PushAddress (LineStack, reinterpret_cast <void *> (l));
15743 : 0 : }
15744 : :
15745 : :
15746 : : /*
15747 : : BuildStmtNoteTok - adds a nop (with an assigned tokenno location) to the code.
15748 : : */
15749 : :
15750 : 452076 : static void BuildStmtNoteTok (unsigned int tokenno)
15751 : : {
15752 : 452076 : NameKey_Name filename;
15753 : 452076 : M2Quads_QuadFrame f;
15754 : :
15755 : 452076 : f = GetQF (NextQuad-1);
15756 : : /* no need to have multiple notes at the same position. */
15757 : 452076 : if ((f->Operator != M2Quads_StatementNoteOp) || (f->Operand3 != tokenno))
15758 : : {
15759 : 445238 : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
15760 : 445238 : GenQuad (M2Quads_StatementNoteOp, (unsigned int ) (filename), SymbolTable_NulSym, tokenno);
15761 : : }
15762 : 452076 : }
15763 : :
15764 : :
15765 : : /*
15766 : : GetRecordOrField -
15767 : : */
15768 : :
15769 : 1218 : static unsigned int GetRecordOrField (void)
15770 : : {
15771 : 1218 : unsigned int f;
15772 : :
15773 : 1218 : VarientFieldNo += 1;
15774 : 1218 : f = static_cast<unsigned int> (Lists_GetItemFromList (VarientFields, VarientFieldNo));
15775 : 1218 : if (DebugVarients)
15776 : : {
15777 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
15778 : : if (SymbolTable_IsRecord (f))
15779 : : {
15780 : : 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));
15781 : : }
15782 : : else
15783 : : {
15784 : : 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));
15785 : : }
15786 : : }
15787 : 1218 : return f;
15788 : : /* static analysis guarentees a RETURN statement will be used before here. */
15789 : : __builtin_unreachable ();
15790 : : }
15791 : :
15792 : :
15793 : : /*
15794 : : PushTFAD - Push True, False, Array, Dim, numbers onto the
15795 : : True/False stack. True and False are assumed to
15796 : : contain Symbols or Ident etc.
15797 : : */
15798 : :
15799 : 384 : static void PushTFAD (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim)
15800 : : {
15801 : 384 : M2Quads_BoolFrame f;
15802 : :
15803 : 384 : f = newBoolFrame ();
15804 : 384 : f->TrueExit = static_cast<unsigned int> (True);
15805 : 384 : f->FalseExit = static_cast<unsigned int> (False);
15806 : 384 : f->Unbounded = static_cast<unsigned int> (Array);
15807 : 384 : f->Dimension = static_cast<unsigned int> (Dim);
15808 : 384 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15809 : 384 : }
15810 : :
15811 : :
15812 : : /*
15813 : : PushTFADtok - Push True, False, Array, Dim, numbers onto the
15814 : : True/False stack. True and False are assumed to
15815 : : contain Symbols or Ident etc.
15816 : : */
15817 : :
15818 : 2976 : static void PushTFADtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int tokno)
15819 : : {
15820 : 2976 : M2Quads_BoolFrame f;
15821 : :
15822 : 2976 : f = newBoolFrame ();
15823 : 2976 : f->TrueExit = static_cast<unsigned int> (True);
15824 : 2976 : f->FalseExit = static_cast<unsigned int> (False);
15825 : 2976 : f->Unbounded = static_cast<unsigned int> (Array);
15826 : 2976 : f->Dimension = static_cast<unsigned int> (Dim);
15827 : 2976 : f->tokenno = tokno;
15828 : 2976 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15829 : 2976 : }
15830 : :
15831 : :
15832 : : /*
15833 : : PushTFADrwtok - Push True, False, Array, Dim, rw, numbers onto the
15834 : : True/False stack. True and False are assumed to
15835 : : contain Symbols or Ident etc.
15836 : : */
15837 : :
15838 : 7638 : static void PushTFADrwtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int Dim, unsigned int rw, unsigned int Tok)
15839 : : {
15840 : 7638 : M2Quads_BoolFrame f;
15841 : :
15842 : 7638 : f = newBoolFrame ();
15843 : 7638 : f->TrueExit = static_cast<unsigned int> (True);
15844 : 7638 : f->FalseExit = static_cast<unsigned int> (False);
15845 : 7638 : f->Unbounded = static_cast<unsigned int> (Array);
15846 : 7638 : f->Dimension = static_cast<unsigned int> (Dim);
15847 : 7638 : f->ReadWrite = static_cast<unsigned int> (rw);
15848 : 7638 : f->tokenno = Tok;
15849 : 7638 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15850 : 7638 : }
15851 : :
15852 : :
15853 : : /*
15854 : : PopTFrwtok - Pop a True and False number from the True/False stack.
15855 : : True and False are assumed to contain Symbols or Ident etc.
15856 : : */
15857 : :
15858 : 255174 : static void PopTFrwtok (unsigned int *True, unsigned int *False, unsigned int *rw, unsigned int *tokno)
15859 : : {
15860 : 255174 : M2Quads_BoolFrame f;
15861 : :
15862 : 255174 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15863 : 255174 : (*True) = static_cast<unsigned int> (f->TrueExit);
15864 : 255174 : (*False) = static_cast<unsigned int> (f->FalseExit);
15865 : 255174 : M2Debug_Assert (! f->BooleanOp);
15866 : 255174 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15867 : 255174 : (*tokno) = f->tokenno;
15868 : 255174 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15869 : 255174 : }
15870 : :
15871 : :
15872 : : /*
15873 : : PushTFrwtok - Push an item onto the stack in the T (true) position,
15874 : : it is assummed to be a token and its token location is recorded.
15875 : : */
15876 : :
15877 : 285296 : static void PushTFrwtok (unsigned int True, unsigned int False, unsigned int rw, unsigned int tokno)
15878 : : {
15879 : 285296 : M2Quads_BoolFrame f;
15880 : :
15881 : 285296 : f = newBoolFrame ();
15882 : 285296 : f->TrueExit = static_cast<unsigned int> (True);
15883 : 285296 : f->FalseExit = static_cast<unsigned int> (False);
15884 : 285296 : f->ReadWrite = static_cast<unsigned int> (rw);
15885 : 285296 : f->tokenno = tokno;
15886 : 285296 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15887 : 285296 : }
15888 : :
15889 : :
15890 : : /*
15891 : : PushTFDtok - Push True, False, Dim, numbers onto the
15892 : : True/False stack. True and False are assumed to
15893 : : contain Symbols or Ident etc.
15894 : : */
15895 : :
15896 : 258 : static void PushTFDtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int Tok)
15897 : : {
15898 : 258 : M2Quads_BoolFrame f;
15899 : :
15900 : 258 : f = newBoolFrame ();
15901 : 258 : f->TrueExit = static_cast<unsigned int> (True);
15902 : 258 : f->FalseExit = static_cast<unsigned int> (False);
15903 : 258 : f->Dimension = static_cast<unsigned int> (Dim);
15904 : 258 : f->tokenno = Tok;
15905 : 258 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15906 : 258 : }
15907 : :
15908 : :
15909 : : /*
15910 : : PopTFDtok - Pop a True, False, Dim number from the True/False stack.
15911 : : True and False are assumed to contain Symbols or Ident etc.
15912 : : */
15913 : :
15914 : 258 : static void PopTFDtok (unsigned int *True, unsigned int *False, unsigned int *Dim, unsigned int *Tok)
15915 : : {
15916 : 258 : M2Quads_BoolFrame f;
15917 : :
15918 : 258 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15919 : 258 : (*True) = static_cast<unsigned int> (f->TrueExit);
15920 : 258 : (*False) = static_cast<unsigned int> (f->FalseExit);
15921 : 258 : (*Dim) = static_cast<unsigned int> (f->Dimension);
15922 : 258 : (*Tok) = f->tokenno;
15923 : 258 : M2Debug_Assert (! f->BooleanOp);
15924 : 258 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15925 : 258 : }
15926 : :
15927 : :
15928 : : /*
15929 : : PushTFDrwtok - Push True, False, Dim, numbers onto the
15930 : : True/False stack. True and False are assumed to
15931 : : contain Symbols or Ident etc.
15932 : : */
15933 : :
15934 : 40986 : static void PushTFDrwtok (unsigned int True, unsigned int False, unsigned int Dim, unsigned int rw, unsigned int Tok)
15935 : : {
15936 : 40986 : M2Quads_BoolFrame f;
15937 : :
15938 : 40986 : f = newBoolFrame ();
15939 : 40986 : f->TrueExit = static_cast<unsigned int> (True);
15940 : 40986 : f->FalseExit = static_cast<unsigned int> (False);
15941 : 40986 : f->Dimension = static_cast<unsigned int> (Dim);
15942 : 40986 : f->ReadWrite = static_cast<unsigned int> (rw);
15943 : 40986 : f->tokenno = Tok;
15944 : 40986 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15945 : 40986 : }
15946 : :
15947 : :
15948 : : /*
15949 : : PushTFrw - Push a True and False numbers onto the True/False stack.
15950 : : True and False are assumed to contain Symbols or Ident etc.
15951 : : It also pushes the higher level symbol which is associated
15952 : : with the True symbol. Eg record variable or array variable.
15953 : : */
15954 : :
15955 : 2412 : static void PushTFrw (unsigned int True, unsigned int False, unsigned int rw)
15956 : : {
15957 : 2412 : M2Quads_BoolFrame f;
15958 : :
15959 : 2412 : f = newBoolFrame ();
15960 : 2412 : f->TrueExit = static_cast<unsigned int> (True);
15961 : 2412 : f->FalseExit = static_cast<unsigned int> (False);
15962 : 2412 : f->ReadWrite = rw;
15963 : 2412 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
15964 : 2412 : }
15965 : :
15966 : :
15967 : : /*
15968 : : PopTFrw - Pop a True and False number from the True/False stack.
15969 : : True and False are assumed to contain Symbols or Ident etc.
15970 : : */
15971 : :
15972 : 28604 : static void PopTFrw (unsigned int *True, unsigned int *False, unsigned int *rw)
15973 : : {
15974 : 28604 : M2Quads_BoolFrame f;
15975 : :
15976 : 28604 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
15977 : 28604 : (*True) = static_cast<unsigned int> (f->TrueExit);
15978 : 28604 : (*False) = static_cast<unsigned int> (f->FalseExit);
15979 : 28604 : M2Debug_Assert (! f->BooleanOp);
15980 : 28604 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
15981 : 28604 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15982 : 28604 : }
15983 : :
15984 : :
15985 : : /*
15986 : : newBoolFrame - creates a new BoolFrame with all fields initialised to their defaults.
15987 : : */
15988 : :
15989 : 207089827 : static M2Quads_BoolFrame newBoolFrame (void)
15990 : : {
15991 : 207089827 : M2Quads_BoolFrame f;
15992 : :
15993 : 207089827 : Storage_ALLOCATE ((void **) &f, sizeof (M2Quads__T2));
15994 : 207089827 : f->TrueExit = 0;
15995 : 207089827 : f->FalseExit = 0;
15996 : 207089827 : f->Unbounded = SymbolTable_NulSym;
15997 : 207089827 : f->BooleanOp = false;
15998 : 207089827 : f->Dimension = 0;
15999 : 207089827 : f->ReadWrite = SymbolTable_NulSym;
16000 : 207089827 : f->name = SymbolTable_NulSym;
16001 : 207089827 : f->Annotation = static_cast<DynamicStrings_String> (NULL);
16002 : 207089827 : f->tokenno = M2LexBuf_UnknownTokenNo;
16003 : 207089827 : return f;
16004 : : /* static analysis guarentees a RETURN statement will be used before here. */
16005 : : __builtin_unreachable ();
16006 : : }
16007 : :
16008 : :
16009 : : /*
16010 : : PushTrwtok - Push an item onto the True/False stack. The False value will be zero.
16011 : : */
16012 : :
16013 : 144 : static void PushTrwtok (unsigned int True, unsigned int rw, unsigned int tok)
16014 : : {
16015 : 144 : M2Quads_BoolFrame f;
16016 : :
16017 : 144 : f = newBoolFrame ();
16018 : 144 : f->TrueExit = static_cast<unsigned int> (True);
16019 : 144 : f->ReadWrite = static_cast<unsigned int> (rw);
16020 : 144 : f->tokenno = tok;
16021 : 144 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
16022 : 144 : }
16023 : :
16024 : :
16025 : : /*
16026 : : PopTrw - Pop a True field and rw symbol from the stack.
16027 : : */
16028 : :
16029 : 2412 : static void PopTrw (unsigned int *True, unsigned int *rw)
16030 : : {
16031 : 2412 : M2Quads_BoolFrame f;
16032 : :
16033 : 2412 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
16034 : 2412 : (*True) = static_cast<unsigned int> (f->TrueExit);
16035 : 2412 : M2Debug_Assert (! f->BooleanOp);
16036 : 2412 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
16037 : 2412 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16038 : 2412 : }
16039 : :
16040 : :
16041 : : /*
16042 : : PopTrwtok - Pop a True field and rw symbol from the stack.
16043 : : */
16044 : :
16045 : 906338 : static void PopTrwtok (unsigned int *True, unsigned int *rw, unsigned int *tok)
16046 : : {
16047 : 906338 : M2Quads_BoolFrame f;
16048 : :
16049 : 906338 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
16050 : 906338 : (*True) = static_cast<unsigned int> (f->TrueExit);
16051 : 906338 : M2Debug_Assert (! f->BooleanOp);
16052 : 906338 : (*rw) = static_cast<unsigned int> (f->ReadWrite);
16053 : 906338 : (*tok) = f->tokenno;
16054 : 906338 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
16055 : 906338 : }
16056 : :
16057 : :
16058 : : /*
16059 : : gdbhook - a debugger convenience hook.
16060 : : */
16061 : :
16062 : 0 : static void gdbhook (void)
16063 : : {
16064 : 0 : }
16065 : :
16066 : :
16067 : : /*
16068 : : BreakWhenQuadCreated - to be called interactively by gdb.
16069 : : */
16070 : :
16071 : 15260 : static void BreakWhenQuadCreated (unsigned int quad)
16072 : : {
16073 : 15260 : BreakQuad = quad;
16074 : 0 : }
16075 : :
16076 : :
16077 : : /*
16078 : : CheckBreak - if quad = BreakQuad then call gdbhook.
16079 : : */
16080 : :
16081 : 0 : static void CheckBreak (unsigned int quad)
16082 : : {
16083 : 0 : if (quad == BreakQuad)
16084 : : {
16085 : 0 : gdbhook ();
16086 : : }
16087 : 0 : }
16088 : :
16089 : :
16090 : : /*
16091 : : Init - initialize the M2Quads module, all the stacks, all the lists
16092 : : and the quads list.
16093 : : */
16094 : :
16095 : 15260 : static void Init (void)
16096 : : {
16097 : 15260 : BreakWhenQuadCreated (0); /* Disable the intereactive quad watch. */
16098 : : /* To examine the quad table when a quad is created run cc1gm2 from gdb
16099 : : and set a break point on gdbhook.
16100 : : (gdb) break gdbhook
16101 : : (gdb) run
16102 : : Now below interactively call BreakWhenQuadCreated with the quad
16103 : : under investigation. */
16104 : 15260 : gdbhook ();
16105 : : /* Now is the time to interactively call gdb, for example:
16106 : : (gdb) print BreakWhenQuadCreated (1234)
16107 : : (gdb) cont
16108 : : and you will arrive at gdbhook when this quad is created. */
16109 : 15260 : LogicalOrTok = NameKey_MakeKey ((const char *) "_LOR", 4);
16110 : 15260 : LogicalAndTok = NameKey_MakeKey ((const char *) "_LAND", 5);
16111 : 15260 : LogicalXorTok = NameKey_MakeKey ((const char *) "_LXOR", 5);
16112 : 15260 : LogicalDifferenceTok = NameKey_MakeKey ((const char *) "_LDIFF", 6);
16113 : 15260 : ArithPlusTok = NameKey_MakeKey ((const char *) "_ARITH_+", 8);
16114 : 15260 : QuadArray = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
16115 : 15260 : FreeList = 1;
16116 : 15260 : NewQuad (&NextQuad);
16117 : 15260 : M2Debug_Assert (NextQuad == 1);
16118 : 15260 : BoolStack = M2StackAddress_InitStackAddress ();
16119 : 15260 : ExitStack = M2StackWord_InitStackWord ();
16120 : 15260 : RepeatStack = M2StackWord_InitStackWord ();
16121 : 15260 : WhileStack = M2StackWord_InitStackWord ();
16122 : 15260 : ForStack = M2StackWord_InitStackWord ();
16123 : 15260 : WithStack = M2StackAddress_InitStackAddress ();
16124 : 15260 : ReturnStack = M2StackWord_InitStackWord ();
16125 : 15260 : LineStack = M2StackAddress_InitStackAddress ();
16126 : 15260 : PriorityStack = M2StackWord_InitStackWord ();
16127 : 15260 : TryStack = M2StackWord_InitStackWord ();
16128 : 15260 : CatchStack = M2StackWord_InitStackWord ();
16129 : 15260 : ExceptStack = M2StackWord_InitStackWord ();
16130 : 15260 : ConstructorStack = M2StackAddress_InitStackAddress ();
16131 : 15260 : ConstParamStack = M2StackWord_InitStackWord ();
16132 : 15260 : ConstExprStack = M2StackWord_InitStackWord ();
16133 : : /* StressStack ; */
16134 : 15260 : SuppressWith = false;
16135 : 15260 : Head = 1;
16136 : 15260 : LastQuadNo = 0;
16137 : 15260 : MustNotCheckBounds = false;
16138 : 15260 : InitQuad = 0;
16139 : 15260 : GrowInitialization = 0;
16140 : 15260 : ForInfo = Indexing_InitIndex (1);
16141 : 15260 : QuadrupleGeneration = true;
16142 : 15260 : BuildingHigh = false;
16143 : 15260 : BuildingSize = false;
16144 : 15260 : AutoStack = M2StackWord_InitStackWord ();
16145 : 15260 : IsAutoOn = true;
16146 : 15260 : InConstExpression = false;
16147 : 15260 : InConstParameters = false;
16148 : 15260 : FreeLineList = NULL;
16149 : 15260 : Lists_InitList (&VarientFields);
16150 : 15260 : VarientFieldNo = 0;
16151 : 15260 : NoOfQuads = 0;
16152 : 15260 : }
16153 : :
16154 : :
16155 : : /*
16156 : : SetOptionCoding - builds a code quadruple if the profiling
16157 : : option was given to the compiler.
16158 : : */
16159 : :
16160 : 0 : extern "C" void M2Quads_SetOptionCoding (bool b)
16161 : : {
16162 : 0 : if (b != M2Options_Coding)
16163 : : {
16164 : 0 : if (b)
16165 : : {
16166 : 0 : M2Quads_BuildCodeOn ();
16167 : : }
16168 : : else
16169 : : {
16170 : 0 : M2Quads_BuildCodeOff ();
16171 : : }
16172 : 0 : M2Options_Coding = b;
16173 : : }
16174 : 0 : }
16175 : :
16176 : :
16177 : : /*
16178 : : SetOptionProfiling - builds a profile quadruple if the profiling
16179 : : option was given to the compiler.
16180 : : */
16181 : :
16182 : 0 : extern "C" void M2Quads_SetOptionProfiling (bool b)
16183 : : {
16184 : 0 : if (b != M2Options_Profiling)
16185 : : {
16186 : 0 : if (b)
16187 : : {
16188 : 0 : M2Quads_BuildProfileOn ();
16189 : : }
16190 : : else
16191 : : {
16192 : 0 : M2Quads_BuildProfileOff ();
16193 : : }
16194 : 0 : M2Options_Profiling = b;
16195 : : }
16196 : 0 : }
16197 : :
16198 : :
16199 : : /*
16200 : : SetOptionOptimizing - builds a quadruple to say that the optimization option
16201 : : has been found in a comment.
16202 : : */
16203 : :
16204 : 0 : extern "C" void M2Quads_SetOptionOptimizing (bool b)
16205 : : {
16206 : 0 : if (b)
16207 : : {
16208 : 0 : M2Quads_BuildOptimizeOn ();
16209 : : }
16210 : : else
16211 : : {
16212 : 0 : M2Quads_BuildOptimizeOff ();
16213 : : }
16214 : 0 : }
16215 : :
16216 : :
16217 : : /*
16218 : : Opposite - returns the opposite comparison operator.
16219 : : */
16220 : :
16221 : 65958 : extern "C" M2Quads_QuadOperator M2Quads_Opposite (M2Quads_QuadOperator Operator)
16222 : : {
16223 : 65958 : M2Quads_QuadOperator Op;
16224 : :
16225 : 65958 : switch (Operator)
16226 : : {
16227 : : case M2Quads_IfNotEquOp:
16228 : : Op = M2Quads_IfEquOp;
16229 : : break;
16230 : :
16231 : : case M2Quads_IfEquOp:
16232 : : Op = M2Quads_IfNotEquOp;
16233 : : break;
16234 : :
16235 : : case M2Quads_IfLessEquOp:
16236 : : Op = M2Quads_IfGreOp;
16237 : : break;
16238 : :
16239 : : case M2Quads_IfGreOp:
16240 : : Op = M2Quads_IfLessEquOp;
16241 : : break;
16242 : :
16243 : : case M2Quads_IfGreEquOp:
16244 : : Op = M2Quads_IfLessOp;
16245 : : break;
16246 : :
16247 : : case M2Quads_IfLessOp:
16248 : : Op = M2Quads_IfGreEquOp;
16249 : : break;
16250 : :
16251 : : case M2Quads_IfInOp:
16252 : : Op = M2Quads_IfNotInOp;
16253 : : break;
16254 : :
16255 : : case M2Quads_IfNotInOp:
16256 : : Op = M2Quads_IfInOp;
16257 : : break;
16258 : :
16259 : :
16260 : 0 : default:
16261 : 0 : M2Error_InternalError ((const char *) "unexpected operator", 19);
16262 : 65958 : break;
16263 : : }
16264 : 65958 : return Op;
16265 : : /* static analysis guarentees a RETURN statement will be used before here. */
16266 : : __builtin_unreachable ();
16267 : : }
16268 : :
16269 : :
16270 : : /*
16271 : : IsReferenced - returns true if QuadNo is referenced by another quadruple.
16272 : : */
16273 : :
16274 : 178463313 : extern "C" bool M2Quads_IsReferenced (unsigned int QuadNo)
16275 : : {
16276 : 178463313 : M2Quads_QuadFrame f;
16277 : :
16278 : 178463313 : f = GetQF (QuadNo);
16279 : 178463313 : return ((f->Operator == M2Quads_ProcedureScopeOp) || (f->Operator == M2Quads_NewLocalVarOp)) || (f->NoOfTimesReferenced > 0);
16280 : : /* static analysis guarentees a RETURN statement will be used before here. */
16281 : : __builtin_unreachable ();
16282 : : }
16283 : :
16284 : :
16285 : : /*
16286 : : IsBackReference - returns TRUE if quadruple, q, is referenced from a quad further on.
16287 : : */
16288 : :
16289 : 7247 : extern "C" bool M2Quads_IsBackReference (unsigned int q)
16290 : : {
16291 : 7247 : unsigned int i;
16292 : 7247 : M2Quads_QuadOperator op;
16293 : 7247 : unsigned int op1;
16294 : 7247 : unsigned int op2;
16295 : 7247 : unsigned int op3;
16296 : :
16297 : 7247 : i = q;
16298 : 27956 : while (i != 0)
16299 : : {
16300 : 27956 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
16301 : 27956 : switch (op)
16302 : : {
16303 : : case M2Quads_NewLocalVarOp:
16304 : : case M2Quads_KillLocalVarOp:
16305 : : case M2Quads_FinallyStartOp:
16306 : : case M2Quads_FinallyEndOp:
16307 : : case M2Quads_InitEndOp:
16308 : : case M2Quads_InitStartOp:
16309 : : case M2Quads_EndFileOp:
16310 : : case M2Quads_StartDefFileOp:
16311 : : case M2Quads_StartModFileOp:
16312 : : return false; /* run into end of procedure or module */
16313 : 708 : break;
16314 : :
16315 : 708 : case M2Quads_GotoOp:
16316 : 708 : case M2Quads_IfEquOp:
16317 : 708 : case M2Quads_IfLessEquOp:
16318 : 708 : case M2Quads_IfGreEquOp:
16319 : 708 : case M2Quads_IfGreOp:
16320 : 708 : case M2Quads_IfLessOp:
16321 : 708 : case M2Quads_IfNotEquOp:
16322 : 708 : case M2Quads_IfInOp:
16323 : 708 : case M2Quads_IfNotInOp:
16324 : 708 : if (op3 == q) /* run into end of procedure or module */
16325 : : {
16326 : : return true;
16327 : : }
16328 : : break;
16329 : :
16330 : :
16331 : : default:
16332 : : break;
16333 : : }
16334 : 20709 : i = M2Quads_GetNextQuad (i);
16335 : : }
16336 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16337 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16338 : : __builtin_unreachable ();
16339 : : }
16340 : :
16341 : :
16342 : : /*
16343 : : IsUnConditional - returns true if QuadNo is an unconditional jump.
16344 : : */
16345 : :
16346 : 327253774 : extern "C" bool M2Quads_IsUnConditional (unsigned int QuadNo)
16347 : : {
16348 : 327253774 : M2Quads_QuadFrame f;
16349 : :
16350 : 327253774 : f = GetQF (QuadNo);
16351 : 327253774 : switch (f->Operator)
16352 : : {
16353 : : case M2Quads_ThrowOp:
16354 : : case M2Quads_RetryOp:
16355 : : case M2Quads_CallOp:
16356 : : case M2Quads_ReturnOp:
16357 : : case M2Quads_GotoOp:
16358 : : return true;
16359 : 311942026 : break;
16360 : :
16361 : :
16362 : 311942026 : default:
16363 : 311942026 : return false;
16364 : : break;
16365 : : }
16366 : : /* static analysis guarentees a RETURN statement will be used before here. */
16367 : : __builtin_unreachable ();
16368 : : }
16369 : :
16370 : :
16371 : : /*
16372 : : IsConditional - returns true if QuadNo is a conditional jump.
16373 : : */
16374 : :
16375 : 327270027 : extern "C" bool M2Quads_IsConditional (unsigned int QuadNo)
16376 : : {
16377 : 327270027 : M2Quads_QuadFrame f;
16378 : :
16379 : 327270027 : f = GetQF (QuadNo);
16380 : 327270027 : switch (f->Operator)
16381 : : {
16382 : : case M2Quads_IfInOp:
16383 : : case M2Quads_IfNotInOp:
16384 : : case M2Quads_IfEquOp:
16385 : : case M2Quads_IfNotEquOp:
16386 : : case M2Quads_IfLessOp:
16387 : : case M2Quads_IfLessEquOp:
16388 : : case M2Quads_IfGreOp:
16389 : : case M2Quads_IfGreEquOp:
16390 : : return true;
16391 : 324240800 : break;
16392 : :
16393 : :
16394 : 324240800 : default:
16395 : 324240800 : return false;
16396 : : break;
16397 : : }
16398 : : /* static analysis guarentees a RETURN statement will be used before here. */
16399 : : __builtin_unreachable ();
16400 : : }
16401 : :
16402 : :
16403 : : /*
16404 : : IsBackReferenceConditional - returns TRUE if quadruple, q, is referenced from
16405 : : a conditional quad further on.
16406 : : */
16407 : :
16408 : 0 : extern "C" bool M2Quads_IsBackReferenceConditional (unsigned int q)
16409 : : {
16410 : 0 : unsigned int i;
16411 : 0 : M2Quads_QuadOperator op;
16412 : 0 : unsigned int op1;
16413 : 0 : unsigned int op2;
16414 : 0 : unsigned int op3;
16415 : :
16416 : 0 : i = q;
16417 : 0 : while (i != 0)
16418 : : {
16419 : 0 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
16420 : 0 : switch (op)
16421 : : {
16422 : : case M2Quads_NewLocalVarOp:
16423 : : case M2Quads_KillLocalVarOp:
16424 : : case M2Quads_FinallyStartOp:
16425 : : case M2Quads_FinallyEndOp:
16426 : : case M2Quads_InitEndOp:
16427 : : case M2Quads_InitStartOp:
16428 : : case M2Quads_EndFileOp:
16429 : : case M2Quads_StartDefFileOp:
16430 : : case M2Quads_StartModFileOp:
16431 : : return false; /* run into end of procedure or module */
16432 : 0 : break;
16433 : :
16434 : 0 : case M2Quads_TryOp:
16435 : 0 : case M2Quads_RetryOp:
16436 : 0 : case M2Quads_GotoOp:
16437 : 0 : case M2Quads_IfEquOp:
16438 : 0 : case M2Quads_IfLessEquOp:
16439 : 0 : case M2Quads_IfGreEquOp:
16440 : 0 : case M2Quads_IfGreOp:
16441 : 0 : case M2Quads_IfLessOp:
16442 : 0 : case M2Quads_IfNotEquOp:
16443 : 0 : case M2Quads_IfInOp:
16444 : 0 : case M2Quads_IfNotInOp:
16445 : 0 : if ((op3 == q) && (M2Quads_IsConditional (q))) /* run into end of procedure or module */
16446 : : {
16447 : : return true;
16448 : : }
16449 : 0 : break;
16450 : :
16451 : :
16452 : : default:
16453 : : return false;
16454 : 0 : break;
16455 : : }
16456 : 0 : i = M2Quads_GetNextQuad (i);
16457 : : }
16458 : 0 : M2Error_InternalError ((const char *) "fix this for the sake of efficiency..", 37);
16459 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Quads.def", 20, 1);
16460 : : __builtin_unreachable ();
16461 : : }
16462 : :
16463 : :
16464 : : /*
16465 : : IsGoto - returns true if QuadNo is a goto operation.
16466 : : */
16467 : :
16468 : 7247 : extern "C" bool M2Quads_IsGoto (unsigned int QuadNo)
16469 : : {
16470 : 7247 : return IsQuadA (QuadNo, M2Quads_GotoOp);
16471 : : /* static analysis guarentees a RETURN statement will be used before here. */
16472 : : __builtin_unreachable ();
16473 : : }
16474 : :
16475 : :
16476 : : /*
16477 : : IsCall - returns true if QuadNo is a call operation.
16478 : : */
16479 : :
16480 : 327261021 : extern "C" bool M2Quads_IsCall (unsigned int QuadNo)
16481 : : {
16482 : 327261021 : return IsQuadA (QuadNo, M2Quads_CallOp);
16483 : : /* static analysis guarentees a RETURN statement will be used before here. */
16484 : : __builtin_unreachable ();
16485 : : }
16486 : :
16487 : :
16488 : : /*
16489 : : IsReturn - returns true if QuadNo is a return operation.
16490 : : */
16491 : :
16492 : 327361301 : extern "C" bool M2Quads_IsReturn (unsigned int QuadNo)
16493 : : {
16494 : 327361301 : return IsQuadA (QuadNo, M2Quads_ReturnOp);
16495 : : /* static analysis guarentees a RETURN statement will be used before here. */
16496 : : __builtin_unreachable ();
16497 : : }
16498 : :
16499 : :
16500 : : /*
16501 : : IsProcedureScope - returns true if QuadNo is a ProcedureScope operation.
16502 : : */
16503 : :
16504 : 0 : extern "C" bool M2Quads_IsProcedureScope (unsigned int QuadNo)
16505 : : {
16506 : 0 : return IsQuadA (QuadNo, M2Quads_ProcedureScopeOp);
16507 : : /* static analysis guarentees a RETURN statement will be used before here. */
16508 : : __builtin_unreachable ();
16509 : : }
16510 : :
16511 : :
16512 : : /*
16513 : : IsNewLocalVar - returns true if QuadNo is a NewLocalVar operation.
16514 : : */
16515 : :
16516 : 0 : extern "C" bool M2Quads_IsNewLocalVar (unsigned int QuadNo)
16517 : : {
16518 : 0 : return IsQuadA (QuadNo, M2Quads_NewLocalVarOp);
16519 : : /* static analysis guarentees a RETURN statement will be used before here. */
16520 : : __builtin_unreachable ();
16521 : : }
16522 : :
16523 : :
16524 : : /*
16525 : : IsKillLocalVar - returns true if QuadNo is a KillLocalVar operation.
16526 : : */
16527 : :
16528 : 103307 : extern "C" bool M2Quads_IsKillLocalVar (unsigned int QuadNo)
16529 : : {
16530 : 103307 : return IsQuadA (QuadNo, M2Quads_KillLocalVarOp);
16531 : : /* static analysis guarentees a RETURN statement will be used before here. */
16532 : : __builtin_unreachable ();
16533 : : }
16534 : :
16535 : :
16536 : : /*
16537 : : IsCatchBegin - returns true if QuadNo is a catch begin quad.
16538 : : */
16539 : :
16540 : 78724 : extern "C" bool M2Quads_IsCatchBegin (unsigned int QuadNo)
16541 : : {
16542 : 78724 : return IsQuadA (QuadNo, M2Quads_CatchBeginOp);
16543 : : /* static analysis guarentees a RETURN statement will be used before here. */
16544 : : __builtin_unreachable ();
16545 : : }
16546 : :
16547 : :
16548 : : /*
16549 : : IsCatchEnd - returns true if QuadNo is a catch end quad.
16550 : : */
16551 : :
16552 : 91840 : extern "C" bool M2Quads_IsCatchEnd (unsigned int QuadNo)
16553 : : {
16554 : 91840 : return IsQuadA (QuadNo, M2Quads_CatchEndOp);
16555 : : /* static analysis guarentees a RETURN statement will be used before here. */
16556 : : __builtin_unreachable ();
16557 : : }
16558 : :
16559 : :
16560 : : /*
16561 : : IsInitStart - returns true if QuadNo is a init start quad.
16562 : : */
16563 : :
16564 : 78724 : extern "C" bool M2Quads_IsInitStart (unsigned int QuadNo)
16565 : : {
16566 : 78724 : return IsQuadA (QuadNo, M2Quads_InitStartOp);
16567 : : /* static analysis guarentees a RETURN statement will be used before here. */
16568 : : __builtin_unreachable ();
16569 : : }
16570 : :
16571 : :
16572 : : /*
16573 : : IsInitEnd - returns true if QuadNo is a init end quad.
16574 : : */
16575 : :
16576 : 78724 : extern "C" bool M2Quads_IsInitEnd (unsigned int QuadNo)
16577 : : {
16578 : 78724 : return IsQuadA (QuadNo, M2Quads_InitEndOp);
16579 : : /* static analysis guarentees a RETURN statement will be used before here. */
16580 : : __builtin_unreachable ();
16581 : : }
16582 : :
16583 : :
16584 : : /*
16585 : : IsFinallyStart - returns true if QuadNo is a finally start quad.
16586 : : */
16587 : :
16588 : 74386 : extern "C" bool M2Quads_IsFinallyStart (unsigned int QuadNo)
16589 : : {
16590 : 74386 : return IsQuadA (QuadNo, M2Quads_FinallyStartOp);
16591 : : /* static analysis guarentees a RETURN statement will be used before here. */
16592 : : __builtin_unreachable ();
16593 : : }
16594 : :
16595 : :
16596 : : /*
16597 : : IsFinallyEnd - returns true if QuadNo is a finally end quad.
16598 : : */
16599 : :
16600 : 70048 : extern "C" bool M2Quads_IsFinallyEnd (unsigned int QuadNo)
16601 : : {
16602 : 70048 : return IsQuadA (QuadNo, M2Quads_FinallyEndOp);
16603 : : /* static analysis guarentees a RETURN statement will be used before here. */
16604 : : __builtin_unreachable ();
16605 : : }
16606 : :
16607 : :
16608 : : /*
16609 : : IsBecomes - return TRUE if QuadNo is a BecomesOp.
16610 : : */
16611 : :
16612 : 0 : extern "C" bool M2Quads_IsBecomes (unsigned int QuadNo)
16613 : : {
16614 : 0 : return IsQuadA (QuadNo, M2Quads_BecomesOp);
16615 : : /* static analysis guarentees a RETURN statement will be used before here. */
16616 : : __builtin_unreachable ();
16617 : : }
16618 : :
16619 : :
16620 : : /*
16621 : : IsDummy - return TRUE if QuadNo is a DummyOp.
16622 : : */
16623 : :
16624 : 0 : extern "C" bool M2Quads_IsDummy (unsigned int QuadNo)
16625 : : {
16626 : 0 : return IsQuadA (QuadNo, M2Quads_DummyOp);
16627 : : /* static analysis guarentees a RETURN statement will be used before here. */
16628 : : __builtin_unreachable ();
16629 : : }
16630 : :
16631 : :
16632 : : /*
16633 : : IsQuadConstExpr - returns TRUE if QuadNo is part of a constant expression.
16634 : : */
16635 : :
16636 : 0 : extern "C" bool M2Quads_IsQuadConstExpr (unsigned int QuadNo)
16637 : : {
16638 : 0 : M2Quads_QuadFrame f;
16639 : :
16640 : 0 : f = GetQF (QuadNo);
16641 : 0 : return f->ConstExpr;
16642 : : /* static analysis guarentees a RETURN statement will be used before here. */
16643 : : __builtin_unreachable ();
16644 : : }
16645 : :
16646 : :
16647 : : /*
16648 : : SetQuadConstExpr - sets the constexpr field to value.
16649 : : */
16650 : :
16651 : 0 : extern "C" void M2Quads_SetQuadConstExpr (unsigned int QuadNo, bool value)
16652 : : {
16653 : 0 : M2Quads_QuadFrame f;
16654 : :
16655 : 0 : f = GetQF (QuadNo);
16656 : 0 : f->ConstExpr = value;
16657 : 0 : }
16658 : :
16659 : :
16660 : : /*
16661 : : GetQuadDest - returns the jump destination associated with quad.
16662 : : */
16663 : :
16664 : 0 : extern "C" unsigned int M2Quads_GetQuadDest (unsigned int QuadNo)
16665 : : {
16666 : 0 : return M2Quads_GetQuadOp3 (QuadNo);
16667 : : /* static analysis guarentees a RETURN statement will be used before here. */
16668 : : __builtin_unreachable ();
16669 : : }
16670 : :
16671 : :
16672 : : /*
16673 : : GetQuadOp1 - returns the 1st operand associated with quad.
16674 : : */
16675 : :
16676 : 0 : extern "C" unsigned int M2Quads_GetQuadOp1 (unsigned int QuadNo)
16677 : : {
16678 : 0 : M2Quads_QuadFrame f;
16679 : :
16680 : 0 : f = GetQF (QuadNo);
16681 : 0 : return f->Operand1;
16682 : : /* static analysis guarentees a RETURN statement will be used before here. */
16683 : : __builtin_unreachable ();
16684 : : }
16685 : :
16686 : :
16687 : : /*
16688 : : GetQuadOp2 - returns the 2nd operand associated with quad.
16689 : : */
16690 : :
16691 : 0 : extern "C" unsigned int M2Quads_GetQuadOp2 (unsigned int QuadNo)
16692 : : {
16693 : 0 : M2Quads_QuadFrame f;
16694 : :
16695 : 0 : f = GetQF (QuadNo);
16696 : 0 : return f->Operand2;
16697 : : /* static analysis guarentees a RETURN statement will be used before here. */
16698 : : __builtin_unreachable ();
16699 : : }
16700 : :
16701 : :
16702 : : /*
16703 : : GetQuadOp3 - returns the 3rd operand associated with quad.
16704 : : */
16705 : :
16706 : 0 : extern "C" unsigned int M2Quads_GetQuadOp3 (unsigned int QuadNo)
16707 : : {
16708 : 0 : M2Quads_QuadFrame f;
16709 : :
16710 : 0 : f = GetQF (QuadNo);
16711 : 0 : return f->Operand3;
16712 : : /* static analysis guarentees a RETURN statement will be used before here. */
16713 : : __builtin_unreachable ();
16714 : : }
16715 : :
16716 : :
16717 : : /*
16718 : : IsInitialisingConst - returns TRUE if the quadruple is setting
16719 : : a const (op1) with a value.
16720 : : */
16721 : :
16722 : 0 : extern "C" bool M2Quads_IsInitialisingConst (unsigned int QuadNo)
16723 : : {
16724 : 0 : M2Quads_QuadOperator op;
16725 : 0 : unsigned int op1;
16726 : 0 : unsigned int op2;
16727 : 0 : unsigned int op3;
16728 : :
16729 : 0 : M2Quads_GetQuad (QuadNo, &op, &op1, &op2, &op3);
16730 : 0 : return (OpUsesOp1 (op)) && (SymbolTable_IsConst (op1));
16731 : : /* static analysis guarentees a RETURN statement will be used before here. */
16732 : : __builtin_unreachable ();
16733 : : }
16734 : :
16735 : :
16736 : : /*
16737 : : IsConstQuad - return TRUE if the quadruple is marked as a constexpr.
16738 : : */
16739 : :
16740 : 0 : extern "C" bool M2Quads_IsConstQuad (unsigned int quad)
16741 : : {
16742 : 0 : M2Quads_QuadFrame f;
16743 : :
16744 : 0 : f = GetQF (quad);
16745 : 0 : return f->ConstExpr;
16746 : : /* static analysis guarentees a RETURN statement will be used before here. */
16747 : : __builtin_unreachable ();
16748 : : }
16749 : :
16750 : :
16751 : : /*
16752 : : IsConditionalBooleanQuad - return TRUE if operand 1 is a boolean result.
16753 : : */
16754 : :
16755 : 318370 : extern "C" bool M2Quads_IsConditionalBooleanQuad (unsigned int quad)
16756 : : {
16757 : 318370 : M2Quads_QuadFrame f;
16758 : :
16759 : 318370 : f = GetQF (quad);
16760 : 318370 : return ((OpUsesOp1 (f->Operator)) && ((SymbolTable_IsVar (f->Operand1)) || (SymbolTable_IsConst (f->Operand1)))) && (SymbolTable_IsVarConditional (f->Operand1));
16761 : : /* static analysis guarentees a RETURN statement will be used before here. */
16762 : : __builtin_unreachable ();
16763 : : }
16764 : :
16765 : :
16766 : : /*
16767 : : IsOptimizeOn - returns true if the Optimize flag was true at QuadNo.
16768 : : */
16769 : :
16770 : 0 : extern "C" bool M2Quads_IsOptimizeOn (unsigned int QuadNo)
16771 : : {
16772 : 0 : M2Quads_QuadFrame f;
16773 : 0 : unsigned int n;
16774 : 0 : unsigned int q;
16775 : 0 : bool On;
16776 : :
16777 : 0 : On = M2Options_Optimizing;
16778 : 0 : q = Head;
16779 : 0 : while ((q != 0) && (q != QuadNo))
16780 : : {
16781 : 0 : f = GetQF (q);
16782 : 0 : if (f->Operator == M2Quads_OptimizeOnOp)
16783 : : {
16784 : : On = true;
16785 : : }
16786 : 0 : else if (f->Operator == M2Quads_OptimizeOffOp)
16787 : : {
16788 : : /* avoid dangling else. */
16789 : 0 : On = false;
16790 : : }
16791 : 0 : n = f->Next;
16792 : 0 : q = n;
16793 : : }
16794 : 0 : return On;
16795 : : /* static analysis guarentees a RETURN statement will be used before here. */
16796 : : __builtin_unreachable ();
16797 : : }
16798 : :
16799 : :
16800 : : /*
16801 : : IsProfileOn - returns true if the Profile flag was true at QuadNo.
16802 : : */
16803 : :
16804 : 0 : extern "C" bool M2Quads_IsProfileOn (unsigned int QuadNo)
16805 : : {
16806 : 0 : M2Quads_QuadFrame f;
16807 : 0 : unsigned int n;
16808 : 0 : unsigned int q;
16809 : 0 : bool On;
16810 : :
16811 : 0 : On = M2Options_Profiling;
16812 : 0 : q = Head;
16813 : 0 : while ((q != 0) && (q != QuadNo))
16814 : : {
16815 : 0 : f = GetQF (q);
16816 : 0 : if (f->Operator == M2Quads_ProfileOnOp)
16817 : : {
16818 : : On = true;
16819 : : }
16820 : 0 : else if (f->Operator == M2Quads_ProfileOffOp)
16821 : : {
16822 : : /* avoid dangling else. */
16823 : 0 : On = false;
16824 : : }
16825 : 0 : n = f->Next;
16826 : 0 : q = n;
16827 : : }
16828 : 0 : return On;
16829 : : /* static analysis guarentees a RETURN statement will be used before here. */
16830 : : __builtin_unreachable ();
16831 : : }
16832 : :
16833 : :
16834 : : /*
16835 : : IsCodeOn - returns true if the Code flag was true at QuadNo.
16836 : : */
16837 : :
16838 : 0 : extern "C" bool M2Quads_IsCodeOn (unsigned int QuadNo)
16839 : : {
16840 : 0 : M2Quads_QuadFrame f;
16841 : 0 : unsigned int n;
16842 : 0 : unsigned int q;
16843 : 0 : bool On;
16844 : :
16845 : 0 : On = M2Options_Coding;
16846 : 0 : q = Head;
16847 : 0 : while ((q != 0) && (q != QuadNo))
16848 : : {
16849 : 0 : f = GetQF (q);
16850 : 0 : if (f->Operator == M2Quads_CodeOnOp)
16851 : : {
16852 : : On = true;
16853 : : }
16854 : 0 : else if (f->Operator == M2Quads_CodeOffOp)
16855 : : {
16856 : : /* avoid dangling else. */
16857 : 0 : On = false;
16858 : : }
16859 : 0 : n = f->Next;
16860 : 0 : q = n;
16861 : : }
16862 : 0 : return On;
16863 : : /* static analysis guarentees a RETURN statement will be used before here. */
16864 : : __builtin_unreachable ();
16865 : : }
16866 : :
16867 : :
16868 : : /*
16869 : : IsPseudoQuad - returns true if QuadNo is a compiler directive.
16870 : : ie code, profile and optimize.
16871 : : StartFile, EndFile,
16872 : : */
16873 : :
16874 : 19389039 : extern "C" bool M2Quads_IsPseudoQuad (unsigned int QuadNo)
16875 : : {
16876 : 19389039 : M2Quads_QuadFrame f;
16877 : :
16878 : 19389039 : f = GetQF (QuadNo);
16879 : 19389039 : 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);
16880 : : /* static analysis guarentees a RETURN statement will be used before here. */
16881 : : __builtin_unreachable ();
16882 : : }
16883 : :
16884 : :
16885 : : /*
16886 : : IsDefOrModFile - returns TRUE if QuadNo is a start of Module or Def file
16887 : : directive.
16888 : : */
16889 : :
16890 : 327253774 : extern "C" bool M2Quads_IsDefOrModFile (unsigned int QuadNo)
16891 : : {
16892 : 327253774 : M2Quads_QuadFrame f;
16893 : :
16894 : 327253774 : f = GetQF (QuadNo);
16895 : 327253774 : return (f->Operator == M2Quads_StartDefFileOp) || (f->Operator == M2Quads_StartModFileOp);
16896 : : /* static analysis guarentees a RETURN statement will be used before here. */
16897 : : __builtin_unreachable ();
16898 : : }
16899 : :
16900 : :
16901 : : /*
16902 : : DumpQuadruples - dump all quadruples providing the -fq, -fdump-lang-quad,
16903 : : -fdump-lang-quad= or -fdump-lang-all were issued to the
16904 : : command line.
16905 : : */
16906 : :
16907 : 71357 : extern "C" void M2Quads_DumpQuadruples (const char *title_, unsigned int _title_high)
16908 : : {
16909 : 71357 : char title[_title_high+1];
16910 : :
16911 : : /* make a local copy of each unbounded array. */
16912 : 71357 : memcpy (title, title_, _title_high+1);
16913 : :
16914 : 71357 : if (M2Options_GetDumpQuad ())
16915 : : {
16916 : 0 : M2LangDump_CreateDumpQuad ((const char *) title, _title_high);
16917 : 0 : if ((M2Options_GetM2DumpFilter ()) == NULL)
16918 : : {
16919 : 0 : DumpQuadrupleAll ();
16920 : : }
16921 : : else
16922 : : {
16923 : 0 : DumpQuadrupleFilter ();
16924 : : }
16925 : 0 : M2LangDump_CloseDumpQuad ();
16926 : : }
16927 : 71357 : }
16928 : :
16929 : :
16930 : : /*
16931 : : DisplayQuadRange - displays all quads in list range, start..end.
16932 : : */
16933 : :
16934 : 0 : extern "C" void M2Quads_DisplayQuadRange (unsigned int scope, unsigned int start, unsigned int end)
16935 : : {
16936 : 0 : M2Quads_QuadFrame f;
16937 : :
16938 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "Quadruples for scope: %d\\n", 26, (const unsigned char *) &scope, (sizeof (scope)-1));
16939 : 0 : while ((start <= end) && (start != 0))
16940 : : {
16941 : 0 : M2Quads_DisplayQuad (start);
16942 : 0 : f = GetQF (start);
16943 : 0 : start = f->Next;
16944 : : }
16945 : 0 : }
16946 : :
16947 : :
16948 : : /*
16949 : : DisplayQuad - displays a quadruple, QuadNo.
16950 : : */
16951 : :
16952 : 0 : extern "C" void M2Quads_DisplayQuad (unsigned int QuadNo)
16953 : : {
16954 : 0 : DSdbEnter ();
16955 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%4d ", 5, (const unsigned char *) &QuadNo, (sizeof (QuadNo)-1));
16956 : 0 : WriteQuad (QuadNo);
16957 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
16958 : 0 : DSdbExit ();
16959 : 0 : }
16960 : :
16961 : :
16962 : : /*
16963 : : GetLastFileQuad - returns the Quadruple number of the last StartDefFile or
16964 : : StartModFile quadruple.
16965 : : */
16966 : :
16967 : 0 : extern "C" unsigned int M2Quads_GetLastFileQuad (unsigned int QuadNo)
16968 : : {
16969 : 0 : M2Quads_QuadFrame f;
16970 : 0 : unsigned int q;
16971 : 0 : unsigned int i;
16972 : 0 : unsigned int FileQuad;
16973 : :
16974 : 0 : q = Head;
16975 : 0 : FileQuad = 0;
16976 : 0 : do {
16977 : 0 : f = GetQF (q);
16978 : 0 : if ((f->Operator == M2Quads_StartModFileOp) || (f->Operator == M2Quads_StartDefFileOp))
16979 : : {
16980 : 0 : FileQuad = q;
16981 : : }
16982 : 0 : i = f->Next;
16983 : 0 : q = i;
16984 : 0 : } while (! ((i == QuadNo) || (i == 0)));
16985 : 0 : M2Debug_Assert (i != 0);
16986 : 0 : M2Debug_Assert (FileQuad != 0);
16987 : 0 : return FileQuad;
16988 : : /* static analysis guarentees a RETURN statement will be used before here. */
16989 : : __builtin_unreachable ();
16990 : : }
16991 : :
16992 : :
16993 : : /*
16994 : : GetLastQuadNo - returns the last quadruple number referenced
16995 : : by a GetQuad.
16996 : : */
16997 : :
16998 : 0 : extern "C" unsigned int M2Quads_GetLastQuadNo (void)
16999 : : {
17000 : 0 : return LastQuadNo;
17001 : : /* static analysis guarentees a RETURN statement will be used before here. */
17002 : : __builtin_unreachable ();
17003 : : }
17004 : :
17005 : :
17006 : : /*
17007 : : QuadToTokenNo - Converts a QuadNo into the approprate token number of the
17008 : : source file, the line number is returned.
17009 : :
17010 : : This may be used to yield an idea where abouts in the
17011 : : source file the code generetion is
17012 : : processing.
17013 : : */
17014 : :
17015 : 5930493 : extern "C" unsigned int M2Quads_QuadToTokenNo (unsigned int QuadNo)
17016 : : {
17017 : 5930493 : M2Quads_QuadFrame f;
17018 : :
17019 : 5930493 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
17020 : : {
17021 : 0 : return 0;
17022 : : }
17023 : : else
17024 : : {
17025 : 5930493 : f = GetQF (QuadNo);
17026 : 5930493 : return f->TokenNo;
17027 : : }
17028 : : /* static analysis guarentees a RETURN statement will be used before here. */
17029 : : __builtin_unreachable ();
17030 : : }
17031 : :
17032 : :
17033 : : /*
17034 : : QuadToLineNo - Converts a QuadNo into the approprate line number of the
17035 : : source file, the line number is returned.
17036 : :
17037 : : This may be used to yield an idea where abouts in the
17038 : : source file the code generetion is
17039 : : processing.
17040 : : */
17041 : :
17042 : 0 : extern "C" unsigned int M2Quads_QuadToLineNo (unsigned int QuadNo)
17043 : : {
17044 : 0 : M2Quads_QuadFrame f;
17045 : :
17046 : 0 : if ((((LastQuadNo == 0) && (! (M2Pass_IsNoPass ()))) && (! (M2Pass_IsPassCodeGeneration ()))) || (! (Indexing_InBounds (QuadArray, QuadNo))))
17047 : : {
17048 : 0 : return 0;
17049 : : }
17050 : : else
17051 : : {
17052 : 0 : f = GetQF (QuadNo);
17053 : 0 : return f->LineNo;
17054 : : }
17055 : : /* static analysis guarentees a RETURN statement will be used before here. */
17056 : : __builtin_unreachable ();
17057 : : }
17058 : :
17059 : :
17060 : : /*
17061 : : GetQuad - returns the Quadruple QuadNo.
17062 : : */
17063 : :
17064 : 876047632 : extern "C" void M2Quads_GetQuad (unsigned int QuadNo, M2Quads_QuadOperator *Op, unsigned int *Oper1, unsigned int *Oper2, unsigned int *Oper3)
17065 : : {
17066 : 876047632 : M2Quads_QuadFrame f;
17067 : :
17068 : 876047632 : f = GetQF (QuadNo);
17069 : 876047632 : LastQuadNo = QuadNo;
17070 : 876047632 : (*Op) = f->Operator;
17071 : 876047632 : (*Oper1) = f->Operand1;
17072 : 876047632 : (*Oper2) = f->Operand2;
17073 : 876047632 : (*Oper3) = f->Operand3;
17074 : 876047632 : }
17075 : :
17076 : :
17077 : : /*
17078 : : GetQuadOp - returns the operator for quad.
17079 : : */
17080 : :
17081 : 24 : extern "C" M2Quads_QuadOperator M2Quads_GetQuadOp (unsigned int quad)
17082 : : {
17083 : 24 : M2Quads_QuadFrame f;
17084 : :
17085 : 24 : f = GetQF (quad);
17086 : 24 : return f->Operator;
17087 : : /* static analysis guarentees a RETURN statement will be used before here. */
17088 : : __builtin_unreachable ();
17089 : : }
17090 : :
17091 : :
17092 : : /*
17093 : : GetM2OperatorDesc - returns the Modula-2 string associated with the quad operator
17094 : : (if possible). It returns NIL if no there is not an obvious match
17095 : : in Modula-2. It is assummed that the string will be used during
17096 : : construction of error messages and therefore keywords are
17097 : : wrapped with a format specifier.
17098 : : */
17099 : :
17100 : 31 : extern "C" DynamicStrings_String M2Quads_GetM2OperatorDesc (M2Quads_QuadOperator op)
17101 : : {
17102 : 31 : switch (op)
17103 : : {
17104 : 6 : case M2Quads_NegateOp:
17105 : 6 : return DynamicStrings_InitString ((const char *) "-", 1);
17106 : 18 : break;
17107 : :
17108 : 18 : case M2Quads_AddOp:
17109 : 18 : return DynamicStrings_InitString ((const char *) "+", 1);
17110 : 0 : break;
17111 : :
17112 : 0 : case M2Quads_SubOp:
17113 : 0 : return DynamicStrings_InitString ((const char *) "-", 1);
17114 : 0 : break;
17115 : :
17116 : 0 : case M2Quads_MultOp:
17117 : 0 : return DynamicStrings_InitString ((const char *) "*", 1);
17118 : 0 : break;
17119 : :
17120 : 0 : case M2Quads_DivM2Op:
17121 : 0 : case M2Quads_DivCeilOp:
17122 : 0 : case M2Quads_DivFloorOp:
17123 : 0 : case M2Quads_DivTruncOp:
17124 : 0 : return DynamicStrings_InitString ((const char *) "{%kDIV}", 7);
17125 : 0 : break;
17126 : :
17127 : 0 : case M2Quads_ModM2Op:
17128 : 0 : case M2Quads_ModCeilOp:
17129 : 0 : case M2Quads_ModFloorOp:
17130 : 0 : return DynamicStrings_InitString ((const char *) "{%kMOD}", 7);
17131 : 0 : break;
17132 : :
17133 : 0 : case M2Quads_ModTruncOp:
17134 : 0 : return DynamicStrings_InitString ((const char *) "{%kREM}", 7);
17135 : 0 : break;
17136 : :
17137 : 0 : case M2Quads_LogicalOrOp:
17138 : 0 : return DynamicStrings_InitString ((const char *) "{%kOR}", 6);
17139 : 0 : break;
17140 : :
17141 : 0 : case M2Quads_LogicalAndOp:
17142 : 0 : return DynamicStrings_InitString ((const char *) "{%kAND}", 7);
17143 : 0 : break;
17144 : :
17145 : 0 : case M2Quads_InclOp:
17146 : 0 : return DynamicStrings_InitString ((const char *) "{%kINCL}", 8);
17147 : 0 : break;
17148 : :
17149 : 0 : case M2Quads_ExclOp:
17150 : 0 : return DynamicStrings_InitString ((const char *) "{%kEXCL}", 8);
17151 : 7 : break;
17152 : :
17153 : 7 : case M2Quads_IfEquOp:
17154 : 7 : return DynamicStrings_InitString ((const char *) "=", 1);
17155 : 0 : break;
17156 : :
17157 : 0 : case M2Quads_IfLessEquOp:
17158 : 0 : return DynamicStrings_InitString ((const char *) "<=", 2);
17159 : 0 : break;
17160 : :
17161 : 0 : case M2Quads_IfGreEquOp:
17162 : 0 : return DynamicStrings_InitString ((const char *) ">=", 2);
17163 : 0 : break;
17164 : :
17165 : 0 : case M2Quads_IfGreOp:
17166 : 0 : return DynamicStrings_InitString ((const char *) ">", 1);
17167 : 0 : break;
17168 : :
17169 : 0 : case M2Quads_IfLessOp:
17170 : 0 : return DynamicStrings_InitString ((const char *) "<", 1);
17171 : 0 : break;
17172 : :
17173 : 0 : case M2Quads_IfNotEquOp:
17174 : 0 : return DynamicStrings_InitString ((const char *) "#", 1);
17175 : 0 : break;
17176 : :
17177 : 0 : case M2Quads_IfInOp:
17178 : 0 : return DynamicStrings_InitString ((const char *) "IN", 2);
17179 : 0 : break;
17180 : :
17181 : 0 : case M2Quads_IfNotInOp:
17182 : 0 : return DynamicStrings_InitString ((const char *) "NOT IN", 6);
17183 : : break;
17184 : :
17185 : :
17186 : : default:
17187 : : return static_cast<DynamicStrings_String> (NULL);
17188 : : break;
17189 : : }
17190 : : /* static analysis guarentees a RETURN statement will be used before here. */
17191 : : __builtin_unreachable ();
17192 : : }
17193 : :
17194 : :
17195 : : /*
17196 : : GetQuadtok - returns the Quadruple QuadNo.
17197 : : */
17198 : :
17199 : 106988258 : 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)
17200 : : {
17201 : 106988258 : M2Quads_QuadFrame f;
17202 : :
17203 : 106988258 : f = GetQF (QuadNo);
17204 : 106988258 : LastQuadNo = QuadNo;
17205 : 106988258 : (*Op) = f->Operator;
17206 : 106988258 : (*Oper1) = f->Operand1;
17207 : 106988258 : (*Oper2) = f->Operand2;
17208 : 106988258 : (*Oper3) = f->Operand3;
17209 : 106988258 : (*Op1Pos) = f->op1pos;
17210 : 106988258 : (*Op2Pos) = f->op2pos;
17211 : 106988258 : (*Op3Pos) = f->op3pos;
17212 : 106988258 : }
17213 : :
17214 : :
17215 : : /*
17216 : : GetQuadOtok - returns the Quadruple QuadNo.
17217 : : */
17218 : :
17219 : 5117753 : 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)
17220 : : {
17221 : 5117753 : M2Quads_QuadFrame f;
17222 : :
17223 : 5117753 : f = GetQF (QuadNo);
17224 : 5117753 : LastQuadNo = QuadNo;
17225 : 5117753 : (*Op) = f->Operator;
17226 : 5117753 : (*Oper1) = f->Operand1;
17227 : 5117753 : (*Oper2) = f->Operand2;
17228 : 5117753 : (*Oper3) = f->Operand3;
17229 : 5117753 : (*Op1Pos) = f->op1pos;
17230 : 5117753 : (*Op2Pos) = f->op2pos;
17231 : 5117753 : (*Op3Pos) = f->op3pos;
17232 : 5117753 : (*tok) = f->TokenNo;
17233 : 5117753 : (*overflowChecking) = f->CheckOverflow;
17234 : 5117753 : (*constExpr) = f->ConstExpr;
17235 : 5117753 : }
17236 : :
17237 : :
17238 : : /*
17239 : : GetQuadOTypetok - returns the fields associated with quadruple QuadNo.
17240 : : */
17241 : :
17242 : 4920 : 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)
17243 : : {
17244 : 4920 : M2Quads_QuadFrame f;
17245 : :
17246 : 4920 : f = GetQF (QuadNo);
17247 : 4920 : LastQuadNo = QuadNo;
17248 : 4920 : (*Op) = f->Operator;
17249 : 4920 : (*Oper1) = f->Operand1;
17250 : 4920 : (*Oper2) = f->Operand2;
17251 : 4920 : (*Oper3) = f->Operand3;
17252 : 4920 : (*Op1Pos) = f->op1pos;
17253 : 4920 : (*Op2Pos) = f->op2pos;
17254 : 4920 : (*Op3Pos) = f->op3pos;
17255 : 4920 : (*tok) = f->TokenNo;
17256 : 4920 : (*overflowChecking) = f->CheckOverflow;
17257 : 4920 : (*typeChecking) = f->CheckType;
17258 : 4920 : (*constExpr) = f->ConstExpr;
17259 : 4920 : }
17260 : :
17261 : :
17262 : : /*
17263 : : PutQuadOtok - alters a quadruple QuadNo with Op, Oper1, Oper2, Oper3, and
17264 : : sets a boolean to determinine whether overflow should be checked.
17265 : : */
17266 : :
17267 : 65951 : 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)
17268 : : {
17269 : 65951 : M2Quads_QuadFrame f;
17270 : :
17271 : 65951 : if (QuadrupleGeneration)
17272 : : {
17273 : 65951 : M2Quads_EraseQuad (QuadNo);
17274 : 65951 : AddQuadInformation (QuadNo, Op, Oper1, Oper2, Oper3);
17275 : 65951 : f = GetQF (QuadNo);
17276 : 65951 : f->Operator = Op;
17277 : 65951 : f->Operand1 = Oper1;
17278 : 65951 : f->Operand2 = Oper2;
17279 : 65951 : f->Operand3 = Oper3;
17280 : 65951 : f->CheckOverflow = overflowChecking;
17281 : 65951 : f->op1pos = Op1Pos;
17282 : 65951 : f->op2pos = Op2Pos;
17283 : 65951 : f->op3pos = Op3Pos;
17284 : 65951 : f->TokenNo = tok;
17285 : 65951 : f->ConstExpr = constExpr;
17286 : : }
17287 : 65951 : }
17288 : :
17289 : :
17290 : : /*
17291 : : PutQuad - overwrites a quadruple QuadNo with Op, Oper1, Oper2, Oper3
17292 : : */
17293 : :
17294 : 11205 : extern "C" void M2Quads_PutQuad (unsigned int QuadNo, M2Quads_QuadOperator Op, unsigned int Oper1, unsigned int Oper2, unsigned int Oper3)
17295 : : {
17296 : 11205 : PutQuadO (QuadNo, Op, Oper1, Oper2, Oper3, true);
17297 : 11205 : }
17298 : :
17299 : :
17300 : : /*
17301 : : GetFirstQuad - returns the first quadruple.
17302 : : */
17303 : :
17304 : 608361 : extern "C" unsigned int M2Quads_GetFirstQuad (void)
17305 : : {
17306 : 608361 : return Head;
17307 : : /* static analysis guarentees a RETURN statement will be used before here. */
17308 : : __builtin_unreachable ();
17309 : : }
17310 : :
17311 : :
17312 : : /*
17313 : : GetNextQuad - returns the Quadruple number following QuadNo.
17314 : : */
17315 : :
17316 : 1310796711 : extern "C" unsigned int M2Quads_GetNextQuad (unsigned int QuadNo)
17317 : : {
17318 : 1310796711 : M2Quads_QuadFrame f;
17319 : :
17320 : 1310796711 : f = GetQF (QuadNo);
17321 : 1310796711 : return f->Next;
17322 : : /* static analysis guarentees a RETURN statement will be used before here. */
17323 : : __builtin_unreachable ();
17324 : : }
17325 : :
17326 : :
17327 : : /*
17328 : : GetRealQuad - returns the Quadruple number of the real quadruple
17329 : : at QuadNo or beyond.
17330 : : */
17331 : :
17332 : 12964040 : extern "C" unsigned int M2Quads_GetRealQuad (unsigned int QuadNo)
17333 : : {
17334 : 12964040 : M2Quads_QuadFrame f;
17335 : :
17336 : 19352540 : while (QuadNo != 0)
17337 : : {
17338 : 19352540 : if (Indexing_InBounds (QuadArray, QuadNo))
17339 : : {
17340 : 19284421 : f = GetQF (QuadNo);
17341 : 19284421 : if ((((! (M2Quads_IsPseudoQuad (QuadNo))) && (f->Operator != M2Quads_DummyOp)) && (f->Operator != M2Quads_LineNumberOp)) && (f->Operator != M2Quads_StatementNoteOp))
17342 : : {
17343 : : return QuadNo;
17344 : : }
17345 : 6388500 : QuadNo += 1;
17346 : : }
17347 : : else
17348 : : {
17349 : : return 0;
17350 : : }
17351 : : }
17352 : : return 0;
17353 : : /* static analysis guarentees a RETURN statement will be used before here. */
17354 : : __builtin_unreachable ();
17355 : : }
17356 : :
17357 : :
17358 : : /*
17359 : : SubQuad - subtracts a quadruple QuadNo from a list Head.
17360 : : */
17361 : :
17362 : 1568538 : extern "C" void M2Quads_SubQuad (unsigned int QuadNo)
17363 : : {
17364 : 1568538 : unsigned int i;
17365 : 1568538 : M2Quads_QuadFrame f;
17366 : 1568538 : M2Quads_QuadFrame g;
17367 : :
17368 : 1568538 : CheckBreak (QuadNo);
17369 : 1568538 : f = GetQF (QuadNo);
17370 : 1568538 : AlterReference (Head, QuadNo, f->Next);
17371 : 1568538 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
17372 : 1568538 : if (Head == QuadNo)
17373 : : {
17374 : 0 : Head = f->Next;
17375 : : }
17376 : : else
17377 : : {
17378 : 1568538 : i = Head;
17379 : 1568538 : g = GetQF (i);
17380 : 1787154643 : while (g->Next != QuadNo)
17381 : : {
17382 : 1784017567 : i = g->Next;
17383 : 1784017567 : g = GetQF (i);
17384 : : }
17385 : 1568538 : g->Next = f->Next;
17386 : : }
17387 : 1568538 : f->Operator = M2Quads_DummyOp;
17388 : 1568538 : NoOfQuads -= 1;
17389 : 1568538 : }
17390 : :
17391 : :
17392 : : /*
17393 : : EraseQuad - erases a quadruple QuadNo, the quadruple is still in the list
17394 : : but wiped clean.
17395 : : */
17396 : :
17397 : 5317580 : extern "C" void M2Quads_EraseQuad (unsigned int QuadNo)
17398 : : {
17399 : 5317580 : M2Quads_QuadFrame f;
17400 : :
17401 : 5317580 : CheckBreak (QuadNo);
17402 : 5317580 : f = GetQF (QuadNo);
17403 : 5317580 : UndoReadWriteInfo (QuadNo, f->Operator, f->Operand1, f->Operand2, f->Operand3);
17404 : 5317580 : f->Operator = M2Quads_DummyOp; /* finally blank it out */
17405 : 5317580 : f->Operand1 = 0; /* finally blank it out */
17406 : 5317580 : f->Operand2 = 0;
17407 : 5317580 : f->Operand3 = 0;
17408 : 5317580 : f->Trash = 0;
17409 : 5317580 : f->op1pos = M2LexBuf_UnknownTokenNo;
17410 : 5317580 : f->op2pos = M2LexBuf_UnknownTokenNo;
17411 : 5317580 : f->op3pos = M2LexBuf_UnknownTokenNo;
17412 : 5317580 : f->ConstExpr = false;
17413 : 5317580 : }
17414 : :
17415 : :
17416 : : /*
17417 : : CountQuads - returns the number of quadruples.
17418 : : */
17419 : :
17420 : 7245060 : extern "C" unsigned int M2Quads_CountQuads (void)
17421 : : {
17422 : 7245060 : return NoOfQuads;
17423 : : /* static analysis guarentees a RETURN statement will be used before here. */
17424 : : __builtin_unreachable ();
17425 : : }
17426 : :
17427 : :
17428 : : /*
17429 : : BuildScaffold - generate the main, init, finish functions if
17430 : : no -c and this is the application module.
17431 : : */
17432 : :
17433 : 15291 : extern "C" void M2Quads_BuildScaffold (unsigned int tok, unsigned int moduleSym)
17434 : : {
17435 : 15291 : if ((SymbolTable_GetMainModule ()) == moduleSym)
17436 : : {
17437 : 14907 : M2Scaffold_DeclareScaffold (tok);
17438 : 14907 : if (M2Options_ScaffoldMain || ! M2Options_cflag)
17439 : : {
17440 : : /* There are module init/fini functions and
17441 : : application init/fini functions.
17442 : : Here we create the application pair. */
17443 : 2628 : BuildM2LinkFunction (tok);
17444 : 2628 : BuildM2MainFunction (tok);
17445 : 2628 : BuildM2InitFunction (tok, moduleSym); /* Application init. */
17446 : 2628 : BuildM2FiniFunction (tok, moduleSym); /* Application fini. */
17447 : : }
17448 : : /* Application fini. */
17449 : 14907 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17450 : : /* Each module needs a ctor to register the module
17451 : : init/finish/dep with M2RTS. */
17452 : 14907 : BuildM2CtorFunction (tok, moduleSym);
17453 : : }
17454 : 384 : else if (M2Options_WholeProgram)
17455 : : {
17456 : : /* avoid dangling else. */
17457 : 384 : M2Scaffold_DeclareScaffold (tok);
17458 : 384 : BuildM2DepFunction (tok, moduleSym); /* Per module dependency. */
17459 : : /* Each module needs a ctor to register the module
17460 : : init/finish/dep with M2RTS. */
17461 : 384 : BuildM2CtorFunction (tok, moduleSym);
17462 : : }
17463 : 15291 : }
17464 : :
17465 : :
17466 : : /*
17467 : : StartBuildDefFile - generates a StartFileDefOp quadruple indicating the file
17468 : : that has produced the subsequent quadruples.
17469 : : The code generator uses the StartDefFileOp quadruples
17470 : : to relate any error to the appropriate file.
17471 : :
17472 : :
17473 : : Entry Exit
17474 : : ===== ====
17475 : :
17476 : :
17477 : : Ptr -> <- Ptr
17478 : : +------------+ +------------+
17479 : : | ModuleName | | ModuleName |
17480 : : |------------| |------------|
17481 : :
17482 : :
17483 : : Quadruples Produced
17484 : :
17485 : : q StartDefFileOp _ _ ModuleSym
17486 : : */
17487 : :
17488 : 120118 : extern "C" void M2Quads_StartBuildDefFile (unsigned int tok)
17489 : : {
17490 : 120118 : NameKey_Name ModuleName;
17491 : :
17492 : 120118 : M2Quads_PopT (&ModuleName);
17493 : 120118 : M2Quads_PushT (ModuleName);
17494 : 120118 : GenQuadO (tok, M2Quads_StartDefFileOp, tok, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17495 : 120118 : }
17496 : :
17497 : :
17498 : : /*
17499 : : StartBuildModFile - generates a StartModFileOp quadruple indicating the file
17500 : : that has produced the subsequent quadruples.
17501 : : The code generator uses the StartModFileOp quadruples
17502 : : to relate any error to the appropriate file.
17503 : :
17504 : :
17505 : : Entry Exit
17506 : : ===== ====
17507 : :
17508 : :
17509 : : Ptr -> <- Ptr
17510 : : +------------+ +------------+
17511 : : | ModuleName | | ModuleName |
17512 : : |------------| |------------|
17513 : :
17514 : :
17515 : : Quadruples Produced
17516 : :
17517 : : q StartModFileOp lineno filename ModuleSym
17518 : : */
17519 : :
17520 : 65509 : extern "C" void M2Quads_StartBuildModFile (unsigned int tok)
17521 : : {
17522 : 65509 : GenQuadO (tok, M2Quads_StartModFileOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetFileModule (), false);
17523 : 65509 : }
17524 : :
17525 : :
17526 : : /*
17527 : : EndBuildFile - generates an EndFileOp quadruple indicating the file
17528 : : that has produced the previous quadruples has ended.
17529 : :
17530 : : Entry Exit
17531 : : ===== ====
17532 : :
17533 : :
17534 : : Ptr -> <- Ptr
17535 : : +------------+ +------------+
17536 : : | ModuleName | | ModuleName |
17537 : : |------------| |------------|
17538 : :
17539 : :
17540 : : Quadruples Produced
17541 : :
17542 : : q EndFileOp _ _ ModuleSym
17543 : : */
17544 : :
17545 : 185422 : extern "C" void M2Quads_EndBuildFile (unsigned int tok)
17546 : : {
17547 : 185422 : NameKey_Name ModuleName;
17548 : :
17549 : 185422 : ModuleName = static_cast<NameKey_Name> (M2Quads_OperandT (1));
17550 : 185422 : GenQuadO (tok, M2Quads_EndFileOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_GetModule (ModuleName), false);
17551 : 185422 : }
17552 : :
17553 : :
17554 : : /*
17555 : : StartBuildInit - Sets the start of initialization code of the
17556 : : current module to the next quadruple.
17557 : : */
17558 : :
17559 : 65869 : extern "C" void M2Quads_StartBuildInit (unsigned int tok)
17560 : : {
17561 : 65869 : NameKey_Name name;
17562 : 65869 : unsigned int ModuleSym;
17563 : :
17564 : 65869 : M2Quads_PopT (&name);
17565 : 65869 : ModuleSym = SymbolTable_GetCurrentModule ();
17566 : 131738 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17567 : 65869 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17568 : 65863 : SymbolTable_PutModuleStartQuad (ModuleSym, NextQuad);
17569 : 65863 : GenQuad (M2Quads_InitStartOp, tok, SymbolTable_GetFileModule (), ModuleSym);
17570 : 65863 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17571 : 65863 : M2Quads_PushT (name);
17572 : 65863 : CheckVariablesAt (ModuleSym);
17573 : 65863 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17574 : 65863 : M2StackWord_PushWord (TryStack, NextQuad);
17575 : 65863 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17576 : 65863 : if (SymbolTable_HasExceptionBlock (ModuleSym))
17577 : : {
17578 : 54 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
17579 : : }
17580 : 65863 : }
17581 : :
17582 : :
17583 : : /*
17584 : : EndBuildInit - Sets the end initialization code of a module.
17585 : : */
17586 : :
17587 : 65724 : extern "C" void M2Quads_EndBuildInit (unsigned int tok)
17588 : : {
17589 : 65724 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17590 : : {
17591 : 54 : BuildRTExceptLeave (tok, true);
17592 : 54 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17593 : : }
17594 : 65724 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17595 : 65724 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17596 : 65724 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17597 : 65724 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17598 : 65724 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17599 : 65724 : }
17600 : :
17601 : :
17602 : : /*
17603 : : StartBuildFinally - Sets the start of finalization code of the
17604 : : current module to the next quadruple.
17605 : : */
17606 : :
17607 : 15506 : extern "C" void M2Quads_StartBuildFinally (unsigned int tok)
17608 : : {
17609 : 15506 : NameKey_Name name;
17610 : 15506 : unsigned int ModuleSym;
17611 : :
17612 : 15506 : M2Quads_PopT (&name);
17613 : 15500 : ModuleSym = SymbolTable_GetCurrentModule ();
17614 : 31000 : M2Debug_Assert ((SymbolTable_IsModule (ModuleSym)) || (SymbolTable_IsDefImp (ModuleSym)));
17615 : 15500 : M2Debug_Assert ((SymbolTable_GetSymName (ModuleSym)) == name);
17616 : 15500 : SymbolTable_PutModuleFinallyStartQuad (ModuleSym, NextQuad);
17617 : 15500 : GenQuadO (tok, M2Quads_FinallyStartOp, tok, SymbolTable_GetFileModule (), ModuleSym, false);
17618 : 15500 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17619 : 15500 : M2Quads_PushT (name);
17620 : : /* CheckVariablesAt(ModuleSym) ; */
17621 : 15500 : CheckNeedPriorityBegin (tok, ModuleSym, ModuleSym);
17622 : 15500 : M2StackWord_PushWord (TryStack, NextQuad);
17623 : 15500 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17624 : 15500 : if (SymbolTable_HasExceptionFinally (ModuleSym))
17625 : : {
17626 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17627 : : }
17628 : 15500 : }
17629 : :
17630 : :
17631 : : /*
17632 : : EndBuildFinally - Sets the end finalization code of a module.
17633 : : */
17634 : :
17635 : 15500 : extern "C" void M2Quads_EndBuildFinally (unsigned int tok)
17636 : : {
17637 : 15500 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17638 : : {
17639 : 0 : BuildRTExceptLeave (tok, true);
17640 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17641 : : }
17642 : 15500 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17643 : 15500 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17644 : 15500 : SymbolTable_PutModuleFinallyEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17645 : 15500 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17646 : 15500 : GenQuadO (tok, M2Quads_FinallyEndOp, tok, SymbolTable_GetFileModule (), SymbolTable_GetCurrentModule (), false);
17647 : 15500 : }
17648 : :
17649 : :
17650 : : /*
17651 : : BuildExceptInitial - adds an CatchBeginOp, CatchEndOp quadruple
17652 : : in the current block.
17653 : : */
17654 : :
17655 : 2814 : extern "C" void M2Quads_BuildExceptInitial (unsigned int tok)
17656 : : {
17657 : 2814 : unsigned int previous;
17658 : :
17659 : : /* we have finished the 'try' block, so now goto the return
17660 : : section which will tidy up (any) priorities before returning.
17661 : : */
17662 : 2814 : GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
17663 : 2814 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
17664 : : /*
17665 : : this is the 'catch' block.
17666 : : */
17667 : 2814 : BackPatch (M2StackWord_PeepWord (TryStack, 1), NextQuad);
17668 : 2814 : GenQuadO (tok, M2Quads_CatchBeginOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17669 : 2814 : previous = static_cast<unsigned int> (M2StackWord_PopWord (CatchStack));
17670 : 2814 : if (previous != 0)
17671 : : {
17672 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}only allowed one EXCEPT statement in a procedure or module", 62);
17673 : : }
17674 : 2814 : M2StackWord_PushWord (CatchStack, NextQuad-1);
17675 : 2814 : BuildRTExceptEnter (tok);
17676 : 2814 : }
17677 : :
17678 : :
17679 : : /*
17680 : : BuildExceptFinally - adds an ExceptOp quadruple in a modules
17681 : : finally block.
17682 : : */
17683 : :
17684 : 0 : extern "C" void M2Quads_BuildExceptFinally (unsigned int tok)
17685 : : {
17686 : 0 : M2Quads_BuildExceptInitial (tok);
17687 : 0 : }
17688 : :
17689 : :
17690 : : /*
17691 : : BuildExceptProcedure - adds an ExceptOp quadruple in a procedure
17692 : : block.
17693 : : */
17694 : :
17695 : 168 : extern "C" void M2Quads_BuildExceptProcedure (unsigned int tok)
17696 : : {
17697 : 168 : M2Quads_BuildExceptInitial (tok);
17698 : 168 : }
17699 : :
17700 : :
17701 : : /*
17702 : : BuildRetry - adds an RetryOp quadruple.
17703 : : */
17704 : :
17705 : 168 : extern "C" void M2Quads_BuildRetry (unsigned int tok)
17706 : : {
17707 : 168 : if ((M2StackWord_PeepWord (CatchStack, 1)) == 0)
17708 : : {
17709 : 6 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the {%kRETRY} statement must occur after an {%kEXCEPT} statement in the same module or procedure block", 106);
17710 : : }
17711 : : else
17712 : : {
17713 : 162 : BuildRTExceptLeave (tok, false);
17714 : 162 : GenQuadO (tok, M2Quads_RetryOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PeepWord (TryStack, 1), false);
17715 : : }
17716 : 168 : }
17717 : :
17718 : :
17719 : : /*
17720 : : BuildReThrow - creates a ThrowOp _ _ NulSym, indicating that
17721 : : the exception needs to be rethrown. The stack
17722 : : is unaltered.
17723 : : */
17724 : :
17725 : 222 : extern "C" void M2Quads_BuildReThrow (unsigned int tokenno)
17726 : : {
17727 : 222 : GenQuadO (tokenno, M2Quads_ThrowOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17728 : 222 : }
17729 : :
17730 : :
17731 : : /*
17732 : : StartBuildInnerInit - Sets the start of initialization code of the
17733 : : inner module to the next quadruple.
17734 : : */
17735 : :
17736 : 0 : extern "C" void M2Quads_StartBuildInnerInit (unsigned int tok)
17737 : : {
17738 : 0 : SymbolTable_PutModuleStartQuad (SymbolTable_GetCurrentModule (), NextQuad);
17739 : 0 : GenQuadO (tok, M2Quads_InitStartOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17740 : 0 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
17741 : 0 : CheckNeedPriorityBegin (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17742 : 0 : M2StackWord_PushWord (TryStack, NextQuad);
17743 : 0 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
17744 : 0 : if (SymbolTable_HasExceptionFinally (SymbolTable_GetCurrentModule ()))
17745 : : {
17746 : 0 : GenQuadO (tok, M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false);
17747 : : }
17748 : 0 : }
17749 : :
17750 : :
17751 : : /*
17752 : : EndBuildInnerInit - Sets the end initialization code of a module.
17753 : : */
17754 : :
17755 : 0 : extern "C" void M2Quads_EndBuildInnerInit (unsigned int tok)
17756 : : {
17757 : 0 : if (SymbolTable_HasExceptionBlock (SymbolTable_GetCurrentModule ()))
17758 : : {
17759 : 0 : BuildRTExceptLeave (tok, true);
17760 : 0 : GenQuadO (tok, M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym, false);
17761 : : }
17762 : 0 : SymbolTable_PutModuleEndQuad (SymbolTable_GetCurrentModule (), NextQuad);
17763 : 0 : CheckVariablesInBlock (SymbolTable_GetCurrentModule ());
17764 : 0 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
17765 : 0 : CheckNeedPriorityEnd (tok, SymbolTable_GetCurrentModule (), SymbolTable_GetCurrentModule ());
17766 : 0 : GenQuadO (tok, M2Quads_InitEndOp, tok, SymbolTable_NulSym, SymbolTable_GetCurrentModule (), false);
17767 : 0 : }
17768 : :
17769 : :
17770 : : /*
17771 : : BuildBuiltinConst - makes reference to a builtin constant within gm2.
17772 : :
17773 : : Entry Exit
17774 : :
17775 : : Ptr ->
17776 : : +------------+ +------------+
17777 : : | Ident | | Sym |
17778 : : |------------| |------------|
17779 : :
17780 : : Quadruple produced:
17781 : :
17782 : : q Sym BuiltinConstOp Ident
17783 : : */
17784 : :
17785 : 29390 : extern "C" void M2Quads_BuildBuiltinConst (void)
17786 : : {
17787 : 29390 : unsigned int idtok;
17788 : 29390 : unsigned int Id;
17789 : 29390 : unsigned int Sym;
17790 : :
17791 : 29390 : M2Quads_PopTtok (&Id, &idtok);
17792 : 29390 : Sym = SymbolTable_MakeTemporary (idtok, SymbolTable_ImmediateValue);
17793 : 29390 : SymbolTable_PutVar (Sym, M2Base_Integer);
17794 : : /*
17795 : : CASE GetBuiltinConstType(KeyToCharStar(Name(Id))) OF
17796 : :
17797 : : 0: ErrorFormat1(NewError(GetTokenNo()),
17798 : : '%a unrecognised builtin constant', Id) |
17799 : : 1: PutVar(Sym, Integer) |
17800 : : 2: PutVar(Sym, Real)
17801 : :
17802 : : ELSE
17803 : : InternalError ('unrecognised value')
17804 : : END ;
17805 : : */
17806 : 29390 : GenQuadO (idtok, M2Quads_BuiltinConstOp, Sym, SymbolTable_NulSym, Id, false);
17807 : 29390 : M2Quads_PushTtok (Sym, idtok);
17808 : 29390 : }
17809 : :
17810 : :
17811 : : /*
17812 : : BuildBuiltinTypeInfo - make reference to a builtin typeinfo function
17813 : : within gm2.
17814 : :
17815 : : Entry Exit
17816 : :
17817 : : Ptr ->
17818 : : +-------------+
17819 : : | Type |
17820 : : |-------------| +------------+
17821 : : | Ident | | Sym |
17822 : : |-------------| |------------|
17823 : :
17824 : : Quadruple produced:
17825 : :
17826 : : q Sym BuiltinTypeInfoOp Type Ident
17827 : : */
17828 : :
17829 : 360 : extern "C" void M2Quads_BuildBuiltinTypeInfo (void)
17830 : : {
17831 : 360 : unsigned int idtok;
17832 : 360 : unsigned int Ident;
17833 : 360 : unsigned int Type;
17834 : 360 : unsigned int Sym;
17835 : :
17836 : 360 : M2Quads_PopTtok (&Ident, &idtok);
17837 : 360 : M2Quads_PopT (&Type);
17838 : 360 : Sym = SymbolTable_MakeTemporary (M2LexBuf_BuiltinTokenNo, SymbolTable_ImmediateValue);
17839 : 360 : switch (m2builtins_GetBuiltinTypeInfoType (const_cast <const char * > (static_cast <char * > (NameKey_KeyToCharStar ((NameKey_Name) (Ident))))))
17840 : : {
17841 : 0 : case 0:
17842 : 0 : M2Error_ErrorFormat1 (M2Error_NewError (idtok), (const char *) "%a unrecognised builtin constant", 32, (const unsigned char *) &Ident, (sizeof (Ident)-1));
17843 : 0 : break;
17844 : :
17845 : 192 : case 1:
17846 : 192 : SymbolTable_PutVar (Sym, M2Base_Boolean);
17847 : 192 : break;
17848 : :
17849 : 120 : case 2:
17850 : 120 : SymbolTable_PutVar (Sym, M2Base_ZType);
17851 : 120 : break;
17852 : :
17853 : 48 : case 3:
17854 : 48 : SymbolTable_PutVar (Sym, M2Base_RType);
17855 : 48 : break;
17856 : :
17857 : :
17858 : 0 : default:
17859 : 0 : M2Error_InternalError ((const char *) "unrecognised value", 18);
17860 : 360 : break;
17861 : : }
17862 : 360 : GenQuadO (idtok, M2Quads_BuiltinTypeInfoOp, Sym, Type, Ident, false);
17863 : 360 : M2Quads_PushTtok (Sym, idtok);
17864 : 360 : }
17865 : :
17866 : :
17867 : : /*
17868 : : BuildAssignment - Builds an assignment from the values given on the
17869 : : quad stack. Either an assignment to an
17870 : : arithmetic expression or an assignment to a
17871 : : boolean expression. This procedure should not
17872 : : be called in CONST declarations.
17873 : : The Stack is expected to contain:
17874 : :
17875 : :
17876 : : Either
17877 : :
17878 : : Entry Exit
17879 : : ===== ====
17880 : :
17881 : : Ptr ->
17882 : : +------------+
17883 : : | Expression |
17884 : : |------------|
17885 : : | Designator |
17886 : : |------------| +------------+
17887 : : | | | | <- Ptr
17888 : : |------------| |------------|
17889 : :
17890 : :
17891 : : Quadruples Produced
17892 : :
17893 : : q BecomesOp Designator _ Expression
17894 : :
17895 : : OR
17896 : :
17897 : : Entry Exit
17898 : : ===== ====
17899 : :
17900 : : Ptr ->
17901 : : +------------+
17902 : : | True |False|
17903 : : |------------|
17904 : : | Designator |
17905 : : |------------| +------------+
17906 : : | | | | <- Ptr
17907 : : |------------| |------------|
17908 : :
17909 : :
17910 : : Quadruples Produced
17911 : :
17912 : : q BecomesOp Designator _ TRUE
17913 : : q+1 GotoOp q+3
17914 : : q+2 BecomesOp Designator _ FALSE
17915 : :
17916 : : */
17917 : :
17918 : 106211 : extern "C" void M2Quads_BuildAssignment (unsigned int becomesTokNo)
17919 : : {
17920 : 106211 : unsigned int des;
17921 : 106211 : unsigned int exp;
17922 : 106211 : unsigned int destok;
17923 : 106211 : unsigned int exptok;
17924 : 106211 : unsigned int combinedtok;
17925 : :
17926 : 106211 : des = static_cast<unsigned int> (M2Quads_OperandT (2));
17927 : 106211 : if (IsReadOnly (des))
17928 : : {
17929 : 36 : destok = static_cast<unsigned int> (M2Quads_OperandTok (2));
17930 : 36 : exptok = static_cast<unsigned int> (M2Quads_OperandTok (1));
17931 : 36 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
17932 : 36 : if (DebugTokPos)
17933 : : {
17934 : : M2MetaError_MetaErrorT1 (destok, (const char *) "destok {%1Ead}", 14, des);
17935 : : M2MetaError_MetaErrorT1 (exptok, (const char *) "exptok {%1Ead}", 14, exp);
17936 : : }
17937 : 36 : combinedtok = M2LexBuf_MakeVirtualTok (becomesTokNo, destok, exptok);
17938 : 36 : if (DebugTokPos)
17939 : : {
17940 : : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "combined {%1Ead}", 16, des);
17941 : : }
17942 : 36 : if (IsBoolean (1))
17943 : : {
17944 : 0 : M2MetaError_MetaErrorT1 (combinedtok, (const char *) "cannot assign expression to a constant designator {%1Ead}", 57, des);
17945 : : }
17946 : : else
17947 : : {
17948 : 36 : exp = static_cast<unsigned int> (M2Quads_OperandT (1));
17949 : 36 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "cannot assign a constant designator {%1Ead} with an expression {%2Ead}", 70, des, exp);
17950 : : }
17951 : 36 : M2Quads_PopN (2); /* Remove both parameters. */
17952 : : }
17953 : 106175 : else if (SymbolTable_IsError (des))
17954 : : {
17955 : : /* avoid dangling else. */
17956 : 25 : M2Quads_PopN (2); /* Remove both parameters. */
17957 : : }
17958 : : else
17959 : : {
17960 : : /* avoid dangling else. */
17961 : 106150 : doBuildAssignment (becomesTokNo, true, true);
17962 : : }
17963 : 106205 : }
17964 : :
17965 : :
17966 : : /*
17967 : : BuildAssignConstant - used to create constant in the CONST declaration.
17968 : : The stack is expected to contain:
17969 : :
17970 : : Either
17971 : :
17972 : : Entry Exit
17973 : : ===== ====
17974 : :
17975 : : Ptr ->
17976 : : +------------+
17977 : : | Expression |
17978 : : |------------|
17979 : : | Designator |
17980 : : |------------| +------------+
17981 : : | | | | <- Ptr
17982 : : |------------| |------------|
17983 : :
17984 : :
17985 : : Quadruples Produced
17986 : :
17987 : : q BecomesOp Designator _ Expression
17988 : :
17989 : : OR
17990 : :
17991 : : Entry Exit
17992 : : ===== ====
17993 : :
17994 : : Ptr ->
17995 : : +------------+
17996 : : | True |False|
17997 : : |------------|
17998 : : | Designator |
17999 : : |------------| +------------+
18000 : : | | | | <- Ptr
18001 : : |------------| |------------|
18002 : :
18003 : :
18004 : : Quadruples Produced
18005 : :
18006 : : q BecomesOp Designator _ TRUE
18007 : : q+1 GotoOp q+3
18008 : : q+2 BecomesOp Designator _ FALSE
18009 : : */
18010 : :
18011 : 246470 : extern "C" void M2Quads_BuildAssignConstant (unsigned int equalsTokNo)
18012 : : {
18013 : 246470 : doBuildAssignment (equalsTokNo, true, true);
18014 : 246470 : }
18015 : :
18016 : :
18017 : : /*
18018 : : BuildAlignment - builds an assignment to an alignment constant.
18019 : :
18020 : : The Stack is expected to contain:
18021 : :
18022 : :
18023 : : Entry Exit
18024 : : ===== ====
18025 : :
18026 : : Ptr ->
18027 : : +---------------+
18028 : : | Expression |
18029 : : |---------------|
18030 : : | bytealignment |
18031 : : |---------------| empty
18032 : : */
18033 : :
18034 : 72 : extern "C" void M2Quads_BuildAlignment (unsigned int tokno)
18035 : : {
18036 : 72 : NameKey_Name name;
18037 : 72 : unsigned int expr;
18038 : 72 : unsigned int align;
18039 : :
18040 : 72 : M2Quads_PopT (&expr);
18041 : 72 : M2Quads_PopT (&name);
18042 : 72 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
18043 : : {
18044 : 0 : M2MetaError_MetaError1 ((const char *) "expecting bytealignment identifier, rather than {%1Ea}", 54, SymbolTable_MakeError (tokno, name));
18045 : : }
18046 : 72 : FifoQueue_GetConstFromFifoQueue (&align);
18047 : 72 : M2Quads_PushT (align);
18048 : 72 : M2Quads_PushT (expr);
18049 : 72 : M2Quads_BuildAssignConstant (tokno);
18050 : 72 : }
18051 : :
18052 : :
18053 : : /*
18054 : : BuildBitLength - builds an assignment to a bit length constant.
18055 : :
18056 : : The Stack is expected to contain:
18057 : :
18058 : :
18059 : : Entry Exit
18060 : : ===== ====
18061 : :
18062 : : Ptr ->
18063 : : +------------+
18064 : : | Expression |
18065 : : |------------| empty
18066 : : */
18067 : :
18068 : 0 : extern "C" void M2Quads_BuildBitLength (unsigned int tokno)
18069 : : {
18070 : 0 : unsigned int expr;
18071 : 0 : unsigned int length;
18072 : :
18073 : 0 : M2Quads_PopT (&expr);
18074 : 0 : FifoQueue_GetConstFromFifoQueue (&length);
18075 : 0 : M2Quads_PushT (length);
18076 : 0 : M2Quads_PushT (expr);
18077 : 0 : M2Quads_BuildAssignConstant (tokno);
18078 : 0 : }
18079 : :
18080 : :
18081 : : /*
18082 : : BuildPragmaField - builds an assignment to an alignment constant.
18083 : :
18084 : : The Stack is expected to contain:
18085 : :
18086 : :
18087 : : Entry Exit
18088 : : ===== ====
18089 : :
18090 : : Ptr ->
18091 : : +------------+
18092 : : | Expression |
18093 : : |------------| empty
18094 : : */
18095 : :
18096 : 12 : extern "C" void M2Quads_BuildPragmaField (void)
18097 : : {
18098 : 12 : unsigned int expr;
18099 : 12 : unsigned int const_;
18100 : 12 : NameKey_Name name;
18101 : :
18102 : 12 : M2Quads_PopT (&expr);
18103 : 12 : M2Quads_PopT (&name);
18104 : 12 : if ((name != (NameKey_MakeKey ((const char *) "unused", 6))) && (name != (NameKey_MakeKey ((const char *) "bytealignment", 13))))
18105 : : {
18106 : 0 : M2MetaError_MetaError0 ((const char *) "only allowed to use the attribute {%Ekbytealignment} in the default record field alignment pragma", 97);
18107 : : }
18108 : 12 : if (expr != SymbolTable_NulSym)
18109 : : {
18110 : 12 : FifoQueue_GetConstFromFifoQueue (&const_);
18111 : 12 : M2Quads_PushT (const_);
18112 : 12 : M2Quads_PushT (expr);
18113 : 12 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
18114 : : }
18115 : 12 : }
18116 : :
18117 : :
18118 : : /*
18119 : : BuildDefaultFieldAlignment - builds an assignment to an alignment constant.
18120 : :
18121 : : The Stack is expected to contain:
18122 : :
18123 : :
18124 : : Entry Exit
18125 : : ===== ====
18126 : :
18127 : : Ptr ->
18128 : : +------------+
18129 : : | Expression |
18130 : : |------------| empty
18131 : : */
18132 : :
18133 : 36 : extern "C" void M2Quads_BuildDefaultFieldAlignment (void)
18134 : : {
18135 : 36 : unsigned int expr;
18136 : 36 : unsigned int align;
18137 : 36 : NameKey_Name name;
18138 : :
18139 : 36 : M2Quads_PopT (&expr);
18140 : 36 : M2Quads_PopT (&name);
18141 : 36 : if (name != (NameKey_MakeKey ((const char *) "bytealignment", 13)))
18142 : : {
18143 : 0 : M2MetaError_MetaError0 ((const char *) "{%E}only allowed to use the attribute {%kbytealignment} in the default record field alignment pragma", 100);
18144 : : }
18145 : 36 : FifoQueue_GetConstFromFifoQueue (&align);
18146 : 36 : M2Quads_PushT (align);
18147 : 36 : M2Quads_PushT (expr);
18148 : 36 : M2Quads_BuildAssignConstant (M2LexBuf_GetTokenNo ());
18149 : 36 : }
18150 : :
18151 : :
18152 : : /*
18153 : : BuildRepeat - Builds the repeat statement from the quad stack.
18154 : : The Stack is expected to contain:
18155 : :
18156 : :
18157 : : Entry Exit
18158 : : ===== ====
18159 : :
18160 : :
18161 : : Empty
18162 : : <- Ptr
18163 : : +------------+
18164 : : | RepeatQuad |
18165 : : |------------|
18166 : :
18167 : : */
18168 : :
18169 : 1274 : extern "C" void M2Quads_BuildRepeat (void)
18170 : : {
18171 : 1274 : M2Quads_PushT (NextQuad);
18172 : 1274 : }
18173 : :
18174 : :
18175 : : /*
18176 : : BuildUntil - Builds the until part of the repeat statement
18177 : : from the quad stack.
18178 : : The Stack is expected to contain:
18179 : :
18180 : :
18181 : : Entry Exit
18182 : : ===== ====
18183 : :
18184 : : Ptr ->
18185 : : +------------+
18186 : : | t | f |
18187 : : |------------|
18188 : : | RepeatQuad | Empty
18189 : : |------------|
18190 : : */
18191 : :
18192 : 1274 : extern "C" void M2Quads_BuildUntil (void)
18193 : : {
18194 : 1274 : unsigned int t;
18195 : 1274 : unsigned int f;
18196 : 1274 : unsigned int Repeat;
18197 : :
18198 : 1274 : CheckBooleanId ();
18199 : 1274 : PopBool (&t, &f);
18200 : 1274 : M2Quads_PopT (&Repeat);
18201 : 1274 : BackPatch (f, Repeat); /* If False then keep on repeating */
18202 : 1274 : BackPatch (t, NextQuad); /* If True then exit repeat */
18203 : 1274 : }
18204 : :
18205 : :
18206 : : /*
18207 : : BuildWhile - Builds the While part of the While statement
18208 : : from the quad stack.
18209 : : The Stack is expected to contain:
18210 : :
18211 : :
18212 : : Entry Exit
18213 : : ===== ====
18214 : :
18215 : : <- Ptr
18216 : : |------------|
18217 : : Empty | WhileQuad |
18218 : : |------------|
18219 : : */
18220 : :
18221 : 6098 : extern "C" void M2Quads_BuildWhile (void)
18222 : : {
18223 : 6098 : M2Quads_PushT (NextQuad);
18224 : 6098 : }
18225 : :
18226 : :
18227 : : /*
18228 : : BuildDoWhile - Builds the Do part of the while statement
18229 : : from the quad stack.
18230 : : The Stack is expected to contain:
18231 : :
18232 : :
18233 : : Entry Exit
18234 : : ===== ====
18235 : :
18236 : : Ptr ->
18237 : : +------------+ +------------+
18238 : : | t | f | | 0 | f |
18239 : : |------------| |------------|
18240 : : | WhileQuad | | WhileQuad |
18241 : : |------------| |------------|
18242 : :
18243 : : Quadruples
18244 : :
18245 : : BackPatch t exit to the NextQuad
18246 : : */
18247 : :
18248 : 6098 : extern "C" void M2Quads_BuildDoWhile (void)
18249 : : {
18250 : 6098 : unsigned int t;
18251 : 6098 : unsigned int f;
18252 : :
18253 : 6098 : CheckBooleanId ();
18254 : 6098 : PopBool (&t, &f);
18255 : 6098 : BackPatch (t, NextQuad);
18256 : 6098 : PushBool (0, f);
18257 : 6098 : }
18258 : :
18259 : :
18260 : : /*
18261 : : BuildEndWhile - Builds the end part of the while statement
18262 : : from the quad stack.
18263 : : The Stack is expected to contain:
18264 : :
18265 : :
18266 : : Entry Exit
18267 : : ===== ====
18268 : :
18269 : : Ptr ->
18270 : : +------------+
18271 : : | t | f |
18272 : : |------------|
18273 : : | WhileQuad | Empty
18274 : : |------------|
18275 : :
18276 : : Quadruples
18277 : :
18278 : : q GotoOp WhileQuad
18279 : : False exit is backpatched with q+1
18280 : : */
18281 : :
18282 : 6098 : extern "C" void M2Quads_BuildEndWhile (int reltokpos)
18283 : : {
18284 : 6098 : unsigned int tok;
18285 : 6098 : unsigned int While;
18286 : 6098 : unsigned int t;
18287 : 6098 : unsigned int f;
18288 : :
18289 : 6098 : tok = M2LexBuf_GetTokenNo ();
18290 : 6098 : tok = ((int ) (tok))+reltokpos;
18291 : 6098 : PopBool (&t, &f);
18292 : 6098 : M2Debug_Assert (t == 0);
18293 : 6098 : M2Quads_PopT (&While);
18294 : 6098 : GenQuadO (tok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, While, false);
18295 : 6098 : BackPatch (f, NextQuad);
18296 : 6098 : }
18297 : :
18298 : :
18299 : : /*
18300 : : BuildLoop - Builds the Loop part of the Loop statement
18301 : : from the quad stack.
18302 : : The Stack is expected to contain:
18303 : :
18304 : :
18305 : : Entry Exit
18306 : : ===== ====
18307 : :
18308 : : <- Ptr
18309 : : Empty +------------+
18310 : : | LoopQuad |
18311 : : |------------|
18312 : : */
18313 : :
18314 : 516 : extern "C" void M2Quads_BuildLoop (void)
18315 : : {
18316 : 516 : M2Quads_PushT (NextQuad);
18317 : 516 : PushExit (0); /* Seperate Exit Stack for loop end */
18318 : 516 : }
18319 : :
18320 : :
18321 : : /*
18322 : : BuildExit - Builds the Exit part of the Loop statement.
18323 : : */
18324 : :
18325 : 94 : extern "C" void M2Quads_BuildExit (void)
18326 : : {
18327 : 94 : if (M2StackWord_IsEmptyWord (ExitStack))
18328 : : {
18329 : 0 : M2MetaError_MetaError0 ((const char *) "{%EkEXIT} is only allowed in a {%kLOOP} statement", 49);
18330 : : }
18331 : : else
18332 : : {
18333 : 94 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18334 : 94 : PushExit (Merge (PopExit (), NextQuad-1));
18335 : : }
18336 : 94 : }
18337 : :
18338 : :
18339 : : /*
18340 : : BuildEndLoop - Builds the End part of the Loop statement
18341 : : from the quad stack.
18342 : : The Stack is expected to contain:
18343 : :
18344 : :
18345 : : Entry Exit
18346 : : ===== ====
18347 : :
18348 : : Ptr ->
18349 : : +------------+
18350 : : | LoopQuad | Empty
18351 : : |------------|
18352 : :
18353 : : Quadruples
18354 : :
18355 : : Goto _ _ LoopQuad
18356 : : */
18357 : :
18358 : 516 : extern "C" void M2Quads_BuildEndLoop (void)
18359 : : {
18360 : 516 : unsigned int Loop;
18361 : :
18362 : 516 : M2Quads_PopT (&Loop);
18363 : 516 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, Loop);
18364 : 516 : BackPatch (PopExit (), NextQuad);
18365 : 516 : }
18366 : :
18367 : :
18368 : : /*
18369 : : BuildThenIf - Builds the Then part of the If statement
18370 : : from the quad stack.
18371 : : The Stack is expected to contain:
18372 : :
18373 : :
18374 : : Entry Exit
18375 : : ===== ====
18376 : :
18377 : : Ptr -> <- Ptr
18378 : : +------------+ +------------+
18379 : : | t | f | | 0 | f |
18380 : : |------------| |------------|
18381 : :
18382 : : Quadruples
18383 : :
18384 : : The true exit is BackPatched to point to
18385 : : the NextQuad.
18386 : : */
18387 : :
18388 : 36067 : extern "C" void M2Quads_BuildThenIf (void)
18389 : : {
18390 : 36067 : unsigned int t;
18391 : 36067 : unsigned int f;
18392 : :
18393 : 36067 : CheckBooleanId ();
18394 : 36067 : PopBool (&t, &f);
18395 : 36067 : BackPatch (t, NextQuad);
18396 : 36067 : PushBool (0, f);
18397 : 36067 : }
18398 : :
18399 : :
18400 : : /*
18401 : : BuildElse - Builds the Else part of the If statement
18402 : : from the quad stack.
18403 : : The Stack is expected to contain:
18404 : :
18405 : :
18406 : : Entry Exit
18407 : : ===== ====
18408 : :
18409 : : Ptr ->
18410 : : +------------+ +------------+
18411 : : | t | f | | t+q | 0 |
18412 : : |------------| |------------|
18413 : :
18414 : : Quadruples
18415 : :
18416 : : q GotoOp _ _ 0
18417 : : q+1 <- BackPatched from f
18418 : : */
18419 : :
18420 : 11864 : extern "C" void M2Quads_BuildElse (void)
18421 : : {
18422 : 11864 : unsigned int t;
18423 : 11864 : unsigned int f;
18424 : :
18425 : 11864 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18426 : 11864 : PopBool (&t, &f);
18427 : 11864 : BackPatch (f, NextQuad);
18428 : 11864 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18429 : 11864 : }
18430 : :
18431 : :
18432 : : /*
18433 : : BuildEndIf - Builds the End part of the If statement
18434 : : from the quad stack.
18435 : : The Stack is expected to contain:
18436 : :
18437 : :
18438 : : Entry Exit
18439 : : ===== ====
18440 : :
18441 : : Ptr ->
18442 : : +------------+
18443 : : | t | f | Empty
18444 : : |------------|
18445 : :
18446 : : Quadruples
18447 : :
18448 : : Both t and f are backpatched to point to the NextQuad
18449 : : */
18450 : :
18451 : 33199 : extern "C" void M2Quads_BuildEndIf (void)
18452 : : {
18453 : 33199 : unsigned int t;
18454 : 33199 : unsigned int f;
18455 : :
18456 : 33199 : PopBool (&t, &f);
18457 : 33199 : BackPatch (t, NextQuad);
18458 : 33199 : BackPatch (f, NextQuad);
18459 : 33199 : }
18460 : :
18461 : :
18462 : : /*
18463 : : BuildElsif1 - Builds the Elsif part of the If statement
18464 : : from the quad stack.
18465 : : The Stack is expected to contain:
18466 : :
18467 : :
18468 : : Entry Exit
18469 : : ===== ====
18470 : :
18471 : : Ptr ->
18472 : : +------------+ +------------+
18473 : : | t | f | | t+q | 0 |
18474 : : |------------| |------------|
18475 : :
18476 : : Quadruples
18477 : :
18478 : : q GotoOp _ _ 0
18479 : : q+1 <- BackPatched from f
18480 : : */
18481 : :
18482 : 2868 : extern "C" void M2Quads_BuildElsif1 (void)
18483 : : {
18484 : 2868 : unsigned int t;
18485 : 2868 : unsigned int f;
18486 : :
18487 : 2868 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18488 : 2868 : PopBool (&t, &f);
18489 : 2868 : BackPatch (f, NextQuad);
18490 : 2868 : PushBool (Merge (t, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18491 : 2868 : }
18492 : :
18493 : :
18494 : : /*
18495 : : BuildElsif2 - Builds the Elsif until part of the If statement
18496 : : from the quad stack.
18497 : : The Stack is expected to contain:
18498 : :
18499 : :
18500 : : Entry Exit
18501 : : ===== ====
18502 : :
18503 : : Ptr ->
18504 : : +--------------+
18505 : : | 0 | f1 | <- Ptr
18506 : : |--------------| +---------------+
18507 : : | t2 | f2 | | t2 | f1+f2 |
18508 : : |--------------| |---------------|
18509 : : */
18510 : :
18511 : 2868 : extern "C" void M2Quads_BuildElsif2 (void)
18512 : : {
18513 : 2868 : unsigned int t1;
18514 : 2868 : unsigned int f1;
18515 : 2868 : unsigned int t2;
18516 : 2868 : unsigned int f2;
18517 : :
18518 : 2868 : PopBool (&t1, &f1);
18519 : 2868 : M2Debug_Assert (t1 == 0);
18520 : 2868 : PopBool (&t2, &f2);
18521 : 2868 : PushBool (t2, Merge (f1, f2));
18522 : 2868 : }
18523 : :
18524 : :
18525 : : /*
18526 : : BuildForToByDo - Builds the For To By Do part of the For statement
18527 : : from the quad stack.
18528 : : The Stack is expected to contain:
18529 : :
18530 : :
18531 : : Entry Exit
18532 : : ===== ====
18533 : :
18534 : : <- Ptr
18535 : : +----------------+
18536 : : Ptr -> | RangeId |
18537 : : +----------------+ |----------------|
18538 : : | BySym | ByType | | ForQuad |
18539 : : |----------------| |----------------|
18540 : : | e2 | | LastValue |
18541 : : |----------------| |----------------|
18542 : : | e1 | | BySym | ByType |
18543 : : |----------------| |----------------|
18544 : : | Ident | | IdentSym |
18545 : : |----------------| |----------------|
18546 : :
18547 : :
18548 : : x := e1 ;
18549 : : Note that LASTVALUE is calculated during M2GenGCC
18550 : : after all the types have been resolved.
18551 : : LASTVALUE := ((e2-e1) DIV BySym) * BySym + e1
18552 : : IF BySym<0
18553 : : THEN
18554 : : IF e1<e2
18555 : : THEN
18556 : : goto exit
18557 : : END
18558 : : ELSE
18559 : : IF e1>e2
18560 : : THEN
18561 : : goto exit
18562 : : END
18563 : : END ;
18564 : : LOOP
18565 : : body
18566 : : IF x=LASTVALUE
18567 : : THEN
18568 : : goto exit
18569 : : END ;
18570 : : INC(x, BySym)
18571 : : END
18572 : :
18573 : : Quadruples:
18574 : :
18575 : : q BecomesOp IdentSym _ e1
18576 : : q+ LastForIteratorOp LastValue := ((e1-e2) DIV by) * by + e1
18577 : : q+1 if >= by 0 q+..2
18578 : : q+2 GotoOp q+3
18579 : : q+3 If >= e1 e2 q+5
18580 : : q+4 GotoOp exit
18581 : : q+5 ..
18582 : : q+..1 Goto q+..5
18583 : : q+..2 If >= e2 e1 q+..4
18584 : : q+..3 GotoOp exit
18585 : : q+..4 ..
18586 : :
18587 : : The For Loop is regarded:
18588 : :
18589 : : For ident := e1 To e2 By by Do
18590 : :
18591 : : End
18592 : : */
18593 : :
18594 : 2110 : extern "C" void M2Quads_BuildForToByDo (void)
18595 : : {
18596 : 2110 : M2Quads_LineNote l1;
18597 : 2110 : M2Quads_LineNote l2;
18598 : 2110 : NameKey_Name e1;
18599 : 2110 : NameKey_Name e2;
18600 : 2110 : NameKey_Name Id;
18601 : 2110 : unsigned int e1tok;
18602 : 2110 : unsigned int e2tok;
18603 : 2110 : unsigned int idtok;
18604 : 2110 : unsigned int bytok;
18605 : 2110 : unsigned int LastIterator;
18606 : 2110 : unsigned int exit1;
18607 : 2110 : unsigned int IdSym;
18608 : 2110 : unsigned int BySym;
18609 : 2110 : unsigned int ByType;
18610 : 2110 : unsigned int ForLoop;
18611 : 2110 : unsigned int RangeId;
18612 : 2110 : unsigned int t;
18613 : 2110 : unsigned int f;
18614 : 2110 : unsigned int etype;
18615 : 2110 : unsigned int t1;
18616 : :
18617 : 2110 : l2 = PopLineNo ();
18618 : 2110 : l1 = PopLineNo ();
18619 : 2110 : UseLineNote (l1);
18620 : 2110 : PushFor (0);
18621 : 2110 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18622 : 2110 : M2Quads_PopTtok (&e2, &e2tok);
18623 : 2110 : M2Quads_PopTtok (&e1, &e1tok);
18624 : 2110 : M2Quads_PopTtok (&Id, &idtok);
18625 : 2110 : IdSym = SymbolTable_RequestSym (idtok, Id);
18626 : 2110 : RangeId = M2Range_InitForLoopBeginRangeCheck (IdSym, idtok, e1, e1tok, e2, e2tok, BySym, bytok);
18627 : 2110 : BuildRange (RangeId);
18628 : 2110 : M2Quads_PushTtok (IdSym, idtok);
18629 : 2110 : M2Quads_PushTtok (e1, e1tok);
18630 : 2110 : BuildAssignmentWithoutBounds (idtok, true, true);
18631 : 2110 : UseLineNote (l2);
18632 : 2688 : LastIterator = SymbolTable_MakeTemporary (e2tok, AreConstant (((SymbolTable_IsConst (e1)) && (SymbolTable_IsConst (e2))) && (SymbolTable_IsConst (BySym))));
18633 : 2110 : SymbolTable_PutVar (LastIterator, SymbolTable_GetSType (IdSym));
18634 : 2110 : etype = M2Base_MixTypes (SymbolTable_GetSType (e1), SymbolTable_GetSType (e2), e2tok);
18635 : 2110 : e1 = doConvert (etype, e1);
18636 : 2110 : e2 = doConvert (etype, e2);
18637 : 2104 : ForLoopLastIterator (LastIterator, e1, e2, BySym, e1tok, e2tok, bytok);
18638 : : /* q+2 GotoOp q+3 */
18639 : 2104 : M2Quads_PushTFtok (BySym, ByType, bytok); /* BuildRelOp 1st parameter. */
18640 : 2104 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter. */
18641 : : /* 3rd parameter. */
18642 : 2104 : PushZero (bytok, ByType);
18643 : 2104 : M2Quads_BuildRelOp (e2tok); /* Choose final expression position. */
18644 : 2104 : PopBool (&t, &f); /* Choose final expression position. */
18645 : 2104 : BackPatch (f, NextQuad);
18646 : : /* q+4 GotoOp Exit */
18647 : 2104 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* BuildRelOp 1st parameter */
18648 : 2104 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18649 : 2104 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* 3rd parameter */
18650 : 2104 : M2Quads_BuildRelOp (e2tok); /* Choose final expression position. */
18651 : 2104 : PopBool (&t1, &exit1); /* Choose final expression position. */
18652 : 2104 : BackPatch (t1, NextQuad);
18653 : 2104 : PushFor (Merge (PopFor (), exit1)); /* Merge exit1. */
18654 : 2104 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0); /* Merge exit1. */
18655 : 2104 : ForLoop = NextQuad-1;
18656 : : /* ELSE. */
18657 : 2104 : BackPatch (t, NextQuad);
18658 : 2104 : M2Quads_PushTFtok (e2, SymbolTable_GetSType (e2), e2tok); /* BuildRelOp 1st parameter */
18659 : 2104 : M2Quads_PushT (M2Reserved_GreaterEqualTok); /* 2nd parameter */
18660 : 2104 : M2Quads_PushTFtok (e1, SymbolTable_GetSType (e1), e1tok); /* 3rd parameter */
18661 : 2104 : M2Quads_BuildRelOp (e2tok); /* 3rd parameter */
18662 : 2104 : PopBool (&t1, &exit1);
18663 : 2104 : BackPatch (t1, NextQuad);
18664 : 2104 : PushFor (Merge (PopFor (), exit1)); /* Merge exit1. */
18665 : 2104 : BackPatch (ForLoop, NextQuad); /* Fixes the start of the for loop. */
18666 : 2104 : ForLoop = NextQuad;
18667 : : /* And set up the stack. */
18668 : 2104 : M2Quads_PushTFtok (IdSym, SymbolTable_GetSym (IdSym), idtok);
18669 : 2104 : M2Quads_PushTFtok (BySym, ByType, bytok);
18670 : 2104 : M2Quads_PushTFtok (LastIterator, SymbolTable_GetSType (LastIterator), e2tok);
18671 : 2104 : M2Quads_PushT (ForLoop);
18672 : 2104 : M2Quads_PushT (RangeId);
18673 : 2104 : }
18674 : :
18675 : :
18676 : : /*
18677 : : BuildPseudoBy - Builds the Non existant part of the By
18678 : : clause of the For statement
18679 : : from the quad stack.
18680 : : The Stack is expected to contain:
18681 : :
18682 : :
18683 : : Entry Exit
18684 : : ===== ====
18685 : :
18686 : : <- Ptr
18687 : : +------------+
18688 : : Ptr -> | BySym | t |
18689 : : +------------+ |------------|
18690 : : | e | t | | e | t |
18691 : : |------------| |------------|
18692 : : */
18693 : :
18694 : 1768 : extern "C" void M2Quads_BuildPseudoBy (void)
18695 : : {
18696 : 1768 : unsigned int expr;
18697 : 1768 : unsigned int type;
18698 : 1768 : unsigned int dotok;
18699 : :
18700 : : /* As there is no BY token this position is the DO at the end of the last expression. */
18701 : 1768 : M2Quads_PopTFtok (&expr, &type, &dotok);
18702 : 1768 : M2Quads_PushTFtok (expr, type, dotok);
18703 : 1768 : if (type == SymbolTable_NulSym)
18704 : : {} /* empty. */
18705 : : /* Use type. */
18706 : 1656 : else if ((SymbolTable_IsEnumeration (SymbolTable_SkipType (type))) || ((SymbolTable_SkipType (type)) == M2Base_Char))
18707 : : {
18708 : : /* avoid dangling else. */
18709 : : }
18710 : 1436 : else if (M2Base_IsOrdinalType (SymbolTable_SkipType (type)))
18711 : : {
18712 : : /* avoid dangling else. */
18713 : 1436 : type = M2Base_ZType;
18714 : : }
18715 : 1768 : PushOne (dotok, type, (const char *) "the implied {%kFOR} loop increment will cause an overflow {%1ad}", 64);
18716 : 1768 : }
18717 : :
18718 : :
18719 : : /*
18720 : : BuildEndFor - Builds the End part of the For statement
18721 : : from the quad stack.
18722 : : The Stack is expected to contain:
18723 : :
18724 : :
18725 : : Entry Exit
18726 : : ===== ====
18727 : :
18728 : : Ptr ->
18729 : : +----------------+
18730 : : | RangeId |
18731 : : |----------------|
18732 : : | ForQuad |
18733 : : |----------------|
18734 : : | LastValue |
18735 : : |----------------|
18736 : : | BySym | ByType |
18737 : : |----------------|
18738 : : | IdSym | Empty
18739 : : |----------------|
18740 : : */
18741 : :
18742 : 2104 : extern "C" void M2Quads_BuildEndFor (unsigned int endpostok)
18743 : : {
18744 : 2104 : unsigned int t;
18745 : 2104 : unsigned int f;
18746 : 2104 : unsigned int tsym;
18747 : 2104 : unsigned int RangeId;
18748 : 2104 : unsigned int IncQuad;
18749 : 2104 : unsigned int ForQuad;
18750 : 2104 : unsigned int LastSym;
18751 : 2104 : unsigned int ByType;
18752 : 2104 : unsigned int BySym;
18753 : 2104 : unsigned int bytok;
18754 : 2104 : unsigned int IdSym;
18755 : 2104 : unsigned int idtok;
18756 : :
18757 : 2104 : M2Quads_PopT (&RangeId);
18758 : 2104 : M2Quads_PopT (&ForQuad);
18759 : 2104 : M2Quads_PopT (&LastSym);
18760 : 2104 : M2Quads_PopTFtok (&BySym, &ByType, &bytok);
18761 : 2104 : M2Quads_PopTtok (&IdSym, &idtok);
18762 : : /* IF IdSym=LastSym THEN exit END */
18763 : 2104 : M2Quads_PushTF (IdSym, SymbolTable_GetSType (IdSym));
18764 : 2104 : M2Quads_PushT (M2Reserved_EqualTok);
18765 : 2104 : M2Quads_PushTF (LastSym, SymbolTable_GetSType (LastSym));
18766 : 2104 : M2Quads_BuildRelOp (endpostok);
18767 : 2104 : PopBool (&t, &f);
18768 : 2104 : BackPatch (t, NextQuad);
18769 : 2104 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18770 : 2104 : PushFor (Merge (PopFor (), NextQuad-1));
18771 : 2104 : BackPatch (f, NextQuad);
18772 : 2104 : if ((SymbolTable_GetMode (IdSym)) == SymbolTable_LeftValue)
18773 : : {
18774 : : /* index variable is a LeftValue, therefore we must dereference it */
18775 : 0 : tsym = SymbolTable_MakeTemporary (idtok, SymbolTable_RightValue);
18776 : 0 : SymbolTable_PutVar (tsym, SymbolTable_GetSType (IdSym));
18777 : 0 : CheckPointerThroughNil (idtok, IdSym);
18778 : 0 : doIndrX (endpostok, tsym, IdSym);
18779 : 0 : BuildRange (M2Range_InitForLoopEndRangeCheck (tsym, BySym)); /* --fixme-- pass endpostok. */
18780 : 0 : IncQuad = NextQuad;
18781 : : /* we have explicitly checked using the above and also
18782 : : this addition can legitimately overflow if a cardinal type
18783 : : is counting down. The above test will generate a more
18784 : : precise error message, so we suppress overflow detection
18785 : : here. */
18786 : 0 : GenQuadOTypetok (bytok, M2Quads_AddOp, tsym, tsym, BySym, false, false, idtok, idtok, bytok);
18787 : 0 : CheckPointerThroughNil (idtok, IdSym);
18788 : 0 : GenQuadOtok (idtok, M2Quads_XIndrOp, IdSym, SymbolTable_GetSType (IdSym), tsym, false, idtok, idtok, idtok);
18789 : : }
18790 : : else
18791 : : {
18792 : 2104 : BuildRange (M2Range_InitForLoopEndRangeCheck (IdSym, BySym));
18793 : 2104 : IncQuad = NextQuad;
18794 : : /* we have explicitly checked using the above and also
18795 : : this addition can legitimately overflow if a cardinal type
18796 : : is counting down. The above test will generate a more
18797 : : precise error message, so we suppress overflow detection
18798 : : here.
18799 : :
18800 : : This quadruple suppresses the generic binary op type
18801 : : check (performed in M2GenGCC.mod) as there
18802 : : will be a more informative/exhaustive check performed by the
18803 : : InitForLoopBeginRangeCheck setup in BuildForToByDo and
18804 : : performed by M2Range.mod. */
18805 : 2104 : GenQuadOTypetok (idtok, M2Quads_AddOp, IdSym, IdSym, BySym, false, false, idtok, idtok, bytok);
18806 : : }
18807 : 2104 : GenQuadO (endpostok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, ForQuad, false);
18808 : 2104 : BackPatch (PopFor (), NextQuad);
18809 : 2104 : AddForInfo (ForQuad, NextQuad-1, IncQuad, IdSym, idtok);
18810 : 2104 : M2Range_PutRangeForIncrement (RangeId, IncQuad);
18811 : 2104 : }
18812 : :
18813 : :
18814 : : /*
18815 : : BuildCaseStart - starts the case statement.
18816 : : It initializes a backpatch list on the compile
18817 : : time stack, the list is used to contain all
18818 : : case break points. The list is later backpatched
18819 : : and contains all positions of the case statement
18820 : : which jump to the end of the case statement.
18821 : : The stack also contains room for a boolean
18822 : : expression, this is needed to allow , operator
18823 : : in the CaseField alternatives.
18824 : :
18825 : : The Stack is expected to contain:
18826 : :
18827 : :
18828 : : Entry Exit
18829 : : ===== ====
18830 : :
18831 : : <- Ptr
18832 : : +------------+
18833 : : | 0 | 0 |
18834 : : |------------|
18835 : : | 0 | 0 |
18836 : : +-------------+ |------------|
18837 : : | Expr | | | Expr | |
18838 : : |-------------| |------------|
18839 : : */
18840 : :
18841 : 606 : extern "C" void M2Quads_BuildCaseStart (void)
18842 : : {
18843 : 606 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (SymbolTable_NulSym, SymbolTable_NulSym, M2Quads_OperandT (1))));
18844 : 606 : PushBool (0, 0); /* BackPatch list initialized */
18845 : 606 : PushBool (0, 0); /* Room for a boolean expression */
18846 : 606 : }
18847 : :
18848 : :
18849 : : /*
18850 : : BuildCaseStartStatementSequence - starts the statement sequence
18851 : : inside a case clause.
18852 : : BackPatches the true exit to the
18853 : : NextQuad.
18854 : : The Stack:
18855 : :
18856 : : Entry Exit
18857 : :
18858 : : Ptr -> <- Ptr
18859 : : +-----------+ +------------+
18860 : : | t | f | | 0 | f |
18861 : : |-----------| |------------|
18862 : : */
18863 : :
18864 : 2852 : extern "C" void M2Quads_BuildCaseStartStatementSequence (void)
18865 : : {
18866 : 2852 : unsigned int t;
18867 : 2852 : unsigned int f;
18868 : :
18869 : 2852 : PopBool (&t, &f);
18870 : 2852 : BackPatch (t, NextQuad);
18871 : 2852 : PushBool (0, f);
18872 : 2852 : }
18873 : :
18874 : :
18875 : : /*
18876 : : BuildCaseEndStatementSequence - ends the statement sequence
18877 : : inside a case clause.
18878 : : BackPatches the false exit f1 to the
18879 : : NextQuad.
18880 : : Asserts that t1 and f2 is 0
18881 : : Pushes t2+q and 0
18882 : :
18883 : : Quadruples:
18884 : :
18885 : : q GotoOp _ _ 0
18886 : :
18887 : : The Stack:
18888 : :
18889 : : Entry Exit
18890 : :
18891 : : Ptr -> <- Ptr
18892 : : +-----------+ +------------+
18893 : : | t1 | f1 | | 0 | 0 |
18894 : : |-----------| |------------|
18895 : : | t2 | f2 | | t2+q | 0 |
18896 : : |-----------| |------------|
18897 : : */
18898 : :
18899 : 2852 : extern "C" void M2Quads_BuildCaseEndStatementSequence (void)
18900 : : {
18901 : 2852 : unsigned int t1;
18902 : 2852 : unsigned int f1;
18903 : 2852 : unsigned int t2;
18904 : 2852 : unsigned int f2;
18905 : :
18906 : 2852 : GenQuad (M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
18907 : 2852 : PopBool (&t1, &f1);
18908 : 2852 : PopBool (&t2, &f2); /* t2 contains the break list for the case */
18909 : 2852 : BackPatch (f1, NextQuad); /* f1 no longer needed */
18910 : 2852 : M2Debug_Assert (t1 == 0); /* f1 no longer needed */
18911 : 2852 : M2Debug_Assert (f2 == 0);
18912 : 2852 : PushBool (Merge (t2, NextQuad-1), 0); /* NextQuad-1 = Goto Quad */
18913 : 2852 : PushBool (0, 0); /* Room for boolean expression */
18914 : 2852 : }
18915 : :
18916 : :
18917 : : /*
18918 : : BuildCaseRange - builds the range testing quaruples for
18919 : : a case clause.
18920 : :
18921 : : IF (e1>=ce1) AND (e1<=ce2)
18922 : : THEN
18923 : :
18924 : : ELS..
18925 : :
18926 : : The Stack:
18927 : :
18928 : : Entry Exit
18929 : :
18930 : : Ptr ->
18931 : : +-----------+
18932 : : | ce2 | <- Ptr
18933 : : |-----------| +-----------+
18934 : : | ce1 | | t | f |
18935 : : |-----------| |-----------|
18936 : : | t1 | f1 | | t1 | f1 |
18937 : : |-----------| |-----------|
18938 : : | t2 | f2 | | t2 | f2 |
18939 : : |-----------| |-----------|
18940 : : | e1 | | e1 |
18941 : : |-----------| |-----------|
18942 : : */
18943 : :
18944 : 172 : extern "C" void M2Quads_BuildCaseRange (void)
18945 : : {
18946 : 172 : unsigned int ce1;
18947 : 172 : unsigned int ce2;
18948 : 172 : unsigned int combinedtok;
18949 : 172 : unsigned int ce1tok;
18950 : 172 : unsigned int ce2tok;
18951 : 172 : unsigned int e1tok;
18952 : 172 : unsigned int e1;
18953 : 172 : unsigned int t2;
18954 : 172 : unsigned int f2;
18955 : 172 : unsigned int t1;
18956 : 172 : unsigned int f1;
18957 : :
18958 : 172 : M2Quads_PopTtok (&ce2, &ce2tok);
18959 : 172 : M2Quads_PopTtok (&ce1, &ce1tok);
18960 : 172 : combinedtok = M2LexBuf_MakeVirtualTok (ce2tok, ce2tok, ce1tok);
18961 : 172 : M2CaseList_AddRange (ce1, ce2, combinedtok);
18962 : 172 : PopBool (&t1, &f1);
18963 : 172 : PopBool (&t2, &f2);
18964 : 172 : M2Quads_PopTtok (&e1, &e1tok);
18965 : 172 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
18966 : 172 : PushBool (t2, f2); /* leave e1 on bottom of stack when exit procedure */
18967 : 172 : PushBool (t1, f1); /* also leave t1 and f1 on the bottom of the stack */
18968 : 172 : M2Quads_PushTtok (e1, e1tok); /* also leave t1 and f1 on the bottom of the stack */
18969 : 172 : M2Quads_PushT (M2Reserved_GreaterEqualTok);
18970 : 172 : M2Quads_PushTtok (ce1, ce1tok);
18971 : 172 : M2Quads_BuildRelOp (combinedtok);
18972 : 172 : M2Quads_PushT (M2Reserved_AndTok);
18973 : 172 : M2Quads_RecordOp ();
18974 : 172 : M2Quads_PushTtok (e1, e1tok);
18975 : 172 : M2Quads_PushT (M2Reserved_LessEqualTok);
18976 : 172 : M2Quads_PushTtok (ce2, ce2tok);
18977 : 172 : M2Quads_BuildRelOp (combinedtok);
18978 : 172 : M2Quads_BuildBinaryOp ();
18979 : 172 : }
18980 : :
18981 : :
18982 : : /*
18983 : : BuildCaseEquality - builds the range testing quadruples for
18984 : : a case clause.
18985 : :
18986 : : IF e1=ce1
18987 : : THEN
18988 : :
18989 : : ELS..
18990 : :
18991 : : The Stack:
18992 : :
18993 : : Entry Exit
18994 : :
18995 : : Ptr ->
18996 : : +-----------+ +-----------+
18997 : : | ce1 | | t | f |
18998 : : |-----------| |-----------|
18999 : : | t1 | f1 | | t1 | f1 |
19000 : : |-----------| |-----------|
19001 : : | t2 | f2 | | t2 | f2 |
19002 : : |-----------| |-----------|
19003 : : | e1 | | e1 |
19004 : : |-----------| |-----------|
19005 : : */
19006 : :
19007 : 2730 : extern "C" void M2Quads_BuildCaseEquality (void)
19008 : : {
19009 : 2730 : unsigned int ce1tok;
19010 : 2730 : unsigned int e1tok;
19011 : 2730 : unsigned int ce1;
19012 : 2730 : unsigned int e1;
19013 : 2730 : unsigned int t2;
19014 : 2730 : unsigned int f2;
19015 : 2730 : unsigned int t1;
19016 : 2730 : unsigned int f1;
19017 : :
19018 : 2730 : M2Quads_PopTtok (&ce1, &ce1tok);
19019 : 2730 : M2CaseList_AddRange (ce1, SymbolTable_NulSym, ce1tok);
19020 : 2730 : PopBool (&t1, &f1);
19021 : 2730 : PopBool (&t2, &f2);
19022 : 2730 : M2Quads_PopTtok (&e1, &e1tok);
19023 : 2730 : M2Quads_PushTtok (e1, e1tok); /* leave e1 on bottom of stack when exit procedure */
19024 : 2730 : PushBool (t2, f2); /* also leave t2 and f2 on the bottom of the stack */
19025 : 2730 : PushBool (t1, f1); /* also leave t2 and f2 on the bottom of the stack */
19026 : 2730 : M2Quads_PushTtok (e1, e1tok);
19027 : 2730 : M2Quads_PushT (M2Reserved_EqualTok);
19028 : 2730 : M2Quads_PushTtok (ce1, ce1tok);
19029 : 2730 : M2Quads_BuildRelOp (ce1tok);
19030 : 2730 : }
19031 : :
19032 : :
19033 : : /*
19034 : : BuildCaseList - merges two case tests into one
19035 : :
19036 : : The Stack:
19037 : :
19038 : : Entry Exit
19039 : :
19040 : : Ptr ->
19041 : : +-----------+
19042 : : | t2 | f2 |
19043 : : |-----------| +-------------+
19044 : : | t1 | f1 | | t1+t2| f1+f2|
19045 : : |-----------| |-------------|
19046 : : */
19047 : :
19048 : 2902 : extern "C" void M2Quads_BuildCaseList (void)
19049 : : {
19050 : 2902 : unsigned int t2;
19051 : 2902 : unsigned int f2;
19052 : 2902 : unsigned int t1;
19053 : 2902 : unsigned int f1;
19054 : :
19055 : 2902 : PopBool (&t2, &f2);
19056 : 2902 : PopBool (&t1, &f1);
19057 : 2902 : PushBool (Merge (t1, t2), Merge (f1, f2));
19058 : 2902 : }
19059 : :
19060 : :
19061 : : /*
19062 : : BuildCaseOr - builds the , in the case clause.
19063 : :
19064 : : The Stack:
19065 : :
19066 : : Entry Exit
19067 : :
19068 : : Ptr -> <- Ptr
19069 : : +-----------+ +------------+
19070 : : | t | f | | t | 0 |
19071 : : |-----------| |------------|
19072 : : */
19073 : :
19074 : 50 : extern "C" void M2Quads_BuildCaseOr (void)
19075 : : {
19076 : 50 : unsigned int t;
19077 : 50 : unsigned int f;
19078 : :
19079 : 50 : PopBool (&t, &f);
19080 : 50 : BackPatch (f, NextQuad);
19081 : 50 : PushBool (t, 0);
19082 : 50 : }
19083 : :
19084 : :
19085 : : /*
19086 : : BuildCaseElse - builds the else of case clause.
19087 : :
19088 : : The Stack:
19089 : :
19090 : : Entry Exit
19091 : :
19092 : : Ptr -> <- Ptr
19093 : : +-----------+ +------------+
19094 : : | t | f | | t | 0 |
19095 : : |-----------| |------------|
19096 : : */
19097 : :
19098 : 606 : extern "C" void M2Quads_BuildCaseElse (void)
19099 : : {
19100 : 606 : unsigned int t;
19101 : 606 : unsigned int f;
19102 : :
19103 : 606 : PopBool (&t, &f);
19104 : 606 : BackPatch (f, NextQuad);
19105 : 606 : PushBool (t, 0);
19106 : 606 : }
19107 : :
19108 : :
19109 : : /*
19110 : : BuildCaseEnd - builds the end of case clause.
19111 : :
19112 : : The Stack:
19113 : :
19114 : : Entry Exit
19115 : :
19116 : : Ptr ->
19117 : : +-----------+
19118 : : | t1 | f1 |
19119 : : |-----------|
19120 : : | t2 | f2 |
19121 : : |-----------|
19122 : : | e1 |
19123 : : |-----------| Empty
19124 : : */
19125 : :
19126 : 606 : extern "C" void M2Quads_BuildCaseEnd (void)
19127 : : {
19128 : 606 : unsigned int e1;
19129 : 606 : unsigned int t;
19130 : 606 : unsigned int f;
19131 : :
19132 : 606 : PopBool (&t, &f);
19133 : 606 : BackPatch (f, NextQuad);
19134 : 606 : BackPatch (t, NextQuad);
19135 : 606 : PopBool (&t, &f);
19136 : 606 : BackPatch (f, NextQuad);
19137 : 606 : BackPatch (t, NextQuad);
19138 : 606 : M2Quads_PopT (&e1);
19139 : 606 : M2CaseList_PopCase ();
19140 : 606 : }
19141 : :
19142 : :
19143 : : /*
19144 : : BuildCaseCheck - builds the case checking code to ensure that
19145 : : the program does not need an else clause at runtime.
19146 : : The stack is unaltered.
19147 : : */
19148 : :
19149 : 342 : extern "C" void M2Quads_BuildCaseCheck (void)
19150 : : {
19151 : 342 : BuildError (M2Range_InitNoElseRangeCheck ());
19152 : 342 : }
19153 : :
19154 : :
19155 : : /*
19156 : : BuildNulParam - Builds a nul parameter on the stack.
19157 : : The Stack:
19158 : :
19159 : : Entry Exit
19160 : :
19161 : : <- Ptr
19162 : : Empty +------------+
19163 : : | 0 |
19164 : : |------------|
19165 : : */
19166 : :
19167 : 16945 : extern "C" void M2Quads_BuildNulParam (void)
19168 : : {
19169 : 16945 : M2Quads_PushT (static_cast<unsigned int> (0));
19170 : 16945 : }
19171 : :
19172 : :
19173 : : /*
19174 : : BuildProcedureCall - builds a procedure call.
19175 : : Although this procedure does not directly
19176 : : destroy the procedure parameters, it calls
19177 : : routine which will manipulate the stack and
19178 : : so the entry and exit states of the stack are shown.
19179 : :
19180 : : The Stack:
19181 : :
19182 : :
19183 : : Entry Exit
19184 : :
19185 : : Ptr ->
19186 : : +----------------+
19187 : : | NoOfParam |
19188 : : |----------------|
19189 : : | Param 1 |
19190 : : |----------------|
19191 : : | Param 2 |
19192 : : |----------------|
19193 : : . .
19194 : : . .
19195 : : . .
19196 : : |----------------|
19197 : : | Param # |
19198 : : |----------------|
19199 : : | ProcSym | Type | Empty
19200 : : |----------------|
19201 : : */
19202 : :
19203 : 164786 : extern "C" void M2Quads_BuildProcedureCall (unsigned int tokno)
19204 : : {
19205 : 164786 : unsigned int NoOfParam;
19206 : 164786 : unsigned int ProcSym;
19207 : :
19208 : 164786 : M2Quads_PopT (&NoOfParam);
19209 : 164786 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19210 : 164786 : M2Quads_PushT (NoOfParam); /* Compile time stack restored to entry state */
19211 : 164786 : if ((M2Base_IsPseudoBaseProcedure (ProcSym)) || (M2System_IsPseudoSystemProcedure (ProcSym))) /* Compile time stack restored to entry state */
19212 : : {
19213 : 18330 : M2Quads_DisplayStack ();
19214 : 18330 : ManipulatePseudoCallParameters ();
19215 : 18330 : M2Quads_DisplayStack ();
19216 : 18330 : BuildPseudoProcedureCall (tokno);
19217 : 18330 : M2Quads_DisplayStack ();
19218 : : }
19219 : 146456 : else if (SymbolTable_IsUnknown (ProcSym))
19220 : : {
19221 : : /* avoid dangling else. */
19222 : 12 : M2MetaError_MetaError1 ((const char *) "{%1Ua} is not recognised as a procedure, check declaration or import", 68, ProcSym);
19223 : 12 : M2Quads_PopN (NoOfParam+2);
19224 : : }
19225 : : else
19226 : : {
19227 : : /* avoid dangling else. */
19228 : 146444 : M2Quads_DisplayStack ();
19229 : 146444 : BuildRealProcedureCall (tokno);
19230 : 146438 : M2Quads_DisplayStack ();
19231 : : }
19232 : 164780 : }
19233 : :
19234 : :
19235 : : /*
19236 : : CheckBuildFunction - checks to see whether ProcSym is a function
19237 : : and if so it adds a TempSym value which will
19238 : : hold the return value once the function finishes.
19239 : : This procedure also generates an error message
19240 : : if the user is calling a function and ignoring
19241 : : the return result. The additional TempSym
19242 : : is not created if ProcSym is a procedure
19243 : : and the stack is unaltered.
19244 : :
19245 : : The Stack:
19246 : :
19247 : :
19248 : : Entry Exit
19249 : :
19250 : : Ptr ->
19251 : :
19252 : : +----------------+
19253 : : | ProcSym | Type |
19254 : : +----------------+ |----------------|
19255 : : | ProcSym | Type | | TempSym | Type |
19256 : : |----------------| |----------------|
19257 : : */
19258 : :
19259 : 96165 : extern "C" bool M2Quads_CheckBuildFunction (void)
19260 : : {
19261 : 96165 : unsigned int tokpos;
19262 : 96165 : unsigned int TempSym;
19263 : 96165 : unsigned int ProcSym;
19264 : 96165 : unsigned int Type;
19265 : :
19266 : 96165 : M2Quads_PopTFtok (&ProcSym, &Type, &tokpos);
19267 : 96165 : if ((SymbolTable_IsVar (ProcSym)) && (SymbolTable_IsProcType (Type)))
19268 : : {
19269 : : /* avoid dangling else. */
19270 : 644 : if ((SymbolTable_GetSType (Type)) != SymbolTable_NulSym)
19271 : : {
19272 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
19273 : 0 : SymbolTable_PutVar (TempSym, SymbolTable_GetSType (Type));
19274 : 0 : M2Quads_PushTFtok (TempSym, SymbolTable_GetSType (Type), tokpos);
19275 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
19276 : 0 : if (! (SymbolTable_IsReturnOptionalAny (Type)))
19277 : : {
19278 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
19279 : : }
19280 : 0 : return true;
19281 : : }
19282 : : }
19283 : 95521 : else if ((SymbolTable_IsProcedure (ProcSym)) && (Type != SymbolTable_NulSym))
19284 : : {
19285 : : /* avoid dangling else. */
19286 : 0 : TempSym = SymbolTable_MakeTemporary (tokpos, SymbolTable_RightValue);
19287 : 0 : SymbolTable_PutVar (TempSym, Type);
19288 : 0 : M2Quads_PushTFtok (TempSym, Type, tokpos);
19289 : 0 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
19290 : 0 : if (! (SymbolTable_IsReturnOptionalAny (ProcSym)))
19291 : : {
19292 : 0 : M2MetaError_MetaErrorT1 (tokpos, (const char *) "function {%1Ea} is called but its return value is ignored", 57, ProcSym);
19293 : : }
19294 : 0 : return true;
19295 : : }
19296 : 96165 : M2Quads_PushTFtok (ProcSym, Type, tokpos);
19297 : 96165 : return false;
19298 : : /* static analysis guarentees a RETURN statement will be used before here. */
19299 : : __builtin_unreachable ();
19300 : : }
19301 : :
19302 : :
19303 : : /*
19304 : : BuildFunctionCall - builds a function call.
19305 : : The Stack:
19306 : :
19307 : :
19308 : : Entry Exit
19309 : :
19310 : : Ptr ->
19311 : : +----------------+
19312 : : | NoOfParam |
19313 : : |----------------|
19314 : : | Param 1 |
19315 : : |----------------|
19316 : : | Param 2 |
19317 : : |----------------|
19318 : : . .
19319 : : . .
19320 : : . .
19321 : : |----------------|
19322 : : | Param # | <- Ptr
19323 : : |----------------| +------------+
19324 : : | ProcSym | Type | | ReturnVar |
19325 : : |----------------| |------------|
19326 : : */
19327 : :
19328 : 75282 : extern "C" void M2Quads_BuildFunctionCall (bool ConstExpr)
19329 : : {
19330 : 75282 : unsigned int paramtok;
19331 : 75282 : unsigned int combinedtok;
19332 : 75282 : unsigned int functok;
19333 : 75282 : unsigned int NoOfParam;
19334 : 75282 : unsigned int ProcSym;
19335 : :
19336 : 75282 : M2Quads_PopT (&NoOfParam);
19337 : 75282 : functok = OperandTtok (NoOfParam+1);
19338 : 75282 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19339 : 75282 : ProcSym = PCSymBuild_SkipConst (ProcSym);
19340 : 75282 : M2Quads_PushT (NoOfParam);
19341 : : /* Compile time stack restored to entry state. */
19342 : 75282 : if (SymbolTable_IsUnknown (ProcSym))
19343 : : {
19344 : 6 : paramtok = OperandTtok (1);
19345 : 6 : combinedtok = M2LexBuf_MakeVirtual2Tok (functok, paramtok);
19346 : 6 : M2MetaError_MetaErrorT1 (functok, (const char *) "procedure function {%1Ea} is undefined", 38, ProcSym);
19347 : 6 : M2Quads_PopN (NoOfParam+2);
19348 : : /* Fake return value to continue compiling. */
19349 : 6 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym));
19350 : : }
19351 : 75276 : else if (SymbolTable_IsAModula2Type (ProcSym))
19352 : : {
19353 : : /* avoid dangling else. */
19354 : 1454 : ManipulatePseudoCallParameters ();
19355 : 1448 : BuildTypeCoercion (ConstExpr);
19356 : : }
19357 : 73822 : else if ((M2System_IsPseudoSystemFunction (ProcSym)) || (M2Base_IsPseudoBaseFunction (ProcSym)))
19358 : : {
19359 : : /* avoid dangling else. */
19360 : 33002 : ManipulatePseudoCallParameters ();
19361 : 33002 : BuildPseudoFunctionCall (ConstExpr);
19362 : : }
19363 : : else
19364 : : {
19365 : : /* avoid dangling else. */
19366 : 40820 : BuildRealFunctionCall (functok, ConstExpr);
19367 : : }
19368 : 75258 : }
19369 : :
19370 : :
19371 : : /*
19372 : : BuildConstFunctionCall - builds a function call and checks that this function can be
19373 : : called inside a ConstExpression.
19374 : :
19375 : : The Stack:
19376 : :
19377 : :
19378 : : Entry Exit
19379 : :
19380 : : Ptr ->
19381 : : +----------------+
19382 : : | NoOfParam |
19383 : : |----------------|
19384 : : | Param 1 |
19385 : : |----------------|
19386 : : | Param 2 |
19387 : : |----------------|
19388 : : . .
19389 : : . .
19390 : : . .
19391 : : |----------------|
19392 : : | Param # | <- Ptr
19393 : : |----------------| +------------+
19394 : : | ProcSym | Type | | ReturnVar |
19395 : : |----------------| |------------|
19396 : :
19397 : : */
19398 : :
19399 : 4416 : extern "C" void M2Quads_BuildConstFunctionCall (void)
19400 : : {
19401 : 4416 : unsigned int functok;
19402 : 4416 : unsigned int combinedtok;
19403 : 4416 : unsigned int paramtok;
19404 : 4416 : unsigned int ConstExpression;
19405 : 4416 : unsigned int NoOfParam;
19406 : 4416 : unsigned int ProcSym;
19407 : :
19408 : 4416 : M2Quads_DisplayStack ();
19409 : 4416 : M2Quads_PopT (&NoOfParam);
19410 : 4416 : ProcSym = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19411 : 4416 : functok = OperandTtok (NoOfParam+1);
19412 : 4416 : if (M2Options_CompilerDebugging)
19413 : : {
19414 : 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));
19415 : : }
19416 : : /* ErrorStringAt (InitString ('constant function'), functok). */
19417 : 4416 : M2Quads_PushT (NoOfParam);
19418 : 4416 : if ((ProcSym != M2Base_Convert) && (((M2Base_IsPseudoBaseFunction (ProcSym)) || (M2System_IsPseudoSystemFunctionConstExpression (ProcSym))) || ((SymbolTable_IsProcedure (ProcSym)) && (SymbolTable_IsProcedureBuiltin (ProcSym)))))
19419 : : {
19420 : 4284 : M2Quads_BuildFunctionCall (true);
19421 : : }
19422 : : else
19423 : : {
19424 : 132 : if (SymbolTable_IsAModula2Type (ProcSym))
19425 : : {
19426 : : /* Type conversion. */
19427 : 132 : if (NoOfParam == 1)
19428 : : {
19429 : 132 : ConstExpression = static_cast<unsigned int> (M2Quads_OperandT (NoOfParam+1));
19430 : 132 : paramtok = OperandTtok (NoOfParam+1);
19431 : 132 : M2Quads_PopN (NoOfParam+2);
19432 : : /* Build macro: CONVERT( ProcSym, ConstExpression ). */
19433 : 132 : M2Quads_PushTFtok (M2Base_Convert, static_cast<unsigned int> (SymbolTable_NulSym), functok);
19434 : 132 : M2Quads_PushTtok (ProcSym, functok);
19435 : 132 : M2Quads_PushTtok (ConstExpression, paramtok);
19436 : 132 : M2Quads_PushT (static_cast<unsigned int> (2)); /* Two parameters. */
19437 : 132 : BuildConvertFunction (M2Base_Convert, true); /* Two parameters. */
19438 : : }
19439 : : else
19440 : : {
19441 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "{%E}a constant type conversion can only have one argument", 57);
19442 : : }
19443 : : }
19444 : : else
19445 : : {
19446 : : /* Error issue message and fake return stack. */
19447 : 0 : if (M2Options_Iso)
19448 : : {
19449 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kCMPLX}, {%kFLOAT}, {%kHIGH}, {%kIM}, {%kLENGTH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kRE}, {%kSIZE}, {%kTSIZE}, {%kTRUNC}, {%kVAL} and gcc builtins", 231);
19450 : : }
19451 : : else
19452 : : {
19453 : 0 : M2MetaError_MetaErrorT0 (functok, (const char *) "the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kFLOAT}, {%kHIGH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kSIZE}, {%kTSIZE}, {%kTRUNC}, {%kVAL} and gcc builtins", 192);
19454 : : }
19455 : 0 : if (NoOfParam > 0)
19456 : : {
19457 : 0 : paramtok = OperandTtok (NoOfParam+1);
19458 : 0 : combinedtok = M2LexBuf_MakeVirtualTok (functok, functok, paramtok);
19459 : : }
19460 : : else
19461 : : {
19462 : 0 : combinedtok = functok;
19463 : : }
19464 : 0 : M2Quads_PopN (NoOfParam+2);
19465 : 0 : M2Quads_PushT (SymbolTable_MakeConstLit (combinedtok, NameKey_MakeKey ((const char *) "0", 1), SymbolTable_NulSym)); /* Fake return value to continue compiling. */
19466 : : }
19467 : : }
19468 : 4416 : }
19469 : :
19470 : :
19471 : : /*
19472 : : BuildBooleanVariable - tests to see whether top of stack is a boolean
19473 : : conditional and if so it converts it into a boolean
19474 : : variable.
19475 : : */
19476 : :
19477 : 295081 : extern "C" void M2Quads_BuildBooleanVariable (void)
19478 : : {
19479 : 295081 : if (IsBoolean (1))
19480 : : {
19481 : 6694 : ConvertBooleanToVariable (OperandTtok (1), 1);
19482 : : }
19483 : 295081 : }
19484 : :
19485 : :
19486 : : /*
19487 : : BuildModuleStart - starts current module scope.
19488 : : */
19489 : :
19490 : 65923 : extern "C" void M2Quads_BuildModuleStart (unsigned int tok)
19491 : : {
19492 : 65923 : GenQuadO (tok, M2Quads_ModuleScopeOp, tok, (unsigned int ) (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()))), SymbolTable_GetCurrentModule (), false);
19493 : 65923 : }
19494 : :
19495 : :
19496 : : /*
19497 : : BuildProcedureStart - Builds start of the procedure. Generates a
19498 : : quadruple which indicated the start of
19499 : : this procedure declarations scope.
19500 : : The Stack is expected to contain:
19501 : :
19502 : :
19503 : : Entry Exit
19504 : : ===== ====
19505 : :
19506 : : Ptr -> <- Ptr
19507 : : +------------+ +-----------+
19508 : : | ProcSym | | ProcSym |
19509 : : |------------| |-----------|
19510 : : | Name | | Name |
19511 : : |------------| |-----------|
19512 : :
19513 : :
19514 : : Quadruples:
19515 : :
19516 : : q ProcedureScopeOp Line# Scope ProcSym
19517 : : */
19518 : :
19519 : 71150 : extern "C" void M2Quads_BuildProcedureStart (void)
19520 : : {
19521 : 71150 : unsigned int ProcSym;
19522 : :
19523 : 71150 : M2Quads_PopT (&ProcSym);
19524 : 71150 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19525 : 71150 : SymbolTable_PutProcedureScopeQuad (ProcSym, NextQuad);
19526 : 71150 : GenQuad (M2Quads_ProcedureScopeOp, M2LexBuf_GetPreviousTokenLineNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19527 : 71150 : M2Quads_PushT (ProcSym);
19528 : 71150 : }
19529 : :
19530 : :
19531 : : /*
19532 : : BuildProcedureBegin - determines the start of the BEGIN END block of
19533 : : the procedure.
19534 : : The Stack is expected to contain:
19535 : :
19536 : :
19537 : : Entry Exit
19538 : : ===== ====
19539 : :
19540 : : Ptr -> <- Ptr
19541 : : +------------+ +-----------+
19542 : : | ProcSym | | ProcSym |
19543 : : |------------| |-----------|
19544 : : | Name | | Name |
19545 : : |------------| |-----------|
19546 : :
19547 : :
19548 : : Quadruples:
19549 : :
19550 : : q NewLocalVarOp TokenNo(BEGIN) _ ProcSym
19551 : : */
19552 : :
19553 : 71138 : extern "C" void M2Quads_BuildProcedureBegin (void)
19554 : : {
19555 : 71138 : unsigned int ProcSym;
19556 : :
19557 : 71138 : M2Quads_PopT (&ProcSym);
19558 : 71138 : M2Debug_Assert (SymbolTable_IsProcedure (ProcSym));
19559 : 71138 : SymbolTable_PutProcedureStartQuad (ProcSym, NextQuad);
19560 : 71138 : SymbolTable_PutProcedureBegin (ProcSym, M2LexBuf_GetTokenNo ());
19561 : 71138 : GenQuad (M2Quads_NewLocalVarOp, M2LexBuf_GetTokenNo (), SymbolTable_GetScope (ProcSym), ProcSym);
19562 : 71138 : CurrentProc = ProcSym;
19563 : 71138 : M2StackWord_PushWord (ReturnStack, static_cast<unsigned int> (0));
19564 : 71138 : M2Quads_PushT (ProcSym);
19565 : 71138 : CheckVariablesAt (ProcSym);
19566 : 71138 : CheckNeedPriorityBegin (M2LexBuf_GetTokenNo (), ProcSym, SymbolTable_GetCurrentModule ());
19567 : 71138 : M2StackWord_PushWord (TryStack, NextQuad);
19568 : 71138 : M2StackWord_PushWord (CatchStack, static_cast<unsigned int> (0));
19569 : 71138 : if (SymbolTable_HasExceptionBlock (ProcSym))
19570 : : {
19571 : 168 : GenQuad (M2Quads_TryOp, SymbolTable_NulSym, SymbolTable_NulSym, 0);
19572 : : }
19573 : 71138 : }
19574 : :
19575 : :
19576 : : /*
19577 : : BuildProcedureEnd - Builds end of the procedure. Destroys space for
19578 : : the local variables.
19579 : : The Stack is expected to contain:
19580 : :
19581 : :
19582 : : Entry Exit
19583 : : ===== ====
19584 : :
19585 : : Ptr -> <- Ptr
19586 : : +------------+ +-----------+
19587 : : | ProcSym | | ProcSym |
19588 : : |------------| |-----------|
19589 : : | Name | | Name |
19590 : : |------------| |-----------|
19591 : :
19592 : :
19593 : : Quadruples:
19594 : :
19595 : : q KillLocalVarOp TokenNo(END) _ ProcSym
19596 : : */
19597 : :
19598 : 71108 : extern "C" void M2Quads_BuildProcedureEnd (void)
19599 : : {
19600 : 71108 : unsigned int tok;
19601 : 71108 : unsigned int ProcSym;
19602 : :
19603 : 71108 : M2Quads_PopTtok (&ProcSym, &tok);
19604 : 71108 : if (SymbolTable_HasExceptionBlock (ProcSym))
19605 : : {
19606 : 168 : BuildRTExceptLeave (tok, true);
19607 : 168 : GenQuad (M2Quads_CatchEndOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
19608 : : }
19609 : 71108 : if ((SymbolTable_GetSType (ProcSym)) != SymbolTable_NulSym)
19610 : : {
19611 : 12239 : BuildError (M2Range_InitNoReturnRangeCheck ());
19612 : : }
19613 : 71108 : BackPatch (M2StackWord_PopWord (ReturnStack), NextQuad);
19614 : 71108 : CheckNeedPriorityEnd (tok, ProcSym, SymbolTable_GetCurrentModule ());
19615 : 71108 : CurrentProc = SymbolTable_NulSym;
19616 : 71108 : SymbolTable_PutProcedureEnd (ProcSym, (M2LexBuf_GetTokenNo ())-1); /* --fixme-- */
19617 : 71108 : GenQuad (M2Quads_KillLocalVarOp, (M2LexBuf_GetTokenNo ())-1, SymbolTable_NulSym, ProcSym); /* --fixme-- */
19618 : 71108 : SymbolTable_PutProcedureEndQuad (ProcSym, NextQuad);
19619 : 71108 : GenQuad (M2Quads_ReturnOp, SymbolTable_NulSym, SymbolTable_NulSym, ProcSym);
19620 : 71108 : CheckFunctionReturn (ProcSym);
19621 : 71108 : CheckVariablesInBlock (ProcSym);
19622 : : /* Call PutProcedureEndQuad so that any runtime procedure will be
19623 : : seen as defined even if it not seen during pass 2 (which will also
19624 : : call PutProcedureEndQuad). */
19625 : 71108 : SymbolTable_PutProcedureParametersDefined (ProcSym, SymbolTable_ProperProcedure);
19626 : 71108 : SymbolTable_PutProcedureDefined (ProcSym, SymbolTable_ProperProcedure);
19627 : 71108 : M2StackWord_RemoveTop (CatchStack);
19628 : 71108 : M2StackWord_RemoveTop (TryStack);
19629 : 71108 : M2Quads_PushT (ProcSym);
19630 : 71108 : }
19631 : :
19632 : :
19633 : : /*
19634 : : BuildReturn - Builds the Return part of the procedure.
19635 : : tokreturn is the location of the RETURN keyword.
19636 : : The Stack is expected to contain:
19637 : :
19638 : :
19639 : : Entry Exit
19640 : : ===== ====
19641 : :
19642 : : Ptr ->
19643 : : +------------+
19644 : : | e1 | Empty
19645 : : |------------|
19646 : : */
19647 : :
19648 : 19773 : extern "C" void M2Quads_BuildReturn (unsigned int tokreturn)
19649 : : {
19650 : 19773 : unsigned int tokcombined;
19651 : 19773 : unsigned int tokexpr;
19652 : 19773 : unsigned int e1;
19653 : 19773 : unsigned int t1;
19654 : 19773 : unsigned int t;
19655 : 19773 : unsigned int f;
19656 : 19773 : unsigned int Des;
19657 : :
19658 : 19773 : if (IsBoolean (1))
19659 : : {
19660 : 1564 : PopBooltok (&t, &f, &tokexpr);
19661 : : /* Des will be a boolean type */
19662 : 1564 : Des = SymbolTable_MakeTemporary (tokexpr, SymbolTable_RightValue);
19663 : 1564 : SymbolTable_PutVar (Des, M2Base_Boolean);
19664 : 1564 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19665 : 1564 : PushBooltok (t, f, tokexpr);
19666 : 1564 : BuildAssignmentWithoutBounds (tokreturn, false, true);
19667 : 1564 : M2Quads_PushTFtok (Des, M2Base_Boolean, tokexpr);
19668 : : }
19669 : 19773 : M2Quads_PopTFtok (&e1, &t1, &tokexpr);
19670 : 19773 : tokcombined = M2LexBuf_MakeVirtualTok (tokreturn, tokreturn, tokexpr);
19671 : 19773 : if (e1 != SymbolTable_NulSym)
19672 : : {
19673 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
19674 : : /* Check we are in a procedure scope and that the procedure has a return type. */
19675 : 19017 : if (CurrentProc == SymbolTable_NulSym)
19676 : : {
19677 : 6 : M2MetaError_MetaErrorT0 (tokcombined, (const char *) "{%1E} attempting to return a value when not in a procedure scope", 64);
19678 : : }
19679 : 19011 : else if ((SymbolTable_GetSType (CurrentProc)) == SymbolTable_NulSym)
19680 : : {
19681 : : /* avoid dangling else. */
19682 : 6 : M2MetaError_MetaErrorT1 (tokcombined, (const char *) "attempting to return a value from procedure {%1Ea} which does not have a return type", 84, CurrentProc);
19683 : : }
19684 : : else
19685 : : {
19686 : : /* avoid dangling else. */
19687 : 19005 : BuildReturnLower (tokcombined, tokexpr, e1, t1);
19688 : : }
19689 : : }
19690 : 19773 : GenQuadO (tokcombined, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, M2StackWord_PopWord (ReturnStack), false);
19691 : 19773 : M2StackWord_PushWord (ReturnStack, NextQuad-1);
19692 : 19773 : }
19693 : :
19694 : :
19695 : : /*
19696 : : BuildModulePriority - assigns the current module with a priority
19697 : : from the top of stack.
19698 : :
19699 : : Entry Exit
19700 : : ===== ====
19701 : :
19702 : :
19703 : : Ptr -> Empty
19704 : : +------------+
19705 : : | Priority |
19706 : : |------------|
19707 : : */
19708 : :
19709 : 38 : extern "C" void M2Quads_BuildModulePriority (void)
19710 : : {
19711 : 38 : unsigned int Priority;
19712 : :
19713 : 38 : M2Quads_PopT (&Priority);
19714 : 38 : SymbolTable_PutPriority (SymbolTable_GetCurrentModule (), Priority);
19715 : 38 : }
19716 : :
19717 : :
19718 : : /*
19719 : : StartBuildWith - performs the with statement.
19720 : : The Stack:
19721 : :
19722 : : Entry Exit
19723 : :
19724 : : +------------+
19725 : : | Sym | Type | Empty
19726 : : |------------|
19727 : : */
19728 : :
19729 : 5598 : extern "C" void M2Quads_StartBuildWith (unsigned int withTok)
19730 : : {
19731 : 5598 : unsigned int tok;
19732 : 5598 : unsigned int Sym;
19733 : 5598 : unsigned int Type;
19734 : 5598 : unsigned int Ref;
19735 : :
19736 : 5598 : DebugLocation (static_cast<unsigned int> (M2Reserved_withtok), (const char *) "with", 4);
19737 : 5598 : BuildStmtNoteTok (withTok);
19738 : 5598 : M2Quads_DisplayStack ();
19739 : 5598 : M2Quads_PopTFtok (&Sym, &Type, &tok);
19740 : 5598 : DebugLocation (tok, (const char *) "expression", 10);
19741 : 5598 : Type = SymbolTable_SkipType (Type);
19742 : 5598 : if (Type == SymbolTable_NulSym)
19743 : : {
19744 : 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);
19745 : : }
19746 : : else
19747 : : {
19748 : 5592 : Ref = SymbolTable_MakeTemporary (tok, SymbolTable_LeftValue);
19749 : 5592 : SymbolTable_PutVar (Ref, Type);
19750 : 5592 : if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
19751 : : {
19752 : : /* Copy LeftValue. */
19753 : 5358 : GenQuadO (tok, M2Quads_BecomesOp, Ref, SymbolTable_NulSym, Sym, true);
19754 : : }
19755 : : else
19756 : : {
19757 : : /* Calculate the address of Sym. */
19758 : 234 : GenQuadO (tok, M2Quads_AddrOp, Ref, SymbolTable_NulSym, Sym, true);
19759 : : }
19760 : 5592 : PushWith (Sym, Type, Ref, tok);
19761 : 5592 : DebugLocation (tok, (const char *) "with ref", 8);
19762 : 5592 : if (! (SymbolTable_IsRecord (Type)))
19763 : : {
19764 : 0 : M2MetaError_MetaErrorT1 (tok, (const char *) "the {%kWITH} statement requires that {%1Ea} {%1d} be of a {%kRECORD} {%1tsa:type rather than {%1tsa}}", 101, Sym);
19765 : : }
19766 : 5592 : SymbolTable_StartScope (Type);
19767 : : }
19768 : 5592 : M2Quads_DisplayStack ();
19769 : 5592 : }
19770 : :
19771 : :
19772 : : /*
19773 : : EndBuildWith - terminates the innermost with scope.
19774 : : */
19775 : :
19776 : 5592 : extern "C" void M2Quads_EndBuildWith (void)
19777 : : {
19778 : 5592 : M2Quads_DisplayStack ();
19779 : 5592 : SymbolTable_EndScope ();
19780 : 5592 : PopWith ();
19781 : 5592 : M2Quads_DisplayStack ();
19782 : 5592 : }
19783 : :
19784 : :
19785 : : /*
19786 : : CheckWithReference - performs the with statement.
19787 : : The Stack:
19788 : :
19789 : : Entry Exit
19790 : :
19791 : : +------------+ +------------+
19792 : : | Sym | Type | | Sym | Type |
19793 : : |------------| |------------|
19794 : : */
19795 : :
19796 : 572421 : extern "C" void M2Quads_CheckWithReference (void)
19797 : : {
19798 : 572421 : M2Quads_WithFrame f;
19799 : 572421 : unsigned int tokpos;
19800 : 572421 : unsigned int i;
19801 : 572421 : unsigned int n;
19802 : 572421 : unsigned int rw;
19803 : 572421 : unsigned int Sym;
19804 : 572421 : unsigned int Type;
19805 : :
19806 : 572421 : n = M2StackAddress_NoOfItemsInStackAddress (WithStack);
19807 : 572421 : if ((n > 0) && ! SuppressWith)
19808 : : {
19809 : 100504 : PopTFrwtok (&Sym, &Type, &rw, &tokpos);
19810 : 100504 : M2Debug_Assert (tokpos != M2LexBuf_UnknownTokenNo);
19811 : : /* inner WITH always has precidence */
19812 : 100504 : i = 1; /* top of stack */
19813 : : /* WriteString('Checking for a with') ; */
19814 : 314304 : while (i <= n)
19815 : : {
19816 : 113296 : f = static_cast<M2Quads_WithFrame> (M2StackAddress_PeepAddress (WithStack, i));
19817 : 113296 : if ((SymbolTable_IsRecordField (Sym)) && ((SymbolTable_GetRecord (SymbolTable_GetParent (Sym))) == f->RecordType))
19818 : : {
19819 : 28604 : if (SymbolTable_IsUnused (Sym))
19820 : : {
19821 : 0 : M2MetaError_MetaError1 ((const char *) "record field {%1Dad} was declared as unused by a pragma", 55, Sym);
19822 : : }
19823 : : /* Fake a RecordSym.op */
19824 : 28604 : PushTFrwtok (f->RecordRef, f->RecordType, f->rw, f->RecordTokPos);
19825 : 28604 : M2Quads_PushTFtok (Sym, Type, tokpos);
19826 : 28604 : BuildAccessWithField ();
19827 : 28604 : PopTFrw (&Sym, &Type, &f->rw);
19828 : 28604 : i = n+1; /* Finish loop. */
19829 : : }
19830 : : else
19831 : : {
19832 : 84692 : i += 1;
19833 : : }
19834 : : }
19835 : 100504 : PushTFrwtok (Sym, Type, rw, tokpos);
19836 : : }
19837 : 572421 : }
19838 : :
19839 : :
19840 : : /*
19841 : : BuildDesignatorRecord - Builds the record referencing.
19842 : : The Stack is expected to contain:
19843 : :
19844 : :
19845 : : Entry Exit
19846 : : ===== ====
19847 : :
19848 : : Ptr ->
19849 : : +--------------+
19850 : : | n |
19851 : : |--------------|
19852 : : | fld1 | type1 |
19853 : : |--------------|
19854 : : . .
19855 : : . .
19856 : : . .
19857 : : |--------------|
19858 : : | fldn | typen | <- Ptr
19859 : : |--------------| +-------------+
19860 : : | Sym | Type | | S | type1|
19861 : : |--------------| |-------------|
19862 : : */
19863 : :
19864 : 98336 : extern "C" void M2Quads_BuildDesignatorRecord (unsigned int dottok)
19865 : : {
19866 : 98336 : unsigned int RecordTok;
19867 : 98336 : unsigned int FieldTok;
19868 : 98336 : unsigned int combinedtok;
19869 : 98336 : unsigned int n;
19870 : 98336 : unsigned int rw;
19871 : 98336 : unsigned int Field;
19872 : 98336 : unsigned int FieldType;
19873 : 98336 : unsigned int RecordSym;
19874 : 98336 : unsigned int Res;
19875 : :
19876 : 98336 : M2Quads_PopT (&n);
19877 : 98336 : RecordSym = static_cast<unsigned int> (M2Quads_OperandT (n+1));
19878 : : /* RecordType could be found by: SkipType (OperandF (n+1)). */
19879 : 98336 : RecordTok = static_cast<unsigned int> (M2Quads_OperandTok (n+1));
19880 : 98336 : rw = static_cast<unsigned int> (OperandMergeRW (n+1));
19881 : 98336 : M2Debug_Assert (SymbolTable_IsLegal (rw));
19882 : 98336 : Field = static_cast<unsigned int> (M2Quads_OperandT (n));
19883 : 98336 : FieldType = SymbolTable_SkipType (M2Quads_OperandF (n));
19884 : 98336 : FieldTok = static_cast<unsigned int> (M2Quads_OperandTok (n));
19885 : 98336 : combinedtok = M2LexBuf_MakeVirtualTok (dottok, RecordTok, FieldTok);
19886 : 98336 : if (n > 1)
19887 : : {
19888 : 0 : M2Error_InternalError ((const char *) "not expecting to see n>1", 24);
19889 : : }
19890 : 98336 : if (SymbolTable_IsUnused (Field))
19891 : : {
19892 : 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);
19893 : : }
19894 : 98336 : Res = SymbolTable_MakeComponentRef (SymbolTable_MakeComponentRecord (combinedtok, SymbolTable_RightValue, RecordSym), Field);
19895 : 98336 : SymbolTable_PutVarConst (Res, IsReadOnly (RecordSym));
19896 : 98336 : GenQuadO (combinedtok, M2Quads_RecordFieldOp, Res, RecordSym, Field, false);
19897 : 98336 : M2Quads_PopN (n+1);
19898 : 98336 : PushTFrwtok (Res, FieldType, rw, combinedtok);
19899 : 98336 : }
19900 : :
19901 : :
19902 : : /*
19903 : : BuildDesignatorArray - Builds the array referencing.
19904 : : The purpose of this procedure is to work out
19905 : : whether the DesignatorArray is a constant string or
19906 : : dynamic array/static array and to call the appropriate
19907 : : BuildRoutine.
19908 : :
19909 : : The Stack is expected to contain:
19910 : :
19911 : : Entry Exit
19912 : : ===== ====
19913 : :
19914 : : Ptr ->
19915 : : +--------------+
19916 : : | e | <- Ptr
19917 : : |--------------| +------------+
19918 : : | Sym | Type | | S | T |
19919 : : |--------------| |------------|
19920 : : */
19921 : :
19922 : 48666 : extern "C" void M2Quads_BuildDesignatorArray (void)
19923 : : {
19924 : 48666 : if ((SymbolTable_IsConst (M2Quads_OperandT (2))) && (SymbolTable_IsConstString (M2Quads_OperandT (2))))
19925 : : {
19926 : 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));
19927 : 6 : BuildDesignatorError ((const char *) "bad array access", 16);
19928 : : }
19929 : : else
19930 : : {
19931 : 48660 : BuildDesignatorArrayStaticDynamic ();
19932 : : }
19933 : 48660 : }
19934 : :
19935 : :
19936 : : /*
19937 : : BuildDesignatorPointer - Builds a pointer reference.
19938 : : The Stack is expected to contain:
19939 : :
19940 : :
19941 : : Entry Exit
19942 : : ===== ====
19943 : :
19944 : : Ptr -> <- Ptr
19945 : : +--------------+ +--------------+
19946 : : | Sym1 | Type1| | Sym2 | Type2|
19947 : : |--------------| |--------------|
19948 : : */
19949 : :
19950 : 14006 : extern "C" void M2Quads_BuildDesignatorPointer (unsigned int ptrtok)
19951 : : {
19952 : 14006 : unsigned int combinedtok;
19953 : 14006 : unsigned int destok;
19954 : 14006 : unsigned int rw;
19955 : 14006 : unsigned int Sym1;
19956 : 14006 : unsigned int Type1;
19957 : 14006 : unsigned int Sym2;
19958 : 14006 : unsigned int Type2;
19959 : :
19960 : 14006 : PopTFrwtok (&Sym1, &Type1, &rw, &destok);
19961 : 14006 : DebugLocation (destok, (const char *) "des ptr expression", 18);
19962 : 14006 : Type1 = SymbolTable_SkipType (Type1);
19963 : 14006 : if (Type1 == SymbolTable_NulSym)
19964 : : {
19965 : 0 : M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1ad} has no type and therefore cannot be dereferenced by ^", 60, Sym1);
19966 : : }
19967 : 14006 : else if (SymbolTable_IsUnknown (Sym1))
19968 : : {
19969 : : /* avoid dangling else. */
19970 : 0 : M2MetaError_MetaError1 ((const char *) "{%1EMad} is undefined and therefore {%1ad}^ cannot be resolved", 62, Sym1);
19971 : : }
19972 : : else
19973 : : {
19974 : : /* avoid dangling else. */
19975 : 14006 : combinedtok = M2LexBuf_MakeVirtual2Tok (destok, ptrtok);
19976 : 14006 : if (SymbolTable_IsPointer (Type1))
19977 : : {
19978 : 14004 : Type2 = SymbolTable_GetSType (Type1);
19979 : 14004 : Sym2 = SymbolTable_MakeTemporary (ptrtok, SymbolTable_LeftValue);
19980 : : /*
19981 : : Ok must reference by address
19982 : : - but we contain the type of the referenced entity
19983 : : */
19984 : 14004 : MarkAsRead (rw);
19985 : 14004 : SymbolTable_PutVarPointerCheck (Sym1, true);
19986 : 14004 : CheckPointerThroughNil (ptrtok, Sym1);
19987 : 14004 : if ((SymbolTable_GetMode (Sym1)) == SymbolTable_LeftValue)
19988 : : {
19989 : 510 : rw = SymbolTable_NulSym;
19990 : 510 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, Type1);
19991 : 510 : GenQuadO (ptrtok, M2Quads_IndrXOp, Sym2, Type1, Sym1, false); /* Sym2 := *Sym1. */
19992 : : }
19993 : : else
19994 : : {
19995 : 13494 : SymbolTable_PutLeftValueFrontBackType (Sym2, Type2, SymbolTable_NulSym);
19996 : 13494 : GenQuadO (ptrtok, M2Quads_BecomesOp, Sym2, SymbolTable_NulSym, Sym1, false); /* Sym2 := Sym1. */
19997 : : }
19998 : : /* We should check this for Sym2 later on (pointer via NIL). */
19999 : 14004 : SymbolTable_PutVarPointerCheck (Sym2, true);
20000 : 14004 : PushTFrwtok (Sym2, Type2, rw, combinedtok);
20001 : 14004 : DebugLocation (combinedtok, (const char *) "pointer expression", 18);
20002 : : }
20003 : 2 : else if ((SymbolTable_IsHiddenType (Type1)) && ((SymbolTable_GetModuleScope (Type1)) != (SymbolTable_GetCurrentModuleScope ())))
20004 : : {
20005 : : /* avoid dangling else. */
20006 : 2 : M2MetaError_MetaErrorT1 (ptrtok, (const char *) "{%1Ead} is declared with an opaque type from a different module and cannot be dereferenced", 90, Sym1);
20007 : 2 : MarkAsRead (rw);
20008 : 2 : BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad opaque pointer dereference", 30);
20009 : : }
20010 : : else
20011 : : {
20012 : : /* avoid dangling else. */
20013 : 0 : M2MetaError_MetaError2 ((const char *) "{%1Ead} is not a pointer type but a {%2d}", 41, Sym1, Type1);
20014 : 0 : MarkAsRead (rw);
20015 : 0 : BuildDesignatorPointerError (Type1, rw, combinedtok, (const char *) "bad pointer dereference", 23);
20016 : : }
20017 : : }
20018 : 14006 : }
20019 : :
20020 : :
20021 : : /*
20022 : : BuildNulExpression - Builds a nul expression on the stack.
20023 : : The Stack:
20024 : :
20025 : : Entry Exit
20026 : :
20027 : : <- Ptr
20028 : : Empty +------------+
20029 : : | NulSym |
20030 : : |------------|
20031 : : tokpos is the position of the RETURN token.
20032 : : */
20033 : :
20034 : 756 : extern "C" void M2Quads_BuildNulExpression (unsigned int tokpos)
20035 : : {
20036 : 756 : M2Quads_PushTtok (static_cast<unsigned int> (SymbolTable_NulSym), tokpos);
20037 : 756 : }
20038 : :
20039 : :
20040 : : /*
20041 : : BuildSetStart - Pushes a Bitset type on the stack.
20042 : :
20043 : : The Stack:
20044 : :
20045 : : Entry Exit
20046 : :
20047 : : Ptr -> <- Ptr
20048 : :
20049 : : Empty +--------------+
20050 : : | Bitset |
20051 : : |--------------|
20052 : : */
20053 : :
20054 : 0 : extern "C" void M2Quads_BuildSetStart (unsigned int tokpos)
20055 : : {
20056 : 0 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
20057 : 0 : }
20058 : :
20059 : :
20060 : : /*
20061 : : BuildSetEnd - pops the set value and type from the stack
20062 : : and pushes the value,type pair.
20063 : :
20064 : : Entry Exit
20065 : :
20066 : : Ptr ->
20067 : : +--------------+
20068 : : | Set Value | <- Ptr
20069 : : |--------------| +--------------+
20070 : : | Set Type | | Value | Type |
20071 : : |--------------| |--------------|
20072 : : */
20073 : :
20074 : 0 : extern "C" void M2Quads_BuildSetEnd (void)
20075 : : {
20076 : 0 : unsigned int valuepos;
20077 : 0 : unsigned int typepos;
20078 : 0 : unsigned int combined;
20079 : 0 : unsigned int value;
20080 : 0 : unsigned int type;
20081 : :
20082 : 0 : M2Quads_PopTtok (&value, &valuepos);
20083 : 0 : M2Quads_PopTtok (&type, &typepos);
20084 : 0 : combined = M2LexBuf_MakeVirtual2Tok (typepos, valuepos);
20085 : 0 : M2Quads_PushTFtok (value, type, combined);
20086 : 0 : M2Debug_Assert (SymbolTable_IsSet (type));
20087 : 0 : }
20088 : :
20089 : :
20090 : : /*
20091 : : BuildEmptySet - Builds an empty set on the stack.
20092 : : The Stack:
20093 : :
20094 : : Entry Exit
20095 : :
20096 : : <- Ptr
20097 : : +-------------+
20098 : : Ptr -> | Value |
20099 : : +-----------+ |-------------|
20100 : : | SetType | | SetType |
20101 : : |-----------| |-------------|
20102 : :
20103 : : tokpos points to the opening '{'.
20104 : : */
20105 : :
20106 : 0 : extern "C" void M2Quads_BuildEmptySet (unsigned int tokpos)
20107 : : {
20108 : 0 : NameKey_Name n;
20109 : 0 : unsigned int typepos;
20110 : 0 : unsigned int Type;
20111 : 0 : unsigned int NulSet;
20112 : :
20113 : 0 : M2Quads_PopTtok (&Type, &typepos); /* type of set we are building */
20114 : 0 : if ((Type == SymbolTable_NulSym) && M2Options_Pim)
20115 : : {
20116 : : /* allowed generic {} in PIM Modula-2 */
20117 : 0 : typepos = tokpos;
20118 : : }
20119 : 0 : else if (SymbolTable_IsUnknown (Type))
20120 : : {
20121 : : /* avoid dangling else. */
20122 : 0 : n = SymbolTable_GetSymName (Type);
20123 : 0 : M2Error_WriteFormat1 ((const char *) "set type %a is undefined", 24, (const unsigned char *) &n, (sizeof (n)-1));
20124 : 0 : Type = M2Bitset_Bitset;
20125 : : }
20126 : 0 : else if (! (SymbolTable_IsSet (SymbolTable_SkipType (Type))))
20127 : : {
20128 : : /* avoid dangling else. */
20129 : 0 : n = SymbolTable_GetSymName (Type);
20130 : 0 : M2Error_WriteFormat1 ((const char *) "expecting a set type %a", 23, (const unsigned char *) &n, (sizeof (n)-1));
20131 : 0 : Type = M2Bitset_Bitset;
20132 : : }
20133 : : else
20134 : : {
20135 : : /* avoid dangling else. */
20136 : 0 : Type = SymbolTable_SkipType (Type);
20137 : 0 : M2Debug_Assert (Type != SymbolTable_NulSym);
20138 : : }
20139 : 0 : NulSet = SymbolTable_MakeTemporary (typepos, SymbolTable_ImmediateValue);
20140 : 0 : SymbolTable_PutVar (NulSet, Type);
20141 : 0 : SymbolTable_PutConstSet (NulSet);
20142 : 0 : if (M2Options_CompilerDebugging)
20143 : : {
20144 : 0 : n = SymbolTable_GetSymName (Type);
20145 : 0 : M2Printf_printf1 ((const char *) "set type = %a\\n", 15, (const unsigned char *) &n, (sizeof (n)-1));
20146 : : }
20147 : 0 : M2ALU_PushNulSet (Type); /* onto the ALU stack */
20148 : 0 : SymbolTable_PopValue (NulSet); /* ALU -> symbol table */
20149 : : /* and now construct the M2Quads stack as defined by the comments above */
20150 : 0 : M2Quads_PushTtok (Type, typepos);
20151 : 0 : M2Quads_PushTtok (NulSet, typepos);
20152 : 0 : if (M2Options_CompilerDebugging)
20153 : : {
20154 : 0 : n = SymbolTable_GetSymName (Type);
20155 : 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));
20156 : 0 : M2Quads_DisplayStack (); /* Debugging info */
20157 : : }
20158 : 0 : }
20159 : :
20160 : :
20161 : : /*
20162 : : BuildInclRange - includes a set range with a set.
20163 : :
20164 : :
20165 : : Entry Exit
20166 : : ===== ====
20167 : :
20168 : :
20169 : : Ptr ->
20170 : : +------------+
20171 : : | El2 |
20172 : : |------------|
20173 : : | El1 | <- Ptr
20174 : : |------------| +-------------------+
20175 : : | Set Value | | Value + {El1..El2}|
20176 : : |------------| |-------------------|
20177 : :
20178 : : No quadruples produced as the range info is contained within
20179 : : the set value.
20180 : : */
20181 : :
20182 : 0 : extern "C" void M2Quads_BuildInclRange (void)
20183 : : {
20184 : 0 : NameKey_Name n;
20185 : 0 : unsigned int el1;
20186 : 0 : unsigned int el2;
20187 : 0 : unsigned int value;
20188 : :
20189 : 0 : M2Quads_PopT (&el2);
20190 : 0 : M2Quads_PopT (&el1);
20191 : 0 : M2Quads_PopT (&value);
20192 : 0 : if (! (SymbolTable_IsConstSet (value)))
20193 : : {
20194 : 0 : n = SymbolTable_GetSymName (el1);
20195 : 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));
20196 : : }
20197 : 0 : if ((SymbolTable_IsConst (el1)) && (SymbolTable_IsConst (el2)))
20198 : : {
20199 : 0 : SymbolTable_PushValue (value); /* onto ALU stack */
20200 : 0 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), el1, el2); /* onto ALU stack */
20201 : 0 : SymbolTable_PopValue (value); /* ALU -> symboltable */
20202 : : }
20203 : : else
20204 : : {
20205 : 0 : if (! (SymbolTable_IsConst (el1)))
20206 : : {
20207 : 0 : n = SymbolTable_GetSymName (el1);
20208 : 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));
20209 : : }
20210 : 0 : if (! (SymbolTable_IsConst (el2)))
20211 : : {
20212 : 0 : n = SymbolTable_GetSymName (el2);
20213 : 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));
20214 : : }
20215 : : }
20216 : 0 : M2Quads_PushT (value);
20217 : 0 : }
20218 : :
20219 : :
20220 : : /*
20221 : : BuildInclBit - includes a bit into the set.
20222 : :
20223 : : Entry Exit
20224 : : ===== ====
20225 : :
20226 : :
20227 : : Ptr ->
20228 : : +------------+
20229 : : | Element | <- Ptr
20230 : : |------------| +------------+
20231 : : | Value | | Value |
20232 : : |------------| |------------|
20233 : :
20234 : : */
20235 : :
20236 : 10866 : extern "C" void M2Quads_BuildInclBit (void)
20237 : : {
20238 : 10866 : unsigned int tok;
20239 : 10866 : unsigned int el;
20240 : 10866 : unsigned int value;
20241 : 10866 : unsigned int t;
20242 : :
20243 : 10866 : M2Quads_PopT (&el);
20244 : 10866 : M2Quads_PopT (&value);
20245 : 10866 : tok = M2LexBuf_GetTokenNo ();
20246 : 10866 : if (SymbolTable_IsConst (el))
20247 : : {
20248 : 10816 : SymbolTable_PushValue (value); /* onto ALU stack */
20249 : 10816 : M2ALU_AddBit (tok, el); /* onto ALU stack */
20250 : 10816 : SymbolTable_PopValue (value); /* ALU -> symboltable */
20251 : : }
20252 : : else
20253 : : {
20254 : 50 : if ((SymbolTable_GetMode (el)) == SymbolTable_LeftValue)
20255 : : {
20256 : 0 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
20257 : 0 : SymbolTable_PutVar (t, SymbolTable_GetSType (el));
20258 : 0 : CheckPointerThroughNil (tok, el);
20259 : 0 : doIndrX (tok, t, el);
20260 : 0 : el = t;
20261 : : }
20262 : 50 : if (SymbolTable_IsConst (value))
20263 : : {
20264 : : /* move constant into a variable to achieve the include */
20265 : 50 : t = SymbolTable_MakeTemporary (tok, SymbolTable_RightValue);
20266 : 50 : SymbolTable_PutVar (t, SymbolTable_GetSType (value));
20267 : 50 : GenQuad (M2Quads_BecomesOp, t, SymbolTable_NulSym, value);
20268 : 50 : value = t;
20269 : : }
20270 : 50 : GenQuad (M2Quads_InclOp, value, SymbolTable_NulSym, el);
20271 : : }
20272 : 10866 : M2Quads_PushT (value);
20273 : 10866 : }
20274 : :
20275 : :
20276 : : /*
20277 : : SilentBuildConstructor - places NulSym into the constructor fifo queue.
20278 : : */
20279 : :
20280 : 0 : extern "C" void M2Quads_SilentBuildConstructor (void)
20281 : : {
20282 : 0 : FifoQueue_PutConstructorIntoFifoQueue (SymbolTable_NulSym);
20283 : 0 : }
20284 : :
20285 : :
20286 : : /*
20287 : : SilentBuildConstructorStart - removes an entry from the constructor fifo queue.
20288 : : */
20289 : :
20290 : 11560 : extern "C" void M2Quads_SilentBuildConstructorStart (void)
20291 : : {
20292 : 11560 : unsigned int constValue;
20293 : :
20294 : 11560 : FifoQueue_GetConstructorFromFifoQueue (&constValue);
20295 : 11560 : }
20296 : :
20297 : :
20298 : : /*
20299 : : BuildConstructor - builds a constructor.
20300 : : Stack
20301 : :
20302 : : Entry Exit
20303 : :
20304 : : Ptr ->
20305 : : +------------+
20306 : : | Type | <- Ptr
20307 : : |------------+
20308 : : */
20309 : :
20310 : 22046 : extern "C" void M2Quads_BuildConstructor (unsigned int tokcbrpos)
20311 : : {
20312 : 22046 : unsigned int tok;
20313 : 22046 : unsigned int constValue;
20314 : 22046 : unsigned int type;
20315 : :
20316 : 22046 : M2Quads_PopTtok (&type, &tok);
20317 : 22046 : constValue = SymbolTable_MakeTemporary (tok, SymbolTable_ImmediateValue);
20318 : 22046 : SymbolTable_PutVar (constValue, type);
20319 : 22046 : SymbolTable_PutConstructor (constValue);
20320 : 22046 : SymbolTable_PushValue (constValue);
20321 : 22046 : if (type == SymbolTable_NulSym)
20322 : : {
20323 : 6 : M2MetaError_MetaErrorT0 (tokcbrpos, (const char *) "{%E}constructor requires a type before the opening %{", 53);
20324 : : }
20325 : : else
20326 : : {
20327 : 22040 : M2ALU_ChangeToConstructor (tok, type);
20328 : 22040 : SymbolTable_PutConstructorFrom (constValue, type);
20329 : 22040 : SymbolTable_PopValue (constValue);
20330 : 22040 : FifoQueue_PutConstructorIntoFifoQueue (constValue);
20331 : : }
20332 : 22046 : PushConstructor (type);
20333 : 22046 : }
20334 : :
20335 : :
20336 : : /*
20337 : : BuildConstructorStart - builds a constructor.
20338 : : Stack
20339 : :
20340 : : Entry Exit
20341 : :
20342 : : Ptr -> <- Ptr
20343 : : +------------+ +----------------+
20344 : : | Type | | ConstructorSym |
20345 : : |------------+ |----------------|
20346 : : */
20347 : :
20348 : 10474 : extern "C" void M2Quads_BuildConstructorStart (unsigned int cbratokpos)
20349 : : {
20350 : 10474 : unsigned int typepos;
20351 : 10474 : unsigned int constValue;
20352 : 10474 : unsigned int type;
20353 : :
20354 : 10474 : M2Quads_PopTtok (&type, &typepos); /* we ignore the type as we already have the constructor symbol from pass C */
20355 : 10474 : FifoQueue_GetConstructorFromFifoQueue (&constValue); /* we ignore the type as we already have the constructor symbol from pass C */
20356 : 10474 : if (type != (SymbolTable_GetSType (constValue)))
20357 : : {
20358 : 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);
20359 : : }
20360 : 10474 : M2Quads_PushTtok (constValue, cbratokpos);
20361 : 10474 : PushConstructor (type);
20362 : 10474 : }
20363 : :
20364 : :
20365 : : /*
20366 : : BuildConstructorEnd - removes the current constructor frame from the
20367 : : constructor stack (it does not effect the quad
20368 : : stack)
20369 : :
20370 : : Entry Exit
20371 : :
20372 : : Ptr -> <- Ptr
20373 : : +------------+ +------------+
20374 : : | const | | const |
20375 : : |------------| |------------|
20376 : :
20377 : : startpos is the start of the constructor, either the typename or '{'
20378 : : cbratokpos is the '}'.
20379 : : */
20380 : :
20381 : 10474 : extern "C" void M2Quads_BuildConstructorEnd (unsigned int startpos, unsigned int cbratokpos)
20382 : : {
20383 : 10474 : unsigned int value;
20384 : 10474 : unsigned int valtok;
20385 : :
20386 : 10474 : if (DebugTokPos)
20387 : : {
20388 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "startpos", 8), startpos);
20389 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "cbratokpos", 10), cbratokpos);
20390 : : }
20391 : 10474 : M2Quads_PopTtok (&value, &valtok);
20392 : 10474 : if (DebugTokPos)
20393 : : {
20394 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "value valtok", 12), valtok);
20395 : : }
20396 : 10474 : valtok = M2LexBuf_MakeVirtual2Tok (startpos, cbratokpos);
20397 : 10474 : SymbolTable_PutDeclared (valtok, value);
20398 : 10474 : M2Quads_PushTtok (value, valtok); /* Use valtok as we now know it was a constructor. */
20399 : 10474 : M2Quads_PopConstructor (); /* Use valtok as we now know it was a constructor. */
20400 : 10474 : if (DebugTokPos)
20401 : : {
20402 : : M2Error_WarnStringAt (DynamicStrings_InitString ((const char *) "aggregate constant", 18), valtok);
20403 : : }
20404 : 10474 : }
20405 : :
20406 : :
20407 : : /*
20408 : : NextConstructorField - increments the top of constructor stacks index by one.
20409 : : */
20410 : :
20411 : 33460 : extern "C" void M2Quads_NextConstructorField (void)
20412 : : {
20413 : 33460 : M2Quads_ConstructorFrame c;
20414 : :
20415 : 33460 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20416 : 33460 : c->index += 1;
20417 : 33460 : }
20418 : :
20419 : :
20420 : : /*
20421 : : BuildTypeForConstructor - pushes the type implied by the current constructor.
20422 : : If no constructor is currently being built then
20423 : : it Pushes a Bitset type.
20424 : : */
20425 : :
20426 : 1728 : extern "C" void M2Quads_BuildTypeForConstructor (unsigned int tokpos)
20427 : : {
20428 : 1728 : M2Quads_ConstructorFrame c;
20429 : :
20430 : 1728 : if ((M2StackAddress_NoOfItemsInStackAddress (ConstructorStack)) == 0)
20431 : : {
20432 : 660 : M2Quads_PushTtok (M2Bitset_Bitset, tokpos);
20433 : : }
20434 : : else
20435 : : {
20436 : 1068 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PeepAddress (ConstructorStack, 1));
20437 : 1068 : if ((SymbolTable_IsArray (c->type)) || (SymbolTable_IsSet (c->type)))
20438 : : {
20439 : 972 : M2Quads_PushTtok (SymbolTable_GetSType (c->type), tokpos);
20440 : : }
20441 : 96 : else if (SymbolTable_IsRecord (c->type))
20442 : : {
20443 : : /* avoid dangling else. */
20444 : 96 : M2Quads_PushTtok (SymbolTable_GetSType (SymbolTable_GetNth (c->type, c->index)), tokpos);
20445 : : }
20446 : : else
20447 : : {
20448 : : /* avoid dangling else. */
20449 : 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);
20450 : : }
20451 : : }
20452 : 1728 : }
20453 : :
20454 : :
20455 : : /*
20456 : : BuildComponentValue - builds a component value.
20457 : :
20458 : : Entry Exit
20459 : :
20460 : : Ptr -> <- Ptr
20461 : :
20462 : :
20463 : : +------------+ +------------+
20464 : : | const | | const |
20465 : : |------------| |------------|
20466 : : */
20467 : :
20468 : 24808 : extern "C" void M2Quads_BuildComponentValue (void)
20469 : : {
20470 : 24808 : unsigned int const_;
20471 : 24808 : unsigned int e1;
20472 : 24808 : unsigned int e2;
20473 : 24808 : NameKey_Name nuldotdot;
20474 : 24808 : NameKey_Name nulby;
20475 : :
20476 : 24808 : M2Quads_PopT (&nulby);
20477 : 24808 : if (nulby == M2Reserved_NulTok)
20478 : : {
20479 : 24778 : M2Quads_PopT (&nuldotdot);
20480 : 24778 : if (nuldotdot == M2Reserved_NulTok)
20481 : : {
20482 : 24536 : M2Quads_PopT (&e1);
20483 : 24536 : M2Quads_PopT (&const_);
20484 : 24536 : M2Quads_PushT (AddFieldTo (const_, e1));
20485 : : }
20486 : : else
20487 : : {
20488 : 242 : M2Quads_PopT (&e2);
20489 : 242 : M2Quads_PopT (&e1);
20490 : 242 : M2Quads_PopT (&const_);
20491 : 242 : SymbolTable_PushValue (const_);
20492 : 242 : M2ALU_AddBitRange (M2LexBuf_GetTokenNo (), e1, e2);
20493 : 242 : SymbolTable_PopValue (const_);
20494 : 242 : M2Quads_PushT (const_);
20495 : : }
20496 : : }
20497 : : else
20498 : : {
20499 : 30 : M2Quads_PopT (&e1);
20500 : 30 : M2Quads_PopT (&nuldotdot);
20501 : 30 : if (nuldotdot == M2Reserved_NulTok)
20502 : : {
20503 : 30 : M2Quads_PopT (&e2);
20504 : 30 : M2Quads_PopT (&const_);
20505 : 30 : SymbolTable_PushValue (const_);
20506 : 30 : M2ALU_AddElements (M2LexBuf_GetTokenNo (), e2, e1);
20507 : 30 : SymbolTable_PopValue (const_);
20508 : 30 : M2Quads_PushT (const_);
20509 : : }
20510 : : else
20511 : : {
20512 : 0 : M2Quads_PopT (&e2);
20513 : 0 : M2Quads_PopT (&e1);
20514 : 0 : M2Quads_PopT (&const_);
20515 : 0 : M2Error_WriteFormat0 ((const char *) "the constant must be either an array constructor or a set constructor", 69);
20516 : 0 : M2Quads_PushT (const_);
20517 : : }
20518 : : }
20519 : 24808 : }
20520 : :
20521 : :
20522 : : /*
20523 : : PopConstructor - removes the top constructor from the top of stack.
20524 : : */
20525 : :
20526 : 32520 : extern "C" void M2Quads_PopConstructor (void)
20527 : : {
20528 : 32520 : M2Quads_ConstructorFrame c;
20529 : :
20530 : 32520 : c = static_cast<M2Quads_ConstructorFrame> (M2StackAddress_PopAddress (ConstructorStack));
20531 : 32520 : Storage_DEALLOCATE ((void **) &c, sizeof (M2Quads__T1));
20532 : 32520 : }
20533 : :
20534 : :
20535 : : /*
20536 : : BuildNot - Builds a NOT operation from the quad stack.
20537 : : The Stack is expected to contain:
20538 : :
20539 : :
20540 : : Entry Exit
20541 : : ===== ====
20542 : :
20543 : : Ptr -> <- Ptr
20544 : : +------------+ +------------+
20545 : : | t | f | | f | t |
20546 : : |------------| |------------|
20547 : : */
20548 : :
20549 : 4200 : extern "C" void M2Quads_BuildNot (unsigned int notTokPos)
20550 : : {
20551 : 4200 : unsigned int combinedTok;
20552 : 4200 : unsigned int exprTokPos;
20553 : 4200 : unsigned int t;
20554 : 4200 : unsigned int f;
20555 : :
20556 : 4200 : CheckBooleanId ();
20557 : 4200 : PopBooltok (&t, &f, &exprTokPos);
20558 : 4200 : combinedTok = M2LexBuf_MakeVirtualTok (notTokPos, notTokPos, exprTokPos);
20559 : 4200 : PushBooltok (f, t, combinedTok);
20560 : 4200 : }
20561 : :
20562 : :
20563 : : /*
20564 : : RecordOp - Records the operator passed on the stack.
20565 : : This is called when a boolean operator is found in an
20566 : : expression. It is called just after the lhs has been built
20567 : : and pushed to the quad stack and prior to the rhs build.
20568 : : It checks to see if AND OR or equality tests are required.
20569 : : It will short circuit AND and OR expressions. It also
20570 : : converts a lhs to a boolean variable if an xor comparison
20571 : : is about to be performed.
20572 : :
20573 : : Checks for AND operator or OR operator
20574 : : if either of these operators are found then BackPatching
20575 : : takes place.
20576 : : The Expected Stack:
20577 : :
20578 : : Entry Exit
20579 : :
20580 : : Ptr -> <- Ptr
20581 : : +-------------+ +-------------+
20582 : : | OperatorTok | | OperatorTok |
20583 : : |-------------| |-------------|
20584 : : | t | f | | t | f |
20585 : : |-------------| |-------------|
20586 : :
20587 : :
20588 : : If OperatorTok=AndTok
20589 : : Then
20590 : : BackPatch(f, NextQuad)
20591 : : Elsif OperatorTok=OrTok
20592 : : Then
20593 : : BackPatch(t, NextQuad)
20594 : : End
20595 : : */
20596 : :
20597 : 79646 : extern "C" void M2Quads_RecordOp (void)
20598 : : {
20599 : 79646 : NameKey_Name Op;
20600 : 79646 : unsigned int tokno;
20601 : 79646 : unsigned int t;
20602 : 79646 : unsigned int f;
20603 : :
20604 : 79646 : M2Quads_PopTtok (&Op, &tokno);
20605 : 79646 : if ((Op == M2Reserved_AndTok) || (Op == M2Reserved_AmbersandTok))
20606 : : {
20607 : 7860 : CheckBooleanId ();
20608 : 7860 : PopBool (&t, &f);
20609 : 7860 : BackPatch (t, NextQuad);
20610 : 7860 : PushBool (0, f);
20611 : : }
20612 : 71786 : else if (Op == M2Reserved_OrTok)
20613 : : {
20614 : : /* avoid dangling else. */
20615 : 3206 : CheckBooleanId ();
20616 : 3206 : PopBool (&t, &f);
20617 : 3206 : BackPatch (f, NextQuad);
20618 : 3206 : PushBool (t, 0);
20619 : : }
20620 : 68580 : else if ((IsBoolean (1)) && ((((Op == M2Reserved_EqualTok) || (Op == M2Reserved_LessGreaterTok)) || (Op == M2Reserved_HashTok)) || (Op == M2Reserved_InTok)))
20621 : : {
20622 : : /* avoid dangling else. */
20623 : 24 : ConvertBooleanToVariable (tokno, 1);
20624 : : }
20625 : 79646 : M2Quads_PushTtok (Op, tokno);
20626 : 79646 : }
20627 : :
20628 : :
20629 : : /*
20630 : : BuildRelOp - Builds a relative operation from the quad stack.
20631 : : The Stack is expected to contain:
20632 : :
20633 : :
20634 : : Entry Exit
20635 : : ===== ====
20636 : :
20637 : : Ptr ->
20638 : : +------------+
20639 : : | e1 |
20640 : : |------------| <- Ptr
20641 : : | Operator |
20642 : : |------------| +------------+
20643 : : | e2 | | t | f |
20644 : : |------------| |------------|
20645 : :
20646 : :
20647 : : Quadruples Produced
20648 : :
20649 : : q IFOperator e2 e1 TrueExit ; e2 e1 since
20650 : : q+1 GotoOp FalseExit ; relation > etc
20651 : : ; requires order.
20652 : : */
20653 : :
20654 : 74751 : extern "C" void M2Quads_BuildRelOp (unsigned int optokpos)
20655 : : {
20656 : 74751 : unsigned int combinedTok;
20657 : 74751 : unsigned int rightpos;
20658 : 74751 : unsigned int leftpos;
20659 : 74751 : NameKey_Name Op;
20660 : 74751 : unsigned int t;
20661 : 74751 : unsigned int rightType;
20662 : 74751 : unsigned int leftType;
20663 : 74751 : unsigned int right;
20664 : 74751 : unsigned int left;
20665 : 74751 : DynamicStrings_String s;
20666 : :
20667 : 74751 : if (M2Options_CompilerDebugging)
20668 : : {
20669 : 0 : M2Quads_DisplayStack (); /* Debugging info */
20670 : : }
20671 : 74751 : if (((M2Quads_IsInConstExpression ()) && (IsBoolean (1))) && (IsBoolean (3)))
20672 : : {
20673 : : /*
20674 : : we allow # and = to be used with Boolean expressions.
20675 : : we do not allow > < >= <= though. We only examine
20676 : : this case if we are in a const expression as there will be
20677 : : no dereferencing of operands.
20678 : : */
20679 : 0 : BuildRelOpFromBoolean (optokpos);
20680 : : }
20681 : : else
20682 : : {
20683 : 74751 : if (IsBoolean (1))
20684 : : {
20685 : 36 : ConvertBooleanToVariable (OperandTtok (1), 1);
20686 : : }
20687 : 74751 : if (IsBoolean (3))
20688 : : {
20689 : 0 : ConvertBooleanToVariable (OperandTtok (3), 3);
20690 : : }
20691 : 74751 : M2Quads_PopTFtok (&right, &rightType, &rightpos);
20692 : 74751 : M2Quads_PopT (&Op);
20693 : 74751 : M2Quads_PopTFtok (&left, &leftType, &leftpos);
20694 : 74751 : CheckVariableOrConstantOrProcedure (rightpos, right);
20695 : 74751 : CheckVariableOrConstantOrProcedure (leftpos, left);
20696 : 74751 : combinedTok = M2LexBuf_MakeVirtualTok (optokpos, leftpos, rightpos);
20697 : 74751 : if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
20698 : : {
20699 : : /* BuildRange will check the expression later on once gcc knows about all data types. */
20700 : 74751 : BuildRange (M2Range_InitTypesExpressionCheck (combinedTok, left, right, true, Op == M2Reserved_InTok));
20701 : : }
20702 : : /* Must dereference LeftValue operands. */
20703 : 74751 : if ((SymbolTable_GetMode (right)) == SymbolTable_LeftValue)
20704 : : {
20705 : 1380 : t = SymbolTable_MakeTemporary (rightpos, SymbolTable_RightValue);
20706 : 1380 : SymbolTable_PutVar (t, SymbolTable_GetSType (right));
20707 : 1380 : CheckPointerThroughNil (rightpos, right);
20708 : 1380 : doIndrX (rightpos, t, right);
20709 : 1380 : right = t;
20710 : : }
20711 : 74751 : if ((SymbolTable_GetMode (left)) == SymbolTable_LeftValue)
20712 : : {
20713 : 6145 : t = SymbolTable_MakeTemporary (leftpos, SymbolTable_RightValue);
20714 : 6145 : SymbolTable_PutVar (t, SymbolTable_GetSType (left));
20715 : 6145 : CheckPointerThroughNil (leftpos, left);
20716 : 6145 : doIndrX (leftpos, t, left);
20717 : 6145 : left = t;
20718 : : }
20719 : 74751 : if (DebugTokPos)
20720 : : {
20721 : : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (M2LexBuf_GetTokenName (Op)));
20722 : : M2Error_WarnStringAt (s, optokpos);
20723 : : s = DynamicStrings_InitString ((const char *) "left", 4);
20724 : : M2Error_WarnStringAt (s, leftpos);
20725 : : s = DynamicStrings_InitString ((const char *) "right", 5);
20726 : : M2Error_WarnStringAt (s, rightpos);
20727 : : s = DynamicStrings_InitString ((const char *) "caret", 5);
20728 : : M2Error_WarnStringAt (s, optokpos);
20729 : : s = DynamicStrings_InitString ((const char *) "combined", 8);
20730 : : M2Error_WarnStringAt (s, combinedTok);
20731 : : }
20732 : 74751 : GenQuadOtok (combinedTok, MakeOp (Op), left, right, 0, false, leftpos, rightpos, M2LexBuf_UnknownTokenNo); /* True Exit */
20733 : 74751 : GenQuadO (combinedTok, M2Quads_GotoOp, SymbolTable_NulSym, SymbolTable_NulSym, 0, false); /* False Exit */
20734 : 74751 : PushBooltok (NextQuad-2, NextQuad-1, combinedTok); /* False Exit */
20735 : : }
20736 : 74751 : }
20737 : :
20738 : :
20739 : : /*
20740 : : BuildBinaryOp - Builds a binary operation from the quad stack.
20741 : : Be aware that this procedure will check for
20742 : : the overloading of the bitset operators + - \ *.
20743 : : So do NOT call this procedure if you are building
20744 : : a reference to an array which has a bitset type or
20745 : : the address arithmetic will be wrongly coersed into
20746 : : logical ORs.
20747 : :
20748 : : The Stack is expected to contain:
20749 : :
20750 : :
20751 : : Entry Exit
20752 : : ===== ====
20753 : :
20754 : : Ptr ->
20755 : : +------------+
20756 : : | Sym1 |
20757 : : |------------|
20758 : : | Operator | <- Ptr
20759 : : |------------| +------------+
20760 : : | Sym2 | | Temporary |
20761 : : |------------| |------------|
20762 : :
20763 : :
20764 : : Quadruples Produced
20765 : :
20766 : : q Operator Temporary Sym1 Sym2
20767 : :
20768 : :
20769 : : OR
20770 : :
20771 : :
20772 : : Entry Exit
20773 : : ===== ====
20774 : :
20775 : : Ptr ->
20776 : : +------------+
20777 : : | T1 | F1 |
20778 : : |------------|
20779 : : | OrTok | <- Ptr
20780 : : |------------| +------------+
20781 : : | T2 | F2 | | T1+T2| F1 |
20782 : : |------------| |------------|
20783 : :
20784 : :
20785 : : Quadruples Produced
20786 : :
20787 : : */
20788 : :
20789 : 50982 : extern "C" void M2Quads_BuildBinaryOp (void)
20790 : : {
20791 : 50982 : doBuildBinaryOp (true, true);
20792 : 50874 : }
20793 : :
20794 : :
20795 : : /*
20796 : : BuildUnaryOp - Builds a unary operation from the quad stack.
20797 : : The Stack is expected to contain:
20798 : :
20799 : :
20800 : : Entry Exit
20801 : : ===== ====
20802 : :
20803 : : Ptr ->
20804 : : +------------+
20805 : : | Sym |
20806 : : |------------| +------------+
20807 : : | Operator | | Temporary | <- Ptr
20808 : : |------------| |------------|
20809 : :
20810 : :
20811 : : Quadruples Produced
20812 : :
20813 : : q Operator Temporary _ Sym
20814 : :
20815 : : */
20816 : :
20817 : 20454 : extern "C" void M2Quads_BuildUnaryOp (void)
20818 : : {
20819 : 20454 : unsigned int sympos;
20820 : 20454 : unsigned int tokpos;
20821 : 20454 : NameKey_Name Tok;
20822 : 20454 : unsigned int type;
20823 : 20454 : unsigned int Sym;
20824 : 20454 : unsigned int SymT;
20825 : 20454 : unsigned int r;
20826 : 20454 : unsigned int t;
20827 : :
20828 : 20454 : PopTrwtok (&Sym, &r, &sympos);
20829 : 20454 : M2Quads_PopTtok (&Tok, &tokpos);
20830 : 20454 : if (Tok == M2Reserved_MinusTok)
20831 : : {
20832 : 20310 : MarkAsRead (r);
20833 : 20310 : type = M2Base_NegateType (SymbolTable_GetSType (Sym)); /* , sympos */
20834 : 20310 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20835 : 40620 : t = SymbolTable_MakeTemporary (tokpos, AreConstant (SymbolTable_IsConst (Sym)));
20836 : 20310 : SymbolTable_PutVar (t, type);
20837 : : /*
20838 : : variables must have a type and REAL/LONGREAL constants must
20839 : : be typed
20840 : : */
20841 : 20310 : if (! (SymbolTable_IsConst (Sym)))
20842 : : {
20843 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
20844 : 840 : if ((type != SymbolTable_NulSym) && (SymbolTable_IsSet (SymbolTable_SkipType (type))))
20845 : : {} /* empty. */
20846 : : /* do not dereference set variables */
20847 : 818 : else if ((SymbolTable_GetMode (Sym)) == SymbolTable_LeftValue)
20848 : : {
20849 : : /* avoid dangling else. */
20850 : : /* dereference symbols which are not sets and which are variables */
20851 : 0 : SymT = SymbolTable_MakeTemporary (sympos, SymbolTable_RightValue);
20852 : 0 : SymbolTable_PutVar (SymT, SymbolTable_GetSType (Sym));
20853 : 0 : CheckPointerThroughNil (sympos, Sym);
20854 : 0 : doIndrX (sympos, SymT, Sym);
20855 : 0 : Sym = SymT;
20856 : : }
20857 : : }
20858 : 20310 : GenQuadO (tokpos, M2Quads_NegateOp, t, SymbolTable_NulSym, Sym, true);
20859 : 20310 : M2Quads_PushTtok (t, tokpos);
20860 : : }
20861 : 144 : else if (Tok == M2Reserved_PlusTok)
20862 : : {
20863 : : /* avoid dangling else. */
20864 : 144 : tokpos = M2LexBuf_MakeVirtualTok (tokpos, tokpos, sympos);
20865 : 144 : PushTrwtok (Sym, r, tokpos);
20866 : : }
20867 : : else
20868 : : {
20869 : : /* avoid dangling else. */
20870 : 0 : M2MetaError_MetaErrorNT1 (tokpos, (const char *) "expecting an unary operator, seen {%Ek%a}", 41, Tok);
20871 : : }
20872 : 20454 : }
20873 : :
20874 : :
20875 : : /*
20876 : : OperandT - returns the ident operand stored in the true position on the boolean stack.
20877 : : */
20878 : :
20879 : 129313327 : extern "C" unsigned int M2Quads_OperandT (unsigned int pos)
20880 : : {
20881 : 129313327 : M2Debug_Assert (! (IsBoolean (pos)));
20882 : 129313327 : return OperandTno (pos);
20883 : : /* static analysis guarentees a RETURN statement will be used before here. */
20884 : : __builtin_unreachable ();
20885 : : }
20886 : :
20887 : :
20888 : : /*
20889 : : OperandF - returns the ident operand stored in the false position on the boolean stack.
20890 : : */
20891 : :
20892 : 150710 : extern "C" unsigned int M2Quads_OperandF (unsigned int pos)
20893 : : {
20894 : 150710 : M2Debug_Assert (! (IsBoolean (pos)));
20895 : 150710 : return OperandFno (pos);
20896 : : /* static analysis guarentees a RETURN statement will be used before here. */
20897 : : __builtin_unreachable ();
20898 : : }
20899 : :
20900 : :
20901 : : /*
20902 : : PushTF - Push a True and False numbers onto the True/False stack.
20903 : : True and False are assumed to contain Symbols or Ident etc.
20904 : : */
20905 : :
20906 : 8865816 : extern "C" void M2Quads_PushTF (unsigned int True, unsigned int False)
20907 : : {
20908 : 8865816 : M2Quads_BoolFrame f;
20909 : :
20910 : 8865816 : f = newBoolFrame ();
20911 : 8865816 : f->TrueExit = static_cast<unsigned int> (True);
20912 : 8865816 : f->FalseExit = static_cast<unsigned int> (False);
20913 : 8865816 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20914 : 8865816 : }
20915 : :
20916 : :
20917 : : /*
20918 : : PopTF - Pop a True and False number from the True/False stack.
20919 : : True and False are assumed to contain Symbols or Ident etc.
20920 : : */
20921 : :
20922 : 6233464 : extern "C" void M2Quads_PopTF (unsigned int *True, unsigned int *False)
20923 : : {
20924 : 6233464 : M2Quads_BoolFrame f;
20925 : :
20926 : 6233464 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20927 : 6233464 : (*True) = static_cast<unsigned int> (f->TrueExit);
20928 : 6233464 : (*False) = static_cast<unsigned int> (f->FalseExit);
20929 : 6233464 : M2Debug_Assert (! f->BooleanOp);
20930 : 6233464 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20931 : 6233464 : }
20932 : :
20933 : :
20934 : : /*
20935 : : PushT - Push an item onto the stack in the T (true) position.
20936 : : */
20937 : :
20938 : 59833443 : extern "C" void M2Quads_PushT (unsigned int True)
20939 : : {
20940 : 59833443 : M2Quads_BoolFrame f;
20941 : :
20942 : 59833443 : f = newBoolFrame ();
20943 : 59833443 : f->TrueExit = static_cast<unsigned int> (True);
20944 : 59833443 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20945 : 59833443 : }
20946 : :
20947 : :
20948 : : /*
20949 : : PopT - Pops the T value from the stack.
20950 : : */
20951 : :
20952 : 86590477 : extern "C" void M2Quads_PopT (unsigned int *True)
20953 : : {
20954 : 86590477 : M2Quads_BoolFrame f;
20955 : :
20956 : 86590477 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
20957 : 86590471 : (*True) = static_cast<unsigned int> (f->TrueExit);
20958 : 86590471 : M2Debug_Assert (! f->BooleanOp);
20959 : 86590471 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
20960 : 86590471 : }
20961 : :
20962 : :
20963 : : /*
20964 : : PushTtok - Push an item onto the stack in the T (true) position,
20965 : : it is assummed to be a token and its token location is recorded.
20966 : : */
20967 : :
20968 : 44513701 : extern "C" void M2Quads_PushTtok (unsigned int True, unsigned int tokno)
20969 : : {
20970 : 44513701 : M2Quads_BoolFrame f;
20971 : :
20972 : : /* PrintTokenNo (tokno) ; */
20973 : 44513701 : f = newBoolFrame ();
20974 : 44513701 : f->TrueExit = static_cast<unsigned int> (True);
20975 : 44513701 : f->tokenno = tokno;
20976 : 44513701 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20977 : 44513701 : }
20978 : :
20979 : :
20980 : : /*
20981 : : PushTFtok - Push an item onto the stack in the T (true) position,
20982 : : it is assummed to be a token and its token location is recorded.
20983 : : */
20984 : :
20985 : 92800901 : extern "C" void M2Quads_PushTFtok (unsigned int True, unsigned int False, unsigned int tokno)
20986 : : {
20987 : 92800901 : M2Quads_BoolFrame f;
20988 : :
20989 : 92800901 : f = newBoolFrame ();
20990 : 92800901 : f->TrueExit = static_cast<unsigned int> (True);
20991 : 92800901 : f->FalseExit = static_cast<unsigned int> (False);
20992 : 92800901 : f->tokenno = tokno;
20993 : 92800901 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
20994 : 92800901 : }
20995 : :
20996 : :
20997 : : /*
20998 : : PopTFtok - Pop T/F/tok from the stack.
20999 : : */
21000 : :
21001 : 5927873 : extern "C" void M2Quads_PopTFtok (unsigned int *True, unsigned int *False, unsigned int *tokno)
21002 : : {
21003 : 5927873 : M2Quads_BoolFrame f;
21004 : :
21005 : 5927873 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21006 : 5927873 : (*True) = static_cast<unsigned int> (f->TrueExit);
21007 : 5927873 : (*False) = static_cast<unsigned int> (f->FalseExit);
21008 : 5927873 : (*tokno) = f->tokenno;
21009 : 5927873 : }
21010 : :
21011 : :
21012 : : /*
21013 : : PushTFAtok - Push T/F/A/tok to the stack.
21014 : : */
21015 : :
21016 : 54 : extern "C" void M2Quads_PushTFAtok (unsigned int True, unsigned int False, unsigned int Array, unsigned int tokno)
21017 : : {
21018 : 54 : M2Quads_BoolFrame f;
21019 : :
21020 : 54 : f = newBoolFrame ();
21021 : 54 : f->TrueExit = static_cast<unsigned int> (True);
21022 : 54 : f->FalseExit = static_cast<unsigned int> (False);
21023 : 54 : f->Unbounded = static_cast<unsigned int> (Array);
21024 : 54 : f->tokenno = tokno;
21025 : 54 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21026 : 54 : }
21027 : :
21028 : :
21029 : : /*
21030 : : PopTtok - Pops the T value from the stack and token position.
21031 : : */
21032 : :
21033 : 66196560 : extern "C" void M2Quads_PopTtok (unsigned int *True, unsigned int *tok)
21034 : : {
21035 : 66196560 : M2Quads_BoolFrame f;
21036 : :
21037 : 66196560 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21038 : 66196560 : (*True) = static_cast<unsigned int> (f->TrueExit);
21039 : 66196560 : (*tok) = f->tokenno;
21040 : 66196560 : M2Debug_Assert (! f->BooleanOp);
21041 : 66196560 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21042 : 66196560 : }
21043 : :
21044 : :
21045 : : /*
21046 : : PushTFn - Push a True and False numbers onto the True/False stack.
21047 : : True and False are assumed to contain Symbols or Ident etc.
21048 : : */
21049 : :
21050 : 0 : extern "C" void M2Quads_PushTFn (unsigned int True, unsigned int False, unsigned int n)
21051 : : {
21052 : 0 : M2Quads_BoolFrame f;
21053 : :
21054 : 0 : f = newBoolFrame ();
21055 : 0 : f->TrueExit = static_cast<unsigned int> (True);
21056 : 0 : f->FalseExit = static_cast<unsigned int> (False);
21057 : 0 : f->name = static_cast<unsigned int> (n);
21058 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21059 : 0 : }
21060 : :
21061 : :
21062 : : /*
21063 : : PushTFntok - Push a True and False numbers onto the True/False stack.
21064 : : True and False are assumed to contain Symbols or Ident etc.
21065 : : */
21066 : :
21067 : 547522 : extern "C" void M2Quads_PushTFntok (unsigned int True, unsigned int False, unsigned int n, unsigned int tokno)
21068 : : {
21069 : 547522 : M2Quads_BoolFrame f;
21070 : :
21071 : 547522 : f = newBoolFrame ();
21072 : 547522 : f->TrueExit = static_cast<unsigned int> (True);
21073 : 547522 : f->FalseExit = static_cast<unsigned int> (False);
21074 : 547522 : f->name = static_cast<unsigned int> (n);
21075 : 547522 : f->tokenno = tokno;
21076 : 547522 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21077 : 547522 : }
21078 : :
21079 : :
21080 : : /*
21081 : : PopTFn - Pop a True and False number from the True/False stack.
21082 : : True and False are assumed to contain Symbols or Ident etc.
21083 : : */
21084 : :
21085 : 0 : extern "C" void M2Quads_PopTFn (unsigned int *True, unsigned int *False, unsigned int *n)
21086 : : {
21087 : 0 : M2Quads_BoolFrame f;
21088 : :
21089 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21090 : 0 : (*True) = static_cast<unsigned int> (f->TrueExit);
21091 : 0 : (*False) = static_cast<unsigned int> (f->FalseExit);
21092 : 0 : (*n) = static_cast<unsigned int> (f->name);
21093 : 0 : M2Debug_Assert (! f->BooleanOp);
21094 : 0 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21095 : 0 : }
21096 : :
21097 : :
21098 : : /*
21099 : : PopNothing - pops the top element on the boolean stack.
21100 : : */
21101 : :
21102 : 40742463 : extern "C" void M2Quads_PopNothing (void)
21103 : : {
21104 : 40742463 : M2Quads_BoolFrame f;
21105 : :
21106 : 40742463 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21107 : 40742463 : Storage_DEALLOCATE ((void **) &f, sizeof (M2Quads__T2));
21108 : 40742463 : }
21109 : :
21110 : :
21111 : : /*
21112 : : PopN - pops multiple elements from the BoolStack.
21113 : : */
21114 : :
21115 : 8053373 : extern "C" void M2Quads_PopN (unsigned int n)
21116 : : {
21117 : 31752106 : while (n > 0)
21118 : : {
21119 : 23698733 : M2Quads_PopNothing ();
21120 : 23698733 : n -= 1;
21121 : : }
21122 : 8053373 : }
21123 : :
21124 : :
21125 : : /*
21126 : : PushTFA - Push True, False, Array, numbers onto the
21127 : : True/False stack. True and False are assumed to
21128 : : contain Symbols or Ident etc.
21129 : : */
21130 : :
21131 : 0 : extern "C" void M2Quads_PushTFA (unsigned int True, unsigned int False, unsigned int Array)
21132 : : {
21133 : 0 : M2Quads_BoolFrame f;
21134 : :
21135 : 0 : f = newBoolFrame ();
21136 : 0 : f->TrueExit = static_cast<unsigned int> (True);
21137 : 0 : f->FalseExit = static_cast<unsigned int> (False);
21138 : 0 : f->Unbounded = static_cast<unsigned int> (Array);
21139 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21140 : 0 : }
21141 : :
21142 : :
21143 : : /*
21144 : : OperandTok - returns the token associated with pos, on the stack.
21145 : : */
21146 : :
21147 : 35856408 : extern "C" unsigned int M2Quads_OperandTok (unsigned int pos)
21148 : : {
21149 : 35856408 : M2Debug_Assert (! (IsBoolean (pos)));
21150 : 35856408 : return static_cast<unsigned int> (OperandTtok (pos));
21151 : : /* static analysis guarentees a RETURN statement will be used before here. */
21152 : : __builtin_unreachable ();
21153 : : }
21154 : :
21155 : :
21156 : : /*
21157 : : OperandA - returns possible array symbol associated with the ident
21158 : : operand stored on the boolean stack.
21159 : : */
21160 : :
21161 : 1408571 : extern "C" unsigned int M2Quads_OperandA (unsigned int pos)
21162 : : {
21163 : 1408571 : M2Quads_BoolFrame f;
21164 : :
21165 : 1408571 : M2Debug_Assert (pos > 0);
21166 : 1408571 : M2Debug_Assert (! (IsBoolean (pos)));
21167 : 1408571 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, pos));
21168 : 1408571 : return static_cast<unsigned int> (f->Unbounded);
21169 : : /* static analysis guarentees a RETURN statement will be used before here. */
21170 : : __builtin_unreachable ();
21171 : : }
21172 : :
21173 : :
21174 : : /*
21175 : : OperandAnno - returns the annotation string associated with the
21176 : : position, n, on the stack.
21177 : : */
21178 : :
21179 : 0 : extern "C" DynamicStrings_String M2Quads_OperandAnno (unsigned int n)
21180 : : {
21181 : 0 : M2Quads_BoolFrame f;
21182 : :
21183 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, n));
21184 : 0 : return f->Annotation;
21185 : : /* static analysis guarentees a RETURN statement will be used before here. */
21186 : : __builtin_unreachable ();
21187 : : }
21188 : :
21189 : :
21190 : : /*
21191 : : Annotate - annotate the top of stack.
21192 : : */
21193 : :
21194 : 74962793 : extern "C" void M2Quads_Annotate (const char *a_, unsigned int _a_high)
21195 : : {
21196 : 74962793 : M2Quads_BoolFrame f;
21197 : 74962793 : char a[_a_high+1];
21198 : :
21199 : : /* make a local copy of each unbounded array. */
21200 : 74962793 : memcpy (a, a_, _a_high+1);
21201 : :
21202 : 0 : if ((DebugStackOn && M2Options_CompilerDebugging) && ((M2StackAddress_NoOfItemsInStackAddress (BoolStack)) > 0))
21203 : : {
21204 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PeepAddress (BoolStack, 1)); /* top of stack */
21205 : 0 : if (f->Annotation != NULL) /* top of stack */
21206 : : {
21207 : 0 : f->Annotation = DynamicStrings_KillString (f->Annotation);
21208 : : }
21209 : 0 : f->Annotation = DynamicStrings_InitString ((const char *) a, _a_high);
21210 : : }
21211 : 74962793 : }
21212 : :
21213 : :
21214 : : /*
21215 : : DisplayStack - displays the compile time symbol stack.
21216 : : */
21217 : :
21218 : 12943514 : extern "C" void M2Quads_DisplayStack (void)
21219 : : {
21220 : 12943514 : if (DebugStackOn && M2Options_CompilerDebugging)
21221 : : {
21222 : 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});
21223 : : }
21224 : 12943514 : }
21225 : :
21226 : :
21227 : : /*
21228 : : Top - returns the no of items held in the stack.
21229 : : */
21230 : :
21231 : 51215648 : extern "C" unsigned int M2Quads_Top (void)
21232 : : {
21233 : 51215648 : return M2StackAddress_NoOfItemsInStackAddress (BoolStack);
21234 : : /* static analysis guarentees a RETURN statement will be used before here. */
21235 : : __builtin_unreachable ();
21236 : : }
21237 : :
21238 : :
21239 : : /*
21240 : : DupFrame - duplicate the top of stack and push the new frame.
21241 : : */
21242 : :
21243 : 0 : extern "C" void M2Quads_DupFrame (void)
21244 : : {
21245 : 0 : M2Quads_BoolFrame f;
21246 : 0 : M2Quads_BoolFrame newf;
21247 : :
21248 : 0 : f = static_cast<M2Quads_BoolFrame> (M2StackAddress_PopAddress (BoolStack));
21249 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (f));
21250 : 0 : newf = newBoolFrame ();
21251 : 0 : (*newf) = (*f);
21252 : 0 : M2StackAddress_PushAddress (BoolStack, reinterpret_cast <void *> (newf));
21253 : 0 : }
21254 : :
21255 : :
21256 : : /*
21257 : : WriteOperand - displays the operands name, symbol id and mode of addressing.
21258 : : */
21259 : :
21260 : 0 : extern "C" void M2Quads_WriteOperand (unsigned int Sym)
21261 : : {
21262 : 0 : NameKey_Name n;
21263 : :
21264 : 0 : if (Sym == SymbolTable_NulSym)
21265 : : {
21266 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "<nulsym>", 8);
21267 : : }
21268 : : else
21269 : : {
21270 : 0 : n = SymbolTable_GetSymName (Sym);
21271 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "%a", 2, (const unsigned char *) &n, (sizeof (n)-1));
21272 : 0 : if ((SymbolTable_IsVar (Sym)) || (SymbolTable_IsConst (Sym)))
21273 : : {
21274 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "[", 1);
21275 : 0 : WriteMode (SymbolTable_GetMode (Sym));
21276 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "]", 1);
21277 : : }
21278 : 0 : M2Printf_fprintf1 (M2LangDump_GetDumpFile (), (const char *) "(%d)", 4, (const unsigned char *) &Sym, (sizeof (Sym)-1));
21279 : : }
21280 : 0 : }
21281 : :
21282 : :
21283 : : /*
21284 : : BeginVarient - begin a varient record.
21285 : : */
21286 : :
21287 : 276 : extern "C" void M2Quads_BeginVarient (void)
21288 : : {
21289 : 276 : unsigned int r;
21290 : 276 : unsigned int v;
21291 : :
21292 : 276 : r = GetRecordOrField ();
21293 : 552 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
21294 : 276 : v = GetRecordOrField ();
21295 : 276 : M2Debug_Assert (SymbolTable_IsVarient (v));
21296 : 276 : BuildRange (M2Range_InitCaseBounds (M2CaseList_PushCase (r, v, SymbolTable_NulSym)));
21297 : 276 : }
21298 : :
21299 : :
21300 : : /*
21301 : : EndVarient - end a varient record.
21302 : : */
21303 : :
21304 : 276 : extern "C" void M2Quads_EndVarient (void)
21305 : : {
21306 : 276 : M2CaseList_PopCase ();
21307 : 276 : }
21308 : :
21309 : :
21310 : : /*
21311 : : ElseVarient - associate an ELSE clause with a varient record.
21312 : : */
21313 : :
21314 : 114 : extern "C" void M2Quads_ElseVarient (void)
21315 : : {
21316 : 114 : unsigned int f;
21317 : :
21318 : 114 : f = GetRecordOrField ();
21319 : 114 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21320 : 114 : M2CaseList_ElseCase (f);
21321 : 114 : }
21322 : :
21323 : :
21324 : : /*
21325 : : BeginVarientList - begin an ident list containing ranges belonging to a
21326 : : varient list.
21327 : : */
21328 : :
21329 : 552 : extern "C" void M2Quads_BeginVarientList (void)
21330 : : {
21331 : 552 : unsigned int f;
21332 : :
21333 : 552 : f = GetRecordOrField ();
21334 : 552 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21335 : 552 : M2CaseList_BeginCaseList (f);
21336 : 552 : }
21337 : :
21338 : :
21339 : : /*
21340 : : EndVarientList - end a range list for a varient field.
21341 : : */
21342 : :
21343 : 552 : extern "C" void M2Quads_EndVarientList (void)
21344 : : {
21345 : 552 : M2CaseList_EndCaseList ();
21346 : 552 : }
21347 : :
21348 : :
21349 : : /*
21350 : : AddRecordToList - adds the record held on the top of stack to the
21351 : : list of records and varient fields.
21352 : : */
21353 : :
21354 : 276 : extern "C" void M2Quads_AddRecordToList (void)
21355 : : {
21356 : 276 : unsigned int r;
21357 : 276 : unsigned int n;
21358 : :
21359 : 276 : r = static_cast<unsigned int> (M2Quads_OperandT (1));
21360 : 552 : M2Debug_Assert ((SymbolTable_IsRecord (r)) || (SymbolTable_IsFieldVarient (r)));
21361 : : /*
21362 : : r might be a field varient if the declaration consists of nested
21363 : : varients. However ISO TSIZE can only utilise record types, we store
21364 : : a varient field anyway as the next pass would not know whether to
21365 : : ignore a varient field.
21366 : : */
21367 : 276 : Lists_PutItemIntoList (VarientFields, r);
21368 : 276 : if (DebugVarients)
21369 : : {
21370 : : n = Lists_NoOfItemsInList (VarientFields);
21371 : : if (SymbolTable_IsRecord (r))
21372 : : {
21373 : : 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));
21374 : : }
21375 : : else
21376 : : {
21377 : : 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));
21378 : : }
21379 : : }
21380 : 276 : }
21381 : :
21382 : :
21383 : : /*
21384 : : AddVarientToList - adds varient held on the top of stack to the list.
21385 : : */
21386 : :
21387 : 276 : extern "C" void M2Quads_AddVarientToList (void)
21388 : : {
21389 : 276 : unsigned int v;
21390 : 276 : unsigned int n;
21391 : :
21392 : 276 : v = static_cast<unsigned int> (M2Quads_OperandT (1));
21393 : 276 : M2Debug_Assert (SymbolTable_IsVarient (v));
21394 : 276 : Lists_PutItemIntoList (VarientFields, v);
21395 : 276 : if (DebugVarients)
21396 : : {
21397 : : n = Lists_NoOfItemsInList (VarientFields);
21398 : : 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));
21399 : : }
21400 : 276 : }
21401 : :
21402 : :
21403 : : /*
21404 : : AddVarientFieldToList - adds varient field, f, to the list of all varient
21405 : : fields created.
21406 : : */
21407 : :
21408 : 666 : extern "C" void M2Quads_AddVarientFieldToList (unsigned int f)
21409 : : {
21410 : 666 : unsigned int n;
21411 : :
21412 : 666 : M2Debug_Assert (SymbolTable_IsFieldVarient (f));
21413 : 666 : Lists_PutItemIntoList (VarientFields, f);
21414 : 666 : if (DebugVarients)
21415 : : {
21416 : : n = Lists_NoOfItemsInList (VarientFields);
21417 : : 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));
21418 : : }
21419 : 666 : }
21420 : :
21421 : :
21422 : : /*
21423 : : AddVarientRange - creates a range from the top two contant expressions
21424 : : on the stack which are recorded with the current
21425 : : varient field. The stack is unaltered.
21426 : : */
21427 : :
21428 : 0 : extern "C" void M2Quads_AddVarientRange (void)
21429 : : {
21430 : 0 : unsigned int r1;
21431 : 0 : unsigned int r2;
21432 : :
21433 : 0 : M2Quads_PopT (&r2);
21434 : 0 : M2Quads_PopT (&r1);
21435 : 0 : M2CaseList_AddRange (r1, r2, M2LexBuf_GetTokenNo ());
21436 : 0 : }
21437 : :
21438 : :
21439 : : /*
21440 : : AddVarientEquality - adds the contant expression on the top of the stack
21441 : : to the current varient field being recorded.
21442 : : The stack is unaltered.
21443 : : */
21444 : :
21445 : 594 : extern "C" void M2Quads_AddVarientEquality (void)
21446 : : {
21447 : 594 : unsigned int r1;
21448 : :
21449 : 594 : M2Quads_PopT (&r1);
21450 : 594 : M2CaseList_AddRange (r1, SymbolTable_NulSym, M2LexBuf_GetTokenNo ());
21451 : 594 : }
21452 : :
21453 : :
21454 : : /*
21455 : : BuildCodeOn - generates a quadruple declaring that code should be
21456 : : emmitted from henceforth.
21457 : :
21458 : : The Stack is unnaffected.
21459 : : */
21460 : :
21461 : 0 : extern "C" void M2Quads_BuildCodeOn (void)
21462 : : {
21463 : 0 : GenQuad (M2Quads_CodeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21464 : 0 : }
21465 : :
21466 : :
21467 : : /*
21468 : : BuildCodeOff - generates a quadruple declaring that code should not be
21469 : : emmitted from henceforth.
21470 : :
21471 : : The Stack is unnaffected.
21472 : : */
21473 : :
21474 : 0 : extern "C" void M2Quads_BuildCodeOff (void)
21475 : : {
21476 : 0 : GenQuad (M2Quads_CodeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21477 : 0 : }
21478 : :
21479 : :
21480 : : /*
21481 : : BuildProfileOn - generates a quadruple declaring that profile timings
21482 : : should be emmitted from henceforth.
21483 : :
21484 : : The Stack is unnaffected.
21485 : : */
21486 : :
21487 : 0 : extern "C" void M2Quads_BuildProfileOn (void)
21488 : : {
21489 : 0 : GenQuad (M2Quads_ProfileOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21490 : 0 : }
21491 : :
21492 : 0 : extern "C" void M2Quads_BuildProfileOff (void)
21493 : : {
21494 : : /*
21495 : : BuildProfileOn - generates a quadruple declaring that profile timings
21496 : : should be emmitted from henceforth.
21497 : :
21498 : : The Stack is unnaffected.
21499 : : */
21500 : 0 : GenQuad (M2Quads_ProfileOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21501 : 0 : }
21502 : :
21503 : :
21504 : : /*
21505 : : BuildOptimizeOn - generates a quadruple declaring that optimization
21506 : : should occur from henceforth.
21507 : :
21508 : : The Stack is unnaffected.
21509 : : */
21510 : :
21511 : 0 : extern "C" void M2Quads_BuildOptimizeOn (void)
21512 : : {
21513 : 0 : GenQuad (M2Quads_OptimizeOnOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21514 : 0 : }
21515 : :
21516 : :
21517 : : /*
21518 : : BuildOptimizeOff - generates a quadruple declaring that optimization
21519 : : should not occur from henceforth.
21520 : :
21521 : : The Stack is unnaffected.
21522 : : */
21523 : :
21524 : 0 : extern "C" void M2Quads_BuildOptimizeOff (void)
21525 : : {
21526 : 0 : GenQuad (M2Quads_OptimizeOffOp, SymbolTable_NulSym, SymbolTable_NulSym, SymbolTable_NulSym);
21527 : 0 : }
21528 : :
21529 : :
21530 : : /*
21531 : : BuildAsm - builds an Inline pseudo quadruple operator.
21532 : : The inline interface, Sym, is stored as the operand
21533 : : to the operator InlineOp.
21534 : :
21535 : : The stack is expected to contain:
21536 : :
21537 : :
21538 : : Entry Exit
21539 : : ===== ====
21540 : :
21541 : : Ptr ->
21542 : : +--------------+
21543 : : | Sym | Empty
21544 : : |--------------|
21545 : : */
21546 : :
21547 : 27 : extern "C" void M2Quads_BuildAsm (unsigned int tok)
21548 : : {
21549 : 27 : unsigned int Sym;
21550 : :
21551 : 27 : M2Quads_PopT (&Sym);
21552 : 27 : GenQuadO (tok, M2Quads_InlineOp, SymbolTable_NulSym, SymbolTable_NulSym, Sym, false);
21553 : 27 : }
21554 : :
21555 : :
21556 : : /*
21557 : : BuildLineNo - builds a LineNumberOp pseudo quadruple operator.
21558 : : This quadruple indicates which source line has been
21559 : : processed, these quadruples are only generated if we
21560 : : are producing runtime debugging information.
21561 : :
21562 : : The stack is not affected, read or altered in any way.
21563 : :
21564 : :
21565 : : Entry Exit
21566 : : ===== ====
21567 : :
21568 : : Ptr -> <- Ptr
21569 : : */
21570 : :
21571 : 0 : extern "C" void M2Quads_BuildLineNo (void)
21572 : : {
21573 : 0 : NameKey_Name filename;
21574 : 0 : M2Quads_QuadFrame f;
21575 : :
21576 : 0 : if (((NextQuad != Head) && (M2Options_GenerateLineDebug || M2Options_GenerateDebugging)) && false)
21577 : : {
21578 : : filename = NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ()));
21579 : : f = GetQF (NextQuad-1);
21580 : : if (! ((f->Operator == M2Quads_LineNumberOp) && (f->Operand1 == ((unsigned int ) (filename)))))
21581 : : {
21582 : : GenQuad (M2Quads_LineNumberOp, (unsigned int ) (filename), SymbolTable_NulSym, (unsigned int ) (M2LexBuf_GetLineNo ()));
21583 : : }
21584 : : }
21585 : 0 : }
21586 : :
21587 : :
21588 : : /*
21589 : : PushLineNo - pushes the current file and line number to the stack.
21590 : : */
21591 : :
21592 : 4220 : extern "C" void M2Quads_PushLineNo (void)
21593 : : {
21594 : 4220 : PushLineNote (InitLineNote (NameKey_makekey (DynamicStrings_string (M2LexBuf_GetFileName ())), M2LexBuf_GetLineNo ()));
21595 : 4220 : }
21596 : :
21597 : :
21598 : : /*
21599 : : BuildStmtNote - builds a StatementNoteOp pseudo quadruple operator.
21600 : : This quadruple indicates which source line has been
21601 : : processed and it represents the start of a statement
21602 : : sequence.
21603 : : It differs from LineNumberOp in that multiple successive
21604 : : LineNumberOps will be removed and the final one is attached to
21605 : : the next real GCC tree. Whereas a StatementNoteOp is always left
21606 : : alone. Depending upon the debugging level it will issue a nop
21607 : : instruction to ensure that the gdb single step will step into
21608 : : this line. Practically it allows pedalogical debugging to
21609 : : occur when there is syntax sugar such as:
21610 : :
21611 : :
21612 : : END step
21613 : : END step
21614 : : END ; step
21615 : : a := 1 ; step
21616 : :
21617 : : REPEAT step
21618 : : i := 1 step
21619 : :
21620 : : The stack is not affected, read or altered in any way.
21621 : :
21622 : :
21623 : : Entry Exit
21624 : : ===== ====
21625 : :
21626 : : Ptr -> <- Ptr
21627 : : */
21628 : :
21629 : 446478 : extern "C" void M2Quads_BuildStmtNote (int offset)
21630 : : {
21631 : 446478 : int tokenno;
21632 : :
21633 : 446478 : if (NextQuad != Head)
21634 : : {
21635 : 446478 : tokenno = offset;
21636 : 446478 : tokenno += M2LexBuf_GetTokenNo ();
21637 : 446478 : BuildStmtNoteTok ((unsigned int ) (tokenno));
21638 : : }
21639 : 446478 : }
21640 : :
21641 : :
21642 : : /*
21643 : : LoopAnalysis - checks whether an infinite loop exists.
21644 : : */
21645 : :
21646 : 317533 : extern "C" void M2Quads_LoopAnalysis (unsigned int Scope, unsigned int Current, unsigned int End)
21647 : : {
21648 : 317533 : M2Quads_QuadOperator op;
21649 : 317533 : unsigned int op1;
21650 : 317533 : unsigned int op2;
21651 : 317533 : unsigned int op3;
21652 : :
21653 : 317533 : if (M2Options_Pedantic)
21654 : : {
21655 : 9768 : while ((Current <= End) && (Current != 0))
21656 : : {
21657 : 8622 : M2Quads_GetQuad (Current, &op, &op1, &op2, &op3);
21658 : 8622 : if ((op == M2Quads_GotoOp) || (M2Quads_IsConditional (Current)))
21659 : : {
21660 : 114 : if (op3 <= Current)
21661 : : {
21662 : : /* found a loop - ie a branch which goes back in quadruple numbers */
21663 : 24 : if (IsInfiniteLoop (Current))
21664 : : {
21665 : 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);
21666 : 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);
21667 : : }
21668 : : /*
21669 : : WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'),
21670 : : QuadToTokenNo(op3)) ;
21671 : : WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'),
21672 : : QuadToTokenNo(Current))
21673 : : */
21674 : : }
21675 : : }
21676 : 8622 : Current = M2Quads_GetNextQuad (Current);
21677 : : }
21678 : : }
21679 : 317533 : }
21680 : :
21681 : :
21682 : : /*
21683 : : ForLoopAnalysis - checks all the FOR loops for index variable manipulation
21684 : : and dangerous usage outside the loop.
21685 : : */
21686 : :
21687 : 14329 : extern "C" void M2Quads_ForLoopAnalysis (void)
21688 : : {
21689 : 14329 : unsigned int i;
21690 : 14329 : unsigned int n;
21691 : 14329 : M2Quads_ForLoopInfo forDesc;
21692 : :
21693 : 14329 : if (M2Options_Pedantic)
21694 : : {
21695 : 96 : n = Indexing_HighIndice (ForInfo);
21696 : 96 : i = 1;
21697 : 192 : while (i <= n)
21698 : : {
21699 : 0 : forDesc = static_cast<M2Quads_ForLoopInfo> (Indexing_GetIndice (ForInfo, i));
21700 : 0 : CheckForIndex (forDesc);
21701 : 0 : i += 1;
21702 : : }
21703 : : }
21704 : 14329 : }
21705 : :
21706 : :
21707 : : /*
21708 : : BuildSizeCheckStart - switches off all quadruple generation if the function SIZE or HIGH
21709 : : is being "called". This should be done as SIZE only requires the
21710 : : actual type of the expression, not its value. Consider the problem of
21711 : : SIZE(UninitializedPointer^) which is quite legal and it must
21712 : : also be safe!
21713 : : ISO Modula-2 also allows HIGH(a[0]) for a two dimensional array
21714 : : and there is no need to compute a[0], we just need to follow the
21715 : : type and count dimensions. However if SIZE(a) or HIGH(a) occurs
21716 : : and, a, is an unbounded array then we turn on quadruple generation.
21717 : :
21718 : : The Stack is expected to contain:
21719 : :
21720 : :
21721 : : Entry Exit
21722 : : ===== ====
21723 : :
21724 : : Ptr -> <- Ptr
21725 : : +----------------------+ +----------------------+
21726 : : | ProcSym | Type | tok | | ProcSym | Type | tok |
21727 : : |----------------------| |----------------------|
21728 : : */
21729 : :
21730 : 152249 : extern "C" void M2Quads_BuildSizeCheckStart (void)
21731 : : {
21732 : 152249 : unsigned int ProcSym;
21733 : 152249 : unsigned int Type;
21734 : 152249 : unsigned int tok;
21735 : :
21736 : 152249 : M2Quads_PopTFtok (&ProcSym, &Type, &tok);
21737 : 152249 : if (((ProcSym == M2Size_Size) || (ProcSym == M2System_TSize)) || (ProcSym == M2System_TBitSize))
21738 : : {
21739 : 2936 : QuadrupleGeneration = false;
21740 : 2936 : BuildingSize = true;
21741 : : }
21742 : 149313 : else if (ProcSym == M2Base_High)
21743 : : {
21744 : : /* avoid dangling else. */
21745 : 2328 : QuadrupleGeneration = false;
21746 : 2328 : BuildingHigh = true;
21747 : : }
21748 : 152249 : M2Quads_PushTFtok (ProcSym, Type, tok);
21749 : 152249 : }
21750 : :
21751 : :
21752 : : /*
21753 : : BackPatchSubrangesAndOptParam - runs through all the quadruples and finds SubrangeLow or SubrangeHigh
21754 : : quadruples and replaces it by an assignment to the Low or High component
21755 : : of the subrange type.
21756 : :
21757 : : Input:
21758 : : SubrangeLow op1 op3 op3 is a subrange
21759 : :
21760 : : Output:
21761 : : Becomes op1 low
21762 : :
21763 : : Input:
21764 : : SubrangeHigh op1 op3 op3 is a subrange
21765 : :
21766 : : Output:
21767 : : Becomes op1 high
21768 : :
21769 : : Input:
21770 : : OptParam op1 op2 op3
21771 : :
21772 : : Output:
21773 : : Param op1 op2 GetOptArgInit(op3)
21774 : : */
21775 : :
21776 : 14329 : extern "C" void M2Quads_BackPatchSubrangesAndOptParam (void)
21777 : : {
21778 : 14329 : M2Quads_QuadFrame f;
21779 : 14329 : unsigned int q;
21780 : :
21781 : 14329 : q = M2Quads_GetFirstQuad ();
21782 : 14329 : if (q != 0)
21783 : : {
21784 : 5191980 : do {
21785 : 5191980 : f = GetQF (q);
21786 : 5191980 : switch (f->Operator)
21787 : : {
21788 : 234 : case M2Quads_SubrangeLowOp:
21789 : 234 : f->Operand3 = CollectLow (f->Operand3);
21790 : 234 : f->Operator = M2Quads_BecomesOp;
21791 : 234 : f->ConstExpr = false;
21792 : 234 : break;
21793 : :
21794 : 3116 : case M2Quads_SubrangeHighOp:
21795 : 3116 : f->Operand3 = CollectHigh (f->Operand3);
21796 : 3116 : f->Operator = M2Quads_BecomesOp;
21797 : 3116 : f->ConstExpr = false;
21798 : 3116 : break;
21799 : :
21800 : 2886 : case M2Quads_OptParamOp:
21801 : 2886 : f->Operand3 = SymbolTable_GetOptArgInit (f->Operand3);
21802 : 2886 : f->Operator = M2Quads_ParamOp;
21803 : 2886 : break;
21804 : :
21805 : :
21806 : : default:
21807 : : break;
21808 : : }
21809 : 5191980 : q = f->Next;
21810 : 5191980 : } while (! (q == 0));
21811 : : }
21812 : 14329 : }
21813 : :
21814 : :
21815 : : /*
21816 : : WriteOperator - writes the name of the quadruple operator.
21817 : : */
21818 : :
21819 : 0 : extern "C" void M2Quads_WriteOperator (M2Quads_QuadOperator Operator)
21820 : : {
21821 : 0 : switch (Operator)
21822 : : {
21823 : 0 : case M2Quads_ArithAddOp:
21824 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Arith + ", 18);
21825 : 0 : break;
21826 : :
21827 : 0 : case M2Quads_InitAddressOp:
21828 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitAddress ", 18);
21829 : 0 : break;
21830 : :
21831 : 0 : case M2Quads_LastForIteratorOp:
21832 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LastForIterator ", 18);
21833 : 0 : break;
21834 : :
21835 : 0 : case M2Quads_LogicalOrOp:
21836 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Or ", 18);
21837 : 0 : break;
21838 : :
21839 : 0 : case M2Quads_LogicalAndOp:
21840 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "And ", 18);
21841 : 0 : break;
21842 : :
21843 : 0 : case M2Quads_LogicalXorOp:
21844 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Xor ", 18);
21845 : 0 : break;
21846 : :
21847 : 0 : case M2Quads_LogicalDiffOp:
21848 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Ldiff ", 18);
21849 : 0 : break;
21850 : :
21851 : 0 : case M2Quads_LogicalShiftOp:
21852 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Shift ", 18);
21853 : 0 : break;
21854 : :
21855 : 0 : case M2Quads_LogicalRotateOp:
21856 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Rotate ", 18);
21857 : 0 : break;
21858 : :
21859 : 0 : case M2Quads_BecomesOp:
21860 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Becomes ", 18);
21861 : 0 : break;
21862 : :
21863 : 0 : case M2Quads_IndrXOp:
21864 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "IndrX ", 18);
21865 : 0 : break;
21866 : :
21867 : 0 : case M2Quads_XIndrOp:
21868 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "XIndr ", 18);
21869 : 0 : break;
21870 : :
21871 : 0 : case M2Quads_ArrayOp:
21872 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Array ", 18);
21873 : 0 : break;
21874 : :
21875 : 0 : case M2Quads_ElementSizeOp:
21876 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ElementSize ", 18);
21877 : 0 : break;
21878 : :
21879 : 0 : case M2Quads_RecordFieldOp:
21880 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RecordField ", 18);
21881 : 0 : break;
21882 : :
21883 : 0 : case M2Quads_AddrOp:
21884 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Addr ", 18);
21885 : 0 : break;
21886 : :
21887 : 0 : case M2Quads_SizeOp:
21888 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Size ", 18);
21889 : 0 : break;
21890 : :
21891 : 0 : case M2Quads_IfInOp:
21892 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If IN ", 18);
21893 : 0 : break;
21894 : :
21895 : 0 : case M2Quads_IfNotInOp:
21896 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If NOT IN ", 18);
21897 : 0 : break;
21898 : :
21899 : 0 : case M2Quads_IfNotEquOp:
21900 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <> ", 18);
21901 : 0 : break;
21902 : :
21903 : 0 : case M2Quads_IfEquOp:
21904 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If = ", 18);
21905 : 0 : break;
21906 : :
21907 : 0 : case M2Quads_IfLessEquOp:
21908 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If <= ", 18);
21909 : 0 : break;
21910 : :
21911 : 0 : case M2Quads_IfGreEquOp:
21912 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If >= ", 18);
21913 : 0 : break;
21914 : :
21915 : 0 : case M2Quads_IfGreOp:
21916 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If > ", 18);
21917 : 0 : break;
21918 : :
21919 : 0 : case M2Quads_IfLessOp:
21920 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "If < ", 18);
21921 : 0 : break;
21922 : :
21923 : 0 : case M2Quads_GotoOp:
21924 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Goto ", 18);
21925 : 0 : break;
21926 : :
21927 : 0 : case M2Quads_DummyOp:
21928 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Dummy ", 18);
21929 : 0 : break;
21930 : :
21931 : 0 : case M2Quads_ModuleScopeOp:
21932 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ModuleScopeOp ", 18);
21933 : 0 : break;
21934 : :
21935 : 0 : case M2Quads_StartDefFileOp:
21936 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartDefFile ", 18);
21937 : 0 : break;
21938 : :
21939 : 0 : case M2Quads_StartModFileOp:
21940 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StartModFile ", 18);
21941 : 0 : break;
21942 : :
21943 : 0 : case M2Quads_EndFileOp:
21944 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "EndFileOp ", 18);
21945 : 0 : break;
21946 : :
21947 : 0 : case M2Quads_InitStartOp:
21948 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitStart ", 18);
21949 : 0 : break;
21950 : :
21951 : 0 : case M2Quads_InitEndOp:
21952 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "InitEnd ", 18);
21953 : 0 : break;
21954 : :
21955 : 0 : case M2Quads_FinallyStartOp:
21956 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyStart ", 18);
21957 : 0 : break;
21958 : :
21959 : 0 : case M2Quads_FinallyEndOp:
21960 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FinallyEnd ", 18);
21961 : 0 : break;
21962 : :
21963 : 0 : case M2Quads_RetryOp:
21964 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Retry ", 18);
21965 : 0 : break;
21966 : :
21967 : 0 : case M2Quads_TryOp:
21968 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Try ", 18);
21969 : 0 : break;
21970 : :
21971 : 0 : case M2Quads_ThrowOp:
21972 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Throw ", 18);
21973 : 0 : break;
21974 : :
21975 : 0 : case M2Quads_CatchBeginOp:
21976 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchBegin ", 18);
21977 : 0 : break;
21978 : :
21979 : 0 : case M2Quads_CatchEndOp:
21980 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CatchEnd ", 18);
21981 : 0 : break;
21982 : :
21983 : 0 : case M2Quads_AddOp:
21984 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "+ ", 18);
21985 : 0 : break;
21986 : :
21987 : 0 : case M2Quads_SubOp:
21988 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "- ", 18);
21989 : 0 : break;
21990 : :
21991 : 0 : case M2Quads_DivM2Op:
21992 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV M2 ", 18);
21993 : 0 : break;
21994 : :
21995 : 0 : case M2Quads_ModM2Op:
21996 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD M2 ", 18);
21997 : 0 : break;
21998 : :
21999 : 0 : case M2Quads_DivCeilOp:
22000 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV ceil ", 18);
22001 : 0 : break;
22002 : :
22003 : 0 : case M2Quads_ModCeilOp:
22004 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD ceil ", 18);
22005 : 0 : break;
22006 : :
22007 : 0 : case M2Quads_DivFloorOp:
22008 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV floor ", 18);
22009 : 0 : break;
22010 : :
22011 : 0 : case M2Quads_ModFloorOp:
22012 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD floor ", 18);
22013 : 0 : break;
22014 : :
22015 : 0 : case M2Quads_DivTruncOp:
22016 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "DIV trunc ", 18);
22017 : 0 : break;
22018 : :
22019 : 0 : case M2Quads_ModTruncOp:
22020 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "MOD trunc ", 18);
22021 : 0 : break;
22022 : :
22023 : 0 : case M2Quads_MultOp:
22024 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "* ", 18);
22025 : 0 : break;
22026 : :
22027 : 0 : case M2Quads_NegateOp:
22028 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Negate ", 18);
22029 : 0 : break;
22030 : :
22031 : 0 : case M2Quads_InclOp:
22032 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Incl ", 18);
22033 : 0 : break;
22034 : :
22035 : 0 : case M2Quads_ExclOp:
22036 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Excl ", 18);
22037 : 0 : break;
22038 : :
22039 : 0 : case M2Quads_ReturnOp:
22040 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Return ", 18);
22041 : 0 : break;
22042 : :
22043 : 0 : case M2Quads_ReturnValueOp:
22044 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ReturnValue ", 18);
22045 : 0 : break;
22046 : :
22047 : 0 : case M2Quads_FunctValueOp:
22048 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "FunctValue ", 18);
22049 : 0 : break;
22050 : :
22051 : 0 : case M2Quads_CallOp:
22052 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Call ", 18);
22053 : 0 : break;
22054 : :
22055 : 0 : case M2Quads_ParamOp:
22056 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Param ", 18);
22057 : 0 : break;
22058 : :
22059 : 0 : case M2Quads_OptParamOp:
22060 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptParam ", 18);
22061 : 0 : break;
22062 : :
22063 : 0 : case M2Quads_NewLocalVarOp:
22064 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "NewLocalVar ", 18);
22065 : 0 : break;
22066 : :
22067 : 0 : case M2Quads_KillLocalVarOp:
22068 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "KillLocalVar ", 18);
22069 : 0 : break;
22070 : :
22071 : 0 : case M2Quads_ProcedureScopeOp:
22072 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProcedureScope ", 18);
22073 : 0 : break;
22074 : :
22075 : 0 : case M2Quads_UnboundedOp:
22076 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Unbounded ", 18);
22077 : 0 : break;
22078 : :
22079 : 0 : case M2Quads_CoerceOp:
22080 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Coerce ", 18);
22081 : 0 : break;
22082 : :
22083 : 0 : case M2Quads_ConvertOp:
22084 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Convert ", 18);
22085 : 0 : break;
22086 : :
22087 : 0 : case M2Quads_CastOp:
22088 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Cast ", 18);
22089 : 0 : break;
22090 : :
22091 : 0 : case M2Quads_HighOp:
22092 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "High ", 18);
22093 : 0 : break;
22094 : :
22095 : 0 : case M2Quads_CodeOnOp:
22096 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOn ", 18);
22097 : 0 : break;
22098 : :
22099 : 0 : case M2Quads_CodeOffOp:
22100 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "CodeOff ", 18);
22101 : 0 : break;
22102 : :
22103 : 0 : case M2Quads_ProfileOnOp:
22104 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOn ", 18);
22105 : 0 : break;
22106 : :
22107 : 0 : case M2Quads_ProfileOffOp:
22108 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "ProfileOff ", 18);
22109 : 0 : break;
22110 : :
22111 : 0 : case M2Quads_OptimizeOnOp:
22112 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOn ", 18);
22113 : 0 : break;
22114 : :
22115 : 0 : case M2Quads_OptimizeOffOp:
22116 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "OptimizeOff ", 18);
22117 : 0 : break;
22118 : :
22119 : 0 : case M2Quads_InlineOp:
22120 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Inline ", 18);
22121 : 0 : break;
22122 : :
22123 : 0 : case M2Quads_StatementNoteOp:
22124 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StatementNote ", 18);
22125 : 0 : break;
22126 : :
22127 : 0 : case M2Quads_LineNumberOp:
22128 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "LineNumber ", 18);
22129 : 0 : break;
22130 : :
22131 : 0 : case M2Quads_BuiltinConstOp:
22132 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinConst ", 18);
22133 : 0 : break;
22134 : :
22135 : 0 : case M2Quads_BuiltinTypeInfoOp:
22136 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "BuiltinTypeInfo ", 18);
22137 : 0 : break;
22138 : :
22139 : 0 : case M2Quads_StandardFunctionOp:
22140 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StandardFunction ", 18);
22141 : 0 : break;
22142 : :
22143 : 0 : case M2Quads_SavePriorityOp:
22144 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SavePriority ", 18);
22145 : 0 : break;
22146 : :
22147 : 0 : case M2Quads_RestorePriorityOp:
22148 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestorePriority ", 18);
22149 : 0 : break;
22150 : :
22151 : 0 : case M2Quads_RangeCheckOp:
22152 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RangeCheck ", 18);
22153 : 0 : break;
22154 : :
22155 : 0 : case M2Quads_ErrorOp:
22156 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "Error ", 18);
22157 : 0 : break;
22158 : :
22159 : 0 : case M2Quads_SaveExceptionOp:
22160 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SaveException ", 18);
22161 : 0 : break;
22162 : :
22163 : 0 : case M2Quads_RestoreExceptionOp:
22164 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "RestoreException ", 18);
22165 : 0 : break;
22166 : :
22167 : 0 : case M2Quads_StringConvertCnulOp:
22168 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertCnul ", 18);
22169 : 0 : break;
22170 : :
22171 : 0 : case M2Quads_StringConvertM2nulOp:
22172 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringConvertM2nul", 18);
22173 : 0 : break;
22174 : :
22175 : 0 : case M2Quads_StringLengthOp:
22176 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "StringLength ", 18);
22177 : 0 : break;
22178 : :
22179 : 0 : case M2Quads_SubrangeHighOp:
22180 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeHigh ", 18);
22181 : 0 : break;
22182 : :
22183 : 0 : case M2Quads_SubrangeLowOp:
22184 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "SubrangeLow ", 18);
22185 : 0 : break;
22186 : :
22187 : :
22188 : 0 : default:
22189 : 0 : M2Error_InternalError ((const char *) "operator not expected", 21);
22190 : 0 : break;
22191 : : }
22192 : 0 : }
22193 : :
22194 : :
22195 : : /*
22196 : : PushAutoOn - push the auto flag and then set it to TRUE.
22197 : : Any call to ident in the parser will result in the token being pushed.
22198 : : */
22199 : :
22200 : 36700908 : extern "C" void M2Quads_PushAutoOn (void)
22201 : : {
22202 : 36700908 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
22203 : 36700908 : IsAutoOn = true;
22204 : 36700908 : }
22205 : :
22206 : :
22207 : : /*
22208 : : PushAutoOff - push the auto flag and then set it to FALSE.
22209 : : */
22210 : :
22211 : 65822937 : extern "C" void M2Quads_PushAutoOff (void)
22212 : : {
22213 : 65822937 : M2StackWord_PushWord (AutoStack, static_cast<unsigned int> (IsAutoOn));
22214 : 65822937 : IsAutoOn = false;
22215 : 65822937 : }
22216 : :
22217 : :
22218 : : /*
22219 : : IsAutoPushOn - returns the value of the current Auto ident push flag.
22220 : : */
22221 : :
22222 : 326461981 : extern "C" bool M2Quads_IsAutoPushOn (void)
22223 : : {
22224 : 326461981 : return IsAutoOn;
22225 : : /* static analysis guarentees a RETURN statement will be used before here. */
22226 : : __builtin_unreachable ();
22227 : : }
22228 : :
22229 : :
22230 : : /*
22231 : : PopAuto - restores the previous value of the Auto flag.
22232 : : */
22233 : :
22234 : 102499835 : extern "C" void M2Quads_PopAuto (void)
22235 : : {
22236 : 102499835 : IsAutoOn = static_cast<bool> (M2StackWord_PopWord (AutoStack));
22237 : 102499835 : }
22238 : :
22239 : :
22240 : : /*
22241 : : MustCheckOverflow - returns TRUE if the quadruple should test for overflow.
22242 : : */
22243 : :
22244 : 444556 : extern "C" bool M2Quads_MustCheckOverflow (unsigned int q)
22245 : : {
22246 : 444556 : M2Quads_QuadFrame f;
22247 : :
22248 : 444556 : f = GetQF (q);
22249 : 444556 : return f->CheckOverflow;
22250 : : /* static analysis guarentees a RETURN statement will be used before here. */
22251 : : __builtin_unreachable ();
22252 : : }
22253 : :
22254 : :
22255 : : /*
22256 : : PushInConstExpression - push the InConstExpression flag and then set it to TRUE.
22257 : : */
22258 : :
22259 : 944422 : extern "C" void M2Quads_PushInConstExpression (void)
22260 : : {
22261 : 944422 : M2StackWord_PushWord (ConstExprStack, static_cast<unsigned int> (InConstExpression));
22262 : 944422 : InConstExpression = true;
22263 : 944422 : }
22264 : :
22265 : :
22266 : : /*
22267 : : PopInConstExpression - restores the previous value of the InConstExpression.
22268 : : */
22269 : :
22270 : 944398 : extern "C" void M2Quads_PopInConstExpression (void)
22271 : : {
22272 : 944398 : InConstExpression = static_cast<bool> (M2StackWord_PopWord (ConstExprStack));
22273 : 944398 : }
22274 : :
22275 : :
22276 : : /*
22277 : : IsInConstExpression - returns the value of the InConstExpression.
22278 : : */
22279 : :
22280 : 81505 : extern "C" bool M2Quads_IsInConstExpression (void)
22281 : : {
22282 : 81505 : return InConstExpression;
22283 : : /* static analysis guarentees a RETURN statement will be used before here. */
22284 : : __builtin_unreachable ();
22285 : : }
22286 : :
22287 : :
22288 : : /*
22289 : : PushInConstParameters - push the InConstParameters flag and then set it to TRUE.
22290 : : */
22291 : :
22292 : 1654 : extern "C" void M2Quads_PushInConstParameters (void)
22293 : : {
22294 : 1654 : M2StackWord_PushWord (ConstParamStack, static_cast<unsigned int> (InConstParameters));
22295 : 1654 : InConstParameters = true;
22296 : 1654 : }
22297 : :
22298 : :
22299 : : /*
22300 : : PopInConstParameters - restores the previous value of the InConstParameters.
22301 : : */
22302 : :
22303 : 1654 : extern "C" void M2Quads_PopInConstParameters (void)
22304 : : {
22305 : 1654 : InConstParameters = static_cast<bool> (M2StackWord_PopWord (ConstParamStack));
22306 : 1654 : }
22307 : :
22308 : :
22309 : : /*
22310 : : IsInConstParameters - returns the value of the InConstParameters.
22311 : : */
22312 : :
22313 : 65132 : extern "C" bool M2Quads_IsInConstParameters (void)
22314 : : {
22315 : 65132 : return InConstParameters;
22316 : : /* static analysis guarentees a RETURN statement will be used before here. */
22317 : : __builtin_unreachable ();
22318 : : }
22319 : :
22320 : :
22321 : : /*
22322 : : BuildAsmElement - the stack is expected to contain:
22323 : :
22324 : :
22325 : : Entry Exit
22326 : : ===== ====
22327 : :
22328 : : Ptr ->
22329 : : +------------------+
22330 : : | expr | tokpos |
22331 : : |------------------|
22332 : : | str |
22333 : : |------------------|
22334 : : | name |
22335 : : |------------------| +------------------+
22336 : : | CurrentInterface | | CurrentInterface |
22337 : : |------------------| |------------------|
22338 : : | CurrentAsm | | CurrentAsm |
22339 : : |------------------| |------------------|
22340 : : | n | | n |
22341 : : |------------------| |------------------|
22342 : : */
22343 : :
22344 : 33 : extern "C" void M2Quads_BuildAsmElement (bool input, bool output)
22345 : : {
22346 : 33 : DynamicStrings_String s;
22347 : 33 : unsigned int n;
22348 : 33 : unsigned int str;
22349 : 33 : unsigned int expr;
22350 : 33 : unsigned int tokpos;
22351 : 33 : unsigned int CurrentInterface;
22352 : 33 : unsigned int CurrentAsm;
22353 : 33 : unsigned int name;
22354 : :
22355 : 33 : M2Quads_PopTtok (&expr, &tokpos);
22356 : 33 : M2Quads_PopT (&str);
22357 : 33 : M2Quads_PopT (&name);
22358 : 33 : M2Quads_PopT (&CurrentInterface);
22359 : 33 : M2Quads_PopT (&CurrentAsm);
22360 : 66 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22361 : 33 : M2Quads_PopT (&n);
22362 : 33 : n += 1;
22363 : 33 : if (CurrentInterface == SymbolTable_NulSym)
22364 : : {
22365 : 30 : CurrentInterface = SymbolTable_MakeRegInterface ();
22366 : : }
22367 : 33 : if (input)
22368 : : {
22369 : 18 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, NextQuad, 0);
22370 : 18 : if (DebugAsmTokPos)
22371 : : {
22372 : : s = DynamicStrings_InitString ((const char *) "input expression", 16);
22373 : : M2Error_WarnStringAt (s, tokpos);
22374 : : }
22375 : : }
22376 : 33 : if (output)
22377 : : {
22378 : 15 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, 0, NextQuad);
22379 : 15 : if (DebugAsmTokPos)
22380 : : {
22381 : : s = DynamicStrings_InitString ((const char *) "output expression", 17);
22382 : : M2Error_WarnStringAt (s, tokpos);
22383 : : }
22384 : : }
22385 : 33 : M2Quads_PushT (n);
22386 : 33 : M2Quads_PushT (CurrentAsm);
22387 : 33 : M2Quads_PushT (CurrentInterface);
22388 : 33 : }
22389 : :
22390 : :
22391 : : /*
22392 : : BuildAsmTrash - the stack is expected to contain:
22393 : :
22394 : :
22395 : : Entry Exit
22396 : : ===== ====
22397 : :
22398 : : Ptr ->
22399 : : +------------------+
22400 : : | expr | tokpos |
22401 : : |------------------| +------------------+
22402 : : | CurrentInterface | | CurrentInterface |
22403 : : |------------------| |------------------|
22404 : : | CurrentAsm | | CurrentAsm |
22405 : : |------------------| |------------------|
22406 : : | n | | n |
22407 : : |------------------| |------------------|
22408 : : */
22409 : :
22410 : 3 : extern "C" void M2Quads_BuildAsmTrash (void)
22411 : : {
22412 : 3 : unsigned int n;
22413 : 3 : unsigned int expr;
22414 : 3 : unsigned int tokpos;
22415 : 3 : unsigned int CurrentInterface;
22416 : 3 : unsigned int CurrentAsm;
22417 : :
22418 : 3 : M2Quads_PopTtok (&expr, &tokpos);
22419 : 3 : M2Quads_PopT (&CurrentInterface);
22420 : 3 : M2Quads_PopT (&CurrentAsm);
22421 : 6 : M2Debug_Assert ((SymbolTable_IsGnuAsm (CurrentAsm)) || (SymbolTable_IsGnuAsmVolatile (CurrentAsm)));
22422 : 3 : M2Quads_PopT (&n);
22423 : 3 : n += 1;
22424 : 3 : if (CurrentInterface == SymbolTable_NulSym)
22425 : : {
22426 : 3 : CurrentInterface = SymbolTable_MakeRegInterface ();
22427 : : }
22428 : 3 : SymbolTable_PutRegInterface (tokpos, CurrentInterface, n, NameKey_NulName, SymbolTable_NulSym, expr, 0, NextQuad);
22429 : 3 : M2Quads_PushT (n);
22430 : 3 : M2Quads_PushT (CurrentAsm);
22431 : 3 : M2Quads_PushT (CurrentInterface);
22432 : 3 : }
22433 : :
22434 : :
22435 : : /*
22436 : : GetQuadTrash - return the symbol associated with the trashed operand.
22437 : : */
22438 : :
22439 : 120 : extern "C" unsigned int M2Quads_GetQuadTrash (unsigned int quad)
22440 : : {
22441 : 120 : M2Quads_QuadFrame f;
22442 : :
22443 : 120 : f = GetQF (quad);
22444 : 120 : LastQuadNo = quad;
22445 : 120 : return f->Trash;
22446 : : /* static analysis guarentees a RETURN statement will be used before here. */
22447 : : __builtin_unreachable ();
22448 : : }
22449 : :
22450 : 15260 : extern "C" void _M2_M2Quads_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
22451 : : {
22452 : 15260 : Init ();
22453 : 15260 : }
22454 : :
22455 : 0 : extern "C" void _M2_M2Quads_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
22456 : : {
22457 : 0 : }
|