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