]> andersk Git - splint.git/blame - src/ctype.c
Prewinter break editing commit.
[splint.git] / src / ctype.c
CommitLineData
885824d3 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
35static void ctype_recordConj (ctype p_c);
36
a0a162cd 37
885824d3 38/*
39** ctbase file
40*/
41
42# include "ctbase.i"
43
44/*
45** ctype table
46*/
47
48# include "cttable.i"
49
50static ctype ctype_getConjA (ctype p_c) /*@*/ ;
51static ctype ctype_getConjB (ctype p_c) /*@*/ ;
52
53static bool ctype_isComplex (ctype c)
54{
55 return (ctentry_isComplex (ctype_getCtentry(c)));
56}
57
58static bool ctype_isPlain (ctype c)
59{
60 return (ctentry_isPlain (ctype_getCtentry(c)));
61}
62
63static 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
79ctkind
80ctkind_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
96void
97ctype_initTable ()
98{
99 cttable_init ();
100}
101
102void
103ctype_destroyMod ()
104{
105 cttable_reset ();
106}
107
108void
109ctype_loadTable (FILE *f)
110{
111 cttable_load (f);
112}
113
114void
115ctype_dumpTable (FILE *f)
116{
a0a162cd 117 DPRINTF (("Dumping cttable!"));
885824d3 118 cttable_dump (f);
119}
120
121cstring
122ctype_unparseTable ()
123{
124 return (cttable_unparse ());
125}
126
127void
128ctype_printTable ()
129{
130 cttable_print ();
131}
132
133bool
134ctype_isUserBool (ctype ct)
135{
136 if (ctype_isUA (ct))
137 {
138 return (usymtab_isBoolType (ctype_typeId (ct)));
139 }
140
141 return (FALSE);
142}
143
144ctype
145ctype_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
153ctype
154ctype_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
161int
162ctype_count (void)
163{
164 return (cttab.size);
165}
166
167ctype
168ctype_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
a0a162cd 177 if (ctype_isManifestBool (r))
885824d3 178 {
a0a162cd 179 if (context_canAccessBool ())
885824d3 180 {
a0a162cd 181 r = context_boolImplementationType ();
885824d3 182 }
183 }
184
185 return r;
186}
187
188bool
189ctype_isSimple (ctype c)
190{
191 return (!(ctype_isPointer (c)
192 || ctype_isArray (c)
193 || ctype_isFunction (c)));
194}
195
196ctype
197ctype_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
209ctype
210ctype_realishType (ctype c)
211{
212 if (ctype_isUA (c))
213 {
a0a162cd 214 if (ctype_isManifestBool (c))
885824d3 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
229bool
230ctype_isUA (ctype c)
231{
232 return (ctbase_isUA (ctype_getCtbase (c)));
233}
234
235bool
236ctype_isUser (ctype c)
237{
238 return (ctbase_isUser (ctype_getCtbase (c)));
239}
240
241bool
242ctype_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
250bool
251ctype_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
276ctype
277ctype_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
305ctype ctype_makeFixedArray (ctype c, long size)
306{
307 return (cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c));
308}
309
310ctype
311ctype_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
330ctype
331ctype_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
371ctype
372ctype_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
382ctype_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
394ctype
395ctype_newBase (ctype c, ctype p)
396{
397 return (ctbase_newBase (c, p));
398}
399
400bool
401ctype_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
459int
460ctype_compare (ctype c1, ctype c2)
461{
462 ctentry ce1;
463 ctentry ce2;
464
a0a162cd 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
885824d3 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
505ctype
506ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
507{
508 uentryList_fixImpParams (p);
509 return (ctype_makeFunction (base, p));
510}
511
512ctype
513ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
514{
515 uentryList_fixImpParams (p);
516 return (ctbase_makeNFFunction (base, p));
517}
518
519ctype
520ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
521{
522 ctype ret;
523 ret = ctbase_makeFunction (base, p);
524 return (ret);
525}
526
527ctype 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
543ctype 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
558bool
559ctype_isFunction (ctype c)
560{
561 return (ctbase_isFunction (ctype_getCtbase (c)));
562}
563
564bool
565ctype_isExpFcn (ctype c)
566{
567 return (ctbase_isExpFcn (ctype_getCtbase (c)));
568}
569
570bool
571ctype_isVoid (ctype c)
572{
573 return (c == CTX_VOID);
574}
575
576bool
577ctype_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
585bool
586ctype_isUnsignedIntegral (ctype c)
587{
588 ctype cr = ctype_realType (c);
589
590 return (cr == ctype_unsignedintegral);
591}
592
593bool
594ctype_isSignedIntegral (ctype c)
595{
596 ctype cr = ctype_realType (c);
597
598 return (cr == ctype_signedintegral);
599}
600
601bool
602ctype_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
612bool
613ctype_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
624bool
625ctype_isString (ctype c)
626{
627 return (c == ctype_string
628 || (ctype_isPointer (c)
629 && ctype_isChar (ctype_baseArrayPtr (c))));
630}
631
632bool
633ctype_isChar (ctype c)
634{
635 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
636 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
637}
638
639bool
640ctype_isUnsignedChar (ctype c)
641{
642 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
643}
644
645bool
646ctype_isSignedChar (ctype c)
647{
648 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
649}
650
a0a162cd 651/*
652** Returns true if c matches the name -booltype <bool>
653*/
654
655bool
656ctype_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
885824d3 677bool
678ctype_isBool (ctype c)
679{
a0a162cd 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 */
885824d3 688
a0a162cd 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
885824d3 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 ()))));
a0a162cd 718# endif
885824d3 719}
720
721bool
722ctype_isDirectBool (ctype c)
723{
724 return (c == CTX_BOOL);
725}
726
727bool
728ctype_isReal (ctype c)
729{
730 return (cprim_isAnyReal (ctype_toCprim (c)));
731}
732
733bool
734ctype_isFloat (ctype c)
735{
736 return (c == ctype_float);
737}
738
739bool
740ctype_isDouble (ctype c)
741{
742 return (c == ctype_double || c == ctype_ldouble);
743}
744
745bool
746ctype_isSigned (ctype c)
747{
748 return (!ctype_isUnsigned (c));
749}
750
751bool
752ctype_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
764bool
765ctype_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
776bool
777ctype_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
791bool
792ctype_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
809bool
810ctype_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
827bool
828ctype_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
836bool
837ctype_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
847bool
848ctype_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
856bool
857ctype_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
865bool
866ctype_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
874bool
875ctype_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
887static 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
920bool
921ctype_isForceRealNumeric (ctype * c)
922{
923 return (ctype_isForcePred (c, ctype_isRealNumeric));
924}
925
926bool
927ctype_isForceRealInt (ctype * c)
928{
929 return (ctype_isForcePred (c, ctype_isRealInt));
930}
931
932bool
933ctype_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
944static ctype
945ctype_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
968ctype
969ctype_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
989static ctype ic = ctype_unknown; /* int | char */
990static ctype ib = ctype_unknown; /* int | bool */
991static ctype ifl = ctype_unknown; /* int | float */
992static ctype ibf = ctype_unknown; /* int | bool | float */
993static ctype ibc = ctype_unknown; /* int | bool | char */
994static ctype iv = ctype_unknown; /* int | void * */
995static ctype ivf = ctype_unknown; /* int | void * | float */
996static ctype ivb = ctype_unknown; /* int | void * | bool */
997static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
998static ctype cuc = ctype_unknown; /* char | unsigned char */
999
1000static void
1001ctype_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
1113ctype
1114ctype_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 {
a0a162cd 1132 if (ctype_isManifestBool (c1))
885824d3 1133 {
1134 c1 = ctype_bool;
1135 }
1136
a0a162cd 1137 if (ctype_isManifestBool (c2))
885824d3 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
1310bool
1311ctype_isConj (ctype c)
1312{
1313 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1314}
1315
1316static ctype
1317ctype_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
1324static ctype
1325ctype_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
1332static bool
1333ctype_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
1344ctype
1345ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1346{
1347 ctype ct;
1348
a0a162cd 1349 DPRINTF (("Creating a struct: %s / %s",
1350 n, uentryList_unparse (f)));
1351
885824d3 1352 ct = cttable_addComplex (ctbase_createStruct (n, f));
a0a162cd 1353 DPRINTF (("ct: %s", ctype_unparse (ct)));
885824d3 1354 return (ct);
1355}
1356
1357uentryList
1358ctype_getFields (ctype c)
1359{
1360 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1361}
1362
1363ctype
1364ctype_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
1381static bool
1382 quickMatch (ctype c1, ctype c2)
1383{
1384 if (c1 == c2)
1385 return TRUE;
1386
1387 return FALSE;
1388}
1389
1390bool
a0a162cd 1391ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
885824d3 1392{
1393 bool match;
1394
a0a162cd 1395 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1396
885824d3 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 {
a0a162cd 1408 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
885824d3 1409 return (match);
1410 }
1411}
1412
1413bool
1414ctype_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
1422bool
1423ctype_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
1435bool
1436ctype_matchDef (ctype c1, ctype c2)
1437{
a0a162cd 1438 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1439
885824d3 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
1460bool 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
1474bool
1475ctype_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
a0a162cd 1486 /*@-modobserver@*/
1487 /* The call forceMatch may modify the observer params, but, we don't care. */
885824d3 1488 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
a0a162cd 1489 /*@=modobserver@*/
885824d3 1490}
1491
1492bool
1493ctype_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
1516bool
1517ctype_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
1542bool
1543ctype_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
1568bool
1569ctype_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
1579bool ctype_isIncompleteArray (ctype c)
1580{
1581 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1582}
1583
1584bool ctype_isFixedArray (ctype c)
1585{
1586 if (ctype_isElips (c)) return FALSE;
1587
1588 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
1589}
1590
1591bool
1592ctype_isArrayPtr (ctype c)
1593{
1594 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1595}
1596
1597typeId
1598ctype_typeId (ctype c)
1599{
1600 return (ctbase_typeId (ctype_getCtbase (c)));
1601}
1602
1603cstring
1604ctype_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
1610cstring
1611ctype_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
1629cstring
1630ctype_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
1660cstring
1661ctype_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
1675ctype
1676ctype_undump (char **c)
1677{
1678 return ((ctype) getInt (c)); /* check its valid? */
1679}
1680
1681cstring
1682ctype_dump (ctype c)
1683{
a0a162cd 1684 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1685
885824d3 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
a0a162cd 1706 DPRINTF (("Returning: %d", c));
885824d3 1707 return (message ("%d", c));
1708}
1709
1710ctype
1711ctype_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
1767ctype
1768ctype_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
1794enumNameList
1795ctype_elist (ctype c)
1796{
1797 return (ctbase_elist (ctype_getCtbase (c)));
1798}
1799
1800bool
1801ctype_isFirstVoid (ctype c)
1802{
1803 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
1804}
1805
1806ctype
1807ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
1808{
1809 return (cttable_addComplex (ctbase_createEnum (tag, el)));
1810}
1811
1812bool
1813ctype_isEnum (ctype c)
1814{
1815 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
1816}
1817
1818cstring
1819ctype_enumTag (ctype c)
1820{
1821 llassert (ctype_isEnum (c));
1822
1823 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
1824}
1825
1826bool
1827ctype_isStruct (ctype c)
1828{
1829 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
1830}
1831
1832bool
1833ctype_isUnion (ctype c)
1834{
1835 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
1836}
1837
1838ctype
1839ctype_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
1866bool
1867ctype_isStructorUnion (ctype c)
1868{
1869 return (ctype_isStruct (c) || ctype_isUnion (c));
1870}
1871
1872ctype
1873ctype_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
1890ctype
1891ctype_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
1913ctype
1914ctype_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
1935ctype
1936ctype_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
1945ctype
1946ctype_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
1955ctype
1956ctype_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
1970bool 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
1983bool 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
1994bool 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) */
2030bool 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
2049ctype 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;
a0a162cd 2094
2095 /* evs 2000-07-28: added this line */
2096 if (dominant == ctype_llint) return ctype_ullint;
2097
885824d3 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
2288ctype ctype_resolve (ctype c)
2289{
2290 if (ctype_isUnknown (c)) return ctype_int;
2291 return c;
2292}
2293
2294ctype 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
2305bool
2306ctype_isAnyFloat (ctype c)
2307{
2308 return (cprim_isAnyReal (ctype_toCprim (c)));
2309}
2310
2311bool
2312ctype_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
2323static bool
2324ctype_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
2333static bool
2334ctype_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
2343bool
2344ctype_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
2355static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2356{
2357 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2358}
2359
2360static 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
2367ctype
2368ctype_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}
34f0c5e7 2380
2381/*drl 11/28/2000 */
2382/* requires that the type is an fixed array */
2383/* return the size of the array */
2384
f5ac53de 2385long int ctype_getArraySize (ctype c)
34f0c5e7 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.467709 seconds and 5 git commands to generate.