1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
15 **
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** ctype.c
26 **
27 ** This files implements three types: ctentry, cttable and ctype.
28 ** They should probably be separated soon.
29 */
30
31 # include "splintMacros.nf"
32 # include "basic.h"
33 # include "structNames.h"
34
35 static void ctype_recordConj (ctype p_c);
36
37
38 /*
39 ** ctbase file
40 */
41
42 # include "ctbase.i"
43
44 /*
45 ** ctype table
46 */
47
48 # include "cttable.i"
49
50 static ctype ctype_getConjA (ctype p_c) /*@*/ ;
51 static ctype ctype_getConjB (ctype p_c) /*@*/ ;
52
ctype_isComplex(ctype c)53 static bool ctype_isComplex (ctype c)
54 {
55 return (ctentry_isComplex (ctype_getCtentry (c)));
56 }
57
ctype_isPlain(ctype c)58 static bool ctype_isPlain (ctype c)
59 {
60 return (ctentry_isPlain (ctype_getCtentry (c)));
61 }
62
ctype_isBroken(ctype c)63 static bool ctype_isBroken (ctype c)
64 {
65 /*@+enumint@*/
66 if (c == CTK_DNE || c == CTK_INVALID || c == CTK_UNKNOWN)
67 {
68 /*@-enumint@*/
69 return TRUE;
70 }
71 else
72 {
73 ctentry cte = ctype_getCtentry (c);
74
75 return (ctentry_isBogus (cte));
76 }
77 }
78
79 ctkind
ctkind_fromInt(int i)80 ctkind_fromInt (int i)
81 {
82 /*@+enumint@*/
83 if (i < CTK_UNKNOWN || i > CTK_COMPLEX)
84 {
85 llcontbug (message ("ctkind_fromInt: out of range: %d", i));
86 return CTK_INVALID;
87 }
88 return (ctkind) i;
89 /*@=enumint@*/
90 }
91
92 /*
93 ** ctype functions
94 */
95
96 void
ctype_initTable()97 ctype_initTable ()
98 {
99 cttable_init ();
100 }
101
102 void
ctype_destroyMod()103 ctype_destroyMod ()
104 {
105 cttable_reset ();
106 }
107
108 void
ctype_loadTable(FILE * f)109 ctype_loadTable (FILE *f)
110 {
111 DPRINTF (("Loading cttable!"));
112 cttable_load (f);
113 }
114
115 void
ctype_dumpTable(FILE * f)116 ctype_dumpTable (FILE *f)
117 {
118 DPRINTF (("Dumping cttable!"));
119 cttable_dump (f);
120 }
121
122 cstring
ctype_unparseTable()123 ctype_unparseTable ()
124 {
125 return (cttable_unparse ());
126 }
127
128 void
ctype_printTable()129 ctype_printTable ()
130 {
131 cttable_print ();
132 }
133
134 bool
ctype_isUserBool(ctype ct)135 ctype_isUserBool (ctype ct)
136 {
137 if (ctype_isUA (ct))
138 {
139 return (usymtab_isBoolType (ctype_typeId (ct)));
140 }
141
142 return (FALSE);
143 }
144
145 ctype
ctype_createUser(typeId u)146 ctype_createUser (typeId u)
147 {
148 /* requires: ctype_createUser (u) is never called more than once for any u. */
149
150 ctbase ct = ctbase_createUser (u);
151 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ct)));
152 }
153
154 ctype
ctype_createAbstract(typeId u)155 ctype_createAbstract (typeId u)
156 {
157 /* requires: ctype_createAbstract (u) is never called more than once for any u. */
158 /* [ tested by cttable_addFullSafe, not really required ] */
159
160 return (cttable_addFullSafe
161 (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u))));
162 }
163
164 ctype
ctype_createNumAbstract(typeId u)165 ctype_createNumAbstract (typeId u)
166 {
167 /* requires: ctype_createAbstract (u) is never called more than once for any u. */
168 /* [ tested by cttable_addFullSafe, not really required ] */
169
170 return (cttable_addFullSafe
171 (ctentry_makeNew (CTK_PLAIN, ctbase_createNumAbstract (u))));
172 }
173
174 int
ctype_count(void)175 ctype_count (void)
176 {
177 return (cttab.size);
178 }
179
180 ctype
ctype_realType(ctype c)181 ctype_realType (ctype c)
182 {
183 ctype r = c;
184
185 if (ctype_isElips (c) || ctype_isMissingParamsMarker (c))
186 {
187 return c;
188 }
189
190 if (ctype_isUA (c))
191 {
192 r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c)));
193 }
194
195 if (ctype_isManifestBool (r))
196 {
197 if (context_canAccessBool ())
198 {
199 r = context_boolImplementationType ();
200 }
201 }
202
203 return r;
204 }
205
206 bool
ctype_isSimple(ctype c)207 ctype_isSimple (ctype c)
208 {
209 return (! (ctype_isPointer (c)
210 || ctype_isArray (c)
211 || ctype_isFunction (c)));
212 }
213
214 ctype
ctype_forceRealType(ctype c)215 ctype_forceRealType (ctype c)
216 {
217 ctype r = c;
218
219 if (ctype_isUA (c))
220 {
221 r = uentry_getForceRealType (usymtab_getTypeEntry (ctype_typeId (c)));
222 }
223
224 return r;
225 }
226
227 ctype
ctype_realishType(ctype c)228 ctype_realishType (ctype c)
229 {
230 if (ctype_isUA (c))
231 {
232 if (ctype_isManifestBool (c))
233 {
234 return ctype_bool;
235 }
236 else
237 {
238 ctype r = uentry_getRealType (usymtab_getTypeEntry
239 (ctype_typeId (c)));
240 return (r);
241 }
242 }
243
244 return c;
245 }
246
247 bool
ctype_isUA(ctype c)248 ctype_isUA (ctype c)
249 {
250 return (!ctype_isUnknown (c)
251 && ctbase_isUA (ctype_getCtbase (c)));
252 }
253
254 bool
ctype_isUser(ctype c)255 ctype_isUser (ctype c)
256 {
257 return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c)));
258 }
259
260 bool
ctype_isAbstract(ctype c)261 ctype_isAbstract (ctype c)
262 {
263 return (!ctype_isUnknown (c)
264 && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
265 (ctype_isConj (c) &&
266 (ctype_isAbstract (ctype_getConjA (c))
267 || ctype_isAbstract (ctype_getConjB (c))))));
268 }
269
270 bool
ctype_isNumAbstract(ctype c)271 ctype_isNumAbstract (ctype c)
272 {
273 return (!ctype_isUnknown (c)
274 && ((ctype_isPlain (c) && ctbase_isNumAbstract (ctype_getCtbaseSafe (c))) ||
275 (ctype_isConj (c) &&
276 (ctype_isNumAbstract (ctype_getConjA (c))
277 || ctype_isNumAbstract (ctype_getConjB (c))))));
278 }
279
280 bool
ctype_isImmutableAbstract(ctype t)281 ctype_isImmutableAbstract (ctype t)
282 {
283 return (ctype_isAbstract (t) && !ctype_isMutable (t));
284 }
285
286 bool
ctype_isRealAbstract(ctype c)287 ctype_isRealAbstract (ctype c)
288 {
289 return (ctype_isAbstract (ctype_realType (c)) ||
290 (ctype_isConj (c) &&
291 (ctype_isRealAbstract (ctype_getConjA (c)) ||
292 ctype_isRealAbstract (ctype_getConjB (c)))));
293 }
294
295 bool
ctype_isRealNumAbstract(ctype c)296 ctype_isRealNumAbstract (ctype c)
297 {
298 return (ctype_isNumAbstract (ctype_realType (c)) ||
299 (ctype_isConj (c) &&
300 (ctype_isRealNumAbstract (ctype_getConjA (c)) ||
301 ctype_isRealNumAbstract (ctype_getConjB (c)))));
302 }
303
304 /*
305 ** primitive creators
306 */
307
308 /*
309 ** createPrim not necessary --- subsumed by ctype_int, etc.
310 */
311
312 /*
313 ** ctbase_unknown --- removed argument
314 */
315
316 /*
317 ** derived types:
318 ** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
319 */
320
321 ctype
ctype_makePointer(ctype c)322 ctype_makePointer (ctype c)
323 {
324 if (c == ctype_char)
325 {
326 return ctype_string;
327 }
328 else if (c == ctype_void)
329 {
330 return ctype_voidPointer;
331 }
332 else
333 {
334 ctentry cte = ctype_getCtentry (c);
335 ctype clp = ctentry_getPtr (cte);
336
337 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
338 {
339 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
340 ctentry_setPtr (cte, cnew);
341 return (cnew);
342 }
343 else
344 {
345 return clp;
346 }
347 }
348 }
349
ctype_makeFixedArray(ctype c,size_t size)350 ctype ctype_makeFixedArray (ctype c, size_t size)
351 {
352 ctype res;
353 res = cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c);
354 return res;
355 }
356
357 /*
358 ** In C, array terms appear backwards:
359 **
360 ** int a[5][7]
361 **
362 ** declares an array of 5 elements, each of which is
363 ** an array of 7 int's.
364 **
365 ** We represent this as,
366 **
367 ** array (array (int, 7), 5)
368 **
369 ** Hence, the rightmost declaration is the innermost type.
370 */
371
ctype_makeInnerFixedArray(ctype c,size_t size)372 ctype ctype_makeInnerFixedArray (ctype c, size_t size)
373 {
374 ctype res;
375
376 DPRINTF (("makeinnerfixed: %s / %d", ctype_unparse (c), size));
377
378 if (ctype_isFixedArray (c))
379 {
380 ctype cb = ctype_baseArrayPtr (c);
381 size_t osize = ctype_getArraySize (c);
382
383 res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize);
384 DPRINTF (("res 1: %s", ctype_unparse (res)));
385 }
386 else if (ctype_isArray (c))
387 {
388 ctype cb = ctype_baseArrayPtr (c);
389
390 res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
391 DPRINTF (("res 2: %s", ctype_unparse (res)));
392 }
393 else
394 {
395 res = ctype_makeFixedArray (c, size);
396 DPRINTF (("res 3: %s", ctype_unparse (res)));
397 }
398
399 DPRINTF (("Make inner fixed array: %s / base: %s",
400 ctype_unparse (res), ctype_unparse (ctype_baseArrayPtr (res))));
401 return res;
402 }
403
ctype_makeInnerArray(ctype c)404 ctype ctype_makeInnerArray (ctype c)
405 {
406 ctype res;
407
408 DPRINTF (("Make inner array: %s", ctype_unparse (c)));
409
410 if (ctype_isFixedArray (c))
411 {
412 ctype cb = ctype_baseArrayPtr (c);
413 size_t osize = ctype_getArraySize (c);
414
415 res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize);
416 }
417 else if (ctype_isArray (c))
418 {
419 ctype cb = ctype_baseArrayPtr (c);
420 res = ctype_makeArray (ctype_makeInnerArray (cb));
421 }
422 else
423 {
424 res = ctype_makeArray (c);
425 }
426
427 DPRINTF (("Make inner array: %s", ctype_unparse (res)));
428 return res;
429 }
430
431 ctype
ctype_makeArray(ctype c)432 ctype_makeArray (ctype c)
433 {
434 ctentry cte = ctype_getCtentry (c);
435 ctype clp = ctentry_getArray (cte);
436
437 DPRINTF (("Make array: %s", ctype_unparse (c)));
438
439 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
440 {
441 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
442 ctentry_setArray (cte, cnew);
443 return (cnew);
444 }
445 else
446 {
447 return clp;
448 }
449 }
450
451 /*
452 ** requires c is a pointer of array
453 */
454
455 ctype
ctype_baseArrayPtr(ctype c)456 ctype_baseArrayPtr (ctype c)
457 {
458 ctentry cte = ctype_getCtentry (ctype_realType (c));
459
460 if (ctype_isConj (c))
461 {
462 if (ctype_isAP (ctype_getConjA (c)))
463 {
464 if (ctype_isAP (ctype_getConjB (c)))
465 {
466 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
467 ctype_baseArrayPtr (ctype_getConjB (c))));
468 }
469 else
470 {
471 return (ctype_baseArrayPtr (ctype_getConjA (c)));
472 }
473 }
474 else
475 {
476 return (ctype_baseArrayPtr (ctype_getConjB (c)));
477 }
478 }
479 else if (ctype_isInt (c)) /* could be NULL */
480 {
481 return ctype_unknown;
482 }
483 else
484 {
485 ctype clp = ctentry_getBase (cte);
486
487 if (ctype_isBroken (clp))
488 {
489 llcontbug (message ("ctype_baseArrayPtr: bogus ctype getting base of: %s", ctype_unparse (c)));
490 return ctype_unknown;
491 }
492
493 return clp;
494 }
495 }
496
497 /*
498 ** wchar_t *
499 */
500
501 ctype
ctype_makeWideString()502 ctype_makeWideString ()
503 {
504 static ctype res = ctype_unknown;
505
506 if (ctype_isUnknown (res))
507 {
508 ctype wchart;
509
510 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
511 {
512 wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
513 }
514 else
515 {
516 wchart = ctype_char;
517 }
518
519 res = ctype_makePointer (wchart);
520 }
521
522 return res;
523 }
524
525 bool
ctype_isWideString(ctype c)526 ctype_isWideString (ctype c)
527 {
528 if (ctype_isPointer (c))
529 {
530 ctype ct = ctype_baseArrayPtr (c);
531
532 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
533 {
534 return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
535 }
536 else
537 {
538 return FALSE;
539 }
540 }
541 else
542 {
543 return FALSE;
544 }
545 }
546
547 ctype
ctype_getReturnType(ctype c)548 ctype_getReturnType (ctype c)
549 {
550 if (ctype_isUnknown (c))
551 {
552 return ctype_unknown;
553 }
554
555 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
556 }
557
558 /*
559 ** must be a shared pointer
560 */
561
562 /*@observer@*/ uentryList
ctype_argsFunction(ctype c)563 ctype_argsFunction (ctype c)
564 {
565 if (ctype_isUnknown (c))
566 {
567 return uentryList_undefined;
568 }
569
570 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
571 }
572
573 /*
574 ** Returns type with base type p and compound types from c.
575 **
576 ** i.e., c = char *[]; p = int
577 ** => int *[]
578 */
579
580 ctype
ctype_newBase(ctype c,ctype p)581 ctype_newBase (ctype c, ctype p)
582 {
583 return (ctbase_newBase (c, p));
584 }
585
586 bool
ctype_sameAltTypes(ctype c1,ctype c2)587 ctype_sameAltTypes (ctype c1, ctype c2)
588 {
589 ctype c1a, c2a;
590 ctype c1b, c2b;
591
592 llassert (ctype_isConj (c1) && ctype_isConj (c2));
593
594 c1a = ctype_getConjA (c1);
595 c2a = ctype_getConjA (c2);
596
597 c1b = ctype_getConjB (c1);
598 c2b = ctype_getConjB (c2);
599
600 if (ctype_compare (c1a, c2a) == 0)
601 {
602 if (ctype_compare (c1b, c2b) == 0)
603 {
604 return TRUE;
605 }
606 else
607 {
608 if (ctype_isConj (c1b) && ctype_isConj (c2b))
609 {
610 return ctype_sameAltTypes (c1b, c2b);
611 }
612 else
613 {
614 return FALSE;
615 }
616 }
617 }
618 else
619 {
620 if (ctype_compare (c1a, c2b) == 0)
621 {
622 if (ctype_compare (c1b, c2a) == 0)
623 {
624 return TRUE;
625 }
626 else
627 {
628 if (ctype_isConj (c1b) && ctype_isConj (c2a))
629 {
630 return ctype_sameAltTypes (c1b, c2a);
631 }
632 else
633 {
634 return FALSE;
635 }
636 }
637 }
638 else
639 {
640 return FALSE;
641 }
642 }
643 }
644
645 int
ctype_compare(ctype c1,ctype c2)646 ctype_compare (ctype c1, ctype c2)
647 {
648 ctentry ce1;
649 ctentry ce2;
650
651 if (ctype_isUnknown (c1))
652 {
653 if (ctype_isUnknown (c2))
654 {
655 return 0;
656 }
657 else
658 {
659 return 1;
660 }
661 }
662
663 if (ctype_isUnknown (c2))
664 {
665 return -1;
666 }
667
668 /* Can't get entries for special ctypes (elips marker) */
669
670 if (ctype_isElips (c1) || ctype_isElips (c2)
671 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
672 return int_compare (c1, c2);
673 }
674
675 ce1 = ctype_getCtentry (c1);
676 ce2 = ctype_getCtentry (c2);
677
678 if (ctentry_isComplex (ce1))
679 {
680 if (ctentry_isComplex (ce2))
681 {
682 return (ctbase_compare (ctype_getCtbase (c1),
683 ctype_getCtbase (c2), FALSE));
684 }
685 else
686 {
687 return 1;
688 }
689 }
690 else if (ctentry_isComplex (ce2))
691 {
692 return -1;
693 }
694 else
695 {
696 return (int_compare (c1, c2));
697 }
698 }
699
700 /*
701 ** complex types
702 */
703
704 /*
705 ** makeFunction: pointer to function returning base
706 */
707
708 ctype
ctype_makeParamsFunction(ctype base,uentryList p)709 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
710 {
711 uentryList_fixImpParams (p);
712 return (ctype_makeFunction (base, p));
713 }
714
715 ctype
ctype_makeNFParamsFunction(ctype base,uentryList p)716 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
717 {
718 uentryList_fixImpParams (p);
719 return (ctbase_makeNFFunction (base, p));
720 }
721
722 ctype
ctype_makeFunction(ctype base,uentryList p)723 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
724 {
725 ctype ret;
726 ret = ctbase_makeFunction (base, p);
727 return (ret);
728 }
729
ctype_expectFunction(ctype c)730 ctype ctype_expectFunction (ctype c)
731 {
732 /* handle parenthesized declarations */
733
734 if (!ctype_isAP (c))
735 {
736 c = ctype_makePointer (c);
737 }
738
739 return (cttable_addComplex (ctbase_expectFunction (c)));
740 }
741
ctype_dontExpectFunction(ctype c)742 ctype ctype_dontExpectFunction (ctype c)
743 {
744 ctbase ctb = ctype_getCtbase (c);
745
746 /* what about this?
747 if (!ctype_isAP (c))
748 {
749 c = ctype_makePointer (c);
750 }
751 */
752
753 return (ctbase_getExpectFunction (ctb));
754 }
755
756 /*
757 ** makeRealFunction: function returning base
758 */
759
ctype_makeRawFunction(ctype base,uentryList p)760 ctype ctype_makeRawFunction (ctype base, uentryList p)
761 {
762 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
763 }
764
765 /*
766 ** plain predicates
767 */
768
769 /***
770 **** this is very poorly defined
771 ****
772 **** need to unify function/function pointer meaning
773 ***/
774
775 bool
ctype_isFunction(ctype c)776 ctype_isFunction (ctype c)
777 {
778 if (ctype_isKnown (c) && ctype_isDefined (c))
779 {
780 return (ctbase_isFunction (ctype_getCtbase (c)));
781 }
782 else
783 {
784 return FALSE;
785 }
786 }
787
788 bool
ctype_isExpFcn(ctype c)789 ctype_isExpFcn (ctype c)
790 {
791 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
792 }
793
794 bool
ctype_isVoid(ctype c)795 ctype_isVoid (ctype c)
796 {
797 return (c == CTX_VOID);
798 }
799
800 bool
ctype_isArbitraryIntegral(ctype c)801 ctype_isArbitraryIntegral (ctype c)
802 {
803 ctype cr = ctype_realType (c);
804
805 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
806 || cr == ctype_signedintegral);
807 }
808
809 bool
ctype_isUnsignedIntegral(ctype c)810 ctype_isUnsignedIntegral (ctype c)
811 {
812 ctype cr = ctype_realType (c);
813
814 return (cr == ctype_unsignedintegral);
815 }
816
817 bool
ctype_isSignedIntegral(ctype c)818 ctype_isSignedIntegral (ctype c)
819 {
820 ctype cr = ctype_realType (c);
821
822 return (cr == ctype_signedintegral);
823 }
824
825 bool
ctype_isInt(ctype c)826 ctype_isInt (ctype c)
827 {
828 cprim cp = ctype_toCprim (c);
829
830 return (c == ctype_unknown || cprim_isAnyInt (cp)
831 || (cprim_isAnyChar (cp) && context_msgCharInt ())
832 || (c == ctype_bool && context_msgBoolInt ())
833 || (ctype_isEnum (c) && context_msgEnumInt ()));
834 }
835
836 bool
ctype_isRegularInt(ctype c)837 ctype_isRegularInt (ctype c)
838 {
839 cprim cp = ctype_toCprim (c);
840
841 return (c == ctype_unknown
842 || cprim_closeEnough (cprim_int, cp)
843 || (cprim_isAnyChar (cp) && context_msgCharInt ())
844 || (c == ctype_bool && context_msgBoolInt ())
845 || (ctype_isEnum (c) && context_msgEnumInt ()));
846 }
847
848 bool
ctype_isString(ctype c)849 ctype_isString (ctype c)
850 {
851 return (c == ctype_string
852 || (ctype_isPointer (c)
853 && ctype_isChar (ctype_baseArrayPtr (c))));
854 }
855
856 bool
ctype_isChar(ctype c)857 ctype_isChar (ctype c)
858 {
859 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
860 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
861 }
862
863 bool
ctype_isUnsignedChar(ctype c)864 ctype_isUnsignedChar (ctype c)
865 {
866 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
867 }
868
869 bool
ctype_isSignedChar(ctype c)870 ctype_isSignedChar (ctype c)
871 {
872 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
873 }
874
875 /*
876 ** Returns true if c matches the name -booltype <bool>
877 */
878
879 bool
ctype_isManifestBool(ctype c)880 ctype_isManifestBool (ctype c)
881 {
882 /*
883 ** Changed the meaning of ctype_isBool - evs 2000-07-24
884 ** The old meaning was very convoluted!
885 **
886 ** c is a bool if:
887 ** c == CTX_BOOL - its a direct bool
888 ** c is a user/abstract type matching the bool name
889 ** (should never occur?)
890 */
891
892 if (ctype_isDirectBool (c)) {
893 return TRUE;
894 } else if (ctype_isUA (c)) {
895 return ctype_isUserBool (c);
896 } else {
897 return FALSE;
898 }
899 }
900
901 bool
ctype_isBool(ctype c)902 ctype_isBool (ctype c)
903 {
904 /*
905 ** Changed the meaning of ctype_isBool - evs 2000-07-24
906 ** The old meaning was very convoluted!
907 **
908 ** c is a bool if:
909 ** its a manifest bool
910 ** +boolint and ctype_isInt (c)
911 */
912
913 if (ctype_isManifestBool (c)) {
914 return TRUE;
915 } else if (context_msgBoolInt ()) {
916 return ctype_isInt (c);
917 } else {
918 return FALSE;
919 }
920
921 # if 0
922 if (context_getFlag (FLG_ABSTRACTBOOL))
923 {
924 if (typeId_isInvalid (boolType))
925 {
926 boolType = usymtab_getTypeId (context_getBoolName ());
927 }
928
929 if (context_hasAccess (boolType))
930 {
931 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
932 || (context_msgBoolInt ()
933 && (c == CTX_INT
934 || (c == CTX_CHAR && context_msgCharInt ()))))
935 || ctype_isInt (c));
936 }
937 }
938
939 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
940 || (context_msgBoolInt ()
941 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
942 # endif
943 }
944
945 bool
ctype_isDirectBool(ctype c)946 ctype_isDirectBool (ctype c)
947 {
948 return (c == CTX_BOOL);
949 }
950
951 bool
ctype_isReal(ctype c)952 ctype_isReal (ctype c)
953 {
954 return (cprim_isAnyReal (ctype_toCprim (c)));
955 }
956
957 bool
ctype_isFloat(ctype c)958 ctype_isFloat (ctype c)
959 {
960 return (c == ctype_float);
961 }
962
963 bool
ctype_isDouble(ctype c)964 ctype_isDouble (ctype c)
965 {
966 return (c == ctype_double || c == ctype_ldouble);
967 }
968
969 bool
ctype_isSigned(ctype c)970 ctype_isSigned (ctype c)
971 {
972 return (!ctype_isUnsigned (c));
973 }
974
975 bool
ctype_isNumeric(ctype c)976 ctype_isNumeric (ctype c)
977 {
978 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
979 /* evans 2001-10-05: added this: */
980 || ctype_isArbitraryIntegral (c));
981 }
982
983
984 /*
985 ** real predicates
986 **
987 ** work on actual type in current context
988 */
989
990 bool
ctype_isRealNumeric(ctype c)991 ctype_isRealNumeric (ctype c)
992 {
993 if (ctype_isPlain (c))
994 return (ctype_isNumeric (ctype_realType (c)));
995 if (ctype_isConj (c))
996 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
997 ctype_isRealNumeric (ctype_getConjB (c)));
998 else
999 return FALSE;
1000 }
1001
1002 bool
ctype_isRealInt(ctype c)1003 ctype_isRealInt (ctype c)
1004 {
1005 if (ctype_isPlain (c))
1006 return (ctype_isInt (ctype_realType (c)));
1007 else if (ctype_isConj (c))
1008 return (ctype_isRealInt (ctype_getConjA (c)) ||
1009 ctype_isRealInt (ctype_getConjB (c)));
1010 else
1011 {
1012 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
1013 return FALSE;
1014 }
1015 }
1016
1017 bool
ctype_isRealVoid(ctype c)1018 ctype_isRealVoid (ctype c)
1019 {
1020 if (ctype_isPlain (c))
1021 {
1022 return (ctype_isVoid (ctype_realType (c)));
1023 }
1024 else if (ctype_isConj (c))
1025 {
1026 return (ctype_isRealVoid (ctype_getConjA (c)) ||
1027 ctype_isRealVoid (ctype_getConjB (c)));
1028 }
1029 else
1030 {
1031 return FALSE;
1032 }
1033 }
1034
1035 bool
ctype_isRealBool(ctype c)1036 ctype_isRealBool (ctype c)
1037 {
1038 if (ctype_isPlain (c))
1039 {
1040 return (ctype_isBool (ctype_realishType (c)));
1041 }
1042 else if (ctype_isConj (c))
1043 {
1044 return (ctype_isRealBool (ctype_getConjA (c)) ||
1045 ctype_isRealBool (ctype_getConjB (c)));
1046 }
1047 else
1048 {
1049 return FALSE;
1050 }
1051 }
1052
1053 bool
ctype_isRealPointer(ctype c)1054 ctype_isRealPointer (ctype c)
1055 {
1056 if (ctype_isConj (c))
1057 return (ctype_isRealPointer (ctype_getConjA (c)) ||
1058 ctype_isRealPointer (ctype_getConjB (c)));
1059 return (ctype_isPointer (ctype_realType (c)));
1060 }
1061
1062 bool
ctype_isRealSU(ctype c)1063 ctype_isRealSU (ctype c)
1064 {
1065 if (ctype_isConj (c))
1066 {
1067 return (ctype_isRealSU (ctype_getConjA (c)) ||
1068 ctype_isRealSU (ctype_getConjB (c)));
1069 }
1070
1071 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
1072 return (ctype_isStructorUnion (ctype_realType (c)));
1073 }
1074
1075 bool
ctype_isRealArray(ctype c)1076 ctype_isRealArray (ctype c)
1077 {
1078 if (ctype_isConj (c))
1079 return (ctype_isRealArray (ctype_getConjA (c)) ||
1080 ctype_isRealArray (ctype_getConjB (c)));
1081 return (ctype_isArray (ctype_realType (c)));
1082 }
1083
1084 bool
ctype_isRealAP(ctype c)1085 ctype_isRealAP (ctype c)
1086 {
1087 if (ctype_isConj (c))
1088 return (ctype_isRealAP (ctype_getConjA (c)) ||
1089 ctype_isRealAP (ctype_getConjB (c)));
1090 return (ctype_isAP (ctype_realType (c)));
1091 }
1092
1093 bool
ctype_isRealFunction(ctype c)1094 ctype_isRealFunction (ctype c)
1095 {
1096 if (ctype_isConj (c))
1097 return (ctype_isRealFunction (ctype_getConjA (c)) ||
1098 ctype_isRealFunction (ctype_getConjB (c)));
1099 return (ctype_isFunction (ctype_realType (c)));
1100 }
1101
1102 bool
ctype_isDirectInt(ctype c)1103 ctype_isDirectInt (ctype c)
1104 {
1105 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
1106 }
1107
1108 /*
1109 ** forceful predicates
1110 **
1111 ** take *ctype; if its a conjunct, and there is a match replace with match only.
1112 ** if both match, still conjunct
1113 */
1114
1115 static bool
ctype_isForcePred(ctype * c,bool (pred)(ctype))1116 ctype_isForcePred (ctype * c, bool (pred) (ctype))
1117 {
1118 /*drl bee: pbr */ if (ctype_isConj (*c))
1119 {
1120 ctype cbr = ctype_getConjA (*c);
1121
1122 if ((*pred) (cbr))
1123 {
1124 if ((*pred) (ctype_getConjB (*c)))
1125 {
1126 ;
1127 }
1128 else
1129 {
1130 *c = cbr;
1131 }
1132
1133 return TRUE;
1134 }
1135 else
1136 {
1137 if ((*pred) (cbr = ctype_getConjB (*c)))
1138 {
1139 *c = cbr;
1140 return TRUE;
1141 }
1142 }
1143 }
1144
1145 return ((*pred) (*c));
1146 }
1147
1148 bool
ctype_isForceRealNumeric(ctype * c)1149 ctype_isForceRealNumeric (ctype * c)
1150 {
1151 return (ctype_isForcePred (c, ctype_isRealNumeric));
1152 }
1153
1154 bool
ctype_isForceRealInt(ctype * c)1155 ctype_isForceRealInt (ctype * c)
1156 {
1157 return (ctype_isForcePred (c, ctype_isRealInt));
1158 }
1159
1160 bool
ctype_isForceRealBool(ctype * c)1161 ctype_isForceRealBool (ctype * c)
1162 {
1163 return (ctype_isForcePred (c, ctype_isRealBool));
1164 }
1165
1166 /*
1167 ** conjuncts
1168 **
1169 ** save int/char, int/bool, other random conjuncts
1170 */
1171
1172 static ctype
ctype_makeConjAux(ctype c1,ctype c2,bool isExplicit)1173 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
1174 {
1175 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
1176 {
1177 return c2;
1178 }
1179 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1180 {
1181 return c1;
1182 }
1183 else
1184 {
1185 if (isExplicit)
1186 {
1187 return (ctype_makeExplicitConj (c1, c2));
1188 }
1189 else
1190 {
1191 return (ctype_makeConj (c1, c2));
1192 }
1193 }
1194 }
1195
1196 ctype
ctype_makeExplicitConj(ctype c1,ctype c2)1197 ctype_makeExplicitConj (ctype c1, ctype c2)
1198 {
1199 if (ctype_isAnytype (c1) || ctype_isAnytype (c2))
1200 {
1201 return ctype_makeAnytype ();
1202 }
1203 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1204 {
1205 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
1206
1207 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1208 }
1209 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1210 {
1211 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
1212
1213 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1214 }
1215 else
1216 {
1217 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1218 }
1219 }
1220
1221 static ctype ic = ctype_unknown; /* int | char */
1222 static ctype ib = ctype_unknown; /* int | bool */
1223 static ctype ifl = ctype_unknown; /* int | float */
1224 static ctype ibf = ctype_unknown; /* int | bool | float */
1225 static ctype ibc = ctype_unknown; /* int | bool | char */
1226 static ctype iv = ctype_unknown; /* int | void * */
1227 static ctype ivf = ctype_unknown; /* int | void * | float */
1228 static ctype ivb = ctype_unknown; /* int | void * | bool */
1229 static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1230 static ctype cuc = ctype_unknown; /* char | unsigned char */
1231
1232 static ctype cany = ctype_unknown;
1233
1234 ctype
ctype_makeAnytype()1235 ctype_makeAnytype ()
1236 {
1237 if (cany == ctype_unknown)
1238 {
1239 cany = ctype_makeConj (ctype_unknown, ctype_dne);
1240 llassert (ctype_isAnytype (cany));
1241 }
1242
1243 DPRINTF (("make anytype: %s", ctype_unparse (cany)));
1244 return cany;
1245 }
1246
1247 bool
ctype_isAnytype(ctype c)1248 ctype_isAnytype (ctype c)
1249 {
1250 return (c == cany);
1251 }
1252
1253 static void
ctype_recordConj(ctype c)1254 ctype_recordConj (ctype c)
1255 {
1256 ctype c1, c2;
1257
1258 llassert (ctype_isConj (c));
1259
1260 c1 = ctype_getConjA (c);
1261 c2 = ctype_getConjB (c);
1262
1263 /* No, can't swap!
1264 if (c2 == ctype_int && c1 != ctype_int)
1265 {
1266 ctype tmp;
1267
1268 tmp = c1;
1269 c1 = c2;
1270 c2 = tmp;
1271 }
1272 */
1273
1274 if (c1 == ctype_int)
1275 {
1276 if (c2 == ctype_char)
1277 {
1278 llassert (ic == ctype_unknown);
1279 ic = c;
1280 }
1281 else if (c2 == ctype_bool)
1282 {
1283 llassert (ib == ctype_unknown);
1284 ib = c;
1285 }
1286 else if (c2 == ctype_float)
1287 {
1288 llassert (ifl == ctype_unknown);
1289 ifl = c;
1290 }
1291 else if (c2 == CTP_VOID)
1292 {
1293 llassert (iv == ctype_unknown);
1294 iv = c;
1295 }
1296 else
1297 {
1298 /* not special */
1299 }
1300 }
1301 else if (c1 == ib && ib != ctype_unknown)
1302 {
1303 if (c2 == ctype_float)
1304 {
1305 llassert (ibf == ctype_unknown);
1306 ibf = c;
1307 }
1308 else if (c2 == ctype_char)
1309 {
1310 llassert (ibc == ctype_unknown);
1311 ibc = c;
1312 }
1313 else
1314 {
1315 /* not special */
1316 }
1317 }
1318 else if (c1 == iv)
1319 {
1320 if (c2 == ctype_bool)
1321 {
1322 llassert (ivb == ctype_unknown);
1323 ivb = c;
1324 }
1325 else if (c2 == ctype_float)
1326 {
1327 llassert (ivf == ctype_unknown);
1328 ivf = c;
1329 }
1330 else
1331 {
1332 /* not special */
1333 }
1334 }
1335 else if (c1 == ivf)
1336 {
1337 if (c2 == ctype_bool)
1338 {
1339 llassert (ivbf == ctype_unknown);
1340 ivbf = c;
1341 }
1342 }
1343 else if (c1 == ivb)
1344 {
1345 if (c2 == ctype_float)
1346 {
1347 llassert (ivbf == ctype_unknown);
1348 ivbf = c;
1349 }
1350 }
1351 else if (c1 == ctype_char)
1352 {
1353 if (c2 == ctype_uchar)
1354 {
1355 llassert (cuc == ctype_unknown);
1356
1357 cuc = c;
1358 }
1359 }
1360 else
1361 {
1362 /* not special */
1363 }
1364 }
1365
1366 ctype
ctype_makeConj(ctype c1,ctype c2)1367 ctype_makeConj (ctype c1, ctype c2)
1368 {
1369 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1370
1371 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1372
1373 if (ctype_isAnytype (c1))
1374 {
1375 return c1;
1376 }
1377 else if (ctype_isAnytype (c2))
1378 {
1379 return c2;
1380 }
1381 else if (ctype_isUnknown (c1))
1382 {
1383 return c2;
1384 }
1385 else if (ctype_isUnknown (c2))
1386 {
1387 return c1;
1388 }
1389 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1390 {
1391 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
1392 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1393 }
1394 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1395 {
1396 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
1397 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1398 }
1399 else
1400 {
1401 if (ctype_isManifestBool (c1))
1402 {
1403 c1 = ctype_bool;
1404 }
1405
1406 if (ctype_isManifestBool (c2))
1407 {
1408 c2 = ctype_bool;
1409 }
1410
1411 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1412 {
1413 c1 = ctype_voidPointer;
1414 }
1415
1416 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1417 {
1418 c2 = ctype_voidPointer;
1419 }
1420
1421 /*
1422 ** Ouch, can't do this. unsigned, etc. modifiers might
1423 ** apply to wrong type!
1424 **
1425 ** if (c2 == ctype_int && c1 != ctype_int)
1426 ** {
1427 ** ctype tmp;
1428 **
1429 ** tmp = c1;
1430 ** c1 = c2;
1431 ** c2 = tmp;
1432 ** }
1433 **
1434 */
1435
1436 if (c1 == ctype_int)
1437 {
1438 if (c2 == ctype_char)
1439 {
1440 if (ic == ctype_unknown)
1441 {
1442 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1443 }
1444
1445 return ic;
1446 }
1447 else if (c2 == ctype_bool)
1448 {
1449 if (ib == ctype_unknown)
1450 {
1451 ib = cttable_addComplex
1452 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1453 }
1454
1455 return ib;
1456 }
1457 else if (c2 == ctype_float)
1458 {
1459 if (ifl == ctype_unknown)
1460 {
1461 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1462 }
1463
1464 return ifl;
1465 }
1466 else
1467 {
1468 if (c2 == ctype_voidPointer)
1469 {
1470 if (iv == ctype_unknown)
1471 {
1472 iv = cttable_addComplex
1473 (ctbase_makeConj (ctype_int,
1474 ctype_voidPointer,
1475 FALSE));
1476 }
1477
1478 return iv;
1479 }
1480 }
1481 }
1482 else if (c1 == ib && ib != ctype_unknown)
1483 {
1484 if (c2 == ctype_float)
1485 {
1486 if (ibf == ctype_unknown)
1487 {
1488 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1489 }
1490
1491 return ibf;
1492 }
1493 else if (c2 == ctype_char)
1494 {
1495 if (ibc == ctype_unknown)
1496 {
1497 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1498 }
1499
1500 return ibc;
1501 }
1502 else
1503 {
1504 ;
1505 }
1506 }
1507 else if (c1 == iv)
1508 {
1509 if (c2 == ctype_bool)
1510 {
1511 if (ivb == ctype_unknown)
1512 {
1513 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1514 }
1515
1516 return ivb;
1517 }
1518 else if (c2 == ctype_float)
1519 {
1520 if (ivf == ctype_unknown)
1521 {
1522 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1523 }
1524
1525 return ivf;
1526 }
1527 else
1528 {
1529 ;
1530 }
1531 }
1532 else if (c1 == ivf)
1533 {
1534 if (c2 == ctype_bool)
1535 {
1536 if (ivbf == ctype_unknown)
1537 {
1538 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1539 }
1540
1541 return ivbf;
1542 }
1543 }
1544 else if (c1 == ivb)
1545 {
1546 if (c2 == ctype_float)
1547 {
1548 if (ivbf == ctype_unknown)
1549 {
1550 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1551 }
1552
1553 return ivbf;
1554 }
1555 }
1556 else if (c1 == ctype_char)
1557 {
1558 if (c2 == ctype_uchar)
1559 {
1560 if (cuc == ctype_unknown)
1561 {
1562 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1563 }
1564
1565 return cuc;
1566 }
1567 }
1568 else
1569 {
1570 ;
1571 }
1572
1573 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1574 }
1575 }
1576
1577
1578 bool
ctype_isConj(ctype c)1579 ctype_isConj (ctype c)
1580 {
1581 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1582 }
1583
1584 static ctype
ctype_getConjA(ctype c)1585 ctype_getConjA (ctype c)
1586 {
1587 if (!ctype_isConj (c))
1588 llbuglit ("ctype_getConjA: not a conj");
1589 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1590 }
1591
1592 static ctype
ctype_getConjB(ctype c)1593 ctype_getConjB (ctype c)
1594 {
1595 if (!ctype_isConj (c))
1596 llbuglit ("ctype_getConjB: not a conj");
1597 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1598 }
1599
1600 static bool
ctype_isExplicitConj(ctype c)1601 ctype_isExplicitConj (ctype c)
1602 {
1603 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1604 }
1605
1606 /** << need to fix resolveConj >> **/
1607
1608 /*
1609 ** structs and unions
1610 */
1611
1612 ctype
ctype_createStruct(cstring n,uentryList f)1613 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1614 {
1615 ctype ct;
1616
1617 DPRINTF (("Creating a struct: %s / %s",
1618 n, uentryList_unparse (f)));
1619
1620 ct = cttable_addComplex (ctbase_createStruct (n, f));
1621 DPRINTF (("ct: %s", ctype_unparse (ct)));
1622 return (ct);
1623 }
1624
1625 uentryList
ctype_getFields(ctype c)1626 ctype_getFields (ctype c)
1627 {
1628 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1629 }
1630
1631 ctype
ctype_createUnion(cstring n,uentryList f)1632 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1633 {
1634 ctype ret;
1635
1636 ret = cttable_addComplex (ctbase_createUnion (n, f));
1637 return ret;
1638 }
1639
1640 /*
1641 ** matching
1642 **
1643 ** if ctype's are same, definite match.
1644 ** else, need to call ctbase_match.
1645 **
1646 ** if necessary context can memoize matches
1647 */
1648
1649 static bool
quickMatch(ctype c1,ctype c2)1650 quickMatch (ctype c1, ctype c2)
1651 {
1652 if (c1 == c2)
1653 return TRUE;
1654
1655 return FALSE;
1656 }
1657
1658 bool
ctype_genMatch(ctype c1,ctype c2,bool force,bool arg,bool def,bool deep)1659 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1660 {
1661 bool match;
1662
1663 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1664
1665 if (quickMatch (c1, c2))
1666 {
1667 return TRUE;
1668 }
1669
1670 if (ctype_isElips (c1) || ctype_isElips (c2))
1671 {
1672 return FALSE;
1673 }
1674 else
1675 {
1676 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1677 return (match);
1678 }
1679 }
1680
1681 bool
ctype_sameName(ctype c1,ctype c2)1682 ctype_sameName (ctype c1, ctype c2)
1683 {
1684 if (quickMatch (c1, c2))
1685 return TRUE;
1686 else
1687 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1688 }
1689
1690 bool
ctype_almostEqual(ctype c1,ctype c2)1691 ctype_almostEqual (ctype c1, ctype c2)
1692 {
1693 if (ctype_equal (c1, c2))
1694 {
1695 return TRUE;
1696 }
1697 else
1698 {
1699 if (ctype_isUnknown (c1))
1700 {
1701 return ctype_isUnknown (c2);
1702 }
1703 else if (ctype_isUnknown (c2))
1704 {
1705 return FALSE;
1706 }
1707 else
1708 {
1709 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1710 }
1711 }
1712 }
1713
1714 bool
ctype_matchDef(ctype c1,ctype c2)1715 ctype_matchDef (ctype c1, ctype c2)
1716 {
1717 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1718
1719 if (quickMatch (c1, c2))
1720 return TRUE;
1721
1722 if (ctype_isElips (c1))
1723 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1724
1725 if (ctype_isElips (c2))
1726 {
1727 return (ctype_isUnknown (c2));
1728 }
1729 else
1730 {
1731 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1732 bool res;
1733
1734 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1735 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1736 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1737 return res;
1738 }
1739 }
1740
ctype_match(ctype c1,ctype c2)1741 bool ctype_match (ctype c1, ctype c2)
1742 {
1743 if (quickMatch (c1, c2))
1744 return TRUE;
1745
1746 if (ctype_isElips (c1))
1747 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1748
1749 if (ctype_isElips (c2))
1750 return (ctype_isUnknown (c2));
1751
1752 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1753 }
1754
1755 bool
ctype_forceMatch(ctype c1,ctype c2)1756 ctype_forceMatch (ctype c1, ctype c2)
1757 {
1758 if (quickMatch (c1, c2))
1759 return TRUE;
1760
1761 if (ctype_isElips (c1))
1762 return (ctype_isElips (c2));
1763
1764 if (ctype_isElips (c2))
1765 return FALSE;
1766
1767 /*@-modobserver@*/
1768 /* The call forceMatch may modify the observer params, but, we don't care. */
1769 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1770 /*@=modobserver@*/
1771 }
1772
1773 bool
ctype_matchArg(ctype c1,ctype c2)1774 ctype_matchArg (ctype c1, ctype c2)
1775 {
1776 if (quickMatch (c1, c2))
1777 {
1778 return TRUE;
1779 }
1780 else
1781 {
1782 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1783 }
1784 }
1785
1786 /*
1787 ** simple ctype_is operations.
1788 ** DO NOT use real type of c, only direct type.
1789 */
1790
1791 /*
1792 ** ctype_isVoidPointer
1793 **
1794 ** void *
1795 */
1796
1797 bool
ctype_isVoidPointer(ctype c)1798 ctype_isVoidPointer (ctype c)
1799 {
1800 if (ctype_isComplex (c))
1801 {
1802 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1803 }
1804 if (ctype_isConj (c))
1805 {
1806 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1807 ctype_isVoidPointer (ctype_getConjB (c)));
1808 }
1809 else
1810 {
1811 return (c == ctype_voidPointer
1812 || (ctype_isRealPointer (c)
1813 && ctype_isVoid (ctype_baseArrayPtr (c))));
1814 }
1815 }
1816
1817 /*
1818 ** ctype_isPointer
1819 **
1820 ** true for C and LCL pointers
1821 */
1822
1823 bool
ctype_isPointer(ctype c)1824 ctype_isPointer (ctype c)
1825 {
1826 if (ctype_isElips (c)) return FALSE;
1827
1828 if (ctype_isComplex (c))
1829 {
1830 ctbase ctb = ctype_getCtbaseSafe (c);
1831 bool res = ctbase_isPointer (ctb);
1832
1833 return res;
1834 }
1835 else
1836 {
1837 bool res = ctentry_isPointer (ctype_getCtentry (c));
1838
1839 return res;
1840 }
1841 }
1842
1843 /*
1844 ** ctype_isArray
1845 **
1846 ** true for C and LCL array's
1847 */
1848
1849 bool
ctype_isArray(ctype c)1850 ctype_isArray (ctype c)
1851 {
1852 if (ctype_isElips (c)) return FALSE;
1853
1854 if (ctype_isComplex (c))
1855 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1856 else
1857 return (ctentry_isArray (ctype_getCtentry (c)));
1858 }
1859
ctype_isIncompleteArray(ctype c)1860 bool ctype_isIncompleteArray (ctype c)
1861 {
1862 if (ctype_isArray (c))
1863 {
1864 if (ctype_isFixedArray (c))
1865 {
1866 return ctype_isIncompleteArray (ctype_baseArrayPtr (c));
1867 }
1868 else
1869 {
1870 return TRUE;
1871 }
1872 }
1873
1874 return FALSE;
1875 }
1876
1877 bool
ctype_isArrayPtr(ctype c)1878 ctype_isArrayPtr (ctype c)
1879 {
1880 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1881 }
1882
1883 typeId
ctype_typeId(ctype c)1884 ctype_typeId (ctype c)
1885 {
1886 return (ctbase_typeId (ctype_getCtbase (c)));
1887 }
1888
1889 cstring
ctype_unparseDeclaration(ctype c,cstring name)1890 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1891 {
1892 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1893
1894 if (ctype_isUnknown (c))
1895 {
1896 return message ("? %q", name);
1897 }
1898 else
1899 {
1900 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1901 }
1902 }
1903
1904 cstring
ctype_unparse(ctype c)1905 ctype_unparse (ctype c)
1906 {
1907 if (ctype_isElips (c))
1908 {
1909 return cstring_makeLiteralTemp ("...");
1910 }
1911 else if (ctype_isMissingParamsMarker (c))
1912 {
1913 return cstring_makeLiteralTemp ("-");
1914 }
1915 else if (ctype_isAnytype (c))
1916 {
1917 return cstring_makeLiteralTemp ("<any>");
1918 }
1919 else if (ctype_isUnknown (c))
1920 {
1921 return cstring_makeLiteralTemp ("?");
1922 }
1923 else
1924 {
1925 /*@-modobserver@*/
1926 return (ctentry_doUnparse (ctype_getCtentry (c)));
1927 /*@=modobserver@*/
1928 }
1929 }
1930
1931 cstring
ctype_unparseSafe(ctype c)1932 ctype_unparseSafe (ctype c)
1933 {
1934 if (ctype_isElips (c))
1935 {
1936 return cstring_makeLiteralTemp ("...");
1937 }
1938 else if (ctype_isMissingParamsMarker (c))
1939 {
1940 return cstring_makeLiteralTemp ("-");
1941 }
1942 else
1943 {
1944 cstring ret;
1945
1946 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1947 {
1948 ctentry cte = ctype_getCtentry (c);
1949
1950 if (cstring_isDefined (cte->unparse))
1951 {
1952 return (cte->unparse);
1953 }
1954 }
1955
1956 ret = message ("[%d]", (int) c);
1957 cstring_markOwned (ret);
1958 return ret;
1959 }
1960 }
1961
1962 cstring
ctype_unparseDeep(ctype c)1963 ctype_unparseDeep (ctype c)
1964 {
1965 if (ctype_isElips (c))
1966 {
1967 return cstring_makeLiteralTemp ("...");
1968 }
1969 if (ctype_isMissingParamsMarker (c))
1970 {
1971 return cstring_makeLiteralTemp ("-");
1972 }
1973
1974 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1975 }
1976
1977 ctype
ctype_undump(char ** c)1978 ctype_undump (char **c)
1979 {
1980 return ((ctype) reader_getInt (c)); /* check its valid? */
1981 }
1982
1983 cstring
ctype_dump(ctype c)1984 ctype_dump (ctype c)
1985 {
1986 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1987
1988 if (c < 0)
1989 {
1990 /* Handle invalid types in a kludgey way. */
1991 return (message ("0"));
1992 }
1993
1994 if (ctype_isUA (c))
1995 {
1996 cstring tname = usymtab_getTypeEntryName (usymtab_convertTypeId (ctype_typeId (c)));
1997
1998 if (cstring_equal (tname, context_getBoolName ()))
1999 {
2000 cstring_free (tname);
2001 return (message ("%d", ctype_bool));
2002 }
2003
2004 cstring_free (tname);
2005 }
2006
2007 DPRINTF (("Returning: %d", c));
2008 return (message ("%d", c));
2009 }
2010
2011 ctype
ctype_getBaseType(ctype c)2012 ctype_getBaseType (ctype c)
2013 {
2014 ctentry cte = ctype_getCtentry (c);
2015
2016 switch (ctentry_getKind (cte))
2017 {
2018 case CTK_UNKNOWN:
2019 case CTK_INVALID:
2020 case CTK_PLAIN:
2021 return c;
2022 case CTK_PTR:
2023 case CTK_ARRAY:
2024 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
2025 case CTK_COMPLEX:
2026 {
2027 ctbase ctb = cte->ctbase;
2028
2029 if (ctbase_isDefined (ctb))
2030 {
2031 /*@access ctbase@*/
2032 switch (ctb->type)
2033 {
2034 case CT_UNKNOWN:
2035 case CT_PRIM:
2036 case CT_USER:
2037 case CT_ENUM:
2038 case CT_ENUMLIST:
2039 case CT_BOOL:
2040 case CT_ABST:
2041 case CT_NUMABST:
2042 case CT_FCN:
2043 case CT_STRUCT:
2044 case CT_UNION:
2045 case CT_EXPFCN:
2046 return c;
2047 case CT_PTR:
2048 case CT_ARRAY:
2049 return (ctype_getBaseType (ctb->contents.base));
2050 case CT_FIXEDARRAY:
2051 return (ctype_getBaseType (ctb->contents.farray->base));
2052 case CT_CONJ: /* base type of A conj branch? */
2053 return (ctype_getBaseType (ctb->contents.conj->a));
2054 }
2055 /*@noaccess ctbase@*/
2056 }
2057 else
2058 {
2059 return c;
2060 }
2061 }
2062 default:
2063 llbuglit ("ctype_newBase: bad case");
2064 }
2065 llcontbuglit ("ctype_getBaseType: unreachable code");
2066 return ((ctype)NULL);
2067 }
2068
2069 ctype
ctype_adjustPointers(pointers p,ctype c)2070 ctype_adjustPointers (pointers p, ctype c)
2071 {
2072 int np = pointers_depth (p);
2073
2074 if (ctype_isFunction (c))
2075 {
2076 c = ctype_makeParamsFunction
2077 (ctype_adjustPointers (p, ctype_getReturnType (c)),
2078 uentryList_copy (ctype_argsFunction (c)));
2079 }
2080 else
2081 {
2082 /* fix this should not use getBaseType ??? */
2083 ctype cb = ctype_getBaseType (c);
2084
2085 while (np > 0)
2086 {
2087 cb = ctype_makePointer (cb);
2088 np--;
2089 }
2090 c = ctype_newBase (c, cb);
2091 }
2092
2093 return (c);
2094 }
2095
2096
2097 enumNameList
ctype_elist(ctype c)2098 ctype_elist (ctype c)
2099 {
2100 return (ctbase_elist (ctype_getCtbase (c)));
2101 }
2102
2103 bool
ctype_isFirstVoid(ctype c)2104 ctype_isFirstVoid (ctype c)
2105 {
2106 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2107 }
2108
2109 ctype
ctype_createEnum(cstring tag,enumNameList el)2110 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2111 {
2112 return (cttable_addComplex (ctbase_createEnum (tag, el)));
2113 }
2114
2115 bool
ctype_isEnum(ctype c)2116 ctype_isEnum (ctype c)
2117 {
2118 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2119 }
2120
2121 cstring
ctype_enumTag(ctype c)2122 ctype_enumTag (ctype c)
2123 {
2124 llassert (ctype_isEnum (c));
2125
2126 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2127 }
2128
2129 bool
ctype_isStruct(ctype c)2130 ctype_isStruct (ctype c)
2131 {
2132 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2133 }
2134
2135 bool
ctype_isUnion(ctype c)2136 ctype_isUnion (ctype c)
2137 {
2138 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2139 }
2140
2141 ctype
ctype_resolveNumerics(ctype c1,ctype c2)2142 ctype_resolveNumerics (ctype c1, ctype c2)
2143 {
2144 /*
2145 ** returns longest type of c1 and c2
2146 */
2147
2148 if (c1 == c2) return c1;
2149
2150 c1 = ctype_realType (c1);
2151 c2 = ctype_realType (c2);
2152
2153 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2154 if (ctype_isEnum (c2)) c2 = ctype_int;
2155
2156 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2157
2158 /* 2001-06-08: This fix provided by Jim Zelenka. */
2159 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2160 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2161
2162 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2163 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2164 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2165 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2166
2167 /* 2001-06-08: This fix provided by Jim Zelenka. */
2168 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2169
2170 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2171
2172 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2173 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2174
2175 if (ctype_isKnown (c1)) return c1;
2176 else return c2;
2177 }
2178
2179 bool
ctype_isStructorUnion(ctype c)2180 ctype_isStructorUnion (ctype c)
2181 {
2182 return (ctype_isStruct (c) || ctype_isUnion (c));
2183 }
2184
2185 ctype
ctype_fixArrayPtr(ctype c)2186 ctype_fixArrayPtr (ctype c)
2187 {
2188 if (ctype_isArray (c))
2189 {
2190 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2191 }
2192 else
2193 return c;
2194 }
2195
2196 /*
2197 ** createUnnamedStruct/Union
2198 **
2199 ** check if it corresponds to an existing LCL-specified unnamed struct
2200 ** otherwise, give it a new tag
2201 */
2202
2203 ctype
ctype_createUnnamedStruct(uentryList f)2204 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2205 {
2206 ctype ret = usymtab_structFieldsType (f);
2207
2208 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2209
2210 if (ctype_isDefined (ret))
2211 {
2212 uentryList_free (f);
2213 return ret;
2214 }
2215 else
2216 {
2217 cstring ft = fakeTag ();
2218 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2219 uentry ue = uentry_makeStructTagLoc (ft, ct);
2220
2221 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2222 ue = usymtab_supGlobalEntryReturn (ue);
2223 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2224
2225 cstring_free (ft);
2226 return (ct);
2227 }
2228 }
2229
2230 ctype
ctype_createUnnamedUnion(uentryList f)2231 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2232 {
2233 ctype ret = usymtab_unionFieldsType (f);
2234
2235 if (ctype_isDefined (ret))
2236 {
2237 uentryList_free (f);
2238 return ret;
2239 }
2240 else
2241 {
2242 cstring ft = fakeTag ();
2243 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2244 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2245
2246 usymtab_supGlobalEntry (ue);
2247 cstring_free (ft);
2248 return (ct);
2249 }
2250 }
2251
2252 bool
ctype_isUnnamedSU(ctype c)2253 ctype_isUnnamedSU (ctype c)
2254 {
2255 if (ctype_isSU (c))
2256 {
2257 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2258 }
2259 else
2260 {
2261 return FALSE;
2262 }
2263 }
2264
2265 ctype
ctype_createForwardStruct(cstring n)2266 ctype_createForwardStruct (cstring n)
2267 {
2268 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2269 ctype ct = usymtab_supForwardTypeEntry (ue);
2270
2271 cstring_free (n);
2272 return (ct);
2273 }
2274
2275 ctype
ctype_createForwardUnion(cstring n)2276 ctype_createForwardUnion (cstring n)
2277 {
2278 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2279 ctype ct = usymtab_supForwardTypeEntry (ue);
2280
2281 cstring_free (n);
2282 return (ct);
2283 }
2284
2285 ctype
ctype_createForwardEnum(cstring n)2286 ctype_createForwardEnum (cstring n)
2287 {
2288 uentry ue = uentry_makeEnumTag (n, ctype_unknown, fileloc_undefined);
2289 ctype ct = usymtab_supForwardTypeEntry (ue);
2290
2291 cstring_free (n);
2292 return (ct);
2293 }
2294
2295 ctype
ctype_removePointers(ctype c)2296 ctype_removePointers (ctype c)
2297 {
2298 ctype oldc;
2299
2300 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2301 {
2302 oldc = c;
2303 c = ctype_baseArrayPtr (c);
2304 llassert (c != oldc);
2305 }
2306
2307 return (c);
2308 }
2309
ctype_isMutable(ctype t)2310 bool ctype_isMutable (ctype t)
2311 {
2312 if (ctype_isUA (t))
2313 {
2314 return (uentry_isMutableDatatype
2315 (usymtab_getTypeEntry (ctype_typeId (t))));
2316 }
2317 else
2318 {
2319 return (ctype_isPointer (ctype_realType (t)));
2320 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2321 }
2322 }
2323
ctype_isRefCounted(ctype t)2324 bool ctype_isRefCounted (ctype t)
2325 {
2326 if (ctype_isUA (t))
2327 {
2328 return (uentry_isRefCountedDatatype
2329 (usymtab_getTypeEntry (ctype_typeId (t))));
2330 }
2331
2332 return FALSE;
2333 }
2334
ctype_isVisiblySharable(ctype t)2335 bool ctype_isVisiblySharable (ctype t)
2336 {
2337 if (ctype_isUnknown (t))
2338 {
2339 return TRUE;
2340 }
2341
2342 if (ctype_isConj (t))
2343 {
2344 return (ctype_isVisiblySharable (ctype_getConjA (t))
2345 || ctype_isVisiblySharable (ctype_getConjB (t)));
2346 }
2347
2348 if (ctype_isMutable (t))
2349 {
2350 if (ctype_isUA (t))
2351 {
2352 ctype rt = ctype_realType (t);
2353
2354 if (rt == t)
2355 {
2356 if (ctype_isNumAbstract (t))
2357 {
2358 return FALSE;
2359 }
2360 else
2361 {
2362 return TRUE;
2363 }
2364 }
2365 else
2366 {
2367 return ctype_isVisiblySharable (rt);
2368
2369 }
2370 }
2371 else
2372 {
2373 return TRUE;
2374 }
2375 }
2376
2377 return FALSE;
2378 }
2379
2380 # if 0
2381 /* Replaced by ctype_isMutable (more sensible) */
2382 bool ctype_canAlias (ctype ct)
2383 {
2384 /* can ct refer to memory locations?
2385 ** ==> a pointer or a mutable abstract type
2386 ** arrays?
2387 */
2388
2389 ctype tr = ctype_realType (ct);
2390
2391 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2392 }
2393 # endif
2394
2395 /*
2396 ** c1 is the dominant type; c2 is the modifier type
2397 **
2398 ** eg. double + long int => long double
2399 */
2400
ctype_combine(ctype dominant,ctype modifier)2401 ctype ctype_combine (ctype dominant, ctype modifier)
2402 {
2403 DPRINTF (("Combine: %s + %s",
2404 ctype_unparse (dominant),
2405 ctype_unparse (modifier)));
2406
2407 if (ctype_isConj (dominant))
2408 {
2409 ctype res;
2410
2411 if (ctype_isExplicitConj (dominant))
2412 {
2413 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2414 modifier),
2415 ctype_getConjB (dominant));
2416 }
2417 else
2418 {
2419 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2420 modifier),
2421 ctype_getConjB (dominant));
2422 }
2423
2424 return res;
2425 }
2426
2427 if (ctype_isUnknown (modifier))
2428 {
2429 return dominant;
2430 }
2431 else if (ctype_isUnknown (dominant))
2432 {
2433 return modifier;
2434 }
2435 else
2436 {
2437 if (ctype_isEnum (dominant)) dominant = ctype_int;
2438 if (ctype_isEnum (modifier)) modifier = ctype_int;
2439
2440 if (modifier == ctype_uint)
2441 {
2442 if (dominant == ctype_int) return ctype_uint;
2443 if (dominant == ctype_lint) return ctype_ulint;
2444 if (dominant == ctype_sint) return ctype_usint;
2445 if (dominant == ctype_char) return ctype_uchar;
2446
2447 /* evs 2000-07-28: added this line */
2448 if (dominant == ctype_llint) return ctype_ullint;
2449
2450 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2451 {
2452 voptgenerror (FLG_DUPLICATEQUALS,
2453 message ("Duplicate unsigned qualifier"),
2454 g_currentloc);
2455
2456 return ctype_uint;
2457 }
2458 else
2459 {
2460 voptgenerror (FLG_DUPLICATEQUALS,
2461 message ("Type qualifier unsigned used with %s",
2462 ctype_unparse (dominant)),
2463 g_currentloc);
2464
2465 return dominant;
2466 }
2467 }
2468 else if (modifier == ctype_llint)
2469 {
2470 if (dominant == ctype_int)
2471 {
2472 return ctype_llint;
2473 }
2474
2475 voptgenerror (FLG_DUPLICATEQUALS,
2476 message ("Duplicate long qualifier on non-int"),
2477 g_currentloc);
2478 }
2479 else if (modifier == ctype_lint)
2480 {
2481 if (dominant == ctype_int) return ctype_lint;
2482 if (dominant == ctype_uint) return ctype_ulint;
2483 if (dominant == ctype_double) return ctype_ldouble;
2484
2485 if (dominant == ctype_lint || dominant == ctype_ulint
2486 || dominant == ctype_sint || dominant == ctype_usint
2487 || dominant == ctype_ldouble)
2488 {
2489 if (dominant == ctype_lint)
2490 {
2491 /* long long not supported by ANSI */
2492 return ctype_llint;
2493 }
2494
2495 /* ++jimz */
2496 if (dominant == ctype_ulint)
2497 {
2498 /* unsigned long long not supported by ANSI */
2499 return ctype_ullint;
2500 }
2501 /* ==jimz */
2502
2503 if (dominant == ctype_sint || dominant == ctype_usint)
2504 {
2505 if (!context_getFlag (FLG_IGNOREQUALS))
2506 {
2507 llerrorlit (FLG_SYNTAX,
2508 "Contradictory long and short type qualifiers");
2509 }
2510 }
2511 else
2512 {
2513 voptgenerror (FLG_DUPLICATEQUALS,
2514 message ("Duplicate long qualifier"),
2515 g_currentloc);
2516 }
2517
2518 return ctype_lint;
2519 }
2520 }
2521 else if (modifier == ctype_sint)
2522 {
2523 if (dominant == ctype_int) return ctype_sint;
2524 if (dominant == ctype_uint) return ctype_usint;
2525
2526 if (dominant == ctype_sint || dominant == ctype_usint)
2527 {
2528 voptgenerror (FLG_DUPLICATEQUALS,
2529 message ("Duplicate short qualifier"),
2530 g_currentloc);
2531 return ctype_uint;
2532 }
2533 else if (dominant == ctype_lint)
2534 {
2535 if (!context_getFlag (FLG_IGNOREQUALS))
2536 {
2537 llerrorlit (FLG_SYNTAX,
2538 "Contradictory long and short type qualifiers");
2539 }
2540
2541 return dominant;
2542 }
2543 /* ++jimz */
2544 else if (dominant == ctype_llint)
2545 {
2546 if (!context_getFlag (FLG_IGNOREQUALS))
2547 {
2548 llerrorlit (FLG_SYNTAX,
2549 "Contradictory long long and short type qualifiers");
2550 }
2551
2552 return dominant;
2553 }
2554 /* ==jimz */
2555 else
2556 {
2557 if (!context_getFlag (FLG_IGNOREQUALS))
2558 {
2559 llerror (FLG_SYNTAX,
2560 message ("Type qualifier short used with %s",
2561 ctype_unparse (dominant)));
2562 }
2563
2564 return dominant;
2565 }
2566 }
2567 else if (modifier == ctype_ulint)
2568 {
2569 if (dominant == ctype_int) return modifier;
2570
2571 if (dominant == ctype_lint || dominant == ctype_ulint)
2572 {
2573 voptgenerror (FLG_DUPLICATEQUALS,
2574 message ("Duplicate long qualifier"),
2575 g_currentloc);
2576
2577 return modifier;
2578 }
2579
2580 if (dominant == ctype_uint || dominant == ctype_usint)
2581 {
2582 voptgenerror (FLG_DUPLICATEQUALS,
2583 message ("Duplicate unsigned qualifier"),
2584 g_currentloc);
2585
2586 return modifier;
2587 }
2588
2589 if (dominant == ctype_sint || dominant == ctype_usint)
2590 {
2591 if (!context_getFlag (FLG_IGNOREQUALS))
2592 {
2593 llerrorlit (FLG_SYNTAX,
2594 "Contradictory long and short type qualifiers");
2595 }
2596
2597 return dominant;
2598 }
2599
2600 if (!context_getFlag (FLG_IGNOREQUALS))
2601 {
2602 llerror (FLG_SYNTAX,
2603 message ("Type qualifiers unsigned long used with %s",
2604 ctype_unparse (dominant)));
2605 }
2606
2607 return dominant;
2608 }
2609 else if (modifier == ctype_usint)
2610 {
2611 if (dominant == ctype_int) return modifier;
2612
2613 if (dominant == ctype_sint || dominant == ctype_usint)
2614 {
2615 voptgenerror (FLG_DUPLICATEQUALS,
2616 message ("Duplicate short qualifier"),
2617 g_currentloc);
2618 return modifier;
2619 }
2620
2621 if (dominant == ctype_uint)
2622 {
2623 voptgenerror (FLG_DUPLICATEQUALS,
2624 message ("Duplicate unsigned qualifier"),
2625 g_currentloc);
2626
2627 return modifier;
2628 }
2629
2630 if (dominant == ctype_lint || dominant == ctype_ulint
2631 || dominant == ctype_llint)
2632 {
2633 if (!context_getFlag (FLG_IGNOREQUALS))
2634 {
2635 llerrorlit (FLG_SYNTAX,
2636 "Contradictory long and short type qualifiers");
2637 }
2638
2639 return dominant;
2640 }
2641
2642 if (!context_getFlag (FLG_IGNOREQUALS))
2643 {
2644 llerror (FLG_SYNTAX,
2645 message ("Type qualifiers unsigned short used with %s",
2646 ctype_unparse (dominant)));
2647 }
2648
2649 return dominant;
2650 }
2651 else
2652 {
2653 ;
2654 }
2655
2656 return dominant;
2657 }
2658 }
2659
ctype_resolve(ctype c)2660 ctype ctype_resolve (ctype c)
2661 {
2662 if (ctype_isUnknown (c) && !ctype_isAnytype (c))
2663 {
2664 DPRINTF (("Resolving to int: %s", ctype_unparse (c)));
2665 return ctype_int;
2666 }
2667
2668 return c;
2669 }
2670
ctype_fromQual(qual q)2671 ctype ctype_fromQual (qual q)
2672 {
2673 if (qual_isSigned (q)) return ctype_int;
2674 if (qual_isUnsigned (q)) return ctype_uint;
2675 if (qual_isLong (q)) return ctype_lint;
2676 if (qual_isShort (q)) return ctype_sint;
2677
2678 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2679 return ctype_unknown;
2680 }
2681
2682 bool
ctype_isAnyFloat(ctype c)2683 ctype_isAnyFloat (ctype c)
2684 {
2685 return (cprim_isAnyReal (ctype_toCprim (c)));
2686 }
2687
2688 bool
ctype_isUnsigned(ctype c)2689 ctype_isUnsigned (ctype c)
2690 {
2691 if (ctype_isConj (c))
2692 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2693 ctype_isUnsigned (ctype_getConjB (c)));
2694
2695 return (c == ctype_uint || c == ctype_uchar
2696 || c == ctype_usint || c == ctype_ulint
2697 || c == ctype_ullint
2698 || c == ctype_unsignedintegral);
2699 }
2700
2701 /* ++jimz */
2702 static bool
ctype_isLongLong(ctype c)2703 ctype_isLongLong (ctype c)
2704 {
2705 if (ctype_isConj (c))
2706 return (ctype_isLongLong (ctype_getConjA (c)) ||
2707 ctype_isLongLong (ctype_getConjB (c)));
2708
2709 return (c == ctype_llint || c == ctype_ullint);
2710 }
2711 /* ==jimz */
2712
2713 static bool
ctype_isLong(ctype c)2714 ctype_isLong (ctype c)
2715 {
2716 if (ctype_isConj (c))
2717 return (ctype_isLong (ctype_getConjA (c)) ||
2718 ctype_isLong (ctype_getConjB (c)));
2719
2720 return (c == ctype_lint || c == ctype_ulint);
2721 }
2722
2723 static bool
ctype_isShort(ctype c)2724 ctype_isShort (ctype c)
2725 {
2726 if (ctype_isConj (c))
2727 return (ctype_isShort (ctype_getConjA (c)) ||
2728 ctype_isShort (ctype_getConjB (c)));
2729
2730 return (c == ctype_sint || c == ctype_usint);
2731 }
2732
2733 bool
ctype_isStackAllocated(ctype c)2734 ctype_isStackAllocated (ctype c)
2735 {
2736 ctype ct = ctype_realType (c);
2737
2738 if (ctype_isConj (ct))
2739 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2740 ctype_isStackAllocated (ctype_getConjB (ct)));
2741
2742 return (ctype_isArray (c) || ctype_isSU (c));
2743 }
2744
ctype_isMoreUnsigned(ctype c1,ctype c2)2745 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2746 {
2747 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2748 }
2749
ctype_isLonger(ctype c1,ctype c2)2750 static bool ctype_isLonger (ctype c1, ctype c2)
2751 {
2752 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2753 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2754 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2755 || (ctype_isLong (c1)
2756 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2757 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2758 }
2759
2760 ctype
ctype_widest(ctype c1,ctype c2)2761 ctype_widest (ctype c1, ctype c2)
2762 {
2763 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2764 {
2765 return c2;
2766 }
2767 else
2768 {
2769 return c1;
2770 }
2771 }
2772
ctype_getCtbase(ctype c)2773 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2774 {
2775 /*@+enumint@*/
2776 if (c >= 0 && c < cttab.size)
2777 {
2778 return (cttab.entries[c]->ctbase);
2779 }
2780 else
2781 {
2782 if (c == ctype_unknown)
2783 llbuglit ("ctype_getCtbase: ctype unknown");
2784 if (c == ctype_undefined)
2785 llbuglit ("ctype_getCtbase: ctype undefined");
2786 if (c == ctype_dne)
2787 llbuglit ("ctype_getCtbase: ctype dne");
2788 if (c == ctype_elipsMarker)
2789 llbuglit ("ctype_getCtbase: elips marker");
2790
2791 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2792 BADEXIT;
2793 }
2794
2795 /*@=enumint@*/
2796 }
2797
2798 static /*@notnull@*/ /*@observer@*/ ctbase
ctype_getCtbaseSafe(ctype c)2799 ctype_getCtbaseSafe (ctype c)
2800 {
2801 ctbase res = ctype_getCtbase (c);
2802
2803 llassert (ctbase_isDefined (res));
2804 return res;
2805 }
2806
2807 /*
2808 ** ctentry
2809 */
2810
2811 static ctentry
ctype_getCtentry(ctype c)2812 ctype_getCtentry (ctype c)
2813 {
2814 static /*@only@*/ ctentry errorEntry = NULL;
2815
2816 if (cttab.size == 0)
2817 {
2818 if (errorEntry == NULL)
2819 {
2820 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2821 }
2822
2823 return errorEntry;
2824 }
2825
2826 /*@+enumint@*/
2827 if (c >= CTK_PLAIN && c < cttab.size)
2828 {
2829 return (cttab.entries[c]);
2830 }
2831 else if (c == CTK_UNKNOWN)
2832 llcontbuglit ("ctype_getCtentry: ctype unknown");
2833 else if (c == CTK_INVALID)
2834 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2835 else if (c == CTK_DNE)
2836 llcontbuglit ("ctype_getCtentry: ctype dne");
2837 else if (c == CTK_ELIPS)
2838 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2839 else if (c == CTK_MISSINGPARAMS)
2840 llcontbuglit ("ctype_getCtentry: ctype missing params");
2841 else
2842 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2843
2844 return (cttab.entries[ctype_unknown]);
2845 /*@=enumint@*/
2846 }
2847
2848
ctype_isFixedArray(ctype c)2849 bool ctype_isFixedArray (ctype c)
2850 {
2851 if (ctype_isElips (c)) return FALSE;
2852
2853 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2854 }
2855
2856
2857 /*drl 11/28/2000 */
2858 /* requires that the type is an fixed array */
2859 /* return the size of the array */
2860
ctype_getArraySize(ctype c)2861 size_t ctype_getArraySize (ctype c)
2862 {
2863 size_t size;
2864
2865 ctbase ctb;
2866
2867 llassert (ctype_isFixedArray (c));
2868
2869 ctb = ctype_getCtbaseSafe(c);
2870 size = ctbase_getArraySize (ctb);
2871
2872 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2873 ctype_unparse (c),
2874 (int) size)));
2875 return size;
2876 }
2877
ctype_biggerType(ctype c1,ctype c2)2878 ctype ctype_biggerType (ctype c1, ctype c2)
2879 {
2880 if (ctbase_isBigger (ctype_getCtbaseSafe (c2), ctype_getCtbaseSafe (c1)))
2881 {
2882 return c2;
2883 }
2884 else
2885 {
2886 return c1;
2887 }
2888 }
2889
ctype_getSize(ctype c)2890 int ctype_getSize (ctype c)
2891 {
2892 return ctbase_getSize (ctype_getCtbaseSafe (ctype_realType (c)));
2893 }
2894