]> andersk Git - splint.git/blob - src/ctype.c
Fixed handling of array dimensions (bug reported by Randi J. Relander)
[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 ctype_isFixedArray (ctype c)
1729 {
1730   if (ctype_isElips (c)) return FALSE;
1731
1732   return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
1733 }
1734
1735 bool
1736 ctype_isArrayPtr (ctype c)
1737 {
1738   return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1739 }
1740
1741 typeId
1742 ctype_typeId (ctype c)
1743 {
1744   return (ctbase_typeId (ctype_getCtbase (c)));
1745 }
1746
1747 cstring
1748 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1749 {
1750   llassert (! (ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1751
1752   if (ctype_isUnknown (c))
1753     {
1754       return message ("? %q", name);
1755     }
1756   else
1757     {
1758       return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1759     }
1760 }
1761
1762 cstring
1763 ctype_unparse (ctype c)
1764 {
1765   if (ctype_isElips (c))
1766     {
1767       return cstring_makeLiteralTemp ("...");
1768     }
1769   else if (ctype_isMissingParamsMarker (c))
1770     {
1771       return cstring_makeLiteralTemp ("-");
1772     }
1773   else if (ctype_isUnknown (c))
1774     {
1775       return cstring_makeLiteralTemp ("?");
1776     }
1777   else
1778     {
1779       /*@-modobserver@*/
1780       return (ctentry_doUnparse (ctype_getCtentry (c)));
1781       /*@=modobserver@*/
1782     }
1783 }
1784  
1785 cstring
1786 ctype_unparseSafe (ctype c)
1787 {
1788   if (ctype_isElips (c))
1789     {
1790       return cstring_makeLiteralTemp ("...");
1791     }
1792   else if (ctype_isMissingParamsMarker (c))
1793     {
1794       return cstring_makeLiteralTemp ("-");
1795     }
1796   else
1797     {
1798       cstring ret;
1799
1800       if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1801         {
1802           ctentry cte = ctype_getCtentry (c);
1803           
1804           if (cstring_isDefined (cte->unparse))
1805             {
1806               return (cte->unparse);
1807             }
1808         }
1809       
1810       ret = message ("[%d]", (int) c);
1811       cstring_markOwned (ret);
1812       return ret;
1813     }
1814 }
1815
1816 cstring
1817 ctype_unparseDeep (ctype c)
1818 {
1819   if (ctype_isElips (c))
1820     {
1821       return cstring_makeLiteralTemp ("...");
1822     }
1823   if (ctype_isMissingParamsMarker (c))
1824     {
1825       return cstring_makeLiteralTemp ("-");
1826     }
1827       
1828   return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1829 }
1830
1831 ctype
1832 ctype_undump (char **c)
1833 {
1834   return ((ctype) reader_getInt (c));   /* check its valid? */
1835 }
1836
1837 cstring
1838 ctype_dump (ctype c)
1839 {
1840   DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1841
1842   if (c < 0)
1843     {
1844       /* Handle invalid types in a kludgey way. */
1845       return (message ("0"));
1846     }
1847   
1848   if (ctype_isUA (c))
1849     {
1850       cstring tname = usymtab_getTypeEntryName 
1851          (usymtab_convertId (ctype_typeId (c)));
1852       
1853       if (cstring_equal (tname, context_getBoolName ()))
1854         {
1855           cstring_free (tname);
1856           return (message ("%d", ctype_bool));
1857         }
1858       
1859       cstring_free (tname);
1860     }
1861
1862   DPRINTF (("Returning: %d", c));
1863   return (message ("%d", c));
1864 }
1865
1866 ctype
1867 ctype_getBaseType (ctype c)
1868 {
1869   ctentry cte = ctype_getCtentry (c);
1870
1871   switch (ctentry_getKind (cte))
1872     {
1873     case CTK_UNKNOWN:
1874     case CTK_INVALID:
1875     case CTK_PLAIN:
1876       return c;
1877     case CTK_PTR:
1878     case CTK_ARRAY:
1879       return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1880     case CTK_COMPLEX:
1881       {
1882         ctbase ctb = cte->ctbase;
1883
1884         if (ctbase_isDefined (ctb))
1885           {
1886             /*@access ctbase@*/
1887             switch (ctb->type)
1888               {
1889               case CT_UNKNOWN:
1890               case CT_PRIM:
1891               case CT_USER:
1892               case CT_ENUM:
1893               case CT_ENUMLIST:
1894               case CT_BOOL:
1895               case CT_ABST:
1896               case CT_FCN:
1897               case CT_STRUCT:
1898               case CT_UNION:
1899               case CT_EXPFCN:
1900                 return c;
1901               case CT_PTR:
1902               case CT_ARRAY:
1903                 return (ctype_getBaseType (ctb->contents.base));
1904               case CT_FIXEDARRAY:
1905                 return (ctype_getBaseType (ctb->contents.farray->base));
1906               case CT_CONJ:             /* base type of A conj branch? */
1907                 return (ctype_getBaseType (ctb->contents.conj->a));
1908               }
1909             /*@noaccess ctbase@*/
1910           }
1911         else
1912           {
1913             return c;
1914           }
1915       }
1916     default:
1917       llbuglit ("ctype_newBase: bad case");
1918     }
1919   llcontbuglit ("ctype_getBaseType: unreachable code");
1920   return ((ctype)NULL);
1921 }
1922
1923 ctype
1924 ctype_adjustPointers (int np, ctype c)
1925 {
1926   
1927   if (ctype_isFunction (c))
1928     {
1929       c = ctype_makeParamsFunction
1930          (ctype_adjustPointers (np, ctype_getReturnType (c)),
1931          uentryList_copy (ctype_argsFunction (c)));
1932     }
1933   else
1934     {
1935       /* fix this should not use getBaseType ??? */
1936       ctype cb = ctype_getBaseType (c);
1937
1938       while (np > 0)
1939         {
1940           cb = ctype_makePointer (cb);
1941           np--;
1942         }
1943       c = ctype_newBase (c, cb);
1944     }
1945
1946   return (c);
1947 }
1948
1949
1950 enumNameList
1951 ctype_elist (ctype c)
1952 {
1953   return (ctbase_elist (ctype_getCtbase (c)));
1954 }
1955
1956 bool
1957 ctype_isFirstVoid (ctype c)
1958 {
1959   return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
1960 }
1961
1962 ctype
1963 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
1964 {
1965   return (cttable_addComplex (ctbase_createEnum (tag, el)));
1966 }
1967
1968 bool
1969 ctype_isEnum (ctype c)
1970 {
1971   return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
1972 }
1973
1974 cstring
1975 ctype_enumTag (ctype c)
1976 {
1977   llassert (ctype_isEnum (c));
1978
1979   return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
1980 }
1981
1982 bool
1983 ctype_isStruct (ctype c)
1984 {
1985   return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
1986 }
1987
1988 bool
1989 ctype_isUnion (ctype c)
1990 {
1991   return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
1992 }
1993
1994 ctype
1995 ctype_resolveNumerics (ctype c1, ctype c2)
1996 {
1997   /*
1998   ** returns longest type of c1 and c2
1999   */
2000
2001   if (c1 == c2) return c1;
2002
2003   c1 = ctype_realType (c1);
2004   c2 = ctype_realType (c2);
2005
2006   if (ctype_isEnum (c1)) c1 = ctype_unknown;
2007   if (ctype_isEnum (c2)) c2 = ctype_int;
2008
2009   if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2010
2011   /* 2001-06-08: This fix provided by Jim Zelenka. */
2012   if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2013   if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2014
2015   if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2016   if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2017   if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2018   if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2019
2020   /* 2001-06-08: This fix provided by Jim Zelenka. */
2021   if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2022
2023   if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2024
2025   if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2026   if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2027
2028   if (ctype_isKnown (c1)) return c1;
2029   else return c2;
2030 }
2031
2032 bool
2033 ctype_isStructorUnion (ctype c)
2034 {
2035   return (ctype_isStruct (c) || ctype_isUnion (c));
2036 }
2037
2038 ctype
2039 ctype_fixArrayPtr (ctype c)
2040 {
2041   if (ctype_isArray (c))
2042     {
2043       return (ctype_makePointer (ctype_baseArrayPtr (c)));
2044     }
2045   else
2046     return c;
2047 }
2048
2049 /*
2050 ** createUnnamedStruct/Union
2051 **
2052 ** check if it corresponds to an existing LCL-specified unnamed struct
2053 ** otherwise, give it a new tag
2054 */
2055
2056 ctype
2057 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2058 {
2059   ctype ret = usymtab_structFieldsType (f);
2060
2061   DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2062
2063   if (ctype_isDefined (ret))
2064     {
2065       uentryList_free (f);
2066       return ret;
2067     }
2068   else
2069     {
2070       cstring ft = fakeTag ();
2071       ctype ct = ctype_createStruct (cstring_copy (ft), f);
2072       uentry ue = uentry_makeStructTagLoc (ft, ct);
2073
2074       DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2075       ue = usymtab_supGlobalEntryReturn (ue);
2076       DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2077
2078       cstring_free (ft);
2079       return (ct);
2080     }
2081 }
2082
2083 ctype
2084 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2085 {
2086   ctype ret = usymtab_unionFieldsType (f);
2087   
2088   if (ctype_isDefined (ret))
2089     {
2090       uentryList_free (f);
2091       return ret;
2092     }
2093   else
2094     {
2095       cstring ft = fakeTag ();
2096       ctype ct = ctype_createUnion (cstring_copy (ft), f);
2097       uentry ue = uentry_makeUnionTagLoc (ft, ct);
2098
2099       usymtab_supGlobalEntry (ue);
2100       cstring_free (ft);
2101       return (ct);
2102     }
2103 }
2104
2105 bool
2106 ctype_isUnnamedSU (ctype c)
2107 {
2108   if (ctype_isSU (c))
2109     {
2110       return ctbase_isUnnamedSU (ctype_getCtbase (c));
2111     }
2112   else
2113     {
2114       return FALSE;
2115     }
2116 }
2117
2118 ctype
2119 ctype_createForwardStruct (cstring n)
2120 {
2121   uentry ue  = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2122   ctype ct = usymtab_supForwardTypeEntry (ue);
2123
2124   cstring_free (n);
2125   return (ct);
2126 }
2127
2128 ctype
2129 ctype_createForwardUnion (cstring n)
2130 {
2131   uentry ue  = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2132   ctype ct = usymtab_supForwardTypeEntry (ue);
2133
2134   cstring_free (n);
2135   return (ct);
2136 }
2137
2138 ctype
2139 ctype_removePointers (ctype c)
2140 {
2141   ctype oldc;
2142
2143   while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2144     {
2145       oldc = c;
2146       c = ctype_baseArrayPtr (c);
2147       llassert (c != oldc);
2148     }
2149   
2150   return (c);
2151 }
2152
2153 bool ctype_isMutable (ctype t)
2154 {
2155   if (ctype_isUA (t))
2156     {
2157       return (uentry_isMutableDatatype 
2158               (usymtab_getTypeEntry (ctype_typeId (t))));
2159     }
2160   else 
2161     {
2162       return (ctype_isPointer (ctype_realType (t)));
2163       /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2164     }
2165 }
2166
2167 bool ctype_isRefCounted (ctype t)
2168 {
2169   if (ctype_isUA (t))
2170     {
2171       return (uentry_isRefCountedDatatype 
2172               (usymtab_getTypeEntry (ctype_typeId (t))));
2173     }
2174
2175   return FALSE;
2176 }
2177
2178 bool ctype_isVisiblySharable (ctype t)
2179 {
2180   if (ctype_isUnknown (t)) return TRUE;
2181
2182   if (ctype_isConj (t))
2183     {
2184       return (ctype_isVisiblySharable (ctype_getConjA (t))
2185               || ctype_isVisiblySharable (ctype_getConjB (t)));
2186     }
2187
2188   if (ctype_isMutable (t))
2189     {
2190       if (ctype_isUA (t))
2191         {
2192           ctype rt = ctype_realType (t);
2193
2194           if (rt == t)
2195             {
2196               return TRUE;
2197             }
2198           else
2199             {
2200               return ctype_isVisiblySharable (rt);
2201
2202             }
2203         }
2204       else
2205         {
2206           return TRUE;
2207         }
2208     }
2209   
2210   return FALSE;
2211 }
2212
2213 # if 0
2214 /* Replaced by ctype_isMutable (more sensible) */
2215 bool ctype_canAlias (ctype ct)
2216 {
2217   /* can ct refer to memory locations?
2218   **       ==> a pointer or a mutable abstract type
2219   **           arrays?  
2220   */
2221
2222   ctype tr = ctype_realType (ct);
2223
2224   return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2225 }
2226 # endif
2227
2228 /*
2229 ** c1 is the dominant type; c2 is the modifier type
2230 **
2231 ** eg. double + long int => long double
2232 */
2233
2234 ctype ctype_combine (ctype dominant, ctype modifier)
2235 {
2236   DPRINTF (("Combine: %s + %s", 
2237             ctype_unparse (dominant),
2238             ctype_unparse (modifier)));
2239
2240   if (ctype_isConj (dominant)) 
2241     {      
2242       ctype res;
2243
2244       if (ctype_isExplicitConj (dominant))
2245         {
2246           res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant), 
2247                                                        modifier),
2248                                         ctype_getConjB (dominant));
2249         }
2250       else
2251         {
2252           res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2253                                                modifier),
2254                                 ctype_getConjB (dominant));
2255         }
2256
2257       return res;
2258     }
2259
2260   if (ctype_isUnknown (modifier)) 
2261     {
2262       return dominant;
2263     }
2264   else if (ctype_isUnknown (dominant))
2265     {
2266       return modifier; 
2267     }
2268   else
2269     {
2270       if (ctype_isEnum (dominant)) dominant = ctype_int;
2271       if (ctype_isEnum (modifier)) modifier = ctype_int;
2272       
2273       if (modifier == ctype_uint)
2274         {
2275           if (dominant == ctype_int) return ctype_uint;
2276           if (dominant == ctype_lint) return ctype_ulint;
2277           if (dominant == ctype_sint) return ctype_usint;
2278           if (dominant == ctype_char) return ctype_uchar;
2279
2280           /* evs 2000-07-28: added this line */
2281           if (dominant == ctype_llint) return ctype_ullint;
2282
2283           if ((dominant == ctype_uint) || dominant == ctype_uchar)
2284             {
2285               voptgenerror (FLG_DUPLICATEQUALS, 
2286                             message ("Duplicate unsigned qualifier"),
2287                             g_currentloc);
2288
2289               return ctype_uint;
2290             }
2291           else
2292             {
2293               voptgenerror (FLG_DUPLICATEQUALS, 
2294                             message ("Type qualifier unsigned used with %s", 
2295                                      ctype_unparse (dominant)),
2296                             g_currentloc);
2297           
2298               return dominant;
2299             }
2300         }
2301       else if (modifier == ctype_llint)
2302         {
2303           if (dominant == ctype_int)
2304             {
2305               return ctype_llint;
2306             }
2307           
2308           voptgenerror (FLG_DUPLICATEQUALS, 
2309                         message ("Duplicate long qualifier on non-int"),
2310                         g_currentloc);
2311         }
2312       else if (modifier == ctype_lint)
2313         {
2314           if (dominant == ctype_int) return ctype_lint;
2315           if (dominant == ctype_uint) return ctype_ulint;
2316           if (dominant == ctype_double) return ctype_ldouble;
2317           
2318           if (dominant == ctype_lint || dominant == ctype_ulint 
2319               || dominant == ctype_sint || dominant == ctype_usint
2320               || dominant == ctype_ldouble)
2321             {
2322               if (dominant == ctype_lint)
2323                 {
2324                   /* long long not supported by ANSI */
2325                   return ctype_llint;
2326                 }
2327               
2328               /* ++jimz */
2329               if (dominant == ctype_ulint)
2330                 {
2331                   /* unsigned long long not supported by ANSI */
2332                   return ctype_ullint;
2333                 }
2334               /* ==jimz */
2335
2336               if (dominant == ctype_sint || dominant == ctype_usint)
2337                 {
2338                   if (!context_getFlag (FLG_IGNOREQUALS))
2339                     {
2340                       llerrorlit (FLG_SYNTAX, 
2341                                   "Contradictory long and short type qualifiers");
2342                     }
2343                 }
2344               else
2345                 {
2346                   voptgenerror (FLG_DUPLICATEQUALS, 
2347                                 message ("Duplicate long qualifier"),
2348                                 g_currentloc);
2349                 }
2350               
2351               return ctype_lint;
2352             }
2353         }
2354       else if (modifier == ctype_sint)
2355         {
2356           if (dominant == ctype_int) return ctype_sint;
2357           if (dominant == ctype_uint) return ctype_usint;
2358           
2359           if (dominant == ctype_sint || dominant == ctype_usint)
2360             {
2361               voptgenerror (FLG_DUPLICATEQUALS, 
2362                             message ("Duplicate short qualifier"),
2363                             g_currentloc);
2364               return ctype_uint;
2365             }
2366           else if (dominant == ctype_lint)
2367             {
2368               if (!context_getFlag (FLG_IGNOREQUALS))
2369                 {
2370                   llerrorlit (FLG_SYNTAX, 
2371                               "Contradictory long and short type qualifiers");
2372                 }
2373               
2374               return dominant;
2375             }
2376 /* ++jimz */
2377           else if (dominant == ctype_llint)
2378             {
2379               if (!context_getFlag (FLG_IGNOREQUALS))
2380                 {
2381                   llerrorlit (FLG_SYNTAX, 
2382                               "Contradictory long long and short type qualifiers");
2383                 }
2384               
2385               return dominant;
2386             }
2387 /* ==jimz */
2388           else
2389             {
2390               if (!context_getFlag (FLG_IGNOREQUALS))
2391                 {
2392                   llerror (FLG_SYNTAX, 
2393                            message ("Type qualifier short used with %s", 
2394                                     ctype_unparse (dominant)));
2395                 }
2396
2397               return dominant;
2398             }
2399         }
2400       else if (modifier == ctype_ulint)
2401         {
2402           if (dominant == ctype_int) return modifier;
2403           
2404           if (dominant == ctype_lint || dominant == ctype_ulint)
2405             {
2406               voptgenerror (FLG_DUPLICATEQUALS, 
2407                             message ("Duplicate long qualifier"),
2408                             g_currentloc);
2409
2410               return modifier;
2411             }
2412           
2413           if (dominant == ctype_uint || dominant == ctype_usint)
2414             {
2415               voptgenerror (FLG_DUPLICATEQUALS, 
2416                             message ("Duplicate unsigned qualifier"),
2417                             g_currentloc);
2418
2419               return modifier;
2420             }
2421           
2422           if (dominant == ctype_sint || dominant == ctype_usint)
2423             {
2424               if (!context_getFlag (FLG_IGNOREQUALS))
2425                 {
2426                   llerrorlit (FLG_SYNTAX,
2427                               "Contradictory long and short type qualifiers");
2428                 }
2429
2430               return dominant;
2431             }
2432           
2433           if (!context_getFlag (FLG_IGNOREQUALS))
2434             {
2435               llerror (FLG_SYNTAX,
2436                        message ("Type qualifiers unsigned long used with %s", 
2437                                 ctype_unparse (dominant)));
2438             }
2439
2440           return dominant;
2441         }
2442       else if (modifier == ctype_usint)
2443         {
2444           if (dominant == ctype_int) return modifier;
2445           
2446           if (dominant == ctype_sint || dominant == ctype_usint)
2447             {
2448               voptgenerror (FLG_DUPLICATEQUALS, 
2449                             message ("Duplicate short qualifier"),
2450                             g_currentloc);
2451               return modifier;
2452             }
2453           
2454           if (dominant == ctype_uint)
2455             {
2456               voptgenerror (FLG_DUPLICATEQUALS, 
2457                             message ("Duplicate unsigned qualifier"),
2458                             g_currentloc);
2459
2460               return modifier;
2461             }
2462           
2463           if (dominant == ctype_lint || dominant == ctype_ulint
2464               || dominant == ctype_llint)
2465             {
2466               if (!context_getFlag (FLG_IGNOREQUALS))
2467                 {
2468                   llerrorlit (FLG_SYNTAX, 
2469                               "Contradictory long and short type qualifiers");
2470                 }
2471
2472               return dominant;
2473             }
2474           
2475           if (!context_getFlag (FLG_IGNOREQUALS))
2476             {
2477               llerror (FLG_SYNTAX, 
2478                        message ("Type qualifiers unsigned short used with %s",
2479                                 ctype_unparse (dominant)));
2480             }
2481
2482           return dominant;
2483         }
2484       else
2485         {
2486           ;
2487         }
2488
2489       return dominant;
2490     }
2491 }
2492   
2493 ctype ctype_resolve (ctype c)
2494 {
2495   if (ctype_isUnknown (c)) return ctype_int;
2496   return c;
2497 }
2498
2499 ctype ctype_fromQual (qual q)
2500 {
2501   if (qual_isSigned (q)) return ctype_int;
2502   if (qual_isUnsigned (q)) return ctype_uint;
2503   if (qual_isLong (q)) return ctype_lint;
2504   if (qual_isShort (q)) return ctype_sint;
2505   
2506   llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2507   return ctype_unknown;
2508 }
2509
2510 bool 
2511 ctype_isAnyFloat (ctype c)
2512 {
2513   return (cprim_isAnyReal (ctype_toCprim (c)));
2514 }
2515
2516 bool
2517 ctype_isUnsigned (ctype c)
2518 {
2519   if (ctype_isConj (c))
2520     return (ctype_isUnsigned (ctype_getConjA (c)) ||
2521             ctype_isUnsigned (ctype_getConjB (c)));
2522
2523   return (c == ctype_uint || c == ctype_uchar
2524           || c == ctype_usint || c == ctype_ulint
2525           || c == ctype_ullint
2526           || c == ctype_unsignedintegral);
2527 }
2528
2529 /* ++jimz */
2530 static bool
2531 ctype_isLongLong (ctype c)
2532 {
2533   if (ctype_isConj (c))
2534     return (ctype_isLongLong (ctype_getConjA (c)) ||
2535             ctype_isLongLong (ctype_getConjB (c)));
2536
2537   return (c == ctype_llint || c == ctype_ullint);
2538 }
2539 /* ==jimz */
2540
2541 static bool
2542 ctype_isLong (ctype c)
2543 {
2544   if (ctype_isConj (c))
2545     return (ctype_isLong (ctype_getConjA (c)) ||
2546             ctype_isLong (ctype_getConjB (c)));
2547
2548   return (c == ctype_lint || c == ctype_ulint);
2549 }
2550
2551 static bool
2552 ctype_isShort (ctype c)
2553 {
2554   if (ctype_isConj (c))
2555     return (ctype_isShort (ctype_getConjA (c)) ||
2556             ctype_isShort (ctype_getConjB (c)));
2557
2558   return (c == ctype_sint || c == ctype_usint);
2559 }
2560
2561 bool
2562 ctype_isStackAllocated (ctype c)
2563 {
2564   ctype ct = ctype_realType (c);
2565
2566   if (ctype_isConj (ct))
2567     return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2568             ctype_isStackAllocated (ctype_getConjB (ct)));
2569   
2570   return (ctype_isArray (c) || ctype_isSU (c));
2571 }
2572
2573 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2574 {
2575   return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2576 }
2577
2578 static bool ctype_isLonger (ctype c1, ctype c2)
2579 {
2580   /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2581   return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2582           || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2583           || (ctype_isLong (c1) 
2584               && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2585           || (ctype_isShort (c2) && !ctype_isShort (c1)));
2586 }
2587
2588 ctype
2589 ctype_widest (ctype c1, ctype c2)
2590 {
2591   if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2592     {
2593       return c2;
2594     }
2595   else
2596     {
2597       return c1;
2598     }
2599 }
2600
2601 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2602 {
2603   /*@+enumint@*/
2604   if (c >= 0 && c < cttab.size)
2605     {
2606       return (cttab.entries[c]->ctbase);
2607     }
2608   else 
2609     {
2610       if (c == ctype_unknown)
2611         llbuglit ("ctype_getCtbase: ctype unknown");
2612       if (c == ctype_undefined)
2613         llbuglit ("ctype_getCtbase: ctype undefined");
2614       if (c == ctype_dne)
2615         llbuglit ("ctype_getCtbase: ctype dne");
2616       if (c == ctype_elipsMarker)
2617         llbuglit ("ctype_getCtbase: elips marker");
2618       
2619       llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2620       BADEXIT;
2621     }
2622
2623   /*@=enumint@*/
2624 }
2625
2626 static /*@notnull@*/ /*@observer@*/ ctbase
2627 ctype_getCtbaseSafe (ctype c)
2628 {
2629   ctbase res = ctype_getCtbase (c);
2630
2631   llassert (ctbase_isDefined (res));
2632   return res;
2633 }
2634
2635 /*
2636 ** ctentry
2637 */
2638
2639 static ctentry
2640 ctype_getCtentry (ctype c)
2641 {
2642   static /*@only@*/ ctentry errorEntry = NULL;
2643
2644   if (cttab.size == 0)
2645     {
2646       if (errorEntry == NULL)
2647         {
2648           errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2649         }
2650
2651       return errorEntry;
2652     }
2653
2654   /*@+enumint@*/
2655   if (c >= CTK_PLAIN && c < cttab.size)
2656     {
2657       return (cttab.entries[c]);
2658     }
2659   else if (c == CTK_UNKNOWN) 
2660     llcontbuglit ("ctype_getCtentry: ctype unknown");
2661   else if (c == CTK_INVALID)
2662     llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2663   else if (c == CTK_DNE)
2664     llcontbuglit ("ctype_getCtentry: ctype dne");
2665   else if (c == CTK_ELIPS) 
2666     llcontbuglit ("ctype_getCtentry: ctype elipsis");
2667   else if (c == CTK_MISSINGPARAMS) 
2668     llcontbuglit ("ctype_getCtentry: ctype missing params");
2669   else
2670     llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2671
2672   return (cttab.entries[ctype_unknown]);
2673   /*@=enumint@*/
2674 }
2675
2676 /*drl 11/28/2000 */
2677 /* requires that the type is an fixed array */
2678 /* return the size of the array */
2679
2680 long int ctype_getArraySize (ctype c)
2681 {
2682   long int size;
2683   ctentry cte = ctype_getCtentry (c);
2684   ctbase ctb;
2685
2686   llassert (ctype_isFixedArray (c));
2687   llassert ((ctentry_getKind (cte) ==  CTK_COMPLEX) || (ctentry_getKind (cte) == CTK_ARRAY));
2688
2689   ctb = cte->ctbase;
2690   size = ctbase_getArraySize (ctb);
2691
2692   DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2693                      ctype_unparse (c),
2694                      (int) size)));
2695   return size;
2696 }
2697
This page took 0.238874 seconds and 5 git commands to generate.