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