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