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 ] */
159 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u))));
169 ctype_realType (ctype c)
173 if (ctype_isElips (c) || ctype_isMissingParamsMarker (c))
180 r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c)));
183 if (ctype_isManifestBool (r))
185 if (context_canAccessBool ())
187 r = context_boolImplementationType ();
195 ctype_isSimple (ctype c)
197 return (! (ctype_isPointer (c)
199 || ctype_isFunction (c)));
203 ctype_forceRealType (ctype c)
209 r = uentry_getForceRealType (usymtab_getTypeEntry (ctype_typeId (c)));
216 ctype_realishType (ctype c)
220 if (ctype_isManifestBool (c))
226 ctype r = uentry_getRealType (usymtab_getTypeEntry
238 return (!ctype_isUnknown (c) && ctbase_isUA (ctype_getCtbase (c)));
242 ctype_isUser (ctype c)
244 return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c)));
248 ctype_isAbstract (ctype c)
250 return (!ctype_isUnknown (c)
251 && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
253 (ctype_isAbstract (ctype_getConjA (c))
254 || ctype_isAbstract (ctype_getConjB (c))))));
258 ctype_isImmutableAbstract (ctype t)
260 return (ctype_isAbstract (t) && !ctype_isMutable (t));
264 ctype_isRealAbstract (ctype c)
266 return (ctype_isAbstract (ctype_realType (c)) ||
268 (ctype_isRealAbstract (ctype_getConjA (c)) ||
269 ctype_isRealAbstract (ctype_getConjB (c)))));
273 ** primitive creators
277 ** createPrim not necessary --- subsumed by ctype_int, etc.
281 ** ctbase_unknown --- removed argument
286 ** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
290 ctype_makePointer (ctype c)
296 else if (c == ctype_void)
298 return ctype_voidPointer;
302 ctentry cte = ctype_getCtentry (c);
303 ctype clp = ctentry_getPtr (cte);
305 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
307 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
308 ctentry_setPtr (cte, cnew);
318 ctype ctype_makeFixedArray (ctype c, long size)
321 res = cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c);
325 ctype ctype_makeInnerFixedArray (ctype c, long size)
329 if (ctype_isFixedArray (c))
331 ctype cb = ctype_baseArrayPtr (c);
332 long osize = ctype_getArraySize (c);
334 res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size),
339 res = ctype_makeFixedArray (c, size);
346 ctype_makeArray (ctype c)
348 ctentry cte = ctype_getCtentry (c);
349 ctype clp = ctentry_getArray (cte);
351 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
353 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
354 ctentry_setArray (cte, cnew);
362 ** requires c is a pointer of array
366 ctype_baseArrayPtr (ctype c)
368 ctentry cte = ctype_getCtentry (ctype_realType (c));
370 if (ctype_isConj (c))
372 if (ctype_isAP (ctype_getConjA (c)))
374 if (ctype_isAP (ctype_getConjB (c)))
376 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
377 ctype_baseArrayPtr (ctype_getConjB (c))));
381 return (ctype_baseArrayPtr (ctype_getConjA (c)));
386 return (ctype_baseArrayPtr (ctype_getConjB (c)));
389 else if (ctype_isInt (c)) /* could be NULL */
391 return ctype_unknown;
395 ctype clp = ctentry_getBase (cte);
397 if (ctype_isBroken (clp))
399 llbuglit ("ctype_baseArrayPtr: bogus ctype");
411 ctype_makeWideString ()
413 static ctype res = ctype_unknown;
415 if (ctype_isUnknown (res))
419 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
421 wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
428 res = ctype_makePointer (wchart);
435 ctype_isWideString (ctype c)
437 if (ctype_isPointer (c))
439 ctype ct = ctype_baseArrayPtr (c);
441 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
443 return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
457 ctype_getReturnType (ctype c)
459 if (ctype_isUnknown (c))
461 return ctype_unknown;
464 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
468 ** must be a shared pointer
471 /*@observer@*/ uentryList
472 ctype_argsFunction (ctype c)
474 if (ctype_isUnknown (c))
476 return uentryList_undefined;
479 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
483 ** Returns type with base type p and compound types from c.
485 ** i.e., c = char *[]; p = int
490 ctype_newBase (ctype c, ctype p)
492 return (ctbase_newBase (c, p));
496 ctype_sameAltTypes (ctype c1, ctype c2)
501 llassert (ctype_isConj (c1) && ctype_isConj (c2));
503 c1a = ctype_getConjA (c1);
504 c2a = ctype_getConjA (c2);
506 c1b = ctype_getConjB (c1);
507 c2b = ctype_getConjB (c2);
509 if (ctype_compare (c1a, c2a) == 0)
511 if (ctype_compare (c1b, c2b) == 0)
517 if (ctype_isConj (c1b) && ctype_isConj (c2b))
519 return ctype_sameAltTypes (c1b, c2b);
529 if (ctype_compare (c1a, c2b) == 0)
531 if (ctype_compare (c1b, c2a) == 0)
537 if (ctype_isConj (c1b) && ctype_isConj (c2a))
539 return ctype_sameAltTypes (c1b, c2a);
555 ctype_compare (ctype c1, ctype c2)
560 if (ctype_isUnknown (c1))
562 if (ctype_isUnknown (c2))
572 if (ctype_isUnknown (c2))
577 /* Can't get entries for special ctypes (elips marker) */
579 if (ctype_isElips (c1) || ctype_isElips (c2)
580 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
581 return int_compare (c1, c2);
584 ce1 = ctype_getCtentry (c1);
585 ce2 = ctype_getCtentry (c2);
587 if (ctentry_isComplex (ce1))
589 if (ctentry_isComplex (ce2))
591 return (ctbase_compare (ctype_getCtbase (c1),
592 ctype_getCtbase (c2), FALSE));
599 else if (ctentry_isComplex (ce2))
605 return (int_compare (c1, c2));
614 ** makeFunction: pointer to function returning base
618 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
620 uentryList_fixImpParams (p);
621 return (ctype_makeFunction (base, p));
625 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
627 uentryList_fixImpParams (p);
628 return (ctbase_makeNFFunction (base, p));
632 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
635 ret = ctbase_makeFunction (base, p);
639 ctype ctype_expectFunction (ctype c)
641 /* handle parenthesized declarations */
645 c = ctype_makePointer (c);
648 return (cttable_addComplex (ctbase_expectFunction (c)));
651 ctype ctype_dontExpectFunction (ctype c)
653 ctbase ctb = ctype_getCtbase (c);
658 c = ctype_makePointer (c);
662 return (ctbase_getExpectFunction (ctb));
666 ** makeRealFunction: function returning base
669 ctype ctype_makeRawFunction (ctype base, uentryList p)
671 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
679 **** this is very poorly defined
681 **** need to unify function/function pointer meaning
685 ctype_isFunction (ctype c)
687 if (ctype_isKnown (c) && ctype_isDefined (c))
689 return (ctbase_isFunction (ctype_getCtbase (c)));
698 ctype_isExpFcn (ctype c)
700 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
704 ctype_isVoid (ctype c)
706 return (c == CTX_VOID);
710 ctype_isArbitraryIntegral (ctype c)
712 ctype cr = ctype_realType (c);
714 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
715 || cr == ctype_signedintegral);
719 ctype_isUnsignedIntegral (ctype c)
721 ctype cr = ctype_realType (c);
723 return (cr == ctype_unsignedintegral);
727 ctype_isSignedIntegral (ctype c)
729 ctype cr = ctype_realType (c);
731 return (cr == ctype_signedintegral);
735 ctype_isInt (ctype c)
737 cprim cp = ctype_toCprim (c);
739 return (c == ctype_unknown || cprim_isAnyInt (cp)
740 || (cprim_isAnyChar (cp) && context_msgCharInt ())
741 || (c == ctype_bool && context_msgBoolInt ())
742 || (ctype_isEnum (c) && context_msgEnumInt ()));
746 ctype_isRegularInt (ctype c)
748 cprim cp = ctype_toCprim (c);
750 return (c == ctype_unknown
751 || cprim_closeEnough (cprim_int, cp)
752 || (cprim_isAnyChar (cp) && context_msgCharInt ())
753 || (c == ctype_bool && context_msgBoolInt ())
754 || (ctype_isEnum (c) && context_msgEnumInt ()));
758 ctype_isString (ctype c)
760 return (c == ctype_string
761 || (ctype_isPointer (c)
762 && ctype_isChar (ctype_baseArrayPtr (c))));
766 ctype_isChar (ctype c)
768 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
769 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
773 ctype_isUnsignedChar (ctype c)
775 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
779 ctype_isSignedChar (ctype c)
781 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
785 ** Returns true if c matches the name -booltype <bool>
789 ctype_isManifestBool (ctype c)
792 ** Changed the meaning of ctype_isBool - evs 2000-07-24
793 ** The old meaning was very convoluted!
796 ** c == CTX_BOOL - its a direct bool
797 ** c is a user/abstract type matching the bool name
798 ** (should never occur?)
801 if (ctype_isDirectBool (c)) {
803 } else if (ctype_isUA (c)) {
804 return ctype_isUserBool (c);
811 ctype_isBool (ctype c)
814 ** Changed the meaning of ctype_isBool - evs 2000-07-24
815 ** The old meaning was very convoluted!
818 ** its a manifest bool
819 ** +boolint and ctype_isInt (c)
822 if (ctype_isManifestBool (c)) {
824 } else if (context_msgBoolInt ()) {
825 return ctype_isInt (c);
831 if (context_getFlag (FLG_ABSTRACTBOOL))
833 if (typeId_isInvalid (boolType))
835 boolType = usymtab_getTypeId (context_getBoolName ());
838 if (context_hasAccess (boolType))
840 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
841 || (context_msgBoolInt ()
843 || (c == CTX_CHAR && context_msgCharInt ()))))
848 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
849 || (context_msgBoolInt ()
850 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
855 ctype_isDirectBool (ctype c)
857 return (c == CTX_BOOL);
861 ctype_isReal (ctype c)
863 return (cprim_isAnyReal (ctype_toCprim (c)));
867 ctype_isFloat (ctype c)
869 return (c == ctype_float);
873 ctype_isDouble (ctype c)
875 return (c == ctype_double || c == ctype_ldouble);
879 ctype_isSigned (ctype c)
881 return (!ctype_isUnsigned (c));
885 ctype_isNumeric (ctype c)
887 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
888 /* evans 2001-10-05: added this: */
889 || ctype_isArbitraryIntegral (c));
896 ** work on actual type in current context
900 ctype_isRealNumeric (ctype c)
902 if (ctype_isPlain (c))
903 return (ctype_isNumeric (ctype_realType (c)));
904 if (ctype_isConj (c))
905 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
906 ctype_isRealNumeric (ctype_getConjB (c)));
912 ctype_isRealInt (ctype c)
914 if (ctype_isPlain (c))
915 return (ctype_isInt (ctype_realType (c)));
916 else if (ctype_isConj (c))
917 return (ctype_isRealInt (ctype_getConjA (c)) ||
918 ctype_isRealInt (ctype_getConjB (c)));
921 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
927 ctype_isRealVoid (ctype c)
929 if (ctype_isPlain (c))
931 return (ctype_isVoid (ctype_realType (c)));
933 else if (ctype_isConj (c))
935 return (ctype_isRealVoid (ctype_getConjA (c)) ||
936 ctype_isRealVoid (ctype_getConjB (c)));
945 ctype_isRealBool (ctype c)
947 if (ctype_isPlain (c))
949 return (ctype_isBool (ctype_realishType (c)));
951 else if (ctype_isConj (c))
953 return (ctype_isRealBool (ctype_getConjA (c)) ||
954 ctype_isRealBool (ctype_getConjB (c)));
963 ctype_isRealPointer (ctype c)
965 if (ctype_isConj (c))
966 return (ctype_isRealPointer (ctype_getConjA (c)) ||
967 ctype_isRealPointer (ctype_getConjB (c)));
968 return (ctype_isPointer (ctype_realType (c)));
972 ctype_isRealSU (ctype c)
974 if (ctype_isConj (c))
976 return (ctype_isRealSU (ctype_getConjA (c)) ||
977 ctype_isRealSU (ctype_getConjB (c)));
980 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
981 return (ctype_isStructorUnion (ctype_realType (c)));
985 ctype_isRealArray (ctype c)
987 if (ctype_isConj (c))
988 return (ctype_isRealArray (ctype_getConjA (c)) ||
989 ctype_isRealArray (ctype_getConjB (c)));
990 return (ctype_isArray (ctype_realType (c)));
994 ctype_isRealAP (ctype c)
996 if (ctype_isConj (c))
997 return (ctype_isRealAP (ctype_getConjA (c)) ||
998 ctype_isRealAP (ctype_getConjB (c)));
999 return (ctype_isAP (ctype_realType (c)));
1003 ctype_isRealFunction (ctype c)
1005 if (ctype_isConj (c))
1006 return (ctype_isRealFunction (ctype_getConjA (c)) ||
1007 ctype_isRealFunction (ctype_getConjB (c)));
1008 return (ctype_isFunction (ctype_realType (c)));
1012 ctype_isDirectInt (ctype c)
1014 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
1018 ** forceful predicates
1020 ** take *ctype; if its a conjunct, and there is a match replace with match only.
1021 ** if both match, still conjunct
1025 ctype_isForcePred (ctype * c, bool (pred) (ctype))
1027 /*drl bee: pbr */ if (ctype_isConj (*c))
1029 ctype cbr = ctype_getConjA (*c);
1031 /*drl bee: si*/ if ((*pred) (cbr))
1033 if ((*pred) (ctype_getConjB (*c)))
1046 if ((*pred) (cbr = ctype_getConjB (*c)))
1054 return ((*pred) (*c));
1058 ctype_isForceRealNumeric (ctype * c)
1060 return (ctype_isForcePred (c, ctype_isRealNumeric));
1064 ctype_isForceRealInt (ctype * c)
1066 return (ctype_isForcePred (c, ctype_isRealInt));
1070 ctype_isForceRealBool (ctype * c)
1072 return (ctype_isForcePred (c, ctype_isRealBool));
1078 ** save int/char, int/bool, other random conjuncts
1082 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
1084 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
1088 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1096 return (ctype_makeExplicitConj (c1, c2));
1100 return (ctype_makeConj (c1, c2));
1106 ctype_makeExplicitConj (ctype c1, ctype c2)
1108 if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1110 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
1112 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1114 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1116 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
1118 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1122 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1126 static ctype ic = ctype_unknown; /* int | char */
1127 static ctype ib = ctype_unknown; /* int | bool */
1128 static ctype ifl = ctype_unknown; /* int | float */
1129 static ctype ibf = ctype_unknown; /* int | bool | float */
1130 static ctype ibc = ctype_unknown; /* int | bool | char */
1131 static ctype iv = ctype_unknown; /* int | void * */
1132 static ctype ivf = ctype_unknown; /* int | void * | float */
1133 static ctype ivb = ctype_unknown; /* int | void * | bool */
1134 static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1135 static ctype cuc = ctype_unknown; /* char | unsigned char */
1138 ctype_recordConj (ctype c)
1142 llassert (ctype_isConj (c));
1144 c1 = ctype_getConjA (c);
1145 c2 = ctype_getConjB (c);
1148 if (c2 == ctype_int && c1 != ctype_int)
1158 if (c1 == ctype_int)
1160 if (c2 == ctype_char)
1162 llassert (ic == ctype_unknown);
1165 else if (c2 == ctype_bool)
1167 llassert (ib == ctype_unknown);
1170 else if (c2 == ctype_float)
1172 llassert (ifl == ctype_unknown);
1175 else if (c2 == CTP_VOID)
1177 llassert (iv == ctype_unknown);
1185 else if (c1 == ib && ib != ctype_unknown)
1187 if (c2 == ctype_float)
1189 llassert (ibf == ctype_unknown);
1192 else if (c2 == ctype_char)
1194 llassert (ibc == ctype_unknown);
1204 if (c2 == ctype_bool)
1206 llassert (ivb == ctype_unknown);
1209 else if (c2 == ctype_float)
1211 llassert (ivf == ctype_unknown);
1221 if (c2 == ctype_bool)
1223 llassert (ivbf == ctype_unknown);
1229 if (c2 == ctype_float)
1231 llassert (ivbf == ctype_unknown);
1235 else if (c1 == ctype_char)
1237 if (c2 == ctype_uchar)
1239 llassert (cuc == ctype_unknown);
1251 ctype_makeConj (ctype c1, ctype c2)
1253 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1255 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1257 if (ctype_isUnknown (c1))
1261 else if (ctype_isUnknown (c2))
1265 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1267 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
1268 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1270 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1272 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
1273 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1277 if (ctype_isManifestBool (c1))
1282 if (ctype_isManifestBool (c2))
1287 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1289 c1 = ctype_voidPointer;
1292 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1294 c2 = ctype_voidPointer;
1298 ** Ouch, can't do this. unsigned, etc. modifiers might
1299 ** apply to wrong type!
1301 ** if (c2 == ctype_int && c1 != ctype_int)
1312 if (c1 == ctype_int)
1314 if (c2 == ctype_char)
1316 if (ic == ctype_unknown)
1318 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1323 else if (c2 == ctype_bool)
1325 if (ib == ctype_unknown)
1327 ib = cttable_addComplex
1328 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1333 else if (c2 == ctype_float)
1335 if (ifl == ctype_unknown)
1337 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1344 if (c2 == ctype_voidPointer)
1346 if (iv == ctype_unknown)
1348 iv = cttable_addComplex
1349 (ctbase_makeConj (ctype_int,
1358 else if (c1 == ib && ib != ctype_unknown)
1360 if (c2 == ctype_float)
1362 if (ibf == ctype_unknown)
1364 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1369 else if (c2 == ctype_char)
1371 if (ibc == ctype_unknown)
1373 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1385 if (c2 == ctype_bool)
1387 if (ivb == ctype_unknown)
1389 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1394 else if (c2 == ctype_float)
1396 if (ivf == ctype_unknown)
1398 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1410 if (c2 == ctype_bool)
1412 if (ivbf == ctype_unknown)
1414 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1422 if (c2 == ctype_float)
1424 if (ivbf == ctype_unknown)
1426 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1432 else if (c1 == ctype_char)
1434 if (c2 == ctype_uchar)
1436 if (cuc == ctype_unknown)
1438 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1450 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1456 ctype_isConj (ctype c)
1458 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1462 ctype_getConjA (ctype c)
1464 if (!ctype_isConj (c))
1465 llbuglit ("ctype_getConjA: not a conj");
1466 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1470 ctype_getConjB (ctype c)
1472 if (!ctype_isConj (c))
1473 llbuglit ("ctype_getConjB: not a conj");
1474 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1478 ctype_isExplicitConj (ctype c)
1480 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1483 /** << need to fix resolveConj >> **/
1486 ** structs and unions
1490 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1494 DPRINTF (("Creating a struct: %s / %s",
1495 n, uentryList_unparse (f)));
1497 ct = cttable_addComplex (ctbase_createStruct (n, f));
1498 DPRINTF (("ct: %s", ctype_unparse (ct)));
1503 ctype_getFields (ctype c)
1505 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1509 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1513 ret = cttable_addComplex (ctbase_createUnion (n, f));
1520 ** if ctype's are same, definite match.
1521 ** else, need to call ctbase_match.
1523 ** if necessary context can memoize matches
1527 quickMatch (ctype c1, ctype c2)
1536 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1540 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1542 if (quickMatch (c1, c2))
1547 if (ctype_isElips (c1) || ctype_isElips (c2))
1553 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1559 ctype_sameName (ctype c1, ctype c2)
1561 if (quickMatch (c1, c2))
1564 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1568 ctype_almostEqual (ctype c1, ctype c2)
1570 if (ctype_equal (c1, c2))
1576 if (ctype_isUnknown (c1))
1578 return ctype_isUnknown (c2);
1580 else if (ctype_isUnknown (c2))
1586 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1592 ctype_matchDef (ctype c1, ctype c2)
1594 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1596 if (quickMatch (c1, c2))
1599 if (ctype_isElips (c1))
1600 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1602 if (ctype_isElips (c2))
1604 return (ctype_isUnknown (c2));
1608 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1611 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1612 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1613 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1618 bool ctype_match (ctype c1, ctype c2)
1620 if (quickMatch (c1, c2))
1623 if (ctype_isElips (c1))
1624 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1626 if (ctype_isElips (c2))
1627 return (ctype_isUnknown (c2));
1629 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1633 ctype_forceMatch (ctype c1, ctype c2)
1635 if (quickMatch (c1, c2))
1638 if (ctype_isElips (c1))
1639 return (ctype_isElips (c2));
1641 if (ctype_isElips (c2))
1645 /* The call forceMatch may modify the observer params, but, we don't care. */
1646 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1651 ctype_matchArg (ctype c1, ctype c2)
1653 if (quickMatch (c1, c2))
1659 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1664 ** simple ctype_is operations.
1665 ** DO NOT use real type of c, only direct type.
1669 ** ctype_isVoidPointer
1675 ctype_isVoidPointer (ctype c)
1677 if (ctype_isComplex (c))
1679 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1681 if (ctype_isConj (c))
1683 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1684 ctype_isVoidPointer (ctype_getConjB (c)));
1688 return (c == ctype_voidPointer
1689 || (ctype_isRealPointer (c)
1690 && ctype_isVoid (ctype_baseArrayPtr (c))));
1697 ** true for C and LCL pointers
1701 ctype_isPointer (ctype c)
1703 if (ctype_isElips (c)) return FALSE;
1705 if (ctype_isComplex (c))
1707 ctbase ctb = ctype_getCtbaseSafe (c);
1708 bool res = ctbase_isPointer (ctb);
1714 bool res = ctentry_isPointer (ctype_getCtentry (c));
1723 ** true for C and LCL array's
1727 ctype_isArray (ctype c)
1729 if (ctype_isElips (c)) return FALSE;
1731 if (ctype_isComplex (c))
1732 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1734 return (ctentry_isArray (ctype_getCtentry (c)));
1737 bool ctype_isIncompleteArray (ctype c)
1739 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1743 ctype_isArrayPtr (ctype c)
1745 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1749 ctype_typeId (ctype c)
1751 return (ctbase_typeId (ctype_getCtbase (c)));
1755 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1757 llassert (! (ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1759 if (ctype_isUnknown (c))
1761 return message ("? %q", name);
1765 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1770 ctype_unparse (ctype c)
1772 if (ctype_isElips (c))
1774 return cstring_makeLiteralTemp ("...");
1776 else if (ctype_isMissingParamsMarker (c))
1778 return cstring_makeLiteralTemp ("-");
1780 else if (ctype_isUnknown (c))
1782 return cstring_makeLiteralTemp ("?");
1787 return (ctentry_doUnparse (ctype_getCtentry (c)));
1793 ctype_unparseSafe (ctype c)
1795 if (ctype_isElips (c))
1797 return cstring_makeLiteralTemp ("...");
1799 else if (ctype_isMissingParamsMarker (c))
1801 return cstring_makeLiteralTemp ("-");
1807 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1809 ctentry cte = ctype_getCtentry (c);
1811 if (cstring_isDefined (cte->unparse))
1813 return (cte->unparse);
1817 ret = message ("[%d]", (int) c);
1818 cstring_markOwned (ret);
1824 ctype_unparseDeep (ctype c)
1826 if (ctype_isElips (c))
1828 return cstring_makeLiteralTemp ("...");
1830 if (ctype_isMissingParamsMarker (c))
1832 return cstring_makeLiteralTemp ("-");
1835 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1839 ctype_undump (char **c)
1841 return ((ctype) reader_getInt (c)); /* check its valid? */
1845 ctype_dump (ctype c)
1847 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1851 /* Handle invalid types in a kludgey way. */
1852 return (message ("0"));
1857 cstring tname = usymtab_getTypeEntryName
1858 (usymtab_convertId (ctype_typeId (c)));
1860 if (cstring_equal (tname, context_getBoolName ()))
1862 cstring_free (tname);
1863 return (message ("%d", ctype_bool));
1866 cstring_free (tname);
1869 DPRINTF (("Returning: %d", c));
1870 return (message ("%d", c));
1874 ctype_getBaseType (ctype c)
1876 ctentry cte = ctype_getCtentry (c);
1878 switch (ctentry_getKind (cte))
1886 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1889 ctbase ctb = cte->ctbase;
1891 if (ctbase_isDefined (ctb))
1910 return (ctype_getBaseType (ctb->contents.base));
1912 return (ctype_getBaseType (ctb->contents.farray->base));
1913 case CT_CONJ: /* base type of A conj branch? */
1914 return (ctype_getBaseType (ctb->contents.conj->a));
1916 /*@noaccess ctbase@*/
1924 llbuglit ("ctype_newBase: bad case");
1926 llcontbuglit ("ctype_getBaseType: unreachable code");
1927 return ((ctype)NULL);
1931 ctype_adjustPointers (int np, ctype c)
1934 if (ctype_isFunction (c))
1936 c = ctype_makeParamsFunction
1937 (ctype_adjustPointers (np, ctype_getReturnType (c)),
1938 uentryList_copy (ctype_argsFunction (c)));
1942 /* fix this should not use getBaseType ??? */
1943 ctype cb = ctype_getBaseType (c);
1947 cb = ctype_makePointer (cb);
1950 c = ctype_newBase (c, cb);
1958 ctype_elist (ctype c)
1960 return (ctbase_elist (ctype_getCtbase (c)));
1964 ctype_isFirstVoid (ctype c)
1966 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
1970 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
1972 return (cttable_addComplex (ctbase_createEnum (tag, el)));
1976 ctype_isEnum (ctype c)
1978 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
1982 ctype_enumTag (ctype c)
1984 llassert (ctype_isEnum (c));
1986 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
1990 ctype_isStruct (ctype c)
1992 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
1996 ctype_isUnion (ctype c)
1998 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2002 ctype_resolveNumerics (ctype c1, ctype c2)
2005 ** returns longest type of c1 and c2
2008 if (c1 == c2) return c1;
2010 c1 = ctype_realType (c1);
2011 c2 = ctype_realType (c2);
2013 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2014 if (ctype_isEnum (c2)) c2 = ctype_int;
2016 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2018 /* 2001-06-08: This fix provided by Jim Zelenka. */
2019 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2020 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2022 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2023 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2024 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2025 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2027 /* 2001-06-08: This fix provided by Jim Zelenka. */
2028 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2030 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2032 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2033 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2035 if (ctype_isKnown (c1)) return c1;
2040 ctype_isStructorUnion (ctype c)
2042 return (ctype_isStruct (c) || ctype_isUnion (c));
2046 ctype_fixArrayPtr (ctype c)
2048 if (ctype_isArray (c))
2050 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2057 ** createUnnamedStruct/Union
2059 ** check if it corresponds to an existing LCL-specified unnamed struct
2060 ** otherwise, give it a new tag
2064 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2066 ctype ret = usymtab_structFieldsType (f);
2068 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2070 if (ctype_isDefined (ret))
2072 uentryList_free (f);
2077 cstring ft = fakeTag ();
2078 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2079 uentry ue = uentry_makeStructTagLoc (ft, ct);
2081 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2082 ue = usymtab_supGlobalEntryReturn (ue);
2083 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2091 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2093 ctype ret = usymtab_unionFieldsType (f);
2095 if (ctype_isDefined (ret))
2097 uentryList_free (f);
2102 cstring ft = fakeTag ();
2103 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2104 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2106 usymtab_supGlobalEntry (ue);
2113 ctype_isUnnamedSU (ctype c)
2117 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2126 ctype_createForwardStruct (cstring n)
2128 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2129 ctype ct = usymtab_supForwardTypeEntry (ue);
2136 ctype_createForwardUnion (cstring n)
2138 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2139 ctype ct = usymtab_supForwardTypeEntry (ue);
2146 ctype_removePointers (ctype c)
2150 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2153 c = ctype_baseArrayPtr (c);
2154 llassert (c != oldc);
2160 bool ctype_isMutable (ctype t)
2164 return (uentry_isMutableDatatype
2165 (usymtab_getTypeEntry (ctype_typeId (t))));
2169 return (ctype_isPointer (ctype_realType (t)));
2170 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2174 bool ctype_isRefCounted (ctype t)
2178 return (uentry_isRefCountedDatatype
2179 (usymtab_getTypeEntry (ctype_typeId (t))));
2185 bool ctype_isVisiblySharable (ctype t)
2187 if (ctype_isUnknown (t)) return TRUE;
2189 if (ctype_isConj (t))
2191 return (ctype_isVisiblySharable (ctype_getConjA (t))
2192 || ctype_isVisiblySharable (ctype_getConjB (t)));
2195 if (ctype_isMutable (t))
2199 ctype rt = ctype_realType (t);
2207 return ctype_isVisiblySharable (rt);
2221 /* Replaced by ctype_isMutable (more sensible) */
2222 bool ctype_canAlias (ctype ct)
2224 /* can ct refer to memory locations?
2225 ** ==> a pointer or a mutable abstract type
2229 ctype tr = ctype_realType (ct);
2231 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2236 ** c1 is the dominant type; c2 is the modifier type
2238 ** eg. double + long int => long double
2241 ctype ctype_combine (ctype dominant, ctype modifier)
2243 DPRINTF (("Combine: %s + %s",
2244 ctype_unparse (dominant),
2245 ctype_unparse (modifier)));
2247 if (ctype_isConj (dominant))
2251 if (ctype_isExplicitConj (dominant))
2253 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2255 ctype_getConjB (dominant));
2259 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2261 ctype_getConjB (dominant));
2267 if (ctype_isUnknown (modifier))
2271 else if (ctype_isUnknown (dominant))
2277 if (ctype_isEnum (dominant)) dominant = ctype_int;
2278 if (ctype_isEnum (modifier)) modifier = ctype_int;
2280 if (modifier == ctype_uint)
2282 if (dominant == ctype_int) return ctype_uint;
2283 if (dominant == ctype_lint) return ctype_ulint;
2284 if (dominant == ctype_sint) return ctype_usint;
2285 if (dominant == ctype_char) return ctype_uchar;
2287 /* evs 2000-07-28: added this line */
2288 if (dominant == ctype_llint) return ctype_ullint;
2290 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2292 voptgenerror (FLG_DUPLICATEQUALS,
2293 message ("Duplicate unsigned qualifier"),
2300 voptgenerror (FLG_DUPLICATEQUALS,
2301 message ("Type qualifier unsigned used with %s",
2302 ctype_unparse (dominant)),
2308 else if (modifier == ctype_llint)
2310 if (dominant == ctype_int)
2315 voptgenerror (FLG_DUPLICATEQUALS,
2316 message ("Duplicate long qualifier on non-int"),
2319 else if (modifier == ctype_lint)
2321 if (dominant == ctype_int) return ctype_lint;
2322 if (dominant == ctype_uint) return ctype_ulint;
2323 if (dominant == ctype_double) return ctype_ldouble;
2325 if (dominant == ctype_lint || dominant == ctype_ulint
2326 || dominant == ctype_sint || dominant == ctype_usint
2327 || dominant == ctype_ldouble)
2329 if (dominant == ctype_lint)
2331 /* long long not supported by ANSI */
2336 if (dominant == ctype_ulint)
2338 /* unsigned long long not supported by ANSI */
2339 return ctype_ullint;
2343 if (dominant == ctype_sint || dominant == ctype_usint)
2345 if (!context_getFlag (FLG_IGNOREQUALS))
2347 llerrorlit (FLG_SYNTAX,
2348 "Contradictory long and short type qualifiers");
2353 voptgenerror (FLG_DUPLICATEQUALS,
2354 message ("Duplicate long qualifier"),
2361 else if (modifier == ctype_sint)
2363 if (dominant == ctype_int) return ctype_sint;
2364 if (dominant == ctype_uint) return ctype_usint;
2366 if (dominant == ctype_sint || dominant == ctype_usint)
2368 voptgenerror (FLG_DUPLICATEQUALS,
2369 message ("Duplicate short qualifier"),
2373 else if (dominant == ctype_lint)
2375 if (!context_getFlag (FLG_IGNOREQUALS))
2377 llerrorlit (FLG_SYNTAX,
2378 "Contradictory long and short type qualifiers");
2384 else if (dominant == ctype_llint)
2386 if (!context_getFlag (FLG_IGNOREQUALS))
2388 llerrorlit (FLG_SYNTAX,
2389 "Contradictory long long and short type qualifiers");
2397 if (!context_getFlag (FLG_IGNOREQUALS))
2399 llerror (FLG_SYNTAX,
2400 message ("Type qualifier short used with %s",
2401 ctype_unparse (dominant)));
2407 else if (modifier == ctype_ulint)
2409 if (dominant == ctype_int) return modifier;
2411 if (dominant == ctype_lint || dominant == ctype_ulint)
2413 voptgenerror (FLG_DUPLICATEQUALS,
2414 message ("Duplicate long qualifier"),
2420 if (dominant == ctype_uint || dominant == ctype_usint)
2422 voptgenerror (FLG_DUPLICATEQUALS,
2423 message ("Duplicate unsigned qualifier"),
2429 if (dominant == ctype_sint || dominant == ctype_usint)
2431 if (!context_getFlag (FLG_IGNOREQUALS))
2433 llerrorlit (FLG_SYNTAX,
2434 "Contradictory long and short type qualifiers");
2440 if (!context_getFlag (FLG_IGNOREQUALS))
2442 llerror (FLG_SYNTAX,
2443 message ("Type qualifiers unsigned long used with %s",
2444 ctype_unparse (dominant)));
2449 else if (modifier == ctype_usint)
2451 if (dominant == ctype_int) return modifier;
2453 if (dominant == ctype_sint || dominant == ctype_usint)
2455 voptgenerror (FLG_DUPLICATEQUALS,
2456 message ("Duplicate short qualifier"),
2461 if (dominant == ctype_uint)
2463 voptgenerror (FLG_DUPLICATEQUALS,
2464 message ("Duplicate unsigned qualifier"),
2470 if (dominant == ctype_lint || dominant == ctype_ulint
2471 || dominant == ctype_llint)
2473 if (!context_getFlag (FLG_IGNOREQUALS))
2475 llerrorlit (FLG_SYNTAX,
2476 "Contradictory long and short type qualifiers");
2482 if (!context_getFlag (FLG_IGNOREQUALS))
2484 llerror (FLG_SYNTAX,
2485 message ("Type qualifiers unsigned short used with %s",
2486 ctype_unparse (dominant)));
2500 ctype ctype_resolve (ctype c)
2502 if (ctype_isUnknown (c)) return ctype_int;
2506 ctype ctype_fromQual (qual q)
2508 if (qual_isSigned (q)) return ctype_int;
2509 if (qual_isUnsigned (q)) return ctype_uint;
2510 if (qual_isLong (q)) return ctype_lint;
2511 if (qual_isShort (q)) return ctype_sint;
2513 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2514 return ctype_unknown;
2518 ctype_isAnyFloat (ctype c)
2520 return (cprim_isAnyReal (ctype_toCprim (c)));
2524 ctype_isUnsigned (ctype c)
2526 if (ctype_isConj (c))
2527 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2528 ctype_isUnsigned (ctype_getConjB (c)));
2530 return (c == ctype_uint || c == ctype_uchar
2531 || c == ctype_usint || c == ctype_ulint
2532 || c == ctype_ullint
2533 || c == ctype_unsignedintegral);
2538 ctype_isLongLong (ctype c)
2540 if (ctype_isConj (c))
2541 return (ctype_isLongLong (ctype_getConjA (c)) ||
2542 ctype_isLongLong (ctype_getConjB (c)));
2544 return (c == ctype_llint || c == ctype_ullint);
2549 ctype_isLong (ctype c)
2551 if (ctype_isConj (c))
2552 return (ctype_isLong (ctype_getConjA (c)) ||
2553 ctype_isLong (ctype_getConjB (c)));
2555 return (c == ctype_lint || c == ctype_ulint);
2559 ctype_isShort (ctype c)
2561 if (ctype_isConj (c))
2562 return (ctype_isShort (ctype_getConjA (c)) ||
2563 ctype_isShort (ctype_getConjB (c)));
2565 return (c == ctype_sint || c == ctype_usint);
2569 ctype_isStackAllocated (ctype c)
2571 ctype ct = ctype_realType (c);
2573 if (ctype_isConj (ct))
2574 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2575 ctype_isStackAllocated (ctype_getConjB (ct)));
2577 return (ctype_isArray (c) || ctype_isSU (c));
2580 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2582 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2585 static bool ctype_isLonger (ctype c1, ctype c2)
2587 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2588 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2589 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2590 || (ctype_isLong (c1)
2591 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2592 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2596 ctype_widest (ctype c1, ctype c2)
2598 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2608 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2611 if (c >= 0 && c < cttab.size)
2613 return (cttab.entries[c]->ctbase);
2617 if (c == ctype_unknown)
2618 llbuglit ("ctype_getCtbase: ctype unknown");
2619 if (c == ctype_undefined)
2620 llbuglit ("ctype_getCtbase: ctype undefined");
2622 llbuglit ("ctype_getCtbase: ctype dne");
2623 if (c == ctype_elipsMarker)
2624 llbuglit ("ctype_getCtbase: elips marker");
2626 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2633 static /*@notnull@*/ /*@observer@*/ ctbase
2634 ctype_getCtbaseSafe (ctype c)
2636 ctbase res = ctype_getCtbase (c);
2638 llassert (ctbase_isDefined (res));
2647 ctype_getCtentry (ctype c)
2649 static /*@only@*/ ctentry errorEntry = NULL;
2651 if (cttab.size == 0)
2653 if (errorEntry == NULL)
2655 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2662 if (c >= CTK_PLAIN && c < cttab.size)
2664 return (cttab.entries[c]);
2666 else if (c == CTK_UNKNOWN)
2667 llcontbuglit ("ctype_getCtentry: ctype unknown");
2668 else if (c == CTK_INVALID)
2669 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2670 else if (c == CTK_DNE)
2671 llcontbuglit ("ctype_getCtentry: ctype dne");
2672 else if (c == CTK_ELIPS)
2673 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2674 else if (c == CTK_MISSINGPARAMS)
2675 llcontbuglit ("ctype_getCtentry: ctype missing params");
2677 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2679 return (cttab.entries[ctype_unknown]);
2684 bool ctype_isFixedArray (ctype c)
2686 if (ctype_isElips (c)) return FALSE;
2688 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2693 /* requires that the type is an fixed array */
2694 /* return the size of the array */
2696 long int ctype_getArraySize (ctype c)
2702 llassert (ctype_isFixedArray (c));
2704 ctb = ctype_getCtbaseSafe(c);
2705 size = ctbase_getArraySize (ctb);
2707 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",