Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2CaseList. */
2 : : /* M2CaseList.mod implement ISO case label lists.
3 : :
4 : : Copyright (C) 2009-2024 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "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 : : #if defined(__cplusplus)
44 : : # undef NULL
45 : : # define NULL 0
46 : : #endif
47 : : #define _M2CaseList_C
48 : :
49 : : #include "GM2CaseList.h"
50 : : # include "GM2Debug.h"
51 : : # include "GM2GCCDeclare.h"
52 : : # include "GM2MetaError.h"
53 : : # include "GM2Error.h"
54 : : # include "GM2Range.h"
55 : : # include "GM2ALU.h"
56 : : # include "GIndexing.h"
57 : : # include "GLists.h"
58 : : # include "GNameKey.h"
59 : : # include "GSymbolConversion.h"
60 : : # include "GDynamicStrings.h"
61 : : # include "Ggcctypes.h"
62 : : # include "Gm2block.h"
63 : : # include "Gm2type.h"
64 : : # include "Gm2expr.h"
65 : : # include "GStorage.h"
66 : : # include "GM2Base.h"
67 : : # include "GM2LexBuf.h"
68 : : # include "GNumberIO.h"
69 : : # include "GSymbolTable.h"
70 : :
71 : : typedef struct M2CaseList__T1_r M2CaseList__T1;
72 : :
73 : : typedef M2CaseList__T1 *M2CaseList_RangePair;
74 : :
75 : : typedef struct M2CaseList__T2_r M2CaseList__T2;
76 : :
77 : : typedef M2CaseList__T2 *M2CaseList_ConflictingPair;
78 : :
79 : : typedef struct M2CaseList__T3_r M2CaseList__T3;
80 : :
81 : : typedef M2CaseList__T3 *M2CaseList_CaseList;
82 : :
83 : : typedef struct M2CaseList__T4_r M2CaseList__T4;
84 : :
85 : : typedef M2CaseList__T4 *M2CaseList_CaseDescriptor;
86 : :
87 : : typedef struct M2CaseList__T5_r M2CaseList__T5;
88 : :
89 : : typedef M2CaseList__T5 *M2CaseList_SetRange;
90 : :
91 : : struct M2CaseList__T1_r {
92 : : unsigned int low;
93 : : unsigned int high;
94 : : unsigned int tokenno;
95 : : };
96 : :
97 : : struct M2CaseList__T2_r {
98 : : M2CaseList_RangePair a;
99 : : M2CaseList_RangePair b;
100 : : };
101 : :
102 : : struct M2CaseList__T3_r {
103 : : unsigned int maxRangeId;
104 : : Indexing_Index rangeArray;
105 : : M2CaseList_RangePair currentRange;
106 : : unsigned int varientField;
107 : : };
108 : :
109 : : struct M2CaseList__T4_r {
110 : : bool resolved;
111 : : bool elseClause;
112 : : unsigned int elseField;
113 : : unsigned int record;
114 : : unsigned int varient;
115 : : unsigned int expression;
116 : : unsigned int maxCaseId;
117 : : Indexing_Index caseListArray;
118 : : M2CaseList_CaseList currentCase;
119 : : M2CaseList_CaseDescriptor next;
120 : : };
121 : :
122 : : struct M2CaseList__T5_r {
123 : : tree low;
124 : : tree high;
125 : : M2CaseList_SetRange next;
126 : : };
127 : :
128 : : static M2CaseList_CaseDescriptor caseStack;
129 : : static unsigned int caseId;
130 : : static Indexing_Index caseArray;
131 : : static Indexing_Index conflictArray;
132 : : static M2CaseList_SetRange FreeRangeList;
133 : : static DynamicStrings_String errorString;
134 : :
135 : : /*
136 : : PushCase - create a case entity and push it to an internal stack.
137 : : rec is NulSym if this is a CASE statement.
138 : : If rec is a record then it indicates a possible
139 : : varients reside in the record to check.
140 : : Both rec and va might be NulSym and then the expr
141 : : will contain the selector expression to a case statement.
142 : : Return the case id.
143 : : */
144 : :
145 : : extern "C" unsigned int M2CaseList_PushCase (unsigned int rec, unsigned int va, unsigned int expr);
146 : :
147 : : /*
148 : : PopCase - pop the top element of the case entity from the internal
149 : : stack.
150 : : */
151 : :
152 : : extern "C" void M2CaseList_PopCase (void);
153 : :
154 : : /*
155 : : ElseCase - indicates that this case varient does have an else clause.
156 : : */
157 : :
158 : : extern "C" void M2CaseList_ElseCase (unsigned int f);
159 : :
160 : : /*
161 : : BeginCaseList - create a new label list.
162 : : */
163 : :
164 : : extern "C" void M2CaseList_BeginCaseList (unsigned int v);
165 : :
166 : : /*
167 : : EndCaseList - terminate the current label list.
168 : : */
169 : :
170 : : extern "C" void M2CaseList_EndCaseList (void);
171 : :
172 : : /*
173 : : AddRange - add a range to the current label list.
174 : : */
175 : :
176 : : extern "C" void M2CaseList_AddRange (unsigned int r1, unsigned int r2, unsigned int tok);
177 : :
178 : : /*
179 : : CaseBoundsResolved - returns TRUE if all constants in the case list, c,
180 : : are known to GCC.
181 : : */
182 : :
183 : : extern "C" bool M2CaseList_CaseBoundsResolved (unsigned int tokenno, unsigned int c);
184 : :
185 : : /*
186 : : TypeCaseBounds - returns true if all bounds in case list, c, are
187 : : compatible with the tagged type.
188 : : */
189 : :
190 : : extern "C" bool M2CaseList_TypeCaseBounds (unsigned int c);
191 : :
192 : : /*
193 : : OverlappingCaseBounds - returns TRUE if there were any overlapping bounds
194 : : in the case list, c. It will generate an error
195 : : messages for each overlapping bound found.
196 : : */
197 : :
198 : : extern "C" bool M2CaseList_OverlappingCaseBounds (unsigned int c);
199 : :
200 : : /*
201 : : MissingCaseBounds - returns true if there were any missing bounds
202 : : in the varient record case list, c. It will
203 : : generate an error message for each missing
204 : : bounds found.
205 : : */
206 : :
207 : : extern "C" bool M2CaseList_MissingCaseBounds (unsigned int tokenno, unsigned int c);
208 : :
209 : : /*
210 : : MissingCaseStatementBounds - returns true if the case statement has a missing
211 : : clause. It will also generate error messages.
212 : : */
213 : :
214 : : extern "C" bool M2CaseList_MissingCaseStatementBounds (unsigned int tokenno, unsigned int c);
215 : :
216 : : /*
217 : : WriteCase - dump out the case list (internal debugging).
218 : : */
219 : :
220 : : extern "C" void M2CaseList_WriteCase (unsigned int c);
221 : :
222 : : /*
223 : : GetVariantTagType - returns the type associated with, variant.
224 : : */
225 : :
226 : : static unsigned int GetVariantTagType (unsigned int variant);
227 : :
228 : : /*
229 : : CheckCaseBoundsResolved - return TRUE if all constants in the case list c are known to GCC.
230 : : */
231 : :
232 : : static bool CheckCaseBoundsResolved (unsigned int tokenno, unsigned int c);
233 : :
234 : : /*
235 : : ConvertNulStr2NulChar -
236 : : */
237 : :
238 : : static void ConvertNulStr2NulChar (unsigned int tokenno, unsigned int c);
239 : :
240 : : /*
241 : : NulStr2NulChar - if sym is a const string of length 0 then return
242 : : a nul char instead otherwise return sym.
243 : : */
244 : :
245 : : static unsigned int NulStr2NulChar (unsigned int tok, unsigned int sym);
246 : :
247 : : /*
248 : : IsSame - return TRUE if r, s, are in, e.
249 : : */
250 : :
251 : : static bool IsSame (M2CaseList_ConflictingPair e, M2CaseList_RangePair r, M2CaseList_RangePair s);
252 : :
253 : : /*
254 : : SeenBefore -
255 : : */
256 : :
257 : : static bool SeenBefore (M2CaseList_RangePair r, M2CaseList_RangePair s);
258 : :
259 : : /*
260 : : Overlaps -
261 : : */
262 : :
263 : : static bool Overlaps (M2CaseList_RangePair r, M2CaseList_RangePair s);
264 : :
265 : : /*
266 : : GetCaseExpression - return the type from the expression.
267 : : */
268 : :
269 : : static unsigned int GetCaseExpression (M2CaseList_CaseDescriptor p);
270 : :
271 : : /*
272 : : OverlappingCaseBound - returns TRUE if, r, overlaps any case bound in the
273 : : case statement, c.
274 : : */
275 : :
276 : : static bool OverlappingCaseBound (M2CaseList_RangePair r, unsigned int c);
277 : :
278 : : /*
279 : : NewRanges - return a new range from the freelist or heap.
280 : : */
281 : :
282 : : static M2CaseList_SetRange NewRanges (void);
283 : :
284 : : /*
285 : : NewSet - returns a new set based on type with the low and high fields assigned
286 : : to the min and max values for the type.
287 : : */
288 : :
289 : : static M2CaseList_SetRange NewSet (unsigned int type);
290 : :
291 : : /*
292 : : DisposeRanges - place set and its list onto the free list.
293 : : */
294 : :
295 : : static M2CaseList_SetRange DisposeRanges (M2CaseList_SetRange set);
296 : :
297 : : /*
298 : : RemoveRange - removes the range descriptor h from set and return the
299 : : possibly new head of set.
300 : : */
301 : :
302 : : static M2CaseList_SetRange RemoveRange (M2CaseList_SetRange set, M2CaseList_SetRange h);
303 : :
304 : : /*
305 : : SubBitRange - subtracts bits, lo..hi, from, set.
306 : : */
307 : :
308 : : static M2CaseList_SetRange SubBitRange (M2CaseList_SetRange set, tree lo, tree hi, unsigned int tokenno);
309 : :
310 : : /*
311 : : CheckLowHigh - checks to see the low value <= high value and issues an error
312 : : if this is not true.
313 : : */
314 : :
315 : : static void CheckLowHigh (M2CaseList_RangePair rp);
316 : :
317 : : /*
318 : : ExcludeCaseRanges - excludes all case ranges found in, p, from, set
319 : : */
320 : :
321 : : static M2CaseList_SetRange ExcludeCaseRanges (M2CaseList_SetRange set, M2CaseList_CaseDescriptor cd);
322 : :
323 : : /*
324 : : IncludeElement - only include enumeration field into errorString if it lies between low..high.
325 : : */
326 : :
327 : : static void IncludeElement (Lists_List enumList, unsigned int field, tree low, tree high);
328 : :
329 : : /*
330 : : IncludeElements - only include enumeration field values low..high in errorString.
331 : : */
332 : :
333 : : static void IncludeElements (unsigned int type, Lists_List enumList, tree low, tree high);
334 : :
335 : : /*
336 : : ErrorRangeEnum - include enumeration fields Low to High in errorString.
337 : : */
338 : :
339 : : static void ErrorRangeEnum (unsigned int type, M2CaseList_SetRange set, Lists_List enumList);
340 : :
341 : : /*
342 : : ErrorRanges - return a list of all enumeration fields not present in the case statement.
343 : : The return value will be nil if type is not an enumeration type.
344 : : */
345 : :
346 : : static Lists_List ErrorRanges (unsigned int type, M2CaseList_SetRange set);
347 : :
348 : : /*
349 : : appendString - appends str to errorString.
350 : : */
351 : :
352 : : static void appendString (DynamicStrings_String str);
353 : :
354 : : /*
355 : : appendEnum - appends enum to errorString.
356 : : */
357 : :
358 : : static void appendEnum (unsigned int enum_);
359 : :
360 : : /*
361 : : appendStr - appends str to errorString.
362 : : */
363 : :
364 : : static void appendStr (const char *str_, unsigned int _str_high);
365 : :
366 : : /*
367 : : EnumerateErrors - populate errorString with the contents of enumList.
368 : : */
369 : :
370 : : static void EnumerateErrors (Lists_List enumList);
371 : :
372 : : /*
373 : : NoOfSetElements - return the number of set elements.
374 : : */
375 : :
376 : : static tree NoOfSetElements (M2CaseList_SetRange set);
377 : :
378 : : /*
379 : : isPrintableChar - a cautious isprint.
380 : : */
381 : :
382 : : static bool isPrintableChar (tree value);
383 : :
384 : : /*
385 : : appendTree - append tree value to the errorString. It attempts to pretty print
386 : : CHAR constants and will fall back to CHR (x) if necessary.
387 : : */
388 : :
389 : : static void appendTree (tree value, unsigned int type);
390 : :
391 : : /*
392 : : SubrangeErrors - create an errorString containing all set ranges.
393 : : */
394 : :
395 : : static void SubrangeErrors (unsigned int subrangetype, M2CaseList_SetRange set);
396 : :
397 : : /*
398 : : EmitMissingRangeErrors - emits a singular/plural error message for an enumeration type.
399 : : */
400 : :
401 : : static void EmitMissingRangeErrors (unsigned int tokenno, unsigned int type, M2CaseList_SetRange set);
402 : :
403 : : /*
404 : : checkTypes - checks to see that, constant, and, type, are compatible.
405 : : */
406 : :
407 : : static bool checkTypes (unsigned int constant, unsigned int type);
408 : :
409 : : /*
410 : : inRange - returns true if, min <= i <= max.
411 : : */
412 : :
413 : : static bool inRange (unsigned int i, unsigned int min, unsigned int max);
414 : :
415 : :
416 : : /*
417 : : GetVariantTagType - returns the type associated with, variant.
418 : : */
419 : :
420 : 768 : static unsigned int GetVariantTagType (unsigned int variant)
421 : : {
422 : 768 : unsigned int tag;
423 : :
424 : 768 : tag = SymbolTable_GetVarientTag (variant);
425 : 768 : if ((SymbolTable_IsFieldVarient (tag)) || (SymbolTable_IsRecordField (tag)))
426 : : {
427 : 744 : return SymbolTable_GetType (tag);
428 : : }
429 : : else
430 : : {
431 : : return tag;
432 : : }
433 : : /* static analysis guarentees a RETURN statement will be used before here. */
434 : : __builtin_unreachable ();
435 : : }
436 : :
437 : :
438 : : /*
439 : : CheckCaseBoundsResolved - return TRUE if all constants in the case list c are known to GCC.
440 : : */
441 : :
442 : 1132 : static bool CheckCaseBoundsResolved (unsigned int tokenno, unsigned int c)
443 : : {
444 : 1132 : M2CaseList_CaseDescriptor p;
445 : 1132 : M2CaseList_CaseList q;
446 : 1132 : M2CaseList_RangePair r;
447 : 1132 : unsigned int min;
448 : 1132 : unsigned int max;
449 : 1132 : unsigned int type;
450 : 1132 : unsigned int i;
451 : 1132 : unsigned int j;
452 : :
453 : 1132 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
454 : 1132 : if (p->varient != SymbolTable_NulSym)
455 : : {
456 : : /* not a CASE statement, but a varient record containing without an ELSE clause */
457 : 480 : type = GetVariantTagType (p->varient);
458 : 480 : p->resolved = true;
459 : 480 : if (! (SymbolConversion_GccKnowsAbout (type)))
460 : : {
461 : : /* do we need to add, type, to the list of types required to be resolved? */
462 : 114 : p->resolved = false;
463 : : }
464 : 480 : min = M2GCCDeclare_GetTypeMin (type);
465 : 480 : if (! (SymbolConversion_GccKnowsAbout (min)))
466 : : {
467 : 204 : M2GCCDeclare_TryDeclareConstant (tokenno, min);
468 : 204 : p->resolved = false;
469 : : }
470 : 480 : max = M2GCCDeclare_GetTypeMax (type);
471 : 480 : if (! (SymbolConversion_GccKnowsAbout (max)))
472 : : {
473 : 204 : M2GCCDeclare_TryDeclareConstant (tokenno, max);
474 : 204 : p->resolved = false;
475 : : }
476 : 480 : if (! p->resolved)
477 : : {
478 : : return false;
479 : : }
480 : : }
481 : : i = 1;
482 : 4130 : while (i <= p->maxCaseId)
483 : : {
484 : 3274 : q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
485 : 3274 : j = 1;
486 : 9842 : while (j <= q->maxRangeId)
487 : : {
488 : 3366 : r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
489 : 3366 : if (r->low != SymbolTable_NulSym)
490 : : {
491 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
492 : 3366 : if (SymbolTable_IsConst (r->low))
493 : : {
494 : : /* avoid dangling else. */
495 : 3366 : M2GCCDeclare_TryDeclareConstant (tokenno, r->low);
496 : 3366 : if (! (SymbolConversion_GccKnowsAbout (r->low)))
497 : : {
498 : : return false;
499 : : }
500 : : }
501 : : else
502 : : {
503 : 0 : if (r->high == SymbolTable_NulSym)
504 : : {
505 : 0 : M2MetaError_MetaError1 ((const char *) "the CASE statement variant must be defined by a constant {%1Da:is a {%1d}}", 74, r->low);
506 : : }
507 : : else
508 : : {
509 : 0 : M2MetaError_MetaError1 ((const char *) "the CASE statement variant low value in a range must be defined by a constant {%1Da:is a {%1d}}", 95, r->low);
510 : : }
511 : : }
512 : : }
513 : 3294 : if (r->high != SymbolTable_NulSym)
514 : : {
515 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
516 : 168 : if (SymbolTable_IsConst (r->high))
517 : : {
518 : : /* avoid dangling else. */
519 : 168 : M2GCCDeclare_TryDeclareConstant (tokenno, r->high);
520 : 168 : if (! (SymbolConversion_GccKnowsAbout (r->high)))
521 : : {
522 : : return false;
523 : : }
524 : : }
525 : : else
526 : : {
527 : 0 : M2MetaError_MetaError1 ((const char *) "the CASE statement variant high value in a range must be defined by a constant {%1Da:is a {%1d}}", 96, r->high);
528 : : }
529 : : }
530 : 3294 : j += 1;
531 : : }
532 : 3202 : i += 1;
533 : : }
534 : : return true;
535 : : /* static analysis guarentees a RETURN statement will be used before here. */
536 : : __builtin_unreachable ();
537 : : }
538 : :
539 : :
540 : : /*
541 : : ConvertNulStr2NulChar -
542 : : */
543 : :
544 : 856 : static void ConvertNulStr2NulChar (unsigned int tokenno, unsigned int c)
545 : : {
546 : 856 : M2CaseList_CaseDescriptor p;
547 : 856 : M2CaseList_CaseList q;
548 : 856 : M2CaseList_RangePair r;
549 : 856 : unsigned int i;
550 : 856 : unsigned int j;
551 : :
552 : 856 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
553 : 856 : i = 1;
554 : 4914 : while (i <= p->maxCaseId)
555 : : {
556 : 3202 : q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
557 : 3202 : j = 1;
558 : 9698 : while (j <= q->maxRangeId)
559 : : {
560 : 3294 : r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
561 : 3294 : r->low = NulStr2NulChar (tokenno, r->low);
562 : 3294 : r->high = NulStr2NulChar (tokenno, r->high);
563 : 3294 : j += 1;
564 : : }
565 : 3202 : i += 1;
566 : : }
567 : 856 : }
568 : :
569 : :
570 : : /*
571 : : NulStr2NulChar - if sym is a const string of length 0 then return
572 : : a nul char instead otherwise return sym.
573 : : */
574 : :
575 : 6588 : static unsigned int NulStr2NulChar (unsigned int tok, unsigned int sym)
576 : : {
577 : 6588 : if (sym != SymbolTable_NulSym)
578 : : {
579 : 3462 : if (((SymbolTable_IsConst (sym)) && (SymbolTable_IsConstString (sym))) && (SymbolConversion_GccKnowsAbout (sym)))
580 : : {
581 : 500 : if ((SymbolTable_GetStringLength (tok, sym)) == 0)
582 : : {
583 : 6 : sym = SymbolTable_MakeConstVar (tok, NameKey_NulName);
584 : 6 : SymbolTable_PutConst (sym, M2Base_Char);
585 : 6 : M2ALU_PushCard (0);
586 : 6 : SymbolTable_PopValue (sym);
587 : 6 : M2GCCDeclare_TryDeclareConstant (tok, sym);
588 : 6 : M2Debug_Assert (SymbolConversion_GccKnowsAbout (sym));
589 : : }
590 : : }
591 : : }
592 : 6588 : return sym;
593 : : /* static analysis guarentees a RETURN statement will be used before here. */
594 : : __builtin_unreachable ();
595 : : }
596 : :
597 : :
598 : : /*
599 : : IsSame - return TRUE if r, s, are in, e.
600 : : */
601 : :
602 : 24 : static bool IsSame (M2CaseList_ConflictingPair e, M2CaseList_RangePair r, M2CaseList_RangePair s)
603 : : {
604 : 24 : return ((e->a == r) && (e->b == s)) || ((e->a == s) && (e->b == r));
605 : : /* static analysis guarentees a RETURN statement will be used before here. */
606 : : __builtin_unreachable ();
607 : : }
608 : :
609 : :
610 : : /*
611 : : SeenBefore -
612 : : */
613 : :
614 : 48 : static bool SeenBefore (M2CaseList_RangePair r, M2CaseList_RangePair s)
615 : : {
616 : 48 : unsigned int i;
617 : 48 : unsigned int h;
618 : 48 : M2CaseList_ConflictingPair e;
619 : :
620 : 48 : h = Indexing_HighIndice (conflictArray);
621 : 48 : i = 1;
622 : 96 : while (i <= h)
623 : : {
624 : 24 : e = static_cast<M2CaseList_ConflictingPair> (Indexing_GetIndice (conflictArray, i));
625 : 24 : if (IsSame (e, r, s))
626 : : {
627 : : return true;
628 : : }
629 : 0 : i += 1;
630 : : }
631 : 24 : Storage_ALLOCATE ((void **) &e, sizeof (M2CaseList__T2));
632 : 24 : e->a = r;
633 : 24 : e->b = s;
634 : 24 : Indexing_PutIndice (conflictArray, h+1, reinterpret_cast <void *> (e));
635 : 24 : return false;
636 : : /* static analysis guarentees a RETURN statement will be used before here. */
637 : : __builtin_unreachable ();
638 : : }
639 : :
640 : :
641 : : /*
642 : : Overlaps -
643 : : */
644 : :
645 : 51256 : static bool Overlaps (M2CaseList_RangePair r, M2CaseList_RangePair s)
646 : : {
647 : 51256 : unsigned int a;
648 : 51256 : unsigned int b;
649 : 51256 : unsigned int c;
650 : 51256 : unsigned int d;
651 : :
652 : 51256 : a = r->low;
653 : 51256 : c = s->low;
654 : 51256 : if (r->high == SymbolTable_NulSym)
655 : : {
656 : : /* avoid dangling else. */
657 : 50752 : b = a;
658 : 50752 : if (s->high == SymbolTable_NulSym)
659 : : {
660 : : /* avoid dangling else. */
661 : 50416 : d = c;
662 : 50416 : if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
663 : : {
664 : 24 : if (! (SeenBefore (r, s)))
665 : : {
666 : 12 : M2MetaError_MetaErrorT2 (r->tokenno, (const char *) "case label {%1ad} is a duplicate with {%2ad}", 44, a, c);
667 : 12 : M2MetaError_MetaErrorT2 (s->tokenno, (const char *) "case label {%1ad} is a duplicate with {%2ad}", 44, c, a);
668 : : }
669 : 24 : return true;
670 : : }
671 : : }
672 : : else
673 : : {
674 : 336 : d = s->high;
675 : 336 : if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
676 : : {
677 : 6 : if (! (SeenBefore (r, s)))
678 : : {
679 : 6 : M2MetaError_MetaErrorT3 (r->tokenno, (const char *) "case label {%1ad} is a duplicate in the range {%2ad}..{%3ad}", 60, a, c, d);
680 : 6 : M2MetaError_MetaErrorT3 (s->tokenno, (const char *) "case range {%2ad}..{%3ad} is a duplicate of case label {%1ad}", 61, c, d, a);
681 : : }
682 : 6 : return true;
683 : : }
684 : : }
685 : : }
686 : : else
687 : : {
688 : 504 : b = r->high;
689 : 504 : if (s->high == SymbolTable_NulSym)
690 : : {
691 : : /* avoid dangling else. */
692 : 336 : d = c;
693 : 336 : if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
694 : : {
695 : 6 : if (! (SeenBefore (r, s)))
696 : : {
697 : 0 : M2MetaError_MetaErrorT3 (r->tokenno, (const char *) "case range {%1ad}..{%2ad} is a duplicate with case label {%3ad}", 63, a, b, c);
698 : 0 : M2MetaError_MetaErrorT3 (s->tokenno, (const char *) "case label {%1ad} is a duplicate with case range %{2ad}..{%3ad}", 63, c, a, b);
699 : : }
700 : 6 : return true;
701 : : }
702 : : }
703 : : else
704 : : {
705 : 168 : d = s->high;
706 : 168 : if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
707 : : {
708 : 12 : if (! (SeenBefore (r, s)))
709 : : {
710 : 6 : M2MetaError_MetaErrorT4 (r->tokenno, (const char *) "case range {%1ad}..{%2ad} overlaps case range {%3ad}..{%4ad}", 60, a, b, c, d);
711 : 6 : M2MetaError_MetaErrorT4 (s->tokenno, (const char *) "case range {%1ad}..{%2ad} overlaps case range {%3ad}..{%4ad}", 60, c, d, a, b);
712 : : }
713 : 12 : return true;
714 : : }
715 : : }
716 : : }
717 : : return false;
718 : : /* static analysis guarentees a RETURN statement will be used before here. */
719 : : __builtin_unreachable ();
720 : : }
721 : :
722 : :
723 : : /*
724 : : GetCaseExpression - return the type from the expression.
725 : : */
726 : :
727 : 120 : static unsigned int GetCaseExpression (M2CaseList_CaseDescriptor p)
728 : : {
729 : 120 : unsigned int type;
730 : :
731 : 120 : if (p->expression == SymbolTable_NulSym)
732 : : {
733 : : type = SymbolTable_NulSym;
734 : : }
735 : : else
736 : : {
737 : 120 : type = SymbolTable_SkipType (SymbolTable_GetType (p->expression));
738 : : }
739 : 120 : return type;
740 : : /* static analysis guarentees a RETURN statement will be used before here. */
741 : : __builtin_unreachable ();
742 : : }
743 : :
744 : :
745 : : /*
746 : : OverlappingCaseBound - returns TRUE if, r, overlaps any case bound in the
747 : : case statement, c.
748 : : */
749 : :
750 : 3294 : static bool OverlappingCaseBound (M2CaseList_RangePair r, unsigned int c)
751 : : {
752 : 3294 : M2CaseList_CaseDescriptor p;
753 : 3294 : M2CaseList_CaseList q;
754 : 3294 : M2CaseList_RangePair s;
755 : 3294 : unsigned int i;
756 : 3294 : unsigned int j;
757 : 3294 : bool overlap;
758 : :
759 : 3294 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
760 : 3294 : overlap = false;
761 : 3294 : i = 1;
762 : 60806 : while (i <= p->maxCaseId)
763 : : {
764 : 54218 : q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
765 : 54218 : j = 1;
766 : 162986 : while (j <= q->maxRangeId)
767 : : {
768 : 54550 : s = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
769 : 54550 : if ((s != r) && (Overlaps (r, s)))
770 : : {
771 : : overlap = true;
772 : : }
773 : 54550 : j += 1;
774 : : }
775 : 54218 : i += 1;
776 : : }
777 : 3294 : return overlap;
778 : : /* static analysis guarentees a RETURN statement will be used before here. */
779 : : __builtin_unreachable ();
780 : : }
781 : :
782 : :
783 : : /*
784 : : NewRanges - return a new range from the freelist or heap.
785 : : */
786 : :
787 : 164 : static M2CaseList_SetRange NewRanges (void)
788 : : {
789 : 164 : M2CaseList_SetRange s;
790 : :
791 : 164 : if (FreeRangeList == NULL)
792 : : {
793 : 152 : Storage_ALLOCATE ((void **) &s, sizeof (M2CaseList__T5));
794 : : }
795 : : else
796 : : {
797 : 12 : s = FreeRangeList;
798 : 12 : FreeRangeList = FreeRangeList->next;
799 : : }
800 : 164 : s->next = NULL;
801 : 164 : return s;
802 : : /* static analysis guarentees a RETURN statement will be used before here. */
803 : : __builtin_unreachable ();
804 : : }
805 : :
806 : :
807 : : /*
808 : : NewSet - returns a new set based on type with the low and high fields assigned
809 : : to the min and max values for the type.
810 : : */
811 : :
812 : 128 : static M2CaseList_SetRange NewSet (unsigned int type)
813 : : {
814 : 128 : M2CaseList_SetRange s;
815 : :
816 : 128 : s = NewRanges ();
817 : 128 : s->low = SymbolConversion_Mod2Gcc (M2GCCDeclare_GetTypeMin (type));
818 : 128 : s->high = SymbolConversion_Mod2Gcc (M2GCCDeclare_GetTypeMax (type));
819 : 128 : s->next = NULL;
820 : 128 : return s;
821 : : /* static analysis guarentees a RETURN statement will be used before here. */
822 : : __builtin_unreachable ();
823 : : }
824 : :
825 : :
826 : : /*
827 : : DisposeRanges - place set and its list onto the free list.
828 : : */
829 : :
830 : 202 : static M2CaseList_SetRange DisposeRanges (M2CaseList_SetRange set)
831 : : {
832 : 202 : M2CaseList_SetRange t;
833 : :
834 : 202 : if (set != NULL)
835 : : {
836 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
837 : 134 : if (FreeRangeList == NULL)
838 : : {
839 : 128 : FreeRangeList = set;
840 : : }
841 : : else
842 : : {
843 : : t = set;
844 : 6 : while (t->next != NULL)
845 : : {
846 : : t = t->next;
847 : : }
848 : 6 : t->next = FreeRangeList;
849 : 6 : FreeRangeList = set;
850 : : }
851 : : }
852 : 202 : return NULL;
853 : : /* static analysis guarentees a RETURN statement will be used before here. */
854 : : __builtin_unreachable ();
855 : : }
856 : :
857 : :
858 : : /*
859 : : RemoveRange - removes the range descriptor h from set and return the
860 : : possibly new head of set.
861 : : */
862 : :
863 : 74 : static M2CaseList_SetRange RemoveRange (M2CaseList_SetRange set, M2CaseList_SetRange h)
864 : : {
865 : 74 : M2CaseList_SetRange i;
866 : :
867 : 74 : if (h == set)
868 : : {
869 : 68 : set = set->next;
870 : 68 : h->next = NULL;
871 : 68 : h = DisposeRanges (h);
872 : : }
873 : : else
874 : : {
875 : : i = set;
876 : 6 : while (i->next != h)
877 : : {
878 : : i = i->next;
879 : : }
880 : 6 : i->next = h->next;
881 : 6 : i = h;
882 : 6 : h = h->next;
883 : 6 : i->next = NULL;
884 : 6 : i = DisposeRanges (i);
885 : : }
886 : 74 : return set;
887 : : /* static analysis guarentees a RETURN statement will be used before here. */
888 : : __builtin_unreachable ();
889 : : }
890 : :
891 : :
892 : : /*
893 : : SubBitRange - subtracts bits, lo..hi, from, set.
894 : : */
895 : :
896 : 384 : static M2CaseList_SetRange SubBitRange (M2CaseList_SetRange set, tree lo, tree hi, unsigned int tokenno)
897 : : {
898 : 384 : M2CaseList_SetRange h;
899 : 384 : M2CaseList_SetRange i;
900 : :
901 : 384 : h = set;
902 : : /* Check to see if a single set element h is obliterated by lo..hi. */
903 : 1114 : while (h != NULL)
904 : : {
905 : 742 : if ((h->high == NULL) || (M2Range_IsEqual (h->high, h->low)))
906 : : {
907 : 166 : if ((M2Range_IsEqual (h->low, lo)) || (M2Range_OverlapsRange (lo, hi, h->low, h->low)))
908 : : {
909 : 62 : set = RemoveRange (set, h);
910 : 62 : h = set;
911 : : }
912 : : else
913 : : {
914 : 104 : h = h->next;
915 : : }
916 : : /* Now check to see if the lo..hi match exactly with the set range. */
917 : : }
918 : 576 : else if (((h->high != NULL) && (M2Range_IsEqual (lo, h->low))) && (M2Range_IsEqual (hi, h->high)))
919 : : {
920 : : /* avoid dangling else. */
921 : : /* Remove h and return as lo..hi have been removed. */
922 : 12 : return RemoveRange (set, h);
923 : : }
924 : : else
925 : : {
926 : : /* avoid dangling else. */
927 : : /* All other cases require modifying the existing set range. */
928 : 564 : if (M2Range_OverlapsRange (lo, hi, h->low, h->high))
929 : : {
930 : 304 : if ((M2Range_IsGreater (h->low, lo)) || (M2Range_IsGreater (hi, h->high)))
931 : : {
932 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "variant case range lies outside tag value", 41);
933 : : }
934 : : else
935 : : {
936 : 304 : if (M2Range_IsEqual (h->low, lo))
937 : : {
938 : 230 : M2ALU_PushIntegerTree (hi);
939 : 230 : M2ALU_PushInt (1);
940 : 230 : M2ALU_Addn ();
941 : 230 : h->low = M2ALU_PopIntegerTree ();
942 : : }
943 : 74 : else if (M2Range_IsEqual (h->high, hi))
944 : : {
945 : : /* avoid dangling else. */
946 : 38 : M2ALU_PushIntegerTree (lo);
947 : 38 : M2ALU_PushInt (1);
948 : 38 : M2ALU_Sub ();
949 : 38 : h->high = M2ALU_PopIntegerTree ();
950 : : }
951 : : else
952 : : {
953 : : /* avoid dangling else. */
954 : : /* lo..hi exist inside range h^.low..h^.high */
955 : 36 : i = NewRanges ();
956 : 36 : i->next = h->next;
957 : 36 : h->next = i;
958 : 36 : i->high = h->high;
959 : 36 : M2ALU_PushIntegerTree (lo);
960 : 36 : M2ALU_PushInt (1);
961 : 36 : M2ALU_Sub ();
962 : 36 : h->high = M2ALU_PopIntegerTree ();
963 : 36 : M2ALU_PushIntegerTree (hi);
964 : 36 : M2ALU_PushInt (1);
965 : 36 : M2ALU_Addn ();
966 : 36 : i->low = M2ALU_PopIntegerTree ();
967 : : }
968 : : }
969 : : }
970 : : else
971 : : {
972 : 260 : h = h->next;
973 : : }
974 : : }
975 : : }
976 : : return set;
977 : : /* static analysis guarentees a RETURN statement will be used before here. */
978 : : __builtin_unreachable ();
979 : : }
980 : :
981 : :
982 : : /*
983 : : CheckLowHigh - checks to see the low value <= high value and issues an error
984 : : if this is not true.
985 : : */
986 : :
987 : 66 : static void CheckLowHigh (M2CaseList_RangePair rp)
988 : : {
989 : 66 : tree lo;
990 : 66 : tree hi;
991 : 66 : unsigned int temp;
992 : :
993 : 66 : lo = SymbolConversion_Mod2Gcc (rp->low);
994 : 66 : hi = SymbolConversion_Mod2Gcc (rp->high);
995 : 66 : if (M2Range_IsGreater (lo, hi))
996 : : {
997 : 0 : M2MetaError_MetaErrorT2 (rp->tokenno, (const char *) "case range should be low..high rather than high..low, range specified as {%1Euad}..{%2Euad}", 91, rp->low, rp->high);
998 : 0 : temp = rp->high;
999 : 0 : rp->high = rp->low;
1000 : 0 : rp->low = temp;
1001 : : }
1002 : 66 : }
1003 : :
1004 : :
1005 : : /*
1006 : : ExcludeCaseRanges - excludes all case ranges found in, p, from, set
1007 : : */
1008 : :
1009 : 128 : static M2CaseList_SetRange ExcludeCaseRanges (M2CaseList_SetRange set, M2CaseList_CaseDescriptor cd)
1010 : : {
1011 : 128 : unsigned int i;
1012 : 128 : unsigned int j;
1013 : 128 : M2CaseList_CaseList cl;
1014 : 128 : M2CaseList_RangePair rp;
1015 : :
1016 : 128 : i = 1;
1017 : 462 : while (i <= cd->maxCaseId)
1018 : : {
1019 : 334 : cl = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (cd->caseListArray, i));
1020 : 334 : j = 1;
1021 : 1052 : while (j <= cl->maxRangeId)
1022 : : {
1023 : 384 : rp = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (cl->rangeArray, j));
1024 : 384 : if (rp->high == SymbolTable_NulSym)
1025 : : {
1026 : 318 : set = SubBitRange (set, SymbolConversion_Mod2Gcc (rp->low), SymbolConversion_Mod2Gcc (rp->low), rp->tokenno);
1027 : : }
1028 : : else
1029 : : {
1030 : 66 : CheckLowHigh (rp);
1031 : 66 : set = SubBitRange (set, SymbolConversion_Mod2Gcc (rp->low), SymbolConversion_Mod2Gcc (rp->high), rp->tokenno);
1032 : : }
1033 : 384 : j += 1;
1034 : : }
1035 : 334 : i += 1;
1036 : : }
1037 : 128 : return set;
1038 : : /* static analysis guarentees a RETURN statement will be used before here. */
1039 : : __builtin_unreachable ();
1040 : : }
1041 : :
1042 : :
1043 : : /*
1044 : : IncludeElement - only include enumeration field into errorString if it lies between low..high.
1045 : : */
1046 : :
1047 : 18 : static void IncludeElement (Lists_List enumList, unsigned int field, tree low, tree high)
1048 : : {
1049 : 18 : tree fieldTree;
1050 : :
1051 : 18 : if (field != SymbolTable_NulSym)
1052 : : {
1053 : 18 : fieldTree = SymbolConversion_Mod2Gcc (field);
1054 : 18 : if (M2Range_OverlapsRange (fieldTree, fieldTree, low, high))
1055 : : {
1056 : 6 : Lists_IncludeItemIntoList (enumList, field);
1057 : : }
1058 : : }
1059 : 18 : }
1060 : :
1061 : :
1062 : : /*
1063 : : IncludeElements - only include enumeration field values low..high in errorString.
1064 : : */
1065 : :
1066 : 6 : static void IncludeElements (unsigned int type, Lists_List enumList, tree low, tree high)
1067 : : {
1068 : 6 : unsigned int field;
1069 : 6 : unsigned int i;
1070 : 6 : unsigned int NoElements;
1071 : :
1072 : 6 : NoElements = SymbolTable_NoOfElements (type);
1073 : 6 : i = 1;
1074 : 30 : while (i <= NoElements)
1075 : : {
1076 : 18 : field = SymbolTable_GetNth (type, i);
1077 : 18 : IncludeElement (enumList, field, low, high);
1078 : 18 : i += 1;
1079 : : }
1080 : 6 : }
1081 : :
1082 : :
1083 : : /*
1084 : : ErrorRangeEnum - include enumeration fields Low to High in errorString.
1085 : : */
1086 : :
1087 : 6 : static void ErrorRangeEnum (unsigned int type, M2CaseList_SetRange set, Lists_List enumList)
1088 : : {
1089 : 6 : tree Low;
1090 : 6 : tree High;
1091 : :
1092 : 6 : Low = set->low;
1093 : 6 : High = set->high;
1094 : 6 : if (Low == NULL)
1095 : : {
1096 : 0 : Low = High;
1097 : : }
1098 : 6 : if (High == NULL)
1099 : : {
1100 : 0 : High = Low;
1101 : : }
1102 : 6 : if ((Low != NULL) && (High != NULL))
1103 : : {
1104 : 6 : IncludeElements (type, enumList, Low, High);
1105 : : }
1106 : 6 : }
1107 : :
1108 : :
1109 : : /*
1110 : : ErrorRanges - return a list of all enumeration fields not present in the case statement.
1111 : : The return value will be nil if type is not an enumeration type.
1112 : : */
1113 : :
1114 : 6 : static Lists_List ErrorRanges (unsigned int type, M2CaseList_SetRange set)
1115 : : {
1116 : 6 : Lists_List enumSet;
1117 : :
1118 : 6 : type = SymbolTable_SkipType (type);
1119 : 6 : if (SymbolTable_IsEnumeration (type))
1120 : : {
1121 : 6 : Lists_InitList (&enumSet);
1122 : 18 : while (set != NULL)
1123 : : {
1124 : 6 : ErrorRangeEnum (type, set, enumSet);
1125 : 6 : set = set->next;
1126 : : }
1127 : 6 : return enumSet;
1128 : : }
1129 : : return static_cast<Lists_List> (NULL);
1130 : : /* static analysis guarentees a RETURN statement will be used before here. */
1131 : : __builtin_unreachable ();
1132 : : }
1133 : :
1134 : :
1135 : : /*
1136 : : appendString - appends str to errorString.
1137 : : */
1138 : :
1139 : 450 : static void appendString (DynamicStrings_String str)
1140 : : {
1141 : 450 : errorString = DynamicStrings_ConCat (errorString, str);
1142 : 450 : }
1143 : :
1144 : :
1145 : : /*
1146 : : appendEnum - appends enum to errorString.
1147 : : */
1148 : :
1149 : 6 : static void appendEnum (unsigned int enum_)
1150 : : {
1151 : 6 : appendString (DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (enum_)))));
1152 : 6 : }
1153 : :
1154 : :
1155 : : /*
1156 : : appendStr - appends str to errorString.
1157 : : */
1158 : :
1159 : 162 : static void appendStr (const char *str_, unsigned int _str_high)
1160 : : {
1161 : 162 : char str[_str_high+1];
1162 : :
1163 : : /* make a local copy of each unbounded array. */
1164 : 162 : memcpy (str, str_, _str_high+1);
1165 : :
1166 : 162 : appendString (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) str, _str_high)));
1167 : 162 : }
1168 : :
1169 : :
1170 : : /*
1171 : : EnumerateErrors - populate errorString with the contents of enumList.
1172 : : */
1173 : :
1174 : 6 : static void EnumerateErrors (Lists_List enumList)
1175 : : {
1176 : 6 : unsigned int i;
1177 : 6 : unsigned int n;
1178 : :
1179 : 6 : n = Lists_NoOfItemsInList (enumList);
1180 : 6 : if ((enumList != NULL) && (n > 0))
1181 : : {
1182 : 6 : if (n == 1)
1183 : : {
1184 : 6 : errorString = DynamicStrings_InitString ((const char *) "{%W}the missing enumeration field is: ", 38);
1185 : : }
1186 : : else
1187 : : {
1188 : 0 : errorString = DynamicStrings_InitString ((const char *) "{%W}the missing enumeration fields are: ", 40);
1189 : : }
1190 : 6 : appendEnum (Lists_GetItemFromList (enumList, 1));
1191 : 6 : if (n > 1)
1192 : : {
1193 : 0 : if (n > 2)
1194 : : {
1195 : : i = 2;
1196 : 0 : while (i <= (n-1))
1197 : : {
1198 : 0 : appendStr ((const char *) ", ", 2);
1199 : 0 : appendEnum (Lists_GetItemFromList (enumList, i));
1200 : 0 : i += 1;
1201 : : }
1202 : : }
1203 : 0 : appendStr ((const char *) " and ", 5);
1204 : 0 : appendEnum (Lists_GetItemFromList (enumList, n));
1205 : : }
1206 : : }
1207 : 6 : }
1208 : :
1209 : :
1210 : : /*
1211 : : NoOfSetElements - return the number of set elements.
1212 : : */
1213 : :
1214 : 42 : static tree NoOfSetElements (M2CaseList_SetRange set)
1215 : : {
1216 : 42 : M2ALU_PushInt (0);
1217 : 156 : while (set != NULL)
1218 : : {
1219 : 72 : if (((set->low != NULL) && (set->high == NULL)) || ((set->low == NULL) && (set->high != NULL)))
1220 : : {
1221 : 0 : M2ALU_PushInt (1);
1222 : 0 : M2ALU_Addn ();
1223 : : }
1224 : 72 : else if ((set->low != NULL) && (set->high != NULL))
1225 : : {
1226 : : /* avoid dangling else. */
1227 : 72 : M2ALU_PushIntegerTree (set->high);
1228 : 72 : M2ALU_PushIntegerTree (set->low);
1229 : 72 : M2ALU_Sub ();
1230 : 72 : M2ALU_PushInt (1);
1231 : 72 : M2ALU_Addn ();
1232 : 72 : M2ALU_Addn ();
1233 : : }
1234 : 72 : set = set->next;
1235 : : }
1236 : 42 : return M2ALU_PopIntegerTree ();
1237 : : /* static analysis guarentees a RETURN statement will be used before here. */
1238 : : __builtin_unreachable ();
1239 : : }
1240 : :
1241 : :
1242 : : /*
1243 : : isPrintableChar - a cautious isprint.
1244 : : */
1245 : :
1246 : 60 : static bool isPrintableChar (tree value)
1247 : : {
1248 : 60 : if (((m2expr_CSTIntToChar (value)) >= 'a') && ((m2expr_CSTIntToChar (value)) <= 'z'))
1249 : : {
1250 : : return true;
1251 : : }
1252 : 18 : else if (((m2expr_CSTIntToChar (value)) >= 'A') && ((m2expr_CSTIntToChar (value)) <= 'Z'))
1253 : : {
1254 : : return true;
1255 : : }
1256 : 18 : else if (((m2expr_CSTIntToChar (value)) >= '0') && ((m2expr_CSTIntToChar (value)) <= '9'))
1257 : : {
1258 : : return true;
1259 : : }
1260 : 18 : else if (((m2expr_CSTIntToChar (value)) == '!') || ((m2expr_CSTIntToChar (value)) == '@'))
1261 : : {
1262 : 0 : return true;
1263 : : }
1264 : 18 : else if (((m2expr_CSTIntToChar (value)) == '#') || ((m2expr_CSTIntToChar (value)) == '$'))
1265 : : {
1266 : 0 : return true;
1267 : : }
1268 : 18 : else if (((m2expr_CSTIntToChar (value)) == '%') || ((m2expr_CSTIntToChar (value)) == '^'))
1269 : : {
1270 : 0 : return true;
1271 : : }
1272 : 18 : else if (((m2expr_CSTIntToChar (value)) == '&') || ((m2expr_CSTIntToChar (value)) == '*'))
1273 : : {
1274 : 0 : return true;
1275 : : }
1276 : 18 : else if (((m2expr_CSTIntToChar (value)) == '(') || ((m2expr_CSTIntToChar (value)) == ')'))
1277 : : {
1278 : 0 : return true;
1279 : : }
1280 : 18 : else if (((m2expr_CSTIntToChar (value)) == '[') || ((m2expr_CSTIntToChar (value)) == ']'))
1281 : : {
1282 : 0 : return true;
1283 : : }
1284 : 18 : else if (((m2expr_CSTIntToChar (value)) == '{') || ((m2expr_CSTIntToChar (value)) == '}'))
1285 : : {
1286 : 0 : return true;
1287 : : }
1288 : 18 : else if (((m2expr_CSTIntToChar (value)) == '-') || ((m2expr_CSTIntToChar (value)) == '+'))
1289 : : {
1290 : 0 : return true;
1291 : : }
1292 : 18 : else if (((m2expr_CSTIntToChar (value)) == '_') || ((m2expr_CSTIntToChar (value)) == '='))
1293 : : {
1294 : 0 : return true;
1295 : : }
1296 : 18 : else if (((m2expr_CSTIntToChar (value)) == ':') || ((m2expr_CSTIntToChar (value)) == ';'))
1297 : : {
1298 : 0 : return true;
1299 : : }
1300 : 18 : else if (((m2expr_CSTIntToChar (value)) == '\'') || ((m2expr_CSTIntToChar (value)) == '"'))
1301 : : {
1302 : 0 : return true;
1303 : : }
1304 : 18 : else if (((m2expr_CSTIntToChar (value)) == ',') || ((m2expr_CSTIntToChar (value)) == '.'))
1305 : : {
1306 : 0 : return true;
1307 : : }
1308 : 18 : else if (((m2expr_CSTIntToChar (value)) == '<') || ((m2expr_CSTIntToChar (value)) == '>'))
1309 : : {
1310 : 0 : return true;
1311 : : }
1312 : 18 : else if (((m2expr_CSTIntToChar (value)) == '/') || ((m2expr_CSTIntToChar (value)) == '?'))
1313 : : {
1314 : 0 : return true;
1315 : : }
1316 : 18 : else if (((m2expr_CSTIntToChar (value)) == '\\') || ((m2expr_CSTIntToChar (value)) == '|'))
1317 : : {
1318 : 0 : return true;
1319 : : }
1320 : 18 : else if (((m2expr_CSTIntToChar (value)) == '~') || ((m2expr_CSTIntToChar (value)) == '`'))
1321 : : {
1322 : 6 : return true;
1323 : : }
1324 : 12 : else if (((m2expr_CSTIntToChar (value)) == ' '))
1325 : : {
1326 : : return true;
1327 : : }
1328 : :
1329 : : else {
1330 : : return false;
1331 : : }
1332 : : /* static analysis guarentees a RETURN statement will be used before here. */
1333 : : __builtin_unreachable ();
1334 : : }
1335 : :
1336 : :
1337 : : /*
1338 : : appendTree - append tree value to the errorString. It attempts to pretty print
1339 : : CHAR constants and will fall back to CHR (x) if necessary.
1340 : : */
1341 : :
1342 : 120 : static void appendTree (tree value, unsigned int type)
1343 : : {
1344 : 120 : if ((SymbolTable_SkipType (SymbolTable_GetType (type))) == M2Base_Char)
1345 : : {
1346 : 60 : if (isPrintableChar (value))
1347 : : {
1348 : 48 : if ((m2expr_CSTIntToChar (value)) == '\'')
1349 : : {
1350 : 0 : appendString (DynamicStrings_InitStringChar ('"'));
1351 : 0 : appendString (DynamicStrings_InitStringChar (m2expr_CSTIntToChar (value)));
1352 : 0 : appendString (DynamicStrings_InitStringChar ('"'));
1353 : : }
1354 : : else
1355 : : {
1356 : 48 : appendString (DynamicStrings_InitStringChar ('\''));
1357 : 48 : appendString (DynamicStrings_InitStringChar (m2expr_CSTIntToChar (value)));
1358 : 48 : appendString (DynamicStrings_InitStringChar ('\''));
1359 : : }
1360 : : }
1361 : : else
1362 : : {
1363 : 12 : appendString (DynamicStrings_InitString ((const char *) "CHR (", 5));
1364 : 12 : appendString (DynamicStrings_InitStringCharStar (reinterpret_cast <void *> (m2expr_CSTIntToString (value))));
1365 : 12 : appendString (DynamicStrings_InitStringChar (')'));
1366 : : }
1367 : : }
1368 : : else
1369 : : {
1370 : 60 : appendString (DynamicStrings_InitStringCharStar (reinterpret_cast <void *> (m2expr_CSTIntToString (value))));
1371 : : }
1372 : 120 : }
1373 : :
1374 : :
1375 : : /*
1376 : : SubrangeErrors - create an errorString containing all set ranges.
1377 : : */
1378 : :
1379 : 42 : static void SubrangeErrors (unsigned int subrangetype, M2CaseList_SetRange set)
1380 : : {
1381 : 42 : M2CaseList_SetRange sr;
1382 : 42 : unsigned int rangeNo;
1383 : 42 : tree nMissing;
1384 : 42 : tree zero;
1385 : 42 : tree one;
1386 : :
1387 : 42 : nMissing = NoOfSetElements (set);
1388 : 42 : M2ALU_PushInt (0);
1389 : 42 : zero = M2ALU_PopIntegerTree ();
1390 : 42 : if (M2Range_IsGreater (nMissing, zero))
1391 : : {
1392 : 42 : M2ALU_PushInt (1);
1393 : 42 : one = M2ALU_PopIntegerTree ();
1394 : 42 : if (M2Range_IsGreater (nMissing, one))
1395 : : {
1396 : 30 : errorString = DynamicStrings_InitString ((const char *) "{%W}there are a total of ", 25);
1397 : : }
1398 : : else
1399 : : {
1400 : 12 : errorString = DynamicStrings_InitString ((const char *) "{%W}there is a total of ", 24);
1401 : : }
1402 : 42 : appendString (DynamicStrings_InitStringCharStar (reinterpret_cast <void *> (m2expr_CSTIntToString (nMissing))));
1403 : 42 : appendStr ((const char *) " missing values in the subrange, the {%kCASE} statement needs labels (or an {%kELSE} statement)", 95);
1404 : 42 : appendStr ((const char *) " for the following values: ", 27);
1405 : 42 : sr = set;
1406 : 42 : rangeNo = 0;
1407 : 156 : while (sr != NULL)
1408 : : {
1409 : 72 : rangeNo += 1;
1410 : 72 : if (rangeNo > 1)
1411 : : {
1412 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1413 : 30 : if (sr->next == NULL)
1414 : : {
1415 : 24 : appendStr ((const char *) " and ", 5);
1416 : : }
1417 : : else
1418 : : {
1419 : 6 : appendStr ((const char *) ", ", 2);
1420 : : }
1421 : : }
1422 : 72 : if (sr->low == NULL)
1423 : : {
1424 : 0 : appendTree (sr->high, subrangetype);
1425 : : }
1426 : 72 : else if ((sr->high == NULL) || (M2Range_IsEqual (sr->low, sr->high)))
1427 : : {
1428 : : /* avoid dangling else. */
1429 : 24 : appendTree (sr->low, subrangetype);
1430 : : }
1431 : : else
1432 : : {
1433 : : /* avoid dangling else. */
1434 : 48 : appendTree (sr->low, subrangetype);
1435 : 48 : appendStr ((const char *) "..", 2);
1436 : 48 : appendTree (sr->high, subrangetype);
1437 : : }
1438 : 72 : sr = sr->next;
1439 : : }
1440 : : }
1441 : 42 : }
1442 : :
1443 : :
1444 : : /*
1445 : : EmitMissingRangeErrors - emits a singular/plural error message for an enumeration type.
1446 : : */
1447 : :
1448 : 60 : static void EmitMissingRangeErrors (unsigned int tokenno, unsigned int type, M2CaseList_SetRange set)
1449 : : {
1450 : 60 : errorString = static_cast<DynamicStrings_String> (NULL);
1451 : 60 : if (SymbolTable_IsEnumeration (type))
1452 : : {
1453 : 6 : EnumerateErrors (ErrorRanges (type, set));
1454 : : }
1455 : 54 : else if (SymbolTable_IsSubrange (type))
1456 : : {
1457 : : /* avoid dangling else. */
1458 : 42 : SubrangeErrors (type, set);
1459 : : }
1460 : 60 : if (errorString != NULL)
1461 : : {
1462 : 48 : M2MetaError_MetaErrorStringT0 (tokenno, errorString);
1463 : : }
1464 : 60 : }
1465 : :
1466 : :
1467 : : /*
1468 : : checkTypes - checks to see that, constant, and, type, are compatible.
1469 : : */
1470 : :
1471 : 1188 : static bool checkTypes (unsigned int constant, unsigned int type)
1472 : : {
1473 : 1188 : unsigned int consttype;
1474 : :
1475 : 1188 : if ((constant != SymbolTable_NulSym) && (SymbolTable_IsConst (constant)))
1476 : : {
1477 : 594 : consttype = SymbolTable_GetType (constant);
1478 : 594 : if (! (M2Base_IsExpressionCompatible (consttype, type)))
1479 : : {
1480 : 0 : M2MetaError_MetaError2 ((const char *) "the case statement variant tag {%1ad} must be type compatible with the constant {%2Da:is a {%2d}}", 97, type, constant);
1481 : 0 : return false;
1482 : : }
1483 : : }
1484 : : return true;
1485 : : /* static analysis guarentees a RETURN statement will be used before here. */
1486 : : __builtin_unreachable ();
1487 : : }
1488 : :
1489 : :
1490 : : /*
1491 : : inRange - returns true if, min <= i <= max.
1492 : : */
1493 : :
1494 : 594 : static bool inRange (unsigned int i, unsigned int min, unsigned int max)
1495 : : {
1496 : 594 : return M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (i), SymbolConversion_Mod2Gcc (i), SymbolConversion_Mod2Gcc (min), SymbolConversion_Mod2Gcc (max));
1497 : : /* static analysis guarentees a RETURN statement will be used before here. */
1498 : : __builtin_unreachable ();
1499 : : }
1500 : :
1501 : :
1502 : : /*
1503 : : PushCase - create a case entity and push it to an internal stack.
1504 : : rec is NulSym if this is a CASE statement.
1505 : : If rec is a record then it indicates a possible
1506 : : varients reside in the record to check.
1507 : : Both rec and va might be NulSym and then the expr
1508 : : will contain the selector expression to a case statement.
1509 : : Return the case id.
1510 : : */
1511 : :
1512 : 856 : extern "C" unsigned int M2CaseList_PushCase (unsigned int rec, unsigned int va, unsigned int expr)
1513 : : {
1514 : 856 : M2CaseList_CaseDescriptor c;
1515 : :
1516 : 856 : caseId += 1;
1517 : 856 : Storage_ALLOCATE ((void **) &c, sizeof (M2CaseList__T4));
1518 : 856 : if (c == NULL)
1519 : : {
1520 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1521 : : }
1522 : : else
1523 : : {
1524 : 856 : c->resolved = false;
1525 : 856 : c->elseClause = false;
1526 : 856 : c->elseField = SymbolTable_NulSym;
1527 : 856 : c->record = rec;
1528 : 856 : c->varient = va;
1529 : 856 : c->expression = expr;
1530 : 856 : c->maxCaseId = 0;
1531 : 856 : c->caseListArray = Indexing_InitIndex (1);
1532 : 856 : c->next = caseStack;
1533 : 856 : c->currentCase = NULL;
1534 : 856 : caseStack = c;
1535 : 856 : Indexing_PutIndice (caseArray, caseId, reinterpret_cast <void *> (c));
1536 : : }
1537 : 856 : return caseId;
1538 : : /* static analysis guarentees a RETURN statement will be used before here. */
1539 : : __builtin_unreachable ();
1540 : : }
1541 : :
1542 : :
1543 : : /*
1544 : : PopCase - pop the top element of the case entity from the internal
1545 : : stack.
1546 : : */
1547 : :
1548 : 856 : extern "C" void M2CaseList_PopCase (void)
1549 : : {
1550 : 856 : if (caseStack == NULL)
1551 : : {
1552 : 0 : M2Error_InternalError ((const char *) "case stack is empty", 19);
1553 : : }
1554 : 856 : caseStack = caseStack->next;
1555 : 856 : }
1556 : :
1557 : :
1558 : : /*
1559 : : ElseCase - indicates that this case varient does have an else clause.
1560 : : */
1561 : :
1562 : 358 : extern "C" void M2CaseList_ElseCase (unsigned int f)
1563 : : {
1564 : 358 : caseStack->elseClause = true;
1565 : 358 : caseStack->elseField = f;
1566 : 358 : }
1567 : :
1568 : :
1569 : : /*
1570 : : BeginCaseList - create a new label list.
1571 : : */
1572 : :
1573 : 3202 : extern "C" void M2CaseList_BeginCaseList (unsigned int v)
1574 : : {
1575 : 3202 : M2CaseList_CaseList l;
1576 : :
1577 : 3202 : Storage_ALLOCATE ((void **) &l, sizeof (M2CaseList__T3));
1578 : 3202 : if (l == NULL)
1579 : : {
1580 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1581 : : }
1582 : 3202 : l->maxRangeId = 0;
1583 : 3202 : l->rangeArray = Indexing_InitIndex (1);
1584 : 3202 : l->currentRange = NULL;
1585 : 3202 : l->varientField = v;
1586 : 3202 : caseStack->maxCaseId += 1;
1587 : 3202 : Indexing_PutIndice (caseStack->caseListArray, caseStack->maxCaseId, reinterpret_cast <void *> (l));
1588 : 3202 : caseStack->currentCase = l;
1589 : 3202 : }
1590 : :
1591 : :
1592 : : /*
1593 : : EndCaseList - terminate the current label list.
1594 : : */
1595 : :
1596 : 3202 : extern "C" void M2CaseList_EndCaseList (void)
1597 : : {
1598 : 3202 : caseStack->currentCase = NULL;
1599 : 3202 : }
1600 : :
1601 : :
1602 : : /*
1603 : : AddRange - add a range to the current label list.
1604 : : */
1605 : :
1606 : 3294 : extern "C" void M2CaseList_AddRange (unsigned int r1, unsigned int r2, unsigned int tok)
1607 : : {
1608 : 3294 : M2CaseList_RangePair r;
1609 : :
1610 : 3294 : Storage_ALLOCATE ((void **) &r, sizeof (M2CaseList__T1));
1611 : 3294 : if (r == NULL)
1612 : : {
1613 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1614 : : }
1615 : : else
1616 : : {
1617 : 3294 : r->low = r1;
1618 : 3294 : r->high = r2;
1619 : 3294 : r->tokenno = tok;
1620 : 3294 : caseStack->currentCase->maxRangeId += 1;
1621 : 3294 : Indexing_PutIndice (caseStack->currentCase->rangeArray, caseStack->currentCase->maxRangeId, reinterpret_cast <void *> (r));
1622 : 3294 : caseStack->currentCase->currentRange = r;
1623 : : }
1624 : 3294 : }
1625 : :
1626 : :
1627 : : /*
1628 : : CaseBoundsResolved - returns TRUE if all constants in the case list, c,
1629 : : are known to GCC.
1630 : : */
1631 : :
1632 : 1132 : extern "C" bool M2CaseList_CaseBoundsResolved (unsigned int tokenno, unsigned int c)
1633 : : {
1634 : 1132 : M2CaseList_CaseDescriptor p;
1635 : :
1636 : 1132 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
1637 : 1132 : if (p->resolved)
1638 : : {
1639 : : return true;
1640 : : }
1641 : : else
1642 : : {
1643 : 1132 : if (CheckCaseBoundsResolved (tokenno, c))
1644 : : {
1645 : 856 : ConvertNulStr2NulChar (tokenno, c);
1646 : 856 : return true;
1647 : : }
1648 : : else
1649 : : {
1650 : : return false;
1651 : : }
1652 : : }
1653 : : /* static analysis guarentees a RETURN statement will be used before here. */
1654 : : __builtin_unreachable ();
1655 : : }
1656 : :
1657 : :
1658 : : /*
1659 : : TypeCaseBounds - returns true if all bounds in case list, c, are
1660 : : compatible with the tagged type.
1661 : : */
1662 : :
1663 : 856 : extern "C" bool M2CaseList_TypeCaseBounds (unsigned int c)
1664 : : {
1665 : 856 : M2CaseList_CaseDescriptor p;
1666 : 856 : M2CaseList_CaseList q;
1667 : 856 : M2CaseList_RangePair r;
1668 : 856 : unsigned int min;
1669 : 856 : unsigned int max;
1670 : 856 : unsigned int type;
1671 : 856 : unsigned int i;
1672 : 856 : unsigned int j;
1673 : 856 : bool compatible;
1674 : :
1675 : 856 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
1676 : 856 : type = SymbolTable_NulSym;
1677 : 856 : type = SymbolTable_NulSym;
1678 : 856 : if (p->varient != SymbolTable_NulSym)
1679 : : {
1680 : : /* not a CASE statement, but a varient record containing without an ELSE clause */
1681 : 276 : type = GetVariantTagType (p->varient);
1682 : 276 : min = M2GCCDeclare_GetTypeMin (type);
1683 : 276 : max = M2GCCDeclare_GetTypeMax (type);
1684 : : }
1685 : 276 : if (type == SymbolTable_NulSym)
1686 : : {
1687 : 580 : return true;
1688 : : }
1689 : : compatible = true;
1690 : : i = 1;
1691 : 828 : while (i <= p->maxCaseId)
1692 : : {
1693 : 552 : q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
1694 : 552 : j = 1;
1695 : 1698 : while (j <= q->maxRangeId)
1696 : : {
1697 : 594 : r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
1698 : 594 : if ((r->low != SymbolTable_NulSym) && (! (inRange (r->low, min, max))))
1699 : : {
1700 : 0 : M2MetaError_MetaError2 ((const char *) "the CASE statement variant range {%1ad} exceeds that of the tag type {%2ad}", 75, r->low, type);
1701 : 0 : compatible = false;
1702 : : }
1703 : 594 : if (! (checkTypes (r->low, type)))
1704 : : {
1705 : 0 : compatible = false;
1706 : : }
1707 : 594 : if ((r->high != SymbolTable_NulSym) && (! (inRange (r->high, min, max))))
1708 : : {
1709 : 0 : M2MetaError_MetaError2 ((const char *) "the CASE statement variant range {%1ad} exceeds that of the tag type {%2ad}", 75, r->high, type);
1710 : 0 : compatible = false;
1711 : : }
1712 : 594 : if (! (checkTypes (r->high, type)))
1713 : : {
1714 : 0 : compatible = false;
1715 : : }
1716 : 594 : j += 1;
1717 : : }
1718 : 552 : i += 1;
1719 : : }
1720 : : return compatible;
1721 : : /* static analysis guarentees a RETURN statement will be used before here. */
1722 : : __builtin_unreachable ();
1723 : : }
1724 : :
1725 : :
1726 : : /*
1727 : : OverlappingCaseBounds - returns TRUE if there were any overlapping bounds
1728 : : in the case list, c. It will generate an error
1729 : : messages for each overlapping bound found.
1730 : : */
1731 : :
1732 : 856 : extern "C" bool M2CaseList_OverlappingCaseBounds (unsigned int c)
1733 : : {
1734 : 856 : M2CaseList_CaseDescriptor p;
1735 : 856 : M2CaseList_CaseList q;
1736 : 856 : M2CaseList_RangePair r;
1737 : 856 : unsigned int i;
1738 : 856 : unsigned int j;
1739 : 856 : bool overlap;
1740 : :
1741 : 856 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
1742 : 856 : overlap = false;
1743 : 856 : i = 1;
1744 : 4914 : while (i <= p->maxCaseId)
1745 : : {
1746 : 3202 : q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
1747 : 3202 : j = 1;
1748 : 9698 : while (j <= q->maxRangeId)
1749 : : {
1750 : 3294 : r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
1751 : 3294 : if (OverlappingCaseBound (r, c))
1752 : : {
1753 : 48 : overlap = true;
1754 : : }
1755 : 3294 : j += 1;
1756 : : }
1757 : 3202 : i += 1;
1758 : : }
1759 : 856 : return overlap;
1760 : : /* static analysis guarentees a RETURN statement will be used before here. */
1761 : : __builtin_unreachable ();
1762 : : }
1763 : :
1764 : :
1765 : : /*
1766 : : MissingCaseBounds - returns true if there were any missing bounds
1767 : : in the varient record case list, c. It will
1768 : : generate an error message for each missing
1769 : : bounds found.
1770 : : */
1771 : :
1772 : 362 : extern "C" bool M2CaseList_MissingCaseBounds (unsigned int tokenno, unsigned int c)
1773 : : {
1774 : 362 : M2CaseList_CaseDescriptor p;
1775 : 362 : unsigned int type;
1776 : 362 : bool missing;
1777 : 362 : M2CaseList_SetRange set;
1778 : :
1779 : 362 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
1780 : 362 : missing = false;
1781 : 362 : if (! p->elseClause)
1782 : : {
1783 : 260 : if ((p->record != SymbolTable_NulSym) && (p->varient != SymbolTable_NulSym))
1784 : : {
1785 : : /* Not a case statement, but a varient record without an else clause. */
1786 : 12 : type = GetVariantTagType (p->varient);
1787 : 12 : set = NewSet (type);
1788 : 12 : set = ExcludeCaseRanges (set, p);
1789 : 12 : if (set != NULL)
1790 : : {
1791 : 12 : missing = true;
1792 : 12 : M2MetaError_MetaErrorT2 (tokenno, (const char *) "not all variant record alternatives in the {%kCASE} clause are specified, hint you either need to specify each value of {%2ad} or use an {%kELSE} clause", 152, p->varient, type);
1793 : 12 : EmitMissingRangeErrors (tokenno, type, set);
1794 : : }
1795 : 12 : set = DisposeRanges (set);
1796 : : }
1797 : : }
1798 : 362 : return missing;
1799 : : /* static analysis guarentees a RETURN statement will be used before here. */
1800 : : __builtin_unreachable ();
1801 : : }
1802 : :
1803 : :
1804 : : /*
1805 : : MissingCaseStatementBounds - returns true if the case statement has a missing
1806 : : clause. It will also generate error messages.
1807 : : */
1808 : :
1809 : 148 : extern "C" bool M2CaseList_MissingCaseStatementBounds (unsigned int tokenno, unsigned int c)
1810 : : {
1811 : 148 : M2CaseList_CaseDescriptor p;
1812 : 148 : unsigned int type;
1813 : 148 : bool missing;
1814 : 148 : M2CaseList_SetRange set;
1815 : :
1816 : 148 : p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
1817 : 148 : missing = false;
1818 : 148 : if (! p->elseClause)
1819 : : {
1820 : 120 : type = GetCaseExpression (p);
1821 : 120 : if (type != SymbolTable_NulSym)
1822 : : {
1823 : 120 : if ((SymbolTable_IsEnumeration (type)) || (SymbolTable_IsSubrange (type)))
1824 : : {
1825 : : /* A case statement sequence without an else clause but
1826 : : selecting using an enumeration type. */
1827 : 116 : set = NewSet (type);
1828 : 116 : set = ExcludeCaseRanges (set, p);
1829 : 116 : if (set != NULL)
1830 : : {
1831 : 48 : missing = true;
1832 : 48 : M2MetaError_MetaErrorT1 (tokenno, (const char *) "not all {%1Wd} values in the {%kCASE} statements are specified, hint you either need to specify each value of {%1ad} or use an {%kELSE} clause", 142, type);
1833 : 48 : EmitMissingRangeErrors (tokenno, type, set);
1834 : : }
1835 : 116 : set = DisposeRanges (set);
1836 : : }
1837 : : }
1838 : : }
1839 : 148 : return missing;
1840 : : /* static analysis guarentees a RETURN statement will be used before here. */
1841 : : __builtin_unreachable ();
1842 : : }
1843 : :
1844 : :
1845 : : /*
1846 : : WriteCase - dump out the case list (internal debugging).
1847 : : */
1848 : :
1849 : 0 : extern "C" void M2CaseList_WriteCase (unsigned int c)
1850 : : {
1851 : : /* this debugging PROCEDURE should be finished. */
1852 : 0 : NumberIO_WriteCard (c, 0);
1853 : 0 : }
1854 : :
1855 : 14232 : extern "C" void _M2_M2CaseList_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
1856 : : {
1857 : 14232 : caseStack = NULL;
1858 : 14232 : caseId = 0;
1859 : 14232 : caseArray = Indexing_InitIndex (1);
1860 : 14232 : conflictArray = Indexing_InitIndex (1);
1861 : 14232 : FreeRangeList = NULL;
1862 : 14232 : }
1863 : :
1864 : 0 : extern "C" void _M2_M2CaseList_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
1865 : : {
1866 : 0 : }
|