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