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