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