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