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