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