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