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