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