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