]> andersk Git - splint.git/blob - src/ctype.c
Temporarily set flags to splintme without warnings.
[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
1819     {
1820       /*@-modobserver@*/
1821       return (ctentry_doUnparse (ctype_getCtentry (c)));
1822       /*@=modobserver@*/
1823     }
1824 }
1825  
1826 cstring
1827 ctype_unparseSafe (ctype c)
1828 {
1829   if (ctype_isElips (c))
1830     {
1831       return cstring_makeLiteralTemp ("...");
1832     }
1833   else if (ctype_isMissingParamsMarker (c))
1834     {
1835       return cstring_makeLiteralTemp ("-");
1836     }
1837   else
1838     {
1839       cstring ret;
1840
1841       if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1842         {
1843           ctentry cte = ctype_getCtentry (c);
1844           
1845           if (cstring_isDefined (cte->unparse))
1846             {
1847               return (cte->unparse);
1848             }
1849         }
1850       
1851       ret = message ("[%d]", (int) c);
1852       cstring_markOwned (ret);
1853       return ret;
1854     }
1855 }
1856
1857 cstring
1858 ctype_unparseDeep (ctype c)
1859 {
1860   if (ctype_isElips (c))
1861     {
1862       return cstring_makeLiteralTemp ("...");
1863     }
1864   if (ctype_isMissingParamsMarker (c))
1865     {
1866       return cstring_makeLiteralTemp ("-");
1867     }
1868       
1869   return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1870 }
1871
1872 ctype
1873 ctype_undump (char **c)
1874 {
1875   return ((ctype) reader_getInt (c));   /* check its valid? */
1876 }
1877
1878 cstring
1879 ctype_dump (ctype c)
1880 {
1881   DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1882
1883   if (c < 0)
1884     {
1885       /* Handle invalid types in a kludgey way. */
1886       return (message ("0"));
1887     }
1888   
1889   if (ctype_isUA (c))
1890     {
1891       cstring tname = usymtab_getTypeEntryName 
1892          (usymtab_convertId (ctype_typeId (c)));
1893       
1894       if (cstring_equal (tname, context_getBoolName ()))
1895         {
1896           cstring_free (tname);
1897           return (message ("%d", ctype_bool));
1898         }
1899       
1900       cstring_free (tname);
1901     }
1902
1903   DPRINTF (("Returning: %d", c));
1904   return (message ("%d", c));
1905 }
1906
1907 ctype
1908 ctype_getBaseType (ctype c)
1909 {
1910   ctentry cte = ctype_getCtentry (c);
1911
1912   switch (ctentry_getKind (cte))
1913     {
1914     case CTK_UNKNOWN:
1915     case CTK_INVALID:
1916     case CTK_PLAIN:
1917       return c;
1918     case CTK_PTR:
1919     case CTK_ARRAY:
1920       return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1921     case CTK_COMPLEX:
1922       {
1923         ctbase ctb = cte->ctbase;
1924
1925         if (ctbase_isDefined (ctb))
1926           {
1927             /*@access ctbase@*/
1928             switch (ctb->type)
1929               {
1930               case CT_UNKNOWN:
1931               case CT_PRIM:
1932               case CT_USER:
1933               case CT_ENUM:
1934               case CT_ENUMLIST:
1935               case CT_BOOL:
1936               case CT_ABST:
1937               case CT_FCN:
1938               case CT_STRUCT:
1939               case CT_UNION:
1940               case CT_EXPFCN:
1941                 return c;
1942               case CT_PTR:
1943               case CT_ARRAY:
1944                 return (ctype_getBaseType (ctb->contents.base));
1945               case CT_FIXEDARRAY:
1946                 return (ctype_getBaseType (ctb->contents.farray->base));
1947               case CT_CONJ:             /* base type of A conj branch? */
1948                 return (ctype_getBaseType (ctb->contents.conj->a));
1949               }
1950             /*@noaccess ctbase@*/
1951           }
1952         else
1953           {
1954             return c;
1955           }
1956       }
1957     default:
1958       llbuglit ("ctype_newBase: bad case");
1959     }
1960   llcontbuglit ("ctype_getBaseType: unreachable code");
1961   return ((ctype)NULL);
1962 }
1963
1964 ctype
1965 ctype_adjustPointers (int np, ctype c)
1966 {
1967   
1968   if (ctype_isFunction (c))
1969     {
1970       c = ctype_makeParamsFunction
1971          (ctype_adjustPointers (np, ctype_getReturnType (c)),
1972          uentryList_copy (ctype_argsFunction (c)));
1973     }
1974   else
1975     {
1976       /* fix this should not use getBaseType ??? */
1977       ctype cb = ctype_getBaseType (c);
1978
1979       while (np > 0)
1980         {
1981           cb = ctype_makePointer (cb);
1982           np--;
1983         }
1984       c = ctype_newBase (c, cb);
1985     }
1986
1987   return (c);
1988 }
1989
1990
1991 enumNameList
1992 ctype_elist (ctype c)
1993 {
1994   return (ctbase_elist (ctype_getCtbase (c)));
1995 }
1996
1997 bool
1998 ctype_isFirstVoid (ctype c)
1999 {
2000   return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2001 }
2002
2003 ctype
2004 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2005 {
2006   return (cttable_addComplex (ctbase_createEnum (tag, el)));
2007 }
2008
2009 bool
2010 ctype_isEnum (ctype c)
2011 {
2012   return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2013 }
2014
2015 cstring
2016 ctype_enumTag (ctype c)
2017 {
2018   llassert (ctype_isEnum (c));
2019
2020   return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2021 }
2022
2023 bool
2024 ctype_isStruct (ctype c)
2025 {
2026   return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2027 }
2028
2029 bool
2030 ctype_isUnion (ctype c)
2031 {
2032   return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2033 }
2034
2035 ctype
2036 ctype_resolveNumerics (ctype c1, ctype c2)
2037 {
2038   /*
2039   ** returns longest type of c1 and c2
2040   */
2041
2042   if (c1 == c2) return c1;
2043
2044   c1 = ctype_realType (c1);
2045   c2 = ctype_realType (c2);
2046
2047   if (ctype_isEnum (c1)) c1 = ctype_unknown;
2048   if (ctype_isEnum (c2)) c2 = ctype_int;
2049
2050   if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2051
2052   /* 2001-06-08: This fix provided by Jim Zelenka. */
2053   if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2054   if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2055
2056   if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2057   if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2058   if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2059   if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2060
2061   /* 2001-06-08: This fix provided by Jim Zelenka. */
2062   if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2063
2064   if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2065
2066   if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2067   if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2068
2069   if (ctype_isKnown (c1)) return c1;
2070   else return c2;
2071 }
2072
2073 bool
2074 ctype_isStructorUnion (ctype c)
2075 {
2076   return (ctype_isStruct (c) || ctype_isUnion (c));
2077 }
2078
2079 ctype
2080 ctype_fixArrayPtr (ctype c)
2081 {
2082   if (ctype_isArray (c))
2083     {
2084       return (ctype_makePointer (ctype_baseArrayPtr (c)));
2085     }
2086   else
2087     return c;
2088 }
2089
2090 /*
2091 ** createUnnamedStruct/Union
2092 **
2093 ** check if it corresponds to an existing LCL-specified unnamed struct
2094 ** otherwise, give it a new tag
2095 */
2096
2097 ctype
2098 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2099 {
2100   ctype ret = usymtab_structFieldsType (f);
2101
2102   DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2103
2104   if (ctype_isDefined (ret))
2105     {
2106       uentryList_free (f);
2107       return ret;
2108     }
2109   else
2110     {
2111       cstring ft = fakeTag ();
2112       ctype ct = ctype_createStruct (cstring_copy (ft), f);
2113       uentry ue = uentry_makeStructTagLoc (ft, ct);
2114
2115       DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2116       ue = usymtab_supGlobalEntryReturn (ue);
2117       DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2118
2119       cstring_free (ft);
2120       return (ct);
2121     }
2122 }
2123
2124 ctype
2125 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2126 {
2127   ctype ret = usymtab_unionFieldsType (f);
2128   
2129   if (ctype_isDefined (ret))
2130     {
2131       uentryList_free (f);
2132       return ret;
2133     }
2134   else
2135     {
2136       cstring ft = fakeTag ();
2137       ctype ct = ctype_createUnion (cstring_copy (ft), f);
2138       uentry ue = uentry_makeUnionTagLoc (ft, ct);
2139
2140       usymtab_supGlobalEntry (ue);
2141       cstring_free (ft);
2142       return (ct);
2143     }
2144 }
2145
2146 bool
2147 ctype_isUnnamedSU (ctype c)
2148 {
2149   if (ctype_isSU (c))
2150     {
2151       return ctbase_isUnnamedSU (ctype_getCtbase (c));
2152     }
2153   else
2154     {
2155       return FALSE;
2156     }
2157 }
2158
2159 ctype
2160 ctype_createForwardStruct (cstring n)
2161 {
2162   uentry ue  = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2163   ctype ct = usymtab_supForwardTypeEntry (ue);
2164
2165   cstring_free (n);
2166   return (ct);
2167 }
2168
2169 ctype
2170 ctype_createForwardUnion (cstring n)
2171 {
2172   uentry ue  = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2173   ctype ct = usymtab_supForwardTypeEntry (ue);
2174
2175   cstring_free (n);
2176   return (ct);
2177 }
2178
2179 ctype
2180 ctype_removePointers (ctype c)
2181 {
2182   ctype oldc;
2183
2184   while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2185     {
2186       oldc = c;
2187       c = ctype_baseArrayPtr (c);
2188       llassert (c != oldc);
2189     }
2190   
2191   return (c);
2192 }
2193
2194 bool ctype_isMutable (ctype t)
2195 {
2196   if (ctype_isUA (t))
2197     {
2198       return (uentry_isMutableDatatype 
2199               (usymtab_getTypeEntry (ctype_typeId (t))));
2200     }
2201   else 
2202     {
2203       return (ctype_isPointer (ctype_realType (t)));
2204       /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2205     }
2206 }
2207
2208 bool ctype_isRefCounted (ctype t)
2209 {
2210   if (ctype_isUA (t))
2211     {
2212       return (uentry_isRefCountedDatatype 
2213               (usymtab_getTypeEntry (ctype_typeId (t))));
2214     }
2215
2216   return FALSE;
2217 }
2218
2219 bool ctype_isVisiblySharable (ctype t)
2220 {
2221   if (ctype_isUnknown (t)) return TRUE;
2222
2223   if (ctype_isConj (t))
2224     {
2225       return (ctype_isVisiblySharable (ctype_getConjA (t))
2226               || ctype_isVisiblySharable (ctype_getConjB (t)));
2227     }
2228
2229   if (ctype_isMutable (t))
2230     {
2231       if (ctype_isUA (t))
2232         {
2233           ctype rt = ctype_realType (t);
2234
2235           if (rt == t)
2236             {
2237               return TRUE;
2238             }
2239           else
2240             {
2241               return ctype_isVisiblySharable (rt);
2242
2243             }
2244         }
2245       else
2246         {
2247           return TRUE;
2248         }
2249     }
2250   
2251   return FALSE;
2252 }
2253
2254 # if 0
2255 /* Replaced by ctype_isMutable (more sensible) */
2256 bool ctype_canAlias (ctype ct)
2257 {
2258   /* can ct refer to memory locations?
2259   **       ==> a pointer or a mutable abstract type
2260   **           arrays?  
2261   */
2262
2263   ctype tr = ctype_realType (ct);
2264
2265   return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2266 }
2267 # endif
2268
2269 /*
2270 ** c1 is the dominant type; c2 is the modifier type
2271 **
2272 ** eg. double + long int => long double
2273 */
2274
2275 ctype ctype_combine (ctype dominant, ctype modifier)
2276 {
2277   DPRINTF (("Combine: %s + %s", 
2278             ctype_unparse (dominant),
2279             ctype_unparse (modifier)));
2280
2281   if (ctype_isConj (dominant)) 
2282     {      
2283       ctype res;
2284
2285       if (ctype_isExplicitConj (dominant))
2286         {
2287           res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant), 
2288                                                        modifier),
2289                                         ctype_getConjB (dominant));
2290         }
2291       else
2292         {
2293           res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2294                                                modifier),
2295                                 ctype_getConjB (dominant));
2296         }
2297
2298       return res;
2299     }
2300
2301   if (ctype_isUnknown (modifier)) 
2302     {
2303       return dominant;
2304     }
2305   else if (ctype_isUnknown (dominant))
2306     {
2307       return modifier; 
2308     }
2309   else
2310     {
2311       if (ctype_isEnum (dominant)) dominant = ctype_int;
2312       if (ctype_isEnum (modifier)) modifier = ctype_int;
2313       
2314       if (modifier == ctype_uint)
2315         {
2316           if (dominant == ctype_int) return ctype_uint;
2317           if (dominant == ctype_lint) return ctype_ulint;
2318           if (dominant == ctype_sint) return ctype_usint;
2319           if (dominant == ctype_char) return ctype_uchar;
2320
2321           /* evs 2000-07-28: added this line */
2322           if (dominant == ctype_llint) return ctype_ullint;
2323
2324           if ((dominant == ctype_uint) || dominant == ctype_uchar)
2325             {
2326               voptgenerror (FLG_DUPLICATEQUALS, 
2327                             message ("Duplicate unsigned qualifier"),
2328                             g_currentloc);
2329
2330               return ctype_uint;
2331             }
2332           else
2333             {
2334               voptgenerror (FLG_DUPLICATEQUALS, 
2335                             message ("Type qualifier unsigned used with %s", 
2336                                      ctype_unparse (dominant)),
2337                             g_currentloc);
2338           
2339               return dominant;
2340             }
2341         }
2342       else if (modifier == ctype_llint)
2343         {
2344           if (dominant == ctype_int)
2345             {
2346               return ctype_llint;
2347             }
2348           
2349           voptgenerror (FLG_DUPLICATEQUALS, 
2350                         message ("Duplicate long qualifier on non-int"),
2351                         g_currentloc);
2352         }
2353       else if (modifier == ctype_lint)
2354         {
2355           if (dominant == ctype_int) return ctype_lint;
2356           if (dominant == ctype_uint) return ctype_ulint;
2357           if (dominant == ctype_double) return ctype_ldouble;
2358           
2359           if (dominant == ctype_lint || dominant == ctype_ulint 
2360               || dominant == ctype_sint || dominant == ctype_usint
2361               || dominant == ctype_ldouble)
2362             {
2363               if (dominant == ctype_lint)
2364                 {
2365                   /* long long not supported by ANSI */
2366                   return ctype_llint;
2367                 }
2368               
2369               /* ++jimz */
2370               if (dominant == ctype_ulint)
2371                 {
2372                   /* unsigned long long not supported by ANSI */
2373                   return ctype_ullint;
2374                 }
2375               /* ==jimz */
2376
2377               if (dominant == ctype_sint || dominant == ctype_usint)
2378                 {
2379                   if (!context_getFlag (FLG_IGNOREQUALS))
2380                     {
2381                       llerrorlit (FLG_SYNTAX, 
2382                                   "Contradictory long and short type qualifiers");
2383                     }
2384                 }
2385               else
2386                 {
2387                   voptgenerror (FLG_DUPLICATEQUALS, 
2388                                 message ("Duplicate long qualifier"),
2389                                 g_currentloc);
2390                 }
2391               
2392               return ctype_lint;
2393             }
2394         }
2395       else if (modifier == ctype_sint)
2396         {
2397           if (dominant == ctype_int) return ctype_sint;
2398           if (dominant == ctype_uint) return ctype_usint;
2399           
2400           if (dominant == ctype_sint || dominant == ctype_usint)
2401             {
2402               voptgenerror (FLG_DUPLICATEQUALS, 
2403                             message ("Duplicate short qualifier"),
2404                             g_currentloc);
2405               return ctype_uint;
2406             }
2407           else if (dominant == ctype_lint)
2408             {
2409               if (!context_getFlag (FLG_IGNOREQUALS))
2410                 {
2411                   llerrorlit (FLG_SYNTAX, 
2412                               "Contradictory long and short type qualifiers");
2413                 }
2414               
2415               return dominant;
2416             }
2417 /* ++jimz */
2418           else if (dominant == ctype_llint)
2419             {
2420               if (!context_getFlag (FLG_IGNOREQUALS))
2421                 {
2422                   llerrorlit (FLG_SYNTAX, 
2423                               "Contradictory long long and short type qualifiers");
2424                 }
2425               
2426               return dominant;
2427             }
2428 /* ==jimz */
2429           else
2430             {
2431               if (!context_getFlag (FLG_IGNOREQUALS))
2432                 {
2433                   llerror (FLG_SYNTAX, 
2434                            message ("Type qualifier short used with %s", 
2435                                     ctype_unparse (dominant)));
2436                 }
2437
2438               return dominant;
2439             }
2440         }
2441       else if (modifier == ctype_ulint)
2442         {
2443           if (dominant == ctype_int) return modifier;
2444           
2445           if (dominant == ctype_lint || dominant == ctype_ulint)
2446             {
2447               voptgenerror (FLG_DUPLICATEQUALS, 
2448                             message ("Duplicate long qualifier"),
2449                             g_currentloc);
2450
2451               return modifier;
2452             }
2453           
2454           if (dominant == ctype_uint || dominant == ctype_usint)
2455             {
2456               voptgenerror (FLG_DUPLICATEQUALS, 
2457                             message ("Duplicate unsigned qualifier"),
2458                             g_currentloc);
2459
2460               return modifier;
2461             }
2462           
2463           if (dominant == ctype_sint || dominant == ctype_usint)
2464             {
2465               if (!context_getFlag (FLG_IGNOREQUALS))
2466                 {
2467                   llerrorlit (FLG_SYNTAX,
2468                               "Contradictory long and short type qualifiers");
2469                 }
2470
2471               return dominant;
2472             }
2473           
2474           if (!context_getFlag (FLG_IGNOREQUALS))
2475             {
2476               llerror (FLG_SYNTAX,
2477                        message ("Type qualifiers unsigned long used with %s", 
2478                                 ctype_unparse (dominant)));
2479             }
2480
2481           return dominant;
2482         }
2483       else if (modifier == ctype_usint)
2484         {
2485           if (dominant == ctype_int) return modifier;
2486           
2487           if (dominant == ctype_sint || dominant == ctype_usint)
2488             {
2489               voptgenerror (FLG_DUPLICATEQUALS, 
2490                             message ("Duplicate short qualifier"),
2491                             g_currentloc);
2492               return modifier;
2493             }
2494           
2495           if (dominant == ctype_uint)
2496             {
2497               voptgenerror (FLG_DUPLICATEQUALS, 
2498                             message ("Duplicate unsigned qualifier"),
2499                             g_currentloc);
2500
2501               return modifier;
2502             }
2503           
2504           if (dominant == ctype_lint || dominant == ctype_ulint
2505               || dominant == ctype_llint)
2506             {
2507               if (!context_getFlag (FLG_IGNOREQUALS))
2508                 {
2509                   llerrorlit (FLG_SYNTAX, 
2510                               "Contradictory long and short type qualifiers");
2511                 }
2512
2513               return dominant;
2514             }
2515           
2516           if (!context_getFlag (FLG_IGNOREQUALS))
2517             {
2518               llerror (FLG_SYNTAX, 
2519                        message ("Type qualifiers unsigned short used with %s",
2520                                 ctype_unparse (dominant)));
2521             }
2522
2523           return dominant;
2524         }
2525       else
2526         {
2527           ;
2528         }
2529
2530       return dominant;
2531     }
2532 }
2533   
2534 ctype ctype_resolve (ctype c)
2535 {
2536   if (ctype_isUnknown (c)) return ctype_int;
2537   return c;
2538 }
2539
2540 ctype ctype_fromQual (qual q)
2541 {
2542   if (qual_isSigned (q)) return ctype_int;
2543   if (qual_isUnsigned (q)) return ctype_uint;
2544   if (qual_isLong (q)) return ctype_lint;
2545   if (qual_isShort (q)) return ctype_sint;
2546   
2547   llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2548   return ctype_unknown;
2549 }
2550
2551 bool 
2552 ctype_isAnyFloat (ctype c)
2553 {
2554   return (cprim_isAnyReal (ctype_toCprim (c)));
2555 }
2556
2557 bool
2558 ctype_isUnsigned (ctype c)
2559 {
2560   if (ctype_isConj (c))
2561     return (ctype_isUnsigned (ctype_getConjA (c)) ||
2562             ctype_isUnsigned (ctype_getConjB (c)));
2563
2564   return (c == ctype_uint || c == ctype_uchar
2565           || c == ctype_usint || c == ctype_ulint
2566           || c == ctype_ullint
2567           || c == ctype_unsignedintegral);
2568 }
2569
2570 /* ++jimz */
2571 static bool
2572 ctype_isLongLong (ctype c)
2573 {
2574   if (ctype_isConj (c))
2575     return (ctype_isLongLong (ctype_getConjA (c)) ||
2576             ctype_isLongLong (ctype_getConjB (c)));
2577
2578   return (c == ctype_llint || c == ctype_ullint);
2579 }
2580 /* ==jimz */
2581
2582 static bool
2583 ctype_isLong (ctype c)
2584 {
2585   if (ctype_isConj (c))
2586     return (ctype_isLong (ctype_getConjA (c)) ||
2587             ctype_isLong (ctype_getConjB (c)));
2588
2589   return (c == ctype_lint || c == ctype_ulint);
2590 }
2591
2592 static bool
2593 ctype_isShort (ctype c)
2594 {
2595   if (ctype_isConj (c))
2596     return (ctype_isShort (ctype_getConjA (c)) ||
2597             ctype_isShort (ctype_getConjB (c)));
2598
2599   return (c == ctype_sint || c == ctype_usint);
2600 }
2601
2602 bool
2603 ctype_isStackAllocated (ctype c)
2604 {
2605   ctype ct = ctype_realType (c);
2606
2607   if (ctype_isConj (ct))
2608     return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2609             ctype_isStackAllocated (ctype_getConjB (ct)));
2610   
2611   return (ctype_isArray (c) || ctype_isSU (c));
2612 }
2613
2614 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2615 {
2616   return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2617 }
2618
2619 static bool ctype_isLonger (ctype c1, ctype c2)
2620 {
2621   /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2622   return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2623           || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2624           || (ctype_isLong (c1) 
2625               && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2626           || (ctype_isShort (c2) && !ctype_isShort (c1)));
2627 }
2628
2629 ctype
2630 ctype_widest (ctype c1, ctype c2)
2631 {
2632   if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2633     {
2634       return c2;
2635     }
2636   else
2637     {
2638       return c1;
2639     }
2640 }
2641
2642 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2643 {
2644   /*@+enumint@*/
2645   if (c >= 0 && c < cttab.size)
2646     {
2647       return (cttab.entries[c]->ctbase);
2648     }
2649   else 
2650     {
2651       if (c == ctype_unknown)
2652         llbuglit ("ctype_getCtbase: ctype unknown");
2653       if (c == ctype_undefined)
2654         llbuglit ("ctype_getCtbase: ctype undefined");
2655       if (c == ctype_dne)
2656         llbuglit ("ctype_getCtbase: ctype dne");
2657       if (c == ctype_elipsMarker)
2658         llbuglit ("ctype_getCtbase: elips marker");
2659       
2660       llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2661       BADEXIT;
2662     }
2663
2664   /*@=enumint@*/
2665 }
2666
2667 static /*@notnull@*/ /*@observer@*/ ctbase
2668 ctype_getCtbaseSafe (ctype c)
2669 {
2670   ctbase res = ctype_getCtbase (c);
2671
2672   llassert (ctbase_isDefined (res));
2673   return res;
2674 }
2675
2676 /*
2677 ** ctentry
2678 */
2679
2680 static ctentry
2681 ctype_getCtentry (ctype c)
2682 {
2683   static /*@only@*/ ctentry errorEntry = NULL;
2684
2685   if (cttab.size == 0)
2686     {
2687       if (errorEntry == NULL)
2688         {
2689           errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2690         }
2691
2692       return errorEntry;
2693     }
2694
2695   /*@+enumint@*/
2696   if (c >= CTK_PLAIN && c < cttab.size)
2697     {
2698       return (cttab.entries[c]);
2699     }
2700   else if (c == CTK_UNKNOWN) 
2701     llcontbuglit ("ctype_getCtentry: ctype unknown");
2702   else if (c == CTK_INVALID)
2703     llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2704   else if (c == CTK_DNE)
2705     llcontbuglit ("ctype_getCtentry: ctype dne");
2706   else if (c == CTK_ELIPS) 
2707     llcontbuglit ("ctype_getCtentry: ctype elipsis");
2708   else if (c == CTK_MISSINGPARAMS) 
2709     llcontbuglit ("ctype_getCtentry: ctype missing params");
2710   else
2711     llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2712
2713   return (cttab.entries[ctype_unknown]);
2714   /*@=enumint@*/
2715 }
2716
2717
2718 bool ctype_isFixedArray (ctype c)
2719 {
2720   if (ctype_isElips (c)) return FALSE;
2721
2722   return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2723 }
2724
2725
2726 /*drl 11/28/2000 */
2727 /* requires that the type is an fixed array */
2728 /* return the size of the array */
2729
2730 long int ctype_getArraySize (ctype c)
2731 {
2732   long int size;
2733
2734   ctbase ctb;
2735
2736   llassert (ctype_isFixedArray (c));
2737
2738   ctb = ctype_getCtbaseSafe(c);
2739   size = ctbase_getArraySize (ctb);
2740
2741   DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2742                      ctype_unparse (c),
2743                      (int) size)));
2744   return size;
2745 }
2746
This page took 3.62306 seconds and 5 git commands to generate.