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