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);
357 ctype ctype_makeInnerFixedArray (ctype c, size_t size)
361 if (ctype_isFixedArray (c))
363 ctype cb = ctype_baseArrayPtr (c);
364 size_t osize = ctype_getArraySize (c);
366 res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize);
368 else if (ctype_isArray (c))
370 ctype cb = ctype_baseArrayPtr (c);
372 res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
376 res = ctype_makeFixedArray (c, size);
379 DPRINTF (("Make inner fixed array: %s", ctype_unparse (res)));
383 ctype ctype_makeInnerArray (ctype c)
387 DPRINTF (("Make inner array: %s", ctype_unparse (c)));
389 if (ctype_isFixedArray (c))
391 ctype cb = ctype_baseArrayPtr (c);
392 size_t osize = ctype_getArraySize (c);
394 res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize);
398 res = ctype_makeArray (c);
401 DPRINTF (("Make inner array: %s", ctype_unparse (res)));
406 ctype_makeArray (ctype c)
408 ctentry cte = ctype_getCtentry (c);
409 ctype clp = ctentry_getArray (cte);
411 DPRINTF (("Make array: %s", ctype_unparse (c)));
413 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
415 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
416 ctentry_setArray (cte, cnew);
426 ** requires c is a pointer of array
430 ctype_baseArrayPtr (ctype c)
432 ctentry cte = ctype_getCtentry (ctype_realType (c));
434 if (ctype_isConj (c))
436 if (ctype_isAP (ctype_getConjA (c)))
438 if (ctype_isAP (ctype_getConjB (c)))
440 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
441 ctype_baseArrayPtr (ctype_getConjB (c))));
445 return (ctype_baseArrayPtr (ctype_getConjA (c)));
450 return (ctype_baseArrayPtr (ctype_getConjB (c)));
453 else if (ctype_isInt (c)) /* could be NULL */
455 return ctype_unknown;
459 ctype clp = ctentry_getBase (cte);
461 if (ctype_isBroken (clp))
463 llcontbug (message ("ctype_baseArrayPtr: bogus ctype getting base of: %s", ctype_unparse (c)));
464 return ctype_unknown;
476 ctype_makeWideString ()
478 static ctype res = ctype_unknown;
480 if (ctype_isUnknown (res))
484 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
486 wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
493 res = ctype_makePointer (wchart);
500 ctype_isWideString (ctype c)
502 if (ctype_isPointer (c))
504 ctype ct = ctype_baseArrayPtr (c);
506 if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
508 return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
522 ctype_getReturnType (ctype c)
524 if (ctype_isUnknown (c))
526 return ctype_unknown;
529 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
533 ** must be a shared pointer
536 /*@observer@*/ uentryList
537 ctype_argsFunction (ctype c)
539 if (ctype_isUnknown (c))
541 return uentryList_undefined;
544 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
548 ** Returns type with base type p and compound types from c.
550 ** i.e., c = char *[]; p = int
555 ctype_newBase (ctype c, ctype p)
557 return (ctbase_newBase (c, p));
561 ctype_sameAltTypes (ctype c1, ctype c2)
566 llassert (ctype_isConj (c1) && ctype_isConj (c2));
568 c1a = ctype_getConjA (c1);
569 c2a = ctype_getConjA (c2);
571 c1b = ctype_getConjB (c1);
572 c2b = ctype_getConjB (c2);
574 if (ctype_compare (c1a, c2a) == 0)
576 if (ctype_compare (c1b, c2b) == 0)
582 if (ctype_isConj (c1b) && ctype_isConj (c2b))
584 return ctype_sameAltTypes (c1b, c2b);
594 if (ctype_compare (c1a, c2b) == 0)
596 if (ctype_compare (c1b, c2a) == 0)
602 if (ctype_isConj (c1b) && ctype_isConj (c2a))
604 return ctype_sameAltTypes (c1b, c2a);
620 ctype_compare (ctype c1, ctype c2)
625 if (ctype_isUnknown (c1))
627 if (ctype_isUnknown (c2))
637 if (ctype_isUnknown (c2))
642 /* Can't get entries for special ctypes (elips marker) */
644 if (ctype_isElips (c1) || ctype_isElips (c2)
645 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
646 return int_compare (c1, c2);
649 ce1 = ctype_getCtentry (c1);
650 ce2 = ctype_getCtentry (c2);
652 if (ctentry_isComplex (ce1))
654 if (ctentry_isComplex (ce2))
656 return (ctbase_compare (ctype_getCtbase (c1),
657 ctype_getCtbase (c2), FALSE));
664 else if (ctentry_isComplex (ce2))
670 return (int_compare (c1, c2));
679 ** makeFunction: pointer to function returning base
683 ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
685 uentryList_fixImpParams (p);
686 return (ctype_makeFunction (base, p));
690 ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
692 uentryList_fixImpParams (p);
693 return (ctbase_makeNFFunction (base, p));
697 ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
700 ret = ctbase_makeFunction (base, p);
704 ctype ctype_expectFunction (ctype c)
706 /* handle parenthesized declarations */
710 c = ctype_makePointer (c);
713 return (cttable_addComplex (ctbase_expectFunction (c)));
716 ctype ctype_dontExpectFunction (ctype c)
718 ctbase ctb = ctype_getCtbase (c);
723 c = ctype_makePointer (c);
727 return (ctbase_getExpectFunction (ctb));
731 ** makeRealFunction: function returning base
734 ctype ctype_makeRawFunction (ctype base, uentryList p)
736 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
744 **** this is very poorly defined
746 **** need to unify function/function pointer meaning
750 ctype_isFunction (ctype c)
752 if (ctype_isKnown (c) && ctype_isDefined (c))
754 return (ctbase_isFunction (ctype_getCtbase (c)));
763 ctype_isExpFcn (ctype c)
765 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
769 ctype_isVoid (ctype c)
771 return (c == CTX_VOID);
775 ctype_isArbitraryIntegral (ctype c)
777 ctype cr = ctype_realType (c);
779 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
780 || cr == ctype_signedintegral);
784 ctype_isUnsignedIntegral (ctype c)
786 ctype cr = ctype_realType (c);
788 return (cr == ctype_unsignedintegral);
792 ctype_isSignedIntegral (ctype c)
794 ctype cr = ctype_realType (c);
796 return (cr == ctype_signedintegral);
800 ctype_isInt (ctype c)
802 cprim cp = ctype_toCprim (c);
804 return (c == ctype_unknown || cprim_isAnyInt (cp)
805 || (cprim_isAnyChar (cp) && context_msgCharInt ())
806 || (c == ctype_bool && context_msgBoolInt ())
807 || (ctype_isEnum (c) && context_msgEnumInt ()));
811 ctype_isRegularInt (ctype c)
813 cprim cp = ctype_toCprim (c);
815 return (c == ctype_unknown
816 || cprim_closeEnough (cprim_int, cp)
817 || (cprim_isAnyChar (cp) && context_msgCharInt ())
818 || (c == ctype_bool && context_msgBoolInt ())
819 || (ctype_isEnum (c) && context_msgEnumInt ()));
823 ctype_isString (ctype c)
825 return (c == ctype_string
826 || (ctype_isPointer (c)
827 && ctype_isChar (ctype_baseArrayPtr (c))));
831 ctype_isChar (ctype c)
833 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
834 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
838 ctype_isUnsignedChar (ctype c)
840 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
844 ctype_isSignedChar (ctype c)
846 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
850 ** Returns true if c matches the name -booltype <bool>
854 ctype_isManifestBool (ctype c)
857 ** Changed the meaning of ctype_isBool - evs 2000-07-24
858 ** The old meaning was very convoluted!
861 ** c == CTX_BOOL - its a direct bool
862 ** c is a user/abstract type matching the bool name
863 ** (should never occur?)
866 if (ctype_isDirectBool (c)) {
868 } else if (ctype_isUA (c)) {
869 return ctype_isUserBool (c);
876 ctype_isBool (ctype c)
879 ** Changed the meaning of ctype_isBool - evs 2000-07-24
880 ** The old meaning was very convoluted!
883 ** its a manifest bool
884 ** +boolint and ctype_isInt (c)
887 if (ctype_isManifestBool (c)) {
889 } else if (context_msgBoolInt ()) {
890 return ctype_isInt (c);
896 if (context_getFlag (FLG_ABSTRACTBOOL))
898 if (typeId_isInvalid (boolType))
900 boolType = usymtab_getTypeId (context_getBoolName ());
903 if (context_hasAccess (boolType))
905 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
906 || (context_msgBoolInt ()
908 || (c == CTX_CHAR && context_msgCharInt ()))))
913 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
914 || (context_msgBoolInt ()
915 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
920 ctype_isDirectBool (ctype c)
922 return (c == CTX_BOOL);
926 ctype_isReal (ctype c)
928 return (cprim_isAnyReal (ctype_toCprim (c)));
932 ctype_isFloat (ctype c)
934 return (c == ctype_float);
938 ctype_isDouble (ctype c)
940 return (c == ctype_double || c == ctype_ldouble);
944 ctype_isSigned (ctype c)
946 return (!ctype_isUnsigned (c));
950 ctype_isNumeric (ctype c)
952 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
953 /* evans 2001-10-05: added this: */
954 || ctype_isArbitraryIntegral (c));
961 ** work on actual type in current context
965 ctype_isRealNumeric (ctype c)
967 if (ctype_isPlain (c))
968 return (ctype_isNumeric (ctype_realType (c)));
969 if (ctype_isConj (c))
970 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
971 ctype_isRealNumeric (ctype_getConjB (c)));
977 ctype_isRealInt (ctype c)
979 if (ctype_isPlain (c))
980 return (ctype_isInt (ctype_realType (c)));
981 else if (ctype_isConj (c))
982 return (ctype_isRealInt (ctype_getConjA (c)) ||
983 ctype_isRealInt (ctype_getConjB (c)));
986 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
992 ctype_isRealVoid (ctype c)
994 if (ctype_isPlain (c))
996 return (ctype_isVoid (ctype_realType (c)));
998 else if (ctype_isConj (c))
1000 return (ctype_isRealVoid (ctype_getConjA (c)) ||
1001 ctype_isRealVoid (ctype_getConjB (c)));
1010 ctype_isRealBool (ctype c)
1012 if (ctype_isPlain (c))
1014 return (ctype_isBool (ctype_realishType (c)));
1016 else if (ctype_isConj (c))
1018 return (ctype_isRealBool (ctype_getConjA (c)) ||
1019 ctype_isRealBool (ctype_getConjB (c)));
1028 ctype_isRealPointer (ctype c)
1030 if (ctype_isConj (c))
1031 return (ctype_isRealPointer (ctype_getConjA (c)) ||
1032 ctype_isRealPointer (ctype_getConjB (c)));
1033 return (ctype_isPointer (ctype_realType (c)));
1037 ctype_isRealSU (ctype c)
1039 if (ctype_isConj (c))
1041 return (ctype_isRealSU (ctype_getConjA (c)) ||
1042 ctype_isRealSU (ctype_getConjB (c)));
1045 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
1046 return (ctype_isStructorUnion (ctype_realType (c)));
1050 ctype_isRealArray (ctype c)
1052 if (ctype_isConj (c))
1053 return (ctype_isRealArray (ctype_getConjA (c)) ||
1054 ctype_isRealArray (ctype_getConjB (c)));
1055 return (ctype_isArray (ctype_realType (c)));
1059 ctype_isRealAP (ctype c)
1061 if (ctype_isConj (c))
1062 return (ctype_isRealAP (ctype_getConjA (c)) ||
1063 ctype_isRealAP (ctype_getConjB (c)));
1064 return (ctype_isAP (ctype_realType (c)));
1068 ctype_isRealFunction (ctype c)
1070 if (ctype_isConj (c))
1071 return (ctype_isRealFunction (ctype_getConjA (c)) ||
1072 ctype_isRealFunction (ctype_getConjB (c)));
1073 return (ctype_isFunction (ctype_realType (c)));
1077 ctype_isDirectInt (ctype c)
1079 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
1083 ** forceful predicates
1085 ** take *ctype; if its a conjunct, and there is a match replace with match only.
1086 ** if both match, still conjunct
1090 ctype_isForcePred (ctype * c, bool (pred) (ctype))
1092 /*drl bee: pbr */ if (ctype_isConj (*c))
1094 ctype cbr = ctype_getConjA (*c);
1098 if ((*pred) (ctype_getConjB (*c)))
1111 if ((*pred) (cbr = ctype_getConjB (*c)))
1119 return ((*pred) (*c));
1123 ctype_isForceRealNumeric (ctype * c)
1125 return (ctype_isForcePred (c, ctype_isRealNumeric));
1129 ctype_isForceRealInt (ctype * c)
1131 return (ctype_isForcePred (c, ctype_isRealInt));
1135 ctype_isForceRealBool (ctype * c)
1137 return (ctype_isForcePred (c, ctype_isRealBool));
1143 ** save int/char, int/bool, other random conjuncts
1147 ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
1149 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
1153 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1161 return (ctype_makeExplicitConj (c1, c2));
1165 return (ctype_makeConj (c1, c2));
1171 ctype_makeExplicitConj (ctype c1, ctype c2)
1173 if (ctype_isAnytype (c1) || ctype_isAnytype (c2))
1175 return ctype_makeAnytype ();
1177 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1179 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
1181 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1183 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1185 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
1187 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1191 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1195 static ctype ic = ctype_unknown; /* int | char */
1196 static ctype ib = ctype_unknown; /* int | bool */
1197 static ctype ifl = ctype_unknown; /* int | float */
1198 static ctype ibf = ctype_unknown; /* int | bool | float */
1199 static ctype ibc = ctype_unknown; /* int | bool | char */
1200 static ctype iv = ctype_unknown; /* int | void * */
1201 static ctype ivf = ctype_unknown; /* int | void * | float */
1202 static ctype ivb = ctype_unknown; /* int | void * | bool */
1203 static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1204 static ctype cuc = ctype_unknown; /* char | unsigned char */
1206 static ctype cany = ctype_unknown;
1209 ctype_makeAnytype ()
1211 if (cany == ctype_unknown)
1213 cany = ctype_makeConj (ctype_unknown, ctype_dne);
1214 llassert (ctype_isAnytype (cany));
1217 DPRINTF (("make anytype: %s", ctype_unparse (cany)));
1222 ctype_isAnytype (ctype c)
1228 ctype_recordConj (ctype c)
1232 llassert (ctype_isConj (c));
1234 c1 = ctype_getConjA (c);
1235 c2 = ctype_getConjB (c);
1238 if (c2 == ctype_int && c1 != ctype_int)
1248 if (c1 == ctype_int)
1250 if (c2 == ctype_char)
1252 llassert (ic == ctype_unknown);
1255 else if (c2 == ctype_bool)
1257 llassert (ib == ctype_unknown);
1260 else if (c2 == ctype_float)
1262 llassert (ifl == ctype_unknown);
1265 else if (c2 == CTP_VOID)
1267 llassert (iv == ctype_unknown);
1275 else if (c1 == ib && ib != ctype_unknown)
1277 if (c2 == ctype_float)
1279 llassert (ibf == ctype_unknown);
1282 else if (c2 == ctype_char)
1284 llassert (ibc == ctype_unknown);
1294 if (c2 == ctype_bool)
1296 llassert (ivb == ctype_unknown);
1299 else if (c2 == ctype_float)
1301 llassert (ivf == ctype_unknown);
1311 if (c2 == ctype_bool)
1313 llassert (ivbf == ctype_unknown);
1319 if (c2 == ctype_float)
1321 llassert (ivbf == ctype_unknown);
1325 else if (c1 == ctype_char)
1327 if (c2 == ctype_uchar)
1329 llassert (cuc == ctype_unknown);
1341 ctype_makeConj (ctype c1, ctype c2)
1343 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1345 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1347 if (ctype_isAnytype (c1))
1351 else if (ctype_isAnytype (c2))
1355 else if (ctype_isUnknown (c1))
1359 else if (ctype_isUnknown (c2))
1363 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1365 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
1366 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1368 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1370 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
1371 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1375 if (ctype_isManifestBool (c1))
1380 if (ctype_isManifestBool (c2))
1385 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1387 c1 = ctype_voidPointer;
1390 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1392 c2 = ctype_voidPointer;
1396 ** Ouch, can't do this. unsigned, etc. modifiers might
1397 ** apply to wrong type!
1399 ** if (c2 == ctype_int && c1 != ctype_int)
1410 if (c1 == ctype_int)
1412 if (c2 == ctype_char)
1414 if (ic == ctype_unknown)
1416 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1421 else if (c2 == ctype_bool)
1423 if (ib == ctype_unknown)
1425 ib = cttable_addComplex
1426 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1431 else if (c2 == ctype_float)
1433 if (ifl == ctype_unknown)
1435 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1442 if (c2 == ctype_voidPointer)
1444 if (iv == ctype_unknown)
1446 iv = cttable_addComplex
1447 (ctbase_makeConj (ctype_int,
1456 else if (c1 == ib && ib != ctype_unknown)
1458 if (c2 == ctype_float)
1460 if (ibf == ctype_unknown)
1462 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1467 else if (c2 == ctype_char)
1469 if (ibc == ctype_unknown)
1471 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1483 if (c2 == ctype_bool)
1485 if (ivb == ctype_unknown)
1487 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1492 else if (c2 == ctype_float)
1494 if (ivf == ctype_unknown)
1496 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1508 if (c2 == ctype_bool)
1510 if (ivbf == ctype_unknown)
1512 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1520 if (c2 == ctype_float)
1522 if (ivbf == ctype_unknown)
1524 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1530 else if (c1 == ctype_char)
1532 if (c2 == ctype_uchar)
1534 if (cuc == ctype_unknown)
1536 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1547 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1553 ctype_isConj (ctype c)
1555 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1559 ctype_getConjA (ctype c)
1561 if (!ctype_isConj (c))
1562 llbuglit ("ctype_getConjA: not a conj");
1563 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1567 ctype_getConjB (ctype c)
1569 if (!ctype_isConj (c))
1570 llbuglit ("ctype_getConjB: not a conj");
1571 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1575 ctype_isExplicitConj (ctype c)
1577 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1580 /** << need to fix resolveConj >> **/
1583 ** structs and unions
1587 ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1591 DPRINTF (("Creating a struct: %s / %s",
1592 n, uentryList_unparse (f)));
1594 ct = cttable_addComplex (ctbase_createStruct (n, f));
1595 DPRINTF (("ct: %s", ctype_unparse (ct)));
1600 ctype_getFields (ctype c)
1602 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1606 ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1610 ret = cttable_addComplex (ctbase_createUnion (n, f));
1617 ** if ctype's are same, definite match.
1618 ** else, need to call ctbase_match.
1620 ** if necessary context can memoize matches
1624 quickMatch (ctype c1, ctype c2)
1633 ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1637 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1639 if (quickMatch (c1, c2))
1644 if (ctype_isElips (c1) || ctype_isElips (c2))
1650 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1656 ctype_sameName (ctype c1, ctype c2)
1658 if (quickMatch (c1, c2))
1661 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1665 ctype_almostEqual (ctype c1, ctype c2)
1667 if (ctype_equal (c1, c2))
1673 if (ctype_isUnknown (c1))
1675 return ctype_isUnknown (c2);
1677 else if (ctype_isUnknown (c2))
1683 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1689 ctype_matchDef (ctype c1, ctype c2)
1691 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1693 if (quickMatch (c1, c2))
1696 if (ctype_isElips (c1))
1697 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1699 if (ctype_isElips (c2))
1701 return (ctype_isUnknown (c2));
1705 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1708 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1709 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1710 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1715 bool ctype_match (ctype c1, ctype c2)
1717 if (quickMatch (c1, c2))
1720 if (ctype_isElips (c1))
1721 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1723 if (ctype_isElips (c2))
1724 return (ctype_isUnknown (c2));
1726 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1730 ctype_forceMatch (ctype c1, ctype c2)
1732 if (quickMatch (c1, c2))
1735 if (ctype_isElips (c1))
1736 return (ctype_isElips (c2));
1738 if (ctype_isElips (c2))
1742 /* The call forceMatch may modify the observer params, but, we don't care. */
1743 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1748 ctype_matchArg (ctype c1, ctype c2)
1750 if (quickMatch (c1, c2))
1756 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1761 ** simple ctype_is operations.
1762 ** DO NOT use real type of c, only direct type.
1766 ** ctype_isVoidPointer
1772 ctype_isVoidPointer (ctype c)
1774 if (ctype_isComplex (c))
1776 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1778 if (ctype_isConj (c))
1780 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1781 ctype_isVoidPointer (ctype_getConjB (c)));
1785 return (c == ctype_voidPointer
1786 || (ctype_isRealPointer (c)
1787 && ctype_isVoid (ctype_baseArrayPtr (c))));
1794 ** true for C and LCL pointers
1798 ctype_isPointer (ctype c)
1800 if (ctype_isElips (c)) return FALSE;
1802 if (ctype_isComplex (c))
1804 ctbase ctb = ctype_getCtbaseSafe (c);
1805 bool res = ctbase_isPointer (ctb);
1811 bool res = ctentry_isPointer (ctype_getCtentry (c));
1820 ** true for C and LCL array's
1824 ctype_isArray (ctype c)
1826 if (ctype_isElips (c)) return FALSE;
1828 if (ctype_isComplex (c))
1829 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1831 return (ctentry_isArray (ctype_getCtentry (c)));
1834 bool ctype_isIncompleteArray (ctype c)
1836 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1840 ctype_isArrayPtr (ctype c)
1842 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1846 ctype_typeId (ctype c)
1848 return (ctbase_typeId (ctype_getCtbase (c)));
1852 ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1854 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
1856 if (ctype_isUnknown (c))
1858 return message ("? %q", name);
1862 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1867 ctype_unparse (ctype c)
1869 if (ctype_isElips (c))
1871 return cstring_makeLiteralTemp ("...");
1873 else if (ctype_isMissingParamsMarker (c))
1875 return cstring_makeLiteralTemp ("-");
1877 else if (ctype_isAnytype (c))
1879 return cstring_makeLiteralTemp ("<any>");
1881 else if (ctype_isUnknown (c))
1883 return cstring_makeLiteralTemp ("?");
1888 return (ctentry_doUnparse (ctype_getCtentry (c)));
1894 ctype_unparseSafe (ctype c)
1896 if (ctype_isElips (c))
1898 return cstring_makeLiteralTemp ("...");
1900 else if (ctype_isMissingParamsMarker (c))
1902 return cstring_makeLiteralTemp ("-");
1908 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1910 ctentry cte = ctype_getCtentry (c);
1912 if (cstring_isDefined (cte->unparse))
1914 return (cte->unparse);
1918 ret = message ("[%d]", (int) c);
1919 cstring_markOwned (ret);
1925 ctype_unparseDeep (ctype c)
1927 if (ctype_isElips (c))
1929 return cstring_makeLiteralTemp ("...");
1931 if (ctype_isMissingParamsMarker (c))
1933 return cstring_makeLiteralTemp ("-");
1936 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1940 ctype_undump (char **c)
1942 return ((ctype) reader_getInt (c)); /* check its valid? */
1946 ctype_dump (ctype c)
1948 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1952 /* Handle invalid types in a kludgey way. */
1953 return (message ("0"));
1958 cstring tname = usymtab_getTypeEntryName (usymtab_convertTypeId (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))
2011 return (ctype_getBaseType (ctb->contents.base));
2013 return (ctype_getBaseType (ctb->contents.farray->base));
2014 case CT_CONJ: /* base type of A conj branch? */
2015 return (ctype_getBaseType (ctb->contents.conj->a));
2017 /*@noaccess ctbase@*/
2025 llbuglit ("ctype_newBase: bad case");
2027 llcontbuglit ("ctype_getBaseType: unreachable code");
2028 return ((ctype)NULL);
2032 ctype_adjustPointers (pointers p, ctype c)
2034 int np = pointers_depth (p);
2036 if (ctype_isFunction (c))
2038 c = ctype_makeParamsFunction
2039 (ctype_adjustPointers (p, ctype_getReturnType (c)),
2040 uentryList_copy (ctype_argsFunction (c)));
2044 /* fix this should not use getBaseType ??? */
2045 ctype cb = ctype_getBaseType (c);
2049 cb = ctype_makePointer (cb);
2052 c = ctype_newBase (c, cb);
2060 ctype_elist (ctype c)
2062 return (ctbase_elist (ctype_getCtbase (c)));
2066 ctype_isFirstVoid (ctype c)
2068 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2072 ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2074 return (cttable_addComplex (ctbase_createEnum (tag, el)));
2078 ctype_isEnum (ctype c)
2080 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2084 ctype_enumTag (ctype c)
2086 llassert (ctype_isEnum (c));
2088 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2092 ctype_isStruct (ctype c)
2094 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2098 ctype_isUnion (ctype c)
2100 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2104 ctype_resolveNumerics (ctype c1, ctype c2)
2107 ** returns longest type of c1 and c2
2110 if (c1 == c2) return c1;
2112 c1 = ctype_realType (c1);
2113 c2 = ctype_realType (c2);
2115 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2116 if (ctype_isEnum (c2)) c2 = ctype_int;
2118 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
2120 /* 2001-06-08: This fix provided by Jim Zelenka. */
2121 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2122 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2124 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2125 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2126 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2127 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
2129 /* 2001-06-08: This fix provided by Jim Zelenka. */
2130 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2132 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
2134 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2135 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2137 if (ctype_isKnown (c1)) return c1;
2142 ctype_isStructorUnion (ctype c)
2144 return (ctype_isStruct (c) || ctype_isUnion (c));
2148 ctype_fixArrayPtr (ctype c)
2150 if (ctype_isArray (c))
2152 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2159 ** createUnnamedStruct/Union
2161 ** check if it corresponds to an existing LCL-specified unnamed struct
2162 ** otherwise, give it a new tag
2166 ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2168 ctype ret = usymtab_structFieldsType (f);
2170 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2172 if (ctype_isDefined (ret))
2174 uentryList_free (f);
2179 cstring ft = fakeTag ();
2180 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2181 uentry ue = uentry_makeStructTagLoc (ft, ct);
2183 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2184 ue = usymtab_supGlobalEntryReturn (ue);
2185 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2193 ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2195 ctype ret = usymtab_unionFieldsType (f);
2197 if (ctype_isDefined (ret))
2199 uentryList_free (f);
2204 cstring ft = fakeTag ();
2205 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2206 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2208 usymtab_supGlobalEntry (ue);
2215 ctype_isUnnamedSU (ctype c)
2219 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2228 ctype_createForwardStruct (cstring n)
2230 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2231 ctype ct = usymtab_supForwardTypeEntry (ue);
2238 ctype_createForwardUnion (cstring n)
2240 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2241 ctype ct = usymtab_supForwardTypeEntry (ue);
2248 ctype_createForwardEnum (cstring n)
2250 uentry ue = uentry_makeEnumTag (n, ctype_unknown, fileloc_undefined);
2251 ctype ct = usymtab_supForwardTypeEntry (ue);
2258 ctype_removePointers (ctype c)
2262 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
2265 c = ctype_baseArrayPtr (c);
2266 llassert (c != oldc);
2272 bool ctype_isMutable (ctype t)
2276 return (uentry_isMutableDatatype
2277 (usymtab_getTypeEntry (ctype_typeId (t))));
2281 return (ctype_isPointer (ctype_realType (t)));
2282 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
2286 bool ctype_isRefCounted (ctype t)
2290 return (uentry_isRefCountedDatatype
2291 (usymtab_getTypeEntry (ctype_typeId (t))));
2297 bool ctype_isVisiblySharable (ctype t)
2299 if (ctype_isUnknown (t))
2304 if (ctype_isConj (t))
2306 return (ctype_isVisiblySharable (ctype_getConjA (t))
2307 || ctype_isVisiblySharable (ctype_getConjB (t)));
2310 if (ctype_isMutable (t))
2314 ctype rt = ctype_realType (t);
2318 if (ctype_isNumAbstract (t))
2329 return ctype_isVisiblySharable (rt);
2343 /* Replaced by ctype_isMutable (more sensible) */
2344 bool ctype_canAlias (ctype ct)
2346 /* can ct refer to memory locations?
2347 ** ==> a pointer or a mutable abstract type
2351 ctype tr = ctype_realType (ct);
2353 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2358 ** c1 is the dominant type; c2 is the modifier type
2360 ** eg. double + long int => long double
2363 ctype ctype_combine (ctype dominant, ctype modifier)
2365 DPRINTF (("Combine: %s + %s",
2366 ctype_unparse (dominant),
2367 ctype_unparse (modifier)));
2369 if (ctype_isConj (dominant))
2373 if (ctype_isExplicitConj (dominant))
2375 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2377 ctype_getConjB (dominant));
2381 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2383 ctype_getConjB (dominant));
2389 if (ctype_isUnknown (modifier))
2393 else if (ctype_isUnknown (dominant))
2399 if (ctype_isEnum (dominant)) dominant = ctype_int;
2400 if (ctype_isEnum (modifier)) modifier = ctype_int;
2402 if (modifier == ctype_uint)
2404 if (dominant == ctype_int) return ctype_uint;
2405 if (dominant == ctype_lint) return ctype_ulint;
2406 if (dominant == ctype_sint) return ctype_usint;
2407 if (dominant == ctype_char) return ctype_uchar;
2409 /* evs 2000-07-28: added this line */
2410 if (dominant == ctype_llint) return ctype_ullint;
2412 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2414 voptgenerror (FLG_DUPLICATEQUALS,
2415 message ("Duplicate unsigned qualifier"),
2422 voptgenerror (FLG_DUPLICATEQUALS,
2423 message ("Type qualifier unsigned used with %s",
2424 ctype_unparse (dominant)),
2430 else if (modifier == ctype_llint)
2432 if (dominant == ctype_int)
2437 voptgenerror (FLG_DUPLICATEQUALS,
2438 message ("Duplicate long qualifier on non-int"),
2441 else if (modifier == ctype_lint)
2443 if (dominant == ctype_int) return ctype_lint;
2444 if (dominant == ctype_uint) return ctype_ulint;
2445 if (dominant == ctype_double) return ctype_ldouble;
2447 if (dominant == ctype_lint || dominant == ctype_ulint
2448 || dominant == ctype_sint || dominant == ctype_usint
2449 || dominant == ctype_ldouble)
2451 if (dominant == ctype_lint)
2453 /* long long not supported by ANSI */
2458 if (dominant == ctype_ulint)
2460 /* unsigned long long not supported by ANSI */
2461 return ctype_ullint;
2465 if (dominant == ctype_sint || dominant == ctype_usint)
2467 if (!context_getFlag (FLG_IGNOREQUALS))
2469 llerrorlit (FLG_SYNTAX,
2470 "Contradictory long and short type qualifiers");
2475 voptgenerror (FLG_DUPLICATEQUALS,
2476 message ("Duplicate long qualifier"),
2483 else if (modifier == ctype_sint)
2485 if (dominant == ctype_int) return ctype_sint;
2486 if (dominant == ctype_uint) return ctype_usint;
2488 if (dominant == ctype_sint || dominant == ctype_usint)
2490 voptgenerror (FLG_DUPLICATEQUALS,
2491 message ("Duplicate short qualifier"),
2495 else if (dominant == ctype_lint)
2497 if (!context_getFlag (FLG_IGNOREQUALS))
2499 llerrorlit (FLG_SYNTAX,
2500 "Contradictory long and short type qualifiers");
2506 else if (dominant == ctype_llint)
2508 if (!context_getFlag (FLG_IGNOREQUALS))
2510 llerrorlit (FLG_SYNTAX,
2511 "Contradictory long long and short type qualifiers");
2519 if (!context_getFlag (FLG_IGNOREQUALS))
2521 llerror (FLG_SYNTAX,
2522 message ("Type qualifier short used with %s",
2523 ctype_unparse (dominant)));
2529 else if (modifier == ctype_ulint)
2531 if (dominant == ctype_int) return modifier;
2533 if (dominant == ctype_lint || dominant == ctype_ulint)
2535 voptgenerror (FLG_DUPLICATEQUALS,
2536 message ("Duplicate long qualifier"),
2542 if (dominant == ctype_uint || dominant == ctype_usint)
2544 voptgenerror (FLG_DUPLICATEQUALS,
2545 message ("Duplicate unsigned qualifier"),
2551 if (dominant == ctype_sint || dominant == ctype_usint)
2553 if (!context_getFlag (FLG_IGNOREQUALS))
2555 llerrorlit (FLG_SYNTAX,
2556 "Contradictory long and short type qualifiers");
2562 if (!context_getFlag (FLG_IGNOREQUALS))
2564 llerror (FLG_SYNTAX,
2565 message ("Type qualifiers unsigned long used with %s",
2566 ctype_unparse (dominant)));
2571 else if (modifier == ctype_usint)
2573 if (dominant == ctype_int) return modifier;
2575 if (dominant == ctype_sint || dominant == ctype_usint)
2577 voptgenerror (FLG_DUPLICATEQUALS,
2578 message ("Duplicate short qualifier"),
2583 if (dominant == ctype_uint)
2585 voptgenerror (FLG_DUPLICATEQUALS,
2586 message ("Duplicate unsigned qualifier"),
2592 if (dominant == ctype_lint || dominant == ctype_ulint
2593 || dominant == ctype_llint)
2595 if (!context_getFlag (FLG_IGNOREQUALS))
2597 llerrorlit (FLG_SYNTAX,
2598 "Contradictory long and short type qualifiers");
2604 if (!context_getFlag (FLG_IGNOREQUALS))
2606 llerror (FLG_SYNTAX,
2607 message ("Type qualifiers unsigned short used with %s",
2608 ctype_unparse (dominant)));
2622 ctype ctype_resolve (ctype c)
2624 if (ctype_isUnknown (c) && !ctype_isAnytype (c))
2626 DPRINTF (("Resolving to int: %s", ctype_unparse (c)));
2633 ctype ctype_fromQual (qual q)
2635 if (qual_isSigned (q)) return ctype_int;
2636 if (qual_isUnsigned (q)) return ctype_uint;
2637 if (qual_isLong (q)) return ctype_lint;
2638 if (qual_isShort (q)) return ctype_sint;
2640 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2641 return ctype_unknown;
2645 ctype_isAnyFloat (ctype c)
2647 return (cprim_isAnyReal (ctype_toCprim (c)));
2651 ctype_isUnsigned (ctype c)
2653 if (ctype_isConj (c))
2654 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2655 ctype_isUnsigned (ctype_getConjB (c)));
2657 return (c == ctype_uint || c == ctype_uchar
2658 || c == ctype_usint || c == ctype_ulint
2659 || c == ctype_ullint
2660 || c == ctype_unsignedintegral);
2665 ctype_isLongLong (ctype c)
2667 if (ctype_isConj (c))
2668 return (ctype_isLongLong (ctype_getConjA (c)) ||
2669 ctype_isLongLong (ctype_getConjB (c)));
2671 return (c == ctype_llint || c == ctype_ullint);
2676 ctype_isLong (ctype c)
2678 if (ctype_isConj (c))
2679 return (ctype_isLong (ctype_getConjA (c)) ||
2680 ctype_isLong (ctype_getConjB (c)));
2682 return (c == ctype_lint || c == ctype_ulint);
2686 ctype_isShort (ctype c)
2688 if (ctype_isConj (c))
2689 return (ctype_isShort (ctype_getConjA (c)) ||
2690 ctype_isShort (ctype_getConjB (c)));
2692 return (c == ctype_sint || c == ctype_usint);
2696 ctype_isStackAllocated (ctype c)
2698 ctype ct = ctype_realType (c);
2700 if (ctype_isConj (ct))
2701 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2702 ctype_isStackAllocated (ctype_getConjB (ct)));
2704 return (ctype_isArray (c) || ctype_isSU (c));
2707 static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2709 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2712 static bool ctype_isLonger (ctype c1, ctype c2)
2714 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
2715 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
2716 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2717 || (ctype_isLong (c1)
2718 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
2719 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2723 ctype_widest (ctype c1, ctype c2)
2725 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
2735 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2738 if (c >= 0 && c < cttab.size)
2740 return (cttab.entries[c]->ctbase);
2744 if (c == ctype_unknown)
2745 llbuglit ("ctype_getCtbase: ctype unknown");
2746 if (c == ctype_undefined)
2747 llbuglit ("ctype_getCtbase: ctype undefined");
2749 llbuglit ("ctype_getCtbase: ctype dne");
2750 if (c == ctype_elipsMarker)
2751 llbuglit ("ctype_getCtbase: elips marker");
2753 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2760 static /*@notnull@*/ /*@observer@*/ ctbase
2761 ctype_getCtbaseSafe (ctype c)
2763 ctbase res = ctype_getCtbase (c);
2765 llassert (ctbase_isDefined (res));
2774 ctype_getCtentry (ctype c)
2776 static /*@only@*/ ctentry errorEntry = NULL;
2778 if (cttab.size == 0)
2780 if (errorEntry == NULL)
2782 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2789 if (c >= CTK_PLAIN && c < cttab.size)
2791 return (cttab.entries[c]);
2793 else if (c == CTK_UNKNOWN)
2794 llcontbuglit ("ctype_getCtentry: ctype unknown");
2795 else if (c == CTK_INVALID)
2796 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2797 else if (c == CTK_DNE)
2798 llcontbuglit ("ctype_getCtentry: ctype dne");
2799 else if (c == CTK_ELIPS)
2800 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2801 else if (c == CTK_MISSINGPARAMS)
2802 llcontbuglit ("ctype_getCtentry: ctype missing params");
2804 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2806 return (cttab.entries[ctype_unknown]);
2811 bool ctype_isFixedArray (ctype c)
2813 if (ctype_isElips (c)) return FALSE;
2815 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2820 /* requires that the type is an fixed array */
2821 /* return the size of the array */
2823 size_t ctype_getArraySize (ctype c)
2829 llassert (ctype_isFixedArray (c));
2831 ctb = ctype_getCtbaseSafe(c);
2832 size = ctbase_getArraySize (ctb);
2834 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2840 ctype ctype_biggerType (ctype c1, ctype c2)
2842 if (ctbase_isBigger (ctype_getCtbaseSafe (c2), ctype_getCtbaseSafe (c1)))
2852 int ctype_getSize (ctype c)
2854 return ctbase_getSize (ctype_getCtbaseSafe (ctype_realType (c)));