X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/616915ddfdcba888735f45cbd9c26c9b5383ee2c..ed62d3fbeda6bb085991cdd683ceacfc57f7afbe:/src/ctype.c diff --git a/src/ctype.c b/src/ctype.c index 02cd2a5..8ed249f 100644 --- a/src/ctype.c +++ b/src/ctype.c @@ -1,6 +1,6 @@ /* -** LCLint - annotation-assisted static program checker -** Copyright (C) 1994-2000 University of Virginia, +** Splint - annotation-assisted static program checker +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -17,9 +17,9 @@ ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ** MA 02111-1307, USA. ** -** For information on lclint: lclint-request@cs.virginia.edu -** To report a bug: lclint-bug@cs.virginia.edu -** For more information: http://lclint.cs.virginia.edu +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org +** For more information: http://www.splint.org */ /* ** ctype.c @@ -28,7 +28,7 @@ ** They should probably be separated soon. */ -# include "lclintMacros.nf" +# include "splintMacros.nf" # include "basic.h" # include "structNames.h" @@ -52,12 +52,12 @@ static ctype ctype_getConjB (ctype p_c) /*@*/ ; static bool ctype_isComplex (ctype c) { - return (ctentry_isComplex (ctype_getCtentry(c))); + return (ctentry_isComplex (ctype_getCtentry (c))); } static bool ctype_isPlain (ctype c) { - return (ctentry_isPlain (ctype_getCtentry(c))); + return (ctentry_isPlain (ctype_getCtentry (c))); } static bool ctype_isBroken (ctype c) @@ -108,6 +108,7 @@ ctype_destroyMod () void ctype_loadTable (FILE *f) { + DPRINTF (("Loading cttable!")); cttable_load (f); } @@ -153,9 +154,21 @@ ctype_createUser (typeId u) ctype ctype_createAbstract (typeId u) { - /* requires: ctype_createAbstract (u) is never called more than once for any u. */ - /* [ tested by cttable_addFullSafe, not really required ] */ - return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u)))); + /* requires: ctype_createAbstract (u) is never called more than once for any u. */ + /* [ tested by cttable_addFullSafe, not really required ] */ + + return (cttable_addFullSafe + (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u)))); +} + +ctype +ctype_createNumAbstract (typeId u) +{ + /* requires: ctype_createAbstract (u) is never called more than once for any u. */ + /* [ tested by cttable_addFullSafe, not really required ] */ + + return (cttable_addFullSafe + (ctentry_makeNew (CTK_PLAIN, ctbase_createNumAbstract (u)))); } int @@ -169,6 +182,11 @@ ctype_realType (ctype c) { ctype r = c; + if (ctype_isElips (c) || ctype_isMissingParamsMarker (c)) + { + return c; + } + if (ctype_isUA (c)) { r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c))); @@ -188,7 +206,7 @@ ctype_realType (ctype c) bool ctype_isSimple (ctype c) { - return (!(ctype_isPointer (c) + return (! (ctype_isPointer (c) || ctype_isArray (c) || ctype_isFunction (c))); } @@ -218,7 +236,7 @@ ctype_realishType (ctype c) else { ctype r = uentry_getRealType (usymtab_getTypeEntry - (ctype_typeId (c))); + (ctype_typeId (c))); return (r); } } @@ -229,22 +247,40 @@ ctype_realishType (ctype c) bool ctype_isUA (ctype c) { - return (ctbase_isUA (ctype_getCtbase (c))); + return (!ctype_isUnknown (c) + && ctbase_isUA (ctype_getCtbase (c))); } bool ctype_isUser (ctype c) { - return (ctbase_isUser (ctype_getCtbase (c))); + return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c))); } bool ctype_isAbstract (ctype c) { - return ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) || - (ctype_isConj (c) && - (ctype_isAbstract (ctype_getConjA (c)) - || ctype_isAbstract (ctype_getConjB (c))))); + return (!ctype_isUnknown (c) + && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) || + (ctype_isConj (c) && + (ctype_isAbstract (ctype_getConjA (c)) + || ctype_isAbstract (ctype_getConjB (c)))))); +} + +bool +ctype_isNumAbstract (ctype c) +{ + return (!ctype_isUnknown (c) + && ((ctype_isPlain (c) && ctbase_isNumAbstract (ctype_getCtbaseSafe (c))) || + (ctype_isConj (c) && + (ctype_isNumAbstract (ctype_getConjA (c)) + || ctype_isNumAbstract (ctype_getConjB (c)))))); +} + +bool +ctype_isImmutableAbstract (ctype t) +{ + return (ctype_isAbstract (t) && !ctype_isMutable (t)); } bool @@ -256,6 +292,15 @@ ctype_isRealAbstract (ctype c) ctype_isRealAbstract (ctype_getConjB (c))))); } +bool +ctype_isRealNumAbstract (ctype c) +{ + return (ctype_isNumAbstract (ctype_realType (c)) || + (ctype_isConj (c) && + (ctype_isRealNumAbstract (ctype_getConjA (c)) || + ctype_isRealNumAbstract (ctype_getConjB (c))))); +} + /* ** primitive creators */ @@ -293,18 +338,68 @@ ctype_makePointer (ctype c) { ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c); ctentry_setPtr (cte, cnew); - return (cnew); + return (cnew); } else { - return clp; + return clp; } } } -ctype ctype_makeFixedArray (ctype c, long size) +ctype ctype_makeFixedArray (ctype c, size_t size) +{ + ctype res; + res = cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c); + return res; +} + +ctype ctype_makeInnerFixedArray (ctype c, size_t size) +{ + ctype res; + + if (ctype_isFixedArray (c)) + { + ctype cb = ctype_baseArrayPtr (c); + size_t osize = ctype_getArraySize (c); + + res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize); + } + else if (ctype_isArray (c)) + { + ctype cb = ctype_baseArrayPtr (c); + + res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size)); + } + else + { + res = ctype_makeFixedArray (c, size); + } + + DPRINTF (("Make inner fixed array: %s", ctype_unparse (res))); + return res; +} + +ctype ctype_makeInnerArray (ctype c) { - return (cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c)); + ctype res; + + DPRINTF (("Make inner array: %s", ctype_unparse (c))); + + if (ctype_isFixedArray (c)) + { + ctype cb = ctype_baseArrayPtr (c); + size_t osize = ctype_getArraySize (c); + + res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize); + } + else + { + res = ctype_makeArray (c); + } + + DPRINTF (("Make inner array: %s", ctype_unparse (res))); + return res; } ctype @@ -313,6 +408,8 @@ ctype_makeArray (ctype c) ctentry cte = ctype_getCtentry (c); ctype clp = ctentry_getArray (cte); + DPRINTF (("Make array: %s", ctype_unparse (c))); + if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/ { ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c); @@ -320,7 +417,9 @@ ctype_makeArray (ctype c) return (cnew); } else - return clp; + { + return clp; + } } /* @@ -368,9 +467,64 @@ ctype_baseArrayPtr (ctype c) } } +/* +** wchar_t * +*/ + +ctype +ctype_makeWideString () +{ + static ctype res = ctype_unknown; + + if (ctype_isUnknown (res)) + { + ctype wchart; + + if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t"))) + { + wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))); + } + else + { + wchart = ctype_char; + } + + res = ctype_makePointer (wchart); + } + + return res; +} + +bool +ctype_isWideString (ctype c) +{ + if (ctype_isPointer (c)) + { + ctype ct = ctype_baseArrayPtr (c); + + if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t"))) + { + return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")))); + } + else + { + return FALSE; + } + } + else + { + return FALSE; + } +} + ctype -ctype_returnValue (ctype c) +ctype_getReturnType (ctype c) { + if (ctype_isUnknown (c)) + { + return ctype_unknown; + } + return (ctbase_baseFunction (ctype_getCtbaseSafe (c))); } @@ -381,6 +535,11 @@ ctype_returnValue (ctype c) /*@observer@*/ uentryList ctype_argsFunction (ctype c) { + if (ctype_isUnknown (c)) + { + return uentryList_undefined; + } + return (ctbase_argsFunction (ctype_getCtbaseSafe (c))); } @@ -462,6 +621,23 @@ ctype_compare (ctype c1, ctype c2) ctentry ce1; ctentry ce2; + if (ctype_isUnknown (c1)) + { + if (ctype_isUnknown (c2)) + { + return 0; + } + else + { + return 1; + } + } + + if (ctype_isUnknown (c2)) + { + return -1; + } + /* Can't get entries for special ctypes (elips marker) */ if (ctype_isElips (c1) || ctype_isElips (c2) @@ -536,13 +712,27 @@ ctype ctype_expectFunction (ctype c) return (cttable_addComplex (ctbase_expectFunction (c))); } +ctype ctype_dontExpectFunction (ctype c) +{ + ctbase ctb = ctype_getCtbase (c); + + /* what about this? + if (!ctype_isAP (c)) + { + c = ctype_makePointer (c); + } + */ + + return (ctbase_getExpectFunction (ctb)); +} + /* ** makeRealFunction: function returning base */ -ctype ctype_makeRealFunction (ctype base, uentryList p) +ctype ctype_makeRawFunction (ctype base, uentryList p) { - return (cttable_addComplex (ctbase_makeRealFunction (base, p))); + return (cttable_addComplex (ctbase_makeLiveFunction (base, p))); } /* @@ -558,13 +748,20 @@ ctype ctype_makeRealFunction (ctype base, uentryList p) bool ctype_isFunction (ctype c) { - return (ctbase_isFunction (ctype_getCtbase (c))); + if (ctype_isKnown (c) && ctype_isDefined (c)) + { + return (ctbase_isFunction (ctype_getCtbase (c))); + } + else + { + return FALSE; + } } bool ctype_isExpFcn (ctype c) { - return (ctbase_isExpFcn (ctype_getCtbase (c))); + return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c))); } bool @@ -751,7 +948,9 @@ ctype_isSigned (ctype c) bool ctype_isNumeric (ctype c) { - return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)); + return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c) + /* evans 2001-10-05: added this: */ + || ctype_isArbitraryIntegral (c)); } @@ -841,6 +1040,8 @@ ctype_isRealSU (ctype c) return (ctype_isRealSU (ctype_getConjA (c)) || ctype_isRealSU (ctype_getConjB (c))); } + + DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c)))); return (ctype_isStructorUnion (ctype_realType (c))); } @@ -887,11 +1088,11 @@ ctype_isDirectInt (ctype c) static bool ctype_isForcePred (ctype * c, bool (pred) (ctype)) { - if (ctype_isConj (*c)) + /*drl bee: pbr */ if (ctype_isConj (*c)) { ctype cbr = ctype_getConjA (*c); - if ((*pred) (cbr)) + if ((*pred) (cbr)) { if ((*pred) (ctype_getConjB (*c))) { @@ -968,15 +1169,19 @@ ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit) ctype ctype_makeExplicitConj (ctype c1, ctype c2) { - if (ctype_isFunction (c1) && !ctype_isFunction (c2)) + if (ctype_isAnytype (c1) || ctype_isAnytype (c2)) + { + return ctype_makeAnytype (); + } + else if (ctype_isFunction (c1) && !ctype_isFunction (c2)) { - ctype ret = ctype_makeExplicitConj (ctype_returnValue (c1), c2); + ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2); return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1))); } else if (ctype_isFunction (c2) && !ctype_isFunction (c1)) { - ctype ret = ctype_makeExplicitConj (c1, ctype_returnValue (c2)); + ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2)); return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2))); } @@ -997,6 +1202,27 @@ static ctype ivb = ctype_unknown; /* int | void * | bool */ static ctype ivbf = ctype_unknown; /* int | void * | bool | float */ static ctype cuc = ctype_unknown; /* char | unsigned char */ +static ctype cany = ctype_unknown; + +ctype +ctype_makeAnytype () +{ + if (cany == ctype_unknown) + { + cany = ctype_makeConj (ctype_unknown, ctype_dne); + llassert (ctype_isAnytype (cany)); + } + + DPRINTF (("make anytype: %s", ctype_unparse (cany))); + return cany; +} + +bool +ctype_isAnytype (ctype c) +{ + return (c == cany); +} + static void ctype_recordConj (ctype c) { @@ -1117,14 +1343,30 @@ ctype_makeConj (ctype c1, ctype c2) DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2))); - if (ctype_isFunction (c1) && !ctype_isFunction (c2)) + if (ctype_isAnytype (c1)) + { + return c1; + } + else if (ctype_isAnytype (c2)) + { + return c2; + } + else if (ctype_isUnknown (c1)) + { + return c2; + } + else if (ctype_isUnknown (c2)) + { + return c1; + } + else if (ctype_isFunction (c1) && !ctype_isFunction (c2)) { - ctype ret = ctype_makeConj (ctype_returnValue (c1), c2); + ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2); return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1))); } else if (ctype_isFunction (c2) && !ctype_isFunction (c1)) { - ctype ret = ctype_makeConj (c1, ctype_returnValue (c2)); + ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2)); return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2))); } else @@ -1201,7 +1443,7 @@ ctype_makeConj (ctype c1, ctype c2) if (iv == ctype_unknown) { iv = cttable_addComplex - (ctbase_makeConj (ctype_int, + (ctbase_makeConj (ctype_int, ctype_voidPointer, FALSE)); } @@ -1300,7 +1542,6 @@ ctype_makeConj (ctype c1, ctype c2) { ; } - return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE))); } @@ -1428,7 +1669,18 @@ ctype_almostEqual (ctype c1, ctype c2) } else { - return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2))); + if (ctype_isUnknown (c1)) + { + return ctype_isUnknown (c2); + } + else if (ctype_isUnknown (c2)) + { + return FALSE; + } + else + { + return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2))); + } } } @@ -1444,7 +1696,9 @@ ctype_matchDef (ctype c1, ctype c2) return (ctype_isElips (c2) || ctype_isUnknown (c2)); if (ctype_isElips (c2)) - return (ctype_isUnknown (c2)); + { + return (ctype_isUnknown (c2)); + } else { bool oldrelax = context_getFlag (FLG_RELAXQUALS); @@ -1581,13 +1835,6 @@ bool ctype_isIncompleteArray (ctype c) return (ctype_isArray (c) && !ctype_isFixedArray (c)); } -bool ctype_isFixedArray (ctype c) -{ - if (ctype_isElips (c)) return FALSE; - - return (ctbase_isFixedArray (ctype_getCtbaseSafe (c))); -} - bool ctype_isArrayPtr (ctype c) { @@ -1604,7 +1851,15 @@ cstring ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name) { llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c))); - return (ctbase_unparseDeclaration (ctype_getCtbase (c), name)); + + if (ctype_isUnknown (c)) + { + return message ("? %q", name); + } + else + { + return (ctbase_unparseDeclaration (ctype_getCtbase (c), name)); + } } cstring @@ -1618,6 +1873,14 @@ ctype_unparse (ctype c) { return cstring_makeLiteralTemp ("-"); } + else if (ctype_isAnytype (c)) + { + return cstring_makeLiteralTemp (""); + } + else if (ctype_isUnknown (c)) + { + return cstring_makeLiteralTemp ("?"); + } else { /*@-modobserver@*/ @@ -1675,7 +1938,7 @@ ctype_unparseDeep (ctype c) ctype ctype_undump (char **c) { - return ((ctype) getInt (c)); /* check its valid? */ + return ((ctype) reader_getInt (c)); /* check its valid? */ } cstring @@ -1691,8 +1954,7 @@ ctype_dump (ctype c) if (ctype_isUA (c)) { - cstring tname = usymtab_getTypeEntryName - (usymtab_convertId (ctype_typeId (c))); + cstring tname = usymtab_getTypeEntryName (usymtab_convertTypeId (ctype_typeId (c))); if (cstring_equal (tname, context_getBoolName ())) { @@ -1715,9 +1977,7 @@ ctype_getBaseType (ctype c) switch (ctentry_getKind (cte)) { case CTK_UNKNOWN: - llcontbuglit ("ctype_getBaseType: unknown ctype"); break; case CTK_INVALID: - llcontbuglit ("ctype_getBaseType: invalid ctype"); break; case CTK_PLAIN: return c; case CTK_PTR: @@ -1729,6 +1989,7 @@ ctype_getBaseType (ctype c) if (ctbase_isDefined (ctb)) { + /*@access ctbase@*/ switch (ctb->type) { case CT_UNKNOWN: @@ -1738,6 +1999,7 @@ ctype_getBaseType (ctype c) case CT_ENUMLIST: case CT_BOOL: case CT_ABST: + case CT_NUMABST: case CT_FCN: case CT_STRUCT: case CT_UNION: @@ -1751,6 +2013,7 @@ ctype_getBaseType (ctype c) case CT_CONJ: /* base type of A conj branch? */ return (ctype_getBaseType (ctb->contents.conj->a)); } + /*@noaccess ctbase@*/ } else { @@ -1765,13 +2028,14 @@ ctype_getBaseType (ctype c) } ctype -ctype_adjustPointers (int np, ctype c) +ctype_adjustPointers (pointers p, ctype c) { - + int np = pointers_depth (p); + if (ctype_isFunction (c)) { c = ctype_makeParamsFunction - (ctype_adjustPointers (np, ctype_returnValue (c)), + (ctype_adjustPointers (p, ctype_getReturnType (c)), uentryList_copy (ctype_argsFunction (c))); } else @@ -1851,11 +2115,21 @@ ctype_resolveNumerics (ctype c1, ctype c2) if (ctype_isEnum (c2)) c2 = ctype_int; if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble; + + /* 2001-06-08: This fix provided by Jim Zelenka. */ + if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint; + if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint; + if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint; if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint; if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint; if (c1 == ctype_int || c2 == ctype_int) return ctype_int; + + /* 2001-06-08: This fix provided by Jim Zelenka. */ + if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint; + if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint; + if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar; if (c1 == ctype_char || c2 == ctype_char) return ctype_char; @@ -1892,6 +2166,8 @@ ctype_createUnnamedStruct (/*@only@*/ uentryList f) { ctype ret = usymtab_structFieldsType (f); + DPRINTF (("unnamed struct: %s", ctype_unparse (ret))); + if (ctype_isDefined (ret)) { uentryList_free (f); @@ -1902,9 +2178,11 @@ ctype_createUnnamedStruct (/*@only@*/ uentryList f) cstring ft = fakeTag (); ctype ct = ctype_createStruct (cstring_copy (ft), f); uentry ue = uentry_makeStructTagLoc (ft, ct); - - usymtab_supGlobalEntry (ue); - + + DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue))); + ue = usymtab_supGlobalEntryReturn (ue); + DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue))); + cstring_free (ft); return (ct); } @@ -1932,6 +2210,19 @@ ctype_createUnnamedUnion (/*@only@*/ uentryList f) } } +bool +ctype_isUnnamedSU (ctype c) +{ + if (ctype_isSU (c)) + { + return ctbase_isUnnamedSU (ctype_getCtbase (c)); + } + else + { + return FALSE; + } +} + ctype ctype_createForwardStruct (cstring n) { @@ -1952,12 +2243,22 @@ ctype_createForwardUnion (cstring n) return (ct); } +ctype +ctype_createForwardEnum (cstring n) +{ + uentry ue = uentry_makeEnumTag (n, ctype_unknown, fileloc_undefined); + ctype ct = usymtab_supForwardTypeEntry (ue); + + cstring_free (n); + return (ct); +} + ctype ctype_removePointers (ctype c) { ctype oldc; - while (ctype_isArrayPtr (c)) + while (ctype_isKnown (c) && ctype_isArrayPtr (c)) { oldc = c; c = ctype_baseArrayPtr (c); @@ -1977,6 +2278,7 @@ bool ctype_isMutable (ctype t) else { return (ctype_isPointer (ctype_realType (t))); + /*!! || ctype_isStructorUnion (ctype_realType (t))); */ } } @@ -1993,7 +2295,10 @@ bool ctype_isRefCounted (ctype t) bool ctype_isVisiblySharable (ctype t) { - if (ctype_isUnknown (t)) return TRUE; + if (ctype_isUnknown (t)) + { + return TRUE; + } if (ctype_isConj (t)) { @@ -2009,11 +2314,19 @@ bool ctype_isVisiblySharable (ctype t) if (rt == t) { - return TRUE; + if (ctype_isNumAbstract (t)) + { + return FALSE; + } + else + { + return TRUE; + } } else { return ctype_isVisiblySharable (rt); + } } else @@ -2140,6 +2453,14 @@ ctype ctype_combine (ctype dominant, ctype modifier) return ctype_llint; } + /* ++jimz */ + if (dominant == ctype_ulint) + { + /* unsigned long long not supported by ANSI */ + return ctype_ullint; + } + /* ==jimz */ + if (dominant == ctype_sint || dominant == ctype_usint) { if (!context_getFlag (FLG_IGNOREQUALS)) @@ -2180,6 +2501,18 @@ ctype ctype_combine (ctype dominant, ctype modifier) return dominant; } +/* ++jimz */ + else if (dominant == ctype_llint) + { + if (!context_getFlag (FLG_IGNOREQUALS)) + { + llerrorlit (FLG_SYNTAX, + "Contradictory long long and short type qualifiers"); + } + + return dominant; + } +/* ==jimz */ else { if (!context_getFlag (FLG_IGNOREQUALS)) @@ -2287,7 +2620,12 @@ ctype ctype_combine (ctype dominant, ctype modifier) ctype ctype_resolve (ctype c) { - if (ctype_isUnknown (c)) return ctype_int; + if (ctype_isUnknown (c) && !ctype_isAnytype (c)) + { + DPRINTF (("Resolving to int: %s", ctype_unparse (c))); + return ctype_int; + } + return c; } @@ -2317,9 +2655,22 @@ ctype_isUnsigned (ctype c) return (c == ctype_uint || c == ctype_uchar || c == ctype_usint || c == ctype_ulint + || c == ctype_ullint || c == ctype_unsignedintegral); } +/* ++jimz */ +static bool +ctype_isLongLong (ctype c) +{ + if (ctype_isConj (c)) + return (ctype_isLongLong (ctype_getConjA (c)) || + ctype_isLongLong (ctype_getConjB (c))); + + return (c == ctype_llint || c == ctype_ullint); +} +/* ==jimz */ + static bool ctype_isLong (ctype c) { @@ -2359,16 +2710,18 @@ static bool ctype_isMoreUnsigned (ctype c1, ctype c2) static bool ctype_isLonger (ctype c1, ctype c2) { + /* 2001-06-10: Fix for long long's provided by Jim Zelenka */ return ((ctype_isDouble (c1) && !ctype_isDouble (c2)) - || (ctype_isLong (c1) && !ctype_isLong (c2)) + || (ctype_isLongLong (c1) && !ctype_isLongLong (c2)) + || (ctype_isLong (c1) + && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2))) || (ctype_isShort (c2) && !ctype_isShort (c1))); } ctype ctype_widest (ctype c1, ctype c2) { - if (ctype_isMoreUnsigned (c2, c1) - || ctype_isLonger (c2, c1)) + if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1)) { return c2; } @@ -2378,21 +2731,119 @@ ctype_widest (ctype c1, ctype c2) } } +static /*@observer@*/ ctbase ctype_getCtbase (ctype c) +{ + /*@+enumint@*/ + if (c >= 0 && c < cttab.size) + { + return (cttab.entries[c]->ctbase); + } + else + { + if (c == ctype_unknown) + llbuglit ("ctype_getCtbase: ctype unknown"); + if (c == ctype_undefined) + llbuglit ("ctype_getCtbase: ctype undefined"); + if (c == ctype_dne) + llbuglit ("ctype_getCtbase: ctype dne"); + if (c == ctype_elipsMarker) + llbuglit ("ctype_getCtbase: elips marker"); + + llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c)); + BADEXIT; + } + + /*@=enumint@*/ +} + +static /*@notnull@*/ /*@observer@*/ ctbase +ctype_getCtbaseSafe (ctype c) +{ + ctbase res = ctype_getCtbase (c); + + llassert (ctbase_isDefined (res)); + return res; +} + +/* +** ctentry +*/ + +static ctentry +ctype_getCtentry (ctype c) +{ + static /*@only@*/ ctentry errorEntry = NULL; + + if (cttab.size == 0) + { + if (errorEntry == NULL) + { + errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined); + } + + return errorEntry; + } + + /*@+enumint@*/ + if (c >= CTK_PLAIN && c < cttab.size) + { + return (cttab.entries[c]); + } + else if (c == CTK_UNKNOWN) + llcontbuglit ("ctype_getCtentry: ctype unknown"); + else if (c == CTK_INVALID) + llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)"); + else if (c == CTK_DNE) + llcontbuglit ("ctype_getCtentry: ctype dne"); + else if (c == CTK_ELIPS) + llcontbuglit ("ctype_getCtentry: ctype elipsis"); + else if (c == CTK_MISSINGPARAMS) + llcontbuglit ("ctype_getCtentry: ctype missing params"); + else + llbug (message ("ctype_getCtentry: ctype out of range: %d", c)); + + return (cttab.entries[ctype_unknown]); + /*@=enumint@*/ +} + + +bool ctype_isFixedArray (ctype c) +{ + if (ctype_isElips (c)) return FALSE; + + return (ctbase_isFixedArray (ctype_getCtbaseSafe (c))); +} + + /*drl 11/28/2000 */ /* requires that the type is an fixed array */ /* return the size of the array */ -long int ctype_getArraySize (ctype c) +size_t ctype_getArraySize (ctype c) { - ctentry cte = ctype_getCtentry (c); + size_t size; + ctbase ctb; - llassert ( (ctentry_getKind (cte) == CTK_COMPLEX) || (ctentry_getKind(cte) == CTK_ARRAY) ); - ctb = cte->ctbase; + llassert (ctype_isFixedArray (c)); - llassert (ctbase_isDefined (ctb) ); - - llassert (ctb->type == CT_FIXEDARRAY); + ctb = ctype_getCtbaseSafe(c); + size = ctbase_getArraySize (ctb); + + DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ", + ctype_unparse (c), + (int) size))); + return size; +} - return (ctb->contents.farray->size); +ctype ctype_biggerType (ctype c1, ctype c2) +{ + if (ctbase_isBigger (ctype_getCtbaseSafe (c2), ctype_getCtbaseSafe (c1)) ) + { + return c2; + } + else + { + return c1; + } }