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