2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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
161 (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u))));
165 ctype_createNumAbstract (typeId u)
167 /* requires: ctype_createAbstract (u) is never called more than once for any u. */
168 /* [ tested by cttable_addFullSafe, not really required ] */
170 return (cttable_addFullSafe
171 (ctentry_makeNew (CTK_PLAIN, ctbase_createNumAbstract (u))));
181 ctype_realType (ctype c)
185 if (ctype_isElips (c) || ctype_isMissingParamsMarker (c))
192 r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c)));
195 if (ctype_isManifestBool (r))
197 if (context_canAccessBool ())
199 r = context_boolImplementationType ();
207 ctype_isSimple (ctype c)
209 return (! (ctype_isPointer (c)
211 || ctype_isFunction (c)));
215 ctype_forceRealType (ctype c)
221 r = uentry_getForceRealType (usymtab_getTypeEntry (ctype_typeId (c)));
228 ctype_realishType (ctype c)
232 if (ctype_isManifestBool (c))
238 ctype r = uentry_getRealType (usymtab_getTypeEntry
250 return (!ctype_isUnknown (c)
251 && ctbase_isUA (ctype_getCtbase (c)));
255 ctype_isUser (ctype c)
257 return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c)));
261 ctype_isAbstract (ctype c)
263 return (!ctype_isUnknown (c)
264 && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
266 (ctype_isAbstract (ctype_getConjA (c))
267 || ctype_isAbstract (ctype_getConjB (c))))));
271 ctype_isNumAbstract (ctype c)
273 return (!ctype_isUnknown (c)
274 && ((ctype_isPlain (c) && ctbase_isNumAbstract (ctype_getCtbaseSafe (c))) ||
276 (ctype_isNumAbstract (ctype_getConjA (c))
277 || ctype_isNumAbstract (ctype_getConjB (c))))));
281 ctype_isImmutableAbstract (ctype t)
283 return (ctype_isAbstract (t) && !ctype_isMutable (t));
287 ctype_isRealAbstract (ctype c)
289 return (ctype_isAbstract (ctype_realType (c)) ||
291 (ctype_isRealAbstract (ctype_getConjA (c)) ||
292 ctype_isRealAbstract (ctype_getConjB (c)))));
296 ctype_isRealNumAbstract (ctype c)
298 return (ctype_isNumAbstract (ctype_realType (c)) ||
300 (ctype_isRealNumAbstract (ctype_getConjA (c)) ||
301 ctype_isRealNumAbstract (ctype_getConjB (c)))));
305 ** primitive creators
309 ** createPrim not necessary --- subsumed by ctype_int, etc.
313 ** ctbase_unknown --- removed argument
318 ** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
322 ctype_makePointer (ctype c)
328 else if (c == ctype_void)
330 return ctype_voidPointer;
334 ctentry cte = ctype_getCtentry (c);
335 ctype clp = ctentry_getPtr (cte);
337 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
339 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
340 ctentry_setPtr (cte, cnew);
350 ctype ctype_makeFixedArray (ctype c, size_t size)
353 res = cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c);
358 ** In C, array terms appear backwards:
362 ** declares an array of 5 elements, each of which is
363 ** an array of 7 int's.
365 ** We represent this as,
367 ** array (array (int, 7), 5)
369 ** Hence, the rightmost declaration is the innermost type.
372 ctype ctype_makeInnerFixedArray (ctype c, size_t size)
376 DPRINTF (("makeinnerfixed: %s / %d", ctype_unparse (c), size));
378 if (ctype_isFixedArray (c))
380 ctype cb = ctype_baseArrayPtr (c);
381 size_t osize = ctype_getArraySize (c);
383 res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize);
384 DPRINTF (("res 1: %s", ctype_unparse (res)));
386 else if (ctype_isArray (c))
388 ctype cb = ctype_baseArrayPtr (c);
390 res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
391 DPRINTF (("res 2: %s", ctype_unparse (res)));
395 res = ctype_makeFixedArray (c, size);
396 DPRINTF (("res 3: %s", ctype_unparse (res)));
399 DPRINTF (("Make inner fixed array: %s / base: %s",
400 ctype_unparse (res), ctype_unparse (ctype_baseArrayPtr (res))));
404 ctype ctype_makeInnerArray (ctype c)
408 DPRINTF (("Make inner array: %s", ctype_unparse (c)));
410 if (ctype_isFixedArray (c))
412 ctype cb = ctype_baseArrayPtr (c);
413 size_t osize = ctype_getArraySize (c);
415 res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize);
417 else if (ctype_isArray (c))
419 ctype cb = ctype_baseArrayPtr (c);
420 res = ctype_makeArray (ctype_makeInnerArray (cb));
424 res = ctype_makeArray (c);
427 DPRINTF (("Make inner array: %s", ctype_unparse (res)));
432 ctype_makeArray (ctype c)
434 ctentry cte = ctype_getCtentry (c);
435 ctype clp = ctentry_getArray (cte);
437 DPRINTF (("Make array: %s", ctype_unparse (c)));
439 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
441 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
442 ctentry_setArray (cte, cnew);
452 ** requires c is a pointer of array
456 ctype_baseArrayPtr (ctype c)
458 ctentry cte = ctype_getCtentry (ctype_realType (c));
460 if (ctype_isConj (c))
462 if (ctype_isAP (ctype_getConjA (c)))
464 if (ctype_isAP (ctype_getConjB (c)))
466 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
467 ctype_baseArrayPtr (ctype_getConjB (c))));
471 return (ctype_baseArrayPtr (ctype_getConjA (c)));
476 return (ctype_baseArrayPtr (ctype_getConjB (c)));
479 else if (ctype_isInt (c)) /* could be NULL */
481 return ctype_unknown;
485 ctype clp = ctentry_getBase (cte);
487 if (ctype_isBroken (clp))
489 llcontbug (message ("ctype_baseArrayPtr: bogus ctype getting base of: %s", ctype_unparse (c)));
490 return ctype_unknown;
502 ctype_makeWideString ()
504 static ctype res = ctype_unknown;
506 if (ctype_isUnknown (res))
510 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
512 wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
519 res = ctype_makePointer (wchart);
526 ctype_isWideString (ctype c)
528 if (ctype_isPointer (c))
530 ctype ct = ctype_baseArrayPtr (c);
532 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
534 return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
548 ctype_getReturnType (ctype c)
550 if (ctype_isUnknown (c))
552 return ctype_unknown;
555 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
559 ** must be a shared pointer
562 /*@observer@*/ uentryList
563 ctype_argsFunction (ctype c)
565 if (ctype_isUnknown (c))
567 return uentryList_undefined;
570 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
574 ** Returns type with base type p and compound types from c.
576 ** i.e., c = char *[]; p = int
581 ctype_newBase (ctype c, ctype p)
583 return (ctbase_newBase (c, p));
587 ctype_sameAltTypes (ctype c1, ctype c2)
592 llassert (ctype_isConj (c1) && ctype_isConj (c2));
594 c1a = ctype_getConjA (c1);
595 c2a = ctype_getConjA (c2);
597 c1b = ctype_getConjB (c1);
598 c2b = ctype_getConjB (c2);
600 if (ctype_compare (c1a, c2a) == 0)
602 if (ctype_compare (c1b, c2b) == 0)
608 if (ctype_isConj (c1b) && ctype_isConj (c2b))
610 return ctype_sameAltTypes (c1b, c2b);
620 if (ctype_compare (c1a, c2b) == 0)
622 if (ctype_compare (c1b, c2a) == 0)
628 if (ctype_isConj (c1b) && ctype_isConj (c2a))
630 return ctype_sameAltTypes (c1b, c2a);
646 ctype_compare (ctype c1, ctype c2)
651 if (ctype_isUnknown (c1))
653 if (ctype_isUnknown (c2))
663 if (ctype_isUnknown (c2))
668 /* Can't get entries for special ctypes (elips marker) */
670 if (ctype_isElips (c1) || ctype_isElips (c2)
671 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
672 return int_compare (c1, c2);
675 ce1 = ctype_getCtentry (c1);
676 ce2 = ctype_getCtentry (c2);
678 if (ctentry_isComplex (ce1))
680 if (ctentry_isComplex (ce2))
682 return (ctbase_compare (ctype_getCtbase (c1),
683 ctype_getCtbase (c2), FALSE));
690 else if (ctentry_isComplex (ce2))
696 return (int_compare (c1, c2));
705 ** makeFunction: pointer to function returning base
709 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
711 uentryList_fixImpParams (p);
712 return (ctype_makeFunction (base, p));
716 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
718 uentryList_fixImpParams (p);
719 return (ctbase_makeNFFunction (base, p));
723 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
726 ret = ctbase_makeFunction (base, p);
730 ctype ctype_expectFunction (ctype c)
732 /* handle parenthesized declarations */
736 c = ctype_makePointer (c);
739 return (cttable_addComplex (ctbase_expectFunction (c)));
742 ctype ctype_dontExpectFunction (ctype c)
744 ctbase ctb = ctype_getCtbase (c);
749 c = ctype_makePointer (c);
753 return (ctbase_getExpectFunction (ctb));
757 ** makeRealFunction: function returning base
760 ctype ctype_makeRawFunction (ctype base, uentryList p)
762 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
770 **** this is very poorly defined
772 **** need to unify function/function pointer meaning
776 ctype_isFunction (ctype c)
778 if (ctype_isKnown (c) && ctype_isDefined (c))
780 return (ctbase_isFunction (ctype_getCtbase (c)));
789 ctype_isExpFcn (ctype c)
791 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
795 ctype_isVoid (ctype c)
797 return (c == CTX_VOID);
801 ctype_isArbitraryIntegral (ctype c)
803 ctype cr = ctype_realType (c);
805 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
806 || cr == ctype_signedintegral);
810 ctype_isUnsignedIntegral (ctype c)
812 ctype cr = ctype_realType (c);
814 return (cr == ctype_unsignedintegral);
818 ctype_isSignedIntegral (ctype c)
820 ctype cr = ctype_realType (c);
822 return (cr == ctype_signedintegral);
826 ctype_isInt (ctype c)
828 cprim cp = ctype_toCprim (c);
830 return (c == ctype_unknown || cprim_isAnyInt (cp)
831 || (cprim_isAnyChar (cp) && context_msgCharInt ())
832 || (c == ctype_bool && context_msgBoolInt ())
833 || (ctype_isEnum (c) && context_msgEnumInt ()));
837 ctype_isRegularInt (ctype c)
839 cprim cp = ctype_toCprim (c);
841 return (c == ctype_unknown
842 || cprim_closeEnough (cprim_int, cp)
843 || (cprim_isAnyChar (cp) && context_msgCharInt ())
844 || (c == ctype_bool && context_msgBoolInt ())
845 || (ctype_isEnum (c) && context_msgEnumInt ()));
849 ctype_isString (ctype c)
851 return (c == ctype_string
852 || (ctype_isPointer (c)
853 && ctype_isChar (ctype_baseArrayPtr (c))));
857 ctype_isChar (ctype c)
859 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
860 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
864 ctype_isUnsignedChar (ctype c)
866 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
870 ctype_isSignedChar (ctype c)
872 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
876 ** Returns true if c matches the name -booltype <bool>
880 ctype_isManifestBool (ctype c)
883 ** Changed the meaning of ctype_isBool - evs 2000-07-24
884 ** The old meaning was very convoluted!
887 ** c == CTX_BOOL - its a direct bool
888 ** c is a user/abstract type matching the bool name
889 ** (should never occur?)
892 if (ctype_isDirectBool (c)) {
894 } else if (ctype_isUA (c)) {
895 return ctype_isUserBool (c);
902 ctype_isBool (ctype c)
905 ** Changed the meaning of ctype_isBool - evs 2000-07-24
906 ** The old meaning was very convoluted!
909 ** its a manifest bool
910 ** +boolint and ctype_isInt (c)
913 if (ctype_isManifestBool (c)) {
915 } else if (context_msgBoolInt ()) {
916 return ctype_isInt (c);
922 if (context_getFlag (FLG_ABSTRACTBOOL))
924 if (typeId_isInvalid (boolType))
926 boolType = usymtab_getTypeId (context_getBoolName ());
929 if (context_hasAccess (boolType))
931 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
932 || (context_msgBoolInt ()
934 || (c == CTX_CHAR && context_msgCharInt ()))))
939 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
940 || (context_msgBoolInt ()
941 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
946 ctype_isDirectBool (ctype c)
948 return (c == CTX_BOOL);
952 ctype_isReal (ctype c)
954 return (cprim_isAnyReal (ctype_toCprim (c)));
958 ctype_isFloat (ctype c)
960 return (c == ctype_float);
964 ctype_isDouble (ctype c)
966 return (c == ctype_double || c == ctype_ldouble);
970 ctype_isSigned (ctype c)
972 return (!ctype_isUnsigned (c));
976 ctype_isNumeric (ctype c)
978 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
979 /* evans 2001-10-05: added this: */
980 || ctype_isArbitraryIntegral (c));
987 ** work on actual type in current context
991 ctype_isRealNumeric (ctype c)
993 if (ctype_isPlain (c))
994 return (ctype_isNumeric (ctype_realType (c)));
995 if (ctype_isConj (c))
996 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
997 ctype_isRealNumeric (ctype_getConjB (c)));
1003 ctype_isRealInt (ctype c)
1005 if (ctype_isPlain (c))
1006 return (ctype_isInt (ctype_realType (c)));
1007 else if (ctype_isConj (c))
1008 return (ctype_isRealInt (ctype_getConjA (c)) ||
1009 ctype_isRealInt (ctype_getConjB (c)));
1012 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
1018 ctype_isRealVoid (ctype c)
1020 if (ctype_isPlain (c))
1022 return (ctype_isVoid (ctype_realType (c)));
1024 else if (ctype_isConj (c))
1026 return (ctype_isRealVoid (ctype_getConjA (c)) ||
1027 ctype_isRealVoid (ctype_getConjB (c)));
1036 ctype_isRealBool (ctype c)
1038 if (ctype_isPlain (c))
1040 return (ctype_isBool (ctype_realishType (c)));
1042 else if (ctype_isConj (c))
1044 return (ctype_isRealBool (ctype_getConjA (c)) ||
1045 ctype_isRealBool (ctype_getConjB (c)));
1054 ctype_isRealPointer (ctype c)
1056 if (ctype_isConj (c))
1057 return (ctype_isRealPointer (ctype_getConjA (c)) ||
1058 ctype_isRealPointer (ctype_getConjB (c)));
1059 return (ctype_isPointer (ctype_realType (c)));
1063 ctype_isRealSU (ctype c)
1065 if (ctype_isConj (c))
1067 return (ctype_isRealSU (ctype_getConjA (c)) ||
1068 ctype_isRealSU (ctype_getConjB (c)));
1071 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
1072 return (ctype_isStructorUnion (ctype_realType (c)));
1076 ctype_isRealArray (ctype c)
1078 if (ctype_isConj (c))
1079 return (ctype_isRealArray (ctype_getConjA (c)) ||
1080 ctype_isRealArray (ctype_getConjB (c)));
1081 return (ctype_isArray (ctype_realType (c)));
1085 ctype_isRealAP (ctype c)
1087 if (ctype_isConj (c))
1088 return (ctype_isRealAP (ctype_getConjA (c)) ||
1089 ctype_isRealAP (ctype_getConjB (c)));
1090 return (ctype_isAP (ctype_realType (c)));
1094 ctype_isRealFunction (ctype c)
1096 if (ctype_isConj (c))
1097 return (ctype_isRealFunction (ctype_getConjA (c)) ||
1098 ctype_isRealFunction (ctype_getConjB (c)));
1099 return (ctype_isFunction (ctype_realType (c)));
1103 ctype_isDirectInt (ctype c)
1105 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
1109 ** forceful predicates
1111 ** take *ctype; if its a conjunct, and there is a match replace with match only.
1112 ** if both match, still conjunct
1116 ctype_isForcePred (ctype * c, bool (pred) (ctype))
1118 /*drl bee: pbr */ if (ctype_isConj (*c))
1120 ctype cbr = ctype_getConjA (*c);
1124 if ((*pred) (ctype_getConjB (*c)))
1137 if ((*pred) (cbr = ctype_getConjB (*c)))
1145 return ((*pred) (*c));
1149 ctype_isForceRealNumeric (ctype * c)
1151 return (ctype_isForcePred (c, ctype_isRealNumeric));
1155 ctype_isForceRealInt (ctype * c)
1157 return (ctype_isForcePred (c, ctype_isRealInt));
1161 ctype_isForceRealBool (ctype * c)
1163 return (ctype_isForcePred (c, ctype_isRealBool));
1169 ** save int/char, int/bool, other random conjuncts
1173 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
1175 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
1179 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1187 return (ctype_makeExplicitConj (c1, c2));
1191 return (ctype_makeConj (c1, c2));
1197 ctype_makeExplicitConj (ctype c1, ctype c2)
1199 if (ctype_isAnytype (c1) || ctype_isAnytype (c2))
1201 return ctype_makeAnytype ();
1203 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1205 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
1207 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1209 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1211 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
1213 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1217 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1221 static ctype ic = ctype_unknown; /* int | char */
1222 static ctype ib = ctype_unknown; /* int | bool */
1223 static ctype ifl = ctype_unknown; /* int | float */
1224 static ctype ibf = ctype_unknown; /* int | bool | float */
1225 static ctype ibc = ctype_unknown; /* int | bool | char */
1226 static ctype iv = ctype_unknown; /* int | void * */
1227 static ctype ivf = ctype_unknown; /* int | void * | float */
1228 static ctype ivb = ctype_unknown; /* int | void * | bool */
1229 static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1230 static ctype cuc = ctype_unknown; /* char | unsigned char */
1232 static ctype cany = ctype_unknown;
1235 ctype_makeAnytype ()
1237 if (cany == ctype_unknown)
1239 cany = ctype_makeConj (ctype_unknown, ctype_dne);
1240 llassert (ctype_isAnytype (cany));
1243 DPRINTF (("make anytype: %s", ctype_unparse (cany)));
1248 ctype_isAnytype (ctype c)
1254 ctype_recordConj (ctype c)
1258 llassert (ctype_isConj (c));
1260 c1 = ctype_getConjA (c);
1261 c2 = ctype_getConjB (c);
1264 if (c2 == ctype_int && c1 != ctype_int)
1274 if (c1 == ctype_int)
1276 if (c2 == ctype_char)
1278 llassert (ic == ctype_unknown);
1281 else if (c2 == ctype_bool)
1283 llassert (ib == ctype_unknown);
1286 else if (c2 == ctype_float)
1288 llassert (ifl == ctype_unknown);
1291 else if (c2 == CTP_VOID)
1293 llassert (iv == ctype_unknown);
1301 else if (c1 == ib && ib != ctype_unknown)
1303 if (c2 == ctype_float)
1305 llassert (ibf == ctype_unknown);
1308 else if (c2 == ctype_char)
1310 llassert (ibc == ctype_unknown);
1320 if (c2 == ctype_bool)
1322 llassert (ivb == ctype_unknown);
1325 else if (c2 == ctype_float)
1327 llassert (ivf == ctype_unknown);
1337 if (c2 == ctype_bool)
1339 llassert (ivbf == ctype_unknown);
1345 if (c2 == ctype_float)
1347 llassert (ivbf == ctype_unknown);
1351 else if (c1 == ctype_char)
1353 if (c2 == ctype_uchar)
1355 llassert (cuc == ctype_unknown);
1367 ctype_makeConj (ctype c1, ctype c2)
1369 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1371 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1373 if (ctype_isAnytype (c1))
1377 else if (ctype_isAnytype (c2))
1381 else if (ctype_isUnknown (c1))
1385 else if (ctype_isUnknown (c2))
1389 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1391 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
1392 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1394 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1396 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
1397 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1401 if (ctype_isManifestBool (c1))
1406 if (ctype_isManifestBool (c2))
1411 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1413 c1 = ctype_voidPointer;
1416 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1418 c2 = ctype_voidPointer;
1422 ** Ouch, can't do this. unsigned, etc. modifiers might
1423 ** apply to wrong type!
1425 ** if (c2 == ctype_int && c1 != ctype_int)
1436 if (c1 == ctype_int)
1438 if (c2 == ctype_char)
1440 if (ic == ctype_unknown)
1442 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1447 else if (c2 == ctype_bool)
1449 if (ib == ctype_unknown)
1451 ib = cttable_addComplex
1452 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1457 else if (c2 == ctype_float)
1459 if (ifl == ctype_unknown)
1461 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1468 if (c2 == ctype_voidPointer)
1470 if (iv == ctype_unknown)
1472 iv = cttable_addComplex
1473 (ctbase_makeConj (ctype_int,
1482 else if (c1 == ib && ib != ctype_unknown)
1484 if (c2 == ctype_float)
1486 if (ibf == ctype_unknown)
1488 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1493 else if (c2 == ctype_char)
1495 if (ibc == ctype_unknown)
1497 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1509 if (c2 == ctype_bool)
1511 if (ivb == ctype_unknown)
1513 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1518 else if (c2 == ctype_float)
1520 if (ivf == ctype_unknown)
1522 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1534 if (c2 == ctype_bool)
1536 if (ivbf == ctype_unknown)
1538 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1546 if (c2 == ctype_float)
1548 if (ivbf == ctype_unknown)
1550 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1556 else if (c1 == ctype_char)
1558 if (c2 == ctype_uchar)
1560 if (cuc == ctype_unknown)
1562 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1573 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1579 ctype_isConj (ctype c)
1581 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1585 ctype_getConjA (ctype c)
1587 if (!ctype_isConj (c))
1588 llbuglit ("ctype_getConjA: not a conj");
1589 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1593 ctype_getConjB (ctype c)
1595 if (!ctype_isConj (c))
1596 llbuglit ("ctype_getConjB: not a conj");
1597 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1601 ctype_isExplicitConj (ctype c)
1603 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1606 /** << need to fix resolveConj >> **/
1609 ** structs and unions
1613 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1617 DPRINTF (("Creating a struct: %s / %s",
1618 n, uentryList_unparse (f)));
1620 ct = cttable_addComplex (ctbase_createStruct (n, f));
1621 DPRINTF (("ct: %s", ctype_unparse (ct)));
1626 ctype_getFields (ctype c)
1628 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1632 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1636 ret = cttable_addComplex (ctbase_createUnion (n, f));
1643 ** if ctype's are same, definite match.
1644 ** else, need to call ctbase_match.
1646 ** if necessary context can memoize matches
1650 quickMatch (ctype c1, ctype c2)
1659 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1663 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1665 if (quickMatch (c1, c2))
1670 if (ctype_isElips (c1) || ctype_isElips (c2))
1676 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1682 ctype_sameName (ctype c1, ctype c2)
1684 if (quickMatch (c1, c2))
1687 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1691 ctype_almostEqual (ctype c1, ctype c2)
1693 if (ctype_equal (c1, c2))
1699 if (ctype_isUnknown (c1))
1701 return ctype_isUnknown (c2);
1703 else if (ctype_isUnknown (c2))
1709 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1715 ctype_matchDef (ctype c1, ctype c2)
1717 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1719 if (quickMatch (c1, c2))
1722 if (ctype_isElips (c1))
1723 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1725 if (ctype_isElips (c2))
1727 return (ctype_isUnknown (c2));
1731 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1734 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1735 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1736 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1741 bool ctype_match (ctype c1, ctype c2)
1743 if (quickMatch (c1, c2))
1746 if (ctype_isElips (c1))
1747 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1749 if (ctype_isElips (c2))
1750 return (ctype_isUnknown (c2));
1752 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1756 ctype_forceMatch (ctype c1, ctype c2)
1758 if (quickMatch (c1, c2))
1761 if (ctype_isElips (c1))
1762 return (ctype_isElips (c2));
1764 if (ctype_isElips (c2))
1768 /* The call forceMatch may modify the observer params, but, we don't care. */
1769 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1774 ctype_matchArg (ctype c1, ctype c2)
1776 if (quickMatch (c1, c2))
1782 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1787 ** simple ctype_is operations.
1788 ** DO NOT use real type of c, only direct type.
1792 ** ctype_isVoidPointer
1798 ctype_isVoidPointer (ctype c)
1800 if (ctype_isComplex (c))
1802 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1804 if (ctype_isConj (c))
1806 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1807 ctype_isVoidPointer (ctype_getConjB (c)));
1811 return (c == ctype_voidPointer
1812 || (ctype_isRealPointer (c)
1813 && ctype_isVoid (ctype_baseArrayPtr (c))));
1820 ** true for C and LCL pointers
1824 ctype_isPointer (ctype c)
1826 if (ctype_isElips (c)) return FALSE;
1828 if (ctype_isComplex (c))
1830 ctbase ctb = ctype_getCtbaseSafe (c);
1831 bool res = ctbase_isPointer (ctb);
1837 bool res = ctentry_isPointer (ctype_getCtentry (c));
1846 ** true for C and LCL array's
1850 ctype_isArray (ctype c)
1852 if (ctype_isElips (c)) return FALSE;
1854 if (ctype_isComplex (c))
1855 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1857 return (ctentry_isArray (ctype_getCtentry (c)));
1860 bool ctype_isIncompleteArray (ctype c)
1862 if (ctype_isArray (c))
1864 if (ctype_isFixedArray (c))
1866 return ctype_isIncompleteArray (ctype_baseArrayPtr (c));
1878 ctype_isArrayPtr (ctype c)
1880 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1884 ctype_typeId (ctype c)
1886 return (ctbase_typeId (ctype_getCtbase (c)));
1890 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1892 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1894 if (ctype_isUnknown (c))
1896 return message ("? %q", name);
1900 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1905 ctype_unparse (ctype c)
1907 if (ctype_isElips (c))
1909 return cstring_makeLiteralTemp ("...");
1911 else if (ctype_isMissingParamsMarker (c))
1913 return cstring_makeLiteralTemp ("-");
1915 else if (ctype_isAnytype (c))
1917 return cstring_makeLiteralTemp ("<any>");
1919 else if (ctype_isUnknown (c))
1921 return cstring_makeLiteralTemp ("?");
1926 return (ctentry_doUnparse (ctype_getCtentry (c)));
1932 ctype_unparseSafe (ctype c)
1934 if (ctype_isElips (c))
1936 return cstring_makeLiteralTemp ("...");
1938 else if (ctype_isMissingParamsMarker (c))
1940 return cstring_makeLiteralTemp ("-");
1946 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1948 ctentry cte = ctype_getCtentry (c);
1950 if (cstring_isDefined (cte->unparse))
1952 return (cte->unparse);
1956 ret = message ("[%d]", (int) c);
1957 cstring_markOwned (ret);
1963 ctype_unparseDeep (ctype c)
1965 if (ctype_isElips (c))
1967 return cstring_makeLiteralTemp ("...");
1969 if (ctype_isMissingParamsMarker (c))
1971 return cstring_makeLiteralTemp ("-");
1974 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1978 ctype_undump (char **c)
1980 return ((ctype) reader_getInt (c)); /* check its valid? */
1984 ctype_dump (ctype c)
1986 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1990 /* Handle invalid types in a kludgey way. */
1991 return (message ("0"));
1996 cstring tname = usymtab_getTypeEntryName (usymtab_convertTypeId (ctype_typeId (c)));
1998 if (cstring_equal (tname, context_getBoolName ()))
2000 cstring_free (tname);
2001 return (message ("%d", ctype_bool));
2004 cstring_free (tname);
2007 DPRINTF (("Returning: %d", c));
2008 return (message ("%d", c));
2012 ctype_getBaseType (ctype c)
2014 ctentry cte = ctype_getCtentry (c);
2016 switch (ctentry_getKind (cte))
2024 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
2027 ctbase ctb = cte->ctbase;
2029 if (ctbase_isDefined (ctb))
2049 return (ctype_getBaseType (ctb->contents.base));
2051 return (ctype_getBaseType (ctb->contents.farray->base));
2052 case CT_CONJ: /* base type of A conj branch? */
2053 return (ctype_getBaseType (ctb->contents.conj->a));
2055 /*@noaccess ctbase@*/
2063 llbuglit ("ctype_newBase: bad case");
2065 llcontbuglit ("ctype_getBaseType: unreachable code");
2066 return ((ctype)NULL);
2070 ctype_adjustPointers (pointers p, ctype c)
2072 int np = pointers_depth (p);
2074 if (ctype_isFunction (c))
2076 c = ctype_makeParamsFunction
2077 (ctype_adjustPointers (p, ctype_getReturnType (c)),
2078 uentryList_copy (ctype_argsFunction (c)));
2082 /* fix this should not use getBaseType ??? */
2083 ctype cb = ctype_getBaseType (c);
2087 cb = ctype_makePointer (cb);
2090 c = ctype_newBase (c, cb);
2098 ctype_elist (ctype c)
2100 return (ctbase_elist (ctype_getCtbase (c)));
2104 ctype_isFirstVoid (ctype c)
2106 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2110 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2112 return (cttable_addComplex (ctbase_createEnum (tag, el)));
2116 ctype_isEnum (ctype c)
2118 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2122 ctype_enumTag (ctype c)
2124 llassert (ctype_isEnum (c));
2126 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2130 ctype_isStruct (ctype c)
2132 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2136 ctype_isUnion (ctype c)
2138 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2142 ctype_resolveNumerics (ctype c1, ctype c2)
2145 ** returns longest type of c1 and c2
2148 if (c1 == c2) return c1;
2150 c1 = ctype_realType (c1);
2151 c2 = ctype_realType (c2);
2153 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2154 if (ctype_isEnum (c2)) c2 = ctype_int;
2156 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2158 /* 2001-06-08: This fix provided by Jim Zelenka. */
2159 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2160 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2162 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2163 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2164 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2165 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2167 /* 2001-06-08: This fix provided by Jim Zelenka. */
2168 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2170 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2172 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2173 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2175 if (ctype_isKnown (c1)) return c1;
2180 ctype_isStructorUnion (ctype c)
2182 return (ctype_isStruct (c) || ctype_isUnion (c));
2186 ctype_fixArrayPtr (ctype c)
2188 if (ctype_isArray (c))
2190 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2197 ** createUnnamedStruct/Union
2199 ** check if it corresponds to an existing LCL-specified unnamed struct
2200 ** otherwise, give it a new tag
2204 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2206 ctype ret = usymtab_structFieldsType (f);
2208 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2210 if (ctype_isDefined (ret))
2212 uentryList_free (f);
2217 cstring ft = fakeTag ();
2218 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2219 uentry ue = uentry_makeStructTagLoc (ft, ct);
2221 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2222 ue = usymtab_supGlobalEntryReturn (ue);
2223 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2231 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2233 ctype ret = usymtab_unionFieldsType (f);
2235 if (ctype_isDefined (ret))
2237 uentryList_free (f);
2242 cstring ft = fakeTag ();
2243 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2244 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2246 usymtab_supGlobalEntry (ue);
2253 ctype_isUnnamedSU (ctype c)
2257 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2266 ctype_createForwardStruct (cstring n)
2268 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2269 ctype ct = usymtab_supForwardTypeEntry (ue);
2276 ctype_createForwardUnion (cstring n)
2278 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2279 ctype ct = usymtab_supForwardTypeEntry (ue);
2286 ctype_createForwardEnum (cstring n)
2288 uentry ue = uentry_makeEnumTag (n, ctype_unknown, fileloc_undefined);
2289 ctype ct = usymtab_supForwardTypeEntry (ue);
2296 ctype_removePointers (ctype c)
2300 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2303 c = ctype_baseArrayPtr (c);
2304 llassert (c != oldc);
2310 bool ctype_isMutable (ctype t)
2314 return (uentry_isMutableDatatype
2315 (usymtab_getTypeEntry (ctype_typeId (t))));
2319 return (ctype_isPointer (ctype_realType (t)));
2320 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2324 bool ctype_isRefCounted (ctype t)
2328 return (uentry_isRefCountedDatatype
2329 (usymtab_getTypeEntry (ctype_typeId (t))));
2335 bool ctype_isVisiblySharable (ctype t)
2337 if (ctype_isUnknown (t))
2342 if (ctype_isConj (t))
2344 return (ctype_isVisiblySharable (ctype_getConjA (t))
2345 || ctype_isVisiblySharable (ctype_getConjB (t)));
2348 if (ctype_isMutable (t))
2352 ctype rt = ctype_realType (t);
2356 if (ctype_isNumAbstract (t))
2367 return ctype_isVisiblySharable (rt);
2381 /* Replaced by ctype_isMutable (more sensible) */
2382 bool ctype_canAlias (ctype ct)
2384 /* can ct refer to memory locations?
2385 ** ==> a pointer or a mutable abstract type
2389 ctype tr = ctype_realType (ct);
2391 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2396 ** c1 is the dominant type; c2 is the modifier type
2398 ** eg. double + long int => long double
2401 ctype ctype_combine (ctype dominant, ctype modifier)
2403 DPRINTF (("Combine: %s + %s",
2404 ctype_unparse (dominant),
2405 ctype_unparse (modifier)));
2407 if (ctype_isConj (dominant))
2411 if (ctype_isExplicitConj (dominant))
2413 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2415 ctype_getConjB (dominant));
2419 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2421 ctype_getConjB (dominant));
2427 if (ctype_isUnknown (modifier))
2431 else if (ctype_isUnknown (dominant))
2437 if (ctype_isEnum (dominant)) dominant = ctype_int;
2438 if (ctype_isEnum (modifier)) modifier = ctype_int;
2440 if (modifier == ctype_uint)
2442 if (dominant == ctype_int) return ctype_uint;
2443 if (dominant == ctype_lint) return ctype_ulint;
2444 if (dominant == ctype_sint) return ctype_usint;
2445 if (dominant == ctype_char) return ctype_uchar;
2447 /* evs 2000-07-28: added this line */
2448 if (dominant == ctype_llint) return ctype_ullint;
2450 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2452 voptgenerror (FLG_DUPLICATEQUALS,
2453 message ("Duplicate unsigned qualifier"),
2460 voptgenerror (FLG_DUPLICATEQUALS,
2461 message ("Type qualifier unsigned used with %s",
2462 ctype_unparse (dominant)),
2468 else if (modifier == ctype_llint)
2470 if (dominant == ctype_int)
2475 voptgenerror (FLG_DUPLICATEQUALS,
2476 message ("Duplicate long qualifier on non-int"),
2479 else if (modifier == ctype_lint)
2481 if (dominant == ctype_int) return ctype_lint;
2482 if (dominant == ctype_uint) return ctype_ulint;
2483 if (dominant == ctype_double) return ctype_ldouble;
2485 if (dominant == ctype_lint || dominant == ctype_ulint
2486 || dominant == ctype_sint || dominant == ctype_usint
2487 || dominant == ctype_ldouble)
2489 if (dominant == ctype_lint)
2491 /* long long not supported by ANSI */
2496 if (dominant == ctype_ulint)
2498 /* unsigned long long not supported by ANSI */
2499 return ctype_ullint;
2503 if (dominant == ctype_sint || dominant == ctype_usint)
2505 if (!context_getFlag (FLG_IGNOREQUALS))
2507 llerrorlit (FLG_SYNTAX,
2508 "Contradictory long and short type qualifiers");
2513 voptgenerror (FLG_DUPLICATEQUALS,
2514 message ("Duplicate long qualifier"),
2521 else if (modifier == ctype_sint)
2523 if (dominant == ctype_int) return ctype_sint;
2524 if (dominant == ctype_uint) return ctype_usint;
2526 if (dominant == ctype_sint || dominant == ctype_usint)
2528 voptgenerror (FLG_DUPLICATEQUALS,
2529 message ("Duplicate short qualifier"),
2533 else if (dominant == ctype_lint)
2535 if (!context_getFlag (FLG_IGNOREQUALS))
2537 llerrorlit (FLG_SYNTAX,
2538 "Contradictory long and short type qualifiers");
2544 else if (dominant == ctype_llint)
2546 if (!context_getFlag (FLG_IGNOREQUALS))
2548 llerrorlit (FLG_SYNTAX,
2549 "Contradictory long long and short type qualifiers");
2557 if (!context_getFlag (FLG_IGNOREQUALS))
2559 llerror (FLG_SYNTAX,
2560 message ("Type qualifier short used with %s",
2561 ctype_unparse (dominant)));
2567 else if (modifier == ctype_ulint)
2569 if (dominant == ctype_int) return modifier;
2571 if (dominant == ctype_lint || dominant == ctype_ulint)
2573 voptgenerror (FLG_DUPLICATEQUALS,
2574 message ("Duplicate long qualifier"),
2580 if (dominant == ctype_uint || dominant == ctype_usint)
2582 voptgenerror (FLG_DUPLICATEQUALS,
2583 message ("Duplicate unsigned qualifier"),
2589 if (dominant == ctype_sint || dominant == ctype_usint)
2591 if (!context_getFlag (FLG_IGNOREQUALS))
2593 llerrorlit (FLG_SYNTAX,
2594 "Contradictory long and short type qualifiers");
2600 if (!context_getFlag (FLG_IGNOREQUALS))
2602 llerror (FLG_SYNTAX,
2603 message ("Type qualifiers unsigned long used with %s",
2604 ctype_unparse (dominant)));
2609 else if (modifier == ctype_usint)
2611 if (dominant == ctype_int) return modifier;
2613 if (dominant == ctype_sint || dominant == ctype_usint)
2615 voptgenerror (FLG_DUPLICATEQUALS,
2616 message ("Duplicate short qualifier"),
2621 if (dominant == ctype_uint)
2623 voptgenerror (FLG_DUPLICATEQUALS,
2624 message ("Duplicate unsigned qualifier"),
2630 if (dominant == ctype_lint || dominant == ctype_ulint
2631 || dominant == ctype_llint)
2633 if (!context_getFlag (FLG_IGNOREQUALS))
2635 llerrorlit (FLG_SYNTAX,
2636 "Contradictory long and short type qualifiers");
2642 if (!context_getFlag (FLG_IGNOREQUALS))
2644 llerror (FLG_SYNTAX,
2645 message ("Type qualifiers unsigned short used with %s",
2646 ctype_unparse (dominant)));
2660 ctype ctype_resolve (ctype c)
2662 if (ctype_isUnknown (c) && !ctype_isAnytype (c))
2664 DPRINTF (("Resolving to int: %s", ctype_unparse (c)));
2671 ctype ctype_fromQual (qual q)
2673 if (qual_isSigned (q)) return ctype_int;
2674 if (qual_isUnsigned (q)) return ctype_uint;
2675 if (qual_isLong (q)) return ctype_lint;
2676 if (qual_isShort (q)) return ctype_sint;
2678 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2679 return ctype_unknown;
2683 ctype_isAnyFloat (ctype c)
2685 return (cprim_isAnyReal (ctype_toCprim (c)));
2689 ctype_isUnsigned (ctype c)
2691 if (ctype_isConj (c))
2692 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2693 ctype_isUnsigned (ctype_getConjB (c)));
2695 return (c == ctype_uint || c == ctype_uchar
2696 || c == ctype_usint || c == ctype_ulint
2697 || c == ctype_ullint
2698 || c == ctype_unsignedintegral);
2703 ctype_isLongLong (ctype c)
2705 if (ctype_isConj (c))
2706 return (ctype_isLongLong (ctype_getConjA (c)) ||
2707 ctype_isLongLong (ctype_getConjB (c)));
2709 return (c == ctype_llint || c == ctype_ullint);
2714 ctype_isLong (ctype c)
2716 if (ctype_isConj (c))
2717 return (ctype_isLong (ctype_getConjA (c)) ||
2718 ctype_isLong (ctype_getConjB (c)));
2720 return (c == ctype_lint || c == ctype_ulint);
2724 ctype_isShort (ctype c)
2726 if (ctype_isConj (c))
2727 return (ctype_isShort (ctype_getConjA (c)) ||
2728 ctype_isShort (ctype_getConjB (c)));
2730 return (c == ctype_sint || c == ctype_usint);
2734 ctype_isStackAllocated (ctype c)
2736 ctype ct = ctype_realType (c);
2738 if (ctype_isConj (ct))
2739 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2740 ctype_isStackAllocated (ctype_getConjB (ct)));
2742 return (ctype_isArray (c) || ctype_isSU (c));
2745 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2747 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2750 static bool ctype_isLonger (ctype c1, ctype c2)
2752 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2753 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2754 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2755 || (ctype_isLong (c1)
2756 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2757 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2761 ctype_widest (ctype c1, ctype c2)
2763 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2773 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2776 if (c >= 0 && c < cttab.size)
2778 return (cttab.entries[c]->ctbase);
2782 if (c == ctype_unknown)
2783 llbuglit ("ctype_getCtbase: ctype unknown");
2784 if (c == ctype_undefined)
2785 llbuglit ("ctype_getCtbase: ctype undefined");
2787 llbuglit ("ctype_getCtbase: ctype dne");
2788 if (c == ctype_elipsMarker)
2789 llbuglit ("ctype_getCtbase: elips marker");
2791 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2798 static /*@notnull@*/ /*@observer@*/ ctbase
2799 ctype_getCtbaseSafe (ctype c)
2801 ctbase res = ctype_getCtbase (c);
2803 llassert (ctbase_isDefined (res));
2812 ctype_getCtentry (ctype c)
2814 static /*@only@*/ ctentry errorEntry = NULL;
2816 if (cttab.size == 0)
2818 if (errorEntry == NULL)
2820 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2827 if (c >= CTK_PLAIN && c < cttab.size)
2829 return (cttab.entries[c]);
2831 else if (c == CTK_UNKNOWN)
2832 llcontbuglit ("ctype_getCtentry: ctype unknown");
2833 else if (c == CTK_INVALID)
2834 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2835 else if (c == CTK_DNE)
2836 llcontbuglit ("ctype_getCtentry: ctype dne");
2837 else if (c == CTK_ELIPS)
2838 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2839 else if (c == CTK_MISSINGPARAMS)
2840 llcontbuglit ("ctype_getCtentry: ctype missing params");
2842 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2844 return (cttab.entries[ctype_unknown]);
2849 bool ctype_isFixedArray (ctype c)
2851 if (ctype_isElips (c)) return FALSE;
2853 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2858 /* requires that the type is an fixed array */
2859 /* return the size of the array */
2861 size_t ctype_getArraySize (ctype c)
2867 llassert (ctype_isFixedArray (c));
2869 ctb = ctype_getCtbaseSafe(c);
2870 size = ctbase_getArraySize (ctb);
2872 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2878 ctype ctype_biggerType (ctype c1, ctype c2)
2880 if (ctbase_isBigger (ctype_getCtbaseSafe (c2), ctype_getCtbaseSafe (c1)))
2890 int ctype_getSize (ctype c)
2892 return ctbase_getSize (ctype_getCtbaseSafe (ctype_realType (c)));