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