2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
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
27 ** This files implements three types: ctentry, cttable and ctype.
28 ** They should probably be separated soon.
31 # include "lclintMacros.nf"
33 # include "structNames.h"
35 static void ctype_recordConj (ctype p_c);
50 static ctype ctype_getConjA (ctype p_c) /*@*/ ;
51 static ctype ctype_getConjB (ctype p_c) /*@*/ ;
53 static bool ctype_isComplex (ctype c)
55 return (ctentry_isComplex (ctype_getCtentry(c)));
58 static bool ctype_isPlain (ctype c)
60 return (ctentry_isPlain (ctype_getCtentry(c)));
63 static bool ctype_isBroken (ctype c)
66 if (c == CTK_DNE || c == CTK_INVALID || c == CTK_UNKNOWN)
73 ctentry cte = ctype_getCtentry (c);
75 return (ctentry_isBogus (cte));
80 ctkind_fromInt (int i)
83 if (i < CTK_UNKNOWN || i > CTK_COMPLEX)
85 llcontbug (message ("ctkind_fromInt: out of range: %d", i));
109 ctype_loadTable (FILE *f)
115 ctype_dumpTable (FILE *f)
117 DPRINTF (("Dumping cttable!"));
122 ctype_unparseTable ()
124 return (cttable_unparse ());
134 ctype_isUserBool (ctype ct)
138 return (usymtab_isBoolType (ctype_typeId (ct)));
145 ctype_createUser (typeId u)
147 /* requires: ctype_createUser (u) is never called more than once for any u. */
149 ctbase ct = ctbase_createUser (u);
150 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ct)));
154 ctype_createAbstract (typeId u)
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))));
168 ctype_realType (ctype c)
174 r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c)));
177 if (ctype_isManifestBool (r))
179 if (context_canAccessBool ())
181 r = context_boolImplementationType ();
189 ctype_isSimple (ctype c)
191 return (!(ctype_isPointer (c)
193 || ctype_isFunction (c)));
197 ctype_forceRealType (ctype c)
203 r = uentry_getForceRealType (usymtab_getTypeEntry (ctype_typeId (c)));
210 ctype_realishType (ctype c)
214 if (ctype_isManifestBool (c))
220 ctype r = uentry_getRealType (usymtab_getTypeEntry
232 return (ctbase_isUA (ctype_getCtbase (c)));
236 ctype_isUser (ctype c)
238 return (ctbase_isUser (ctype_getCtbase (c)));
242 ctype_isAbstract (ctype c)
244 return ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
246 (ctype_isAbstract (ctype_getConjA (c))
247 || ctype_isAbstract (ctype_getConjB (c)))));
251 ctype_isRealAbstract (ctype c)
253 return (ctype_isAbstract (ctype_realType (c)) ||
255 (ctype_isRealAbstract (ctype_getConjA (c)) ||
256 ctype_isRealAbstract (ctype_getConjB (c)))));
260 ** primitive creators
264 ** createPrim not necessary --- subsumed by ctype_int, etc.
268 ** ctbase_unknown --- removed argument
273 ** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
277 ctype_makePointer (ctype c)
283 else if (c == ctype_void)
285 return ctype_voidPointer;
289 ctentry cte = ctype_getCtentry (c);
290 ctype clp = ctentry_getPtr (cte);
292 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
294 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
295 ctentry_setPtr (cte, cnew);
305 ctype ctype_makeFixedArray (ctype c, long size)
307 return (cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c));
311 ctype_makeArray (ctype c)
313 ctentry cte = ctype_getCtentry (c);
314 ctype clp = ctentry_getArray (cte);
316 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
318 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
319 ctentry_setArray (cte, cnew);
327 ** requires c is a pointer of array
331 ctype_baseArrayPtr (ctype c)
333 ctentry cte = ctype_getCtentry (ctype_realType (c));
335 if (ctype_isConj (c))
337 if (ctype_isAP (ctype_getConjA (c)))
339 if (ctype_isAP (ctype_getConjB (c)))
341 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
342 ctype_baseArrayPtr (ctype_getConjB (c))));
346 return (ctype_baseArrayPtr (ctype_getConjA (c)));
351 return (ctype_baseArrayPtr (ctype_getConjB (c)));
354 else if (ctype_isInt (c)) /* could be NULL */
356 return ctype_unknown;
360 ctype clp = ctentry_getBase (cte);
362 if (ctype_isBroken (clp))
364 llbuglit ("ctype_baseArrayPtr: bogus ctype");
372 ctype_returnValue (ctype c)
374 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
378 ** must be a shared pointer
381 /*@observer@*/ uentryList
382 ctype_argsFunction (ctype c)
384 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
388 ** Returns type with base type p and compound types from c.
390 ** i.e., c = char *[]; p = int
395 ctype_newBase (ctype c, ctype p)
397 return (ctbase_newBase (c, p));
401 ctype_sameAltTypes (ctype c1, ctype c2)
406 llassert (ctype_isConj (c1) && ctype_isConj (c2));
408 c1a = ctype_getConjA (c1);
409 c2a = ctype_getConjA (c2);
411 c1b = ctype_getConjB (c1);
412 c2b = ctype_getConjB (c2);
414 if (ctype_compare (c1a, c2a) == 0)
416 if (ctype_compare (c1b, c2b) == 0)
422 if (ctype_isConj (c1b) && ctype_isConj (c2b))
424 return ctype_sameAltTypes (c1b, c2b);
434 if (ctype_compare (c1a, c2b) == 0)
436 if (ctype_compare (c1b, c2a) == 0)
442 if (ctype_isConj (c1b) && ctype_isConj (c2a))
444 return ctype_sameAltTypes (c1b, c2a);
460 ctype_compare (ctype c1, ctype c2)
465 /* Can't get entries for special ctypes (elips marker) */
467 if (ctype_isElips (c1) || ctype_isElips (c2)
468 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
469 return int_compare (c1, c2);
472 ce1 = ctype_getCtentry (c1);
473 ce2 = ctype_getCtentry (c2);
475 if (ctentry_isComplex (ce1))
477 if (ctentry_isComplex (ce2))
479 return (ctbase_compare (ctype_getCtbase (c1),
480 ctype_getCtbase (c2), FALSE));
487 else if (ctentry_isComplex (ce2))
493 return (int_compare (c1, c2));
502 ** makeFunction: pointer to function returning base
506 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
508 uentryList_fixImpParams (p);
509 return (ctype_makeFunction (base, p));
513 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
515 uentryList_fixImpParams (p);
516 return (ctbase_makeNFFunction (base, p));
520 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
523 ret = ctbase_makeFunction (base, p);
527 ctype ctype_expectFunction (ctype c)
529 /* handle parenthesized declarations */
533 c = ctype_makePointer (c);
536 return (cttable_addComplex (ctbase_expectFunction (c)));
540 ** makeRealFunction: function returning base
543 ctype ctype_makeRealFunction (ctype base, uentryList p)
545 return (cttable_addComplex (ctbase_makeRealFunction (base, p)));
553 **** this is very poorly defined
555 **** need to unify function/function pointer meaning
559 ctype_isFunction (ctype c)
561 return (ctbase_isFunction (ctype_getCtbase (c)));
565 ctype_isExpFcn (ctype c)
567 return (ctbase_isExpFcn (ctype_getCtbase (c)));
571 ctype_isVoid (ctype c)
573 return (c == CTX_VOID);
577 ctype_isArbitraryIntegral (ctype c)
579 ctype cr = ctype_realType (c);
581 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
582 || cr == ctype_signedintegral);
586 ctype_isUnsignedIntegral (ctype c)
588 ctype cr = ctype_realType (c);
590 return (cr == ctype_unsignedintegral);
594 ctype_isSignedIntegral (ctype c)
596 ctype cr = ctype_realType (c);
598 return (cr == ctype_signedintegral);
602 ctype_isInt (ctype c)
604 cprim cp = ctype_toCprim (c);
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 ()));
613 ctype_isRegularInt (ctype c)
615 cprim cp = ctype_toCprim (c);
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 ()));
625 ctype_isString (ctype c)
627 return (c == ctype_string
628 || (ctype_isPointer (c)
629 && ctype_isChar (ctype_baseArrayPtr (c))));
633 ctype_isChar (ctype c)
635 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
636 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
640 ctype_isUnsignedChar (ctype c)
642 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
646 ctype_isSignedChar (ctype c)
648 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
652 ** Returns true if c matches the name -booltype <bool>
656 ctype_isManifestBool (ctype c)
659 ** Changed the meaning of ctype_isBool - evs 2000-07-24
660 ** The old meaning was very convoluted!
663 ** c == CTX_BOOL - its a direct bool
664 ** c is a user/abstract type matching the bool name
665 ** (should never occur?)
668 if (ctype_isDirectBool (c)) {
670 } else if (ctype_isUA (c)) {
671 return ctype_isUserBool (c);
678 ctype_isBool (ctype c)
681 ** Changed the meaning of ctype_isBool - evs 2000-07-24
682 ** The old meaning was very convoluted!
685 ** its a manifest bool
686 ** +boolint and ctype_isInt (c)
689 if (ctype_isManifestBool (c)) {
691 } else if (context_msgBoolInt ()) {
692 return ctype_isInt (c);
698 if (context_getFlag (FLG_ABSTRACTBOOL))
700 if (typeId_isInvalid (boolType))
702 boolType = usymtab_getTypeId (context_getBoolName ());
705 if (context_hasAccess (boolType))
707 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
708 || (context_msgBoolInt ()
710 || (c == CTX_CHAR && context_msgCharInt ()))))
715 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
716 || (context_msgBoolInt ()
717 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
722 ctype_isDirectBool (ctype c)
724 return (c == CTX_BOOL);
728 ctype_isReal (ctype c)
730 return (cprim_isAnyReal (ctype_toCprim (c)));
734 ctype_isFloat (ctype c)
736 return (c == ctype_float);
740 ctype_isDouble (ctype c)
742 return (c == ctype_double || c == ctype_ldouble);
746 ctype_isSigned (ctype c)
748 return (!ctype_isUnsigned (c));
752 ctype_isNumeric (ctype c)
754 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c));
761 ** work on actual type in current context
765 ctype_isRealNumeric (ctype c)
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)));
777 ctype_isRealInt (ctype c)
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)));
786 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
792 ctype_isRealVoid (ctype c)
794 if (ctype_isPlain (c))
796 return (ctype_isVoid (ctype_realType (c)));
798 else if (ctype_isConj (c))
800 return (ctype_isRealVoid (ctype_getConjA (c)) ||
801 ctype_isRealVoid (ctype_getConjB (c)));
810 ctype_isRealBool (ctype c)
812 if (ctype_isPlain (c))
814 return (ctype_isBool (ctype_realishType (c)));
816 else if (ctype_isConj (c))
818 return (ctype_isRealBool (ctype_getConjA (c)) ||
819 ctype_isRealBool (ctype_getConjB (c)));
828 ctype_isRealPointer (ctype c)
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)));
837 ctype_isRealSU (ctype c)
839 if (ctype_isConj (c))
841 return (ctype_isRealSU (ctype_getConjA (c)) ||
842 ctype_isRealSU (ctype_getConjB (c)));
844 return (ctype_isStructorUnion (ctype_realType (c)));
848 ctype_isRealArray (ctype c)
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)));
857 ctype_isRealAP (ctype c)
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)));
866 ctype_isRealFunction (ctype c)
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)));
875 ctype_isDirectInt (ctype c)
877 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
881 ** forceful predicates
883 ** take *ctype; if its a conjunct, and there is a match replace with match only.
884 ** if both match, still conjunct
888 ctype_isForcePred (ctype * c, bool (pred) (ctype))
890 if (ctype_isConj (*c))
892 ctype cbr = ctype_getConjA (*c);
896 if ((*pred) (ctype_getConjB (*c)))
909 if ((*pred) (cbr = ctype_getConjB (*c)))
917 return ((*pred) (*c));
921 ctype_isForceRealNumeric (ctype * c)
923 return (ctype_isForcePred (c, ctype_isRealNumeric));
927 ctype_isForceRealInt (ctype * c)
929 return (ctype_isForcePred (c, ctype_isRealInt));
933 ctype_isForceRealBool (ctype * c)
935 return (ctype_isForcePred (c, ctype_isRealBool));
941 ** save int/char, int/bool, other random conjuncts
945 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
947 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
951 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
959 return (ctype_makeExplicitConj (c1, c2));
963 return (ctype_makeConj (c1, c2));
969 ctype_makeExplicitConj (ctype c1, ctype c2)
971 if (ctype_isFunction (c1) && !ctype_isFunction (c2))
973 ctype ret = ctype_makeExplicitConj (ctype_returnValue (c1), c2);
975 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
977 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
979 ctype ret = ctype_makeExplicitConj (c1, ctype_returnValue (c2));
981 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
985 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
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 */
1001 ctype_recordConj (ctype c)
1005 llassert (ctype_isConj (c));
1007 c1 = ctype_getConjA (c);
1008 c2 = ctype_getConjB (c);
1011 if (c2 == ctype_int && c1 != ctype_int)
1021 if (c1 == ctype_int)
1023 if (c2 == ctype_char)
1025 llassert (ic == ctype_unknown);
1028 else if (c2 == ctype_bool)
1030 llassert (ib == ctype_unknown);
1033 else if (c2 == ctype_float)
1035 llassert (ifl == ctype_unknown);
1038 else if (c2 == CTP_VOID)
1040 llassert (iv == ctype_unknown);
1048 else if (c1 == ib && ib != ctype_unknown)
1050 if (c2 == ctype_float)
1052 llassert (ibf == ctype_unknown);
1055 else if (c2 == ctype_char)
1057 llassert (ibc == ctype_unknown);
1067 if (c2 == ctype_bool)
1069 llassert (ivb == ctype_unknown);
1072 else if (c2 == ctype_float)
1074 llassert (ivf == ctype_unknown);
1084 if (c2 == ctype_bool)
1086 llassert (ivbf == ctype_unknown);
1092 if (c2 == ctype_float)
1094 llassert (ivbf == ctype_unknown);
1098 else if (c1 == ctype_char)
1100 if (c2 == ctype_uchar)
1102 llassert (cuc == ctype_unknown);
1114 ctype_makeConj (ctype c1, ctype c2)
1116 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1118 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1120 if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1122 ctype ret = ctype_makeConj (ctype_returnValue (c1), c2);
1123 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1125 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1127 ctype ret = ctype_makeConj (c1, ctype_returnValue (c2));
1128 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1132 if (ctype_isManifestBool (c1))
1137 if (ctype_isManifestBool (c2))
1142 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1144 c1 = ctype_voidPointer;
1147 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1149 c2 = ctype_voidPointer;
1153 ** Ouch, can't do this. unsigned, etc. modifiers might
1154 ** apply to wrong type!
1156 ** if (c2 == ctype_int && c1 != ctype_int)
1167 if (c1 == ctype_int)
1169 if (c2 == ctype_char)
1171 if (ic == ctype_unknown)
1173 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1178 else if (c2 == ctype_bool)
1180 if (ib == ctype_unknown)
1182 ib = cttable_addComplex
1183 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1188 else if (c2 == ctype_float)
1190 if (ifl == ctype_unknown)
1192 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1199 if (c2 == ctype_voidPointer)
1201 if (iv == ctype_unknown)
1203 iv = cttable_addComplex
1204 (ctbase_makeConj (ctype_int,
1213 else if (c1 == ib && ib != ctype_unknown)
1215 if (c2 == ctype_float)
1217 if (ibf == ctype_unknown)
1219 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1224 else if (c2 == ctype_char)
1226 if (ibc == ctype_unknown)
1228 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1240 if (c2 == ctype_bool)
1242 if (ivb == ctype_unknown)
1244 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1249 else if (c2 == ctype_float)
1251 if (ivf == ctype_unknown)
1253 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1265 if (c2 == ctype_bool)
1267 if (ivbf == ctype_unknown)
1269 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1277 if (c2 == ctype_float)
1279 if (ivbf == ctype_unknown)
1281 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1287 else if (c1 == ctype_char)
1289 if (c2 == ctype_uchar)
1291 if (cuc == ctype_unknown)
1293 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1305 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1311 ctype_isConj (ctype c)
1313 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1317 ctype_getConjA (ctype c)
1319 if (!ctype_isConj (c))
1320 llbuglit ("ctype_getConjA: not a conj");
1321 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1325 ctype_getConjB (ctype c)
1327 if (!ctype_isConj (c))
1328 llbuglit ("ctype_getConjB: not a conj");
1329 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1333 ctype_isExplicitConj (ctype c)
1335 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1338 /** << need to fix resolveConj >> **/
1341 ** structs and unions
1345 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1349 DPRINTF (("Creating a struct: %s / %s",
1350 n, uentryList_unparse (f)));
1352 ct = cttable_addComplex (ctbase_createStruct (n, f));
1353 DPRINTF (("ct: %s", ctype_unparse (ct)));
1358 ctype_getFields (ctype c)
1360 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1364 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1368 ret = cttable_addComplex (ctbase_createUnion (n, f));
1375 ** if ctype's are same, definite match.
1376 ** else, need to call ctbase_match.
1378 ** if necessary context can memoize matches
1382 quickMatch (ctype c1, ctype c2)
1391 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1395 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1397 if (quickMatch (c1, c2))
1402 if (ctype_isElips (c1) || ctype_isElips (c2))
1408 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1414 ctype_sameName (ctype c1, ctype c2)
1416 if (quickMatch (c1, c2))
1419 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1423 ctype_almostEqual (ctype c1, ctype c2)
1425 if (ctype_equal (c1, c2))
1431 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1436 ctype_matchDef (ctype c1, ctype c2)
1438 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1440 if (quickMatch (c1, c2))
1443 if (ctype_isElips (c1))
1444 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1446 if (ctype_isElips (c2))
1447 return (ctype_isUnknown (c2));
1450 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1453 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1454 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1455 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1460 bool ctype_match (ctype c1, ctype c2)
1462 if (quickMatch (c1, c2))
1465 if (ctype_isElips (c1))
1466 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1468 if (ctype_isElips (c2))
1469 return (ctype_isUnknown (c2));
1471 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1475 ctype_forceMatch (ctype c1, ctype c2)
1477 if (quickMatch (c1, c2))
1480 if (ctype_isElips (c1))
1481 return (ctype_isElips (c2));
1483 if (ctype_isElips (c2))
1487 /* The call forceMatch may modify the observer params, but, we don't care. */
1488 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1493 ctype_matchArg (ctype c1, ctype c2)
1495 if (quickMatch (c1, c2))
1501 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1506 ** simple ctype_is operations.
1507 ** DO NOT use real type of c, only direct type.
1511 ** ctype_isVoidPointer
1517 ctype_isVoidPointer (ctype c)
1519 if (ctype_isComplex (c))
1521 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1523 if (ctype_isConj (c))
1525 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1526 ctype_isVoidPointer (ctype_getConjB (c)));
1530 return (c == ctype_voidPointer
1531 || (ctype_isRealPointer (c)
1532 && ctype_isVoid (ctype_baseArrayPtr (c))));
1539 ** true for C and LCL pointers
1543 ctype_isPointer (ctype c)
1545 if (ctype_isElips (c)) return FALSE;
1547 if (ctype_isComplex (c))
1549 ctbase ctb = ctype_getCtbaseSafe (c);
1550 bool res = ctbase_isPointer (ctb);
1556 bool res = ctentry_isPointer (ctype_getCtentry (c));
1565 ** true for C and LCL array's
1569 ctype_isArray (ctype c)
1571 if (ctype_isElips (c)) return FALSE;
1573 if (ctype_isComplex (c))
1574 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1576 return (ctentry_isArray (ctype_getCtentry (c)));
1579 bool ctype_isIncompleteArray (ctype c)
1581 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1584 bool ctype_isFixedArray (ctype c)
1586 if (ctype_isElips (c)) return FALSE;
1588 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
1592 ctype_isArrayPtr (ctype c)
1594 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1598 ctype_typeId (ctype c)
1600 return (ctbase_typeId (ctype_getCtbase (c)));
1604 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1606 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1607 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1611 ctype_unparse (ctype c)
1613 if (ctype_isElips (c))
1615 return cstring_makeLiteralTemp ("...");
1617 else if (ctype_isMissingParamsMarker (c))
1619 return cstring_makeLiteralTemp ("-");
1624 return (ctentry_doUnparse (ctype_getCtentry (c)));
1630 ctype_unparseSafe (ctype c)
1632 if (ctype_isElips (c))
1634 return cstring_makeLiteralTemp ("...");
1636 else if (ctype_isMissingParamsMarker (c))
1638 return cstring_makeLiteralTemp ("-");
1644 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1646 ctentry cte = ctype_getCtentry (c);
1648 if (cstring_isDefined (cte->unparse))
1650 return (cte->unparse);
1654 ret = message ("[%d]", (int) c);
1655 cstring_markOwned (ret);
1661 ctype_unparseDeep (ctype c)
1663 if (ctype_isElips (c))
1665 return cstring_makeLiteralTemp ("...");
1667 if (ctype_isMissingParamsMarker (c))
1669 return cstring_makeLiteralTemp ("-");
1672 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1676 ctype_undump (char **c)
1678 return ((ctype) getInt (c)); /* check its valid? */
1682 ctype_dump (ctype c)
1684 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1688 /* Handle invalid types in a kludgey way. */
1689 return (message ("0"));
1694 cstring tname = usymtab_getTypeEntryName
1695 (usymtab_convertId (ctype_typeId (c)));
1697 if (cstring_equal (tname, context_getBoolName ()))
1699 cstring_free (tname);
1700 return (message ("%d", ctype_bool));
1703 cstring_free (tname);
1706 DPRINTF (("Returning: %d", c));
1707 return (message ("%d", c));
1711 ctype_getBaseType (ctype c)
1713 ctentry cte = ctype_getCtentry (c);
1715 switch (ctentry_getKind (cte))
1718 llcontbuglit ("ctype_getBaseType: unknown ctype"); break;
1720 llcontbuglit ("ctype_getBaseType: invalid ctype"); break;
1725 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1728 ctbase ctb = cte->ctbase;
1730 if (ctbase_isDefined (ctb))
1748 return (ctype_getBaseType (ctb->contents.base));
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));
1761 llbuglit ("ctype_newBase: bad case");
1763 llcontbuglit ("ctype_getBaseType: unreachable code");
1764 return ((ctype)NULL);
1768 ctype_adjustPointers (int np, ctype c)
1771 if (ctype_isFunction (c))
1773 c = ctype_makeParamsFunction
1774 (ctype_adjustPointers (np, ctype_returnValue (c)),
1775 uentryList_copy (ctype_argsFunction (c)));
1779 /* fix this should not use getBaseType ??? */
1780 ctype cb = ctype_getBaseType (c);
1784 cb = ctype_makePointer (cb);
1787 c = ctype_newBase (c, cb);
1795 ctype_elist (ctype c)
1797 return (ctbase_elist (ctype_getCtbase (c)));
1801 ctype_isFirstVoid (ctype c)
1803 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
1807 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
1809 return (cttable_addComplex (ctbase_createEnum (tag, el)));
1813 ctype_isEnum (ctype c)
1815 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
1819 ctype_enumTag (ctype c)
1821 llassert (ctype_isEnum (c));
1823 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
1827 ctype_isStruct (ctype c)
1829 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
1833 ctype_isUnion (ctype c)
1835 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
1839 ctype_resolveNumerics (ctype c1, ctype c2)
1842 ** returns longest type of c1 and c2
1845 if (c1 == c2) return c1;
1847 c1 = ctype_realType (c1);
1848 c2 = ctype_realType (c2);
1850 if (ctype_isEnum (c1)) c1 = ctype_unknown;
1851 if (ctype_isEnum (c2)) c2 = ctype_int;
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;
1862 if (ctype_isKnown (c1)) return c1;
1867 ctype_isStructorUnion (ctype c)
1869 return (ctype_isStruct (c) || ctype_isUnion (c));
1873 ctype_fixArrayPtr (ctype c)
1875 if (ctype_isArray (c))
1877 return (ctype_makePointer (ctype_baseArrayPtr (c)));
1884 ** createUnnamedStruct/Union
1886 ** check if it corresponds to an existing LCL-specified unnamed struct
1887 ** otherwise, give it a new tag
1891 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
1893 ctype ret = usymtab_structFieldsType (f);
1895 if (ctype_isDefined (ret))
1897 uentryList_free (f);
1902 cstring ft = fakeTag ();
1903 ctype ct = ctype_createStruct (cstring_copy (ft), f);
1904 uentry ue = uentry_makeStructTagLoc (ft, ct);
1906 usymtab_supGlobalEntry (ue);
1914 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
1916 ctype ret = usymtab_unionFieldsType (f);
1918 if (ctype_isDefined (ret))
1920 uentryList_free (f);
1925 cstring ft = fakeTag ();
1926 ctype ct = ctype_createUnion (cstring_copy (ft), f);
1927 uentry ue = uentry_makeUnionTagLoc (ft, ct);
1929 usymtab_supGlobalEntry (ue);
1936 ctype_createForwardStruct (cstring n)
1938 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
1939 ctype ct = usymtab_supForwardTypeEntry (ue);
1946 ctype_createForwardUnion (cstring n)
1948 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
1949 ctype ct = usymtab_supForwardTypeEntry (ue);
1956 ctype_removePointers (ctype c)
1960 while (ctype_isArrayPtr (c))
1963 c = ctype_baseArrayPtr (c);
1964 llassert (c != oldc);
1970 bool ctype_isMutable (ctype t)
1974 return (uentry_isMutableDatatype
1975 (usymtab_getTypeEntry (ctype_typeId (t))));
1979 return (ctype_isPointer (ctype_realType (t)));
1983 bool ctype_isRefCounted (ctype t)
1987 return (uentry_isRefCountedDatatype
1988 (usymtab_getTypeEntry (ctype_typeId (t))));
1994 bool ctype_isVisiblySharable (ctype t)
1996 if (ctype_isUnknown (t)) return TRUE;
1998 if (ctype_isConj (t))
2000 return (ctype_isVisiblySharable (ctype_getConjA (t))
2001 || ctype_isVisiblySharable (ctype_getConjB (t)));
2004 if (ctype_isMutable (t))
2008 ctype rt = ctype_realType (t);
2016 return ctype_isVisiblySharable (rt);
2029 /* Replaced by ctype_isMutable (more sensible) */
2030 bool ctype_canAlias (ctype ct)
2032 /* can ct refer to memory locations?
2033 ** ==> a pointer or a mutable abstract type
2037 ctype tr = ctype_realType (ct);
2039 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2044 ** c1 is the dominant type; c2 is the modifier type
2046 ** eg. double + long int => long double
2049 ctype ctype_combine (ctype dominant, ctype modifier)
2051 DPRINTF (("Combine: %s + %s",
2052 ctype_unparse (dominant),
2053 ctype_unparse (modifier)));
2055 if (ctype_isConj (dominant))
2059 if (ctype_isExplicitConj (dominant))
2061 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2063 ctype_getConjB (dominant));
2067 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2069 ctype_getConjB (dominant));
2075 if (ctype_isUnknown (modifier))
2079 else if (ctype_isUnknown (dominant))
2085 if (ctype_isEnum (dominant)) dominant = ctype_int;
2086 if (ctype_isEnum (modifier)) modifier = ctype_int;
2088 if (modifier == ctype_uint)
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;
2095 /* evs 2000-07-28: added this line */
2096 if (dominant == ctype_llint) return ctype_ullint;
2098 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2100 voptgenerror (FLG_DUPLICATEQUALS,
2101 message ("Duplicate unsigned qualifier"),
2108 voptgenerror (FLG_DUPLICATEQUALS,
2109 message ("Type qualifier unsigned used with %s",
2110 ctype_unparse (dominant)),
2116 else if (modifier == ctype_llint)
2118 if (dominant == ctype_int)
2123 voptgenerror (FLG_DUPLICATEQUALS,
2124 message ("Duplicate long qualifier on non-int"),
2127 else if (modifier == ctype_lint)
2129 if (dominant == ctype_int) return ctype_lint;
2130 if (dominant == ctype_uint) return ctype_ulint;
2131 if (dominant == ctype_double) return ctype_ldouble;
2133 if (dominant == ctype_lint || dominant == ctype_ulint
2134 || dominant == ctype_sint || dominant == ctype_usint
2135 || dominant == ctype_ldouble)
2137 if (dominant == ctype_lint)
2139 /* long long not supported by ANSI */
2143 if (dominant == ctype_sint || dominant == ctype_usint)
2145 if (!context_getFlag (FLG_IGNOREQUALS))
2147 llerrorlit (FLG_SYNTAX,
2148 "Contradictory long and short type qualifiers");
2153 voptgenerror (FLG_DUPLICATEQUALS,
2154 message ("Duplicate long qualifier"),
2161 else if (modifier == ctype_sint)
2163 if (dominant == ctype_int) return ctype_sint;
2164 if (dominant == ctype_uint) return ctype_usint;
2166 if (dominant == ctype_sint || dominant == ctype_usint)
2168 voptgenerror (FLG_DUPLICATEQUALS,
2169 message ("Duplicate short qualifier"),
2173 else if (dominant == ctype_lint)
2175 if (!context_getFlag (FLG_IGNOREQUALS))
2177 llerrorlit (FLG_SYNTAX,
2178 "Contradictory long and short type qualifiers");
2185 if (!context_getFlag (FLG_IGNOREQUALS))
2187 llerror (FLG_SYNTAX,
2188 message ("Type qualifier short used with %s",
2189 ctype_unparse (dominant)));
2195 else if (modifier == ctype_ulint)
2197 if (dominant == ctype_int) return modifier;
2199 if (dominant == ctype_lint || dominant == ctype_ulint)
2201 voptgenerror (FLG_DUPLICATEQUALS,
2202 message ("Duplicate long qualifier"),
2208 if (dominant == ctype_uint || dominant == ctype_usint)
2210 voptgenerror (FLG_DUPLICATEQUALS,
2211 message ("Duplicate unsigned qualifier"),
2217 if (dominant == ctype_sint || dominant == ctype_usint)
2219 if (!context_getFlag (FLG_IGNOREQUALS))
2221 llerrorlit (FLG_SYNTAX,
2222 "Contradictory long and short type qualifiers");
2228 if (!context_getFlag (FLG_IGNOREQUALS))
2230 llerror (FLG_SYNTAX,
2231 message ("Type qualifiers unsigned long used with %s",
2232 ctype_unparse (dominant)));
2237 else if (modifier == ctype_usint)
2239 if (dominant == ctype_int) return modifier;
2241 if (dominant == ctype_sint || dominant == ctype_usint)
2243 voptgenerror (FLG_DUPLICATEQUALS,
2244 message ("Duplicate short qualifier"),
2249 if (dominant == ctype_uint)
2251 voptgenerror (FLG_DUPLICATEQUALS,
2252 message ("Duplicate unsigned qualifier"),
2258 if (dominant == ctype_lint || dominant == ctype_ulint
2259 || dominant == ctype_llint)
2261 if (!context_getFlag (FLG_IGNOREQUALS))
2263 llerrorlit (FLG_SYNTAX,
2264 "Contradictory long and short type qualifiers");
2270 if (!context_getFlag (FLG_IGNOREQUALS))
2272 llerror (FLG_SYNTAX,
2273 message ("Type qualifiers unsigned short used with %s",
2274 ctype_unparse (dominant)));
2288 ctype ctype_resolve (ctype c)
2290 if (ctype_isUnknown (c)) return ctype_int;
2294 ctype ctype_fromQual (qual q)
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;
2301 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2302 return ctype_unknown;
2306 ctype_isAnyFloat (ctype c)
2308 return (cprim_isAnyReal (ctype_toCprim (c)));
2312 ctype_isUnsigned (ctype c)
2314 if (ctype_isConj (c))
2315 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2316 ctype_isUnsigned (ctype_getConjB (c)));
2318 return (c == ctype_uint || c == ctype_uchar
2319 || c == ctype_usint || c == ctype_ulint
2320 || c == ctype_unsignedintegral);
2324 ctype_isLong (ctype c)
2326 if (ctype_isConj (c))
2327 return (ctype_isLong (ctype_getConjA (c)) ||
2328 ctype_isLong (ctype_getConjB (c)));
2330 return (c == ctype_lint || c == ctype_ulint);
2334 ctype_isShort (ctype c)
2336 if (ctype_isConj (c))
2337 return (ctype_isShort (ctype_getConjA (c)) ||
2338 ctype_isShort (ctype_getConjB (c)));
2340 return (c == ctype_sint || c == ctype_usint);
2344 ctype_isStackAllocated (ctype c)
2346 ctype ct = ctype_realType (c);
2348 if (ctype_isConj (ct))
2349 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2350 ctype_isStackAllocated (ctype_getConjB (ct)));
2352 return (ctype_isArray (c) || ctype_isSU (c));
2355 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2357 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2360 static bool ctype_isLonger (ctype c1, ctype c2)
2362 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2363 || (ctype_isLong (c1) && !ctype_isLong (c2))
2364 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2368 ctype_widest (ctype c1, ctype c2)
2370 if (ctype_isMoreUnsigned (c2, c1)
2371 || ctype_isLonger (c2, c1))
2382 /* requires that the type is an fixed array */
2383 /* return the size of the array */
2385 long int ctype_getArraySize (ctype c)
2387 ctentry cte = ctype_getCtentry (c);
2389 llassert ( (ctentry_getKind (cte) == CTK_COMPLEX) || (ctentry_getKind(cte) == CTK_ARRAY) );
2393 llassert (ctbase_isDefined (ctb) );
2395 llassert (ctb->type == CT_FIXEDARRAY);
2397 return (ctb->contents.farray->size);