2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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 splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
27 ** This files implements three types: ctentry, cttable and ctype.
28 ** They should probably be separated soon.
31 # include "splintMacros.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)
111 DPRINTF (("Loading cttable!"));
116 ctype_dumpTable (FILE *f)
118 DPRINTF (("Dumping cttable!"));
123 ctype_unparseTable ()
125 return (cttable_unparse ());
135 ctype_isUserBool (ctype ct)
139 return (usymtab_isBoolType (ctype_typeId (ct)));
146 ctype_createUser (typeId u)
148 /* requires: ctype_createUser (u) is never called more than once for any u. */
150 ctbase ct = ctbase_createUser (u);
151 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ct)));
155 ctype_createAbstract (typeId u)
157 /* requires: ctype_createAbstract (u) is never called more than once for any u. */
158 /* [ tested by cttable_addFullSafe, not really required ] */
160 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u))));
170 ctype_realType (ctype c)
174 if (ctype_isElips (c) || ctype_isMissingParamsMarker (c))
181 r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c)));
184 if (ctype_isManifestBool (r))
186 if (context_canAccessBool ())
188 r = context_boolImplementationType ();
196 ctype_isSimple (ctype c)
198 return (! (ctype_isPointer (c)
200 || ctype_isFunction (c)));
204 ctype_forceRealType (ctype c)
210 r = uentry_getForceRealType (usymtab_getTypeEntry (ctype_typeId (c)));
217 ctype_realishType (ctype c)
221 if (ctype_isManifestBool (c))
227 ctype r = uentry_getRealType (usymtab_getTypeEntry
239 return (!ctype_isUnknown (c)
240 && ctbase_isUA (ctype_getCtbase (c)));
244 ctype_isUser (ctype c)
246 return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c)));
250 ctype_isAbstract (ctype c)
252 return (!ctype_isUnknown (c)
253 && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
255 (ctype_isAbstract (ctype_getConjA (c))
256 || ctype_isAbstract (ctype_getConjB (c))))));
260 ctype_isImmutableAbstract (ctype t)
262 return (ctype_isAbstract (t) && !ctype_isMutable (t));
266 ctype_isRealAbstract (ctype c)
268 return (ctype_isAbstract (ctype_realType (c)) ||
270 (ctype_isRealAbstract (ctype_getConjA (c)) ||
271 ctype_isRealAbstract (ctype_getConjB (c)))));
275 ** primitive creators
279 ** createPrim not necessary --- subsumed by ctype_int, etc.
283 ** ctbase_unknown --- removed argument
288 ** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
292 ctype_makePointer (ctype c)
298 else if (c == ctype_void)
300 return ctype_voidPointer;
304 ctentry cte = ctype_getCtentry (c);
305 ctype clp = ctentry_getPtr (cte);
307 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
309 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
310 ctentry_setPtr (cte, cnew);
320 ctype ctype_makeFixedArray (ctype c, size_t size)
323 res = cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c);
327 ctype ctype_makeInnerFixedArray (ctype c, size_t size)
331 if (ctype_isFixedArray (c))
333 ctype cb = ctype_baseArrayPtr (c);
334 size_t osize = ctype_getArraySize (c);
336 res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize);
338 else if (ctype_isArray (c))
340 ctype cb = ctype_baseArrayPtr (c);
342 res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
346 res = ctype_makeFixedArray (c, size);
349 DPRINTF (("Make inner fixed array: %s", ctype_unparse (res)));
353 ctype ctype_makeInnerArray (ctype c)
357 DPRINTF (("Make inner array: %s", ctype_unparse (c)));
359 if (ctype_isFixedArray (c))
361 ctype cb = ctype_baseArrayPtr (c);
362 size_t osize = ctype_getArraySize (c);
364 res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize);
368 res = ctype_makeArray (c);
371 DPRINTF (("Make inner array: %s", ctype_unparse (res)));
376 ctype_makeArray (ctype c)
378 ctentry cte = ctype_getCtentry (c);
379 ctype clp = ctentry_getArray (cte);
381 DPRINTF (("Make array: %s", ctype_unparse (c)));
383 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
385 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
386 ctentry_setArray (cte, cnew);
396 ** requires c is a pointer of array
400 ctype_baseArrayPtr (ctype c)
402 ctentry cte = ctype_getCtentry (ctype_realType (c));
404 if (ctype_isConj (c))
406 if (ctype_isAP (ctype_getConjA (c)))
408 if (ctype_isAP (ctype_getConjB (c)))
410 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
411 ctype_baseArrayPtr (ctype_getConjB (c))));
415 return (ctype_baseArrayPtr (ctype_getConjA (c)));
420 return (ctype_baseArrayPtr (ctype_getConjB (c)));
423 else if (ctype_isInt (c)) /* could be NULL */
425 return ctype_unknown;
429 ctype clp = ctentry_getBase (cte);
431 if (ctype_isBroken (clp))
433 llbuglit ("ctype_baseArrayPtr: bogus ctype");
445 ctype_makeWideString ()
447 static ctype res = ctype_unknown;
449 if (ctype_isUnknown (res))
453 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
455 wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
462 res = ctype_makePointer (wchart);
469 ctype_isWideString (ctype c)
471 if (ctype_isPointer (c))
473 ctype ct = ctype_baseArrayPtr (c);
475 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
477 return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
491 ctype_getReturnType (ctype c)
493 if (ctype_isUnknown (c))
495 return ctype_unknown;
498 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
502 ** must be a shared pointer
505 /*@observer@*/ uentryList
506 ctype_argsFunction (ctype c)
508 if (ctype_isUnknown (c))
510 return uentryList_undefined;
513 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
517 ** Returns type with base type p and compound types from c.
519 ** i.e., c = char *[]; p = int
524 ctype_newBase (ctype c, ctype p)
526 return (ctbase_newBase (c, p));
530 ctype_sameAltTypes (ctype c1, ctype c2)
535 llassert (ctype_isConj (c1) && ctype_isConj (c2));
537 c1a = ctype_getConjA (c1);
538 c2a = ctype_getConjA (c2);
540 c1b = ctype_getConjB (c1);
541 c2b = ctype_getConjB (c2);
543 if (ctype_compare (c1a, c2a) == 0)
545 if (ctype_compare (c1b, c2b) == 0)
551 if (ctype_isConj (c1b) && ctype_isConj (c2b))
553 return ctype_sameAltTypes (c1b, c2b);
563 if (ctype_compare (c1a, c2b) == 0)
565 if (ctype_compare (c1b, c2a) == 0)
571 if (ctype_isConj (c1b) && ctype_isConj (c2a))
573 return ctype_sameAltTypes (c1b, c2a);
589 ctype_compare (ctype c1, ctype c2)
594 if (ctype_isUnknown (c1))
596 if (ctype_isUnknown (c2))
606 if (ctype_isUnknown (c2))
611 /* Can't get entries for special ctypes (elips marker) */
613 if (ctype_isElips (c1) || ctype_isElips (c2)
614 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
615 return int_compare (c1, c2);
618 ce1 = ctype_getCtentry (c1);
619 ce2 = ctype_getCtentry (c2);
621 if (ctentry_isComplex (ce1))
623 if (ctentry_isComplex (ce2))
625 return (ctbase_compare (ctype_getCtbase (c1),
626 ctype_getCtbase (c2), FALSE));
633 else if (ctentry_isComplex (ce2))
639 return (int_compare (c1, c2));
648 ** makeFunction: pointer to function returning base
652 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
654 uentryList_fixImpParams (p);
655 return (ctype_makeFunction (base, p));
659 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
661 uentryList_fixImpParams (p);
662 return (ctbase_makeNFFunction (base, p));
666 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
669 ret = ctbase_makeFunction (base, p);
673 ctype ctype_expectFunction (ctype c)
675 /* handle parenthesized declarations */
679 c = ctype_makePointer (c);
682 return (cttable_addComplex (ctbase_expectFunction (c)));
685 ctype ctype_dontExpectFunction (ctype c)
687 ctbase ctb = ctype_getCtbase (c);
692 c = ctype_makePointer (c);
696 return (ctbase_getExpectFunction (ctb));
700 ** makeRealFunction: function returning base
703 ctype ctype_makeRawFunction (ctype base, uentryList p)
705 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
713 **** this is very poorly defined
715 **** need to unify function/function pointer meaning
719 ctype_isFunction (ctype c)
721 if (ctype_isKnown (c) && ctype_isDefined (c))
723 return (ctbase_isFunction (ctype_getCtbase (c)));
732 ctype_isExpFcn (ctype c)
734 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
738 ctype_isVoid (ctype c)
740 return (c == CTX_VOID);
744 ctype_isArbitraryIntegral (ctype c)
746 ctype cr = ctype_realType (c);
748 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
749 || cr == ctype_signedintegral);
753 ctype_isUnsignedIntegral (ctype c)
755 ctype cr = ctype_realType (c);
757 return (cr == ctype_unsignedintegral);
761 ctype_isSignedIntegral (ctype c)
763 ctype cr = ctype_realType (c);
765 return (cr == ctype_signedintegral);
769 ctype_isInt (ctype c)
771 cprim cp = ctype_toCprim (c);
773 return (c == ctype_unknown || cprim_isAnyInt (cp)
774 || (cprim_isAnyChar (cp) && context_msgCharInt ())
775 || (c == ctype_bool && context_msgBoolInt ())
776 || (ctype_isEnum (c) && context_msgEnumInt ()));
780 ctype_isRegularInt (ctype c)
782 cprim cp = ctype_toCprim (c);
784 return (c == ctype_unknown
785 || cprim_closeEnough (cprim_int, cp)
786 || (cprim_isAnyChar (cp) && context_msgCharInt ())
787 || (c == ctype_bool && context_msgBoolInt ())
788 || (ctype_isEnum (c) && context_msgEnumInt ()));
792 ctype_isString (ctype c)
794 return (c == ctype_string
795 || (ctype_isPointer (c)
796 && ctype_isChar (ctype_baseArrayPtr (c))));
800 ctype_isChar (ctype c)
802 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
803 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
807 ctype_isUnsignedChar (ctype c)
809 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
813 ctype_isSignedChar (ctype c)
815 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
819 ** Returns true if c matches the name -booltype <bool>
823 ctype_isManifestBool (ctype c)
826 ** Changed the meaning of ctype_isBool - evs 2000-07-24
827 ** The old meaning was very convoluted!
830 ** c == CTX_BOOL - its a direct bool
831 ** c is a user/abstract type matching the bool name
832 ** (should never occur?)
835 if (ctype_isDirectBool (c)) {
837 } else if (ctype_isUA (c)) {
838 return ctype_isUserBool (c);
845 ctype_isBool (ctype c)
848 ** Changed the meaning of ctype_isBool - evs 2000-07-24
849 ** The old meaning was very convoluted!
852 ** its a manifest bool
853 ** +boolint and ctype_isInt (c)
856 if (ctype_isManifestBool (c)) {
858 } else if (context_msgBoolInt ()) {
859 return ctype_isInt (c);
865 if (context_getFlag (FLG_ABSTRACTBOOL))
867 if (typeId_isInvalid (boolType))
869 boolType = usymtab_getTypeId (context_getBoolName ());
872 if (context_hasAccess (boolType))
874 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
875 || (context_msgBoolInt ()
877 || (c == CTX_CHAR && context_msgCharInt ()))))
882 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
883 || (context_msgBoolInt ()
884 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
889 ctype_isDirectBool (ctype c)
891 return (c == CTX_BOOL);
895 ctype_isReal (ctype c)
897 return (cprim_isAnyReal (ctype_toCprim (c)));
901 ctype_isFloat (ctype c)
903 return (c == ctype_float);
907 ctype_isDouble (ctype c)
909 return (c == ctype_double || c == ctype_ldouble);
913 ctype_isSigned (ctype c)
915 return (!ctype_isUnsigned (c));
919 ctype_isNumeric (ctype c)
921 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
922 /* evans 2001-10-05: added this: */
923 || ctype_isArbitraryIntegral (c));
930 ** work on actual type in current context
934 ctype_isRealNumeric (ctype c)
936 if (ctype_isPlain (c))
937 return (ctype_isNumeric (ctype_realType (c)));
938 if (ctype_isConj (c))
939 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
940 ctype_isRealNumeric (ctype_getConjB (c)));
946 ctype_isRealInt (ctype c)
948 if (ctype_isPlain (c))
949 return (ctype_isInt (ctype_realType (c)));
950 else if (ctype_isConj (c))
951 return (ctype_isRealInt (ctype_getConjA (c)) ||
952 ctype_isRealInt (ctype_getConjB (c)));
955 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
961 ctype_isRealVoid (ctype c)
963 if (ctype_isPlain (c))
965 return (ctype_isVoid (ctype_realType (c)));
967 else if (ctype_isConj (c))
969 return (ctype_isRealVoid (ctype_getConjA (c)) ||
970 ctype_isRealVoid (ctype_getConjB (c)));
979 ctype_isRealBool (ctype c)
981 if (ctype_isPlain (c))
983 return (ctype_isBool (ctype_realishType (c)));
985 else if (ctype_isConj (c))
987 return (ctype_isRealBool (ctype_getConjA (c)) ||
988 ctype_isRealBool (ctype_getConjB (c)));
997 ctype_isRealPointer (ctype c)
999 if (ctype_isConj (c))
1000 return (ctype_isRealPointer (ctype_getConjA (c)) ||
1001 ctype_isRealPointer (ctype_getConjB (c)));
1002 return (ctype_isPointer (ctype_realType (c)));
1006 ctype_isRealSU (ctype c)
1008 if (ctype_isConj (c))
1010 return (ctype_isRealSU (ctype_getConjA (c)) ||
1011 ctype_isRealSU (ctype_getConjB (c)));
1014 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
1015 return (ctype_isStructorUnion (ctype_realType (c)));
1019 ctype_isRealArray (ctype c)
1021 if (ctype_isConj (c))
1022 return (ctype_isRealArray (ctype_getConjA (c)) ||
1023 ctype_isRealArray (ctype_getConjB (c)));
1024 return (ctype_isArray (ctype_realType (c)));
1028 ctype_isRealAP (ctype c)
1030 if (ctype_isConj (c))
1031 return (ctype_isRealAP (ctype_getConjA (c)) ||
1032 ctype_isRealAP (ctype_getConjB (c)));
1033 return (ctype_isAP (ctype_realType (c)));
1037 ctype_isRealFunction (ctype c)
1039 if (ctype_isConj (c))
1040 return (ctype_isRealFunction (ctype_getConjA (c)) ||
1041 ctype_isRealFunction (ctype_getConjB (c)));
1042 return (ctype_isFunction (ctype_realType (c)));
1046 ctype_isDirectInt (ctype c)
1048 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
1052 ** forceful predicates
1054 ** take *ctype; if its a conjunct, and there is a match replace with match only.
1055 ** if both match, still conjunct
1059 ctype_isForcePred (ctype * c, bool (pred) (ctype))
1061 /*drl bee: pbr */ if (ctype_isConj (*c))
1063 ctype cbr = ctype_getConjA (*c);
1065 /*drl bee: si*/ if ((*pred) (cbr))
1067 if ((*pred) (ctype_getConjB (*c)))
1080 if ((*pred) (cbr = ctype_getConjB (*c)))
1088 return ((*pred) (*c));
1092 ctype_isForceRealNumeric (ctype * c)
1094 return (ctype_isForcePred (c, ctype_isRealNumeric));
1098 ctype_isForceRealInt (ctype * c)
1100 return (ctype_isForcePred (c, ctype_isRealInt));
1104 ctype_isForceRealBool (ctype * c)
1106 return (ctype_isForcePred (c, ctype_isRealBool));
1112 ** save int/char, int/bool, other random conjuncts
1116 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
1118 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
1122 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1130 return (ctype_makeExplicitConj (c1, c2));
1134 return (ctype_makeConj (c1, c2));
1140 ctype_makeExplicitConj (ctype c1, ctype c2)
1142 if (ctype_isAnytype (c1) || ctype_isAnytype (c2))
1144 return ctype_makeAnytype ();
1146 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1148 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
1150 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1152 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1154 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
1156 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1160 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1164 static ctype ic = ctype_unknown; /* int | char */
1165 static ctype ib = ctype_unknown; /* int | bool */
1166 static ctype ifl = ctype_unknown; /* int | float */
1167 static ctype ibf = ctype_unknown; /* int | bool | float */
1168 static ctype ibc = ctype_unknown; /* int | bool | char */
1169 static ctype iv = ctype_unknown; /* int | void * */
1170 static ctype ivf = ctype_unknown; /* int | void * | float */
1171 static ctype ivb = ctype_unknown; /* int | void * | bool */
1172 static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1173 static ctype cuc = ctype_unknown; /* char | unsigned char */
1175 static ctype cany = ctype_unknown;
1178 ctype_makeAnytype ()
1180 if (cany == ctype_unknown)
1182 cany = ctype_makeConj (ctype_unknown, ctype_dne);
1183 llassert (ctype_isAnytype (cany));
1186 DPRINTF (("make anytype: %s", ctype_unparse (cany)));
1191 ctype_isAnytype (ctype c)
1197 ctype_recordConj (ctype c)
1201 llassert (ctype_isConj (c));
1203 c1 = ctype_getConjA (c);
1204 c2 = ctype_getConjB (c);
1207 if (c2 == ctype_int && c1 != ctype_int)
1217 if (c1 == ctype_int)
1219 if (c2 == ctype_char)
1221 llassert (ic == ctype_unknown);
1224 else if (c2 == ctype_bool)
1226 llassert (ib == ctype_unknown);
1229 else if (c2 == ctype_float)
1231 llassert (ifl == ctype_unknown);
1234 else if (c2 == CTP_VOID)
1236 llassert (iv == ctype_unknown);
1244 else if (c1 == ib && ib != ctype_unknown)
1246 if (c2 == ctype_float)
1248 llassert (ibf == ctype_unknown);
1251 else if (c2 == ctype_char)
1253 llassert (ibc == ctype_unknown);
1263 if (c2 == ctype_bool)
1265 llassert (ivb == ctype_unknown);
1268 else if (c2 == ctype_float)
1270 llassert (ivf == ctype_unknown);
1280 if (c2 == ctype_bool)
1282 llassert (ivbf == ctype_unknown);
1288 if (c2 == ctype_float)
1290 llassert (ivbf == ctype_unknown);
1294 else if (c1 == ctype_char)
1296 if (c2 == ctype_uchar)
1298 llassert (cuc == ctype_unknown);
1310 ctype_makeConj (ctype c1, ctype c2)
1312 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1314 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1316 if (ctype_isAnytype (c1))
1320 else if (ctype_isAnytype (c2))
1324 else if (ctype_isUnknown (c1))
1328 else if (ctype_isUnknown (c2))
1332 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1334 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
1335 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1337 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1339 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
1340 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1344 if (ctype_isManifestBool (c1))
1349 if (ctype_isManifestBool (c2))
1354 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1356 c1 = ctype_voidPointer;
1359 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1361 c2 = ctype_voidPointer;
1365 ** Ouch, can't do this. unsigned, etc. modifiers might
1366 ** apply to wrong type!
1368 ** if (c2 == ctype_int && c1 != ctype_int)
1379 if (c1 == ctype_int)
1381 if (c2 == ctype_char)
1383 if (ic == ctype_unknown)
1385 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1390 else if (c2 == ctype_bool)
1392 if (ib == ctype_unknown)
1394 ib = cttable_addComplex
1395 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1400 else if (c2 == ctype_float)
1402 if (ifl == ctype_unknown)
1404 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1411 if (c2 == ctype_voidPointer)
1413 if (iv == ctype_unknown)
1415 iv = cttable_addComplex
1416 (ctbase_makeConj (ctype_int,
1425 else if (c1 == ib && ib != ctype_unknown)
1427 if (c2 == ctype_float)
1429 if (ibf == ctype_unknown)
1431 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1436 else if (c2 == ctype_char)
1438 if (ibc == ctype_unknown)
1440 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1452 if (c2 == ctype_bool)
1454 if (ivb == ctype_unknown)
1456 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1461 else if (c2 == ctype_float)
1463 if (ivf == ctype_unknown)
1465 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1477 if (c2 == ctype_bool)
1479 if (ivbf == ctype_unknown)
1481 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1489 if (c2 == ctype_float)
1491 if (ivbf == ctype_unknown)
1493 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1499 else if (c1 == ctype_char)
1501 if (c2 == ctype_uchar)
1503 if (cuc == ctype_unknown)
1505 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1516 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1522 ctype_isConj (ctype c)
1524 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1528 ctype_getConjA (ctype c)
1530 if (!ctype_isConj (c))
1531 llbuglit ("ctype_getConjA: not a conj");
1532 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1536 ctype_getConjB (ctype c)
1538 if (!ctype_isConj (c))
1539 llbuglit ("ctype_getConjB: not a conj");
1540 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1544 ctype_isExplicitConj (ctype c)
1546 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1549 /** << need to fix resolveConj >> **/
1552 ** structs and unions
1556 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1560 DPRINTF (("Creating a struct: %s / %s",
1561 n, uentryList_unparse (f)));
1563 ct = cttable_addComplex (ctbase_createStruct (n, f));
1564 DPRINTF (("ct: %s", ctype_unparse (ct)));
1569 ctype_getFields (ctype c)
1571 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1575 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1579 ret = cttable_addComplex (ctbase_createUnion (n, f));
1586 ** if ctype's are same, definite match.
1587 ** else, need to call ctbase_match.
1589 ** if necessary context can memoize matches
1593 quickMatch (ctype c1, ctype c2)
1602 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1606 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1608 if (quickMatch (c1, c2))
1613 if (ctype_isElips (c1) || ctype_isElips (c2))
1619 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1625 ctype_sameName (ctype c1, ctype c2)
1627 if (quickMatch (c1, c2))
1630 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1634 ctype_almostEqual (ctype c1, ctype c2)
1636 if (ctype_equal (c1, c2))
1642 if (ctype_isUnknown (c1))
1644 return ctype_isUnknown (c2);
1646 else if (ctype_isUnknown (c2))
1652 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1658 ctype_matchDef (ctype c1, ctype c2)
1660 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1662 if (quickMatch (c1, c2))
1665 if (ctype_isElips (c1))
1666 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1668 if (ctype_isElips (c2))
1670 return (ctype_isUnknown (c2));
1674 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1677 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1678 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1679 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1684 bool ctype_match (ctype c1, ctype c2)
1686 if (quickMatch (c1, c2))
1689 if (ctype_isElips (c1))
1690 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1692 if (ctype_isElips (c2))
1693 return (ctype_isUnknown (c2));
1695 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1699 ctype_forceMatch (ctype c1, ctype c2)
1701 if (quickMatch (c1, c2))
1704 if (ctype_isElips (c1))
1705 return (ctype_isElips (c2));
1707 if (ctype_isElips (c2))
1711 /* The call forceMatch may modify the observer params, but, we don't care. */
1712 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1717 ctype_matchArg (ctype c1, ctype c2)
1719 if (quickMatch (c1, c2))
1725 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1730 ** simple ctype_is operations.
1731 ** DO NOT use real type of c, only direct type.
1735 ** ctype_isVoidPointer
1741 ctype_isVoidPointer (ctype c)
1743 if (ctype_isComplex (c))
1745 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1747 if (ctype_isConj (c))
1749 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1750 ctype_isVoidPointer (ctype_getConjB (c)));
1754 return (c == ctype_voidPointer
1755 || (ctype_isRealPointer (c)
1756 && ctype_isVoid (ctype_baseArrayPtr (c))));
1763 ** true for C and LCL pointers
1767 ctype_isPointer (ctype c)
1769 if (ctype_isElips (c)) return FALSE;
1771 if (ctype_isComplex (c))
1773 ctbase ctb = ctype_getCtbaseSafe (c);
1774 bool res = ctbase_isPointer (ctb);
1780 bool res = ctentry_isPointer (ctype_getCtentry (c));
1789 ** true for C and LCL array's
1793 ctype_isArray (ctype c)
1795 if (ctype_isElips (c)) return FALSE;
1797 if (ctype_isComplex (c))
1798 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1800 return (ctentry_isArray (ctype_getCtentry (c)));
1803 bool ctype_isIncompleteArray (ctype c)
1805 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1809 ctype_isArrayPtr (ctype c)
1811 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1815 ctype_typeId (ctype c)
1817 return (ctbase_typeId (ctype_getCtbase (c)));
1821 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1823 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1825 if (ctype_isUnknown (c))
1827 return message ("? %q", name);
1831 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1836 ctype_unparse (ctype c)
1838 if (ctype_isElips (c))
1840 return cstring_makeLiteralTemp ("...");
1842 else if (ctype_isMissingParamsMarker (c))
1844 return cstring_makeLiteralTemp ("-");
1846 else if (ctype_isAnytype (c))
1848 return cstring_makeLiteralTemp ("<any>");
1850 else if (ctype_isUnknown (c))
1852 return cstring_makeLiteralTemp ("?");
1857 return (ctentry_doUnparse (ctype_getCtentry (c)));
1863 ctype_unparseSafe (ctype c)
1865 if (ctype_isElips (c))
1867 return cstring_makeLiteralTemp ("...");
1869 else if (ctype_isMissingParamsMarker (c))
1871 return cstring_makeLiteralTemp ("-");
1877 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1879 ctentry cte = ctype_getCtentry (c);
1881 if (cstring_isDefined (cte->unparse))
1883 return (cte->unparse);
1887 ret = message ("[%d]", (int) c);
1888 cstring_markOwned (ret);
1894 ctype_unparseDeep (ctype c)
1896 if (ctype_isElips (c))
1898 return cstring_makeLiteralTemp ("...");
1900 if (ctype_isMissingParamsMarker (c))
1902 return cstring_makeLiteralTemp ("-");
1905 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1909 ctype_undump (char **c)
1911 return ((ctype) reader_getInt (c)); /* check its valid? */
1915 ctype_dump (ctype c)
1917 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1921 /* Handle invalid types in a kludgey way. */
1922 return (message ("0"));
1927 cstring tname = usymtab_getTypeEntryName
1928 (usymtab_convertId (ctype_typeId (c)));
1930 if (cstring_equal (tname, context_getBoolName ()))
1932 cstring_free (tname);
1933 return (message ("%d", ctype_bool));
1936 cstring_free (tname);
1939 DPRINTF (("Returning: %d", c));
1940 return (message ("%d", c));
1944 ctype_getBaseType (ctype c)
1946 ctentry cte = ctype_getCtentry (c);
1948 switch (ctentry_getKind (cte))
1956 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1959 ctbase ctb = cte->ctbase;
1961 if (ctbase_isDefined (ctb))
1980 return (ctype_getBaseType (ctb->contents.base));
1982 return (ctype_getBaseType (ctb->contents.farray->base));
1983 case CT_CONJ: /* base type of A conj branch? */
1984 return (ctype_getBaseType (ctb->contents.conj->a));
1986 /*@noaccess ctbase@*/
1994 llbuglit ("ctype_newBase: bad case");
1996 llcontbuglit ("ctype_getBaseType: unreachable code");
1997 return ((ctype)NULL);
2001 ctype_adjustPointers (pointers p, ctype c)
2003 int np = pointers_depth (p);
2005 if (ctype_isFunction (c))
2007 c = ctype_makeParamsFunction
2008 (ctype_adjustPointers (p, ctype_getReturnType (c)),
2009 uentryList_copy (ctype_argsFunction (c)));
2013 /* fix this should not use getBaseType ??? */
2014 ctype cb = ctype_getBaseType (c);
2018 cb = ctype_makePointer (cb);
2021 c = ctype_newBase (c, cb);
2029 ctype_elist (ctype c)
2031 return (ctbase_elist (ctype_getCtbase (c)));
2035 ctype_isFirstVoid (ctype c)
2037 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2041 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2043 return (cttable_addComplex (ctbase_createEnum (tag, el)));
2047 ctype_isEnum (ctype c)
2049 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2053 ctype_enumTag (ctype c)
2055 llassert (ctype_isEnum (c));
2057 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2061 ctype_isStruct (ctype c)
2063 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2067 ctype_isUnion (ctype c)
2069 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2073 ctype_resolveNumerics (ctype c1, ctype c2)
2076 ** returns longest type of c1 and c2
2079 if (c1 == c2) return c1;
2081 c1 = ctype_realType (c1);
2082 c2 = ctype_realType (c2);
2084 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2085 if (ctype_isEnum (c2)) c2 = ctype_int;
2087 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2089 /* 2001-06-08: This fix provided by Jim Zelenka. */
2090 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2091 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2093 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2094 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2095 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2096 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2098 /* 2001-06-08: This fix provided by Jim Zelenka. */
2099 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2101 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2103 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2104 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2106 if (ctype_isKnown (c1)) return c1;
2111 ctype_isStructorUnion (ctype c)
2113 return (ctype_isStruct (c) || ctype_isUnion (c));
2117 ctype_fixArrayPtr (ctype c)
2119 if (ctype_isArray (c))
2121 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2128 ** createUnnamedStruct/Union
2130 ** check if it corresponds to an existing LCL-specified unnamed struct
2131 ** otherwise, give it a new tag
2135 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2137 ctype ret = usymtab_structFieldsType (f);
2139 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2141 if (ctype_isDefined (ret))
2143 uentryList_free (f);
2148 cstring ft = fakeTag ();
2149 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2150 uentry ue = uentry_makeStructTagLoc (ft, ct);
2152 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2153 ue = usymtab_supGlobalEntryReturn (ue);
2154 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2162 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2164 ctype ret = usymtab_unionFieldsType (f);
2166 if (ctype_isDefined (ret))
2168 uentryList_free (f);
2173 cstring ft = fakeTag ();
2174 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2175 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2177 usymtab_supGlobalEntry (ue);
2184 ctype_isUnnamedSU (ctype c)
2188 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2197 ctype_createForwardStruct (cstring n)
2199 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2200 ctype ct = usymtab_supForwardTypeEntry (ue);
2207 ctype_createForwardUnion (cstring n)
2209 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2210 ctype ct = usymtab_supForwardTypeEntry (ue);
2217 ctype_createForwardEnum (cstring n)
2219 uentry ue = uentry_makeEnumTag (n, ctype_unknown, fileloc_undefined);
2220 ctype ct = usymtab_supForwardTypeEntry (ue);
2227 ctype_removePointers (ctype c)
2231 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2234 c = ctype_baseArrayPtr (c);
2235 llassert (c != oldc);
2241 bool ctype_isMutable (ctype t)
2245 return (uentry_isMutableDatatype
2246 (usymtab_getTypeEntry (ctype_typeId (t))));
2250 return (ctype_isPointer (ctype_realType (t)));
2251 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2255 bool ctype_isRefCounted (ctype t)
2259 return (uentry_isRefCountedDatatype
2260 (usymtab_getTypeEntry (ctype_typeId (t))));
2266 bool ctype_isVisiblySharable (ctype t)
2268 if (ctype_isUnknown (t)) return TRUE;
2270 if (ctype_isConj (t))
2272 return (ctype_isVisiblySharable (ctype_getConjA (t))
2273 || ctype_isVisiblySharable (ctype_getConjB (t)));
2276 if (ctype_isMutable (t))
2280 ctype rt = ctype_realType (t);
2288 return ctype_isVisiblySharable (rt);
2302 /* Replaced by ctype_isMutable (more sensible) */
2303 bool ctype_canAlias (ctype ct)
2305 /* can ct refer to memory locations?
2306 ** ==> a pointer or a mutable abstract type
2310 ctype tr = ctype_realType (ct);
2312 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2317 ** c1 is the dominant type; c2 is the modifier type
2319 ** eg. double + long int => long double
2322 ctype ctype_combine (ctype dominant, ctype modifier)
2324 DPRINTF (("Combine: %s + %s",
2325 ctype_unparse (dominant),
2326 ctype_unparse (modifier)));
2328 if (ctype_isConj (dominant))
2332 if (ctype_isExplicitConj (dominant))
2334 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2336 ctype_getConjB (dominant));
2340 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2342 ctype_getConjB (dominant));
2348 if (ctype_isUnknown (modifier))
2352 else if (ctype_isUnknown (dominant))
2358 if (ctype_isEnum (dominant)) dominant = ctype_int;
2359 if (ctype_isEnum (modifier)) modifier = ctype_int;
2361 if (modifier == ctype_uint)
2363 if (dominant == ctype_int) return ctype_uint;
2364 if (dominant == ctype_lint) return ctype_ulint;
2365 if (dominant == ctype_sint) return ctype_usint;
2366 if (dominant == ctype_char) return ctype_uchar;
2368 /* evs 2000-07-28: added this line */
2369 if (dominant == ctype_llint) return ctype_ullint;
2371 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2373 voptgenerror (FLG_DUPLICATEQUALS,
2374 message ("Duplicate unsigned qualifier"),
2381 voptgenerror (FLG_DUPLICATEQUALS,
2382 message ("Type qualifier unsigned used with %s",
2383 ctype_unparse (dominant)),
2389 else if (modifier == ctype_llint)
2391 if (dominant == ctype_int)
2396 voptgenerror (FLG_DUPLICATEQUALS,
2397 message ("Duplicate long qualifier on non-int"),
2400 else if (modifier == ctype_lint)
2402 if (dominant == ctype_int) return ctype_lint;
2403 if (dominant == ctype_uint) return ctype_ulint;
2404 if (dominant == ctype_double) return ctype_ldouble;
2406 if (dominant == ctype_lint || dominant == ctype_ulint
2407 || dominant == ctype_sint || dominant == ctype_usint
2408 || dominant == ctype_ldouble)
2410 if (dominant == ctype_lint)
2412 /* long long not supported by ANSI */
2417 if (dominant == ctype_ulint)
2419 /* unsigned long long not supported by ANSI */
2420 return ctype_ullint;
2424 if (dominant == ctype_sint || dominant == ctype_usint)
2426 if (!context_getFlag (FLG_IGNOREQUALS))
2428 llerrorlit (FLG_SYNTAX,
2429 "Contradictory long and short type qualifiers");
2434 voptgenerror (FLG_DUPLICATEQUALS,
2435 message ("Duplicate long qualifier"),
2442 else if (modifier == ctype_sint)
2444 if (dominant == ctype_int) return ctype_sint;
2445 if (dominant == ctype_uint) return ctype_usint;
2447 if (dominant == ctype_sint || dominant == ctype_usint)
2449 voptgenerror (FLG_DUPLICATEQUALS,
2450 message ("Duplicate short qualifier"),
2454 else if (dominant == ctype_lint)
2456 if (!context_getFlag (FLG_IGNOREQUALS))
2458 llerrorlit (FLG_SYNTAX,
2459 "Contradictory long and short type qualifiers");
2465 else if (dominant == ctype_llint)
2467 if (!context_getFlag (FLG_IGNOREQUALS))
2469 llerrorlit (FLG_SYNTAX,
2470 "Contradictory long long and short type qualifiers");
2478 if (!context_getFlag (FLG_IGNOREQUALS))
2480 llerror (FLG_SYNTAX,
2481 message ("Type qualifier short used with %s",
2482 ctype_unparse (dominant)));
2488 else if (modifier == ctype_ulint)
2490 if (dominant == ctype_int) return modifier;
2492 if (dominant == ctype_lint || dominant == ctype_ulint)
2494 voptgenerror (FLG_DUPLICATEQUALS,
2495 message ("Duplicate long qualifier"),
2501 if (dominant == ctype_uint || dominant == ctype_usint)
2503 voptgenerror (FLG_DUPLICATEQUALS,
2504 message ("Duplicate unsigned qualifier"),
2510 if (dominant == ctype_sint || dominant == ctype_usint)
2512 if (!context_getFlag (FLG_IGNOREQUALS))
2514 llerrorlit (FLG_SYNTAX,
2515 "Contradictory long and short type qualifiers");
2521 if (!context_getFlag (FLG_IGNOREQUALS))
2523 llerror (FLG_SYNTAX,
2524 message ("Type qualifiers unsigned long used with %s",
2525 ctype_unparse (dominant)));
2530 else if (modifier == ctype_usint)
2532 if (dominant == ctype_int) return modifier;
2534 if (dominant == ctype_sint || dominant == ctype_usint)
2536 voptgenerror (FLG_DUPLICATEQUALS,
2537 message ("Duplicate short qualifier"),
2542 if (dominant == ctype_uint)
2544 voptgenerror (FLG_DUPLICATEQUALS,
2545 message ("Duplicate unsigned qualifier"),
2551 if (dominant == ctype_lint || dominant == ctype_ulint
2552 || dominant == ctype_llint)
2554 if (!context_getFlag (FLG_IGNOREQUALS))
2556 llerrorlit (FLG_SYNTAX,
2557 "Contradictory long and short type qualifiers");
2563 if (!context_getFlag (FLG_IGNOREQUALS))
2565 llerror (FLG_SYNTAX,
2566 message ("Type qualifiers unsigned short used with %s",
2567 ctype_unparse (dominant)));
2581 ctype ctype_resolve (ctype c)
2583 if (ctype_isUnknown (c) && !ctype_isAnytype (c))
2585 DPRINTF (("Resolving to int: %s", ctype_unparse (c)));
2592 ctype ctype_fromQual (qual q)
2594 if (qual_isSigned (q)) return ctype_int;
2595 if (qual_isUnsigned (q)) return ctype_uint;
2596 if (qual_isLong (q)) return ctype_lint;
2597 if (qual_isShort (q)) return ctype_sint;
2599 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2600 return ctype_unknown;
2604 ctype_isAnyFloat (ctype c)
2606 return (cprim_isAnyReal (ctype_toCprim (c)));
2610 ctype_isUnsigned (ctype c)
2612 if (ctype_isConj (c))
2613 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2614 ctype_isUnsigned (ctype_getConjB (c)));
2616 return (c == ctype_uint || c == ctype_uchar
2617 || c == ctype_usint || c == ctype_ulint
2618 || c == ctype_ullint
2619 || c == ctype_unsignedintegral);
2624 ctype_isLongLong (ctype c)
2626 if (ctype_isConj (c))
2627 return (ctype_isLongLong (ctype_getConjA (c)) ||
2628 ctype_isLongLong (ctype_getConjB (c)));
2630 return (c == ctype_llint || c == ctype_ullint);
2635 ctype_isLong (ctype c)
2637 if (ctype_isConj (c))
2638 return (ctype_isLong (ctype_getConjA (c)) ||
2639 ctype_isLong (ctype_getConjB (c)));
2641 return (c == ctype_lint || c == ctype_ulint);
2645 ctype_isShort (ctype c)
2647 if (ctype_isConj (c))
2648 return (ctype_isShort (ctype_getConjA (c)) ||
2649 ctype_isShort (ctype_getConjB (c)));
2651 return (c == ctype_sint || c == ctype_usint);
2655 ctype_isStackAllocated (ctype c)
2657 ctype ct = ctype_realType (c);
2659 if (ctype_isConj (ct))
2660 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2661 ctype_isStackAllocated (ctype_getConjB (ct)));
2663 return (ctype_isArray (c) || ctype_isSU (c));
2666 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2668 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2671 static bool ctype_isLonger (ctype c1, ctype c2)
2673 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2674 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2675 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2676 || (ctype_isLong (c1)
2677 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2678 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2682 ctype_widest (ctype c1, ctype c2)
2684 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2694 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2697 if (c >= 0 && c < cttab.size)
2699 return (cttab.entries[c]->ctbase);
2703 if (c == ctype_unknown)
2704 llbuglit ("ctype_getCtbase: ctype unknown");
2705 if (c == ctype_undefined)
2706 llbuglit ("ctype_getCtbase: ctype undefined");
2708 llbuglit ("ctype_getCtbase: ctype dne");
2709 if (c == ctype_elipsMarker)
2710 llbuglit ("ctype_getCtbase: elips marker");
2712 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2719 static /*@notnull@*/ /*@observer@*/ ctbase
2720 ctype_getCtbaseSafe (ctype c)
2722 ctbase res = ctype_getCtbase (c);
2724 llassert (ctbase_isDefined (res));
2733 ctype_getCtentry (ctype c)
2735 static /*@only@*/ ctentry errorEntry = NULL;
2737 if (cttab.size == 0)
2739 if (errorEntry == NULL)
2741 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2748 if (c >= CTK_PLAIN && c < cttab.size)
2750 return (cttab.entries[c]);
2752 else if (c == CTK_UNKNOWN)
2753 llcontbuglit ("ctype_getCtentry: ctype unknown");
2754 else if (c == CTK_INVALID)
2755 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2756 else if (c == CTK_DNE)
2757 llcontbuglit ("ctype_getCtentry: ctype dne");
2758 else if (c == CTK_ELIPS)
2759 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2760 else if (c == CTK_MISSINGPARAMS)
2761 llcontbuglit ("ctype_getCtentry: ctype missing params");
2763 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2765 return (cttab.entries[ctype_unknown]);
2770 bool ctype_isFixedArray (ctype c)
2772 if (ctype_isElips (c)) return FALSE;
2774 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2779 /* requires that the type is an fixed array */
2780 /* return the size of the array */
2782 size_t ctype_getArraySize (ctype c)
2788 llassert (ctype_isFixedArray (c));
2790 ctb = ctype_getCtbaseSafe(c);
2791 size = ctbase_getArraySize (ctb);
2793 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",