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) && ctbase_isUA (ctype_getCtbase (c)));
243 ctype_isUser (ctype c)
245 return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c)));
249 ctype_isAbstract (ctype c)
251 return (!ctype_isUnknown (c)
252 && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
254 (ctype_isAbstract (ctype_getConjA (c))
255 || ctype_isAbstract (ctype_getConjB (c))))));
259 ctype_isImmutableAbstract (ctype t)
261 return (ctype_isAbstract (t) && !ctype_isMutable (t));
265 ctype_isRealAbstract (ctype c)
267 return (ctype_isAbstract (ctype_realType (c)) ||
269 (ctype_isRealAbstract (ctype_getConjA (c)) ||
270 ctype_isRealAbstract (ctype_getConjB (c)))));
274 ** primitive creators
278 ** createPrim not necessary --- subsumed by ctype_int, etc.
282 ** ctbase_unknown --- removed argument
287 ** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
291 ctype_makePointer (ctype c)
297 else if (c == ctype_void)
299 return ctype_voidPointer;
303 ctentry cte = ctype_getCtentry (c);
304 ctype clp = ctentry_getPtr (cte);
306 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
308 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
309 ctentry_setPtr (cte, cnew);
319 ctype ctype_makeFixedArray (ctype c, size_t size)
322 res = cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c);
326 ctype ctype_makeInnerFixedArray (ctype c, size_t size)
330 if (ctype_isFixedArray (c))
332 ctype cb = ctype_baseArrayPtr (c);
333 size_t osize = ctype_getArraySize (c);
335 res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize);
337 else if (ctype_isArray (c))
339 ctype cb = ctype_baseArrayPtr (c);
341 res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
345 res = ctype_makeFixedArray (c, size);
348 DPRINTF (("Make inner fixed array: %s", ctype_unparse (res)));
352 ctype ctype_makeInnerArray (ctype c)
356 DPRINTF (("Make inner array: %s", ctype_unparse (c)));
358 if (ctype_isFixedArray (c))
360 ctype cb = ctype_baseArrayPtr (c);
361 size_t osize = ctype_getArraySize (c);
363 res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize);
367 res = ctype_makeArray (c);
370 DPRINTF (("Make inner array: %s", ctype_unparse (res)));
375 ctype_makeArray (ctype c)
377 ctentry cte = ctype_getCtentry (c);
378 ctype clp = ctentry_getArray (cte);
380 DPRINTF (("Make array: %s", ctype_unparse (c)));
382 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
384 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
385 ctentry_setArray (cte, cnew);
395 ** requires c is a pointer of array
399 ctype_baseArrayPtr (ctype c)
401 ctentry cte = ctype_getCtentry (ctype_realType (c));
403 if (ctype_isConj (c))
405 if (ctype_isAP (ctype_getConjA (c)))
407 if (ctype_isAP (ctype_getConjB (c)))
409 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
410 ctype_baseArrayPtr (ctype_getConjB (c))));
414 return (ctype_baseArrayPtr (ctype_getConjA (c)));
419 return (ctype_baseArrayPtr (ctype_getConjB (c)));
422 else if (ctype_isInt (c)) /* could be NULL */
424 return ctype_unknown;
428 ctype clp = ctentry_getBase (cte);
430 if (ctype_isBroken (clp))
432 llbuglit ("ctype_baseArrayPtr: bogus ctype");
444 ctype_makeWideString ()
446 static ctype res = ctype_unknown;
448 if (ctype_isUnknown (res))
452 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
454 wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
461 res = ctype_makePointer (wchart);
468 ctype_isWideString (ctype c)
470 if (ctype_isPointer (c))
472 ctype ct = ctype_baseArrayPtr (c);
474 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
476 return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
490 ctype_getReturnType (ctype c)
492 if (ctype_isUnknown (c))
494 return ctype_unknown;
497 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
501 ** must be a shared pointer
504 /*@observer@*/ uentryList
505 ctype_argsFunction (ctype c)
507 if (ctype_isUnknown (c))
509 return uentryList_undefined;
512 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
516 ** Returns type with base type p and compound types from c.
518 ** i.e., c = char *[]; p = int
523 ctype_newBase (ctype c, ctype p)
525 return (ctbase_newBase (c, p));
529 ctype_sameAltTypes (ctype c1, ctype c2)
534 llassert (ctype_isConj (c1) && ctype_isConj (c2));
536 c1a = ctype_getConjA (c1);
537 c2a = ctype_getConjA (c2);
539 c1b = ctype_getConjB (c1);
540 c2b = ctype_getConjB (c2);
542 if (ctype_compare (c1a, c2a) == 0)
544 if (ctype_compare (c1b, c2b) == 0)
550 if (ctype_isConj (c1b) && ctype_isConj (c2b))
552 return ctype_sameAltTypes (c1b, c2b);
562 if (ctype_compare (c1a, c2b) == 0)
564 if (ctype_compare (c1b, c2a) == 0)
570 if (ctype_isConj (c1b) && ctype_isConj (c2a))
572 return ctype_sameAltTypes (c1b, c2a);
588 ctype_compare (ctype c1, ctype c2)
593 if (ctype_isUnknown (c1))
595 if (ctype_isUnknown (c2))
605 if (ctype_isUnknown (c2))
610 /* Can't get entries for special ctypes (elips marker) */
612 if (ctype_isElips (c1) || ctype_isElips (c2)
613 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
614 return int_compare (c1, c2);
617 ce1 = ctype_getCtentry (c1);
618 ce2 = ctype_getCtentry (c2);
620 if (ctentry_isComplex (ce1))
622 if (ctentry_isComplex (ce2))
624 return (ctbase_compare (ctype_getCtbase (c1),
625 ctype_getCtbase (c2), FALSE));
632 else if (ctentry_isComplex (ce2))
638 return (int_compare (c1, c2));
647 ** makeFunction: pointer to function returning base
651 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
653 uentryList_fixImpParams (p);
654 return (ctype_makeFunction (base, p));
658 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
660 uentryList_fixImpParams (p);
661 return (ctbase_makeNFFunction (base, p));
665 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
668 ret = ctbase_makeFunction (base, p);
672 ctype ctype_expectFunction (ctype c)
674 /* handle parenthesized declarations */
678 c = ctype_makePointer (c);
681 return (cttable_addComplex (ctbase_expectFunction (c)));
684 ctype ctype_dontExpectFunction (ctype c)
686 ctbase ctb = ctype_getCtbase (c);
691 c = ctype_makePointer (c);
695 return (ctbase_getExpectFunction (ctb));
699 ** makeRealFunction: function returning base
702 ctype ctype_makeRawFunction (ctype base, uentryList p)
704 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
712 **** this is very poorly defined
714 **** need to unify function/function pointer meaning
718 ctype_isFunction (ctype c)
720 if ( ( ctype_isKnown (c) && (!ctype_isElips(c) ) ) && ctype_isDefined (c))
722 return (ctbase_isFunction (ctype_getCtbase (c)));
732 trying to make up or ambiguity if ctype_isFunction
734 bool ctype_isFunctionPointer (ctype c)
736 if (ctype_isFunction(c) && ctype_isPointer(c) )
743 ctype_isExpFcn (ctype c)
745 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
749 ctype_isVoid (ctype c)
751 return (c == CTX_VOID);
755 ctype_isArbitraryIntegral (ctype c)
757 ctype cr = ctype_realType (c);
759 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
760 || cr == ctype_signedintegral);
764 ctype_isUnsignedIntegral (ctype c)
766 ctype cr = ctype_realType (c);
768 return (cr == ctype_unsignedintegral);
772 ctype_isSignedIntegral (ctype c)
774 ctype cr = ctype_realType (c);
776 return (cr == ctype_signedintegral);
780 ctype_isInt (ctype c)
782 cprim cp = ctype_toCprim (c);
784 return (c == ctype_unknown || cprim_isAnyInt (cp)
785 || (cprim_isAnyChar (cp) && context_msgCharInt ())
786 || (c == ctype_bool && context_msgBoolInt ())
787 || (ctype_isEnum (c) && context_msgEnumInt ()));
791 ctype_isRegularInt (ctype c)
793 cprim cp = ctype_toCprim (c);
795 return (c == ctype_unknown
796 || cprim_closeEnough (cprim_int, cp)
797 || (cprim_isAnyChar (cp) && context_msgCharInt ())
798 || (c == ctype_bool && context_msgBoolInt ())
799 || (ctype_isEnum (c) && context_msgEnumInt ()));
803 ctype_isString (ctype c)
805 return (c == ctype_string
806 || (ctype_isPointer (c)
807 && ctype_isChar (ctype_baseArrayPtr (c))));
811 ctype_isChar (ctype c)
813 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
814 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
818 ctype_isUnsignedChar (ctype c)
820 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
824 ctype_isSignedChar (ctype c)
826 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
830 ** Returns true if c matches the name -booltype <bool>
834 ctype_isManifestBool (ctype c)
837 ** Changed the meaning of ctype_isBool - evs 2000-07-24
838 ** The old meaning was very convoluted!
841 ** c == CTX_BOOL - its a direct bool
842 ** c is a user/abstract type matching the bool name
843 ** (should never occur?)
846 if (ctype_isDirectBool (c)) {
848 } else if (ctype_isUA (c)) {
849 return ctype_isUserBool (c);
856 ctype_isBool (ctype c)
859 ** Changed the meaning of ctype_isBool - evs 2000-07-24
860 ** The old meaning was very convoluted!
863 ** its a manifest bool
864 ** +boolint and ctype_isInt (c)
867 if (ctype_isManifestBool (c)) {
869 } else if (context_msgBoolInt ()) {
870 return ctype_isInt (c);
876 if (context_getFlag (FLG_ABSTRACTBOOL))
878 if (typeId_isInvalid (boolType))
880 boolType = usymtab_getTypeId (context_getBoolName ());
883 if (context_hasAccess (boolType))
885 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
886 || (context_msgBoolInt ()
888 || (c == CTX_CHAR && context_msgCharInt ()))))
893 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
894 || (context_msgBoolInt ()
895 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
900 ctype_isDirectBool (ctype c)
902 return (c == CTX_BOOL);
906 ctype_isReal (ctype c)
908 return (cprim_isAnyReal (ctype_toCprim (c)));
912 ctype_isFloat (ctype c)
914 return (c == ctype_float);
918 ctype_isDouble (ctype c)
920 return (c == ctype_double || c == ctype_ldouble);
924 ctype_isSigned (ctype c)
926 return (!ctype_isUnsigned (c));
930 ctype_isNumeric (ctype c)
932 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
933 /* evans 2001-10-05: added this: */
934 || ctype_isArbitraryIntegral (c));
941 ** work on actual type in current context
945 ctype_isRealNumeric (ctype c)
947 if (ctype_isPlain (c))
948 return (ctype_isNumeric (ctype_realType (c)));
949 if (ctype_isConj (c))
950 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
951 ctype_isRealNumeric (ctype_getConjB (c)));
957 ctype_isRealInt (ctype c)
959 if (ctype_isPlain (c))
960 return (ctype_isInt (ctype_realType (c)));
961 else if (ctype_isConj (c))
962 return (ctype_isRealInt (ctype_getConjA (c)) ||
963 ctype_isRealInt (ctype_getConjB (c)));
966 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
972 ctype_isRealVoid (ctype c)
974 if (ctype_isPlain (c))
976 return (ctype_isVoid (ctype_realType (c)));
978 else if (ctype_isConj (c))
980 return (ctype_isRealVoid (ctype_getConjA (c)) ||
981 ctype_isRealVoid (ctype_getConjB (c)));
990 ctype_isRealBool (ctype c)
992 if (ctype_isPlain (c))
994 return (ctype_isBool (ctype_realishType (c)));
996 else if (ctype_isConj (c))
998 return (ctype_isRealBool (ctype_getConjA (c)) ||
999 ctype_isRealBool (ctype_getConjB (c)));
1008 ctype_isRealPointer (ctype c)
1010 if (ctype_isConj (c))
1011 return (ctype_isRealPointer (ctype_getConjA (c)) ||
1012 ctype_isRealPointer (ctype_getConjB (c)));
1013 return (ctype_isPointer (ctype_realType (c)));
1017 ctype_isRealSU (ctype c)
1019 if (ctype_isConj (c))
1021 return (ctype_isRealSU (ctype_getConjA (c)) ||
1022 ctype_isRealSU (ctype_getConjB (c)));
1025 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
1026 return (ctype_isStructorUnion (ctype_realType (c)));
1030 ctype_isRealArray (ctype c)
1032 if (ctype_isConj (c))
1033 return (ctype_isRealArray (ctype_getConjA (c)) ||
1034 ctype_isRealArray (ctype_getConjB (c)));
1035 return (ctype_isArray (ctype_realType (c)));
1039 ctype_isRealAP (ctype c)
1041 if (ctype_isConj (c))
1042 return (ctype_isRealAP (ctype_getConjA (c)) ||
1043 ctype_isRealAP (ctype_getConjB (c)));
1044 return (ctype_isAP (ctype_realType (c)));
1048 ctype_isRealFunction (ctype c)
1050 if (ctype_isConj (c))
1051 return (ctype_isRealFunction (ctype_getConjA (c)) ||
1052 ctype_isRealFunction (ctype_getConjB (c)));
1053 return (ctype_isFunction (ctype_realType (c)));
1057 ctype_isDirectInt (ctype c)
1059 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
1063 ** forceful predicates
1065 ** take *ctype; if its a conjunct, and there is a match replace with match only.
1066 ** if both match, still conjunct
1070 ctype_isForcePred (ctype * c, bool (pred) (ctype))
1072 /*drl bee: pbr */ if (ctype_isConj (*c))
1074 ctype cbr = ctype_getConjA (*c);
1076 /*drl bee: si*/ if ((*pred) (cbr))
1078 if ((*pred) (ctype_getConjB (*c)))
1091 if ((*pred) (cbr = ctype_getConjB (*c)))
1099 return ((*pred) (*c));
1103 ctype_isForceRealNumeric (ctype * c)
1105 return (ctype_isForcePred (c, ctype_isRealNumeric));
1109 ctype_isForceRealInt (ctype * c)
1111 return (ctype_isForcePred (c, ctype_isRealInt));
1115 ctype_isForceRealBool (ctype * c)
1117 return (ctype_isForcePred (c, ctype_isRealBool));
1123 ** save int/char, int/bool, other random conjuncts
1127 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
1129 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
1133 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1141 return (ctype_makeExplicitConj (c1, c2));
1145 return (ctype_makeConj (c1, c2));
1151 ctype_makeExplicitConj (ctype c1, ctype c2)
1153 if (ctype_isAnytype (c1) || ctype_isAnytype (c2))
1155 return ctype_makeAnytype ();
1157 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1159 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
1161 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1163 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1165 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
1167 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1171 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1175 static ctype ic = ctype_unknown; /* int | char */
1176 static ctype ib = ctype_unknown; /* int | bool */
1177 static ctype ifl = ctype_unknown; /* int | float */
1178 static ctype ibf = ctype_unknown; /* int | bool | float */
1179 static ctype ibc = ctype_unknown; /* int | bool | char */
1180 static ctype iv = ctype_unknown; /* int | void * */
1181 static ctype ivf = ctype_unknown; /* int | void * | float */
1182 static ctype ivb = ctype_unknown; /* int | void * | bool */
1183 static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1184 static ctype cuc = ctype_unknown; /* char | unsigned char */
1186 static ctype cany = ctype_unknown;
1189 ctype_makeAnytype ()
1191 if (cany == ctype_unknown)
1193 cany = ctype_makeConj (ctype_unknown, ctype_dne);
1194 llassert (ctype_isAnytype (cany));
1197 DPRINTF (("make anytype: %s", ctype_unparse (cany)));
1202 ctype_isAnytype (ctype c)
1208 ctype_recordConj (ctype c)
1212 llassert (ctype_isConj (c));
1214 c1 = ctype_getConjA (c);
1215 c2 = ctype_getConjB (c);
1218 if (c2 == ctype_int && c1 != ctype_int)
1228 if (c1 == ctype_int)
1230 if (c2 == ctype_char)
1232 llassert (ic == ctype_unknown);
1235 else if (c2 == ctype_bool)
1237 llassert (ib == ctype_unknown);
1240 else if (c2 == ctype_float)
1242 llassert (ifl == ctype_unknown);
1245 else if (c2 == CTP_VOID)
1247 llassert (iv == ctype_unknown);
1255 else if (c1 == ib && ib != ctype_unknown)
1257 if (c2 == ctype_float)
1259 llassert (ibf == ctype_unknown);
1262 else if (c2 == ctype_char)
1264 llassert (ibc == ctype_unknown);
1274 if (c2 == ctype_bool)
1276 llassert (ivb == ctype_unknown);
1279 else if (c2 == ctype_float)
1281 llassert (ivf == ctype_unknown);
1291 if (c2 == ctype_bool)
1293 llassert (ivbf == ctype_unknown);
1299 if (c2 == ctype_float)
1301 llassert (ivbf == ctype_unknown);
1305 else if (c1 == ctype_char)
1307 if (c2 == ctype_uchar)
1309 llassert (cuc == ctype_unknown);
1321 ctype_makeConj (ctype c1, ctype c2)
1323 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1325 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1327 if (ctype_isAnytype (c1))
1331 else if (ctype_isAnytype (c2))
1335 else if (ctype_isUnknown (c1))
1339 else if (ctype_isUnknown (c2))
1343 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1345 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
1346 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1348 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1350 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
1351 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1355 if (ctype_isManifestBool (c1))
1360 if (ctype_isManifestBool (c2))
1365 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1367 c1 = ctype_voidPointer;
1370 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1372 c2 = ctype_voidPointer;
1376 ** Ouch, can't do this. unsigned, etc. modifiers might
1377 ** apply to wrong type!
1379 ** if (c2 == ctype_int && c1 != ctype_int)
1390 if (c1 == ctype_int)
1392 if (c2 == ctype_char)
1394 if (ic == ctype_unknown)
1396 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1401 else if (c2 == ctype_bool)
1403 if (ib == ctype_unknown)
1405 ib = cttable_addComplex
1406 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1411 else if (c2 == ctype_float)
1413 if (ifl == ctype_unknown)
1415 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1422 if (c2 == ctype_voidPointer)
1424 if (iv == ctype_unknown)
1426 iv = cttable_addComplex
1427 (ctbase_makeConj (ctype_int,
1436 else if (c1 == ib && ib != ctype_unknown)
1438 if (c2 == ctype_float)
1440 if (ibf == ctype_unknown)
1442 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1447 else if (c2 == ctype_char)
1449 if (ibc == ctype_unknown)
1451 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1463 if (c2 == ctype_bool)
1465 if (ivb == ctype_unknown)
1467 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1472 else if (c2 == ctype_float)
1474 if (ivf == ctype_unknown)
1476 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1488 if (c2 == ctype_bool)
1490 if (ivbf == ctype_unknown)
1492 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1500 if (c2 == ctype_float)
1502 if (ivbf == ctype_unknown)
1504 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1510 else if (c1 == ctype_char)
1512 if (c2 == ctype_uchar)
1514 if (cuc == ctype_unknown)
1516 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1527 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1533 ctype_isConj (ctype c)
1535 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1539 ctype_getConjA (ctype c)
1541 if (!ctype_isConj (c))
1542 llbuglit ("ctype_getConjA: not a conj");
1543 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1547 ctype_getConjB (ctype c)
1549 if (!ctype_isConj (c))
1550 llbuglit ("ctype_getConjB: not a conj");
1551 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1555 ctype_isExplicitConj (ctype c)
1557 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1560 /** << need to fix resolveConj >> **/
1563 ** structs and unions
1567 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1571 DPRINTF (("Creating a struct: %s / %s",
1572 n, uentryList_unparse (f)));
1574 ct = cttable_addComplex (ctbase_createStruct (n, f));
1575 DPRINTF (("ct: %s", ctype_unparse (ct)));
1580 ctype_getFields (ctype c)
1582 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1586 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1590 ret = cttable_addComplex (ctbase_createUnion (n, f));
1597 ** if ctype's are same, definite match.
1598 ** else, need to call ctbase_match.
1600 ** if necessary context can memoize matches
1604 quickMatch (ctype c1, ctype c2)
1613 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1617 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1619 if (quickMatch (c1, c2))
1624 if (ctype_isElips (c1) || ctype_isElips (c2))
1630 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1636 ctype_sameName (ctype c1, ctype c2)
1638 if (quickMatch (c1, c2))
1641 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1645 ctype_almostEqual (ctype c1, ctype c2)
1647 if (ctype_equal (c1, c2))
1653 if (ctype_isUnknown (c1))
1655 return ctype_isUnknown (c2);
1657 else if (ctype_isUnknown (c2))
1663 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1669 ctype_matchDef (ctype c1, ctype c2)
1671 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1673 if (quickMatch (c1, c2))
1676 if (ctype_isElips (c1))
1677 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1679 if (ctype_isElips (c2))
1681 return (ctype_isUnknown (c2));
1685 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1688 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1689 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1690 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1695 bool ctype_match (ctype c1, ctype c2)
1697 if (quickMatch (c1, c2))
1700 if (ctype_isElips (c1))
1701 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1703 if (ctype_isElips (c2))
1704 return (ctype_isUnknown (c2));
1706 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1710 ctype_forceMatch (ctype c1, ctype c2)
1712 if (quickMatch (c1, c2))
1715 if (ctype_isElips (c1))
1716 return (ctype_isElips (c2));
1718 if (ctype_isElips (c2))
1722 /* The call forceMatch may modify the observer params, but, we don't care. */
1723 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1728 ctype_matchArg (ctype c1, ctype c2)
1730 if (quickMatch (c1, c2))
1736 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1741 ** simple ctype_is operations.
1742 ** DO NOT use real type of c, only direct type.
1746 ** ctype_isVoidPointer
1752 ctype_isVoidPointer (ctype c)
1754 if (ctype_isComplex (c))
1756 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1758 if (ctype_isConj (c))
1760 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1761 ctype_isVoidPointer (ctype_getConjB (c)));
1765 return (c == ctype_voidPointer
1766 || (ctype_isRealPointer (c)
1767 && ctype_isVoid (ctype_baseArrayPtr (c))));
1774 ** true for C and LCL pointers
1778 ctype_isPointer (ctype c)
1780 if (ctype_isElips (c)) return FALSE;
1782 if (ctype_isComplex (c))
1784 ctbase ctb = ctype_getCtbaseSafe (c);
1785 bool res = ctbase_isPointer (ctb);
1791 bool res = ctentry_isPointer (ctype_getCtentry (c));
1800 ** true for C and LCL array's
1804 ctype_isArray (ctype c)
1806 if (ctype_isElips (c)) return FALSE;
1808 if (ctype_isComplex (c))
1809 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1811 return (ctentry_isArray (ctype_getCtentry (c)));
1814 bool ctype_isIncompleteArray (ctype c)
1816 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1820 ctype_isArrayPtr (ctype c)
1822 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1826 ctype_typeId (ctype c)
1828 return (ctbase_typeId (ctype_getCtbase (c)));
1833 ctype_unparseFunctionPointer (ctype c, cstring quals, /*@only@*/ cstring name)
1838 base = ctype_getCtbaseSafe (c);
1839 ctTmp = base->contents.base;
1841 return (ctbase_doUnparseFunctionPointer (ctype_getCtbaseSafe(ctTmp), name, quals) );
1845 ctype_unparseFunction (ctype c, /*@only@*/ cstring name)
1847 return (ctbase_unparseFunction (ctype_getCtbaseSafe (c), name) );
1851 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1853 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1855 if (ctype_isUnknown (c))
1857 return message ("? %q", name);
1861 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1866 ctype_unparse (ctype c)
1868 if (ctype_isElips (c))
1870 return cstring_makeLiteralTemp ("...");
1872 else if (ctype_isMissingParamsMarker (c))
1874 return cstring_makeLiteralTemp ("-");
1876 else if (ctype_isAnytype (c))
1878 return cstring_makeLiteralTemp ("<any>");
1880 else if (ctype_isUnknown (c))
1882 return cstring_makeLiteralTemp ("?");
1887 return (ctentry_doUnparse (ctype_getCtentry (c)));
1893 ctype_unparseSafe (ctype c)
1895 if (ctype_isElips (c))
1897 return cstring_makeLiteralTemp ("...");
1899 else if (ctype_isMissingParamsMarker (c))
1901 return cstring_makeLiteralTemp ("-");
1907 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1909 ctentry cte = ctype_getCtentry (c);
1911 if (cstring_isDefined (cte->unparse))
1913 return (cte->unparse);
1917 ret = message ("[%d]", (int) c);
1918 cstring_markOwned (ret);
1924 ctype_unparseDeep (ctype c)
1926 if (ctype_isElips (c))
1928 return cstring_makeLiteralTemp ("...");
1930 if (ctype_isMissingParamsMarker (c))
1932 return cstring_makeLiteralTemp ("-");
1935 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1939 ctype_undump (char **c)
1941 return ((ctype) reader_getInt (c)); /* check its valid? */
1945 ctype_dump (ctype c)
1947 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1951 /* Handle invalid types in a kludgey way. */
1952 return (message ("0"));
1957 cstring tname = usymtab_getTypeEntryName
1958 (usymtab_convertId (ctype_typeId (c)));
1960 if (cstring_equal (tname, context_getBoolName ()))
1962 cstring_free (tname);
1963 return (message ("%d", ctype_bool));
1966 cstring_free (tname);
1969 DPRINTF (("Returning: %d", c));
1970 return (message ("%d", c));
1974 ctype_getBaseType (ctype c)
1976 ctentry cte = ctype_getCtentry (c);
1978 switch (ctentry_getKind (cte))
1986 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1989 ctbase ctb = cte->ctbase;
1991 if (ctbase_isDefined (ctb))
2010 return (ctype_getBaseType (ctb->contents.base));
2012 return (ctype_getBaseType (ctb->contents.farray->base));
2013 case CT_CONJ: /* base type of A conj branch? */
2014 return (ctype_getBaseType (ctb->contents.conj->a));
2016 /*@noaccess ctbase@*/
2024 llbuglit ("ctype_newBase: bad case");
2026 llcontbuglit ("ctype_getBaseType: unreachable code");
2027 return ((ctype)NULL);
2031 ctype_adjustPointers (int np, ctype c)
2034 if (ctype_isFunction (c))
2036 c = ctype_makeParamsFunction
2037 (ctype_adjustPointers (np, ctype_getReturnType (c)),
2038 uentryList_copy (ctype_argsFunction (c)));
2042 /* fix this should not use getBaseType ??? */
2043 ctype cb = ctype_getBaseType (c);
2047 cb = ctype_makePointer (cb);
2050 c = ctype_newBase (c, cb);
2058 ctype_elist (ctype c)
2060 return (ctbase_elist (ctype_getCtbase (c)));
2064 ctype_isFirstVoid (ctype c)
2066 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2070 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2072 return (cttable_addComplex (ctbase_createEnum (tag, el)));
2076 ctype_isEnum (ctype c)
2078 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2082 ctype_enumTag (ctype c)
2084 llassert (ctype_isEnum (c));
2086 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2090 ctype_isStruct (ctype c)
2092 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2096 ctype_isUnion (ctype c)
2098 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2102 ctype_resolveNumerics (ctype c1, ctype c2)
2105 ** returns longest type of c1 and c2
2108 if (c1 == c2) return c1;
2110 c1 = ctype_realType (c1);
2111 c2 = ctype_realType (c2);
2113 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2114 if (ctype_isEnum (c2)) c2 = ctype_int;
2116 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2118 /* 2001-06-08: This fix provided by Jim Zelenka. */
2119 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2120 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2122 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2123 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2124 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2125 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2127 /* 2001-06-08: This fix provided by Jim Zelenka. */
2128 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2130 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2132 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2133 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2135 if (ctype_isKnown (c1)) return c1;
2140 ctype_isStructorUnion (ctype c)
2142 return (ctype_isStruct (c) || ctype_isUnion (c));
2146 ctype_fixArrayPtr (ctype c)
2148 if (ctype_isArray (c))
2150 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2157 ** createUnnamedStruct/Union
2159 ** check if it corresponds to an existing LCL-specified unnamed struct
2160 ** otherwise, give it a new tag
2164 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2166 ctype ret = usymtab_structFieldsType (f);
2168 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2170 if (ctype_isDefined (ret))
2172 uentryList_free (f);
2177 cstring ft = fakeTag ();
2178 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2179 uentry ue = uentry_makeStructTagLoc (ft, ct);
2181 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2182 ue = usymtab_supGlobalEntryReturn (ue);
2183 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2191 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2193 ctype ret = usymtab_unionFieldsType (f);
2195 if (ctype_isDefined (ret))
2197 uentryList_free (f);
2202 cstring ft = fakeTag ();
2203 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2204 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2206 usymtab_supGlobalEntry (ue);
2213 ctype_isUnnamedSU (ctype c)
2217 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2226 ctype_createForwardStruct (cstring n)
2228 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2229 ctype ct = usymtab_supForwardTypeEntry (ue);
2236 ctype_createForwardUnion (cstring n)
2238 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2239 ctype ct = usymtab_supForwardTypeEntry (ue);
2246 ctype_removePointers (ctype c)
2250 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2253 c = ctype_baseArrayPtr (c);
2254 llassert (c != oldc);
2260 bool ctype_isMutable (ctype t)
2264 return (uentry_isMutableDatatype
2265 (usymtab_getTypeEntry (ctype_typeId (t))));
2269 return (ctype_isPointer (ctype_realType (t)));
2270 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2274 bool ctype_isRefCounted (ctype t)
2278 return (uentry_isRefCountedDatatype
2279 (usymtab_getTypeEntry (ctype_typeId (t))));
2285 bool ctype_isVisiblySharable (ctype t)
2287 if (ctype_isUnknown (t)) return TRUE;
2289 if (ctype_isConj (t))
2291 return (ctype_isVisiblySharable (ctype_getConjA (t))
2292 || ctype_isVisiblySharable (ctype_getConjB (t)));
2295 if (ctype_isMutable (t))
2299 ctype rt = ctype_realType (t);
2307 return ctype_isVisiblySharable (rt);
2321 /* Replaced by ctype_isMutable (more sensible) */
2322 bool ctype_canAlias (ctype ct)
2324 /* can ct refer to memory locations?
2325 ** ==> a pointer or a mutable abstract type
2329 ctype tr = ctype_realType (ct);
2331 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2336 ** c1 is the dominant type; c2 is the modifier type
2338 ** eg. double + long int => long double
2341 ctype ctype_combine (ctype dominant, ctype modifier)
2343 DPRINTF (("Combine: %s + %s",
2344 ctype_unparse (dominant),
2345 ctype_unparse (modifier)));
2347 if (ctype_isConj (dominant))
2351 if (ctype_isExplicitConj (dominant))
2353 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2355 ctype_getConjB (dominant));
2359 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2361 ctype_getConjB (dominant));
2367 if (ctype_isUnknown (modifier))
2371 else if (ctype_isUnknown (dominant))
2377 if (ctype_isEnum (dominant)) dominant = ctype_int;
2378 if (ctype_isEnum (modifier)) modifier = ctype_int;
2380 if (modifier == ctype_uint)
2382 if (dominant == ctype_int) return ctype_uint;
2383 if (dominant == ctype_lint) return ctype_ulint;
2384 if (dominant == ctype_sint) return ctype_usint;
2385 if (dominant == ctype_char) return ctype_uchar;
2387 /* evs 2000-07-28: added this line */
2388 if (dominant == ctype_llint) return ctype_ullint;
2390 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2392 voptgenerror (FLG_DUPLICATEQUALS,
2393 message ("Duplicate unsigned qualifier"),
2400 voptgenerror (FLG_DUPLICATEQUALS,
2401 message ("Type qualifier unsigned used with %s",
2402 ctype_unparse (dominant)),
2408 else if (modifier == ctype_llint)
2410 if (dominant == ctype_int)
2415 voptgenerror (FLG_DUPLICATEQUALS,
2416 message ("Duplicate long qualifier on non-int"),
2419 else if (modifier == ctype_lint)
2421 if (dominant == ctype_int) return ctype_lint;
2422 if (dominant == ctype_uint) return ctype_ulint;
2423 if (dominant == ctype_double) return ctype_ldouble;
2425 if (dominant == ctype_lint || dominant == ctype_ulint
2426 || dominant == ctype_sint || dominant == ctype_usint
2427 || dominant == ctype_ldouble)
2429 if (dominant == ctype_lint)
2431 /* long long not supported by ANSI */
2436 if (dominant == ctype_ulint)
2438 /* unsigned long long not supported by ANSI */
2439 return ctype_ullint;
2443 if (dominant == ctype_sint || dominant == ctype_usint)
2445 if (!context_getFlag (FLG_IGNOREQUALS))
2447 llerrorlit (FLG_SYNTAX,
2448 "Contradictory long and short type qualifiers");
2453 voptgenerror (FLG_DUPLICATEQUALS,
2454 message ("Duplicate long qualifier"),
2461 else if (modifier == ctype_sint)
2463 if (dominant == ctype_int) return ctype_sint;
2464 if (dominant == ctype_uint) return ctype_usint;
2466 if (dominant == ctype_sint || dominant == ctype_usint)
2468 voptgenerror (FLG_DUPLICATEQUALS,
2469 message ("Duplicate short qualifier"),
2473 else if (dominant == ctype_lint)
2475 if (!context_getFlag (FLG_IGNOREQUALS))
2477 llerrorlit (FLG_SYNTAX,
2478 "Contradictory long and short type qualifiers");
2484 else if (dominant == ctype_llint)
2486 if (!context_getFlag (FLG_IGNOREQUALS))
2488 llerrorlit (FLG_SYNTAX,
2489 "Contradictory long long and short type qualifiers");
2497 if (!context_getFlag (FLG_IGNOREQUALS))
2499 llerror (FLG_SYNTAX,
2500 message ("Type qualifier short used with %s",
2501 ctype_unparse (dominant)));
2507 else if (modifier == ctype_ulint)
2509 if (dominant == ctype_int) return modifier;
2511 if (dominant == ctype_lint || dominant == ctype_ulint)
2513 voptgenerror (FLG_DUPLICATEQUALS,
2514 message ("Duplicate long qualifier"),
2520 if (dominant == ctype_uint || dominant == ctype_usint)
2522 voptgenerror (FLG_DUPLICATEQUALS,
2523 message ("Duplicate unsigned qualifier"),
2529 if (dominant == ctype_sint || dominant == ctype_usint)
2531 if (!context_getFlag (FLG_IGNOREQUALS))
2533 llerrorlit (FLG_SYNTAX,
2534 "Contradictory long and short type qualifiers");
2540 if (!context_getFlag (FLG_IGNOREQUALS))
2542 llerror (FLG_SYNTAX,
2543 message ("Type qualifiers unsigned long used with %s",
2544 ctype_unparse (dominant)));
2549 else if (modifier == ctype_usint)
2551 if (dominant == ctype_int) return modifier;
2553 if (dominant == ctype_sint || dominant == ctype_usint)
2555 voptgenerror (FLG_DUPLICATEQUALS,
2556 message ("Duplicate short qualifier"),
2561 if (dominant == ctype_uint)
2563 voptgenerror (FLG_DUPLICATEQUALS,
2564 message ("Duplicate unsigned qualifier"),
2570 if (dominant == ctype_lint || dominant == ctype_ulint
2571 || dominant == ctype_llint)
2573 if (!context_getFlag (FLG_IGNOREQUALS))
2575 llerrorlit (FLG_SYNTAX,
2576 "Contradictory long and short type qualifiers");
2582 if (!context_getFlag (FLG_IGNOREQUALS))
2584 llerror (FLG_SYNTAX,
2585 message ("Type qualifiers unsigned short used with %s",
2586 ctype_unparse (dominant)));
2600 ctype ctype_resolve (ctype c)
2602 if (ctype_isUnknown (c) && !ctype_isAnytype (c))
2604 DPRINTF (("Resolving to int: %s", ctype_unparse (c)));
2611 ctype ctype_fromQual (qual q)
2613 if (qual_isSigned (q)) return ctype_int;
2614 if (qual_isUnsigned (q)) return ctype_uint;
2615 if (qual_isLong (q)) return ctype_lint;
2616 if (qual_isShort (q)) return ctype_sint;
2618 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2619 return ctype_unknown;
2623 ctype_isAnyFloat (ctype c)
2625 return (cprim_isAnyReal (ctype_toCprim (c)));
2629 ctype_isUnsigned (ctype c)
2631 if (ctype_isConj (c))
2632 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2633 ctype_isUnsigned (ctype_getConjB (c)));
2635 return (c == ctype_uint || c == ctype_uchar
2636 || c == ctype_usint || c == ctype_ulint
2637 || c == ctype_ullint
2638 || c == ctype_unsignedintegral);
2643 ctype_isLongLong (ctype c)
2645 if (ctype_isConj (c))
2646 return (ctype_isLongLong (ctype_getConjA (c)) ||
2647 ctype_isLongLong (ctype_getConjB (c)));
2649 return (c == ctype_llint || c == ctype_ullint);
2654 ctype_isLong (ctype c)
2656 if (ctype_isConj (c))
2657 return (ctype_isLong (ctype_getConjA (c)) ||
2658 ctype_isLong (ctype_getConjB (c)));
2660 return (c == ctype_lint || c == ctype_ulint);
2664 ctype_isShort (ctype c)
2666 if (ctype_isConj (c))
2667 return (ctype_isShort (ctype_getConjA (c)) ||
2668 ctype_isShort (ctype_getConjB (c)));
2670 return (c == ctype_sint || c == ctype_usint);
2674 ctype_isStackAllocated (ctype c)
2676 ctype ct = ctype_realType (c);
2678 if (ctype_isConj (ct))
2679 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2680 ctype_isStackAllocated (ctype_getConjB (ct)));
2682 return (ctype_isArray (c) || ctype_isSU (c));
2685 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2687 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2690 static bool ctype_isLonger (ctype c1, ctype c2)
2692 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2693 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2694 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2695 || (ctype_isLong (c1)
2696 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2697 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2701 ctype_widest (ctype c1, ctype c2)
2703 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2714 /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2717 if (c >= 0 && c < cttab.size)
2719 return (cttab.entries[c]->ctbase);
2723 if (c == ctype_unknown)
2724 llbuglit ("ctype_getCtbase: ctype unknown");
2725 if (c == ctype_undefined)
2726 llbuglit ("ctype_getCtbase: ctype undefined");
2728 llbuglit ("ctype_getCtbase: ctype dne");
2729 if (c == ctype_elipsMarker)
2730 llbuglit ("ctype_getCtbase: elips marker");
2732 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2740 /*@notnull@*/ /*@observer@*/ ctbase
2741 ctype_getCtbaseSafe (ctype c)
2743 ctbase res = ctype_getCtbase (c);
2745 llassert (ctbase_isDefined (res));
2754 ctype_getCtentry (ctype c)
2756 static /*@only@*/ ctentry errorEntry = NULL;
2758 if (cttab.size == 0)
2760 if (errorEntry == NULL)
2762 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2769 if (c >= CTK_PLAIN && c < cttab.size)
2771 return (cttab.entries[c]);
2773 else if (c == CTK_UNKNOWN)
2774 llcontbuglit ("ctype_getCtentry: ctype unknown");
2775 else if (c == CTK_INVALID)
2776 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2777 else if (c == CTK_DNE)
2778 llcontbuglit ("ctype_getCtentry: ctype dne");
2779 else if (c == CTK_ELIPS)
2780 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2781 else if (c == CTK_MISSINGPARAMS)
2782 llcontbuglit ("ctype_getCtentry: ctype missing params");
2784 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2786 return (cttab.entries[ctype_unknown]);
2791 bool ctype_isFixedArray (ctype c)
2793 if (ctype_isElips (c)) return FALSE;
2795 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2800 /* requires that the type is an fixed array */
2801 /* return the size of the array */
2803 size_t ctype_getArraySize (ctype c)
2809 llassert (ctype_isFixedArray (c));
2811 ctb = ctype_getCtbaseSafe(c);
2812 size = ctbase_getArraySize (ctb);
2814 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2820 /*drl added 04-22-2002 */
2822 /*This is an ugly and hopefuly temporary function to
2823 print a function pointer.
2824 It assumes that ctype_unparse will give it something like
2825 [function (int, float) returns void *]
2827 to extract information from.
2832 cstring ctype_unparseFunctionPointer (ctype type, cstring quals, cstring name)
2834 cstring up, params, tmp, returns, ret;
2836 up = ctype_unparse(type);
2838 tmp = cstring_beforeChar(up, ')');
2839 params = cstring_afterChar(tmp, '(');
2841 params = cstring_concat (params, cstring_makeLiteral(")") );
2843 returns = cstring_afterChar(up, ')');
2844 returns = cstring_afterChar(returns, 's');
2845 returns = cstring_beforeChar(returns, ']');
2846 returns = cstring_afterChar(returns, ' ');
2847 ret = message("%s %s (* %s) %s", quals, returns, name, params);
2854 cstring qtypetryToPrintStruct(qtype q)
2862 ct = ctype_getCtentry(qtype_getType(q) );
2864 llassert (ct != NULL );
2866 base = ctentry_getCtbase(ct);
2868 //evil abstraction violation fix
2872 llassert(ctbase_isDefined(base) );
2874 if (base->type == CT_USER)
2877 ue = usymtab_getTypeEntry(base->contents.tid);
2879 base = ctentry_getCtbase( ctype_getCtentry(uentry_getType (ue) ) );
2881 llassert(ctbase_isDefined(base) );
2887 if (isFakeTag(base->contents.cenum->tag) )
2889 ret = message ("enum { %s } ",
2890 enumNameList_unparse(base->contents.cenum->members) );
2894 ret = message ("enum %s { %s } ",base->contents.cenum->tag, enumNameList_unparse(base->contents.cenum->members) );
2898 if (isFakeTag(base->contents.su->name) )
2900 ret = message ("struct { %s } ",
2901 uentryList_unparse(base->contents.su->fields) );
2905 ret = message ("struct %s { %s } ",
2906 base->contents.su->name, uentryList_unparse(base->contents.su->fields) );
2911 if (isFakeTag(base->contents.su->name) )
2913 ret = message ("union { %s } ",
2914 uentryList_unparse(base->contents.su->fields) );
2918 ret = message ("union %s { %s } ",
2919 base->contents.su->name, uentryList_unparse(base->contents.su->fields) );
2921 /*@noaccess ctbase@*/
2924 // ret = message("%s", uentry_unparse(ue) );
2928 ret = message ("%s", qtype_unparse(q) );