2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 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 lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
28 # include "lclintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
38 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43 static void uentry_checkIterArgs (uentry p_ue);
44 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
47 static void checkAliasState (/*@notnull@*/ uentry p_old,
48 /*@notnull@*/ uentry p_unew,
49 bool p_mustConform, bool p_completeConform)
50 /*@modifies p_old, p_unew@*/ ;
51 static void checkNullState (/*@notnull@*/ uentry p_old,
52 /*@notnull@*/ uentry p_unew,
53 bool p_mustConform, bool p_completeConform)
54 /*@modifies p_old, p_unew@*/ ;
56 static void checkVarConformance (/*@notnull@*/ uentry p_old,
57 /*@notnull@*/ uentry p_unew,
58 bool p_mustConform, bool p_completeConform)
59 /*@modifies p_old, p_unew@*/;
62 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
63 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
66 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
68 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
69 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
72 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
73 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
74 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
75 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
76 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
78 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
79 ctype p_oldType, /*@notnull@*/ uentry p_unew,
80 /*@notnull@*/ uentry p_newCurrent,
81 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
83 static /*@only@*/ /*@notnull@*/ uentry
84 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
85 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
87 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
89 uentry ue = (uentry) dmalloc (sizeof (*ue));
96 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
97 static void uentry_copyInto (/*@out@*/ /*@unique@*/ uentry p_unew, uentry p_old);
98 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
99 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
100 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
101 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
102 static void uvinfo_free (/*@only@*/ uvinfo p_u);
106 static /*@only@*/ cstring ancontext_unparse (ancontext an)
110 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
111 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
112 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
113 case AN_SUFIELD: return cstring_makeLiteral ("su field");
114 case AN_TDEFN: return cstring_makeLiteral ("type definition");
115 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
116 case AN_CONST: return cstring_makeLiteral ("constant");
122 static int annots[AN_LAST][QU_LAST];
123 static int decls[AN_LAST];
124 static int shdecls[AN_LAST];
125 static int idecls[AN_LAST];
131 for (i = AN_UNKNOWN; i < AN_LAST; i++)
137 for (j = QU_UNKNOWN; j < QU_LAST; j++)
144 static void tallyAnnot (ancontext ac, qual q)
158 for (j = QU_UNKNOWN; j < QU_LAST; j++)
163 for (i = AN_UNKNOWN; i < AN_LAST; i++)
169 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
170 ancontext_unparse (i),
171 decls[i], shdecls[i], idecls[i]);
173 totdecls += decls[i];
174 totshdecls += shdecls[i];
175 totidecls += idecls[i];
177 for (j = QU_UNKNOWN; j < QU_LAST; j++)
179 total[j] += annots[i][j];
180 alltotals += annots[i][j];
183 printf (" Allocation:\n");
187 for (j = QU_UNKNOWN; j < QU_LAST; j++)
189 if (qual_isAliasQual (j) && !qual_isUnique (j))
191 if (annots[i][j] > 0)
193 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
194 100.0 * (double)annots[i][j] / (double)decls[i]);
195 tmptot += annots[i][j];
200 printf (" Exposure:\n");
204 for (j = QU_UNKNOWN; j < QU_LAST; j++)
206 if (qual_isExQual (j))
208 if (annots[i][j] > 0)
210 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
211 100.0 * (double)annots[i][j] / (double)decls[i]);
212 tmptot += annots[i][j];
217 printf (" Definition:\n");
219 for (j = QU_UNKNOWN; j < QU_LAST; j++)
221 if (qual_isAllocQual (j))
223 if (annots[i][j] > 0)
225 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
226 100.0 * (double)annots[i][j] / (double)decls[i]);
233 for (j = QU_UNKNOWN; j < QU_LAST; j++)
235 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
237 if (annots[i][j] > 0)
239 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
240 100.0 * (double)annots[i][j] / (double)decls[i]);
249 for (j = QU_UNKNOWN; j < QU_LAST; j++)
253 for (i = AN_UNKNOWN; i < AN_LAST; i++)
255 if (annots[i][j] > 0)
264 printf ("Annotation: %s\n", qual_unparse (j));
266 for (i = AN_UNKNOWN; i < AN_LAST; i++)
268 if (annots[i][j] > 0)
270 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
277 printf ("All Contexts\n");
279 for (j = QU_UNKNOWN; j < QU_LAST; j++)
283 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
284 100.0 * (double)total[j] / (double)(totdecls));
289 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
291 extern void uentry_tallyAnnots (uentry u, ancontext kind)
293 alkind ak = sRef_getAliasKind (u->sref);
294 exkind ek = sRef_getExKind (u->sref);
295 nstate ns = sRef_getNullState (u->sref);
296 sstate ss = sRef_getDefState (u->sref);
297 bool recordUnknown = FALSE;
300 if (kind == AN_UNKNOWN)
308 else if (e == KCONST || e == KENUMCONST)
312 else if (e == KFCN || e == KITER)
314 uentryList params = uentry_getParams (u);
317 uentryList_elements (params, current)
319 if (uentry_isReturned (current))
323 if (!uentry_isElipsisMarker (current))
325 uentry_tallyAnnots (current, AN_FCNPARAM);
327 } end_uentryList_elements;
331 if (ctype_isFunction (u->utype)
333 && ctype_isVisiblySharable (ctype_realType (ctype_returnValue (u->utype))))
335 recordUnknown = TRUE;
338 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
340 ctype t = ctype_realType (u->utype);
344 uentryList fields = ctype_getFields (t);
346 uentryList_elements (fields, current)
348 uentry_tallyAnnots (current, AN_SUFIELD);
350 } end_uentryList_elements;
354 if (ctype_isVisiblySharable (u->utype))
356 recordUnknown = TRUE;
364 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
366 recordUnknown = TRUE;
373 if (kind == AN_FCNRETURN)
387 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
392 if (ctype_isRealPointer (ctype_realType (u->utype)))
409 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
410 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
411 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
412 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
416 if (uentry_isReturned (u))
418 tallyAnnot (kind, QU_RETURNED);
424 if (ctype_isRefCounted (ctype_realType (u->utype))
425 || (ctype_isFunction (u->utype) &&
426 ctype_isRefCounted (ctype_realType (ctype_returnValue (u->utype)))))
432 if (kind == AN_FCNPARAM)
434 tallyAnnot (kind, QU_TEMP);
436 else if (recordUnknown)
438 if (kind == AN_FCNRETURN)
441 tallyAnnot (kind, QU_UNKNOWN);
445 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
446 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
447 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
448 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
450 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
451 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
452 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
453 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
454 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
455 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
456 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
457 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
458 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
459 case AK_IMPDEPENDENT:
460 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
470 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
471 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
477 case NS_ERROR: break;
478 case NS_UNKNOWN: break;
479 case NS_NOTNULL: break;
480 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
481 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
482 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
483 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
485 case NS_ABSNULL: break;
491 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
495 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
496 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
497 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
498 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
499 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
505 static specCode specCode_fromInt (int i)
508 llassert (i >= SPC_NONE && i < SPC_LAST);
510 return ((specCode) i);
514 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
516 if (uentry_isDeclared (u))
518 return cstring_makeLiteralTemp ("previously declared");
522 return cstring_makeLiteralTemp ("specified");
526 /*@observer@*/ cstring uentry_specDeclName (uentry u)
528 if (uentry_isDeclared (u))
530 return cstring_makeLiteralTemp ("previous declaration");
534 return cstring_makeLiteralTemp ("specification");
538 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
540 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
542 return cstring_makeLiteralTemp ("redefined");
544 else if (uentry_isCodeDefined (unew))
546 return cstring_makeLiteralTemp ("defined");
548 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
550 return cstring_makeLiteralTemp ("redeclared");
554 return cstring_makeLiteralTemp ("declared");
558 static /*@only@*/ fileloc setLocation (void)
560 fileloc fl = context_getSaveLocation ();
562 if (fileloc_isDefined (fl))
568 return fileloc_copy (g_currentloc);
572 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
574 fileloc loc = setLocation ();
575 uentry ue = uentry_makeConstant (n, t, loc);
577 ue->ukind = KENUMCONST;
578 uentry_setDefined (ue, loc);
582 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
584 fileloc loc = setLocation ();
585 uentry ue = uentry_makeConstant (n, t, loc);
586 ctype etype = exprNode_getType (expr);
588 if (!ctype_isRealInt (etype)) {
592 ("Value of enum member is not an integeral type (type %s): %s",
593 ctype_unparse (etype), exprNode_unparse (expr)),
594 exprNode_loc (expr));
597 ue->ukind = KENUMCONST;
598 uentry_setDefined (ue, loc);
603 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
605 uentry ue = uentry_makeConstant (n, t, loc);
607 ue->ukind = KENUMCONST;
612 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
614 return uentry_makeVariable (n, t, setLocation (), FALSE);
618 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
620 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
624 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
626 ctype ct = idDecl_getCtype (id);
627 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
628 MAYBE, MAYBE, setLocation ());
630 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
632 if (!ynm_isOn (ue->info->datatype->abs))
634 if (ctype_isUnknown (ct))
636 ue->info->datatype->mut = MAYBE;
640 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
647 void uentry_checkParams (uentry ue)
649 if (uentry_isValid (ue))
651 bool isExt = uentry_isExtern (ue);
653 if (uentry_isRealFunction (ue))
655 uentryList params = uentry_getParams (ue);
657 uentryList_elements (params, current)
659 if (uentry_isValid (current))
661 ctype ct = current->utype;
663 if (ctype_isFixedArray (ct))
665 if (ctype_isArray (ctype_baseArrayPtr (ct))
666 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
673 (FLG_FIXEDFORMALARRAY,
674 message ("Function parameter %q declared as "
675 "manifest array (size constant is meaningless)",
676 uentry_getName (current)),
677 uentry_whereDeclared (current));
682 if (ctype_isArray (ct))
686 message ("Function parameter %q declared as "
687 "array (treated as pointer)",
688 uentry_getName (current)),
689 uentry_whereDeclared (current));
693 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
695 if (ctype_isAbstract (ct) &&
696 (isExt || (ctype_isAbstract (ctype_realType (ct))
697 && !context_hasFileAccess (ctype_typeId (ct)))))
702 ("Function %q declared with notnull parameter %q of abstract "
705 uentry_getName (current),
708 ("Since %s is an abstract type, notnull can only be "
709 "used for parameters if the function is static to a "
710 "module where %s is accessible.",
713 uentry_whereDeclared (current));
717 } end_uentryList_elements;
719 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
721 ctype ct = ue->utype;
723 if (ctype_isAbstract (ct)
724 && (isExt || (ctype_isAbstract (ctype_realType (ct))
725 && !context_hasFileAccess (ctype_typeId (ct)))))
730 ("%s %q declared %s notnull storage of abstract type %s",
731 ekind_capName (uentry_getKind (ue)),
736 ("Since %s is an abstract type, notnull can only be used "
737 "if it is static to a module where %s is accessible.",
740 uentry_whereDeclared (ue));
747 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
749 alkind ak = sRef_getAliasKind (ue->sref);
751 if (alkind_isRefCounted (ak))
753 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
757 if (alkind_isUnknown (ak))
759 exkind ek = sRef_getExKind (ue->sref);
761 if (exkind_isKnown (ek))
763 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
767 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
769 if (ctype_isVisiblySharable
770 (ctype_realType (ctype_returnValue (ue->utype))))
772 if (uentryList_hasReturned (uentry_getParams (ue)))
778 sRef_setAliasKind (ue->sref, AK_IMPONLY,
788 static /*@notnull@*/ uentry
789 uentry_makeFunctionAux (cstring n, ctype t,
791 /*@only@*/ globSet globs,
792 /*@only@*/ sRefSet mods,
793 /*@keep@*/ fileloc f, bool priv,
794 /*@unused@*/ bool isForward)
796 uentry e = uentry_alloc ();
799 if (ctype_isFunction (t))
801 ret = ctype_returnValue (t);
805 if (ctype_isKnown (t))
807 llbug (message ("not function: %s", ctype_unparse (t)));
814 if (fileloc_isSpec (f) || fileloc_isImport (f))
816 e->whereSpecified = f;
817 e->whereDeclared = fileloc_undefined;
821 e->whereSpecified = fileloc_undefined;
822 e->whereDeclared = f;
825 /* e->shallowCopy = FALSE; */
826 e->uname = cstring_copy (n);
828 e->storageclass = SCNONE;
830 e->sref = sRef_makeType (ret);
832 if (ctype_isUA (ret))
834 sRef_setStateFromType (e->sref, ret);
839 e->uses = filelocList_new ();
841 e->hasNameError = FALSE;
843 e->info = (uinfo) dmalloc (sizeof (*e->info));
844 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
846 e->info->fcn->hasMods = sRefSet_isDefined (mods);
847 e->info->fcn->hasGlobs = globSet_isDefined (globs);
849 e->info->fcn->exitCode = XK_UNKNOWN;
850 e->info->fcn->nullPred = QU_UNKNOWN;
851 e->info->fcn->specialCode = SPC_NONE;
853 e->info->fcn->access = access;
854 e->info->fcn->globs = globs;
855 e->info->fcn->defparams = uentryList_undefined;
857 sRef_setDefined (e->sref, f);
858 e->whereDefined = fileloc_undefined;
860 e->info->fcn->mods = sRefSet_undefined;
861 e->info->fcn->specclauses = NULL;
862 checkGlobalsModifies (e, mods);
863 e->info->fcn->mods = mods;
868 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
871 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
872 typeId_invalid, globSet_undefined,
876 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
877 reflectImplicitFunctionQualifiers (ue, FALSE);
879 if (!uentry_isStatic (ue)
880 && cstring_equalLit (ue->uname, "main"))
882 ctype typ = ue->utype;
886 llassert (ctype_isFunction (typ));
888 retval = ctype_returnValue (typ);
890 if (!ctype_isInt (retval))
894 message ("Function main declared to return %s, should return int",
895 ctype_unparse (retval)),
896 uentry_whereDeclared (ue));
899 args = ctype_argsFunction (typ);
901 if (uentryList_isMissingParams (args)
902 || uentryList_size (args) == 0)
908 if (uentryList_size (args) != 2)
912 message ("Function main declared with %d arg%p, "
913 "should have 2 (int argc, char *argv[])",
914 uentryList_size (args)),
915 uentry_whereLast (ue));
919 uentry arg = uentryList_getN (args, 0);
920 ctype ct = uentry_getType (arg);
922 if (!ctype_isInt (ct))
926 message ("Parameter 1, %q, of function main declared "
927 "with type %t, should have type int",
928 uentry_getName (arg), ct),
929 uentry_whereDeclared (arg));
932 arg = uentryList_getN (args, 1);
933 ct = uentry_getType (arg);
935 if (ctype_isArrayPtr (ct)
936 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
937 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
945 message ("Parameter 2, %q, of function main declared "
946 "with type %t, should have type char **",
947 uentry_getName (arg), ct),
948 uentry_whereDeclared (arg));
957 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
959 alkind ak = sRef_getAliasKind (e->sref);
961 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
962 && context_getFlag (FLG_PARAMIMPTEMP))
964 exkind ek = sRef_getExKind (e->sref);
966 if (exkind_isKnown (ek))
968 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
969 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
973 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
974 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
979 static /*@only@*/ /*@notnull@*/ uentry
980 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
982 cstring pname = makeParam (n);
983 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
985 cstring_free (pname);
986 uentry_implicitParamAnnots (e);
988 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
990 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
991 e->info->var->defstate = defstate;
999 uentry_setRefCounted (uentry e)
1001 if (uentry_isValid (e))
1003 uentry_setAliasKind (e, AK_REFCOUNTED);
1004 sRef_storeState (e->sref);
1010 uentry_setStatic (uentry c)
1012 if (uentry_isValid (c))
1014 alkind ak = sRef_getAliasKind (c->sref);
1015 c->storageclass = SCSTATIC;
1017 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1019 if (!alkind_isUnknown (ak)
1020 && !alkind_isStatic (ak))
1022 if (!(ctype_isRealPointer (uentry_getType (c)))
1023 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1024 && !alkind_isRefCounted (ak))
1026 if (alkind_isImplicit (ak)
1027 && alkind_isDependent (ak)
1028 && ctype_isArray (uentry_getType (c)))
1030 ; /* no error for observer arrays */
1036 message ("Static storage %q declared as %s",
1038 alkind_unparse (ak)),
1039 uentry_whereDeclared (c));
1045 if (alkind_isUnknown (ak)
1046 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1047 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1049 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1050 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1058 uentry_setExtern (uentry c)
1060 if (uentry_isValid (c))
1061 c->storageclass = SCEXTERN;
1065 uentry_setParamNo (uentry ue, int pno)
1067 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1068 sRef_setParamNo (ue->sref, pno);
1072 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1074 sRefSet_allElements (sr, el)
1076 sRef base = sRef_getRootBase (el);
1078 if (sRef_isGlobal (base) || sRef_isInternalState (base)
1079 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1081 if (!globSet_member (ue->info->fcn->globs, base))
1083 if (uentry_hasGlobs (ue)
1084 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1087 (FLG_WARNMISSINGGLOBALS,
1089 ("Modifies list for %q uses global %q, "
1090 "not included in globals list.",
1091 uentry_getName (ue),
1092 sRef_unparse (base)),
1093 uentry_whereLast (ue)))
1095 uentry_showWhereSpecified (ue);
1099 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1101 if (sRef_isFileStatic (base))
1103 context_recordFileGlobals (ue->info->fcn->globs);
1107 } end_sRefSet_allElements;
1111 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
1113 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1117 uentry_fixupSref (uentry ue)
1121 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1126 sr = uentry_getSref (ue);
1128 sRef_resetState (sr);
1129 sRef_clearDerived (sr);
1131 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1132 llassert (sRef_isValid (sr));
1134 if (uentry_isVariable (ue))
1136 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1137 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1141 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
1143 llassert (uentry_isFunction (ue));
1144 llassert (ue->info->fcn->specclauses == NULL);
1146 ue->info->fcn->specclauses = clauses;
1147 specialClauses_checkAll (ue);
1151 ** Used for @modifies@ @endmodifies@ syntax.
1153 ** If ue is specified, sr must contain *only*:
1155 ** o file static globals
1156 ** o sRef's derived from modifies spec (i.e., more specific than
1157 ** what was specified)
1159 ** Otherwise, if sr has modifies it must match sr.
1161 ** If it doesn't have modifies, set them to sr.
1165 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1167 if (sRef_modInFunction ())
1170 (message ("Modifies list not in function context. "
1171 "A modifies list can only appear following the parameter list "
1172 "in a function declaration or header."));
1174 /*@-mustfree@*/ return; /*@=mustfree@*/
1177 if (sRefSet_hasStatic (sr))
1179 context_recordFileModifies (sr);
1182 if (uentry_isValid (ue))
1184 if (uentry_isIter (ue))
1186 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1187 ue->info->iter->mods = sr;
1191 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1193 uentry_makeVarFunction (ue);
1196 llassertfatal (uentry_isFunction (ue));
1197 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1199 ue->info->fcn->mods = sr;
1200 ue->info->fcn->hasMods = TRUE;
1202 checkGlobalsModifies (ue, sr);
1205 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1207 ue->info->fcn->hasGlobs = TRUE;
1217 ** requires: new and old are functions
1221 checkGlobalsConformance (/*@notnull@*/ uentry old,
1222 /*@notnull@*/ uentry unew,
1223 bool mustConform, bool completeConform)
1225 bool hasInternalState = FALSE;
1227 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1229 if (globSet_isDefined (unew->info->fcn->globs))
1231 globSet_allElements (unew->info->fcn->globs, el)
1233 if (sRef_isFileStatic (el))
1235 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1237 if (sRef_isInvalid (sr))
1239 bool hasError = FALSE;
1241 if (!hasInternalState
1242 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1243 sRef_makeInternalState ()))
1244 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1245 sRef_makeSpecState ())))
1248 && !uentry_isStatic (old)
1251 message ("Globals list for %q includes internal state, %q, "
1252 "but %s without globals internalState.",
1253 uentry_getName (old),
1255 uentry_specOrDefName (old)),
1256 uentry_whereLast (unew)))
1258 uentry_showWhereSpecified (old);
1262 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1263 sRef_makeInternalState ());
1264 hasInternalState = TRUE;
1268 && fileloc_sameFile (uentry_whereDeclared (unew),
1269 uentry_whereDeclared (old)))
1274 message ("Function %q inconsistently %rdeclared (in "
1275 "same file) with file static global %q in "
1277 uentry_getName (unew),
1278 uentry_isDeclared (old),
1280 uentry_whereDeclared (unew)))
1282 uentry_showWhereSpecified (old);
1287 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1288 context_recordFileGlobals (old->info->fcn->globs);
1292 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1294 if (sRef_isInvalid (sr))
1299 message ("Function %q inconsistently %rdeclared with "
1300 "%q in globals list",
1301 uentry_getName (unew),
1302 uentry_isDeclared (old),
1304 uentry_whereDeclared (unew)))
1306 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1307 uentry_showWhereSpecified (old);
1312 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1318 ("Function %q global %q inconsistently "
1319 "%rdeclared as %qout global",
1320 uentry_getName (unew),
1322 uentry_isDeclared (old),
1323 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1324 uentry_whereDeclared (unew)))
1326 uentry_showWhereSpecified (old);
1331 } end_globSet_allElements ;
1333 if (completeConform)
1335 globSet_allElements (old->info->fcn->globs, el)
1337 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1339 if (sRef_isInvalid (sr))
1342 && uentry_isReallySpecified (old)
1345 message ("Function %q specified with %q in globals list, "
1346 "but declared without %q",
1347 uentry_getName (unew),
1350 uentry_whereDeclared (unew)))
1352 uentry_showWhereSpecified (old);
1355 } end_globSet_allElements;
1360 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1362 if (uentry_isReallySpecified (old)
1365 message ("%s %q specified with globals list, but "
1366 "declared with no globals",
1367 ekind_capName (unew->ukind),
1368 uentry_getName (unew)),
1369 uentry_whereDeclared (unew)))
1372 (message ("Specification globals: %q",
1373 globSet_unparse (old->info->fcn->globs)),
1374 uentry_whereSpecified (old));
1378 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
1379 old->info->fcn->globs);
1384 ** new modifies list must be included by old modifies list.
1386 ** file static state may be added to new, if old has internal.
1390 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1391 bool mustConform, bool completeConform)
1394 bool changedMods = FALSE;
1395 bool modInternal = FALSE;
1397 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1399 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1400 newMods = unew->info->fcn->mods;
1402 if (sRefSet_isEmpty (newMods))
1404 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1405 && uentry_isReallySpecified (old))
1409 message ("%s %q specified with modifies clause, "
1410 "but declared with no modifies clause",
1411 ekind_capName (unew->ukind),
1412 uentry_getName (unew)),
1413 uentry_whereDeclared (unew)))
1415 llgenindentmsg (message ("Specification has modifies %q",
1416 sRefSet_unparse (old->info->fcn->mods)),
1417 uentry_whereSpecified (old));
1424 sRefSet_allElements (newMods, current)
1426 if (sRef_isValid (current))
1428 sRef rb = sRef_getRootBase (current);
1430 if (sRef_isFileStatic (rb))
1434 if (!sRefSet_isSameMember (old->info->fcn->mods,
1435 sRef_makeInternalState ())
1436 && !sRefSet_isSameMember (old->info->fcn->mods,
1437 sRef_makeSpecState ()))
1440 && !uentry_isStatic (old)
1444 ("Modifies list for %q includes internal state, "
1445 "but %s without modifies internal.",
1446 uentry_getName (old),
1447 uentry_specOrDefName (old)),
1448 uentry_whereLast (unew)))
1450 uentry_showWhereSpecified (old);
1453 old->info->fcn->mods =
1454 sRefSet_insert (old->info->fcn->mods,
1455 sRef_makeInternalState ());
1460 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1466 if (sRef_canModifyVal (current, old->info->fcn->mods))
1468 int size = sRefSet_size (old->info->fcn->mods);
1470 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1473 if (sRefSet_size (old->info->fcn->mods) != size)
1484 ("Modifies list for %q contains %q, not modifiable "
1486 uentry_getName (old),
1487 sRef_unparse (current),
1488 uentry_specDeclName (old)),
1489 uentry_whereLast (unew)))
1491 uentry_showWhereSpecified (old);
1496 } end_sRefSet_allElements;
1498 if (completeConform && uentry_isReallySpecified (old))
1500 sRefSet_allElements (old->info->fcn->mods, el)
1502 if (sRef_canModify (el, newMods))
1511 ("Specification modifies clause for %q contains %q, "
1512 "not included in declaration modifies clause",
1513 uentry_getName (old),
1515 uentry_whereLast (unew)))
1517 uentry_showWhereSpecified (old);
1520 } end_sRefSet_allElements ;
1524 ** Make sure file static elements will be removed.
1529 context_recordFileModifies (old->info->fcn->mods);
1534 uentry_checkMutableType (uentry ue)
1536 ctype ct = uentry_getType (ue);
1538 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1540 voptgenerror (FLG_MUTREP,
1541 message ("Mutable abstract type %q declared without pointer "
1542 "indirection: %t (violates assignment semantics)",
1543 uentry_getName (ue), ct),
1544 uentry_whereDeclared (ue));
1549 uentry_setMutable (uentry e)
1551 llassert (uentry_isDatatype (e));
1552 e->info->datatype->mut = YES;
1556 uentry_checkIterArgs (uentry ue)
1558 bool hasYield = FALSE;
1561 llassert (uentry_isIter (ue));
1563 args = uentry_getParams (ue);
1565 uentryList_elements (args, el)
1567 sstate ds = uentry_getDefState (el);
1569 if (uentry_isYield (el))
1574 if (sstate_isUnknown (ds))
1576 uentry_setDefState (el, SS_DEFINED);
1582 } end_uentryList_elements;
1586 voptgenerror (FLG_HASYIELD,
1587 message ("Iterator %q declared with no yield parameters",
1588 uentry_getName (ue)),
1589 uentry_whereDeclared (ue));
1594 chkind_fromQual (qual qel)
1596 if (qual_isChecked (qel))
1600 else if (qual_isCheckMod (qel))
1604 else if (qual_isCheckedStrict (qel))
1606 return CH_CHECKEDSTRICT;
1608 else if (qual_isUnchecked (qel))
1610 return CH_UNCHECKED;
1615 /*@notreached@*/ return CH_UNKNOWN;
1620 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
1622 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
1624 if (!uentry_isRefCounted (ue))
1628 message ("Reference counting qualifier %s used on non-reference "
1629 "counted storage: %q",
1631 uentry_unparse (ue)));
1635 alkind ak = alkind_fromQual (qel);
1637 uentry_setAliasKind (ue, ak);
1640 else if (qual_isRefCounted (qel))
1642 ctype ct = ctype_realType (uentry_getType (ue));
1645 if (ctype_isPointer (ct)
1646 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
1648 /* check there is a refs field */
1649 uentryList fields = ctype_getFields (rt);
1650 uentry refs = uentry_undefined;
1652 uentryList_elements (fields, field)
1654 if (uentry_isRefsField (field))
1656 if (uentry_isValid (refs))
1660 message ("Reference counted structure type %s has "
1661 "multiple refs fields: %q and %q",
1663 uentry_getName (refs),
1664 uentry_getName (field)));
1669 } end_uentryList_elements;
1671 if (uentry_isInvalid (refs))
1675 message ("Reference counted structure type %s has "
1677 ctype_unparse (ct)),
1679 ("To count reference, the structure must have a field named "
1680 "refs of type int."),
1683 else if (!ctype_isInt (uentry_getType (refs)))
1687 message ("Reference counted structure type %s refs field has "
1688 "type %s (should be int)", ctype_unparse (ct),
1689 ctype_unparse (uentry_getType (refs))));
1693 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1694 uentry_whereDeclared (ue));
1699 if ((ctype_isPointer (ct)
1700 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
1701 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
1703 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1704 uentry_whereDeclared (ue));
1710 message ("Non-pointer to structure type %s declared with "
1711 "refcounted qualifier",
1712 ctype_unparse (ct)));
1716 else if (qual_isRefs (qel))
1718 if (uentry_isVariable (ue) && !uentry_isParam (ue))
1720 uentry_setAliasKind (ue, AK_REFS);
1726 message ("Refs qualifier used on non-structure field: %q",
1727 uentry_unparse (ue)));
1730 else if (qual_isAliasQual (qel))
1732 alkind ak = alkind_fromQual (qel);
1734 alkind oldak = uentry_getAliasKind (ue);
1735 ctype ut = uentry_getType (ue);
1737 if (alkind_isImplicit (ak)
1738 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
1740 /* ignore the implied qualifier */
1744 if (uentry_isEitherConstant (ue))
1748 message ("Alias qualifier %s used on constant: %q",
1749 alkind_unparse (ak), uentry_unparse (ue)));
1753 if (ctype_isFunction (ut))
1755 ut = ctype_returnValue (ut);
1758 if (!(ctype_isVisiblySharable (ut)
1759 || ctype_isRealArray (ut)
1760 || ctype_isRealSU (ut)))
1762 if (!qual_isImplied (qel))
1766 message ("Alias qualifier %s used on unsharable storage type %t: %q",
1767 alkind_unparse (ak), ut, uentry_getName (ue)));
1774 if (uentry_isRefCounted (ue))
1776 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
1777 || qual_isExposed (qel)
1778 || qual_isObserver (qel)))
1780 if (!qual_isImplied (qel))
1785 ("Alias qualifier %s used on reference counted storage: %q",
1786 alkind_unparse (ak),
1787 uentry_unparse (ue)));
1795 if (qual_isRefQual (qel))
1799 message ("Qualifier %s used on non-reference counted storage: %q",
1800 alkind_unparse (ak), uentry_unparse (ue)));
1809 uentry_setAliasKind (ue, ak);
1812 else if (qual_isNull (qel))
1814 if (uentry_isConstant (ue))
1818 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
1819 uentry_whereDeclared (ue));
1823 uentry_setNullState (ue, NS_POSNULL);
1826 else if (qual_isRelNull (qel))
1828 uentry_setNullState (ue, NS_RELNULL);
1830 else if (qual_isNotNull (qel))
1832 uentry_setNullState (ue, NS_MNOTNULL);
1834 else if (qual_isAbstract (qel)
1835 || qual_isConcrete (qel))
1837 if (!uentry_isDatatype (ue))
1841 message ("Qualifier %s used with non-datatype",
1842 qual_unparse (qel)));
1846 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
1849 else if (qual_isMutable (qel))
1851 if (!uentry_isDatatype (ue))
1853 llerror (FLG_SYNTAX,
1854 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
1858 if (!ynm_isOn (ue->info->datatype->mut))
1860 uentry_checkMutableType (ue);
1863 ue->info->datatype->mut = YES;
1866 else if (qual_isImmutable (qel))
1868 if (!uentry_isDatatype (ue))
1870 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
1871 qual_unparse (qel)));
1875 ue->info->datatype->mut = NO;
1878 else if (qual_isNullPred (qel))
1880 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1882 uentry_makeVarFunction (ue);
1885 if (uentry_isFunction (ue))
1887 ctype typ = uentry_getType (ue);
1888 ctype rtype = ctype_returnValue (uentry_getType (ue));
1890 if (ctype_isRealBool (rtype))
1892 uentryList pl = ctype_argsFunction (typ);
1894 if (uentryList_size (pl) == 1)
1896 ue->info->fcn->nullPred = qel;
1900 llerror (FLG_SYNTAX,
1901 message ("Qualifier %s used with function having %d "
1902 "arguments (should have 1)",
1904 uentryList_size (pl)));
1909 llerror (FLG_SYNTAX,
1910 message ("Qualifier %s used with function returning %s "
1911 "(should return bool)",
1913 ctype_unparse (rtype)));
1918 llerror (FLG_SYNTAX,
1919 message ("Qualifier %s used with non-function",
1920 qual_unparse (qel)));
1923 else if (qual_isExitQual (qel))
1925 exitkind exk = exitkind_fromQual (qel);
1927 if (uentry_isFunction (ue))
1929 if (exitkind_isKnown (ue->info->fcn->exitCode))
1931 llerror (FLG_SYNTAX,
1932 message ("Multiple exit qualifiers used on function %q: %s, %s",
1933 uentry_getName (ue),
1934 exitkind_unparse (ue->info->fcn->exitCode),
1935 exitkind_unparse (exk)));
1938 ue->info->fcn->exitCode = exk;
1942 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1944 uentry_makeVarFunction (ue);
1945 ue->info->fcn->exitCode = exk;
1949 llerror (FLG_SYNTAX,
1950 message ("Exit qualifier %s used with non-function (type %s)",
1952 ctype_unparse (uentry_getType (ue))));
1958 if (qual_isCQual (qel))
1964 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
1970 uentry_reflectQualifiers (uentry ue, qualList q)
1972 llassert (uentry_isValid (ue));
1974 qualList_elements (q, qel)
1976 if (qual_isStatic (qel))
1978 uentry_setStatic (ue);
1980 else if (qual_isUnused (qel))
1982 uentry_setUsed (ue, fileloc_undefined);
1984 else if (qual_isExternal (qel))
1986 fileloc_free (ue->whereDefined);
1987 ue->whereDefined = fileloc_createExternal ();
1989 else if (qual_isSef (qel))
1991 if (uentry_isVariable (ue))
1993 vkind vk = ue->info->var->kind;
1995 llassert (vk != VKREFPARAM);
1997 if (vk == VKYIELDPARAM)
2001 message ("Qualifier sef cannot be used with %s: %q",
2002 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2003 uentry_unparse (ue)));
2005 else if (vk == VKRETPARAM)
2007 ue->info->var->kind = VKSEFRETPARAM;
2011 ue->info->var->kind = VKSEFPARAM;
2018 message ("Qualifier sef is meaningful only on parameters: %q",
2019 uentry_unparse (ue)));
2022 else if (qual_isExtern (qel))
2024 ue->storageclass = SCEXTERN;
2026 else if (qual_isGlobalQual (qel)) /* undef, killed */
2028 if (uentry_isVariable (ue))
2030 sstate oldstate = ue->info->var->defstate;
2031 sstate defstate = sstate_fromQual (qel);
2034 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2035 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2037 defstate = SS_UNDEFKILLED;
2044 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2045 ue->info->var->defstate = defstate;
2051 message ("Qualifier %s used on non-variable: %q",
2052 qual_unparse (qel), uentry_unparse (ue)));
2055 /* start modifications */
2057 else if( qual_isBufQualifier(qel) ) {
2058 ctype ct = ctype_realType(uentry_getType(ue));
2060 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2062 if( uentry_hasBufStateInfo(ue) ) {
2064 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2066 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2067 /* If formal func param */
2068 uentry_setNullTerminatedState(ue);
2069 uentry_setLen (ue, 1);
2070 uentry_setSize (ue, 1);
2072 sRef_setNullTerminatedState(uentry_getSref(ue));
2073 sRef_setLen (uentry_getSref(ue), 1);
2074 sRef_setSize (uentry_getSref(ue), 1);
2076 uentry_setPossiblyNullTerminatedState(ue);
2078 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2082 /* put other BufState Qualifiers here */
2084 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2085 struct for identifier %s\n", uentry_getName(ue) ) );
2087 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2089 sRef retSref = uentry_getSref (ue);
2090 ctype retType = sRef_getType (retSref);
2092 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2093 sRef_setNullTerminatedState (retSref);
2099 message ("Qualifier %s used on non-pointer on \
2100 function return: %q", qual_unparse (qel),
2101 uentry_unparse (ue)));
2108 message ("Qualifier %s used on non-pointer: %q",
2109 qual_unparse (qel), uentry_unparse (ue)));
2112 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2114 ctype realType = ctype_realType (ue->utype);
2115 sstate defstate = sstate_fromQual (qel);
2117 if (ctype_isFunction (realType))
2119 realType = ctype_realType (ctype_returnValue (realType));
2122 if (qual_isRelDef (qel))
2124 ; /* okay anywhere */
2128 if (!ctype_isAP (realType)
2129 && !ctype_isSU (realType)
2130 && !ctype_isUnknown (realType)
2131 && !ctype_isAbstract (ue->utype))
2135 message ("Qualifier %s used on non-pointer or struct: %q",
2136 qual_unparse (qel), uentry_unparse (ue)));
2140 uentry_setDefState (ue, defstate);
2142 if (sRef_isStateSpecial (ue->sref)
2143 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2145 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2148 else if (qual_isYield (qel))
2150 if (uentry_isVariable (ue))
2152 ue->info->var->kind = VKYIELDPARAM;
2158 message ("Qualifier %s used on non-iterator parameter: %q",
2159 qual_unparse (qel), uentry_unparse (ue)));
2162 else if (qual_isExQual (qel))
2164 exkind ek = exkind_fromQual (qel);
2165 ctype ut = uentry_getType (ue);
2167 if (ctype_isFunction (ut))
2169 ut = ctype_returnValue (ut);
2172 if (!(ctype_isVisiblySharable (ut))
2173 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2174 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2176 if (!qual_isImplied (qel))
2180 message ("Qualifier %s used on unsharable storage type %t: %q",
2181 exkind_unparse (ek), ut, uentry_getName (ue)));
2186 alkind ak = sRef_getAliasKind (ue->sref);
2188 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2190 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2192 if (!alkind_isTemp (ak))
2194 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2197 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2198 || alkind_isOwned (ak))
2206 message ("Exposure qualifier %s used on %s storage (should "
2207 "be dependent): %q",
2209 alkind_unparse (ak),
2210 uentry_unparse (ue)));
2214 else if (qual_isGlobCheck (qel))
2216 if (uentry_isVariable (ue))
2218 chkind ch = chkind_fromQual (qel);
2220 if (ue->info->var->checked != CH_UNKNOWN)
2222 if (ch == ue->info->var->checked)
2224 llerror (FLG_SYNTAX,
2225 message ("Redundant %s qualifier on %q",
2227 uentry_getName (ue)));
2231 llerror (FLG_SYNTAX,
2233 ("Contradictory %s and %s qualifiers on %q",
2235 checkedName (ue->info->var->checked),
2236 uentry_getName (ue)));
2240 ue->info->var->checked = ch;
2246 message ("Qualifier %s used with non-variable",
2247 qual_unparse (qel)));
2250 else if (qual_isReturned (qel))
2252 if (uentry_isVariable (ue))
2254 ue->info->var->kind = VKRETPARAM;
2258 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2259 qual_unparse (qel)));
2264 uentry_reflectOtherQualifier (ue, qel);
2267 sRef_storeState (ue->sref);
2268 } end_qualList_elements;
2274 uentry_isOnly (uentry ue)
2276 return (!uentry_isUndefined (ue)
2277 && uentry_isVariable (ue)
2278 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2282 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2284 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2285 sRef_setOrigAliasKind (ue->sref, ak);
2289 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2291 if (uentry_isVariable (ue))
2293 ue->info->var->nullstate = ns;
2296 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2300 uentry_isUnique (uentry ue)
2302 return (!uentry_isUndefined (ue)
2303 && uentry_isVariable (ue)
2304 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2308 uentry_isFileStatic (uentry ue)
2310 return (uentry_isStatic (ue)
2311 && (!uentry_isVariable (ue)
2312 || sRef_isFileStatic (uentry_getSref (ue))));
2316 uentry_isExported (uentry ue)
2318 if (uentry_isValid (ue))
2320 if (uentry_isVariable (ue))
2322 return (sRef_isRealGlobal (uentry_getSref (ue)));
2326 return !uentry_isStatic (ue);
2334 uentry_isNonLocal (uentry ue)
2336 return (uentry_isValid (ue) && uentry_isVariable (ue)
2337 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
2341 uentry_isGlobal (uentry ue)
2343 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
2344 sRef_isGlobal (ue->sref));
2348 uentry_isPrintfLike (uentry ue)
2350 return (uentry_isFunction (ue)
2351 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2355 uentry_isScanfLike (uentry ue)
2357 return (uentry_isFunction (ue)
2358 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2362 uentry_isMessageLike (uentry ue)
2364 return (uentry_isFunction (ue)
2365 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2368 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2370 uentryList args = uentry_getParams (ue);
2372 if (!uentryList_isMissingParams (args))
2374 uentry last = uentry_undefined;
2376 uentryList_elements (args, current)
2378 if (uentry_isElipsisMarker (current))
2380 if (uentry_isUndefined (last))
2384 message ("Function %q is marked %s, but has no format "
2385 "string argument before elipsis",
2386 uentry_getName (ue),
2387 specCode_unparse (ue->info->fcn->specialCode)),
2388 uentry_whereLast (ue));
2389 ue->info->fcn->specialCode = SPC_NONE;
2393 ctype rt = ctype_realType (uentry_getType (last));
2395 if (!ctype_match (rt, ctype_string))
2399 /* wchar_t * is okay too */
2400 if (ctype_isAP (rt))
2402 ctype base = ctype_baseArrayPtr (rt);
2404 if (ctype_isArbitraryIntegral (base))
2414 message ("Function %q is marked %s, but the argument "
2415 "before the elipsis has type %s (should be char *)",
2416 uentry_getName (ue),
2417 specCode_unparse (ue->info->fcn->specialCode),
2418 ctype_unparse (uentry_getType (last))),
2419 uentry_whereLast (ue));
2421 ue->info->fcn->specialCode = SPC_NONE;
2428 } end_uentryList_elements ;
2432 message ("Function %q is marked %s, but has no elipsis parameter",
2433 uentry_getName (ue),
2434 specCode_unparse (ue->info->fcn->specialCode)),
2435 uentry_whereLast (ue));
2437 ue->info->fcn->specialCode = SPC_NONE;
2442 uentry_setPrintfLike (uentry ue)
2444 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2446 uentry_makeVarFunction (ue);
2449 llassertfatal (uentry_isFunction (ue));
2450 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2451 checkSpecialFunction (ue);
2455 uentry_setScanfLike (uentry ue)
2457 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2459 uentry_makeVarFunction (ue);
2462 llassertfatal (uentry_isFunction (ue));
2463 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2464 checkSpecialFunction (ue);
2468 uentry_setMessageLike (uentry ue)
2470 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2472 uentry_makeVarFunction (ue);
2475 llassertfatal (uentry_isFunction (ue));
2476 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
2477 checkSpecialFunction (ue);
2481 uentry_isSpecialFunction (uentry ue)
2483 return (uentry_isFunction (ue)
2484 && (ue->info->fcn->specialCode != SPC_NONE));
2487 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
2489 ctype ct = idDecl_getCtype (t);
2491 sRef pref = sRef_makeParam (i, ct);
2492 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
2494 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2495 uentry_implicitParamAnnots (ue);
2497 /* Parameter type [][] or [x][] is invalid */
2499 while (ctype_isFixedArray (base)) {
2500 base = ctype_baseArrayPtr (base);
2503 if (ctype_isIncompleteArray (base)) {
2504 base = ctype_baseArrayPtr (base);
2506 if (ctype_isArray (base)) {
2507 (void) optgenerror (FLG_INCOMPLETETYPE,
2508 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
2509 uentry_getName (ue),
2510 ctype_unparse (ct)),
2511 uentry_whereLast (ue));
2518 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
2520 ctype ct = idDecl_getCtype (t);
2522 if (ctype_isFunction (ct))
2524 return (uentry_makeIdFunction (t));
2528 fileloc loc = setLocation ();
2529 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
2531 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2533 if (!uentry_isExtern (ue))
2535 uentry_setDefined (ue, loc);
2543 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
2545 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
2553 /*@only@*/ /*@notnull@*/
2554 uentry uentry_makeConstantAux (cstring n, ctype t,
2555 /*@keep@*/ fileloc f, bool priv,
2556 /*@only@*/ multiVal m)
2558 uentry e = uentry_alloc ();
2561 e->uname = cstring_copy (n);
2563 e->storageclass = SCNONE;
2565 e->sref = sRef_makeConst (t);
2570 e->uses = filelocList_new ();
2571 e->isPrivate = priv;
2572 e->hasNameError = FALSE;
2574 e->info = (uinfo) dmalloc (sizeof (*e->info));
2575 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
2576 e->info->uconst->val = m;
2577 e->info->uconst->access = typeIdSet_undefined;
2579 uentry_setSpecDef (e, f);
2581 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
2583 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
2589 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
2591 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
2594 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
2596 uentry ue = uentry_makeConstant (idDecl_observeId (t),
2597 idDecl_getCtype (t),
2600 llassert (fileloc_isUndefined (ue->whereDeclared));
2601 ue->whereDeclared = setLocation ();
2603 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2612 void uentry_setDefState (uentry ue, sstate defstate)
2614 if (uentry_isValid (ue))
2616 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2618 if (uentry_isVariable (ue))
2620 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
2625 bool uentry_isCheckedUnknown (uentry ue)
2627 return (uentry_isVar (ue)
2628 && (ue->info->var->checked == CH_UNKNOWN));
2631 bool uentry_isCheckMod (uentry ue)
2633 return (uentry_isVar (ue)
2634 && (ue->info->var->checked == CH_CHECKMOD));
2637 bool uentry_isUnchecked (uentry ue)
2639 return (uentry_isVar (ue)
2640 && (ue->info->var->checked == CH_UNCHECKED));
2643 bool uentry_isChecked (uentry ue)
2645 return (uentry_isVar (ue)
2646 && (ue->info->var->checked == CH_CHECKED));
2649 bool uentry_isCheckedModify (uentry ue)
2651 return (uentry_isVar (ue)
2652 && (ue->info->var->checked == CH_CHECKED
2653 || ue->info->var->checked == CH_CHECKMOD
2654 || ue->info->var->checked == CH_CHECKEDSTRICT));
2657 bool uentry_isCheckedStrict (uentry ue)
2659 return (uentry_isVar (ue)
2660 && (ue->info->var->checked == CH_CHECKEDSTRICT));
2663 void uentry_setUnchecked (uentry ue)
2665 llassert (uentry_isVar (ue));
2667 ue->info->var->checked = CH_UNCHECKED;
2670 void uentry_setChecked (uentry ue)
2672 llassert (uentry_isVar (ue));
2674 ue->info->var->checked = CH_CHECKED;
2677 void uentry_setCheckMod (uentry ue)
2679 llassert (uentry_isVar (ue));
2681 ue->info->var->checked = CH_CHECKMOD;
2684 void uentry_setCheckedStrict (uentry ue)
2686 llassert (uentry_isVar (ue));
2688 ue->info->var->checked = CH_CHECKEDSTRICT;
2691 static /*@only@*/ /*@notnull@*/
2692 uentry uentry_makeVariableAux (cstring n, ctype t,
2694 /*@exposed@*/ sRef s,
2695 bool priv, vkind kind)
2697 uentry e = uentry_alloc ();
2700 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
2703 e->uname = cstring_copy (n);
2706 e->storageclass = SCNONE;
2713 e->uses = filelocList_new ();
2714 e->isPrivate = priv;
2715 e->hasNameError = FALSE;
2717 e->info = (uinfo) dmalloc (sizeof (*e->info));
2718 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
2719 e->info->var->kind = kind;
2721 e->info->var->checked = CH_UNKNOWN;
2723 uentry_setSpecDef (e, f);
2725 if (ctype_isFunction (rt))
2727 rt = ctype_returnValue (rt);
2730 if (ctype_isUA (rt))
2732 sRef_setStateFromType (e->sref, rt);
2735 e->info->var->defstate = sRef_getDefState (e->sref);
2736 e->info->var->nullstate = sRef_getNullState (e->sref);
2738 /* start modifications */
2739 /* This function sets the uentry for a pointer or array variable declaration,
2740 it allocates memory and sets the fields. We check if the type of the variable
2741 is a pointer or array and allocate a `bbufinfo' struct accordingly */
2743 if( ctype_isArray (t) || ctype_isPointer(t)) {
2744 e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
2745 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
2746 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
2748 e->info->var->bufinfo = NULL;
2750 /* end modification */
2756 uentry_isYield (uentry ue)
2758 return (uentry_isVariable (ue)
2759 && (ue->info->var->kind == VKYIELDPARAM
2760 || ue->info->var->kind == VKREFYIELDPARAM));
2764 uentry_isRefsField (uentry ue)
2766 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
2769 /*@only@*/ /*@notnull@*/
2770 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
2772 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
2773 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
2780 void uentry_makeVarFunction (uentry ue)
2787 llassert (uentry_isValid (ue));
2788 llassert (!sRef_modInFunction ());
2790 ak = sRef_getOrigAliasKind (ue->sref);
2791 ek = sRef_getOrigExKind (ue->sref);
2793 oldInfo = ue->info->var;
2795 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
2798 ** expanded macro is marked used (until I write a pre-processor)
2801 ue->used |= (oldInfo->kind == VKEXPMACRO);
2804 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
2805 ue->info->fcn->exitCode = XK_UNKNOWN;
2806 ue->info->fcn->nullPred = QU_UNKNOWN;
2807 ue->info->fcn->specialCode = SPC_NONE;
2808 ue->info->fcn->access = typeIdSet_undefined;
2809 ue->info->fcn->hasGlobs = FALSE;
2810 ue->info->fcn->globs = globSet_undefined;
2811 ue->info->fcn->hasMods = FALSE;
2812 ue->info->fcn->mods = sRefSet_undefined;
2813 ue->info->fcn->specclauses = NULL;
2814 ue->info->fcn->defparams = uentryList_undefined;
2816 if (ctype_isFunction (ue->utype))
2818 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
2822 ue->sref = sRef_makeType (ctype_unknown);
2825 if (sRef_isRefCounted (ue->sref))
2831 if (alkind_isUnknown (ak))
2833 if (exkind_isKnown (ek))
2835 ak = AK_IMPDEPENDENT;
2839 if (context_getFlag (FLG_RETIMPONLY))
2841 if (ctype_isFunction (ue->utype)
2842 && ctype_isVisiblySharable
2843 (ctype_realType (ctype_returnValue (ue->utype))))
2845 if (uentryList_hasReturned (uentry_getParams (ue)))
2859 loc = ue->whereDeclared;
2861 sRef_setAliasKind (ue->sref, ak, loc);
2862 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
2863 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
2864 sRef_setExKind (ue->sref, ek, loc);
2866 if (oldInfo->kind == VKEXPMACRO)
2869 ue->whereDeclared = fileloc_undefined;
2873 fileloc_free (ue->whereDefined);
2874 ue->whereDefined = fileloc_undefined;
2877 uvinfo_free (oldInfo);
2881 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
2883 llassert (uentry_isValid (ue));
2885 if (uentry_isIter (ue))
2887 llassert (globSet_isUndefined (ue->info->iter->globs));
2888 ue->info->iter->globs = globs;
2892 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2894 uentry_makeVarFunction (ue);
2897 llassert (uentry_isFunction (ue));
2898 llassert (!ue->info->fcn->hasGlobs
2899 && globSet_isUndefined (ue->info->fcn->globs));
2901 ue->info->fcn->hasGlobs = TRUE;
2902 /*@-mustfree@*/ ue->info->fcn->globs = globs;
2906 if (globSet_hasStatic (globs))
2908 context_recordFileGlobals (globs);
2911 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
2913 ue->info->fcn->hasMods = TRUE;
2917 void uentry_addAccessType (uentry ue, typeId tid)
2919 if (uentry_isFunction (ue))
2921 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
2923 else if (uentry_isEitherConstant (ue))
2925 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
2927 else if (uentry_isIter (ue))
2929 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
2931 else if (uentry_isEndIter (ue))
2933 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
2937 llbug (message ("no access for: %q", uentry_unparse (ue)));
2941 /*@only@*/ /*@notnull@*/ uentry
2942 uentry_makeFunction (cstring n, ctype t,
2944 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
2947 return (uentry_makeFunctionAux (n, t,
2948 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
2949 : typeIdSet_single (access)),
2955 /*@notnull@*/ uentry
2956 uentry_makePrivFunction2 (cstring n, ctype t,
2958 globSet globs, sRefSet mods,
2961 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
2965 /*@notnull@*/ uentry
2966 uentry_makeSpecFunction (cstring n, ctype t,
2968 /*@only@*/ globSet globs,
2969 /*@only@*/ sRefSet mods,
2972 uentry ue = uentry_makeFunctionAux (n, t, access,
2976 uentry_setHasGlobs (ue);
2977 uentry_setHasMods (ue);
2979 reflectImplicitFunctionQualifiers (ue, TRUE);
2984 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
2986 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
2987 sRef_undefined, FALSE, VKEXPMACRO);
2989 uentry_setDefined (ue, f);
2993 /*@notnull@*/ /*@notnull@*/ uentry
2994 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
2996 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
2997 typeIdSet_singleOpt (access),
2998 globSet_undefined, sRefSet_undefined,
3002 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3006 bool uentry_isForward (uentry e)
3008 if (uentry_isValid (e))
3010 ctype ct = uentry_getType (e);
3012 return (ctype_isUnknown (ct)
3013 || (ctype_isFunction (ct)
3014 && ctype_isUnknown (ctype_returnValue (ct))));
3021 /*@notnull@*/ uentry
3022 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3024 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3030 /*@notnull@*/ uentry
3031 uentry_makeUnspecFunction (cstring n, ctype t,
3035 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
3036 sRefSet_new (), f, FALSE, TRUE);
3038 reflectImplicitFunctionQualifiers (ue, TRUE);
3047 /* is exported for use by usymtab_interface */
3049 /*@notnull@*/ uentry
3050 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
3051 fileloc f, bool priv)
3053 uentry e = uentry_alloc ();
3055 /* e->shallowCopy = FALSE; */
3056 e->ukind = KDATATYPE;
3057 e->uname = cstring_copy (n);
3059 e->storageclass = SCNONE;
3060 e->sref = sRef_makeUnknown ();
3064 sRef_setStateFromType (e->sref, t);
3067 uentry_setSpecDef (e, f);
3069 e->uses = filelocList_new ();
3070 e->isPrivate = priv;
3071 e->hasNameError = FALSE;
3076 e->info = (uinfo) dmalloc (sizeof (*e->info));
3077 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3078 e->info->datatype->abs = abs;
3079 e->info->datatype->mut = mut;
3080 e->info->datatype->type = ctype_undefined;
3082 if (uentry_isDeclared (e))
3084 uentry_setDefined (e, f);
3087 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
3089 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3095 /*@notnull@*/ uentry
3096 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
3099 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
3102 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abs)
3104 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3105 ctype_bool, NO, abs,
3106 fileloc_getBuiltin (),
3109 ret->info->datatype->type = ctype_bool;
3117 static /*@only@*/ /*@notnull@*/ uentry
3118 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3119 /*@only@*/ fileloc f)
3121 uentry e = uentry_alloc ();
3124 e->uname = cstring_copy (n);
3126 e->sref = sRef_makeUnknown ();
3127 e->storageclass = SCNONE;
3131 uentry_setSpecDef (e, f);
3133 e->uses = filelocList_new ();
3134 e->isPrivate = FALSE;
3135 e->hasNameError = FALSE;
3137 e->info = (uinfo) dmalloc (sizeof (*e->info));
3138 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3139 e->info->iter->access = access;
3140 e->info->iter->mods = sRefSet_undefined;
3141 e->info->iter->globs = globSet_undefined;
3143 uentry_checkIterArgs (e);
3147 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3149 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3152 static /*@notnull@*/ uentry
3153 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3155 uentry e = uentry_alloc ();
3157 /* e->shallowCopy = FALSE; */
3158 e->ukind = KENDITER;
3159 e->storageclass = SCNONE;
3160 e->uname = message ("end_%s", n);
3161 e->utype = ctype_unknown;
3162 e->sref = sRef_makeUnknown ();
3164 uentry_setSpecDef (e, f);
3169 e->uses = filelocList_new ();
3170 e->isPrivate = FALSE;
3171 e->hasNameError = FALSE;
3173 e->info = (uinfo) dmalloc (sizeof (*e->info));
3174 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3176 e->info->enditer->access = access;
3181 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3183 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3190 static /*@only@*/ /*@notnull@*/ uentry
3191 uentry_makeTagAux (cstring n, ctype t,
3192 /*@only@*/ fileloc fl,
3193 bool priv, ekind kind)
3195 uentry e = uentry_alloc ();
3197 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3199 llbuglit ("uentry_makeTagAux: not a tag type");
3203 /* e->shallowCopy = FALSE; */
3204 e->uname = cstring_copy (n);
3207 e->sref = sRef_makeUnknown ();
3208 e->storageclass = SCNONE;
3210 uentry_setSpecDef (e, fl);
3215 e->uses = filelocList_new ();
3216 e->isPrivate = priv;
3217 e->hasNameError = FALSE;
3219 e->info = (uinfo) dmalloc (sizeof (*e->info));
3220 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3221 e->info->datatype->abs = NO;
3222 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3223 e->info->datatype->type = t;
3225 if (uentry_isDeclared (e))
3227 uentry_setDefined (e, fl);
3233 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3235 cstring sname = makeStruct (n);
3236 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3238 cstring_free (sname);
3243 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3245 cstring sname = makeStruct (n);
3246 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3248 cstring_free (sname);
3253 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3255 cstring uname = makeUnion (n);
3256 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3258 cstring_free (uname);
3264 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3266 cstring ename = makeEnum (n);
3267 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3269 cstring_free (ename);
3275 uentry_makeUnionTagLoc (cstring n, ctype t)
3277 cstring uname = makeUnion (n);
3278 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3280 cstring_free (uname);
3285 uentry_makeEnumTagLoc (cstring n, ctype t)
3287 cstring ename = makeEnum (n);
3288 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3290 cstring_free (ename);
3295 uentry_isStructTag (uentry ue)
3297 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3301 uentry_isUnionTag (uentry ue)
3303 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3307 uentry_isEnumTag (uentry ue)
3309 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3313 uentry_isAnyTag (uentry ue)
3315 return (uentry_isStructTag (ue)
3316 || uentry_isUnionTag (ue)
3317 || uentry_isEnumTag (ue));
3320 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3322 extern void uentry_destroyMod (void)
3323 /*@globals killed emarker@*/ /*@modifies emarker@*/
3325 static bool wasDestroyed = FALSE;
3327 llassert (!wasDestroyed);
3329 if (emarker != NULL)
3331 uentry_reallyFree (emarker);
3334 wasDestroyed = TRUE;
3338 uentry_makeElipsisMarker (void)
3340 if (emarker == NULL)
3342 emarker = uentry_alloc ();
3344 emarker->ukind = KELIPSMARKER;
3345 emarker->uname = cstring_makeLiteral ("...");
3346 emarker->utype = ctype_elipsMarker;
3347 emarker->sref = sRef_undefined;
3348 emarker->storageclass = SCNONE;
3349 emarker->used = FALSE;
3350 emarker->lset = FALSE;
3351 emarker->info = NULL;
3353 uentry_setSpecDef (emarker, fileloc_undefined);
3354 emarker->uses = filelocList_new ();
3355 emarker->isPrivate = FALSE;
3356 emarker->hasNameError = FALSE;
3359 /*@ignore@*/ return (emarker); /*@end@*/
3367 uentry_equiv (uentry p1, uentry p2)
3369 if (uentry_compare (p1, p2) != 0)
3380 uentry_xcomparealpha (uentry *p1, uentry *p2)
3384 if ((res = uentry_compare (*p1, *p2)) == 0) {
3385 if ((*p1 != NULL) && (*p2 != NULL)) {
3386 res = cstring_compare ((*p1)->uname,
3395 uentry_xcompareuses (uentry *p1, uentry *p2)
3400 if (uentry_isValid (u1))
3402 if (uentry_isValid (u2))
3404 return (-1 * int_compare (filelocList_size (u1->uses),
3405 filelocList_size (u2->uses)));
3414 if (uentry_isValid (u2))
3426 uentry_compareStrict (uentry v1, uentry v2)
3428 COMPARERETURN (uentry_compare (v1, v2));
3430 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
3432 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
3433 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
3434 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
3441 uentry_compare (uentry u1, uentry u2)
3443 if (u1 == u2) return 0;
3445 if (uentry_isInvalid (u1)) return -1;
3446 if (uentry_isInvalid (u2)) return 1;
3448 INTCOMPARERETURN (u1->ukind, u2->ukind);
3449 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
3450 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
3452 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
3458 /* bug detected by lclint:
3459 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
3464 return (multiVal_compare (u1->info->uconst->val,
3465 u2->info->uconst->val));
3469 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
3471 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3472 uentry_accessType (u2)));
3473 return (uentryList_compareParams (uentry_getParams (u1),
3474 uentry_getParams (u2)));
3476 return (typeIdSet_compare (uentry_accessType (u1),
3477 uentry_accessType (u2)));
3479 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3480 uentry_accessType (u2)));
3481 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
3482 uentry_getGlobs (u2)));
3483 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
3484 uentry_getParams (u2)));
3485 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
3486 u2->info->fcn->specialCode));
3487 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
3488 u2->info->fcn->nullPred));
3490 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
3492 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
3493 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
3494 sRef_getOrigAliasKind (u2->sref)));
3495 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
3496 sRef_getOrigExKind (u2->sref)));
3497 COMPARERETURN (generic_compare (u1->info->var->checked,
3498 u2->info->var->checked));
3499 COMPARERETURN (generic_compare (u1->info->var->defstate,
3500 u2->info->var->defstate));
3501 return (generic_compare (u1->info->var->nullstate,
3502 u2->info->var->nullstate));
3504 COMPARERETURN (ctype_compare (u1->info->datatype->type,
3505 u2->info->datatype->type));
3506 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
3507 u2->info->datatype->mut));
3508 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
3517 ** all entries are: <type>[@<info>]*#<name>
3519 ** info depends on kind:
3523 advanceField (char **s)
3529 advanceName (char **s)
3535 vkind_fromInt (int i)
3537 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
3539 llbuglit ("vkind_fromInt: out of range");
3546 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
3547 typeIdSet access, nstate nullstate,
3548 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
3550 uentry e = uentry_alloc ();
3555 e->sref = sRef_makeConst (ct);
3557 sRef_setNullState (e->sref, nullstate, loc);
3558 e->storageclass = SCNONE;
3560 if (fileloc_isSpec (loc))
3562 e->whereSpecified = loc;
3563 e->whereDeclared = fileloc_undefined;
3567 e->whereSpecified = fileloc_undefined;
3568 e->whereDeclared = loc;
3571 e->whereDefined = fileloc_undefined;
3572 e->uses = filelocList_new ();
3573 e->isPrivate = FALSE;
3574 e->hasNameError = FALSE;
3579 e->info = (uinfo) dmalloc (sizeof (*e->info));
3580 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3581 e->info->uconst->val = m;
3582 e->info->uconst->access = access;
3584 sRef_storeState (e->sref);
3589 static /*@only@*/ uentry
3590 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
3591 sstate defstate, nstate isnull, alkind aliased,
3592 exkind exp, chkind checked,
3593 /*@only@*/ fileloc loc)
3595 uentry e = uentry_alloc ();
3600 e->storageclass = SCNONE;
3602 e->sref = sRef_makeType (ct);
3603 sRef_setNullState (e->sref, isnull, loc);
3605 e->whereDefined = fileloc_undefined;
3607 if (fileloc_isSpec (loc))
3609 e->whereSpecified = loc;
3610 e->whereDeclared = fileloc_undefined;
3614 e->whereSpecified = fileloc_undefined;
3615 e->whereDeclared = loc;
3618 e->isPrivate = FALSE;
3619 e->hasNameError = FALSE;
3624 e->uses = filelocList_new ();
3626 e->info = (uinfo) dmalloc (sizeof (*e->info));
3627 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3628 e->info->var->kind = kind;
3629 e->info->var->checked = checked;
3630 e->info->var->defstate = defstate;
3632 sRef_setDefState (e->sref, defstate, loc);
3634 e->info->var->nullstate = sRef_getNullState (e->sref);
3636 sRef_setExKind (e->sref, exp, loc);
3637 sRef_setAliasKind (e->sref, aliased, loc);
3639 sRef_storeState (e->sref);
3643 static /*@only@*/ uentry
3644 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abs,
3645 ynm mut, ctype rtype, alkind ak, exkind exp,
3646 sstate defstate, nstate isnull,
3647 /*@only@*/ fileloc loc)
3649 uentry e = uentry_alloc ();
3651 e->ukind = KDATATYPE;
3652 /* e->shallowCopy = FALSE; */
3655 e->storageclass = SCNONE;
3656 e->sref = sRef_makeUnknown ();
3659 ** This is only setting null state. (I think?)
3662 if (ctype_isUA (ct))
3664 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
3666 if (uentry_isValid (te))
3668 sRef_setStateFromUentry (e->sref, te);
3672 /* problem for recursive type definitions */
3676 sRef_setAliasKind (e->sref, ak, loc);
3677 sRef_setExKind (e->sref, exp, loc);
3679 sRef_setDefState (e->sref, defstate, loc);
3681 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
3683 isnull = NS_ABSNULL;
3686 sRef_mergeNullState (e->sref, isnull);
3688 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
3690 if (fileloc_isSpec (loc))
3692 e->whereSpecified = loc;
3693 e->whereDeclared = fileloc_undefined;
3697 e->whereSpecified = fileloc_undefined;
3698 e->whereDeclared = loc;
3701 e->isPrivate = FALSE;
3702 e->hasNameError = FALSE;
3706 e->uses = filelocList_new ();
3708 e->info = (uinfo) dmalloc (sizeof (*e->info));
3709 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3710 e->info->datatype->abs = abs;
3711 e->info->datatype->mut = mut;
3712 e->info->datatype->type = rtype;
3714 sRef_storeState (e->sref);
3720 static void uentry_setHasGlobs (uentry ue)
3722 llassert (uentry_isFunction (ue));
3724 ue->info->fcn->hasGlobs = TRUE;
3727 static void uentry_setHasMods (uentry ue)
3729 llassert (uentry_isFunction (ue));
3731 ue->info->fcn->hasMods = TRUE;
3735 bool uentry_hasGlobs (uentry ue)
3737 if (uentry_isFunction (ue))
3739 return (ue->info->fcn->hasGlobs);
3745 bool uentry_hasSpecialClauses (uentry ue)
3747 return (uentry_isFunction (ue) && (ue->info->fcn->specclauses != NULL));
3750 specialClauses uentry_getSpecialClauses (uentry ue)
3752 llassert (uentry_isFunction (ue));
3753 return ue->info->fcn->specclauses;
3756 bool uentry_hasMods (uentry ue)
3758 if (uentry_isFunction (ue))
3760 return (ue->info->fcn->hasMods);
3767 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
3769 bool hasGlobs, /*@only@*/ globSet globs,
3770 bool hasMods, /*@only@*/ sRefSet mods,
3771 alkind ak, exkind exp,
3772 sstate defstate, nstate isnull,
3776 /*@only@*/ specialClauses specclauses,
3777 /*@only@*/ fileloc loc)
3779 uentry e = uentry_alloc ();
3782 /* e->shallowCopy = FALSE; */
3786 e->storageclass = SCNONE;
3788 if (ctype_isFunction (ct))
3790 ret = ctype_returnValue (ct);
3794 if (ctype_isKnown (ct))
3796 llbug (message ("not function: %s", ctype_unparse (ct)));
3799 ret = ctype_unknown;
3802 e->sref = sRef_makeType (ret);
3804 if (ctype_isUA (ret))
3806 sRef_setStateFromType (e->sref, ret);
3809 sRef_setDefined (e->sref, loc);
3810 sRef_setNullState (e->sref, isnull, loc);
3812 sRef_setAliasKind (e->sref, ak, loc);
3813 sRef_setExKind (e->sref, exp, loc);
3814 sRef_setDefState (e->sref, defstate, loc);
3816 e->whereSpecified = loc;
3817 e->whereDefined = fileloc_undefined;
3819 e->isPrivate = FALSE;
3820 e->hasNameError = FALSE;
3824 e->uses = filelocList_new ();
3826 e->info = (uinfo) dmalloc (sizeof (*e->info));
3827 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
3829 e->info->fcn->exitCode = exitCode;
3830 e->info->fcn->specialCode = sCode;
3831 e->info->fcn->nullPred = nullPred;
3832 e->info->fcn->access = access;
3834 e->info->fcn->specclauses = specclauses;
3835 e->info->fcn->hasGlobs = hasGlobs;
3836 e->info->fcn->globs = globs;
3838 e->info->fcn->hasMods = hasMods;
3839 e->info->fcn->mods = mods;
3841 e->info->fcn->defparams = uentryList_undefined;
3842 e->whereDeclared = fileloc_undefined;
3844 sRef_storeState (e->sref);
3849 static /*@only@*/ uentry
3850 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
3851 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
3853 uentry e = uentry_alloc ();
3855 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
3857 llbuglit ("uentry_makeTagBase: not a tag type");
3860 /* e->shallowCopy = FALSE; */
3864 e->sref = sRef_makeUnknown ();
3865 e->storageclass = SCNONE;
3867 if (fileloc_isSpec (loc))
3869 e->whereSpecified = loc;
3870 e->whereDeclared = fileloc_undefined;
3874 e->whereDeclared = loc;
3875 e->whereSpecified = fileloc_undefined;
3878 e->whereDefined = fileloc_undefined;
3880 e->isPrivate = FALSE;
3881 e->hasNameError = FALSE;
3885 e->uses = filelocList_new ();
3887 e->info = (uinfo) dmalloc (sizeof (*e->info));
3888 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3889 e->info->datatype->abs = NO;
3890 e->info->datatype->mut = MAYBE;
3891 e->info->datatype->type = rtype;
3893 sRef_storeState (e->sref);
3899 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
3900 ctype ct, /*@only@*/ fileloc loc)
3902 uentry e = uentry_alloc ();
3904 /* e->shallowCopy = FALSE; */
3908 e->sref = sRef_makeUnknown ();
3909 e->storageclass = SCNONE;
3911 if (fileloc_isSpec (loc))
3913 e->whereSpecified = loc;
3914 e->whereDeclared = fileloc_undefined;
3918 e->whereDeclared = loc;
3919 e->whereSpecified = fileloc_undefined;
3922 e->whereDefined = fileloc_undefined;
3924 e->isPrivate = FALSE;
3925 e->hasNameError = FALSE;
3929 e->uses = filelocList_new ();
3931 e->info = (uinfo) dmalloc (sizeof (*e->info));
3932 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3933 e->info->iter->access = access;
3934 e->info->iter->mods = sRefSet_undefined;
3935 e->info->iter->globs = globSet_undefined;
3937 sRef_storeState (e->sref);
3942 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
3943 /*@only@*/ fileloc loc)
3945 uentry e = uentry_alloc ();
3947 /* e->shallowCopy = FALSE; */
3948 e->ukind = KENDITER;
3949 e->storageclass = SCNONE;
3951 e->utype = ctype_unknown;
3952 e->sref = sRef_makeUnknown ();
3954 if (fileloc_isSpec (loc))
3956 e->whereSpecified = loc;
3957 e->whereDeclared = fileloc_undefined;
3961 e->whereDeclared = loc;
3962 e->whereSpecified = fileloc_undefined;
3965 e->whereDefined = fileloc_undefined;
3967 e->isPrivate = FALSE;
3968 e->hasNameError = FALSE;
3972 e->uses = filelocList_new ();
3974 e->info = (uinfo) dmalloc (sizeof (*e->info));
3975 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3976 e->info->enditer->access = access;
3977 sRef_storeState (e->sref);
3982 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
3990 uentry_undump (ekind kind, fileloc loc, char **s)
3998 ue = uentry_makeElipsisMarker ();
4002 ctype ct = ctype_undump (s);
4018 if (optCheckChar (s, '@'))
4020 tkind = vkind_fromInt (getInt (s));
4028 if (optCheckChar (s, '$'))
4030 defstate = SS_UNKNOWN;
4031 isnull = NS_UNKNOWN;
4032 aliased = AK_IMPTEMP;
4034 checked = CH_UNKNOWN;
4036 else if (optCheckChar (s, '&'))
4038 defstate = SS_DEFINED;
4039 isnull = NS_UNKNOWN;
4040 aliased = AK_IMPTEMP;
4042 checked = CH_UNKNOWN;
4044 else if (optCheckChar (s, '^'))
4046 defstate = SS_UNKNOWN;
4047 isnull = NS_UNKNOWN;
4048 aliased = AK_IMPTEMP;
4050 checked = CH_UNKNOWN;
4054 defstate = sstate_fromInt (getInt (s));
4055 advanceField (s); isnull = nstate_fromInt (getInt (s));
4056 advanceField (s); aliased = alkind_fromInt (getInt (s));
4058 if (optCheckChar (s, '&'))
4061 checked = CH_UNKNOWN;
4065 advanceField (s); exp = exkind_fromInt (getInt (s));
4066 advanceField (s); checked = (chkind) (getInt (s));
4071 name = getStringWord (s);
4073 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4074 isnull, aliased, exp,
4075 checked, fileloc_copy (loc));
4088 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
4089 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
4090 advanceField (s); defstate = sstate_fromInt (getInt (s));
4091 advanceField (s); isnull = nstate_fromInt (getInt (s));
4092 advanceField (s); aliased = alkind_fromInt (getInt (s));
4093 advanceField (s); exp = exkind_fromInt (getInt (s));
4094 advanceField (s); rtype = ctype_undump (s);
4096 name = getStringWord (s);
4098 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
4099 aliased, exp, defstate, isnull,
4100 fileloc_copy (loc));
4117 specialClauses specclauses;
4119 if (optCheckChar (s, '$'))
4121 defstate = SS_DEFINED;
4122 isnull = NS_UNKNOWN;
4123 exitCode = XK_UNKNOWN;
4125 nullPred = QU_UNKNOWN;
4129 advanceField (s); defstate = sstate_fromInt (getInt (s));
4130 advanceField (s); isnull = nstate_fromInt (getInt (s));
4131 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
4132 advanceField (s); specc = specCode_fromInt (getInt (s));
4133 advanceField (s); nullPred = qual_fromInt (getInt (s));
4136 if (optCheckChar (s, '$'))
4139 globs = globSet_undefined;
4141 mods = sRefSet_undefined;
4143 else if (optCheckChar (s, '^'))
4146 globs = globSet_undefined;
4148 mods = sRefSet_undefined;
4152 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
4153 advanceField (s); globs = globSet_undump (s);
4154 advanceField (s); hasMods = bool_fromInt (getInt (s));
4155 advanceField (s); mods = sRefSet_undump (s);
4158 if (optCheckChar (s, '$'))
4165 advanceField (s); ak = alkind_fromInt (getInt (s));
4166 advanceField (s); exp = exkind_fromInt (getInt (s));
4169 advanceField (s); access = typeIdSet_undump (s);
4171 if (optCheckChar (s, '@'))
4173 specclauses = specialClauses_undump (s);
4177 specclauses = specialClauses_undefined;
4180 advanceName (s); name = getStringWord (s);
4182 ue = uentry_makeFunctionBase (name, ct, access,
4185 ak, exp, defstate, isnull,
4186 exitCode, specc, nullPred,
4188 fileloc_copy (loc));
4189 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4196 advanceField (s); access = typeIdSet_undump (s);
4197 advanceName (s); name = getStringWord (s);
4199 ue = uentry_makeIterBase (name, access, ct,
4200 fileloc_copy (loc));
4207 advanceField (s); access = typeIdSet_undump (s);
4208 advanceName (s); name = getStringWord (s);
4210 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4220 if (optCheckChar (s, '$'))
4222 val = multiVal_undefined;
4223 access = typeIdSet_undefined;
4224 nullstate = NS_UNKNOWN;
4228 advanceField (s); val = multiVal_undump (s);
4229 advanceField (s); access = typeIdSet_undump (s);
4230 advanceField (s); nullstate = nstate_fromInt (getInt (s));
4233 advanceName (s); name = getStringWord (s);
4235 ue = uentry_makeConstantBase (name, ct, access,
4236 nullstate, fileloc_copy (loc), val);
4245 advanceField (s); rtype = ctype_undump (s);
4246 advanceName (s); name = getStringWord (s);
4247 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4251 llcontbuglit ("uentry_undump: invalid");
4252 ue = uentry_undefined;
4255 llcontbuglit ("uentry_undump: elips marker");
4256 ue = uentry_undefined;
4265 uentry_dump (uentry v)
4267 return (uentry_dumpAux (v, FALSE));
4271 uentry_dumpParam (uentry v)
4273 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4274 ("dump: %s", uentry_unparseFull (v)));
4276 return (uentry_dumpAux (v, TRUE));
4280 uentry_dumpAux (uentry v, bool isParam)
4282 llassert (uentry_isValid (v));
4287 llcontbuglit ("uentry_dump: invalid entry");
4288 return cstring_undefined;
4290 return (message ("!."));
4294 vkind vk = v->info->var->kind;
4295 sstate dss = sRef_getDefState (v->sref);
4296 nstate nst = sRef_getNullState (v->sref);
4297 alkind alk = sRef_getAliasKind (v->sref);
4298 exkind exk = sRef_getExKind (v->sref);
4299 chkind chk = v->info->var->checked;
4301 if (dss == SS_UNKNOWN
4302 && nst == NS_UNKNOWN
4303 && alk == AK_IMPTEMP
4304 && exk == XO_UNKNOWN
4305 && chk == CH_UNKNOWN)
4307 sdump = cstring_makeLiteral ("$");
4309 else if (dss == SS_DEFINED
4310 && nst == NS_UNKNOWN
4311 && alk == AK_IMPTEMP
4312 && exk == XO_UNKNOWN
4313 && chk == CH_UNKNOWN)
4315 sdump = cstring_makeLiteral ("&");
4317 else if (dss == SS_UNKNOWN
4318 && nst == NS_UNKNOWN
4319 && alk == AK_UNKNOWN
4320 && exk == XO_UNKNOWN
4321 && chk == CH_UNKNOWN)
4323 sdump = cstring_makeLiteral ("^");
4325 else if (exk == XO_UNKNOWN
4326 && chk == CH_UNKNOWN)
4328 sdump = message ("%d@%d@%d&",
4335 sdump = message ("%d@%d@%d@%d@%d",
4346 return (message ("%q|@%d|%q#%s",
4347 ctype_dump (v->utype),
4350 isParam ? cstring_undefined : v->uname));
4354 return (message ("%q|%q#%s",
4355 ctype_dump (v->utype),
4357 isParam ? cstring_undefined : v->uname));
4362 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
4363 ctype_dump (v->utype),
4364 ynm_unparseCode (v->info->datatype->abs),
4365 ynm_unparseCode (v->info->datatype->mut),
4366 (int) sRef_getDefState (v->sref),
4367 (int) sRef_getNullState (v->sref),
4368 (int) sRef_getAliasKind (v->sref),
4369 (int) sRef_getExKind (v->sref),
4370 ctype_dump (v->info->datatype->type),
4374 cstring sdump, gdump, adump;
4375 alkind alk = sRef_getAliasKind (v->sref);
4376 exkind exk = sRef_getExKind (v->sref);
4378 if (sRef_getDefState (v->sref) == SS_DEFINED
4379 && !nstate_isKnown (sRef_getNullState (v->sref))
4380 && !exitkind_isKnown (v->info->fcn->exitCode)
4381 && v->info->fcn->specialCode == SPC_NONE
4382 && v->info->fcn->nullPred == QU_UNKNOWN)
4384 sdump = cstring_makeLiteral ("$");
4388 sdump = message ("@%d@%d@%d@%d@%d",
4389 (int) sRef_getDefState (v->sref),
4390 (int) sRef_getNullState (v->sref),
4391 (int) v->info->fcn->exitCode,
4392 (int) v->info->fcn->specialCode,
4393 (int) v->info->fcn->nullPred);
4396 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
4398 gdump = cstring_makeLiteral ("$");
4400 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
4401 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
4403 gdump = cstring_makeLiteral ("^");
4407 gdump = message ("@%s@%q@%s@%q",
4408 bool_dump (uentry_hasGlobs (v)),
4409 globSet_dump (uentry_getGlobs (v)),
4410 bool_dump (uentry_hasMods (v)),
4411 sRefSet_dump (uentry_getMods (v)));
4414 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
4416 adump = cstring_makeLiteral ("$");
4420 adump = message ("@%d@%d", (int) alk, (int) exk);
4423 if (uentry_hasSpecialClauses (v))
4425 return (message ("%q%q%q%q@%q@%q#%s",
4426 ctype_dump (v->utype),
4430 typeIdSet_dump (uentry_accessType (v)),
4431 specialClauses_dump (v->info->fcn->specclauses),
4436 return (message ("%q%q%q%q@%q#%s",
4437 ctype_dump (v->utype),
4441 typeIdSet_dump (uentry_accessType (v)),
4446 return (message ("%q@%q#%s",
4447 ctype_dump (v->utype),
4448 typeIdSet_dump (v->info->iter->access),
4451 return (message ("%q@%q#%s",
4452 ctype_dump (v->utype),
4453 typeIdSet_dump (uentry_accessType (v)),
4460 if (multiVal_isUnknown (v->info->uconst->val)
4461 && typeIdSet_isEmpty (uentry_accessType (v))
4462 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
4464 sdump = cstring_makeLiteral ("$");
4468 sdump = message ("@%q@%q@%d",
4469 multiVal_dump (v->info->uconst->val),
4470 typeIdSet_dump (uentry_accessType (v)),
4471 (int) sRef_getNullState (v->sref));
4474 return (message ("%q%q#%s",
4475 ctype_dump (v->utype),
4482 return (message ("%q@%q#%s",
4483 ctype_dump (v->utype),
4484 ctype_dump (v->info->datatype->type), v->uname));
4491 uentry_unparseAbbrev (uentry v)
4493 if (!uentry_isVariable (v))
4495 llcontbuglit ("uentry_unparseAbbrev: not variable");
4496 return uentry_unparse (v);
4499 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
4503 uentry_unparse (uentry v)
4507 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
4508 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
4510 st = uentry_getName (v);
4512 if (cstring_isDefined (st))
4514 return (ctype_unparseDeclaration (v->utype, st));
4519 return (cstring_copy (ctype_unparse (v->utype)));
4524 uentry_unparseFull (uentry v)
4526 if (uentry_isUndefined (v))
4528 return (cstring_makeLiteral ("<undefined>"));
4530 else if (uentry_isDatatype (v))
4532 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
4534 ekind_unparse (v->ukind),
4538 ctype_isDefined (v->info->datatype->type)
4539 ? v->info->datatype->type : ctype_unknown,
4540 ynm_unparse (v->info->datatype->mut),
4541 ynm_unparse (v->info->datatype->abs),
4542 sRef_unparseState (v->sref),
4543 fileloc_unparse (v->whereSpecified),
4544 fileloc_unparse (v->whereDefined)));
4546 else if (uentry_isFunction (v))
4548 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
4549 "globs: %q / [s: %q; decl: %q; def: %q]",
4551 ekind_unparse (v->ukind),
4554 sRef_unparseFull (v->sref),
4555 sRefSet_unparse (v->info->fcn->mods),
4556 globSet_unparse (v->info->fcn->globs),
4557 fileloc_unparse (v->whereSpecified),
4558 fileloc_unparse (v->whereDeclared),
4559 fileloc_unparse (v->whereDefined)));
4561 else if (uentry_isIter (v))
4563 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
4564 ekind_unparse (v->ukind),
4567 sRef_unparseFull (v->sref),
4568 fileloc_unparse (v->whereSpecified),
4569 fileloc_unparse (v->whereDefined)));
4571 else if (uentry_isVariable (v))
4574 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
4575 "kind <%d> isout <%d> used <%d>",
4576 checkedName (v->info->var->checked),
4578 ekind_unparse (v->ukind),
4581 sRef_unparseDeep (v->sref),
4582 fileloc_unparse (v->whereSpecified),
4583 fileloc_unparse (v->whereDefined),
4584 fileloc_unparse (v->whereDeclared),
4585 (int) v->info->var->kind,
4586 (int) v->info->var->defstate,
4591 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
4592 ekind_unparse (v->ukind),
4595 sRef_unparseFull (v->sref),
4596 fileloc_unparse (v->whereSpecified),
4597 fileloc_unparse (v->whereDefined)));
4602 bool uentry_hasAccessType (uentry e)
4604 if (uentry_isValid (e))
4609 return (!typeIdSet_isEmpty (e->info->iter->access));
4611 return (!typeIdSet_isEmpty (e->info->enditer->access));
4613 return (!typeIdSet_isEmpty (e->info->fcn->access));
4616 return (!typeIdSet_isEmpty (e->info->uconst->access));
4625 typeIdSet uentry_accessType (uentry e)
4627 if (uentry_isValid (e))
4632 return (e->info->iter->access);
4634 return (e->info->enditer->access);
4636 return (e->info->fcn->access);
4639 return (e->info->uconst->access);
4645 return typeIdSet_undefined;
4649 uentry_isVariable (uentry e)
4651 return (uentry_isVar (e));
4655 uentry_isSpecified (uentry e)
4657 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
4661 uentry_isReallySpecified (uentry e)
4663 return (uentry_isValid (e)
4664 && fileloc_isRealSpec (e->whereSpecified));
4668 uentry_isVar (uentry e)
4670 return (!uentry_isUndefined (e) && e->ukind == KVAR);
4674 uentry_isFakeTag (uentry e)
4676 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
4680 uentry_isDatatype (uentry e)
4682 return (!uentry_isUndefined (e) &&
4683 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
4684 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
4688 uentry_setAbstract (uentry e)
4692 llassert (uentry_isDatatype (e)
4693 && (ynm_isMaybe (e->info->datatype->abs)));
4695 oldid = ctype_typeId (e->info->datatype->type);
4696 e->info->datatype->abs = YES;
4697 e->info->datatype->type = ctype_createAbstract (oldid);
4701 uentry_setConcrete (uentry e)
4703 llassert (uentry_isDatatype (e)
4704 && (ynm_isMaybe (e->info->datatype->abs)));
4706 e->info->datatype->abs = NO;
4710 uentry_isAbstractDatatype (uentry e)
4712 return (uentry_isDatatype (e)
4713 && (ynm_isOn (e->info->datatype->abs)));
4717 uentry_isMaybeAbstract (uentry e)
4719 return (uentry_isDatatype (e)
4720 && (ynm_isMaybe (e->info->datatype->abs)));
4724 uentry_isMutableDatatype (uentry e)
4726 bool res = uentry_isDatatype (e)
4727 && (ynm_toBoolRelaxed (e->info->datatype->mut));
4733 uentry_isRefCountedDatatype (uentry e)
4735 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
4739 uentry_isParam (uentry u)
4741 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
4742 || u->info->var->kind == VKYIELDPARAM));
4746 uentry_isExpandedMacro (uentry u)
4748 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
4752 uentry_isSefParam (uentry u)
4754 return (uentry_isVariable (u)
4755 && (u->info->var->kind == VKSEFPARAM
4756 || u->info->var->kind == VKREFSEFPARAM
4757 || u->info->var->kind == VKSEFRETPARAM
4758 || u->info->var->kind == VKREFSEFRETPARAM));
4762 uentry_isRefParam (uentry u)
4764 return (uentry_isVariable (u)
4765 && (u->info->var->kind == VKREFPARAM
4766 || u->info->var->kind == VKREFYIELDPARAM
4767 || u->info->var->kind == VKREFSEFPARAM
4768 || u->info->var->kind == VKREFSEFRETPARAM));
4772 uentry_isAnyParam (uentry u)
4774 return (uentry_isVariable (u)
4775 && ((u->info->var->kind == VKPARAM)
4776 || (u->info->var->kind == VKSEFPARAM)
4777 || (u->info->var->kind == VKYIELDPARAM)
4778 || (u->info->var->kind == VKRETPARAM)
4779 || (u->info->var->kind == VKSEFRETPARAM)));
4783 uentry_getDefState (uentry u)
4785 if (uentry_isValid (u))
4787 return (sRef_getDefState (u->sref));
4791 return (SS_UNKNOWN);
4796 uentry_isOut (uentry u)
4798 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
4799 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4803 uentry_isPartial (uentry u)
4805 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
4806 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4810 uentry_isStateSpecial (uentry u)
4812 return ((uentry_isVariable (u)
4813 && (u->info->var->defstate == SS_SPECIAL))
4814 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
4817 exitkind uentry_getExitCode (uentry ue)
4819 if (uentry_isFunction (ue))
4821 return ue->info->fcn->exitCode;
4830 uentry_nullPred (uentry u)
4832 llassert (uentry_isRealFunction (u));
4834 if (uentry_isFunction (u))
4836 return (u->info->fcn->nullPred);
4845 uentry_possiblyNull (uentry u)
4847 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
4848 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
4852 uentry_getAliasKind (uentry u)
4854 if (uentry_isValid (u))
4856 return (sRef_getAliasKind (uentry_getSref (u)));
4865 uentry_getExpKind (uentry u)
4867 if (uentry_isValid (u))
4869 return (sRef_getExKind (uentry_getSref (u)));
4878 uentry_isIter (uentry e)
4880 return (!uentry_isUndefined (e) && e->ukind == KITER);
4884 uentry_isEndIter (uentry e)
4886 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
4890 uentry_isRealFunction (uentry e)
4892 return (uentry_isFunction (e) ||
4893 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
4897 uentry_hasName (uentry e)
4899 if (uentry_isValid (e))
4901 cstring s = e->uname;
4903 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
4911 bool uentry_hasRealName (uentry e)
4913 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
4917 /*@observer@*/ globSet
4918 uentry_getGlobs (uentry l)
4920 if (uentry_isInvalid (l))
4922 return globSet_undefined;
4925 if (l->ukind != KFCN)
4927 if (l->ukind != KITER && l->ukind != KENDITER)
4929 if (l->ukind == KVAR)
4931 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
4933 ekind_unparse (l->ukind)));
4937 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
4939 ekind_unparse (l->ukind)));
4942 return globSet_undefined;
4945 return l->info->fcn->globs;
4948 /*@observer@*/ sRefSet
4949 uentry_getMods (uentry l)
4951 llassert (uentry_isValid (l));
4953 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
4955 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
4956 return sRefSet_undefined;
4959 return l->info->fcn->mods;
4963 uentry_getKind (uentry e)
4965 llassert (uentry_isValid (e));
4970 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
4972 llassert (uentry_isEitherConstant (e));
4974 return (e->info->uconst->val);
4977 /*@observer@*/ uentryList
4978 uentry_getParams (uentry l)
4980 if (uentry_isInvalid (l)) return uentryList_undefined;
4987 ctype ct = l->utype;
4989 if (ctype_isFunction (ct))
4991 return (ctype_argsFunction (ct));
4995 return uentryList_undefined;
5000 ctype ct = l->utype;
5002 llassert (ctype_isFunction (ct));
5003 return (ctype_argsFunction (ct));
5010 /*@observer@*/ cstring
5011 uentry_rawName (uentry e)
5013 if (uentry_isValid (e))
5019 return cstring_undefined;
5024 uentry_getOptName (uentry e)
5026 cstring s = uentry_getName (e);
5028 if (cstring_isDefined (s))
5030 s = cstring_appendChar (s, ' ');
5037 uentry_getName (uentry e)
5039 cstring ret = cstring_undefined;
5041 if (uentry_isValid (e))
5044 if (uentry_isAnyTag (e))
5046 ret = fixTagName (e->uname);
5048 else if (uentry_isAnyParam (e))
5050 ret = cstring_copy (fixParamName (e->uname));
5054 ret = cstring_copy (e->uname);
5061 cstring uentry_getRealName (uentry e)
5063 if (uentry_isValid (e))
5065 if (uentry_isAnyTag (e))
5067 return (cstring_undefined);
5074 return cstring_undefined;
5077 ctype uentry_getType (uentry e)
5079 if (uentry_isValid (e))
5085 return ctype_unknown;
5089 fileloc uentry_whereLast (uentry e)
5093 if (uentry_isInvalid (e))
5095 return fileloc_undefined;
5098 loc = e->whereDefined;
5100 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5105 loc = uentry_whereDeclared (e);
5107 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5112 loc = uentry_whereSpecified (e);
5116 fileloc uentry_whereEither (uentry e)
5118 if (uentry_isInvalid (e)) return fileloc_undefined;
5120 if (fileloc_isDefined (e->whereDefined)
5121 && !fileloc_isExternal (e->whereDefined))
5123 return e->whereDefined;
5125 else if (fileloc_isDefined (e->whereDeclared))
5127 return e->whereDeclared;
5131 return e->whereSpecified;
5135 fileloc uentry_whereSpecified (uentry e)
5137 if (uentry_isInvalid (e)) return fileloc_undefined;
5139 return (e->whereSpecified);
5142 fileloc uentry_whereDefined (uentry e)
5144 if (uentry_isInvalid (e)) return fileloc_undefined;
5146 return (e->whereDefined);
5149 fileloc uentry_whereDeclared (uentry e)
5151 if (uentry_isInvalid (e)) return fileloc_undefined;
5153 return (e->whereDeclared);
5156 /*@observer@*/ fileloc
5157 uentry_whereEarliest (uentry e)
5159 if (uentry_isInvalid (e)) return fileloc_undefined;
5161 if (fileloc_isDefined (e->whereSpecified))
5163 return (e->whereSpecified);
5165 else if (fileloc_isDefined (e->whereDeclared))
5167 return (e->whereDeclared);
5171 return e->whereDefined;
5176 uentry_setFunctionDefined (uentry e, fileloc loc)
5178 if (uentry_isValid (e))
5180 llassert (uentry_isFunction (e));
5182 if (fileloc_isUndefined (e->whereDeclared))
5184 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5187 if (!fileloc_isDefined (e->whereDefined))
5189 e->whereDefined = fileloc_update (e->whereDefined, loc);
5195 uentry_setDeclDef (uentry e, fileloc f)
5197 uentry_setDeclared (e, f);
5199 if (!uentry_isFunction (e)
5200 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5202 uentry_setDefined (e, f);
5207 uentry_setDeclaredForce (uentry e, fileloc f)
5209 llassert (uentry_isValid (e));
5210 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5214 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5216 llassert (uentry_isValid (e));
5217 fileloc_free (e->whereDeclared);
5218 e->whereDeclared = f;
5222 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5226 llassert (uentry_isValid (e));
5227 oldloc = e->whereDeclared;
5229 if (fileloc_isDefined (oldloc))
5231 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5233 e->whereDeclared = f;
5234 fileloc_free (oldloc);
5243 e->whereDeclared = f;
5244 fileloc_free (oldloc);
5249 uentry_setDeclared (uentry e, fileloc f)
5253 llassert (uentry_isValid (e));
5254 oldloc = e->whereDeclared;
5256 if (fileloc_isDefined (oldloc))
5258 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5260 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5269 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5274 uentry_clearDefined (uentry e)
5276 if (uentry_isValid (e))
5278 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5283 uentry_setDefined (uentry e, fileloc f)
5287 llassert (uentry_isValid (e));
5288 oldloc = e->whereDefined;
5290 if (fileloc_isDefined (oldloc))
5292 if (fileloc_isLib (oldloc)
5293 || fileloc_isImport (oldloc)
5294 || fileloc_isBuiltin (oldloc)
5295 || fileloc_isPreproc (oldloc))
5297 e->whereDefined = fileloc_update (e->whereDefined, f);
5301 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5307 if (optgenerror (FLG_REDEF,
5308 message ("%s %q redefined",
5309 ekind_capName (e->ukind),
5310 uentry_getName (e)),
5313 llgenindentmsg (message ("Previous definition of %q",
5314 uentry_getName (e)),
5322 e->whereDefined = fileloc_update (e->whereDefined, f);
5327 uentry_isCodeDefined (uentry e)
5329 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
5333 uentry_isDeclared (uentry e)
5335 if (uentry_isValid (e))
5337 return (fileloc_isDefined (e->whereDeclared));
5343 sRef uentry_getSref (uentry e)
5345 /* not true, used for functions too (but shouldn't be? */
5346 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
5348 if (uentry_isInvalid (e)) return sRef_undefined;
5353 sRef uentry_getOrigSref (uentry e)
5355 if (uentry_isValid (e))
5357 sRef sr = sRef_copy (uentry_getSref (e));
5359 sRef_resetState (sr);
5360 sRef_clearDerived (sr);
5362 if (uentry_isVariable (e))
5364 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
5365 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
5372 return sRef_undefined;
5377 ** requires: uentry e is not in a hashed symbol table
5381 uentry_setName (uentry e, /*@only@*/ cstring n)
5383 llassert (uentry_isValid (e));
5385 cstring_free (e->uname);
5390 uentry_setType (uentry e, ctype t)
5392 if (uentry_isValid (e))
5395 sRef_setType (e->sref, t);
5400 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
5403 ctype rettype = ctype_unknown;
5405 llassert (uentry_isValid (ue));
5407 rct = ctype_realType (ue->utype);
5409 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
5411 uentry_makeVarFunction (ue);
5414 llassert (uentry_isFunction (ue));
5416 if (ctype_isFunction (rct))
5418 rettype = ctype_returnValue (rct);
5421 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
5425 uentry_setRefParam (uentry e)
5428 if (!uentry_isVar (e))
5430 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5434 if (e->info->var->kind == VKSEFPARAM)
5436 e->info->var->kind = VKREFSEFPARAM;
5438 else if (e->info->var->kind == VKSEFRETPARAM)
5440 e->info->var->kind = VKREFSEFRETPARAM;
5442 else if (e->info->var->kind == VKYIELDPARAM)
5444 e->info->var->kind = VKREFYIELDPARAM;
5448 e->info->var->kind = VKREFPARAM;
5454 uentry_setParam (uentry e)
5456 if (!uentry_isVar (e))
5458 if (uentry_isElipsisMarker (e))
5464 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5471 if (e->info->var->kind == VKYIELDPARAM
5472 || e->info->var->kind == VKSEFPARAM
5473 || e->info->var->kind == VKSEFRETPARAM)
5479 e->info->var->kind = VKPARAM;
5483 e->uname = makeParam (e->uname);
5484 cstring_free (oldname);
5489 uentry_setSref (uentry e, sRef s)
5491 if (uentry_isValid (e))
5493 if (sRef_isValid (e->sref))
5495 sRef_mergeStateQuietReverse (e->sref, s);
5499 e->sref = sRef_saveCopy (s);
5505 uentry_getAbstractType (uentry e)
5507 llassert (uentry_isDatatype (e));
5510 ** This assertion removed.
5511 ** Okay to have undefined type, for system types
5513 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
5514 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
5519 if (ctype_isUndefined (e->info->datatype->type))
5521 return ctype_unknown;
5524 return e->info->datatype->type;
5527 ctype uentry_getRealType (uentry e)
5530 typeId uid = USYMIDINVALID;
5532 if (uentry_isInvalid (e))
5534 return ctype_unknown;
5537 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5539 if (uentry_isAnyTag (e))
5544 if (uentry_isAbstractType (e))
5546 ct = uentry_getAbstractType (e);
5547 llassert (ctype_isUA (ct));
5549 uid = ctype_typeId (ct);
5551 if (!context_hasAccess (uid))
5557 ct = uentry_getType (e);
5559 if (ctype_isUserBool (ct)) return ct;
5561 if (ctype_isUA (ct))
5563 usymId iid = ctype_typeId (ct);
5565 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5567 llcontbug (message ("uentry_getRealType: recursive type! %s",
5568 ctype_unparse (ct)));
5573 return uentry_getRealType (usymtab_getTypeEntry (iid));
5582 ctype uentry_getForceRealType (uentry e)
5585 typeId uid = USYMIDINVALID;
5587 if (uentry_isInvalid (e))
5589 return ctype_unknown;
5592 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5594 if (uentry_isAnyTag (e))
5599 if (uentry_isAbstractType (e))
5601 ct = uentry_getAbstractType (e);
5602 llassert (ctype_isUA (ct));
5604 uid = ctype_typeId (ct);
5605 /* no check for access! */
5608 ct = uentry_getType (e);
5610 if (ctype_isUserBool (ct)) return ct;
5612 if (ctype_isUA (ct))
5614 usymId iid = ctype_typeId (ct);
5616 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5618 llcontbug (message ("uentry_getRealType: recursive type! %s",
5619 ctype_unparse (ct)));
5624 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
5633 uentry uentry_nameCopy (cstring name, uentry e)
5635 uentry enew = uentry_alloc ();
5637 llassert (uentry_isValid (e));
5639 /* enew->shallowCopy = FALSE; */
5640 enew->ukind = e->ukind;
5642 enew->utype = e->utype;
5643 enew->whereSpecified = fileloc_copy (e->whereSpecified);
5644 enew->whereDefined = fileloc_copy (e->whereDefined);
5645 enew->whereDeclared = fileloc_copy (e->whereDeclared);
5646 enew->sref = sRef_copy (e->sref);
5647 enew->used = e->used;
5649 enew->isPrivate = e->isPrivate;
5650 enew->hasNameError = FALSE;
5652 enew->uses = filelocList_new ();
5654 enew->storageclass = e->storageclass;
5655 enew->info = uinfo_copy (e->info, e->ukind);
5661 uentry_setDatatype (uentry e, usymId uid)
5663 llassert (uentry_isDatatype (e));
5665 if (uentry_isAbstractType (e))
5667 e->info->datatype->type = ctype_createAbstract (uid);
5671 e->info->datatype->type = ctype_createUser (uid);
5676 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
5677 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
5680 llassert (uentry_isValid (e));
5682 if (fileloc_isSpec (f) || fileloc_isImport (f))
5684 e->whereSpecified = f;
5685 e->whereDeclared = fileloc_undefined;
5686 e->whereDefined = fileloc_undefined;
5690 e->whereSpecified = fileloc_undefined;
5691 e->whereDeclared = f;
5692 e->whereDefined = fileloc_undefined;
5697 ucinfo_free (/*@only@*/ ucinfo u)
5699 multiVal_free (u->val);
5704 uvinfo_free (/*@only@*/ uvinfo u)
5710 udinfo_free (/*@only@*/ udinfo u)
5716 ufinfo_free (/*@only@*/ ufinfo u)
5718 globSet_free (u->globs);
5719 sRefSet_free (u->mods);
5720 specialClauses_free (u->specclauses);
5726 uiinfo_free (/*@only@*/ uiinfo u)
5732 ueinfo_free (/*@only@*/ ueinfo u)
5737 static /*@only@*/ ucinfo
5738 ucinfo_copy (ucinfo u)
5740 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
5742 ret->val = multiVal_copy (u->val);
5743 ret->access = u->access;
5748 static /*@only@*/ uvinfo
5749 uvinfo_copy (uvinfo u)
5751 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
5753 ret->kind = u->kind;
5754 ret->nullstate = u->nullstate;
5755 ret->defstate = u->defstate;
5756 ret->checked = u->checked;
5761 static /*@only@*/ udinfo
5762 udinfo_copy (udinfo u)
5764 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
5768 ret->type = u->type;
5773 static /*@only@*/ ufinfo
5774 ufinfo_copy (ufinfo u)
5776 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
5778 ret->hasGlobs = u->hasGlobs;
5779 ret->hasMods = u->hasMods;
5780 ret->exitCode = u->exitCode;
5781 ret->specialCode = u->specialCode;
5782 ret->nullPred = u->nullPred;
5783 ret->access = u->access;
5784 ret->globs = globSet_newCopy (u->globs);
5785 ret->mods = sRefSet_newCopy (u->mods);
5786 ret->defparams = u->defparams;
5787 ret->specclauses = specialClauses_copy (u->specclauses);
5792 static /*@only@*/ uiinfo
5793 uiinfo_copy (uiinfo u)
5795 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
5797 ret->access = u->access;
5798 ret->globs = globSet_newCopy (u->globs);
5799 ret->mods = sRefSet_newCopy (u->mods);
5804 static /*@only@*/ ueinfo
5805 ueinfo_copy (ueinfo u)
5807 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
5809 ret->access = u->access;
5814 uinfo_free (uinfo u, ekind kind)
5819 case KCONST: ucinfo_free (u->uconst); break;
5820 case KVAR: uvinfo_free (u->var); break;
5824 case KDATATYPE: udinfo_free (u->datatype); break;
5825 case KFCN: ufinfo_free (u->fcn); break;
5826 case KITER: uiinfo_free (u->iter); break;
5827 case KENDITER: ueinfo_free (u->enditer); break;
5828 case KELIPSMARKER: break;
5829 case KINVALID: break;
5835 static /*@only@*/ /*@null@*/ uinfo
5836 uinfo_copy (uinfo u, ekind kind)
5838 if (kind == KELIPSMARKER || kind == KINVALID)
5844 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
5849 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
5850 case KVAR: ret->var = uvinfo_copy (u->var); break;
5854 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
5855 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
5856 case KITER: ret->iter = uiinfo_copy (u->iter); break;
5857 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
5865 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
5867 filelocList_free (e->uses);
5868 cstring_free (e->uname);
5870 uinfo_free (e->info, e->ukind);
5872 fileloc_free (e->whereSpecified);
5873 fileloc_free (e->whereDefined);
5874 fileloc_free (e->whereDeclared);
5880 extern void uentry_markOwned (/*@owned@*/ uentry u)
5882 sfreeEventually (u);
5886 uentry_free (/*@only@*/ uentry e)
5888 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
5890 uentry_reallyFree (e);
5895 ** For uentry's in the global or file scope
5899 uentry_freeComplete (/*@only@*/ uentry e)
5901 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
5903 /*@i@*/ sRef_free (e->sref);
5904 e->sref = sRef_undefined;
5905 uentry_reallyFree (e);
5910 ** requires old->kind != new->kind, old->uname = new->uname
5914 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
5916 llassert (uentry_isValid (old));
5917 llassert (uentry_isValid (unew));
5919 if (uentry_isEitherConstant (unew)
5920 && (fileloc_isPreproc (uentry_whereDeclared (old))
5921 || ctype_isUnknown (old->utype))
5922 && !uentry_isSpecified (old))
5930 if (!uentry_isDeclared (old))
5932 if (uentry_isSpecified (old))
5934 if (uentry_isSpecified (unew))
5936 llbuglit ("Respecification!");
5938 else if (uentry_isDeclared (unew))
5942 message ("%s %q inconsistently declared as %s: %t",
5943 ekind_capName (old->ukind),
5944 uentry_getName (unew),
5945 ekind_unparseLong (unew->ukind),
5947 uentry_whereDeclared (unew)))
5949 uentry_showWhereLast (old);
5961 message ("%s %q inconsistently declared as %s: %t",
5962 ekind_capName (old->ukind),
5963 uentry_getName (unew),
5964 ekind_unparseLong (unew->ukind),
5966 uentry_whereDeclared (unew)))
5968 uentry_showWhereLast (old);
5974 llassert (uentry_isDeclared (unew));
5978 message ("%s %q inconsistently redeclared as %s",
5979 ekind_capName (old->ukind),
5980 uentry_getName (unew),
5981 ekind_unparseLong (unew->ukind)),
5982 uentry_whereDeclared (unew)))
5984 uentry_showWhereLast (old);
5990 uentry_copyInto (old, unew);
5994 ** def is the definition of spec, modifies spec
5996 ** reports any inconsistencies
5997 ** returns the summary of all available information
5998 ** if spec and def are inconsistent, def is returned
6002 uentry_showWhereLast (uentry spec)
6004 if (uentry_isValid (spec))
6006 if (fileloc_isDefined (spec->whereDefined)
6007 && !fileloc_isLib (spec->whereDefined)
6008 && !fileloc_isPreproc (spec->whereDefined))
6010 llgenindentmsg (message ("Previous definition of %q: %t",
6011 uentry_getName (spec),
6012 uentry_getType (spec)),
6013 uentry_whereDefined (spec));
6015 else if (uentry_isDeclared (spec))
6017 llgenindentmsg (message ("Previous declaration of %q: %t",
6018 uentry_getName (spec),
6019 uentry_getType (spec)),
6020 uentry_whereDeclared (spec));
6022 else if (uentry_isSpecified (spec))
6024 if (uentry_hasName (spec))
6026 llgenindentmsg (message ("Specification of %q: %t",
6027 uentry_getName (spec),
6028 uentry_getType (spec)),
6029 uentry_whereSpecified (spec));
6033 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6034 uentry_whereSpecified (spec));
6039 /* nothing to show */
6045 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6047 fileloc loc = uentry_whereDefined (ce);
6049 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6051 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6055 loc = uentry_whereSpecified (ce);
6057 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6059 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6064 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6066 if (uentry_isDeclared (spec))
6068 llgenindentmsg (message ("Previous declaration of %q: %q",
6069 uentry_getName (spec), extra),
6070 uentry_whereDeclared (spec));
6072 else if (uentry_isSpecified (spec))
6074 llgenindentmsg (message ("Specification of %q: %q",
6075 uentry_getName (spec), extra),
6076 uentry_whereSpecified (spec));
6080 cstring_free (extra);
6085 uentry_showWhereDeclared (uentry spec)
6087 if (uentry_isDeclared (spec))
6089 if (uentry_hasName (spec))
6091 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6092 uentry_whereDeclared (spec));
6096 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6099 else if (uentry_isSpecified (spec))
6101 if (uentry_hasName (spec))
6103 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6104 uentry_whereSpecified (spec));
6108 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6113 /* nothing to show */
6119 uentry_showWhereAny (uentry spec)
6121 if (uentry_isDeclared (spec))
6123 if (uentry_hasName (spec))
6125 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6126 uentry_whereDeclared (spec));
6130 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6133 else if (uentry_isSpecified (spec))
6135 if (uentry_hasName (spec))
6137 llgenindentmsg (message ("Specification of %q",
6138 uentry_getName (spec)),
6139 uentry_whereSpecified (spec));
6143 llgenindentmsg (cstring_makeLiteral ("Specification"),
6144 uentry_whereSpecified (spec));
6147 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6149 if (uentry_hasName (spec))
6151 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6152 uentry_whereDefined (spec));
6156 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6161 /* nothing to show */
6166 uentry_showWhereDefined (uentry spec)
6168 if (uentry_isCodeDefined (spec))
6170 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6171 uentry_whereDefined (spec));
6176 uentry_showWhereLastPlain (uentry spec)
6178 if (uentry_isDeclared (spec))
6180 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6181 uentry_whereDeclared (spec));
6183 else if (uentry_isSpecified (spec))
6185 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6186 uentry_whereSpecified (spec));
6194 uentry_showWhereLastVal (uentry spec, cstring val)
6196 if (uentry_isDeclared (spec))
6198 llgenindentmsg (message ("Previous declaration of %q: %s",
6199 uentry_getName (spec), val),
6200 uentry_whereDeclared (spec));
6202 else if (uentry_isSpecified (spec))
6204 llgenindentmsg (message ("Specification of %q: %s",
6205 uentry_getName (spec), val),
6206 uentry_whereSpecified (spec));
6214 uentry_showWhereSpecified (uentry spec)
6216 if (uentry_isSpecified (spec))
6218 if (uentry_hasName (spec))
6220 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6221 uentry_whereSpecified (spec));
6225 llgenindentmsg (cstring_makeLiteral ("Specification"),
6226 uentry_whereSpecified (spec));
6229 else if (uentry_isDeclared (spec))
6231 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6232 uentry_whereDeclared (spec));
6236 /* nothing to show */
6241 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6243 if (uentry_isSpecified (spec))
6245 if (uentry_hasName (spec))
6247 llgenindentmsg (message ("Specification of %q: %q",
6248 uentry_getName (spec), s),
6249 uentry_whereSpecified (spec));
6253 llgenindentmsg (message ("Specification: %q", s),
6254 uentry_whereSpecified (spec));
6257 else if (uentry_isDeclared (spec))
6259 llgenindentmsg (message ("Declaration of %q: %q",
6260 uentry_getName (spec), s),
6261 uentry_whereDeclared (spec));
6265 llgenindentmsg (message ("Previous: %q", s),
6266 uentry_whereLast (spec));
6275 checkStructConformance (uentry old, uentry unew)
6278 uentryList fold, fnew;
6281 ** requires: types of old and new are structs or unions
6284 llassert (uentry_isValid (old));
6285 llassert (uentry_isValid (unew));
6287 oldr = ctype_realType (old->utype);
6288 fold = ctype_getFields (oldr);
6290 newr = ctype_realType (unew->utype);
6291 fnew = ctype_getFields (newr);
6293 if (!uentryList_matchFields (fold, fnew))
6295 if (fileloc_equal (uentry_whereLast (old),
6296 uentry_whereLast (unew)))
6304 message ("%q %q %rdeclared with fields { %q }, %s "
6305 "with fields { %q }",
6306 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
6307 uentry_getName (old),
6308 uentry_isDeclared (old),
6309 uentryList_unparseAbbrev (fnew),
6310 uentry_specOrDefName (old),
6311 uentryList_unparseAbbrev (fold)),
6312 uentry_whereDeclared (unew)))
6314 uentry_showWhereLastPlain (old);
6315 uentryList_showFieldDifference (fold, fnew);
6319 old->utype = unew->utype;
6324 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6327 ** requires old and new are enums
6330 ctype rold = ctype_realType (old->utype);
6331 ctype rnew = ctype_realType (unew->utype);
6332 enumNameList eold = ctype_elist (rold);
6333 enumNameList enew = ctype_elist (rnew);
6335 if (!enumNameList_match (eold, enew))
6339 message ("Enum %q declared with members { %q } but "
6340 "specified with members { %q }",
6341 uentry_getName (old),
6342 enumNameList_unparse (enew),
6343 enumNameList_unparse (eold)),
6344 uentry_whereDeclared (unew)))
6346 uentry_showWhereSpecified (old);
6347 old->utype = unew->utype;
6353 ** either oldCurrent or newCurrent may be undefined!
6357 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
6358 uentry unew, uentry newCurrent, ctype newType,
6361 bool hasError = FALSE;
6363 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
6365 if (uentry_hasName (newCurrent))
6367 hasError = optgenerror
6369 message ("Parameter %d, %q, of function %q has inconsistent type: "
6370 "declared %t, %s %t",
6371 paramno + 1, uentry_getName (newCurrent),
6372 uentry_getName (unew),
6373 newType, uentry_specOrDefName (old), oldType),
6374 uentry_whereDeclared (newCurrent));
6378 hasError = optgenerror
6380 message ("Parameter %d of function %q has inconsistent type: "
6381 "declared %t, %s %t",
6382 paramno + 1, uentry_getName (unew),
6383 newType, uentry_specOrDefName (old), oldType),
6384 uentry_whereDeclared (newCurrent));
6386 DPRINTF (("type: %s / %s",
6387 ctype_unparse (newType),
6388 ctype_unparse (ctype_realType (newType))));
6393 if (uentry_isDeclared (unew))
6395 hasError = optgenerror
6397 message ("Parameter %d of function %s has inconsistent type: "
6398 "declared %t, %s %t",
6399 paramno + 1, unew->uname,
6400 newType, uentry_specOrDefName (old), oldType),
6401 uentry_whereDeclared (unew));
6405 hasError = optgenerror
6407 message ("Parameter %d of function %s has inconsistent type: "
6408 "declared %t, %s %t",
6409 paramno + 1, unew->uname,
6410 newType, uentry_specOrDefName (old), oldType),
6411 uentry_whereDeclared (unew));
6417 if (!uentry_isUndefined (oldCurrent))
6419 if (!uentry_isUndefined (newCurrent)
6420 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
6422 uentry_showWhereLast (oldCurrent);
6426 uentry_showWhereLastPlain (old);
6429 uentry_setType (oldCurrent, newType);
6433 uentry_showWhereLastPlain (old);
6439 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6443 message ("Function %s %rdeclared with %d arg%p, %s with %d",
6445 uentry_isDeclared (old),
6446 uentryList_size (uentry_getParams (unew)),
6447 uentry_specOrDefName (old),
6448 uentryList_size (uentry_getParams (old))),
6449 uentry_whereDeclared (unew)))
6451 uentry_showWhereLastPlain (old);
6456 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6460 message ("Function %s inconsistently %rdeclared to return %t",
6462 uentry_isDeclared (old),
6463 ctype_returnValue (unew->utype)),
6464 uentry_whereDeclared (unew)))
6466 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
6470 static cstring paramStorageName (uentry ue)
6472 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
6475 static cstring fcnErrName (uentry ue)
6477 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
6480 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
6482 if (uentry_isVar (ue))
6484 return (checkedName (ue->info->var->checked));
6488 return (cstring_makeLiteralTemp ("<checked invalid>"));
6492 static cstring checkedName (chkind checked)
6496 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
6497 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
6498 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
6499 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
6500 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
6506 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
6511 if (uentry_isVar (unew))
6513 llassert (uentry_isVar (old));
6515 oldState = old->info->var->nullstate;
6516 newState = unew->info->var->nullstate;
6520 oldState = sRef_getNullState (old->sref);
6521 newState = sRef_getNullState (unew->sref);
6524 if (oldState == NS_ABSNULL)
6526 if (uentry_isVar (old))
6528 old->info->var->nullstate = newState;
6531 sRef_mergeNullState (old->sref, newState);
6533 else if (newState == NS_UNKNOWN)
6535 if (completeConform && newState != oldState
6536 && uentry_isReallySpecified (old))
6540 message ("%s %q specified as %s, but declared without %s qualifier",
6541 ekind_capName (unew->ukind),
6542 uentry_getName (unew),
6543 nstate_unparse (oldState),
6544 nstate_unparse (oldState)),
6545 uentry_whereDeclared (unew)))
6547 uentry_showWhereSpecified (old);
6551 if (uentry_isVar (unew))
6553 unew->info->var->nullstate = oldState;
6556 sRef_mergeNullState (unew->sref, oldState);
6558 else if (newState == NS_POSNULL)
6560 if (oldState == NS_MNOTNULL
6561 && (ctype_isUA (unew->utype)
6562 || (uentry_isFunction (unew)
6563 && ctype_isUA (ctype_returnValue (unew->utype)))))
6565 if (uentry_isVar (unew))
6567 unew->info->var->nullstate = oldState;
6570 sRef_mergeNullState (unew->sref, oldState);
6574 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
6575 || oldState == NS_UNKNOWN)
6582 ("%s %q inconsistently %rdeclared %s possibly null storage, "
6584 uentry_ekindName (unew),
6585 uentry_getName (unew),
6586 uentry_isDeclared (old),
6588 uentry_specOrDefName (old),
6589 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
6590 uentry_whereDeclared (unew)))
6592 uentry_showWhereSpecified (old);
6597 if (uentry_isVar (old))
6599 old->info->var->nullstate = newState;
6602 sRef_mergeNullState (old->sref, newState);
6605 else if (newState == NS_MNOTNULL)
6607 if (oldState != NS_MNOTNULL)
6613 message ("%s %q inconsistently %rdeclared %s notnull storage, "
6614 "%s without notnull qualifier",
6615 uentry_ekindName (unew),
6616 uentry_getName (unew),
6617 uentry_isDeclared (old),
6619 uentry_specOrDefName (old)),
6620 uentry_whereDeclared (unew)))
6622 uentry_showWhereSpecified (old);
6626 if (uentry_isVar (old))
6628 old->info->var->nullstate = newState;
6631 sRef_mergeNullState (old->sref, newState);
6636 if (uentry_isVar (unew))
6638 unew->info->var->nullstate = oldState;
6641 sRef_mergeNullState (unew->sref, oldState);
6646 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6647 bool mustConform, bool completeConform)
6653 if (uentry_isVar (old) && uentry_isVar (unew))
6655 oldState = old->info->var->defstate;
6656 newState = unew->info->var->defstate;
6661 oldState = sRef_getDefState (old->sref);
6662 newState = sRef_getDefState (unew->sref);
6665 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
6671 message ("%s %q inconsistently %rdeclared %s %s %s, "
6673 uentry_ekindName (unew),
6674 uentry_getName (unew),
6675 uentry_isDeclared (old),
6677 sstate_unparse (newState),
6678 paramStorageName (unew),
6679 uentry_specOrDefName (old),
6681 sstate_unparse (oldState),
6682 paramStorageName (unew)),
6683 uentry_whereDeclared (unew)))
6685 uentry_showWhereSpecified (old);
6689 if (vars) old->info->var->defstate = newState;
6690 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
6695 && (newState != oldState) && (oldState != SS_DEFINED)
6696 && uentry_isReallySpecified (old))
6700 message ("%s %q specified as %s, but declared without %s qualifier",
6701 ekind_capName (unew->ukind),
6702 uentry_getName (unew),
6703 sstate_unparse (oldState),
6704 sstate_unparse (oldState)),
6705 uentry_whereDeclared (unew)))
6707 uentry_showWhereSpecified (old);
6711 if (vars) unew->info->var->defstate = oldState;
6712 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
6717 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6718 bool mustConform, bool completeConform)
6723 oldKind = sRef_getAliasKind (old->sref);
6724 newKind = sRef_getAliasKind (unew->sref);
6726 if (alkind_isImplicit (newKind)
6727 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
6729 if (completeConform && !alkind_equal (newKind, oldKind)
6730 && uentry_isReallySpecified (old))
6734 message ("%s %q specified as %s, but declared without "
6735 "explicit alias qualifier",
6736 ekind_capName (unew->ukind),
6737 uentry_getName (unew),
6738 alkind_unparse (oldKind)),
6739 uentry_whereDeclared (unew)))
6741 uentry_showWhereSpecified (old);
6746 ** This really shouldn't be necessary, but it is!
6747 ** Function params (?) use new here.
6750 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
6754 if (alkind_isKnown (newKind))
6756 if (!alkind_equal (oldKind, newKind))
6758 if (alkind_isKnown (oldKind))
6763 message ("%s %q inconsistently %rdeclared %s %s storage, "
6765 uentry_ekindName (unew),
6766 uentry_getName (unew),
6767 uentry_isDeclared (old),
6769 alkind_unparse (newKind),
6770 uentry_specOrDefName (old),
6771 alkind_unparse (oldKind)),
6772 uentry_whereDeclared (unew)))
6774 uentry_showWhereSpecified (old);
6776 sRef_setAliasKind (old->sref, AK_ERROR,
6777 uentry_whereDeclared (unew));
6781 sRef_setAliasKind (old->sref, newKind,
6782 uentry_whereDeclared (unew));
6787 if (!(alkind_isImplicit (newKind)))
6790 !uentry_isFunction (unew) &&
6793 message ("%s %q inconsistently %rdeclared %s %s storage, "
6794 "implicitly %s as temp storage",
6795 uentry_ekindName (unew),
6796 uentry_getName (unew),
6797 uentry_isDeclared (old),
6799 alkind_unparse (newKind),
6800 uentry_specOrDefName (old)),
6801 uentry_whereDeclared (unew)))
6803 uentry_showWhereSpecified (old);
6807 sRef_setAliasKind (old->sref, newKind,
6808 uentry_whereDeclared (unew));
6810 else /* newKind is temp or refcounted */
6817 else /* newKind unknown */
6824 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6825 bool mustConform, bool completeConform)
6830 oldKind = sRef_getExKind (old->sref);
6831 newKind = sRef_getExKind (unew->sref);
6833 if (exkind_isKnown (newKind))
6835 if (oldKind != newKind)
6837 if (exkind_isKnown (oldKind))
6842 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
6843 uentry_ekindName (unew),
6844 uentry_getName (unew),
6845 uentry_isDeclared (old),
6847 exkind_unparse (newKind),
6848 uentry_specOrDefName (old),
6849 exkind_unparse (oldKind)),
6850 uentry_whereDeclared (unew)))
6852 uentry_showWhereSpecified (old);
6855 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6862 message ("%s %q inconsistently %rdeclared %s %s, "
6863 "implicitly %s without exposure qualifier",
6864 uentry_ekindName (unew),
6865 uentry_getName (unew),
6866 uentry_isDeclared (old),
6868 exkind_unparse (newKind),
6869 uentry_specOrDefName (old)),
6870 uentry_whereDeclared (unew)))
6872 uentry_showWhereSpecified (old);
6875 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6881 if (completeConform && exkind_isKnown (oldKind)
6882 && uentry_isReallySpecified (old))
6886 message ("%s %q specified as %s, but declared without "
6887 "exposure qualifier",
6888 ekind_capName (unew->ukind),
6889 uentry_getName (unew),
6890 exkind_unparse (oldKind)),
6891 uentry_whereDeclared (unew)))
6893 uentry_showWhereSpecified (old);
6897 /* yes, this is necessary! (if its a param) */
6898 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
6903 uentry_checkStateConformance (/*@notnull@*/ uentry old,
6904 /*@notnull@*/ uentry unew,
6905 bool mustConform, bool completeConform)
6907 checkDefState (old, unew, mustConform, completeConform);
6908 checkNullState (old, unew, mustConform, completeConform);
6909 checkAliasState (old, unew, mustConform, completeConform);
6910 checkExpState (old, unew, mustConform, completeConform);
6912 sRef_storeState (old->sref);
6913 sRef_storeState (unew->sref);
6917 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
6919 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
6924 llassert (uentry_isVar (old));
6925 llassert (uentry_isVar (unew));
6927 if (cstring_isEmpty (old->uname))
6929 cstring_free (old->uname);
6930 old->uname = cstring_copy (unew->uname);
6933 if (unew->info->var->kind == VKRETPARAM
6934 || unew->info->var->kind == VKSEFRETPARAM)
6936 if (old->info->var->kind != VKRETPARAM
6937 && old->info->var->kind != VKSEFRETPARAM)
6941 message ("Parameter %q inconsistently %rdeclared as "
6942 "returned parameter",
6943 uentry_getName (unew),
6944 uentry_isDeclared (old)),
6945 uentry_whereDeclared (unew)))
6947 uentry_showWhereSpecified (old);
6948 old->info->var->kind = unew->info->var->kind;
6954 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
6956 if (old->info->var->kind != VKSEFPARAM
6957 && old->info->var->kind != VKSEFRETPARAM)
6961 message ("Parameter %qinconsistently %rdeclared as "
6963 uentry_getOptName (unew),
6964 uentry_isDeclared (old)),
6965 uentry_whereDeclared (unew)))
6967 uentry_showWhereSpecified (old);
6968 old->info->var->kind = unew->info->var->kind;
6973 if (old->info->var->kind == VKSPEC)
6975 old->info->var->kind = unew->info->var->kind;
6979 unew->info->var->kind = old->info->var->kind;
6982 if (unew->info->var->checked != CH_UNKNOWN
6983 && unew->info->var->checked != old->info->var->checked)
6985 if (old->info->var->checked == CH_UNKNOWN
6986 && !fileloc_isUser (uentry_whereLast (old)))
6994 message ("Variable %q inconsistently %rdeclared as "
6995 "%s parameter (was %s)",
6996 uentry_getName (unew),
6997 uentry_isDeclared (old),
6998 checkedName (unew->info->var->checked),
6999 checkedName (old->info->var->checked)),
7000 uentry_whereDeclared (unew)))
7002 uentry_showWhereSpecified (old);
7006 old->info->var->checked = unew->info->var->checked;
7011 && (old->info->var->checked != CH_UNKNOWN)
7012 && uentry_isReallySpecified (old))
7016 message ("%s %q specified as %s, but declared without %s qualifier",
7017 ekind_capName (unew->ukind),
7018 uentry_getName (unew),
7019 checkedName (old->info->var->checked),
7020 checkedName (old->info->var->checked)),
7021 uentry_whereDeclared (unew)))
7023 uentry_showWhereSpecified (old);
7027 unew->info->var->checked = old->info->var->checked;
7030 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7033 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7035 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7040 llassert (uentry_isVar (u1));
7041 llassert (uentry_isVar (u2));
7043 if (u1->info->var->kind != u2->info->var->kind) {
7044 if (u1->info->var->kind == VKSEFRETPARAM) {
7045 if (u2->info->var->kind == VKRETPARAM) {
7048 message ("Function types are inconsistent. Parameter %d is "
7049 "sef parameter, but non-sef parameter in "
7050 "assigned function: %s",
7051 paramno, exprNode_unparse (e)),
7053 } else if (u2->info->var->kind == VKSEFPARAM) {
7056 message ("Function types are inconsistent. Parameter %d is "
7057 "returns parameter, but non-returns parameter in "
7058 "assigned function: %s",
7059 paramno, exprNode_unparse (e)),
7064 message ("Function types are inconsistent. Parameter %d is "
7065 "sef returns parameter, but non-sef returns parameter in "
7066 "assigned function: %s",
7067 paramno, exprNode_unparse (e)),
7070 } else if (u1->info->var->kind == VKRETPARAM) {
7073 message ("Function types are inconsistent. Parameter %d is "
7074 "returns parameter, but non-returns parameter in "
7075 "assigned function: %s",
7076 paramno, exprNode_unparse (e)),
7078 } else if (u1->info->var->kind == VKSEFPARAM) {
7081 message ("Function types are inconsistent. Parameter %d is "
7082 "sef parameter, but non-sef parameter in "
7083 "assigned function: %s",
7084 paramno, exprNode_unparse (e)),
7087 if (u2->info->var->kind == VKSEFRETPARAM) {
7090 message ("Function types are inconsistent. Parameter %d is "
7091 "normal parameter, but sef returns parameter in "
7092 "assigned function: %s",
7093 paramno, exprNode_unparse (e)),
7095 } else if (u2->info->var->kind == VKSEFPARAM) {
7098 message ("Function types are inconsistent. Parameter %d is "
7099 "normal parameter, but sef parameter in "
7100 "assigned function: %s",
7101 paramno, exprNode_unparse (e)),
7103 } else if (u2->info->var->kind == VKRETPARAM) {
7106 message ("Function types are inconsistent. Parameter %d is "
7107 "normal parameter, but returns parameter in "
7108 "assigned function: %s",
7109 paramno, exprNode_unparse (e)),
7117 if (u1->info->var->defstate != u2->info->var->defstate)
7121 message ("Function types are inconsistent. Parameter %d is "
7122 "%s, but %s in assigned function: %s",
7124 sstate_unparse (u1->info->var->defstate),
7125 sstate_unparse (u2->info->var->defstate),
7126 exprNode_unparse (e)),
7130 if (u1->info->var->nullstate != u2->info->var->nullstate)
7134 message ("Function types are inconsistent. Parameter %d is "
7135 "%s, but %s in assigned function: %s",
7137 nstate_unparse (u1->info->var->nullstate),
7138 nstate_unparse (u2->info->var->nullstate),
7139 exprNode_unparse (e)),
7143 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7147 message ("Function types are inconsistent. Parameter %d is "
7148 "%s, but %s in assigned function: %s",
7150 alkind_unparse (sRef_getAliasKind (u1->sref)),
7151 alkind_unparse (sRef_getAliasKind (u2->sref)),
7152 exprNode_unparse (e)),
7156 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7160 message ("Function types are inconsistent. Parameter %d is "
7161 "%s, but %s in assigned function: %s",
7163 exkind_unparse (sRef_getExKind (u1->sref)),
7164 exkind_unparse (sRef_getExKind (u2->sref)),
7165 exprNode_unparse (e)),
7171 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7172 /*@notnull@*/ uentry unew,
7173 bool mustConform, /*@unused@*/ bool completeConform)
7175 uentryList oldParams = uentry_getParams (old);
7176 uentryList newParams = uentry_getParams (unew);
7177 ctype newType = unew->utype;
7178 ctype oldType = old->utype;
7179 ctype oldRetType = ctype_unknown;
7180 ctype newRetType = ctype_unknown;
7182 if (uentry_isForward (old))
7184 mustConform = FALSE;
7185 uentry_copyInto (old, unew);
7190 ** check return values
7193 if (ctype_isKnown (oldType))
7195 llassert (ctype_isFunction (oldType));
7197 oldRetType = ctype_returnValue (oldType);
7200 if (ctype_isKnown (newType))
7202 llassert (ctype_isFunction (newType));
7204 newRetType = ctype_returnValue (newType);
7207 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
7208 && !ctype_matchDef (newRetType, oldRetType))
7210 if (mustConform) returnValueError (old, unew);
7214 if (ctype_isConj (newRetType))
7216 if (ctype_isConj (oldRetType))
7218 if (!ctype_sameAltTypes (newRetType, oldRetType))
7222 message ("Function %q inconsistently %rdeclared to "
7223 "return alternate types %s "
7224 "(types match, but alternates are not identical, "
7225 "so checking may not be correct)",
7226 uentry_getName (unew),
7227 uentry_isDeclared (old),
7228 ctype_unparse (newRetType)),
7229 uentry_whereDeclared (unew)))
7231 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
7237 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
7242 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7244 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
7246 if (exitkind_isKnown (unew->info->fcn->exitCode))
7250 message ("Function %q inconsistently %rdeclared using %s",
7251 uentry_getName (unew),
7252 uentry_isDeclared (old),
7253 exitkind_unparse (unew->info->fcn->exitCode)),
7254 uentry_whereDeclared (unew)))
7256 uentry_showWhereSpecified (old);
7261 unew->info->fcn->exitCode = old->info->fcn->exitCode;
7265 if (!qual_isUnknown (unew->info->fcn->nullPred))
7267 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
7271 message ("Function %q inconsistently %rdeclared using %s",
7272 uentry_getName (unew),
7273 uentry_isDeclared (old),
7274 qual_unparse (unew->info->fcn->nullPred)),
7275 uentry_whereDeclared (unew)))
7277 uentry_showWhereSpecified (old);
7283 unew->info->fcn->nullPred = old->info->fcn->nullPred;
7286 if (unew->info->fcn->specialCode != SPC_NONE)
7288 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
7292 message ("Function %q inconsistently %rdeclared using %s",
7293 uentry_getName (unew),
7294 uentry_isDeclared (old),
7295 specCode_unparse (unew->info->fcn->specialCode)),
7296 uentry_whereDeclared (unew)))
7298 uentry_showWhereSpecified (old);
7304 unew->info->fcn->specialCode = old->info->fcn->specialCode;
7311 if (!uentryList_sameObject (oldParams, newParams)
7312 && (!uentryList_isMissingParams (oldParams)))
7314 if (!uentryList_isMissingParams (newParams))
7317 int nparams = uentryList_size (oldParams);
7318 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
7320 if (nparams != uentryList_size (newParams))
7322 nargsError (old, unew);
7325 if (uentryList_size (newParams) < nparams)
7327 nparams = uentryList_size (newParams);
7330 while (paramno < nparams)
7332 uentry oldCurrent = uentryList_getN (oldParams, paramno);
7333 uentry newCurrent = uentryList_getN (newParams, paramno);
7334 ctype oldCurrentType = uentry_getType (oldCurrent);
7335 ctype newCurrentType = uentry_getType (newCurrent);
7337 llassert (uentry_isValid (oldCurrent)
7338 && uentry_isValid (newCurrent));
7340 if (!uentry_isElipsisMarker (oldCurrent)
7341 && !uentry_isElipsisMarker (newCurrent))
7343 checkVarConformance (oldCurrent, newCurrent,
7344 mustConform, completeConform);
7349 if (uentry_hasName (oldCurrent)
7350 && uentry_hasName (newCurrent))
7352 cstring oldname = uentry_getName (oldCurrent);
7353 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
7355 cstring nname = uentry_getName (newCurrent);
7358 if (cstring_isDefined (pfx)
7359 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
7361 oname = cstring_suffix (oldname, cstring_length (pfx));
7366 /*@-branchstate@*/ } /*@=branchstate@*/
7368 if (cstring_isDefined (pfx)
7369 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
7371 nnamefix = cstring_suffix (nname, cstring_length (pfx));
7376 /*@-branchstate@*/ } /*@=branchstate@*/
7378 if (!cstring_equal (oname, nnamefix))
7381 (FLG_DECLPARAMMATCH,
7382 message ("Definition parameter name %s does not match "
7383 "name of corresponding parameter in "
7386 uentry_whereLast (newCurrent)))
7388 uentry_showWhereLastPlain (oldCurrent);
7392 cstring_free (oldname);
7393 cstring_free (nname);
7397 if (!ctype_match (oldCurrentType, newCurrentType))
7399 paramTypeError (old, oldCurrent, oldCurrentType,
7400 unew, newCurrent, newCurrentType, paramno);
7404 if (ctype_isMissingParamsMarker (newCurrentType)
7405 || ctype_isElips (newCurrentType)
7406 || ctype_isMissingParamsMarker (oldCurrentType)
7407 || ctype_isElips (oldCurrentType))
7413 if (ctype_isConj (newCurrentType))
7415 if (ctype_isConj (oldCurrentType))
7417 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
7421 message ("Parameter %q inconsistently %rdeclared with "
7422 "alternate types %s "
7423 "(types match, but alternates are not identical, "
7424 "so checking may not be correct)",
7425 uentry_getName (newCurrent),
7426 uentry_isDeclared (oldCurrent),
7427 ctype_unparse (newCurrentType)),
7428 uentry_whereDeclared (unew)))
7430 uentry_showWhereLastVal (oldCurrent,
7431 ctype_unparse (oldCurrentType));
7439 message ("Parameter %q inconsistently %rdeclared with "
7440 "alternate types %s",
7441 uentry_getName (newCurrent),
7442 uentry_isDeclared (oldCurrent),
7443 ctype_unparse (newCurrentType)),
7444 uentry_whereDeclared (unew)))
7446 uentry_showWhereLastVal (oldCurrent,
7447 ctype_unparse (oldCurrentType));
7454 if (ctype_isConj (oldCurrentType))
7456 uentry_setType (newCurrent, oldCurrentType);
7464 ** Forgot this! detected by lclint:
7465 ** uentry.c:1257,15: Suspected infinite loop
7471 if (!uentryList_isMissingParams (newParams))
7473 if (ctype_isConj (oldRetType))
7475 old->utype = ctype_makeFunction (oldRetType,
7476 uentryList_copy (newParams));
7480 old->utype = unew->utype;
7484 checkGlobalsConformance (old, unew, mustConform, completeConform);
7485 checkModifiesConformance (old, unew, mustConform, completeConform);
7487 if (unew->info->fcn->specclauses != NULL)
7489 if (old->info->fcn->specclauses == NULL)
7493 message ("Function %q redeclared using special clauses (can only "
7494 "be used in first declaration)",
7495 uentry_getName (unew)),
7496 uentry_whereDeclared (unew)))
7498 uentry_showWhereLast (old);
7503 specialClauses_checkEqual (old, unew);
7507 if (fileloc_isUndefined (old->whereDeclared))
7509 old->whereDeclared = fileloc_copy (unew->whereDeclared);
7511 else if (fileloc_isUndefined (unew->whereDeclared))
7513 unew->whereDeclared = fileloc_copy (old->whereDeclared);
7522 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
7526 llassert (uentry_isValid (ue));
7527 llassert (uentry_isEitherConstant (ue));
7529 uval = ue->info->uconst->val;
7531 if (multiVal_isDefined (uval))
7533 if (multiVal_isDefined (m))
7535 if (!multiVal_equiv (uval, m))
7539 message ("%s %q defined with inconsistent value: %q",
7540 ekind_capName (ue->ukind),
7541 uentry_getName (ue),
7542 multiVal_unparse (m)),
7545 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
7553 ue->info->uconst->val = m;
7554 multiVal_free (uval);
7559 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7562 bool typeError = FALSE;
7564 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
7566 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
7570 checkStructConformance (old, unew);
7575 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7577 llbug (message ("struct tags: bad types: %t / %t",
7578 old->utype, unew->utype));
7582 else if (uentry_isEnumTag (old))
7584 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
7586 if (mustConform) checkEnumConformance (old, unew);
7590 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7592 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
7593 ctype_unparse (unew->utype)));
7597 else if (!ctype_match (old->utype, unew->utype))
7599 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
7601 ctype realt = ctype_realType (unew->utype);
7603 if (ctype_isRealInt (realt) || ctype_isChar (realt))
7605 unew->utype = ctype_bool;
7611 typeError = optgenerror
7613 message ("%q defined as %s", uentry_getName (old),
7614 ctype_unparse (realt)),
7615 uentry_whereDeclared (unew));
7623 ctype oldr = ctype_realType (old->utype);
7624 ctype newr = ctype_realType (unew->utype);
7626 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
7628 checkStructConformance (old, unew);
7630 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
7632 checkStructConformance (old, unew);
7634 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
7636 checkEnumConformance (old, unew);
7638 else if (uentry_isConstant (old)
7639 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
7641 /* okay...for now! (should check the type is reset later... */
7647 message ("%s %q %rdeclared with inconsistent type: %t",
7648 ekind_capName (unew->ukind),
7649 uentry_getName (unew),
7650 uentry_isDeclared (old),
7652 uentry_whereDeclared (unew)))
7654 uentry_showWhereLast (old);
7670 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
7671 /*@notnull@*/ uentry unew,
7672 bool mustConform, bool completeConform)
7674 if (ctype_isDefined (unew->info->datatype->type))
7676 if (ctype_isDirectBool (old->utype) &&
7677 cstring_equalLit (unew->uname, "bool"))
7679 if (!context_getFlag (FLG_ABSTRACTBOOL))
7681 unew->utype = ctype_bool;
7685 if (ctype_isUnknown (old->info->datatype->type))
7687 old->info->datatype->type = unew->info->datatype->type;
7691 if (ctype_matchDef (old->info->datatype->type,
7692 unew->info->datatype->type))
7701 ("Type %q %s with inconsistent type: %t",
7702 uentry_getName (unew),
7703 uentry_reDefDecl (old, unew),
7704 unew->info->datatype->type),
7705 uentry_whereDeclared (unew)))
7707 uentry_showWhereLastExtra
7708 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
7711 old->info->datatype->type = unew->info->datatype->type;
7716 if (unew->info->datatype->abs != MAYBE)
7718 if (ynm_isOff (old->info->datatype->abs)
7719 && ynm_isOn (unew->info->datatype->abs))
7721 if (!ctype_isDirectBool (old->utype))
7726 ("Datatype %q inconsistently %rdeclared as abstract type",
7727 uentry_getName (unew),
7728 uentry_isDeclared (old)),
7729 uentry_whereDeclared (unew)))
7731 uentry_showWhereLastPlain (old);
7735 else if (ynm_isOn (old->info->datatype->abs)
7736 && ynm_isOff (unew->info->datatype->abs))
7738 if (!ctype_isDirectBool (old->utype))
7743 ("Datatype %q inconsistently %rdeclared as concrete type",
7744 uentry_getName (unew),
7745 uentry_isDeclared (old)),
7746 uentry_whereDeclared (unew)))
7748 uentry_showWhereLastPlain (old);
7759 if (ynm_isOn (old->info->datatype->abs))
7761 old->sref = unew->sref;
7762 unew->info->datatype->mut = old->info->datatype->mut;
7765 && uentry_isReallySpecified (old))
7770 ("Datatype %q specified as abstract, "
7771 "but abstract annotation not used in declaration",
7772 uentry_getName (unew)),
7773 uentry_whereDeclared (unew)))
7775 uentry_showWhereLastPlain (old);
7781 unew->info->datatype->abs = old->info->datatype->abs;
7783 if (ynm_isMaybe (unew->info->datatype->mut))
7785 if (completeConform && ynm_isOff (old->info->datatype->mut)
7786 && uentry_isReallySpecified (old))
7791 ("Datatype %q specified as immutable, "
7792 "but immutable annotation not used in declaration",
7793 uentry_getName (unew)),
7794 uentry_whereDeclared (unew)))
7796 uentry_showWhereLastPlain (old);
7800 unew->info->datatype->mut = old->info->datatype->mut;
7802 else if (ynm_isMaybe (old->info->datatype->mut))
7804 old->info->datatype->mut = unew->info->datatype->mut;
7808 if (ynm_isOn (old->info->datatype->abs))
7810 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
7814 message ("Datatype %q inconsistently %rdeclared as immutable",
7815 uentry_getName (unew),
7816 uentry_isDeclared (old)),
7817 uentry_whereDeclared (unew)))
7819 uentry_showWhereLastPlain (old);
7824 if (ynm_isOff (old->info->datatype->mut)
7825 && ynm_isOn (unew->info->datatype->mut))
7829 message ("Datatype %q inconsistently %rdeclared as mutable",
7830 uentry_getName (unew),
7831 uentry_isDeclared (old)),
7832 uentry_whereDeclared (unew)))
7834 uentry_showWhereLastPlain (old);
7839 old->info->datatype->mut = unew->info->datatype->mut;
7842 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7846 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
7847 /*@notnull@*/ uentry unew,
7849 /*@unused@*/ bool completeConform)
7851 multiVal oldVal = old->info->uconst->val;
7852 multiVal newVal = unew->info->uconst->val;
7854 if (multiVal_isDefined (oldVal))
7856 if (multiVal_isDefined (newVal))
7858 if (!multiVal_equiv (oldVal, newVal))
7863 message ("%s %q %rdeclared with inconsistent value: %q",
7864 ekind_capName (unew->ukind),
7865 uentry_getName (unew),
7866 uentry_isDeclared (old),
7867 multiVal_unparse (newVal)),
7868 uentry_whereDeclared (unew)))
7870 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
7874 unew->info->uconst->val = multiVal_copy (oldVal);
7875 multiVal_free (newVal);
7884 old->info->uconst->val = multiVal_copy (newVal);
7889 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7890 /*@notnull@*/ uentry unew, bool mustConform,
7891 bool completeConform)
7893 bool typeError = FALSE;
7894 bool fcnConformance = FALSE;
7896 if (!ekind_equal (unew->ukind, old->ukind))
7899 ** okay, only if one is a function and the other is
7900 ** a variable of type function.
7903 if (unew->ukind == KENUMCONST
7904 && old->ukind == KCONST)
7906 old->ukind = KENUMCONST;
7910 if (unew->ukind == KFCN
7911 && old->ukind == KCONST
7912 && ctype_isUnknown (old->utype))
7915 ** When a function is defined with an unparam macro
7918 uentry_copyInto (old, unew);
7922 if (uentry_isExpandedMacro (old)
7923 && uentry_isEitherConstant (unew))
7925 uentry_copyInto (old, unew);
7929 if (uentry_isEndIter (unew))
7931 if (ctype_isUnknown (old->utype))
7933 if (!uentry_isSpecified (old)
7934 && uentry_isCodeDefined (unew))
7936 if (!fileloc_withinLines (uentry_whereDefined (old),
7937 uentry_whereDeclared (unew), 2))
7938 { /* bogus! will give errors if there is too much whitespace */
7942 ("Iterator finalized name %q does not match name in "
7943 "previous iter declaration (should be end_%q). This iter "
7944 "is declared at %q",
7945 uentry_getName (unew),
7946 uentry_getName (old),
7947 fileloc_unparse (uentry_whereDefined (old))),
7948 uentry_whereDeclared (old));
7952 uentry_copyInto (old, unew);
7957 KindConformanceError (old, unew, mustConform);
7961 if (uentry_isFunction (unew))
7963 if (uentry_isVariable (old))
7965 if (!ctype_isUnknown (old->utype))
7967 if (ctype_isFunction (old->utype))
7969 uentry_makeVarFunction (old);
7970 checkFunctionConformance (old, unew, mustConform,
7972 fcnConformance = TRUE;
7976 KindConformanceError (old, unew, mustConform);
7981 if (uentry_isExpandedMacro (old))
7983 if (fileloc_isUndefined (unew->whereDefined))
7985 unew->whereDefined = fileloc_update (unew->whereDefined,
7989 uentry_copyInto (old, unew);
7990 old->used = unew->used = TRUE;
7995 /* undeclared identifier */
7996 old->utype = unew->utype;
7997 uentry_makeVarFunction (old);
7998 checkFunctionConformance (old, unew, FALSE, FALSE);
7999 fcnConformance = TRUE;
8005 KindConformanceError (old, unew, mustConform);
8008 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8010 if (!ctype_isUnknown (unew->utype))
8012 if (ctype_isFunction (unew->utype))
8014 uentry_makeVarFunction (unew);
8015 checkFunctionConformance (old, unew, mustConform, completeConform);
8016 fcnConformance = TRUE;
8020 KindConformanceError (old, unew, mustConform);
8025 KindConformanceError (old, unew, mustConform);
8030 KindConformanceError (old, unew, mustConform);
8036 ** check parameter lists for functions
8037 ** (before type errors, to get better messages
8040 if (uentry_isFunction (old))
8042 checkFunctionConformance (old, unew, mustConform, completeConform);
8043 fcnConformance = TRUE;
8047 if (!ctype_isUndefined (old->utype))
8049 typeError = checkTypeConformance (old, unew, mustConform);
8056 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8058 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8061 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8063 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8066 if (uentry_isVariable (old) && uentry_isVariable (unew))
8069 !ctype_matchDef (old->utype, unew->utype))
8074 ("Variable %q %s with inconsistent type (arrays and pointers are "
8075 "not identical in variable declarations): %t",
8076 uentry_getName (unew),
8077 uentry_reDefDecl (old, unew),
8079 uentry_whereDeclared (unew)))
8081 uentry_showWhereLast (old);
8084 ** Avoid repeated errors.
8087 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8089 old->whereDefined = fileloc_update (old->whereDefined,
8097 checkVarConformance (old, unew, mustConform, completeConform);
8102 /* old->utype = unew->utype; */
8106 if (ctype_isConj (old->utype))
8108 if (ctype_isConj (unew->utype))
8110 if (!ctype_sameAltTypes (old->utype, unew->utype))
8114 message ("%s %q inconsistently %rdeclared with "
8115 "alternate types %s "
8116 "(types match, but alternates are not identical, "
8117 "so checking may not be correct)",
8118 ekind_capName (uentry_getKind (old)),
8119 uentry_getName (unew),
8120 uentry_isDeclared (old),
8121 ctype_unparse (unew->utype)),
8122 uentry_whereDeclared (unew)))
8124 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
8128 old->utype = unew->utype;
8135 if (ctype_isUnknown (old->utype))
8137 old->utype = unew->utype;
8142 if (unew->ukind == old->ukind)
8145 unew->info = uinfo_copy (old->info, old->ukind);
8148 sRef_storeState (old->sref);
8149 sRef_storeState (unew->sref);
8153 ** modifies spec to reflect def, reports any inconsistencies
8157 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
8159 llassert (uentry_isValid (spec));
8160 llassert (uentry_isValid (def));
8161 llassert (cstring_equal (spec->uname, def->uname));
8163 uentry_checkConformance (spec, def, TRUE,
8164 context_getFlag (FLG_NEEDSPEC));
8166 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
8169 ** okay, declarations conform. Propagate extra information.
8172 uentry_setDefined (spec, uentry_whereDefined (def));
8173 uentry_setDeclared (spec, uentry_whereDeclared (def));
8175 if (uentry_isStatic (def))
8179 message ("%s %q specified, but declared as static",
8180 ekind_capName (def->ukind),
8181 uentry_getName (def)),
8182 uentry_whereDeclared (def)))
8184 uentry_showWhereSpecified (spec);
8189 spec->storageclass = def->storageclass;
8192 sRef_storeState (spec->sref);
8194 spec->used = def->used || spec->used;
8195 spec->hasNameError |= def->hasNameError;
8199 if (!spec->hasNameError)
8201 uentry_checkName (spec);
8210 ** Can't generate function redeclaration errors when the
8211 ** entries are merged, since we don't yet know if its the
8212 ** definition of the function.
8216 uentry_clearDecl (void)
8218 posRedeclared = uentry_undefined;
8219 fileloc_free (posLoc);
8220 posLoc = fileloc_undefined;
8224 uentry_checkDecl (void)
8226 if (uentry_isValid (posRedeclared))
8228 llassert (fileloc_isDefined (posLoc));
8230 if (uentry_isCodeDefined (posRedeclared))
8232 if (optgenerror (FLG_REDECL,
8233 message ("%s %q declared after definition",
8234 ekind_capName (posRedeclared->ukind),
8235 uentry_getName (posRedeclared)),
8238 llgenindentmsg (message ("Definition of %q",
8239 uentry_getName (posRedeclared)),
8240 posRedeclared->whereDeclared);
8245 if (optgenerror (FLG_REDECL,
8246 message ("%s %q declared more than once",
8247 ekind_capName (posRedeclared->ukind),
8248 uentry_getName (posRedeclared)),
8251 llgenindentmsg (message ("Previous declaration of %q",
8252 uentry_getName (posRedeclared)),
8253 posRedeclared->whereDeclared);
8258 fileloc_free (posLoc);
8259 posLoc = fileloc_undefined;
8260 posRedeclared = uentry_undefined;
8264 ** Redefinition of old as unew.
8265 ** modifies old to reflect unew, reports any inconsistencies
8269 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
8271 fileloc olddef = uentry_whereDeclared (old);
8272 fileloc unewdef = uentry_whereDeclared (unew);
8276 if (uentry_isExtern (unew))
8278 uentry_setUsed (old, unewdef);
8282 fileloc_isUndefined (olddef)
8283 && fileloc_isDefined (uentry_whereDefined (old))
8284 && !uentry_isExpandedMacro (old);
8286 if (!context_getFlag (FLG_INCONDEFSLIB)
8287 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8289 mustConform = FALSE;
8296 llassert (uentry_isValid (old));
8297 llassert (uentry_isValid (unew));
8298 llassert (cstring_equal (old->uname, unew->uname));
8301 ** should check old one was extern!
8304 if (uentry_isStatic (old))
8306 if (!(uentry_isStatic (unew)))
8310 message ("%s %q shadows static declaration",
8311 ekind_capName (unew->ukind),
8312 uentry_getName (unew)),
8315 uentry_showWhereLast (old);
8320 uentry_setDeclDef (old, unewdef);
8323 else if (uentry_isStatic (unew))
8325 uentry_setDeclDef (old, unewdef);
8327 else if (uentry_isExtern (old))
8329 uentry_setDeclared (old, unewdef);
8333 if (!uentry_isExtern (unew) && !uentry_isForward (old)
8334 && !fileloc_equal (olddef, unewdef)
8335 && !fileloc_isUndefined (olddef)
8336 && !fileloc_isUndefined (unewdef)
8337 && !fileloc_isBuiltin (olddef)
8338 && !fileloc_isBuiltin (unewdef)
8339 && !uentry_isYield (old)
8340 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8342 if (uentry_isVariable (old) || uentry_isVariable (unew))
8344 ; /* will report redeclaration error later */
8348 if (fileloc_isDefined (uentry_whereDefined (old)))
8352 message ("%s %q defined more than once",
8353 ekind_capName (unew->ukind),
8354 uentry_getName (unew)),
8355 uentry_whereLast (unew)))
8358 (message ("Previous definition of %q",
8359 uentry_getName (old)),
8360 uentry_whereLast (old));
8363 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
8365 uentry_copyInto (old, unew);
8366 old->sref = sRef_saveCopy (old->sref);
8374 if (fileloc_isLib (olddef)
8375 || fileloc_isUndefined (olddef)
8376 || fileloc_isImport (olddef))
8378 if (uentry_isExtern (unew))
8380 if (uentry_isExtern (old)
8381 || (fileloc_isDefined (uentry_whereDeclared (old))
8382 && (!fileloc_equal (uentry_whereDeclared (old),
8383 uentry_whereDefined (old)))))
8387 message ("%s %q declared more than once",
8388 ekind_capName (unew->ukind),
8389 uentry_getName (unew)),
8390 unew->whereDeclared))
8393 (message ("Previous declaration of %q",
8394 uentry_getName (old)),
8395 old->whereDeclared);
8399 uentry_setExtern (old);
8403 uentry_setDefined (old, unewdef);
8409 uentry_checkConformance (old, unew, mustConform, FALSE);
8411 old->used = old->used || unew->used;
8412 old->uses = filelocList_append (old->uses, unew->uses);
8413 unew->uses = filelocList_undefined;
8415 sRef_storeState (old->sref);
8416 sRef_storeState (unew->sref);
8420 old->whereDefined = fileloc_update (old->whereDefined,
8425 ** No redeclaration errors for functions here, since we
8426 ** don't know if this is the definition of the function.
8429 if (fileloc_isUser (old->whereDeclared)
8430 && fileloc_isUser (unew->whereDeclared)
8431 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
8432 && !fileloc_isDefined (unew->whereDefined))
8434 if (uentry_isFunction (old))
8436 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
8437 posLoc = fileloc_update (posLoc, unew->whereDeclared);
8441 if (optgenerror (FLG_REDECL,
8442 message ("%s %q declared more than once",
8443 ekind_capName (unew->ukind),
8444 uentry_getName (unew)),
8445 unew->whereDeclared))
8447 llgenindentmsg (message ("Previous declaration of %q",
8448 uentry_getName (old)),
8449 old->whereDeclared);
8454 if (fileloc_isUndefined (old->whereDefined))
8456 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
8460 if (!context_processingMacros ()
8461 && fileloc_isUser (old->whereDefined)
8462 && fileloc_isUser (unew->whereDefined)
8463 && !fileloc_equal (old->whereDefined, unew->whereDefined))
8465 if (uentry_isVariable (unew) || uentry_isFunction (unew))
8467 if (uentry_isVariable (unew)
8468 && uentry_isExtern (unew))
8470 if (optgenerror (FLG_REDECL,
8471 message ("%s %q declared after definition",
8472 ekind_capName (unew->ukind),
8473 uentry_getName (unew)),
8474 unew->whereDeclared))
8476 llgenindentmsg (message ("Definition of %q",
8477 uentry_getName (old)),
8483 if (optgenerror (FLG_REDEF,
8484 message ("%s %q redefined",
8485 ekind_capName (unew->ukind),
8486 uentry_getName (unew)),
8487 unew->whereDefined))
8489 llgenindentmsg (message ("Previous definition of %q",
8490 uentry_getName (old)),
8498 if (uentry_isExternal (unew))
8500 old->whereDefined = fileloc_createExternal ();
8503 if (unew->hasNameError)
8505 old->hasNameError = TRUE;
8510 if (!old->hasNameError)
8512 uentry_checkName (old);
8515 llassert (!ctype_isUndefined (old->utype));
8519 uentry_copyState (uentry res, uentry other)
8521 llassert (uentry_isValid (res));
8522 llassert (uentry_isValid (other));
8524 res->used = other->used;
8526 res->info->var->kind = other->info->var->kind;
8527 res->info->var->defstate = other->info->var->defstate;
8528 res->info->var->nullstate = other->info->var->nullstate;
8529 res->info->var->checked = other->info->var->checked;
8531 sRef_copyState (res->sref, other->sref);
8535 uentry_sameKind (uentry u1, uentry u2)
8537 if (uentry_isValid (u1) && uentry_isValid (u2))
8539 if (uentry_isVar (u1) && uentry_isVar (u2))
8541 ctype c1 = u1->utype;
8542 ctype c2 = u2->utype;
8544 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
8547 ** both functions, or both not functions
8550 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
8554 return ((u1->ukind == u2->ukind));
8561 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
8563 llassert (uentry_isValid (unew));
8564 llassert (uentry_isValid (old));
8566 unew->ukind = old->ukind;
8567 unew->uname = cstring_copy (old->uname);
8568 unew->utype = old->utype;
8570 unew->whereSpecified = fileloc_copy (old->whereSpecified);
8571 unew->whereDefined = fileloc_copy (old->whereDefined);
8572 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8574 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
8575 unew->used = old->used;
8577 unew->isPrivate = old->isPrivate;
8578 unew->hasNameError = old->hasNameError;
8579 unew->uses = filelocList_undefined;
8581 unew->storageclass = old->storageclass;
8582 unew->info = uinfo_copy (old->info, old->ukind);
8587 uentry_copy (uentry e)
8589 if (uentry_isValid (e))
8591 uentry enew = uentry_alloc ();
8592 DPRINTF (("copy: %s", uentry_unparseFull (e)));
8593 uentry_copyInto (enew, e);
8594 DPRINTF (("Here we are..."));
8595 DPRINTF (("original: %s", uentry_unparseFull (e)));
8596 DPRINTF (("copy: %s", uentry_unparse (enew)));
8597 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
8602 return uentry_undefined;
8607 uentry_setState (uentry res, uentry other)
8609 llassert (uentry_isValid (res));
8610 llassert (uentry_isValid (other));
8612 llassert (res->ukind == other->ukind);
8613 llassert (res->ukind == KVAR);
8615 res->sref = sRef_saveCopy (other->sref);
8616 res->used = other->used;
8617 filelocList_free (res->uses);
8618 res->uses = other->uses;
8619 other->uses = filelocList_undefined;
8620 res->lset = other->lset;
8624 uentry_mergeUses (uentry res, uentry other)
8626 llassert (uentry_isValid (res));
8627 llassert (uentry_isValid (other));
8629 res->used = other->used || res->used;
8630 res->lset = other->lset || res->lset;
8631 res->uses = filelocList_append (res->uses, other->uses);
8632 other->uses = filelocList_undefined;
8637 ** This is a really ugly routine.
8639 ** gack...fix this one day.
8644 ** >> res is the false branch, other is the true branch (or continuation)
8646 ** >> res is the true branch, other is the false branch (or continutation)
8653 ** References not effected by res are propagated from other.
8657 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
8658 bool flip, clause cl, fileloc loc)
8662 message ("%s %q is %s %s, but %s %s.",
8663 ekind_capName (res->ukind), uentry_getName (res),
8664 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
8665 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
8668 if (sRef_isDead (res->sref))
8670 sRef_showStateInfo (res->sref);
8672 else if (sRef_isKept (res->sref))
8674 sRef_showAliasInfo (res->sref);
8676 else /* dependent */
8678 sRef_showAliasInfo (res->sref);
8679 sRef_showAliasInfo (other->sref);
8682 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8686 static bool incompatibleStates (sRef rs, sRef os)
8688 alkind rk = sRef_getAliasKind (rs);
8689 alkind ok = sRef_getAliasKind (os);
8691 if (alkind_isError (rk) || alkind_isError (ok))
8697 return ((sRef_isDead (rs)
8698 || (alkind_isKept (rk) && !alkind_isKept (ok))
8699 || (alkind_isDependent (rk)
8700 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
8701 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
8706 branchStateAltError (/*@notnull@*/ uentry res,
8707 /*@notnull@*/ uentry other, bool flip,
8708 clause cl, fileloc loc)
8712 message ("%s %q is %s %s, but %s %s.",
8713 ekind_capName (res->ukind), uentry_getName (res),
8714 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
8715 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
8718 if (sRef_isDead (other->sref))
8720 sRef_showStateInfo (other->sref);
8724 sRef_showAliasInfo (other->sref);
8727 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8728 sRef_setDefinedComplete (res->sref, fileloc_undefined);
8730 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
8731 sRef_setDefinedComplete (other->sref, fileloc_undefined);
8735 static bool notNull (sRef sr, bool flip)
8737 return (!sRef_definitelyNull (sr)
8738 && !(sRef_isKept (sr))
8739 && !(sRef_isDependent (sr))
8740 && !(flip ? usymtab_isProbableDeepNull (sr)
8741 : usymtab_isAltProbablyDeepNull (sr)));
8745 uentry_mergeState (uentry res, uentry other, fileloc loc,
8746 bool mustReturn, bool flip, bool opt,
8749 llassert (uentry_isValid (res));
8750 llassert (uentry_isValid (other));
8752 llassert (res->ukind == other->ukind);
8753 llassert (res->ukind == KVAR);
8755 DPRINTF (("Merge state: %s / %s",
8756 uentry_unparse (res),
8757 uentry_unparse (other)));
8759 if (sRef_isValid (res->sref))
8763 if (incompatibleStates (res->sref, other->sref))
8765 if (sRef_isThroughArrayFetch (res->sref)
8766 && !context_getFlag (FLG_STRICTBRANCHSTATE))
8768 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
8770 sRef_maybeKill (res->sref, loc);
8772 else if (sRef_isPossiblyDead (other->sref))
8774 sRef_maybeKill (res->sref, loc);
8783 if (notNull (other->sref, flip))
8785 if (sRef_isLocalParamVar (res->sref)
8786 && (sRef_isLocalState (other->sref)
8787 || sRef_isDependent (other->sref)))
8789 if (sRef_isDependent (res->sref))
8791 sRef_setDependent (other->sref, loc);
8795 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8800 branchStateError (res, other, flip, cl, loc);
8805 if (sRef_isKept (res->sref))
8807 sRef_setKept (other->sref, loc);
8812 if (incompatibleStates (other->sref, res->sref))
8814 if (notNull (res->sref, !flip))
8816 if (sRef_isLocalParamVar (res->sref)
8817 && (sRef_isDependent (res->sref)
8818 || sRef_isLocalState (res->sref)))
8820 if (sRef_isDependent (other->sref))
8822 sRef_setDependent (res->sref, loc);
8826 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8831 if (sRef_isParam (other->sref))
8834 ** If the local variable associated
8835 ** with the param has the correct state,
8837 ** (e.g., free (s); s = new(); ...
8840 uentry uvar = usymtab_lookupSafe (other->uname);
8842 if (uentry_isValid (uvar)
8843 && ((sRef_isDead (other->sref)
8844 && sRef_isOnly (uvar->sref))
8845 || (sRef_isDependent (other->sref)
8846 && sRef_isOwned (uvar->sref))))
8852 branchStateAltError (res, other,
8858 branchStateAltError (res, other,
8865 if (sRef_isKept (other->sref))
8867 sRef_setKept (res->sref, loc);
8873 DPRINTF (("Merge opt..."));
8874 sRef_mergeOptState (res->sref, other->sref, cl, loc);
8875 DPRINTF (("Done!"));
8879 sRef_mergeState (res->sref, other->sref, cl, loc);
8884 if (sRef_isModified (other->sref))
8886 sRef_setModified (res->sref);
8890 if (cl == DOWHILECLAUSE)
8892 res->used = other->used || res->used;
8893 res->lset = other->lset || res->lset;
8894 res->uses = filelocList_append (res->uses, other->uses);
8895 other->uses = filelocList_undefined;
8899 if (sRef_isMacroParamRef (res->sref)
8900 && !uentry_isSefParam (other)
8901 && !uentry_isSefParam (res))
8903 bool hasError = FALSE;
8905 if (bool_equal (res->used, other->used))
8907 res->used = other->used;
8911 if (other->used && !flip)
8916 message ("Macro parameter %q used in true clause, "
8917 "but not in false clause",
8918 uentry_getName (res)),
8919 uentry_whereDeclared (res));
8926 message ("Macro parameter %q used in false clause, "
8927 "but not in true clause",
8928 uentry_getName (res)),
8929 uentry_whereDeclared (res));
8935 /* make it sef now, prevent more errors */
8936 res->info->var->kind = VKREFSEFPARAM;
8942 res->used = other->used || res->used;
8943 res->lset = other->lset || res->lset;
8944 res->uses = filelocList_append (res->uses, other->uses);
8945 other->uses = filelocList_undefined;
8951 void uentry_setUsed (uentry e, fileloc loc)
8953 static bool firstTime = TRUE;
8954 static bool showUses = FALSE;
8955 static bool exportLocal = FALSE;
8959 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
8961 showUses = context_getFlag (FLG_SHOWUSES);
8962 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
8967 if (uentry_isValid (e))
8971 if (sRef_isMacroParamRef (e->sref))
8973 if (uentry_isYield (e) || uentry_isSefParam (e))
8979 if (context_inConditional ())
8983 message ("Macro parameter %q used in conditionally "
8984 "executed code (may or may not be "
8985 "evaluated exactly once)",
8986 uentry_getName (e)),
8989 e->info->var->kind = VKREFSEFPARAM;
8998 message ("Macro parameter %q used more than once",
8999 uentry_getName (e)),
9000 uentry_whereDeclared (e)))
9002 e->info->var->kind = VKREFSEFPARAM;
9009 if ((dp = uentry_directParamNo (e)) >= 0)
9011 uentry_setUsed (usymtab_getParam (dp), loc);
9016 if (!sRef_isLocalVar (e->sref))
9020 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
9026 if (context_inMacro ())
9028 e->uses = filelocList_addUndefined (e->uses);
9032 e->uses = filelocList_addDifferentFile
9034 uentry_whereDeclared (e),
9043 bool uentry_isReturned (uentry u)
9045 return (uentry_isValid (u) && uentry_isVar (u)
9046 && (u->info->var->kind == VKRETPARAM
9047 || u->info->var->kind == VKSEFRETPARAM));
9050 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
9052 llassert (uentry_isRealFunction (u));
9054 if (ctype_isFunction (u->utype)
9055 && sRef_isStateSpecial (uentry_getSref (u)))
9057 specialClauses clauses = uentry_getSpecialClauses (u);
9058 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9060 sRef_setAllocated (res, g_currentloc);
9062 specialClauses_postElements (clauses, cl)
9064 sRefSet refs = specialClause_getRefs (cl);
9065 sRefMod modf = specialClause_getEffectFunction (cl);
9067 sRefSet_elements (refs, el)
9069 sRef base = sRef_getRootBase (el);
9071 if (sRef_isResult (base))
9075 sRef sr = sRef_fixBase (el, res);
9076 modf (sr, g_currentloc);
9083 } end_sRefSet_elements ;
9085 } end_specialClauses_postElements ;
9093 sRefSet prefs = sRefSet_new ();
9094 sRef res = sRef_undefined;
9097 params = uentry_getParams (u);
9099 uentryList_elements (params, current)
9101 if (uentry_isReturned (current))
9103 if (exprNodeList_size (args) >= paramno)
9105 exprNode ecur = exprNodeList_nth (args, paramno);
9106 sRef tref = exprNode_getSref (ecur);
9108 if (sRef_isValid (tref))
9110 sRef tcref = sRef_copy (tref);
9112 if (sRef_isDead (tcref))
9114 sRef_setDefined (tcref, g_currentloc);
9115 sRef_setOnly (tcref, g_currentloc);
9118 if (sRef_isRefCounted (tcref))
9120 /* could be a new ref now (but only if its returned) */
9121 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
9124 sRef_makeSafe (tcref);
9126 prefs = sRefSet_insert (prefs, tcref);
9132 } end_uentryList_elements ;
9134 if (sRefSet_size (prefs) > 0)
9136 nstate n = sRef_getNullState (u->sref);
9138 if (sRefSet_size (prefs) == 1)
9140 res = sRefSet_choose (prefs);
9144 res = sRefSet_mergeIntoOne (prefs);
9147 if (nstate_isKnown (n))
9149 sRef_setNullState (res, n, g_currentloc);
9154 if (ctype_isFunction (u->utype))
9156 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9160 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
9163 if (sRef_isRefCounted (res))
9165 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9169 if (sRef_getNullState (res) == NS_ABSNULL)
9171 ctype ct = ctype_realType (u->utype);
9173 if (ctype_isAbstract (ct))
9175 sRef_setNotNull (res, g_currentloc);
9179 if (ctype_isUser (ct))
9181 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
9185 sRef_setNotNull (res, g_currentloc);
9190 if (sRef_isRefCounted (res))
9192 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9194 else if (sRef_isKillRef (res))
9196 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
9203 ak = sRef_getAliasKind (res);
9205 if (alkind_isImplicit (ak))
9207 sRef_setAliasKind (res,
9208 alkind_fixImplicit (ak),
9212 sRefSet_free (prefs);
9218 static bool uentry_isRefCounted (uentry ue)
9220 ctype ct = uentry_getType (ue);
9222 if (ctype_isFunction (ct))
9224 return (ctype_isRefCounted (ctype_returnValue (ct)));
9228 return (ctype_isRefCounted (ct));
9233 ** old was declared yield in the specification.
9234 ** new is declared in the iter implementation.
9237 void uentry_checkYieldParam (uentry old, uentry unew)
9241 llassert (uentry_isVariable (old));
9242 llassert (uentry_isVariable (unew));
9244 unew->info->var->kind = VKYIELDPARAM;
9245 (void) checkTypeConformance (old, unew, TRUE);
9246 checkVarConformance (old, unew, TRUE, FALSE);
9248 /* get rid of param marker */
9250 name = uentry_getName (unew);
9251 cstring_free (unew->uname);
9253 unew->info->var->kind = VKREFYIELDPARAM;
9255 uentry_setUsed (old, fileloc_undefined);
9256 uentry_setUsed (unew, fileloc_undefined);
9259 /*@observer@*/ cstring
9260 uentry_ekindName (uentry ue)
9262 if (uentry_isValid (ue))
9267 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
9269 return cstring_makeLiteralTemp ("Datatype");
9271 return cstring_makeLiteralTemp ("Enum member");
9273 return cstring_makeLiteralTemp ("Constant");
9275 if (uentry_isParam (ue))
9277 return cstring_makeLiteralTemp ("Parameter");
9279 else if (uentry_isExpandedMacro (ue))
9281 return cstring_makeLiteralTemp ("Expanded macro");
9285 return cstring_makeLiteralTemp ("Variable");
9288 return cstring_makeLiteralTemp ("Function");
9290 return cstring_makeLiteralTemp ("Iterator");
9292 return cstring_makeLiteralTemp ("Iterator finalizer");
9294 return cstring_makeLiteralTemp ("Struct tag");
9296 return cstring_makeLiteralTemp ("Union tag");
9298 return cstring_makeLiteralTemp ("Enum tag");
9300 return cstring_makeLiteralTemp ("Optional parameters");
9305 return cstring_makeLiteralTemp ("<Undefined>");
9311 void uentry_setHasNameError (uentry ue)
9313 llassert (uentry_isValid (ue));
9315 ue->hasNameError = TRUE;
9318 void uentry_checkName (uentry ue)
9320 if (uentry_isValid (ue)
9321 && !uentry_isElipsisMarker (ue)
9322 && context_getFlag (FLG_NAMECHECKS)
9323 && !ue->hasNameError
9324 && !uentry_isEndIter (ue)
9325 && !fileloc_isBuiltin (uentry_whereLast (ue))
9326 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
9329 if (uentry_isPriv (ue))
9331 ; /* any checks here? */
9333 else if (fileloc_isExternal (uentry_whereDefined (ue)))
9335 ; /* no errors for externals */
9341 if (uentry_isExpandedMacro (ue))
9347 if (uentry_isExpandedMacro (ue))
9351 else if (uentry_isVariable (ue))
9353 sRef sr = uentry_getSref (ue);
9355 if (sRef_isValid (sr))
9357 scope = sRef_getScope (sr);
9364 else if (uentry_isFunction (ue)
9365 || uentry_isIter (ue)
9366 || uentry_isEndIter (ue)
9367 || uentry_isConstant (ue))
9369 scope = uentry_isStatic (ue) ? fileScope : globScope;
9371 else /* datatypes, etc. must be global */
9376 usymtab_checkDistinctName (ue, scope);
9379 if (context_getFlag (FLG_CPPNAMES))
9381 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
9383 uentry_setHasNameError (ue);
9387 if (scope == globScope)
9389 checkGlobalName (ue);
9391 if (context_getFlag (FLG_ANSIRESERVED))
9393 if (uentry_hasName (ue)
9394 && !uentry_isAnyTag (ue))
9396 if (checkAnsiName (uentry_rawName (ue),
9397 uentry_whereLast (ue)))
9399 uentry_setHasNameError (ue);
9406 checkLocalName (ue);
9408 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
9410 if (uentry_hasName (ue)
9411 && !uentry_isAnyTag (ue))
9413 if (checkAnsiName (uentry_rawName (ue),
9414 uentry_whereLast (ue)))
9416 uentry_setHasNameError (ue);
9422 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
9428 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
9434 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
9435 if (!context_inMacro ())
9437 sRef_setGlobalScopeSafe ();
9440 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
9441 uentry_setUsed (ue, loc);
9443 tloc = fileloc_createExternal ();
9444 uentry_setDefined (ue, tloc);
9445 fileloc_free (tloc);
9446 uentry_setHasNameError (ue);
9448 if (context_getFlag (FLG_REPEATUNRECOG))
9450 uentry_markOwned (ue);
9454 ue = usymtab_supReturnFileEntry (ue);
9457 if (!context_inMacro ())
9459 sRef_clearGlobalScopeSafe ();
9466 /* start modifications */
9468 requires: p_e is defined, is a ptr/array variable
9470 effects: sets the state of the variable
9473 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
9474 if( uentry_isValid(p_e) ) {
9475 if( p_e->info != NULL) {
9476 if( p_e->info->var != NULL) {
9477 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
9478 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9484 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
9488 requires: p_e is defined, is a ptr/array variable
9490 effects: sets the size of the buffer
9493 void uentry_setNullTerminatedState (uentry p_e) {
9494 if( uentry_isValid(p_e) ) {
9495 if( p_e->info != NULL) {
9496 if( p_e->info->var != NULL) {
9497 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
9498 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
9504 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
9509 requires: p_e is defined, is a ptr/array variable
9511 effects: sets the state of the variable
9514 void uentry_setNotNullTerminatedState (uentry p_e) {
9515 if( uentry_isValid(p_e) ) {
9516 if( p_e->info != NULL) {
9517 if( p_e->info->var != NULL) {
9518 p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
9519 p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED;
9525 fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n");
9530 requires: p_e is defined, is a ptr/array variable
9532 effects: sets the size of the buffer
9535 void uentry_setSize (uentry p_e, int size) {
9536 if( uentry_isValid(p_e) ) {
9537 if( p_e->info != NULL) {
9538 if( p_e->info->var != NULL) {
9539 p_e->info->var->bufinfo->size = size;
9540 p_e->sref->bufinfo.size = size;
9546 fprintf(stderr, "uentry:Error in setSize\n");
9551 requires: p_e is defined, is a ptr/array variable
9553 effects: sets the length of the buffer
9556 void uentry_setLen (uentry p_e, int len) {
9557 if( uentry_isValid(p_e) ) {
9558 if( p_e->info != NULL) {
9559 if( p_e->info->var != NULL) {
9560 p_e->info->var->bufinfo->len = len;
9561 p_e->sref->bufinfo.len = len;
9567 fprintf(stderr, "uentry:Error in setLen\n");