2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 # include "splintMacros.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);
46 static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_warningstream@*/ ;
48 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
51 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
55 static void checkAliasState (/*@notnull@*/ uentry p_old,
56 /*@notnull@*/ uentry p_unew,
57 bool p_mustConform, bool p_completeConform)
58 /*@modifies p_old, p_unew@*/ ;
59 static void checkNullState (/*@notnull@*/ uentry p_old,
60 /*@notnull@*/ uentry p_unew,
61 bool p_mustConform, bool p_completeConform)
62 /*@modifies p_old, p_unew@*/ ;
64 static void checkVarConformance (/*@notnull@*/ uentry p_old,
65 /*@notnull@*/ uentry p_unew,
66 bool p_mustConform, bool p_completeConform)
67 /*@modifies p_old, p_unew@*/;
69 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
70 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
72 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
74 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
75 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
78 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
79 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
80 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
81 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
82 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
84 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
85 ctype p_oldType, /*@notnull@*/ uentry p_unew,
86 /*@notnull@*/ uentry p_newCurrent,
87 ctype p_newType, int p_paramno) /*@modifies g_warningstream@*/ ;
89 static /*@only@*/ /*@notnull@*/ uentry
90 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
91 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
93 static /*@only@*/ /*@notnull@*/ uentry
94 uentry_makeConstantAux (cstring p_n, ctype p_t,
95 /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
96 /*@only@*/ multiVal p_m) /*@*/ ;
98 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
100 if (uentry_isVariable (ue)
101 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
102 || ctype_isUnknown (uentry_getType (ue))))
104 uentry_makeVarFunction (ue);
108 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
110 uentry ue = (uentry) dmalloc (sizeof (*ue));
111 ue->warn = warnClause_undefined; /*@i32@*/
118 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
119 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
121 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
122 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
123 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
124 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
125 static void ucinfo_free (/*@only@*/ ucinfo p_u);
126 static void uvinfo_free (/*@only@*/ uvinfo p_u);
130 static /*@only@*/ cstring ancontext_unparse (ancontext an)
134 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
135 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
136 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
137 case AN_SUFIELD: return cstring_makeLiteral ("su field");
138 case AN_TDEFN: return cstring_makeLiteral ("type definition");
139 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
140 case AN_CONST: return cstring_makeLiteral ("constant");
146 static int annots[AN_LAST][QU_LAST];
147 static int decls[AN_LAST];
148 static int shdecls[AN_LAST];
149 static int idecls[AN_LAST];
155 for (i = AN_UNKNOWN; i < AN_LAST; i++)
161 for (j = QU_UNKNOWN; j < QU_LAST; j++)
168 static void tallyAnnot (ancontext ac, qual q)
182 for (j = QU_UNKNOWN; j < QU_LAST; j++)
187 for (i = AN_UNKNOWN; i < AN_LAST; i++)
193 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
194 ancontext_unparse (i),
195 decls[i], shdecls[i], idecls[i]);
197 totdecls += decls[i];
198 totshdecls += shdecls[i];
199 totidecls += idecls[i];
201 for (j = QU_UNKNOWN; j < QU_LAST; j++)
203 total[j] += annots[i][j];
204 alltotals += annots[i][j];
207 printf (" Allocation:\n");
211 for (j = QU_UNKNOWN; j < QU_LAST; j++)
213 if (qual_isAliasQual (j) && !qual_isUnique (j))
215 if (annots[i][j] > 0)
217 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
218 100.0 * (double)annots[i][j] / (double)decls[i]);
219 tmptot += annots[i][j];
224 printf (" Exposure:\n");
228 for (j = QU_UNKNOWN; j < QU_LAST; j++)
230 if (qual_isExQual (j))
232 if (annots[i][j] > 0)
234 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
235 100.0 * (double)annots[i][j] / (double)decls[i]);
236 tmptot += annots[i][j];
241 printf (" Definition:\n");
243 for (j = QU_UNKNOWN; j < QU_LAST; j++)
245 if (qual_isAllocQual (j))
247 if (annots[i][j] > 0)
249 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
250 100.0 * (double)annots[i][j] / (double)decls[i]);
257 for (j = QU_UNKNOWN; j < QU_LAST; j++)
259 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
261 if (annots[i][j] > 0)
263 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
264 100.0 * (double)annots[i][j] / (double)decls[i]);
273 for (j = QU_UNKNOWN; j < QU_LAST; j++)
277 for (i = AN_UNKNOWN; i < AN_LAST; i++)
279 if (annots[i][j] > 0)
288 printf ("Annotation: %s\n", qual_unparse (j));
290 for (i = AN_UNKNOWN; i < AN_LAST; i++)
292 if (annots[i][j] > 0)
294 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
301 printf ("All Contexts\n");
303 for (j = QU_UNKNOWN; j < QU_LAST; j++)
307 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
308 100.0 * (double)total[j] / (double)(totdecls));
313 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
315 extern void uentry_tallyAnnots (uentry u, ancontext kind)
317 alkind ak = sRef_getAliasKind (u->sref);
318 exkind ek = sRef_getExKind (u->sref);
319 nstate ns = sRef_getNullState (u->sref);
320 sstate ss = sRef_getDefState (u->sref);
321 bool recordUnknown = FALSE;
323 if (kind == AN_UNKNOWN)
331 else if (e == KCONST || e == KENUMCONST)
335 else if (e == KFCN || e == KITER)
337 uentryList params = uentry_getParams (u);
340 uentryList_elements (params, current)
342 if (uentry_isReturned (current))
346 if (!uentry_isElipsisMarker (current))
348 uentry_tallyAnnots (current, AN_FCNPARAM);
350 } end_uentryList_elements;
354 if (ctype_isFunction (u->utype)
356 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
358 recordUnknown = TRUE;
361 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
363 ctype t = ctype_realType (u->utype);
367 uentryList fields = ctype_getFields (t);
369 uentryList_elements (fields, current)
371 uentry_tallyAnnots (current, AN_SUFIELD);
373 } end_uentryList_elements;
377 if (ctype_isVisiblySharable (u->utype))
379 recordUnknown = TRUE;
387 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
389 recordUnknown = TRUE;
396 if (kind == AN_FCNRETURN)
410 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
415 if (ctype_isRealPointer (ctype_realType (u->utype)))
423 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
424 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
425 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
426 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
430 if (uentry_isReturned (u))
432 tallyAnnot (kind, QU_RETURNED);
438 if (ctype_isRefCounted (ctype_realType (u->utype))
439 || (ctype_isFunction (u->utype) &&
440 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
446 if (kind == AN_FCNPARAM)
448 tallyAnnot (kind, QU_TEMP);
450 else if (recordUnknown)
452 if (kind == AN_FCNRETURN)
455 tallyAnnot (kind, QU_UNKNOWN);
459 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
460 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
461 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
462 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
464 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
465 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
466 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
467 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
468 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
469 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
470 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
471 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
472 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
473 case AK_IMPDEPENDENT:
474 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
484 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
485 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
491 case NS_ERROR: break;
492 case NS_UNKNOWN: break;
493 case NS_NOTNULL: break;
494 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
495 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
496 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
497 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
499 case NS_ABSNULL: break;
505 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
509 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
510 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
511 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
512 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
513 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
519 static specCode specCode_fromInt (int i)
522 llassert (i >= SPC_NONE && i < SPC_LAST);
524 return ((specCode) i);
528 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
530 if (uentry_isDeclared (u))
532 return cstring_makeLiteralTemp ("previously declared");
536 return cstring_makeLiteralTemp ("specified");
540 /*@observer@*/ cstring uentry_specDeclName (uentry u)
542 if (uentry_isDeclared (u))
544 return cstring_makeLiteralTemp ("previous declaration");
548 return cstring_makeLiteralTemp ("specification");
552 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
554 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
556 return cstring_makeLiteralTemp ("redefined");
558 else if (uentry_isCodeDefined (unew))
560 return cstring_makeLiteralTemp ("defined");
562 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
564 return cstring_makeLiteralTemp ("redeclared");
568 return cstring_makeLiteralTemp ("declared");
572 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
574 if (uentry_isValid (ue))
576 functionConstraint constraint;
578 DPRINTF((message ("called uentry_getFcnPostconditions on %s",
579 uentry_unparse (ue) ) ) );
581 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
583 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
584 uentry_unparse (ue) ) ) );
585 if (!uentry_isFunction (ue) )
587 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
588 uentry_unparse (ue) ) ));
589 return constraintList_undefined;
593 return constraintList_undefined;
596 if (!uentry_isFunction(ue))
599 DPRINTF((message ("called uentry_getFunctionConditions on non function %s",
600 uentry_unparse (ue) ) ) );
601 return constraintList_undefined;
605 llassert (uentry_isFunction (ue));
609 constraint = ue->info->fcn->postconditions;
613 constraint = ue->info->fcn->preconditions;
616 return functionConstraint_getBufferConstraints (constraint);
619 return constraintList_undefined;
624 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
626 return uentry_getFunctionConditions (ue, FALSE);
633 constraintList uentry_getFcnPostconditions (uentry ue)
635 return uentry_getFunctionConditions (ue, TRUE);
638 static /*@only@*/ fileloc setLocation (void)
640 fileloc fl = context_getSaveLocation ();
642 if (fileloc_isDefined (fl))
648 return fileloc_copy (g_currentloc);
652 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
654 llassert (uentry_isEitherConstant (ue));
655 sRef_setValue (ue->sref, val);
658 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
660 fileloc loc = setLocation ();
661 uentry ue = uentry_makeConstant (n, t, loc);
663 ue->ukind = KENUMCONST;
664 uentry_setDefined (ue, loc);
668 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
670 fileloc loc = setLocation ();
671 uentry ue = uentry_makeConstant (n, t, loc);
672 ctype etype = exprNode_getType (expr);
674 if (!ctype_isRealInt (etype)) {
678 ("Value of enum member is not an integeral type (type %s): %s",
679 ctype_unparse (etype), exprNode_unparse (expr)),
680 exprNode_loc (expr));
683 ue->ukind = KENUMCONST;
684 uentry_setDefined (ue, loc);
688 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
690 uentry ue = uentry_makeConstant (n, t, loc);
692 ue->ukind = KENUMCONST;
696 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
698 return uentry_makeVariable (n, t, setLocation (), FALSE);
701 bool uentry_isUnnamedVariable (uentry ue)
703 return uentry_isVariable (ue) && cstring_isUndefined (ue->uname);
706 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
708 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
711 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
713 ctype ct = idDecl_getCtype (id);
714 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
715 MAYBE, MAYBE, setLocation ());
717 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
719 if (!ynm_isOn (ue->info->datatype->abs))
721 if (ctype_isUnknown (ct))
723 ue->info->datatype->mut = MAYBE;
727 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
734 void uentry_checkParams (uentry ue)
736 if (uentry_isValid (ue))
738 bool isExt = uentry_isExtern (ue);
740 if (uentry_isRealFunction (ue))
742 uentryList params = uentry_getParams (ue);
745 uentryList_elements (params, current)
749 if (uentry_isValid (current))
751 ctype ct = current->utype;
753 if (ctype_isFixedArray (ct))
755 if (ctype_isArray (ctype_baseArrayPtr (ct))
756 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
762 if (uentry_hasName (current))
765 (FLG_FIXEDFORMALARRAY,
766 message ("Function parameter %q declared as "
767 "manifest array (size constant is meaningless)",
768 uentry_getName (current)),
769 uentry_whereDeclared (current));
774 (FLG_FIXEDFORMALARRAY,
775 message ("Unnamed function parameter %d declared as "
776 "manifest array (size constant is meaningless)",
778 uentry_whereDeclared (current));
784 if (ctype_isArray (ct))
786 if (uentry_hasName (current))
790 message ("Function parameter %q declared as "
791 "array (treated as pointer)",
792 uentry_getName (current)),
793 uentry_whereDeclared (current));
799 message ("Unnamed function parameter %d declared as "
800 "array (treated as pointer)",
802 uentry_whereDeclared (current));
807 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
809 if (ctype_isAbstract (ct) &&
810 (isExt || (ctype_isAbstract (ctype_realType (ct))
811 && !context_hasFileAccess (ctype_typeId (ct)))))
816 ("Function %q declared with notnull parameter %q of abstract "
819 uentry_getName (current),
822 ("Since %s is an abstract type, notnull can only be "
823 "used for parameters if the function is static to a "
824 "module where %s is accessible.",
827 uentry_whereDeclared (current));
831 } end_uentryList_elements;
833 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
835 ctype ct = ue->utype;
837 if (ctype_isAbstract (ct)
838 && (isExt || (ctype_isAbstract (ctype_realType (ct))
839 && !context_hasFileAccess (ctype_typeId (ct)))))
844 ("%s %q declared %s notnull storage of abstract type %s",
845 ekind_capName (uentry_getKind (ue)),
850 ("Since %s is an abstract type, notnull can only be used "
851 "if it is static to a module where %s is accessible.",
854 uentry_whereDeclared (ue));
861 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
863 alkind ak = sRef_getAliasKind (ue->sref);
865 if (alkind_isRefCounted (ak))
867 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
871 if (alkind_isUnknown (ak))
873 exkind ek = sRef_getExKind (ue->sref);
875 if (exkind_isKnown (ek))
877 DPRINTF (("Setting imp dependent: %s",
878 uentry_unparseFull (ue)));
879 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
883 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
885 /* evans 2000-12-22 removed ctype_realType so it will
886 not apply to immutable abstract types. */
888 if (ctype_isVisiblySharable
889 (ctype_realType (ctype_getReturnType (ue->utype))))
891 if (uentryList_hasReturned (uentry_getParams (ue)))
897 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
899 ; /* Immutable objects are not shared. */
903 sRef_setAliasKind (ue->sref, AK_IMPONLY,
905 DPRINTF (("Ret imp only: %s",
906 ctype_unparse (ctype_getReturnType (ue->utype))));
916 static /*@notnull@*/ uentry
917 uentry_makeFunctionAux (cstring n, ctype t,
919 /*@only@*/ globSet globs,
920 /*@only@*/ sRefSet mods,
921 /*@only@*/ warnClause warn,
922 /*@keep@*/ fileloc f, bool priv,
923 /*@unused@*/ bool isForward)
925 uentry e = uentry_alloc ();
928 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
930 DPRINTF (("Make function: %s", n));
932 if (ctype_isFunction (t))
934 ret = ctype_getReturnType (t);
938 if (ctype_isKnown (t))
940 llbug (message ("not function: %s", ctype_unparse (t)));
947 if (fileloc_isSpec (f) || fileloc_isImport (f))
949 e->whereSpecified = f;
950 e->whereDeclared = fileloc_undefined;
954 e->whereSpecified = fileloc_undefined;
955 e->whereDeclared = f;
958 /* e->shallowCopy = FALSE; */
959 e->uname = cstring_copy (n);
961 e->storageclass = SCNONE;
963 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
965 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
967 if (ctype_isUA (ret))
969 sRef_setStateFromType (e->sref, ret);
974 e->uses = filelocList_new ();
976 e->hasNameError = FALSE;
980 e->info = (uinfo) dmalloc (sizeof (*e->info));
981 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
983 e->info->fcn->hasMods = sRefSet_isDefined (mods);
984 e->info->fcn->hasGlobs = globSet_isDefined (globs);
986 e->info->fcn->exitCode = XK_UNKNOWN;
987 e->info->fcn->nullPred = qual_createUnknown ();
988 e->info->fcn->specialCode = SPC_NONE;
990 e->info->fcn->access = access;
991 e->info->fcn->globs = globs;
992 e->info->fcn->defparams = uentryList_undefined;
994 sRef_setDefined (e->sref, f);
995 e->whereDefined = fileloc_undefined;
997 e->info->fcn->mods = sRefSet_undefined;
998 e->info->fcn->specclauses = NULL;
1001 e->info->fcn->preconditions = NULL;
1005 e->info->fcn->postconditions = NULL;
1008 checkGlobalsModifies (e, mods);
1009 e->info->fcn->mods = mods;
1014 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
1016 functionClauseList_elements (clauses, el)
1018 DPRINTF (("Reflect clause: %s on %s",
1019 functionClause_unparse (el), uentry_getName (ue)));
1021 if (functionClause_isNoMods (el))
1023 modifiesClause mel = functionClause_getModifies (el);
1025 if (uentry_hasGlobs (ue))
1030 ("No globals and modifies inconsistent to globals clause for %q: %q",
1031 uentry_getName (ue),
1032 globSet_unparse (uentry_getGlobs (ue))),
1033 modifiesClause_getLoc (mel));
1037 if (uentry_hasMods (ue))
1042 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1043 uentry_getName (ue),
1044 sRefSet_unparse (uentry_getMods (ue))),
1045 modifiesClause_getLoc (mel));
1048 uentry_setGlobals (ue, globSet_undefined);
1049 uentry_setModifies (ue, sRefSet_undefined);
1051 else if (functionClause_isGlobals (el))
1053 globalsClause glc = functionClause_getGlobals (el);
1055 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1056 globalsClause_unparse (glc)));
1058 if (uentry_hasGlobs (ue))
1063 ("Multiple globals clauses for %q: %q",
1064 uentry_getName (ue),
1065 globalsClause_unparse (glc)),
1066 globalsClause_getLoc (glc));
1067 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1071 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1072 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1073 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1076 else if (functionClause_isModifies (el))
1078 modifiesClause mlc = functionClause_getModifies (el);
1080 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1082 if (uentry_hasMods (ue))
1090 ("Multiple modifies clauses for %s: %s",
1091 uentry_getName (ue),
1092 modifiesClause_unparse (mlc)),
1093 modifiesClause_getLoc (mlc)))
1095 llhint (message ("Previous modifies clause: ",
1096 sRefSet_unparse (uentry_getMods (ue))));
1102 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1106 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1109 else if (functionClause_isEnsures (el))
1111 functionConstraint cl = functionClause_takeEnsures (el);
1112 DPRINTF (("Setting post: %s / %s",
1113 uentry_unparse (ue), functionConstraint_unparse (cl)));
1114 uentry_setPostconditions (ue, cl);
1116 else if (functionClause_isRequires (el))
1118 functionConstraint cl = functionClause_takeRequires (el);
1119 uentry_setPreconditions (ue, cl);
1121 else if (functionClause_isState (el))
1123 stateClause sc = functionClause_takeState (el);
1125 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1127 sRefSet rfs = stateClause_getRefs (sc);
1129 sRefSet_elements (rfs, s)
1131 if (sRef_isParam (s))
1134 ** Can't use requires on parameters
1138 (FLG_ANNOTATIONERROR,
1139 message ("Requires clauses for %q concerns parameters %q should be "
1140 "a parameter annotation instead: %q",
1141 uentry_unparse (ue),
1143 stateClause_unparse (sc)),
1144 stateClause_loc (sc));
1146 } end_sRefSet_elements ;
1149 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1150 uentry_addStateClause (ue, sc);
1152 else if (functionClause_isWarn (el))
1154 warnClause wc = functionClause_takeWarn (el);
1155 uentry_addWarning (ue, wc);
1159 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1161 } end_functionClauseList_elements ;
1163 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1164 stateClauseList_checkAll (ue);
1167 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1169 bool leaveFunc = FALSE;
1171 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1172 typeId_invalid, globSet_undefined,
1173 sRefSet_undefined, warnClause_undefined,
1176 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1179 ** This makes parameters names print out correctly.
1180 ** (But we might be a local variable declaration for a function type...)
1183 if (context_inFunctionLike ())
1185 DPRINTF (("Header: %s / %s",
1186 uentry_unparse (context_getHeader ()),
1187 idDecl_unparse (id)));
1191 context_enterFunctionDeclaration (ue);
1195 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1196 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1197 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1198 reflectImplicitFunctionQualifiers (ue, FALSE);
1199 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1200 uentry_reflectClauses (ue, idDecl_getClauses (id));
1201 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1203 if (!uentry_isStatic (ue)
1204 && cstring_equalLit (ue->uname, "main"))
1206 ctype typ = ue->utype;
1210 llassert (ctype_isFunction (typ));
1212 retval = ctype_getReturnType (typ);
1214 if (!ctype_isInt (retval))
1218 message ("Function main declared to return %s, should return int",
1219 ctype_unparse (retval)),
1220 uentry_whereDeclared (ue));
1223 args = ctype_argsFunction (typ);
1225 if (uentryList_isMissingParams (args)
1226 || uentryList_size (args) == 0)
1232 if (uentryList_size (args) != 2)
1236 message ("Function main declared with %d arg%&, "
1237 "should have 2 (int argc, char *argv[])",
1238 uentryList_size (args)),
1239 uentry_whereLast (ue));
1243 uentry arg = uentryList_getN (args, 0);
1244 ctype ct = uentry_getType (arg);
1246 if (!ctype_isInt (ct))
1250 message ("Parameter 1, %q, of function main declared "
1251 "with type %t, should have type int",
1252 uentry_getName (arg), ct),
1253 uentry_whereDeclared (arg));
1256 arg = uentryList_getN (args, 1);
1257 ct = uentry_getType (arg);
1259 if (ctype_isArrayPtr (ct)
1260 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1261 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1269 message ("Parameter 2, %q, of function main declared "
1270 "with type %t, should have type char **",
1271 uentry_getName (arg), ct),
1272 uentry_whereDeclared (arg));
1280 context_exitFunctionDeclaration ();
1286 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1288 alkind ak = sRef_getAliasKind (e->sref);
1290 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1291 && context_getFlag (FLG_PARAMIMPTEMP))
1293 exkind ek = sRef_getExKind (e->sref);
1295 if (exkind_isKnown (ek))
1297 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1298 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1299 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1303 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1304 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1309 static /*@only@*/ /*@notnull@*/ uentry
1310 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1311 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1313 cstring pname = makeParam (n);
1316 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1317 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1319 cstring_free (pname);
1320 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1321 uentry_implicitParamAnnots (e);
1322 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1324 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1326 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1327 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1328 e->info->var->defstate = defstate;
1331 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1336 uentry_setRefCounted (uentry e)
1338 if (uentry_isValid (e))
1340 uentry_setAliasKind (e, AK_REFCOUNTED);
1341 sRef_storeState (e->sref);
1346 uentry_setStatic (uentry c)
1348 if (uentry_isValid (c))
1350 alkind ak = sRef_getAliasKind (c->sref);
1351 c->storageclass = SCSTATIC;
1353 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1355 if (!alkind_isUnknown (ak)
1356 && !alkind_isStatic (ak))
1358 if (!(ctype_isRealPointer (uentry_getType (c)))
1359 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1360 && !alkind_isRefCounted (ak))
1362 if (alkind_isImplicit (ak)
1363 && alkind_isDependent (ak)
1364 && ctype_isArray (uentry_getType (c)))
1366 ; /* no error for observer arrays */
1372 message ("Static storage %q declared as %s",
1374 alkind_unparse (ak)),
1375 uentry_whereDeclared (c));
1381 if (alkind_isUnknown (ak)
1382 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1383 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1385 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1386 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1394 uentry_setExtern (uentry c)
1396 if (uentry_isValid (c))
1397 c->storageclass = SCEXTERN;
1401 uentry_setParamNo (uentry ue, int pno)
1403 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1404 sRef_setParamNo (ue->sref, pno);
1408 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1410 sRefSet_allElements (sr, el)
1412 sRef base = sRef_getRootBase (el);
1414 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1415 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1417 if (!globSet_member (ue->info->fcn->globs, base))
1419 if (uentry_hasGlobs (ue)
1420 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1423 (FLG_WARNMISSINGGLOBALS,
1425 ("Modifies list for %q uses global %q, "
1426 "not included in globals list.",
1427 uentry_getName (ue),
1428 sRef_unparse (base)),
1429 uentry_whereLast (ue)))
1431 uentry_showWhereSpecified (ue);
1435 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1437 if (sRef_isFileStatic (base))
1439 context_recordFileGlobals (ue->info->fcn->globs);
1443 } end_sRefSet_allElements;
1447 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1449 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1453 uentry_fixupSref (uentry ue)
1457 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1462 sr = uentry_getSref (ue);
1464 sRef_resetState (sr);
1465 sRef_clearDerived (sr);
1467 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1468 llassert (sRef_isValid (sr));
1470 if (uentry_isVariable (ue))
1473 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1474 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1475 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1479 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1482 ** Okay to allow multiple clauses of the same kind.
1483 */ /*@i834 is this true?@*/
1485 ue->info->fcn->specclauses =
1486 stateClauseList_add (ue->info->fcn->specclauses, sc);
1488 /* Will call checkAll to check later... */
1491 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1493 llassert (uentry_isFunction (ue));
1494 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1496 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1497 ue->info->fcn->specclauses = clauses;
1498 stateClauseList_checkAll (ue);
1499 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1503 ** Used for @modifies@ @endmodifies@ syntax.
1505 ** If ue is specified, sr must contain *only*:
1507 ** o file static globals
1508 ** o sRef's derived from modifies spec (i.e., more specific than
1509 ** what was specified)
1511 ** Otherwise, if sr has modifies it must match sr.
1513 ** If it doesn't have modifies, set them to sr.
1517 uentry_checkModifiesContext (void)
1519 if (sRef_modInFunction ())
1523 ("Modifies list not in function context. "
1524 "A modifies list can only appear following the parameter list "
1525 "in a function declaration or header."));
1534 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1536 if (!uentry_checkModifiesContext ())
1542 if (uentry_isValid (ue))
1544 if (uentry_isIter (ue))
1546 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1547 ue->info->iter->mods = sr;
1551 uentry_convertVarFunction (ue);
1552 llassertfatal (uentry_isFunction (ue));
1553 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1555 ue->info->fcn->mods = sr;
1556 ue->info->fcn->hasMods = TRUE;
1558 checkGlobalsModifies (ue, sr);
1561 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1563 ue->info->fcn->hasGlobs = TRUE;
1566 if (sRefSet_hasStatic (ue->info->fcn->mods))
1568 context_recordFileModifies (ue->info->fcn->mods);
1578 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1581 ** Function already has one modifies clause (possibly from
1582 ** a specification).
1585 if (!uentry_checkModifiesContext ())
1590 llassert (uentry_isValid (ue));
1592 if (uentry_isIter (ue))
1594 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1598 llassertfatal (uentry_isFunction (ue));
1599 llassert (ue->info->fcn->hasMods);
1601 checkGlobalsModifies (ue, sr);
1602 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1604 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1606 ue->info->fcn->hasGlobs = TRUE;
1610 if (sRefSet_hasStatic (ue->info->fcn->mods))
1612 context_recordFileModifies (ue->info->fcn->mods);
1616 bool uentry_hasWarning (uentry ue)
1618 return (uentry_isValid (ue)
1619 && warnClause_isDefined (ue->warn));
1622 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1624 llassert (uentry_isValid (ue));
1625 llassert (warnClause_isUndefined (ue->warn));
1630 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1632 if (sRef_modInFunction ())
1635 (message ("Precondition list not in function context. "
1636 "A precondition list can only appear following the parameter list "
1637 "in a function declaration or header."));
1639 /*@-mustfree@*/ return; /*@=mustfree@*/
1642 if (uentry_isValid (ue))
1644 uentry_convertVarFunction (ue);
1645 llassertfatal (uentry_isFunction (ue));
1647 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1649 /*drl oops this date is wronge...*/
1651 I changed this so it didn't appear as a Splint bug
1652 among other things this gets triggered when there is
1653 a function with two requires clauses. Now Splint
1654 prints an error and tries to conjoin the lists.
1657 (message ("Duplicate precondition list"
1658 "Attemping the conjoin the requires clauses"
1662 /* should conjoin constraints? */
1664 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1668 ue->info->fcn->preconditions = preconditions;
1673 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1682 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1684 if (sRef_modInFunction ())
1687 (message ("Postcondition list not in function context. "
1688 "A postcondition list can only appear following the parameter list "
1689 "in a function declaration or header."));
1691 /*@-mustfree@*/ return; /*@=mustfree@*/
1694 if (uentry_isValid (ue))
1696 uentry_convertVarFunction (ue);
1697 llassertfatal (uentry_isFunction (ue));
1699 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1701 ue->info->fcn->postconditions = postconditions;
1705 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1710 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1715 ** requires: new and old are functions
1719 checkGlobalsConformance (/*@notnull@*/ uentry old,
1720 /*@notnull@*/ uentry unew,
1721 bool mustConform, bool completeConform)
1723 bool hasInternalState = FALSE;
1725 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1727 if (globSet_isDefined (unew->info->fcn->globs))
1729 globSet_allElements (unew->info->fcn->globs, el)
1731 if (sRef_isFileStatic (el))
1733 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1735 if (sRef_isInvalid (sr))
1737 bool hasError = FALSE;
1739 if (!hasInternalState
1740 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1741 sRef_makeInternalState ()))
1742 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1743 sRef_makeSpecState ())))
1746 && !uentry_isStatic (old)
1749 message ("Globals list for %q includes internal state, %q, "
1750 "but %s without globals internalState.",
1751 uentry_getName (old),
1753 uentry_specOrDefName (old)),
1754 uentry_whereLast (unew)))
1756 uentry_showWhereSpecified (old);
1760 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1761 sRef_makeInternalState ());
1762 hasInternalState = TRUE;
1766 && fileloc_sameFile (uentry_whereDeclared (unew),
1767 uentry_whereDeclared (old)))
1772 message ("Function %q inconsistently %rdeclared (in "
1773 "same file) with file static global %q in "
1775 uentry_getName (unew),
1776 uentry_isDeclared (old),
1778 uentry_whereDeclared (unew)))
1780 uentry_showWhereSpecified (old);
1785 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1786 context_recordFileGlobals (old->info->fcn->globs);
1790 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1792 if (sRef_isInvalid (sr))
1797 message ("Function %q inconsistently %rdeclared with "
1798 "%q in globals list",
1799 uentry_getName (unew),
1800 uentry_isDeclared (old),
1802 uentry_whereDeclared (unew)))
1804 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1805 uentry_showWhereSpecified (old);
1810 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1816 ("Function %q global %q inconsistently "
1817 "%rdeclared as %qout global",
1818 uentry_getName (unew),
1820 uentry_isDeclared (old),
1821 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1822 uentry_whereDeclared (unew)))
1824 uentry_showWhereSpecified (old);
1829 } end_globSet_allElements ;
1831 if (completeConform)
1833 globSet_allElements (old->info->fcn->globs, el)
1835 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1837 if (sRef_isInvalid (sr))
1840 && uentry_isReallySpecified (old)
1843 message ("Function %q specified with %q in globals list, "
1844 "but declared without %q",
1845 uentry_getName (unew),
1848 uentry_whereDeclared (unew)))
1850 uentry_showWhereSpecified (old);
1853 } end_globSet_allElements;
1858 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1860 if (uentry_isReallySpecified (old)
1863 message ("%s %q specified with globals list, but "
1864 "declared with no globals",
1865 ekind_capName (unew->ukind),
1866 uentry_getName (unew)),
1867 uentry_whereDeclared (unew)))
1870 (message ("Specification globals: %q",
1871 globSet_unparse (old->info->fcn->globs)),
1872 uentry_whereSpecified (old));
1876 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1877 old->info->fcn->globs);
1882 ** new modifies list must be included by old modifies list.
1884 ** file static state may be added to new, if old has internal.
1888 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1889 bool mustConform, bool completeConform)
1892 bool changedMods = FALSE;
1893 bool modInternal = FALSE;
1895 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1897 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1898 newMods = unew->info->fcn->mods;
1900 if (sRefSet_isEmpty (newMods))
1902 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1903 && uentry_isReallySpecified (old))
1907 message ("%s %q specified with modifies clause, "
1908 "but declared with no modifies clause",
1909 ekind_capName (unew->ukind),
1910 uentry_getName (unew)),
1911 uentry_whereDeclared (unew)))
1913 llgenindentmsg (message ("Specification has modifies %q",
1914 sRefSet_unparse (old->info->fcn->mods)),
1915 uentry_whereSpecified (old));
1922 sRefSet_allElements (newMods, current)
1924 if (sRef_isValid (current))
1926 sRef rb = sRef_getRootBase (current);
1928 if (sRef_isFileStatic (rb))
1932 if (!sRefSet_isSameMember (old->info->fcn->mods,
1933 sRef_makeInternalState ())
1934 && !sRefSet_isSameMember (old->info->fcn->mods,
1935 sRef_makeSpecState ()))
1938 && !uentry_isStatic (old)
1942 ("Modifies list for %q includes internal state, "
1943 "but %s without modifies internal.",
1944 uentry_getName (old),
1945 uentry_specOrDefName (old)),
1946 uentry_whereLast (unew)))
1948 uentry_showWhereSpecified (old);
1951 old->info->fcn->mods =
1952 sRefSet_insert (old->info->fcn->mods,
1953 sRef_makeInternalState ());
1958 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1964 if (sRef_canModifyVal (current, old->info->fcn->mods))
1966 int size = sRefSet_size (old->info->fcn->mods);
1968 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1971 if (sRefSet_size (old->info->fcn->mods) != size)
1982 ("Modifies list for %q contains %q, not modifiable "
1984 uentry_getName (old),
1985 sRef_unparse (current),
1986 uentry_specDeclName (old)),
1987 uentry_whereLast (unew)))
1989 uentry_showWhereSpecified (old);
1994 } end_sRefSet_allElements;
1996 if (completeConform && uentry_isReallySpecified (old))
1998 sRefSet_allElements (old->info->fcn->mods, el)
2000 if (sRef_canModify (el, newMods))
2009 ("Specification modifies clause for %q contains %q, "
2010 "not included in declaration modifies clause",
2011 uentry_getName (old),
2013 uentry_whereLast (unew)))
2015 uentry_showWhereSpecified (old);
2018 } end_sRefSet_allElements ;
2022 ** Make sure file static elements will be removed.
2027 context_recordFileModifies (old->info->fcn->mods);
2032 uentry_checkMutableType (uentry ue)
2034 ctype ct = uentry_getType (ue);
2036 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2038 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2040 voptgenerror (FLG_MUTREP,
2041 message ("Mutable abstract type %q declared without pointer "
2042 "indirection: %t (violates assignment semantics)",
2043 uentry_getName (ue), ct),
2044 uentry_whereDeclared (ue));
2049 uentry_setMutable (uentry e)
2051 llassert (uentry_isDatatype (e));
2052 e->info->datatype->mut = YES;
2056 uentry_checkIterArgs (uentry ue)
2058 bool hasYield = FALSE;
2061 llassert (uentry_isIter (ue));
2063 args = uentry_getParams (ue);
2065 uentryList_elements (args, el)
2067 sstate ds = uentry_getDefState (el);
2069 if (uentry_isYield (el))
2074 if (sstate_isUnknown (ds))
2076 uentry_setDefState (el, SS_DEFINED);
2082 } end_uentryList_elements;
2086 voptgenerror (FLG_HASYIELD,
2087 message ("Iterator %q declared with no yield parameters",
2088 uentry_getName (ue)),
2089 uentry_whereDeclared (ue));
2094 chkind_fromQual (qual qel)
2096 if (qual_isChecked (qel))
2100 else if (qual_isCheckMod (qel))
2104 else if (qual_isCheckedStrict (qel))
2106 return CH_CHECKEDSTRICT;
2108 else if (qual_isUnchecked (qel))
2110 return CH_UNCHECKED;
2115 /*@notreached@*/ return CH_UNKNOWN;
2120 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2122 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2124 if (!uentry_isRefCounted (ue))
2127 (FLG_ANNOTATIONERROR,
2128 message ("Reference counting qualifier %s used on non-reference "
2129 "counted storage: %q",
2131 uentry_unparse (ue)),
2132 uentry_whereLast (ue));
2136 alkind ak = alkind_fromQual (qel);
2138 uentry_setAliasKind (ue, ak);
2141 else if (qual_isRefCounted (qel))
2143 ctype ct = ctype_realType (uentry_getType (ue));
2146 if (ctype_isPointer (ct)
2147 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2149 /* check there is a refs field */
2150 uentryList fields = ctype_getFields (rt);
2151 uentry refs = uentry_undefined;
2153 uentryList_elements (fields, field)
2155 if (uentry_isRefsField (field))
2157 if (uentry_isValid (refs))
2160 (FLG_ANNOTATIONERROR,
2161 message ("Reference counted structure type %s has "
2162 "multiple refs fields: %q and %q",
2164 uentry_getName (refs),
2165 uentry_getName (field)),
2166 uentry_whereLast (field));
2171 } end_uentryList_elements;
2173 if (uentry_isInvalid (refs))
2177 message ("Reference counted structure type %s has "
2179 ctype_unparse (ct)),
2181 ("To count reference, the structure must have a field named "
2182 "refs of type int."),
2185 else if (!ctype_isInt (uentry_getType (refs)))
2188 (FLG_ANNOTATIONERROR,
2189 message ("Reference counted structure type %s refs field has "
2190 "type %s (should be int)", ctype_unparse (ct),
2191 ctype_unparse (uentry_getType (refs))),
2192 uentry_whereLast (refs));
2196 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2197 uentry_whereDeclared (ue));
2202 if ((ctype_isPointer (ct)
2203 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2204 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2206 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2207 uentry_whereDeclared (ue));
2212 (FLG_ANNOTATIONERROR,
2213 message ("Non-pointer to structure type %s declared with "
2214 "refcounted qualifier",
2215 ctype_unparse (ct)),
2216 uentry_whereLast (ue));
2220 else if (qual_isRefs (qel))
2222 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2224 uentry_setAliasKind (ue, AK_REFS);
2229 (FLG_ANNOTATIONERROR,
2230 message ("Refs qualifier used on non-structure field: %q",
2231 uentry_unparse (ue)),
2232 uentry_whereLast (ue));
2235 else if (qual_isAliasQual (qel))
2237 alkind ak = alkind_fromQual (qel);
2239 alkind oldak = uentry_getAliasKind (ue);
2240 ctype ut = uentry_getType (ue);
2242 if (alkind_isImplicit (ak)
2243 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2245 /* ignore the implied qualifier */
2249 if (uentry_isEitherConstant (ue))
2252 (FLG_ANNOTATIONERROR,
2253 message ("Alias qualifier %s used on constant: %q",
2254 alkind_unparse (ak), uentry_unparse (ue)),
2255 uentry_whereLast (ue));
2260 if (ctype_isFunction (ut))
2262 ut = ctype_getReturnType (ut);
2265 if (!(ctype_isVisiblySharable (ut)
2266 || ctype_isRealArray (ut)
2267 || ctype_isRealSU (ut)))
2269 if (!qual_isImplied (qel))
2272 (FLG_ANNOTATIONERROR,
2273 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2274 alkind_unparse (ak), ut, uentry_getName (ue)),
2275 uentry_whereLast (ue));
2282 if (uentry_isRefCounted (ue))
2284 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2285 || qual_isExposed (qel)
2286 || qual_isObserver (qel)))
2288 if (!qual_isImplied (qel))
2291 (FLG_ANNOTATIONERROR,
2293 ("Alias qualifier %s used on reference counted storage: %q",
2294 alkind_unparse (ak),
2295 uentry_unparse (ue)),
2296 uentry_whereLast (ue));
2304 if (qual_isRefQual (qel))
2307 (FLG_ANNOTATIONERROR,
2308 message ("Qualifier %s used on non-reference counted storage: %q",
2309 alkind_unparse (ak), uentry_unparse (ue)),
2310 uentry_whereLast (ue));
2319 uentry_setAliasKind (ue, ak);
2322 else if (qual_isNull (qel))
2324 if (uentry_isConstant (ue))
2328 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2329 uentry_whereDeclared (ue));
2333 uentry_setNullState (ue, NS_POSNULL);
2336 else if (qual_isRelNull (qel))
2338 uentry_setNullState (ue, NS_RELNULL);
2340 else if (qual_isNotNull (qel))
2342 uentry_setNullState (ue, NS_MNOTNULL);
2344 else if (qual_isAbstract (qel)
2345 || qual_isConcrete (qel))
2347 if (!uentry_isDatatype (ue))
2350 (FLG_ANNOTATIONERROR,
2351 message ("Qualifier %s used with non-datatype",
2352 qual_unparse (qel)),
2353 uentry_whereLast (ue));
2357 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2360 else if (qual_isMutable (qel))
2362 if (!uentry_isDatatype (ue))
2365 (FLG_ANNOTATIONERROR,
2366 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2367 uentry_whereLast (ue));
2371 if (!ynm_isOn (ue->info->datatype->mut))
2373 uentry_checkMutableType (ue);
2376 ue->info->datatype->mut = YES;
2379 else if (qual_isImmutable (qel))
2381 if (!uentry_isDatatype (ue))
2383 voptgenerror (FLG_ANNOTATIONERROR,
2384 message ("Qualifier %s used with non-datatype",
2385 qual_unparse (qel)),
2386 uentry_whereLast (ue));
2390 ue->info->datatype->mut = NO;
2393 else if (qual_isNullPred (qel))
2395 uentry_convertVarFunction (ue);
2397 if (uentry_isFunction (ue))
2399 ctype typ = uentry_getType (ue);
2400 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2402 if (ctype_isRealBool (rtype))
2404 uentryList pl = ctype_argsFunction (typ);
2406 if (uentryList_size (pl) == 1)
2408 ue->info->fcn->nullPred = qel;
2412 voptgenerror (FLG_ANNOTATIONERROR,
2413 message ("Qualifier %s used with function having %d "
2414 "arguments (should have 1)",
2416 uentryList_size (pl)),
2417 uentry_whereLast (ue));
2422 voptgenerror (FLG_ANNOTATIONERROR,
2423 message ("Qualifier %s used with function returning %s "
2424 "(should return bool)",
2426 ctype_unparse (rtype)),
2427 uentry_whereLast (ue));
2432 voptgenerror (FLG_ANNOTATIONERROR,
2433 message ("Qualifier %s used with non-function",
2434 qual_unparse (qel)),
2435 uentry_whereLast (ue));
2438 else if (qual_isExitQual (qel))
2440 exitkind exk = exitkind_fromQual (qel);
2442 if (uentry_isFunction (ue))
2444 if (exitkind_isKnown (ue->info->fcn->exitCode))
2446 voptgenerror (FLG_ANNOTATIONERROR,
2447 message ("Multiple exit qualifiers used on function %q: %s, %s",
2448 uentry_getName (ue),
2449 exitkind_unparse (ue->info->fcn->exitCode),
2450 exitkind_unparse (exk)),
2451 uentry_whereLast (ue));
2454 ue->info->fcn->exitCode = exk;
2458 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2460 uentry_makeVarFunction (ue);
2461 ue->info->fcn->exitCode = exk;
2465 voptgenerror (FLG_ANNOTATIONERROR,
2466 message ("Exit qualifier %s used with non-function (type %s)",
2468 ctype_unparse (uentry_getType (ue))),
2469 uentry_whereLast (ue));
2473 else if (qual_isMetaState (qel))
2475 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2477 if (annotationInfo_matchesContext (ainfo, ue))
2479 DPRINTF (("Reflecting %s on %s",
2480 annotationInfo_unparse (ainfo),
2481 uentry_unparseFull (ue)));
2483 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2484 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2485 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2490 (FLG_ANNOTATIONERROR,
2491 message ("Attribute annotation %s used in inconsistent context: %q",
2493 uentry_unparse (ue)),
2494 uentry_whereLast (ue)))
2496 /*@i! annotationInfo_showContextError (ainfo, ue); */
2502 if (qual_isCQual (qel))
2508 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2514 uentry_reflectQualifiers (uentry ue, qualList q)
2516 llassert (uentry_isValid (ue));
2518 DPRINTF (("Reflect qualifiers: %s / %s",
2519 uentry_unparseFull (ue), qualList_unparse (q)));
2521 qualList_elements (q, qel)
2523 if (qual_isStatic (qel))
2525 uentry_setStatic (ue);
2527 else if (qual_isUnused (qel))
2529 uentry_setUsed (ue, fileloc_undefined);
2530 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2532 else if (qual_isExternal (qel))
2534 fileloc_free (ue->whereDefined);
2535 ue->whereDefined = fileloc_createExternal ();
2537 else if (qual_isSef (qel))
2539 if (uentry_isVariable (ue))
2541 vkind vk = ue->info->var->kind;
2543 llassert (vk != VKREFPARAM);
2545 if (vk == VKYIELDPARAM)
2548 (FLG_ANNOTATIONERROR,
2549 message ("Qualifier sef cannot be used with %s: %q",
2550 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2551 uentry_unparse (ue)),
2552 uentry_whereLast (ue));
2554 else if (vk == VKRETPARAM)
2556 ue->info->var->kind = VKSEFRETPARAM;
2560 ue->info->var->kind = VKSEFPARAM;
2566 (FLG_ANNOTATIONERROR,
2567 message ("Qualifier sef is meaningful only on parameters: %q",
2568 uentry_unparse (ue)),
2569 uentry_whereLast (ue));
2572 else if (qual_isExtern (qel))
2574 ue->storageclass = SCEXTERN;
2576 else if (qual_isGlobalQual (qel)) /* undef, killed */
2578 DPRINTF (("Reflecting qual: %s / %s",
2579 qual_unparse (qel), uentry_unparse (ue)));
2581 if (uentry_isVariable (ue))
2583 sstate oldstate = ue->info->var->defstate;
2584 sstate defstate = sstate_fromQual (qel);
2587 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2588 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2590 defstate = SS_UNDEFKILLED;
2597 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2598 ue->info->var->defstate = defstate;
2603 (FLG_ANNOTATIONERROR,
2604 message ("Qualifier %s used on non-variable: %q",
2605 qual_unparse (qel), uentry_unparse (ue)),
2606 uentry_whereLast (ue));
2609 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2611 /* start modifications */
2612 else if( qual_isBufQualifier(qel) ) {
2613 ctype ct = ctype_realType(uentry_getType(ue));
2614 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2616 if( uentry_hasBufStateInfo(ue) ) {
2617 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2619 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2620 /* If formal func param */
2621 uentry_setNullTerminatedState(ue);
2622 uentry_setLen (ue, 1);
2623 uentry_setSize (ue, 1);
2625 sRef_setNullTerminatedState(uentry_getSref(ue));
2626 sRef_setLen (uentry_getSref(ue), 1);
2627 sRef_setSize (uentry_getSref(ue), 1);
2629 uentry_setPossiblyNullTerminatedState(ue);
2631 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2635 /* put other BufState Qualifiers here */
2637 cstring s = uentry_getName(ue);
2638 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2639 struct for identifier %s\n", s) );
2641 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2643 sRef retSref = uentry_getSref (ue);
2644 ctype retType = sRef_getType (retSref);
2646 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2647 sRef_setNullTerminatedState (retSref);
2653 message ("Qualifier %s used on non-pointer on \
2654 function return: %q", qual_unparse (qel),
2655 uentry_unparse (ue)));
2662 message ("Qualifier %s used on non-pointer: %q",
2663 qual_unparse (qel), uentry_unparse (ue)));
2665 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2667 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2669 ctype realType = ctype_realType (ue->utype);
2670 sstate defstate = sstate_fromQual (qel);
2672 if (ctype_isFunction (realType))
2674 realType = ctype_realType (ctype_getReturnType (realType));
2677 if (qual_isRelDef (qel))
2679 ; /* okay anywhere */
2683 if (!ctype_isAP (realType)
2684 && !ctype_isSU (realType)
2685 && !ctype_isUnknown (realType)
2686 && !ctype_isAbstract (ue->utype))
2689 (FLG_ANNOTATIONERROR,
2690 message ("Qualifier %s used on non-pointer or struct: %q",
2691 qual_unparse (qel), uentry_unparse (ue)),
2692 uentry_whereLast (ue));
2696 uentry_setDefState (ue, defstate);
2698 if (sRef_isStateSpecial (ue->sref)
2699 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2701 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2704 else if (qual_isYield (qel))
2706 if (uentry_isVariable (ue))
2708 ue->info->var->kind = VKYIELDPARAM;
2713 (FLG_ANNOTATIONERROR,
2714 message ("Qualifier %s used on non-iterator parameter: %q",
2715 qual_unparse (qel), uentry_unparse (ue)),
2716 uentry_whereLast (ue));
2719 else if (qual_isExQual (qel))
2721 exkind ek = exkind_fromQual (qel);
2722 ctype ut = uentry_getType (ue);
2724 DPRINTF (("Reflect ex qual: %s / %s",
2725 uentry_unparse (ue), exkind_unparse (ek)));
2727 if (ctype_isFunction (ut))
2729 ut = ctype_getReturnType (ut);
2732 if (!(ctype_isVisiblySharable (ut))
2733 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2734 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2736 if (!qual_isImplied (qel))
2738 if (ctype_isImmutableAbstract (ut)) {
2740 (FLG_REDUNDANTSHAREQUAL,
2741 message ("Qualifier %s used on unsharable storage type %t: %q",
2742 exkind_unparse (ek), ut, uentry_getName (ue)),
2743 uentry_whereLast (ue));
2746 (FLG_MISPLACEDSHAREQUAL,
2747 message ("Qualifier %s used on unsharable storage type %t: %q",
2748 exkind_unparse (ek), ut, uentry_getName (ue)),
2749 uentry_whereLast (ue));
2755 alkind ak = sRef_getAliasKind (ue->sref);
2757 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2758 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2760 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2762 if (!alkind_isTemp (ak))
2764 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2765 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2768 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2769 || alkind_isOwned (ak))
2777 message ("Exposure qualifier %s used on %s storage (should "
2778 "be dependent): %q",
2780 alkind_unparse (ak),
2781 uentry_unparse (ue)));
2785 else if (qual_isGlobCheck (qel))
2787 if (uentry_isVariable (ue))
2789 chkind ch = chkind_fromQual (qel);
2791 if (ue->info->var->checked != CH_UNKNOWN)
2793 if (ch == ue->info->var->checked)
2795 llerror (FLG_SYNTAX,
2796 message ("Redundant %s qualifier on %q",
2798 uentry_getName (ue)));
2802 llerror (FLG_SYNTAX,
2804 ("Contradictory %s and %s qualifiers on %q",
2806 checkedName (ue->info->var->checked),
2807 uentry_getName (ue)));
2811 ue->info->var->checked = ch;
2817 message ("Qualifier %s used with non-variable",
2818 qual_unparse (qel)));
2821 else if (qual_isReturned (qel))
2823 if (uentry_isVariable (ue))
2825 ue->info->var->kind = VKRETPARAM;
2829 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2830 qual_unparse (qel)));
2835 uentry_reflectOtherQualifier (ue, qel);
2838 sRef_storeState (ue->sref);
2839 } end_qualList_elements;
2843 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2847 uentry_isOnly (uentry ue)
2849 return (!uentry_isUndefined (ue)
2850 && uentry_isVariable (ue)
2851 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2855 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2857 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2858 sRef_setOrigAliasKind (ue->sref, ak);
2862 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2864 if (uentry_isVariable (ue))
2866 ue->info->var->nullstate = ns;
2869 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2873 uentry_isUnique (uentry ue)
2875 return (!uentry_isUndefined (ue)
2876 && uentry_isVariable (ue)
2877 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2881 uentry_isFileStatic (uentry ue)
2883 return (uentry_isStatic (ue)
2884 && (!uentry_isVariable (ue)
2885 || sRef_isFileStatic (uentry_getSref (ue))));
2889 uentry_isExported (uentry ue)
2891 if (uentry_isValid (ue))
2893 if (uentry_isVariable (ue))
2895 return (sRef_isRealGlobal (uentry_getSref (ue)));
2899 return !uentry_isStatic (ue);
2907 uentry_isNonLocal (uentry ue)
2909 return (uentry_isValid (ue) && uentry_isVariable (ue)
2910 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2914 uentry_isGlobalVariable (uentry ue)
2916 return (uentry_isValid (ue) && uentry_isVariable (ue)
2917 && sRef_isFileOrGlobalScope (ue->sref));
2921 uentry_isVisibleExternally (uentry ue)
2923 return (uentry_isValid (ue)
2924 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2925 || (!uentry_isStatic (ue)
2926 && (uentry_isFunction (ue)
2927 || uentry_isIter (ue)
2928 || uentry_isEndIter (ue)
2929 || uentry_isConstant (ue)
2930 || uentry_isDatatype (ue)
2931 || uentry_isAnyTag (ue)))));
2935 uentry_isPrintfLike (uentry ue)
2937 return (uentry_isFunction (ue)
2938 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2942 uentry_isScanfLike (uentry ue)
2944 return (uentry_isFunction (ue)
2945 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2949 uentry_isMessageLike (uentry ue)
2951 return (uentry_isFunction (ue)
2952 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2955 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2957 uentryList args = uentry_getParams (ue);
2959 if (!uentryList_isMissingParams (args))
2961 uentry last = uentry_undefined;
2963 uentryList_elements (args, current)
2965 if (uentry_isElipsisMarker (current))
2967 if (uentry_isUndefined (last))
2971 message ("Function %q is marked %s, but has no format "
2972 "string argument before elipsis",
2973 uentry_getName (ue),
2974 specCode_unparse (ue->info->fcn->specialCode)),
2975 uentry_whereLast (ue));
2976 ue->info->fcn->specialCode = SPC_NONE;
2980 ctype rt = ctype_realType (uentry_getType (last));
2982 if (!ctype_match (rt, ctype_string))
2986 /* wchar_t * is okay too */
2987 if (ctype_isAP (rt))
2989 ctype base = ctype_baseArrayPtr (rt);
2991 if (ctype_isArbitraryIntegral (base))
3001 message ("Function %q is marked %s, but the argument "
3002 "before the elipsis has type %s (should be char *)",
3003 uentry_getName (ue),
3004 specCode_unparse (ue->info->fcn->specialCode),
3005 ctype_unparse (uentry_getType (last))),
3006 uentry_whereLast (ue));
3008 ue->info->fcn->specialCode = SPC_NONE;
3015 } end_uentryList_elements ;
3019 message ("Function %q is marked %s, but has no elipsis parameter",
3020 uentry_getName (ue),
3021 specCode_unparse (ue->info->fcn->specialCode)),
3022 uentry_whereLast (ue));
3024 ue->info->fcn->specialCode = SPC_NONE;
3029 uentry_setPrintfLike (uentry ue)
3031 uentry_convertVarFunction (ue);
3032 llassertfatal (uentry_isFunction (ue));
3033 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3034 checkSpecialFunction (ue);
3038 uentry_setScanfLike (uentry ue)
3040 uentry_convertVarFunction (ue);
3041 llassertfatal (uentry_isFunction (ue));
3042 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3043 checkSpecialFunction (ue);
3047 uentry_setMessageLike (uentry ue)
3049 uentry_convertVarFunction (ue);
3050 llassertfatal (uentry_isFunction (ue));
3051 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3052 checkSpecialFunction (ue);
3056 uentry_isSpecialFunction (uentry ue)
3058 return (uentry_isFunction (ue)
3059 && (ue->info->fcn->specialCode != SPC_NONE));
3062 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3064 ctype ct = idDecl_getCtype (t);
3066 fileloc loc = setLocation ();
3067 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3068 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3070 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3071 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3072 uentry_implicitParamAnnots (ue);
3074 /* Parameter type [][] or [x][] is invalid */
3076 while (ctype_isFixedArray (base)) {
3077 base = ctype_baseArrayPtr (base);
3080 if (ctype_isIncompleteArray (base)) {
3081 base = ctype_baseArrayPtr (base);
3083 if (ctype_isArray (base)) {
3084 if (!uentry_hasName (ue)) {
3085 (void) optgenerror (FLG_INCOMPLETETYPE,
3086 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3088 ctype_unparse (ct)),
3089 uentry_whereLast (ue));
3091 (void) optgenerror (FLG_INCOMPLETETYPE,
3092 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3093 uentry_getName (ue),
3094 ctype_unparse (ct)),
3095 uentry_whereLast (ue));
3100 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3104 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3106 ctype ct = idDecl_getCtype (t);
3108 if (ctype_isFunction (ct))
3110 return (uentry_makeIdFunction (t));
3114 fileloc loc = setLocation ();
3115 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3117 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3119 if (!uentry_isExtern (ue))
3121 uentry_setDefined (ue, loc);
3128 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3130 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3137 static /*@only@*/ /*@notnull@*/
3138 uentry uentry_makeConstantAux (cstring n, ctype t,
3139 /*@keep@*/ fileloc f, bool priv, bool macro,
3140 /*@only@*/ multiVal m)
3142 uentry e = uentry_alloc ();
3145 e->uname = cstring_copy (n);
3147 e->storageclass = SCNONE;
3149 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3151 e->sref = sRef_makeConst (t);
3156 e->uses = filelocList_new ();
3157 e->isPrivate = priv;
3158 e->hasNameError = FALSE;
3160 e->info = (uinfo) dmalloc (sizeof (*e->info));
3161 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3162 e->info->uconst->access = typeIdSet_undefined;
3163 e->info->uconst->macro = macro;
3165 uentry_setSpecDef (e, f);
3167 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3169 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3172 uentry_setConstantValue (e, m);
3177 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3179 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3183 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3185 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3189 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3191 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3195 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3197 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3198 idDecl_getCtype (t),
3201 llassert (fileloc_isUndefined (ue->whereDeclared));
3202 ue->whereDeclared = setLocation ();
3203 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3205 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3206 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3214 void uentry_setDefState (uentry ue, sstate defstate)
3216 if (uentry_isValid (ue))
3218 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3220 if (uentry_isVariable (ue))
3222 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3227 bool uentry_isCheckedUnknown (uentry ue)
3229 return (uentry_isVar (ue)
3230 && (ue->info->var->checked == CH_UNKNOWN));
3233 bool uentry_isCheckMod (uentry ue)
3235 return (uentry_isVar (ue)
3236 && (ue->info->var->checked == CH_CHECKMOD));
3239 bool uentry_isUnchecked (uentry ue)
3241 return (uentry_isVar (ue)
3242 && (ue->info->var->checked == CH_UNCHECKED));
3245 bool uentry_isChecked (uentry ue)
3247 return (uentry_isVar (ue)
3248 && (ue->info->var->checked == CH_CHECKED));
3251 bool uentry_isCheckedModify (uentry ue)
3253 return (uentry_isVar (ue)
3254 && (ue->info->var->checked == CH_CHECKED
3255 || ue->info->var->checked == CH_CHECKMOD
3256 || ue->info->var->checked == CH_CHECKEDSTRICT));
3259 bool uentry_isCheckedStrict (uentry ue)
3261 return (uentry_isVar (ue)
3262 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3265 void uentry_setUnchecked (uentry ue)
3267 llassert (uentry_isVar (ue));
3269 ue->info->var->checked = CH_UNCHECKED;
3272 void uentry_setChecked (uentry ue)
3274 llassert (uentry_isVar (ue));
3276 ue->info->var->checked = CH_CHECKED;
3279 void uentry_setCheckMod (uentry ue)
3281 llassert (uentry_isVar (ue));
3283 ue->info->var->checked = CH_CHECKMOD;
3286 void uentry_setCheckedStrict (uentry ue)
3288 llassert (uentry_isVar (ue));
3290 ue->info->var->checked = CH_CHECKEDSTRICT;
3293 static /*@only@*/ /*@notnull@*/
3294 uentry uentry_makeVariableAux (cstring n, ctype t,
3296 /*@exposed@*/ sRef s,
3297 bool priv, vkind kind)
3299 uentry e = uentry_alloc ();
3302 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3305 e->uname = cstring_copy (n);
3308 e->storageclass = SCNONE;
3310 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3317 e->uses = filelocList_new ();
3318 e->isPrivate = priv;
3319 e->hasNameError = FALSE;
3321 e->info = (uinfo) dmalloc (sizeof (*e->info));
3322 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3323 e->info->var->kind = kind;
3325 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3326 e->info->var->checked = CH_UNKNOWN;
3328 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3329 uentry_setSpecDef (e, f);
3330 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3332 if (ctype_isFunction (rt))
3334 rt = ctype_getReturnType (rt);
3337 if (ctype_isUA (rt))
3339 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3340 sRef_setStateFromType (e->sref, rt);
3343 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3344 e->info->var->defstate = sRef_getDefState (e->sref);
3345 e->info->var->nullstate = sRef_getNullState (e->sref);
3347 /* start modifications */
3348 /* This function sets the uentry for a pointer or array variable declaration,
3349 it allocates memory and sets the fields. We check if the type of the variable
3350 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3352 if (ctype_isArray (t) || ctype_isPointer(t))
3354 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3355 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3356 sRef_setNotNullTerminatedState (s);
3360 e->info->var->bufinfo = NULL;
3362 /* end modification */
3368 uentry_isYield (uentry ue)
3370 return (uentry_isVariable (ue)
3371 && (ue->info->var->kind == VKYIELDPARAM
3372 || ue->info->var->kind == VKREFYIELDPARAM));
3376 uentry_isRefsField (uentry ue)
3378 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3381 /*@only@*/ /*@notnull@*/
3382 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3384 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3385 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3392 void uentry_makeVarFunction (uentry ue)
3399 llassert (uentry_isValid (ue));
3400 llassert (!sRef_modInFunction ());
3402 ak = sRef_getOrigAliasKind (ue->sref);
3403 ek = sRef_getOrigExKind (ue->sref);
3405 llassert (uentry_isVariable (ue));
3406 oldInfo = ue->info->var;
3408 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3409 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3412 ** expanded macro is marked used
3415 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3418 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3419 ue->info->fcn->exitCode = XK_UNKNOWN;
3420 ue->info->fcn->nullPred = qual_createUnknown ();
3421 ue->info->fcn->specialCode = SPC_NONE;
3422 ue->info->fcn->access = typeIdSet_undefined;
3423 ue->info->fcn->hasGlobs = FALSE;
3424 ue->info->fcn->globs = globSet_undefined;
3425 ue->info->fcn->hasMods = FALSE;
3426 ue->info->fcn->mods = sRefSet_undefined;
3427 ue->info->fcn->specclauses = NULL;
3428 ue->info->fcn->defparams = uentryList_undefined;
3431 ue->info->fcn->preconditions = functionConstraint_undefined;
3435 ue->info->fcn->postconditions = functionConstraint_undefined;
3438 if (ctype_isFunction (ue->utype))
3440 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3444 ue->sref = sRef_makeType (ctype_unknown);
3447 if (sRef_isRefCounted (ue->sref))
3453 if (alkind_isUnknown (ak))
3455 if (exkind_isKnown (ek))
3457 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3458 ak = AK_IMPDEPENDENT;
3462 if (context_getFlag (FLG_RETIMPONLY))
3464 if (ctype_isFunction (ue->utype)
3465 && ctype_isVisiblySharable
3466 (ctype_realType (ctype_getReturnType (ue->utype))))
3468 if (uentryList_hasReturned (uentry_getParams (ue)))
3474 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3489 loc = ue->whereDeclared;
3491 sRef_setAliasKind (ue->sref, ak, loc);
3492 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3493 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3494 sRef_setExKind (ue->sref, ek, loc);
3496 if (oldInfo->kind == VKEXPMACRO)
3502 fileloc_free (ue->whereDefined);
3503 ue->whereDefined = fileloc_undefined;
3506 uvinfo_free (oldInfo);
3509 void uentry_makeConstantFunction (uentry ue)
3516 llassert (uentry_isValid (ue));
3517 llassert (!sRef_modInFunction ());
3519 ak = sRef_getOrigAliasKind (ue->sref);
3520 ek = sRef_getOrigExKind (ue->sref);
3522 llassert (uentry_isConstant (ue));
3523 oldInfo = ue->info->uconst;
3525 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3528 ** expanded macro is marked used (until I write a pre-processor)
3532 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3533 ue->info->fcn->exitCode = XK_UNKNOWN;
3534 ue->info->fcn->nullPred = qual_createUnknown ();
3535 ue->info->fcn->specialCode = SPC_NONE;
3536 ue->info->fcn->access = typeIdSet_undefined;
3537 ue->info->fcn->hasGlobs = FALSE;
3538 ue->info->fcn->globs = globSet_undefined;
3539 ue->info->fcn->hasMods = FALSE;
3540 ue->info->fcn->mods = sRefSet_undefined;
3541 ue->info->fcn->specclauses = NULL;
3542 ue->info->fcn->defparams = uentryList_undefined;
3545 ue->info->fcn->preconditions = functionConstraint_undefined;
3549 ue->info->fcn->postconditions = functionConstraint_undefined;
3553 if (ctype_isFunction (ue->utype))
3555 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3559 ue->sref = sRef_makeType (ctype_unknown);
3562 if (sRef_isRefCounted (ue->sref))
3568 if (alkind_isUnknown (ak))
3570 if (exkind_isKnown (ek))
3572 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3573 ak = AK_IMPDEPENDENT;
3577 if (context_getFlag (FLG_RETIMPONLY))
3579 if (ctype_isFunction (ue->utype)
3580 && ctype_isVisiblySharable
3581 (ctype_realType (ctype_getReturnType (ue->utype))))
3583 if (uentryList_hasReturned (uentry_getParams (ue)))
3589 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3604 loc = ue->whereDeclared;
3606 sRef_setAliasKind (ue->sref, ak, loc);
3607 sRef_setExKind (ue->sref, ek, loc);
3609 fileloc_free (ue->whereDefined);
3610 ue->whereDefined = fileloc_undefined;
3611 ucinfo_free (oldInfo);
3615 uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
3617 llassert (uentry_isValid (ue));
3619 globSet_markImmutable (globs);
3621 if (uentry_isIter (ue))
3623 ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
3627 uentry_convertVarFunction (ue);
3628 llassert (uentry_isFunction (ue));
3630 ue->info->fcn->hasGlobs = TRUE;
3631 ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
3634 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3636 ue->info->fcn->hasMods = TRUE;
3640 void uentry_addAccessType (uentry ue, typeId tid)
3642 if (uentry_isFunction (ue))
3644 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3646 else if (uentry_isEitherConstant (ue))
3648 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3650 else if (uentry_isIter (ue))
3652 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3654 else if (uentry_isEndIter (ue))
3656 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3660 llbug (message ("no access for: %q", uentry_unparse (ue)));
3664 /*@only@*/ /*@notnull@*/ uentry
3665 uentry_makeFunction (cstring n, ctype t,
3667 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3668 /*@only@*/ warnClause warn,
3671 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3672 return (uentry_makeFunctionAux (n, t,
3673 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3674 : typeIdSet_single (access)),
3680 /*@notnull@*/ uentry
3681 uentry_makePrivFunction2 (cstring n, ctype t,
3683 globSet globs, sRefSet mods,
3686 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3691 /*@notnull@*/ uentry
3692 uentry_makeSpecFunction (cstring n, ctype t,
3694 /*@only@*/ globSet globs,
3695 /*@only@*/ sRefSet mods,
3698 uentry ue = uentry_makeFunctionAux (n, t, access,
3699 globs, mods, warnClause_undefined,
3702 uentry_setHasGlobs (ue);
3703 uentry_setHasMods (ue);
3705 reflectImplicitFunctionQualifiers (ue, TRUE);
3709 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3711 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3712 sRef_undefined, FALSE, VKEXPMACRO);
3714 uentry_setDefined (ue, f);
3718 /*@notnull@*/ /*@notnull@*/ uentry
3719 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3721 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3722 typeIdSet_singleOpt (access),
3723 globSet_undefined, sRefSet_undefined,
3724 warnClause_undefined,
3728 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3732 bool uentry_isForward (uentry e)
3734 if (uentry_isValid (e))
3736 ctype ct = uentry_getType (e);
3738 return (ctype_isUnknown (ct)
3739 || (ctype_isFunction (ct)
3740 && ctype_isUnknown (ctype_getReturnType (ct))));
3746 /*@notnull@*/ uentry
3747 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3749 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3750 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3754 /*@notnull@*/ uentry
3755 uentry_makeUnspecFunction (cstring n, ctype t,
3759 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3760 sRefSet_undefined, warnClause_undefined,
3763 reflectImplicitFunctionQualifiers (ue, TRUE);
3771 /* is exported for use by usymtab_interface */
3773 /*@notnull@*/ uentry
3774 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3775 fileloc f, bool priv)
3777 uentry e = uentry_alloc ();
3779 DPRINTF (("Make datatype: %s / %s",
3780 n, ctype_unparse (t)));
3782 /* e->shallowCopy = FALSE; */
3783 e->ukind = KDATATYPE;
3784 e->uname = cstring_copy (n);
3786 e->storageclass = SCNONE;
3787 e->sref = sRef_makeUnknown ();
3791 sRef_setStateFromType (e->sref, t);
3794 uentry_setSpecDef (e, f);
3796 e->warn = warnClause_undefined; /*@i634@*/
3797 e->uses = filelocList_new ();
3798 e->isPrivate = priv;
3799 e->hasNameError = FALSE;
3804 e->info = (uinfo) dmalloc (sizeof (*e->info));
3805 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3806 e->info->datatype->abs = abstract;
3807 e->info->datatype->mut = mut;
3808 e->info->datatype->type = ctype_undefined;
3810 if (uentry_isDeclared (e))
3812 uentry_setDefined (e, f);
3815 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3817 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3823 /*@notnull@*/ uentry
3824 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3826 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3829 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3831 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3832 ctype_bool, NO, abstract,
3833 fileloc_getBuiltin (),
3836 ret->info->datatype->type = ctype_bool;
3844 static /*@only@*/ /*@notnull@*/ uentry
3845 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3846 /*@only@*/ fileloc f)
3848 uentry e = uentry_alloc ();
3851 e->uname = cstring_copy (n);
3853 e->sref = sRef_makeUnknown ();
3854 e->storageclass = SCNONE;
3858 uentry_setSpecDef (e, f);
3860 e->warn = warnClause_undefined; /*@i452@*/
3861 e->uses = filelocList_new ();
3862 e->isPrivate = FALSE;
3863 e->hasNameError = FALSE;
3865 e->info = (uinfo) dmalloc (sizeof (*e->info));
3866 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3867 e->info->iter->access = access;
3868 e->info->iter->mods = sRefSet_undefined;
3869 e->info->iter->globs = globSet_undefined;
3871 uentry_checkIterArgs (e);
3875 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3877 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3880 static /*@notnull@*/ uentry
3881 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3883 uentry e = uentry_alloc ();
3885 /* e->shallowCopy = FALSE; */
3886 e->ukind = KENDITER;
3887 e->storageclass = SCNONE;
3888 e->uname = message ("end_%s", n);
3889 e->utype = ctype_unknown;
3890 e->sref = sRef_makeUnknown ();
3892 uentry_setSpecDef (e, f);
3897 e->uses = filelocList_new ();
3898 e->isPrivate = FALSE;
3899 e->hasNameError = FALSE;
3901 e->info = (uinfo) dmalloc (sizeof (*e->info));
3902 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3904 e->info->enditer->access = access;
3906 e->warn = warnClause_undefined; /*@i452@*/
3910 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3912 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3919 static /*@only@*/ /*@notnull@*/ uentry
3920 uentry_makeTagAux (cstring n, ctype t,
3921 /*@only@*/ fileloc fl,
3922 bool priv, ekind kind)
3924 uentry e = uentry_alloc ();
3926 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3928 llbuglit ("uentry_makeTagAux: not a tag type");
3932 /* e->shallowCopy = FALSE; */
3933 e->uname = cstring_copy (n);
3936 e->sref = sRef_makeUnknown ();
3937 e->storageclass = SCNONE;
3939 uentry_setSpecDef (e, fl);
3944 e->uses = filelocList_new ();
3945 e->isPrivate = priv;
3946 e->hasNameError = FALSE;
3948 e->info = (uinfo) dmalloc (sizeof (*e->info));
3949 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3950 e->info->datatype->abs = NO;
3951 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3952 e->info->datatype->type = t;
3953 e->warn = warnClause_undefined; /*@i452@*/
3955 if (uentry_isDeclared (e))
3957 uentry_setDefined (e, fl);
3963 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3965 cstring sname = makeStruct (n);
3966 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3968 cstring_free (sname);
3973 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3975 cstring sname = makeStruct (n);
3976 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3978 cstring_free (sname);
3983 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3985 cstring uname = makeUnion (n);
3986 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3988 cstring_free (uname);
3993 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3995 cstring ename = makeEnum (n);
3996 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3998 cstring_free (ename);
4003 uentry_makeUnionTagLoc (cstring n, ctype t)
4005 cstring uname = makeUnion (n);
4006 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4008 cstring_free (uname);
4013 uentry_makeEnumTagLoc (cstring n, ctype t)
4015 cstring ename = makeEnum (n);
4016 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4018 cstring_free (ename);
4023 uentry_isStructTag (uentry ue)
4025 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4029 uentry_isUnionTag (uentry ue)
4031 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4035 uentry_isEnumTag (uentry ue)
4037 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4041 uentry_isAnyTag (uentry ue)
4043 return (uentry_isStructTag (ue)
4044 || uentry_isUnionTag (ue)
4045 || uentry_isEnumTag (ue));
4048 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4050 extern void uentry_destroyMod (void)
4051 /*@globals killed emarker@*/ /*@modifies emarker@*/
4053 static bool wasDestroyed = FALSE;
4055 llassert (!wasDestroyed);
4057 if (emarker != NULL)
4059 uentry_reallyFree (emarker);
4062 wasDestroyed = TRUE;
4066 uentry_makeElipsisMarker (void)
4068 if (emarker == NULL)
4070 emarker = uentry_alloc ();
4072 emarker->ukind = KELIPSMARKER;
4073 emarker->uname = cstring_makeLiteral ("...");
4074 emarker->utype = ctype_elipsMarker;
4075 emarker->sref = sRef_undefined;
4076 emarker->storageclass = SCNONE;
4077 emarker->used = FALSE;
4078 emarker->lset = FALSE;
4079 emarker->info = NULL;
4081 uentry_setSpecDef (emarker, fileloc_undefined);
4082 emarker->uses = filelocList_new ();
4083 emarker->isPrivate = FALSE;
4084 emarker->hasNameError = FALSE;
4087 /*@ignore@*/ return (emarker); /*@end@*/
4095 uentry_equiv (uentry p1, uentry p2)
4097 if (uentry_compare (p1, p2) != 0)
4108 uentry_xcomparealpha (uentry *p1, uentry *p2)
4112 if ((res = uentry_compare (*p1, *p2)) == 0) {
4113 if ((*p1 != NULL) && (*p2 != NULL)) {
4114 res = cstring_compare ((*p1)->uname,
4123 uentry_xcompareuses (uentry *p1, uentry *p2)
4128 if (uentry_isValid (u1))
4130 if (uentry_isValid (u2))
4132 return (-1 * int_compare (filelocList_size (u1->uses),
4133 filelocList_size (u2->uses)));
4142 if (uentry_isValid (u2))
4154 uentry_compareStrict (uentry v1, uentry v2)
4156 COMPARERETURN (uentry_compare (v1, v2));
4158 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4160 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4161 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4162 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4169 uentry_compare (uentry u1, uentry u2)
4171 if (u1 == u2) return 0;
4173 if (uentry_isInvalid (u1)) return -1;
4174 if (uentry_isInvalid (u2)) return 1;
4176 INTCOMPARERETURN (u1->ukind, u2->ukind);
4177 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4178 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4179 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4185 /* bug detected by splint:
4186 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4191 return (multiVal_compare (uentry_getConstantValue (u1),
4192 uentry_getConstantValue (u2)));
4196 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4198 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4199 uentry_accessType (u2)));
4200 return (uentryList_compareParams (uentry_getParams (u1),
4201 uentry_getParams (u2)));
4203 return (typeIdSet_compare (uentry_accessType (u1),
4204 uentry_accessType (u2)));
4207 ** Functions are never equivalent
4210 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4220 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4221 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4222 sRef_getOrigAliasKind (u2->sref)));
4223 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4224 sRef_getOrigExKind (u2->sref)));
4225 COMPARERETURN (generic_compare (u1->info->var->checked,
4226 u2->info->var->checked));
4227 COMPARERETURN (generic_compare (u1->info->var->defstate,
4228 u2->info->var->defstate));
4229 return (generic_compare (u1->info->var->nullstate,
4230 u2->info->var->nullstate));
4232 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4233 u2->info->datatype->type));
4234 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4235 u2->info->datatype->mut));
4236 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4245 ** all entries are: <type>[@<info>]*#<name>
4247 ** info depends on kind:
4251 advanceField (char **s)
4253 reader_checkChar (s, '@');
4257 advanceName (char **s)
4259 reader_checkChar (s, '#');
4263 vkind_fromInt (int i)
4265 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4267 llbuglit ("vkind_fromInt: out of range");
4274 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4275 typeIdSet access, nstate nullstate,
4276 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4278 uentry e = uentry_alloc ();
4283 e->sref = sRef_makeConst (ct);
4285 sRef_setNullState (e->sref, nullstate, loc);
4286 e->storageclass = SCNONE;
4288 if (fileloc_isSpec (loc))
4290 e->whereSpecified = loc;
4291 e->whereDeclared = fileloc_undefined;
4295 e->whereSpecified = fileloc_undefined;
4296 e->whereDeclared = loc;
4299 e->whereDefined = fileloc_undefined;
4300 e->uses = filelocList_new ();
4301 e->isPrivate = FALSE;
4302 e->hasNameError = FALSE;
4307 e->warn = warnClause_undefined; /*@i452@*/
4309 e->info = (uinfo) dmalloc (sizeof (*e->info));
4310 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4311 e->info->uconst->access = access;
4312 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4313 uentry_setConstantValue (e, m);
4314 sRef_storeState (e->sref);
4319 static /*@only@*/ uentry
4320 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4321 sstate defstate, nstate isnull, alkind aliased,
4322 exkind exp, chkind checked,
4323 /*@only@*/ fileloc loc)
4325 uentry e = uentry_alloc ();
4330 e->storageclass = SCNONE;
4332 e->sref = sRef_makeType (ct);
4333 sRef_setNullState (e->sref, isnull, loc);
4335 e->whereDefined = fileloc_undefined;
4337 if (fileloc_isSpec (loc))
4339 e->whereSpecified = loc;
4340 e->whereDeclared = fileloc_undefined;
4344 e->whereSpecified = fileloc_undefined;
4345 e->whereDeclared = loc;
4348 e->isPrivate = FALSE;
4349 e->hasNameError = FALSE;
4354 e->uses = filelocList_new ();
4355 e->warn = warnClause_undefined; /*@i452@*/
4357 e->info = (uinfo) dmalloc (sizeof (*e->info));
4358 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4359 e->info->var->kind = kind;
4360 e->info->var->checked = checked;
4361 e->info->var->defstate = defstate;
4363 sRef_setDefState (e->sref, defstate, loc);
4365 e->info->var->nullstate = sRef_getNullState (e->sref);
4367 sRef_setExKind (e->sref, exp, loc);
4368 sRef_setAliasKind (e->sref, aliased, loc);
4370 sRef_storeState (e->sref);
4372 /*DRL ADDED 9-1-2000 */
4373 e->info->var->bufinfo = NULL;
4378 static /*@only@*/ uentry
4379 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4380 ynm mut, ctype rtype, alkind ak, exkind exp,
4381 sstate defstate, nstate isnull,
4382 /*@only@*/ fileloc loc)
4384 uentry e = uentry_alloc ();
4386 e->ukind = KDATATYPE;
4387 /* e->shallowCopy = FALSE; */
4390 e->storageclass = SCNONE;
4391 e->sref = sRef_makeUnknown ();
4392 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4395 ** This is only setting null state. (I think?)
4398 if (ctype_isUA (ct))
4400 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4402 if (uentry_isValid (te))
4404 sRef_setStateFromUentry (e->sref, te);
4408 /* problem for recursive type definitions */
4412 sRef_setAliasKind (e->sref, ak, loc);
4413 sRef_setExKind (e->sref, exp, loc);
4415 sRef_setDefState (e->sref, defstate, loc);
4417 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4419 isnull = NS_ABSNULL;
4422 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4423 sRef_mergeNullState (e->sref, isnull);
4425 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4427 if (fileloc_isSpec (loc))
4429 e->whereSpecified = loc;
4430 e->whereDeclared = fileloc_undefined;
4434 e->whereSpecified = fileloc_undefined;
4435 e->whereDeclared = loc;
4438 e->isPrivate = FALSE;
4439 e->hasNameError = FALSE;
4441 e->warn = warnClause_undefined; /*@i452@*/
4445 e->uses = filelocList_new ();
4447 e->info = (uinfo) dmalloc (sizeof (*e->info));
4448 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4449 e->info->datatype->abs = abstract;
4450 e->info->datatype->mut = mut;
4451 e->info->datatype->type = rtype;
4453 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4454 sRef_storeState (e->sref);
4455 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4460 static void uentry_setHasGlobs (uentry ue)
4462 llassert (uentry_isFunction (ue));
4464 ue->info->fcn->hasGlobs = TRUE;
4467 static void uentry_setHasMods (uentry ue)
4469 llassert (uentry_isFunction (ue));
4471 ue->info->fcn->hasMods = TRUE;
4474 bool uentry_hasGlobs (uentry ue)
4476 if (uentry_isFunction (ue))
4478 return (ue->info->fcn->hasGlobs);
4484 bool uentry_hasStateClauseList (uentry ue)
4486 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4489 bool uentry_hasConditions (uentry ue)
4491 return (uentry_isFunction (ue)
4492 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4493 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4496 stateClauseList uentry_getStateClauseList (uentry ue)
4498 if (!uentry_isFunction (ue))
4500 llassert (uentry_isFunction (ue));
4501 return stateClauseList_undefined;
4504 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4505 return ue->info->fcn->specclauses;
4508 bool uentry_hasMods (uentry ue)
4510 if (uentry_isFunction (ue))
4512 return (ue->info->fcn->hasMods);
4519 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4521 bool hasGlobs, /*@only@*/ globSet globs,
4522 bool hasMods, /*@only@*/ sRefSet mods,
4523 alkind ak, exkind exp,
4524 sstate defstate, nstate isnull,
4528 /*@only@*/ stateClauseList specclauses,
4529 /*@only@*/ warnClause warnclause,
4530 /*@only@*/ fileloc loc)
4532 uentry e = uentry_alloc ();
4535 /* e->shallowCopy = FALSE; */
4539 e->storageclass = SCNONE;
4541 if (ctype_isFunction (ct))
4543 ret = ctype_getReturnType (ct);
4547 if (ctype_isKnown (ct))
4549 llbug (message ("not function: %s", ctype_unparse (ct)));
4552 ret = ctype_unknown;
4555 e->sref = sRef_makeType (ret);
4557 if (ctype_isUA (ret))
4559 sRef_setStateFromType (e->sref, ret);
4562 sRef_setDefined (e->sref, loc);
4563 sRef_setNullState (e->sref, isnull, loc);
4565 sRef_setAliasKind (e->sref, ak, loc);
4566 sRef_setExKind (e->sref, exp, loc);
4567 sRef_setDefState (e->sref, defstate, loc);
4569 e->whereSpecified = loc;
4570 e->whereDefined = fileloc_undefined;
4572 e->isPrivate = FALSE;
4573 e->hasNameError = FALSE;
4577 e->uses = filelocList_new ();
4578 e->warn = warnclause;
4580 e->info = (uinfo) dmalloc (sizeof (*e->info));
4581 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4583 e->info->fcn->exitCode = exitCode;
4584 e->info->fcn->specialCode = sCode;
4585 e->info->fcn->nullPred = nullPred;
4586 e->info->fcn->access = access;
4588 e->info->fcn->specclauses = specclauses;
4589 e->info->fcn->hasGlobs = hasGlobs;
4590 e->info->fcn->globs = globs;
4592 e->info->fcn->hasMods = hasMods;
4593 e->info->fcn->mods = mods;
4595 e->info->fcn->defparams = uentryList_undefined;
4596 e->whereDeclared = fileloc_undefined;
4598 sRef_storeState (e->sref);
4601 e->info->fcn->preconditions = NULL;
4605 e->info->fcn->postconditions = NULL;
4611 static /*@only@*/ uentry
4612 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4613 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4615 uentry e = uentry_alloc ();
4617 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4619 llbuglit ("uentry_makeTagBase: not a tag type");
4622 /* e->shallowCopy = FALSE; */
4626 e->sref = sRef_makeUnknown ();
4627 e->storageclass = SCNONE;
4629 if (fileloc_isSpec (loc))
4631 e->whereSpecified = loc;
4632 e->whereDeclared = fileloc_undefined;
4636 e->whereDeclared = loc;
4637 e->whereSpecified = fileloc_undefined;
4640 e->whereDefined = fileloc_undefined;
4642 e->isPrivate = FALSE;
4643 e->hasNameError = FALSE;
4647 e->uses = filelocList_new ();
4648 e->warn = warnClause_undefined; /*@i452@*/
4650 e->info = (uinfo) dmalloc (sizeof (*e->info));
4651 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4652 e->info->datatype->abs = NO;
4653 e->info->datatype->mut = MAYBE;
4654 e->info->datatype->type = rtype;
4656 sRef_storeState (e->sref);
4662 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4663 ctype ct, /*@only@*/ fileloc loc)
4665 uentry e = uentry_alloc ();
4667 /* e->shallowCopy = FALSE; */
4671 e->sref = sRef_makeUnknown ();
4672 e->storageclass = SCNONE;
4674 if (fileloc_isSpec (loc))
4676 e->whereSpecified = loc;
4677 e->whereDeclared = fileloc_undefined;
4681 e->whereDeclared = loc;
4682 e->whereSpecified = fileloc_undefined;
4685 e->whereDefined = fileloc_undefined;
4687 e->isPrivate = FALSE;
4688 e->hasNameError = FALSE;
4692 e->uses = filelocList_new ();
4693 e->warn = warnClause_undefined; /*@i452@*/
4695 e->info = (uinfo) dmalloc (sizeof (*e->info));
4696 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4697 e->info->iter->access = access;
4698 e->info->iter->mods = sRefSet_undefined;
4699 e->info->iter->globs = globSet_undefined;
4701 sRef_storeState (e->sref);
4706 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4707 /*@only@*/ fileloc loc)
4709 uentry e = uentry_alloc ();
4711 /* e->shallowCopy = FALSE; */
4712 e->ukind = KENDITER;
4713 e->storageclass = SCNONE;
4715 e->utype = ctype_unknown;
4716 e->sref = sRef_makeUnknown ();
4718 if (fileloc_isSpec (loc))
4720 e->whereSpecified = loc;
4721 e->whereDeclared = fileloc_undefined;
4725 e->whereDeclared = loc;
4726 e->whereSpecified = fileloc_undefined;
4729 e->whereDefined = fileloc_undefined;
4731 e->isPrivate = FALSE;
4732 e->hasNameError = FALSE;
4736 e->uses = filelocList_new ();
4737 e->warn = warnClause_undefined; /*@i452@*/
4739 e->info = (uinfo) dmalloc (sizeof (*e->info));
4740 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4741 e->info->enditer->access = access;
4742 sRef_storeState (e->sref);
4747 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4755 uentry_undump (ekind kind, fileloc loc, char **s)
4759 DPRINTF (("Uentry undump: %s", *s));
4763 reader_checkChar (s, '!');
4764 reader_checkChar (s, '.');
4765 ue = uentry_makeElipsisMarker ();
4769 ctype ct = ctype_undump (s);
4783 reader_checkChar (s, '|');
4785 if (reader_optCheckChar (s, '@'))
4787 tkind = vkind_fromInt (reader_getInt (s));
4788 reader_checkChar (s, '|');
4795 if (reader_optCheckChar (s, '$'))
4797 defstate = SS_UNKNOWN;
4798 isnull = NS_UNKNOWN;
4799 aliased = AK_IMPTEMP;
4801 checked = CH_UNKNOWN;
4803 else if (reader_optCheckChar (s, '&'))
4805 defstate = SS_DEFINED;
4806 isnull = NS_UNKNOWN;
4807 aliased = AK_IMPTEMP;
4809 checked = CH_UNKNOWN;
4811 else if (reader_optCheckChar (s, '^'))
4813 defstate = SS_UNKNOWN;
4814 isnull = NS_UNKNOWN;
4815 aliased = AK_IMPTEMP;
4817 checked = CH_UNKNOWN;
4821 defstate = sstate_fromInt (reader_getInt (s));
4822 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4823 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4825 if (reader_optCheckChar (s, '&'))
4828 checked = CH_UNKNOWN;
4832 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4833 advanceField (s); checked = (chkind) (reader_getInt (s));
4838 name = reader_getStringWord (s);
4840 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4842 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4843 isnull, aliased, exp,
4844 checked, fileloc_copy (loc));
4857 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4858 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4859 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4860 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4861 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4862 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4863 advanceField (s); rtype = ctype_undump (s);
4865 name = reader_getStringWord (s);
4866 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4867 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4868 aliased, exp, defstate, isnull,
4869 fileloc_copy (loc));
4886 stateClauseList specclauses = stateClauseList_undefined;
4887 warnClause warnclause = warnClause_undefined;
4889 if (reader_optCheckChar (s, '$'))
4891 defstate = SS_DEFINED;
4892 isnull = NS_UNKNOWN;
4893 exitCode = XK_UNKNOWN;
4895 nullPred = qual_createUnknown ();
4899 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4900 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4901 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4902 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4903 advanceField (s); nullPred = qual_undump (s);
4906 if (reader_optCheckChar (s, '$'))
4909 globs = globSet_undefined;
4911 mods = sRefSet_undefined;
4913 else if (reader_optCheckChar (s, '^'))
4916 globs = globSet_undefined;
4918 mods = sRefSet_undefined;
4922 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4923 advanceField (s); globs = globSet_undump (s);
4924 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4925 advanceField (s); mods = sRefSet_undump (s);
4928 if (reader_optCheckChar (s, '$'))
4935 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4936 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4939 advanceField (s); access = typeIdSet_undump (s);
4942 ** Optional clauses: Start with @<code>:
4945 while (reader_optCheckChar (s, '@'))
4947 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4949 reader_checkChar (s, ':');
4950 warnclause = warnClause_undump (s);
4952 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4954 reader_checkChar (s, ':');
4955 specclauses = stateClauseList_undump (s);
4963 advanceName (s); name = reader_getStringWord (s);
4965 ue = uentry_makeFunctionBase (name, ct, access,
4968 ak, exp, defstate, isnull,
4969 exitCode, specc, nullPred,
4972 fileloc_copy (loc));
4973 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4980 advanceField (s); access = typeIdSet_undump (s);
4981 advanceName (s); name = reader_getStringWord (s);
4983 ue = uentry_makeIterBase (name, access, ct,
4984 fileloc_copy (loc));
4991 advanceField (s); access = typeIdSet_undump (s);
4992 advanceName (s); name = reader_getStringWord (s);
4994 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5004 if (reader_optCheckChar (s, '$'))
5006 val = multiVal_undefined;
5007 access = typeIdSet_undefined;
5008 nullstate = NS_UNKNOWN;
5012 advanceField (s); val = multiVal_undump (s);
5013 advanceField (s); access = typeIdSet_undump (s);
5014 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5017 advanceName (s); name = reader_getStringWord (s);
5019 ue = uentry_makeConstantBase (name, ct, access,
5020 nullstate, fileloc_copy (loc), val);
5029 advanceField (s); rtype = ctype_undump (s);
5030 advanceName (s); name = reader_getStringWord (s);
5031 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5035 llcontbuglit ("uentry_undump: invalid");
5036 ue = uentry_undefined;
5039 llcontbuglit ("uentry_undump: elips marker");
5040 ue = uentry_undefined;
5049 uentry_dump (uentry v)
5051 return (uentry_dumpAux (v, FALSE));
5055 uentry_dumpParam (uentry v)
5057 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5058 ("dump: %s", uentry_unparseFull (v)));
5060 return (uentry_dumpAux (v, TRUE));
5064 uentry_dumpAux (uentry v, bool isParam)
5066 llassert (uentry_isValid (v));
5067 llassert (!uentry_isGlobalMarker (v));
5069 DPRINTF (("Dump uentry: [%p]", v));
5070 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5075 llcontbuglit ("uentry_dump: invalid entry");
5076 return cstring_undefined;
5078 return (message ("!."));
5082 vkind vk = v->info->var->kind;
5083 sstate dss = sRef_getDefState (v->sref);
5084 nstate nst = sRef_getNullState (v->sref);
5085 alkind alk = sRef_getAliasKind (v->sref);
5086 exkind exk = sRef_getExKind (v->sref);
5087 chkind chk = v->info->var->checked;
5089 DPRINTF (("Dumping var"));
5091 if (dss == SS_UNKNOWN
5092 && nst == NS_UNKNOWN
5093 && alk == AK_IMPTEMP
5094 && exk == XO_UNKNOWN
5095 && chk == CH_UNKNOWN)
5097 sdump = cstring_makeLiteral ("$");
5099 else if (dss == SS_DEFINED
5100 && nst == NS_UNKNOWN
5101 && alk == AK_IMPTEMP
5102 && exk == XO_UNKNOWN
5103 && chk == CH_UNKNOWN)
5105 sdump = cstring_makeLiteral ("&");
5107 else if (dss == SS_UNKNOWN
5108 && nst == NS_UNKNOWN
5109 && alk == AK_UNKNOWN
5110 && exk == XO_UNKNOWN
5111 && chk == CH_UNKNOWN)
5113 sdump = cstring_makeLiteral ("^");
5115 else if (exk == XO_UNKNOWN
5116 && chk == CH_UNKNOWN)
5118 sdump = message ("%d@%d@%d&",
5125 sdump = message ("%d@%d@%d@%d@%d",
5136 return (message ("%q|@%d|%q#%s",
5137 ctype_dump (v->utype),
5140 isParam ? cstring_undefined : v->uname));
5144 return (message ("%q|%q#%s",
5145 ctype_dump (v->utype),
5147 isParam ? cstring_undefined : v->uname));
5153 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5155 exkind_unparse (sRef_getExKind (v->sref)),
5156 ctype_unparse (v->utype), (int) v->utype));
5159 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5160 ctype_dump (v->utype),
5161 ynm_unparseCode (v->info->datatype->abs),
5162 ynm_unparseCode (v->info->datatype->mut),
5163 (int) sRef_getDefState (v->sref),
5164 (int) sRef_getNullState (v->sref),
5165 (int) sRef_getAliasKind (v->sref),
5166 (int) sRef_getExKind (v->sref),
5167 ctype_dump (v->info->datatype->type),
5171 cstring sdump, gdump, adump, xdump;
5172 alkind alk = sRef_getAliasKind (v->sref);
5173 exkind exk = sRef_getExKind (v->sref);
5175 if (sRef_getDefState (v->sref) == SS_DEFINED
5176 && !nstate_isKnown (sRef_getNullState (v->sref))
5177 && !exitkind_isKnown (v->info->fcn->exitCode)
5178 && v->info->fcn->specialCode == SPC_NONE
5179 && qual_isUnknown (v->info->fcn->nullPred))
5181 sdump = cstring_makeLiteral ("$");
5185 sdump = message ("@%d@%d@%d@%d@%x",
5186 (int) sRef_getDefState (v->sref),
5187 (int) sRef_getNullState (v->sref),
5188 (int) v->info->fcn->exitCode,
5189 (int) v->info->fcn->specialCode,
5190 qual_dump (v->info->fcn->nullPred));
5193 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5195 gdump = cstring_makeLiteral ("$");
5197 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5198 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5200 gdump = cstring_makeLiteral ("^");
5204 gdump = message ("@%s@%q@%s@%q",
5205 bool_dump (uentry_hasGlobs (v)),
5206 globSet_dump (uentry_getGlobs (v)),
5207 bool_dump (uentry_hasMods (v)),
5208 sRefSet_dump (uentry_getMods (v)));
5211 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5213 adump = cstring_makeLiteral ("$");
5217 adump = message ("@%d@%d", (int) alk, (int) exk);
5220 xdump = cstring_undefined;
5222 if (uentry_hasWarning (v))
5224 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5227 if (uentry_hasStateClauseList (v))
5229 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5232 return (message ("%q%q%q%q@%q%q#%s",
5233 ctype_dump (v->utype),
5237 typeIdSet_dump (uentry_accessType (v)),
5242 return (message ("%q@%q#%s",
5243 ctype_dump (v->utype),
5244 typeIdSet_dump (v->info->iter->access),
5247 return (message ("%q@%q#%s",
5248 ctype_dump (v->utype),
5249 typeIdSet_dump (uentry_accessType (v)),
5256 if (multiVal_isUnknown (uentry_getConstantValue (v))
5257 && typeIdSet_isEmpty (uentry_accessType (v))
5258 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5260 sdump = cstring_makeLiteral ("$");
5264 sdump = message ("@%q@%q@%d",
5265 multiVal_dump (uentry_getConstantValue (v)),
5266 typeIdSet_dump (uentry_accessType (v)),
5267 (int) sRef_getNullState (v->sref));
5270 return (message ("%q%q#%s",
5271 ctype_dump (v->utype),
5278 return (message ("%q@%q#%s",
5279 ctype_dump (v->utype),
5280 ctype_dump (v->info->datatype->type), v->uname));
5287 uentry_unparseAbbrev (uentry v)
5289 if (!uentry_isVariable (v))
5291 llcontbuglit ("uentry_unparseAbbrev: not variable");
5292 return uentry_unparse (v);
5295 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5299 uentry_unparse (uentry v)
5303 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5304 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5306 st = uentry_getName (v);
5308 if (cstring_isDefined (st))
5310 return (ctype_unparseDeclaration (v->utype, st));
5315 return (cstring_copy (ctype_unparse (v->utype)));
5320 uentry_unparseFull (uentry v)
5322 if (uentry_isUndefined (v))
5324 return (cstring_makeLiteral ("<undefined>"));
5330 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5331 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5332 ctype_unparse (v->utype),
5333 fileloc_unparse (uentry_whereSpecified (v)),
5334 fileloc_unparse (uentry_whereDeclared (v)),
5335 fileloc_unparse (uentry_whereDefined (v)));
5337 DPRINTF (("uentry: %s", res));
5339 if (uentry_isDatatype (v))
5341 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5344 (ctype_isDefined (v->info->datatype->type)
5345 ? v->info->datatype->type : ctype_unknown),
5346 ynm_unparse (v->info->datatype->mut),
5347 ynm_unparse (v->info->datatype->abs),
5348 sRef_unparseState (v->sref));
5350 else if (uentry_isFunction (v))
5352 res = message ("%q / sref: %q / mods: %q / "
5353 "globs: %q / clauses: %q / pre: %q / post: %q",
5355 sRef_unparseFull (v->sref),
5356 sRefSet_unparse (v->info->fcn->mods),
5357 globSet_unparse (v->info->fcn->globs),
5358 stateClauseList_unparse (v->info->fcn->specclauses),
5359 functionConstraint_unparse (v->info->fcn->preconditions),
5360 functionConstraint_unparse (v->info->fcn->postconditions));
5362 else if (uentry_isIter (v))
5364 res = message ("%q / sref: %q",
5366 sRef_unparseFull (v->sref));
5368 else if (uentry_isVariable (v))
5370 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5372 sRef_unparseFull (v->sref),
5373 (int) v->info->var->kind,
5374 (int) v->info->var->defstate,
5375 (int) v->info->var->nullstate,
5377 DPRINTF (("sref: [%p]", v->sref));
5378 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5379 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5381 else if (uentry_isConstant (v))
5383 res = message ("%q = %q / %q",
5384 res, multiVal_unparse (uentry_getConstantValue (v)),
5385 sRef_unparseFull (v->sref));
5389 res = message ("%q :: %q", res, uentry_unparse (v));
5396 bool uentry_hasAccessType (uentry e)
5398 if (uentry_isValid (e))
5403 return (!typeIdSet_isEmpty (e->info->iter->access));
5405 return (!typeIdSet_isEmpty (e->info->enditer->access));
5407 return (!typeIdSet_isEmpty (e->info->fcn->access));
5410 return (!typeIdSet_isEmpty (e->info->uconst->access));
5419 typeIdSet uentry_accessType (uentry e)
5421 if (uentry_isValid (e))
5426 return (e->info->iter->access);
5428 return (e->info->enditer->access);
5430 return (e->info->fcn->access);
5433 return (e->info->uconst->access);
5439 return typeIdSet_undefined;
5443 uentry_isVariable (uentry e)
5445 return (uentry_isVar (e));
5449 uentry_isSpecified (uentry e)
5451 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5455 uentry_isReallySpecified (uentry e)
5457 return (uentry_isValid (e)
5458 && fileloc_isRealSpec (e->whereSpecified));
5462 uentry_isVar (uentry e)
5464 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5468 uentry_isFakeTag (uentry e)
5470 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5474 uentry_isDatatype (uentry e)
5476 return (!uentry_isUndefined (e) &&
5477 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5478 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5482 uentry_setAbstract (uentry e)
5486 llassert (uentry_isDatatype (e)
5487 && (ynm_isMaybe (e->info->datatype->abs)));
5489 oldid = ctype_typeId (e->info->datatype->type);
5490 e->info->datatype->abs = YES;
5491 e->info->datatype->type = ctype_createAbstract (oldid);
5495 uentry_setConcrete (uentry e)
5497 llassert (uentry_isDatatype (e)
5498 && (ynm_isMaybe (e->info->datatype->abs)));
5500 e->info->datatype->abs = NO;
5504 uentry_isAbstractDatatype (uentry e)
5506 return (uentry_isDatatype (e)
5507 && (ynm_isOn (e->info->datatype->abs)));
5511 uentry_isMaybeAbstract (uentry e)
5513 return (uentry_isDatatype (e)
5514 && (ynm_isMaybe (e->info->datatype->abs)));
5518 uentry_isMutableDatatype (uentry e)
5520 bool res = uentry_isDatatype (e)
5521 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5527 uentry_isRefCountedDatatype (uentry e)
5529 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5533 uentry_isParam (uentry u)
5535 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5536 || u->info->var->kind == VKYIELDPARAM));
5540 uentry_isExpandedMacro (uentry u)
5542 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5546 uentry_isSefParam (uentry u)
5548 return (uentry_isVariable (u)
5549 && (u->info->var->kind == VKSEFPARAM
5550 || u->info->var->kind == VKREFSEFPARAM
5551 || u->info->var->kind == VKSEFRETPARAM
5552 || u->info->var->kind == VKREFSEFRETPARAM));
5556 uentry_isRefParam (uentry u)
5558 return (uentry_isVariable (u)
5559 && (u->info->var->kind == VKREFPARAM
5560 || u->info->var->kind == VKREFYIELDPARAM
5561 || u->info->var->kind == VKREFSEFPARAM
5562 || u->info->var->kind == VKREFSEFRETPARAM));
5566 uentry_isAnyParam (uentry u)
5568 return (uentry_isVariable (u)
5569 && ((u->info->var->kind == VKPARAM)
5570 || (u->info->var->kind == VKSEFPARAM)
5571 || (u->info->var->kind == VKYIELDPARAM)
5572 || (u->info->var->kind == VKRETPARAM)
5573 || (u->info->var->kind == VKSEFRETPARAM)));
5577 uentry_getDefState (uentry u)
5579 if (uentry_isValid (u))
5581 return (sRef_getDefState (u->sref));
5585 return (SS_UNKNOWN);
5590 uentry_isOut (uentry u)
5592 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5593 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5597 uentry_isPartial (uentry u)
5599 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5600 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5604 uentry_isStateSpecial (uentry u)
5606 return ((uentry_isVariable (u)
5607 && (u->info->var->defstate == SS_SPECIAL))
5608 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5611 exitkind uentry_getExitCode (uentry ue)
5613 if (uentry_isFunction (ue))
5615 return ue->info->fcn->exitCode;
5623 qual uentry_nullPred (uentry u)
5625 llassert (uentry_isRealFunction (u));
5627 if (uentry_isFunction (u))
5629 return (u->info->fcn->nullPred);
5633 return qual_createUnknown ();
5638 ** Note for variables, this is checking the declared state, not the current state.
5642 uentry_possiblyNull (uentry u)
5644 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5645 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5649 uentry_getAliasKind (uentry u)
5651 if (uentry_isValid (u))
5653 return (sRef_getAliasKind (uentry_getSref (u)));
5662 uentry_getExpKind (uentry u)
5664 if (uentry_isValid (u))
5666 return (sRef_getExKind (uentry_getSref (u)));
5675 uentry_isIter (uentry e)
5677 return (!uentry_isUndefined (e) && e->ukind == KITER);
5681 uentry_isEndIter (uentry e)
5683 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5687 uentry_isRealFunction (uentry e)
5689 return (uentry_isFunction (e) ||
5690 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5694 uentry_hasName (uentry e)
5696 if (uentry_isValid (e))
5698 cstring s = e->uname;
5700 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5701 || uentry_isFakeTag (e)));
5710 ** Returns true for fake tags.
5711 ** This is used for dumping the library
5714 bool uentry_hasRealName (uentry e)
5716 return (uentry_isValid (e)
5717 && cstring_isNonEmpty (e->uname)
5718 && !uentry_isGlobalMarker (e));
5722 /*@observer@*/ globSet
5723 uentry_getGlobs (uentry l)
5725 if (uentry_isInvalid (l))
5727 return globSet_undefined;
5730 if (uentry_isFunction (l))
5732 return l->info->fcn->globs;
5734 else if (uentry_isIter (l))
5736 return l->info->iter->globs;
5738 else if (uentry_isEndIter (l))
5740 return globSet_undefined;
5744 if (l->ukind == KVAR)
5746 llcontbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5748 ekind_unparse (l->ukind)));
5752 llcontbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5754 ekind_unparse (l->ukind)));
5757 return globSet_undefined;
5761 /*@observer@*/ sRefSet
5762 uentry_getMods (uentry l)
5764 llassert (uentry_isValid (l));
5766 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5768 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5769 return sRefSet_undefined;
5772 if (uentry_isFunction (l))
5774 return l->info->fcn->mods;
5776 else if (uentry_isIter (l))
5778 return l->info->iter->mods;
5780 else if (uentry_isEndIter (l))
5782 return sRefSet_undefined;
5791 uentry_getKind (uentry e)
5793 llassert (uentry_isValid (e));
5798 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5800 llassert (uentry_isEitherConstant (e));
5801 return (sRef_getValue (e->sref));
5804 /*@observer@*/ uentryList
5805 uentry_getParams (uentry l)
5807 if (uentry_isInvalid (l)) return uentryList_undefined;
5814 ctype ct = l->utype;
5816 if (ctype_isFunction (ct))
5818 return (ctype_argsFunction (ct));
5822 return uentryList_undefined;
5827 ctype ct = l->utype;
5829 llassert (ctype_isFunction (ct));
5830 return (ctype_argsFunction (ct));
5837 /*@observer@*/ cstring
5838 uentry_rawName (uentry e)
5840 if (uentry_isValid (e))
5846 return cstring_undefined;
5851 uentry_getOptName (uentry e)
5853 cstring s = uentry_getName (e);
5855 if (cstring_isDefined (s))
5857 s = cstring_appendChar (s, ' ');
5864 uentry_getName (uentry e)
5866 cstring ret = cstring_undefined;
5868 if (uentry_isValid (e))
5870 if (uentry_isAnyTag (e))
5872 ret = fixTagName (e->uname);
5874 else if (uentry_isAnyParam (e))
5876 ret = cstring_copy (fixParamName (e->uname));
5880 ret = cstring_copy (e->uname);
5887 cstring uentry_observeRealName (uentry e)
5889 cstring ret = cstring_undefined;
5891 if (uentry_isValid (e))
5893 if (uentry_isAnyTag (e))
5895 if (isFakeTag (e->uname))
5897 ret = cstring_undefined;
5901 ret = plainTagName (e->uname);
5904 else if (uentry_isAnyParam (e))
5906 ret = fixParamName (e->uname);
5917 cstring uentry_getRealName (uentry e)
5919 if (uentry_isValid (e))
5921 if (uentry_isAnyTag (e))
5923 return (cstring_undefined);
5930 return cstring_undefined;
5933 ctype uentry_getType (uentry e)
5935 if (uentry_isValid (e))
5941 return ctype_unknown;
5945 fileloc uentry_whereLast (uentry e)
5949 if (uentry_isInvalid (e))
5951 return fileloc_undefined;
5954 loc = e->whereDefined;
5956 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5961 loc = uentry_whereDeclared (e);
5963 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5968 loc = uentry_whereSpecified (e);
5972 fileloc uentry_whereEither (uentry e)
5974 if (uentry_isInvalid (e)) return fileloc_undefined;
5976 if (fileloc_isDefined (e->whereDefined)
5977 && !fileloc_isExternal (e->whereDefined))
5979 return e->whereDefined;
5981 else if (fileloc_isDefined (e->whereDeclared))
5983 return e->whereDeclared;
5987 return e->whereSpecified;
5991 fileloc uentry_whereSpecified (uentry e)
5993 if (uentry_isInvalid (e)) return fileloc_undefined;
5995 return (e->whereSpecified);
5998 fileloc uentry_whereDefined (uentry e)
6000 if (uentry_isInvalid (e)) return fileloc_undefined;
6002 return (e->whereDefined);
6005 fileloc uentry_whereDeclared (uentry e)
6007 if (uentry_isInvalid (e)) return fileloc_undefined;
6009 return (e->whereDeclared);
6012 /*@observer@*/ fileloc
6013 uentry_whereEarliest (uentry e)
6015 if (uentry_isInvalid (e)) return fileloc_undefined;
6017 if (fileloc_isDefined (e->whereSpecified))
6019 return (e->whereSpecified);
6021 else if (fileloc_isDefined (e->whereDeclared))
6023 return (e->whereDeclared);
6027 return e->whereDefined;
6032 uentry_setFunctionDefined (uentry e, fileloc loc)
6034 if (uentry_isValid (e))
6036 llassert (uentry_isFunction (e));
6038 if (fileloc_isUndefined (e->whereDeclared))
6040 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6043 if (!fileloc_isDefined (e->whereDefined))
6045 e->whereDefined = fileloc_update (e->whereDefined, loc);
6051 uentry_setDeclDef (uentry e, fileloc f)
6053 uentry_setDeclared (e, f);
6055 if (!uentry_isFunction (e)
6056 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6058 uentry_setDefined (e, f);
6063 uentry_setDeclaredForce (uentry e, fileloc f)
6065 llassert (uentry_isValid (e));
6066 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6070 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6072 llassert (uentry_isValid (e));
6073 fileloc_free (e->whereDeclared);
6074 e->whereDeclared = f;
6078 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6082 llassert (uentry_isValid (e));
6083 oldloc = e->whereDeclared;
6085 if (fileloc_isDefined (oldloc))
6087 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6089 e->whereDeclared = f;
6090 fileloc_free (oldloc);
6099 e->whereDeclared = f;
6100 fileloc_free (oldloc);
6105 uentry_setDeclared (uentry e, fileloc f)
6109 llassert (uentry_isValid (e));
6110 oldloc = e->whereDeclared;
6112 if (fileloc_isDefined (oldloc))
6114 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6116 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6125 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6130 uentry_clearDefined (uentry e)
6132 if (uentry_isValid (e))
6134 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6139 uentry_setDefined (uentry e, fileloc f)
6143 llassert (uentry_isValid (e));
6144 oldloc = e->whereDefined;
6146 if (fileloc_isDefined (oldloc))
6148 if (fileloc_isLib (oldloc)
6149 || fileloc_isImport (oldloc)
6150 || fileloc_isBuiltin (oldloc)
6151 || fileloc_isPreproc (oldloc))
6153 e->whereDefined = fileloc_update (e->whereDefined, f);
6157 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6163 if (optgenerror (FLG_REDEF,
6164 message ("%s %q redefined",
6165 ekind_capName (e->ukind),
6166 uentry_getName (e)),
6169 llgenindentmsg (message ("Previous definition of %q",
6170 uentry_getName (e)),
6178 e->whereDefined = fileloc_update (e->whereDefined, f);
6183 uentry_isCodeDefined (uentry e)
6185 llassert (uentry_isValid (e));
6187 return (fileloc_isDefined (e->whereDefined));
6191 uentry_isDeclared (uentry e)
6193 if (uentry_isValid (e))
6195 return (fileloc_isDefined (e->whereDeclared));
6201 sRef uentry_getSref (uentry e)
6203 /* not true, used for functions too (but shouldn't be? */
6204 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6206 if (uentry_isInvalid (e)) return sRef_undefined;
6211 sRef uentry_getOrigSref (uentry e)
6213 /*@i523*/ /* evans 2001-09-09 - need to fix this
6214 if (uentry_isValid (e))
6216 if (uentry_isVariable (e))
6218 return e->info->var->origsref;
6222 sRef sr = sRef_copy (uentry_getSref (e));
6224 sRef_resetState (sr);
6225 sRef_clearDerived (sr);
6231 return sRef_undefined;
6235 if (uentry_isValid (e))
6237 sRef sr = sRef_copy (uentry_getSref (e));
6239 sRef_resetState (sr);
6240 sRef_clearDerived (sr);
6242 if (uentry_isVariable (e))
6244 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6245 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6252 return sRef_undefined;
6257 ** requires: uentry e is not in a hashed symbol table
6261 uentry_setName (uentry e, /*@only@*/ cstring n)
6263 llassert (uentry_isValid (e));
6265 cstring_free (e->uname);
6270 uentry_setType (uentry e, ctype t)
6272 if (uentry_isValid (e))
6275 sRef_setType (e->sref, t);
6280 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6283 ctype rettype = ctype_unknown;
6285 llassert (uentry_isValid (ue));
6287 uentry_convertVarFunction (ue);
6288 llassert (uentry_isFunction (ue));
6290 rct = ctype_realType (ue->utype);
6292 if (ctype_isFunction (rct))
6294 rettype = ctype_getReturnType (rct);
6297 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6301 uentry_setRefParam (uentry e)
6303 if (!uentry_isVar (e))
6305 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6309 if (e->info->var->kind == VKSEFPARAM)
6311 e->info->var->kind = VKREFSEFPARAM;
6313 else if (e->info->var->kind == VKSEFRETPARAM)
6315 e->info->var->kind = VKREFSEFRETPARAM;
6317 else if (e->info->var->kind == VKYIELDPARAM)
6319 e->info->var->kind = VKREFYIELDPARAM;
6323 e->info->var->kind = VKREFPARAM;
6329 uentry_setParam (uentry e)
6331 if (!uentry_isVar (e))
6333 if (uentry_isElipsisMarker (e))
6339 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6346 if (e->info->var->kind == VKYIELDPARAM
6347 || e->info->var->kind == VKSEFPARAM
6348 || e->info->var->kind == VKSEFRETPARAM)
6354 e->info->var->kind = VKPARAM;
6358 e->uname = makeParam (e->uname);
6359 cstring_free (oldname);
6364 uentry_setSref (uentry e, sRef s)
6366 if (uentry_isValid (e))
6368 if (sRef_isValid (e->sref))
6370 sRef_mergeStateQuietReverse (e->sref, s);
6374 e->sref = sRef_saveCopy (s);
6380 uentry_getAbstractType (uentry e)
6382 llassert (uentry_isDatatype (e));
6385 ** This assertion removed.
6386 ** Okay to have undefined type, for system types
6388 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6389 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6394 if (ctype_isUndefined (e->info->datatype->type))
6396 return ctype_unknown;
6400 ** Sadly, a kludge...
6403 if (ctype_isUserBool (e->info->datatype->type)) {
6407 return e->info->datatype->type;
6410 ctype uentry_getRealType (uentry e)
6413 typeId uid = USYMIDINVALID;
6415 if (uentry_isInvalid (e))
6417 return ctype_unknown;
6420 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6422 if (uentry_isAnyTag (e))
6427 if (uentry_isAbstractType (e))
6429 ct = uentry_getAbstractType (e);
6431 if (ctype_isManifestBool (ct)) {
6435 llassert (ctype_isUA (ct));
6437 uid = ctype_typeId (ct);
6439 if (!context_hasAccess (uid))
6445 ct = uentry_getType (e);
6447 /* if (ctype_isUserBool (ct)) return ct; */
6449 if (ctype_isManifestBool (ct)) {
6453 if (ctype_isUA (ct))
6455 usymId iid = ctype_typeId (ct);
6457 if (usymId_equal (iid, uid))
6459 llcontbug (message ("uentry_getRealType: recursive type! %s",
6460 ctype_unparse (ct)));
6465 /* evs 2000-07-25: possible infinite recursion ? */
6466 uentry ue2 = usymtab_getTypeEntry (iid);
6470 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6471 return ctype_unknown;
6474 return uentry_getRealType (ue2);
6483 ctype uentry_getForceRealType (uentry e)
6486 typeId uid = USYMIDINVALID;
6488 if (uentry_isInvalid (e))
6490 return ctype_unknown;
6493 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6495 if (uentry_isAnyTag (e))
6500 if (uentry_isAbstractType (e))
6502 ct = uentry_getAbstractType (e);
6503 llassert (ctype_isUA (ct));
6505 uid = ctype_typeId (ct);
6506 /* no check for access! */
6509 ct = uentry_getType (e);
6511 /* evs 2000-07-25 */
6512 /* if (ctype_isUserBool (ct)) return ct; */
6514 if (ctype_isManifestBool (ct)) {
6518 if (ctype_isUA (ct))
6520 usymId iid = ctype_typeId (ct);
6522 if (usymId_equal (iid, uid))
6524 llcontbug (message ("uentry_getRealType: recursive type! %s",
6525 ctype_unparse (ct)));
6530 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6539 uentry uentry_nameCopy (cstring name, uentry e)
6541 uentry enew = uentry_alloc ();
6543 llassert (uentry_isValid (e));
6545 /* enew->shallowCopy = FALSE; */
6546 enew->ukind = e->ukind;
6548 enew->utype = e->utype;
6549 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6550 enew->whereDefined = fileloc_copy (e->whereDefined);
6551 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6552 enew->sref = sRef_copy (e->sref);
6553 enew->used = e->used;
6555 enew->isPrivate = e->isPrivate;
6556 enew->hasNameError = FALSE;
6558 enew->uses = filelocList_new ();
6559 enew->warn = warnClause_undefined;
6561 enew->storageclass = e->storageclass;
6562 enew->info = uinfo_copy (e->info, e->ukind);
6568 uentry_setDatatype (uentry e, usymId uid)
6570 llassert (uentry_isDatatype (e));
6572 if (uentry_isAbstractType (e))
6574 e->info->datatype->type = ctype_createAbstract (uid);
6578 e->info->datatype->type = ctype_createUser (uid);
6583 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6584 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6587 llassert (uentry_isValid (e));
6589 if (fileloc_isSpec (f) || fileloc_isImport (f))
6591 e->whereSpecified = f;
6592 e->whereDeclared = fileloc_undefined;
6593 e->whereDefined = fileloc_undefined;
6597 e->whereSpecified = fileloc_undefined;
6598 e->whereDeclared = f;
6599 e->whereDefined = fileloc_undefined;
6602 llassert (fileloc_storable (f));
6606 ucinfo_free (/*@only@*/ ucinfo u)
6612 uvinfo_free (/*@only@*/ uvinfo u)
6614 /*drl7x added 6/29/01 */
6615 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6620 udinfo_free (/*@only@*/ udinfo u)
6626 ufinfo_free (/*@only@*/ ufinfo u)
6628 globSet_free (u->globs);
6629 sRefSet_free (u->mods);
6630 stateClauseList_free (u->specclauses);
6635 uiinfo_free (/*@only@*/ uiinfo u)
6641 ueinfo_free (/*@only@*/ ueinfo u)
6646 static /*@only@*/ ucinfo
6647 ucinfo_copy (ucinfo u)
6649 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6650 ret->access = u->access;
6651 ret->macro = u->macro;
6655 static /*@only@*/ uvinfo
6656 uvinfo_copy (uvinfo u)
6658 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6660 ret->kind = u->kind;
6661 ret->nullstate = u->nullstate;
6662 ret->defstate = u->defstate;
6663 ret->checked = u->checked;
6665 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6667 /* drl added 07-02-001 */
6668 /* copy null terminated information */
6670 if (u->bufinfo != NULL)
6672 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6673 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6674 ret->bufinfo->size = u->bufinfo->size;
6675 ret->bufinfo->len = u->bufinfo->len;
6680 ret->bufinfo = NULL;
6686 static /*@only@*/ udinfo
6687 udinfo_copy (udinfo u)
6689 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6693 ret->type = u->type;
6698 static /*@only@*/ ufinfo
6699 ufinfo_copy (ufinfo u)
6701 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6703 ret->hasGlobs = u->hasGlobs;
6704 ret->hasMods = u->hasMods;
6705 ret->exitCode = u->exitCode;
6706 ret->specialCode = u->specialCode;
6707 ret->nullPred = u->nullPred;
6708 ret->access = u->access;
6709 ret->globs = globSet_newCopy (u->globs);
6710 ret->mods = sRefSet_newCopy (u->mods);
6711 ret->defparams = u->defparams;
6712 ret->specclauses = stateClauseList_copy (u->specclauses);
6714 ret->preconditions = functionConstraint_copy (u->preconditions);
6715 ret->postconditions = functionConstraint_copy (u->postconditions);
6720 static /*@only@*/ uiinfo
6721 uiinfo_copy (uiinfo u)
6723 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6725 ret->access = u->access;
6726 ret->globs = globSet_newCopy (u->globs);
6727 ret->mods = sRefSet_newCopy (u->mods);
6732 static /*@only@*/ ueinfo
6733 ueinfo_copy (ueinfo u)
6735 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6737 ret->access = u->access;
6742 uinfo_free (uinfo u, ekind kind)
6747 case KCONST: ucinfo_free (u->uconst); break;
6748 case KVAR: uvinfo_free (u->var); break;
6752 case KDATATYPE: udinfo_free (u->datatype); break;
6753 case KFCN: ufinfo_free (u->fcn); break;
6754 case KITER: uiinfo_free (u->iter); break;
6755 case KENDITER: ueinfo_free (u->enditer); break;
6756 case KELIPSMARKER: break;
6757 case KINVALID: break;
6763 static /*@only@*/ /*@null@*/ uinfo
6764 uinfo_copy (uinfo u, ekind kind)
6766 if (kind == KELIPSMARKER || kind == KINVALID)
6772 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6777 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6778 case KVAR: ret->var = uvinfo_copy (u->var); break;
6782 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6783 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6784 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6785 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6793 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6795 filelocList_free (e->uses);
6796 cstring_free (e->uname);
6798 uinfo_free (e->info, e->ukind);
6800 fileloc_free (e->whereSpecified);
6801 fileloc_free (e->whereDefined);
6802 fileloc_free (e->whereDeclared);
6804 warnClause_free (e->warn);
6810 extern void uentry_markOwned (/*@owned@*/ uentry u)
6812 sfreeEventually (u);
6816 uentry_free (/*@only@*/ uentry e)
6818 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6820 uentry_reallyFree (e);
6825 ** For uentry's in the global or file scope
6829 uentry_freeComplete (/*@only@*/ uentry e)
6831 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6833 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6834 /*@i@*/ sRef_free (e->sref);
6835 e->sref = sRef_undefined;
6836 uentry_reallyFree (e);
6841 ** requires old->kind != new->kind, old->uname = new->uname
6845 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6847 llassert (uentry_isValid (old));
6848 llassert (uentry_isValid (unew));
6850 if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
6851 && (fileloc_isPreproc (uentry_whereDeclared (old))
6852 || ctype_isUnknown (old->utype))
6853 && !uentry_isSpecified (old))
6861 if (!uentry_isDeclared (old))
6863 if (uentry_isSpecified (old))
6865 if (uentry_isSpecified (unew))
6867 llbuglit ("Respecification!");
6869 else if (uentry_isDeclared (unew))
6873 message ("%s %q inconsistently declared as %s: %t",
6874 ekind_capName (old->ukind),
6875 uentry_getName (unew),
6876 ekind_unparseLong (unew->ukind),
6878 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6880 uentry_showWhereLastKind (old);
6892 message ("%s %q inconsistently declared as %s: %t",
6893 ekind_capName (old->ukind),
6894 uentry_getName (unew),
6895 ekind_unparseLong (unew->ukind),
6897 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6899 uentry_showWhereLastKind (old);
6905 llassert (uentry_isDeclared (unew));
6907 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6908 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6912 message ("%s %q inconsistently redeclared as %s",
6913 ekind_capName (old->ukind),
6914 uentry_getName (unew),
6915 ekind_unparseLong (unew->ukind)),
6916 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6918 uentry_showWhereLastKind (old);
6924 uentry_updateInto (old, unew);
6928 ** def is the definition of spec, modifies spec
6930 ** reports any inconsistencies
6931 ** returns the summary of all available information
6932 ** if spec and def are inconsistent, def is returned
6936 uentry_showWhereLast (uentry spec)
6938 if (uentry_isValid (spec))
6940 if (fileloc_isDefined (spec->whereDefined)
6941 && !fileloc_isLib (spec->whereDefined)
6942 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6944 llgenindentmsg (message ("Previous definition of %q: %t",
6945 uentry_getName (spec),
6946 uentry_getType (spec)),
6947 uentry_whereDefined (spec));
6949 else if (uentry_isDeclared (spec))
6951 llgenindentmsg (message ("Previous declaration of %q: %t",
6952 uentry_getName (spec),
6953 uentry_getType (spec)),
6954 uentry_whereDeclared (spec));
6956 else if (uentry_isSpecified (spec))
6958 if (uentry_hasName (spec))
6960 llgenindentmsg (message ("Specification of %q: %t",
6961 uentry_getName (spec),
6962 uentry_getType (spec)),
6963 uentry_whereSpecified (spec));
6967 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6968 uentry_whereSpecified (spec));
6973 /* nothing to show */
6979 uentry_showWhereLastKind (uentry spec)
6981 if (uentry_isValid (spec))
6983 if (fileloc_isDefined (spec->whereDefined)
6984 && !fileloc_isLib (spec->whereDefined)
6985 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6987 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6988 uentry_getName (spec),
6989 ekind_unparseLong (spec->ukind),
6990 uentry_getType (spec)),
6991 uentry_whereDefined (spec));
6993 else if (uentry_isDeclared (spec))
6995 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6996 uentry_getName (spec),
6997 ekind_unparseLong (spec->ukind),
6998 uentry_getType (spec)),
6999 uentry_whereDeclared (spec));
7001 else if (uentry_isSpecified (spec))
7003 if (uentry_hasName (spec))
7005 llgenindentmsg (message ("Specification of %q as %s: %t",
7006 uentry_getName (spec),
7007 ekind_unparseLong (spec->ukind),
7008 uentry_getType (spec)),
7009 uentry_whereSpecified (spec));
7013 llgenindentmsg (message ("Specification as %s: %t",
7014 ekind_unparseLong (spec->ukind),
7015 uentry_getType (spec)),
7016 uentry_whereSpecified (spec));
7021 /* nothing to show */
7027 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7029 fileloc loc = uentry_whereDefined (ce);
7031 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7033 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7037 loc = uentry_whereSpecified (ce);
7039 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7041 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7046 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7048 if (uentry_isDeclared (spec))
7050 llgenindentmsg (message ("Previous declaration of %q: %q",
7051 uentry_getName (spec), extra),
7052 uentry_whereDeclared (spec));
7054 else if (uentry_isSpecified (spec))
7056 llgenindentmsg (message ("Specification of %q: %q",
7057 uentry_getName (spec), extra),
7058 uentry_whereSpecified (spec));
7062 cstring_free (extra);
7067 uentry_showWhereDeclared (uentry spec)
7069 if (uentry_isDeclared (spec))
7071 if (uentry_hasName (spec))
7073 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7074 uentry_whereDeclared (spec));
7078 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7081 else if (uentry_isSpecified (spec))
7083 if (uentry_hasName (spec))
7085 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7086 uentry_whereSpecified (spec));
7090 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7095 /* nothing to show */
7101 uentry_showWhereAny (uentry spec)
7103 if (uentry_isDeclared (spec))
7105 if (uentry_hasName (spec))
7107 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7108 uentry_whereDeclared (spec));
7112 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7115 else if (uentry_isSpecified (spec))
7117 if (uentry_hasName (spec))
7119 llgenindentmsg (message ("Specification of %q",
7120 uentry_getName (spec)),
7121 uentry_whereSpecified (spec));
7125 llgenindentmsg (cstring_makeLiteral ("Specification"),
7126 uentry_whereSpecified (spec));
7129 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7131 if (uentry_hasName (spec))
7133 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7134 uentry_whereDefined (spec));
7138 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7143 /* nothing to show */
7148 uentry_showWhereDefined (uentry spec)
7150 if (uentry_isCodeDefined (spec))
7152 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7153 uentry_whereDefined (spec));
7158 uentry_showWhereLastPlain (uentry spec)
7160 if (uentry_isDeclared (spec))
7162 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7163 uentry_whereDeclared (spec));
7165 else if (uentry_isSpecified (spec))
7167 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7168 uentry_whereSpecified (spec));
7176 uentry_showWhereLastVal (uentry spec, cstring val)
7178 if (uentry_isDeclared (spec))
7180 llgenindentmsg (message ("Previous declaration of %q: %s",
7181 uentry_getName (spec), val),
7182 uentry_whereDeclared (spec));
7184 else if (uentry_isSpecified (spec))
7186 llgenindentmsg (message ("Specification of %q: %s",
7187 uentry_getName (spec), val),
7188 uentry_whereSpecified (spec));
7196 uentry_showWhereSpecified (uentry spec)
7198 if (uentry_isSpecified (spec))
7200 if (uentry_hasName (spec))
7202 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7203 uentry_whereSpecified (spec));
7207 llgenindentmsg (cstring_makeLiteral ("Specification"),
7208 uentry_whereSpecified (spec));
7211 else if (uentry_isDeclared (spec))
7213 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7214 uentry_whereDeclared (spec));
7218 /* nothing to show */
7223 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7225 if (uentry_isSpecified (spec))
7227 if (uentry_hasName (spec))
7229 llgenindentmsg (message ("Specification of %q: %q",
7230 uentry_getName (spec), s),
7231 uentry_whereSpecified (spec));
7235 llgenindentmsg (message ("Specification: %q", s),
7236 uentry_whereSpecified (spec));
7239 else if (uentry_isDeclared (spec))
7241 llgenindentmsg (message ("Declaration of %q: %q",
7242 uentry_getName (spec), s),
7243 uentry_whereDeclared (spec));
7247 llgenindentmsg (message ("Previous: %q", s),
7248 uentry_whereLast (spec));
7257 checkStructConformance (uentry old, uentry unew)
7260 uentryList fold, fnew;
7263 ** requires: types of old and new are structs or unions
7266 llassert (uentry_isValid (old));
7267 llassert (uentry_isValid (unew));
7269 oldr = ctype_realType (old->utype);
7270 fold = ctype_getFields (oldr);
7272 newr = ctype_realType (unew->utype);
7273 fnew = ctype_getFields (newr);
7275 if (!uentryList_matchFields (fold, fnew))
7277 if (fileloc_equal (uentry_whereLast (old),
7278 uentry_whereLast (unew)))
7286 message ("%q %q %rdeclared with fields { %q }, %s "
7287 "with fields { %q }",
7288 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7289 uentry_getName (old),
7290 uentry_isDeclared (old),
7291 uentryList_unparseAbbrev (fnew),
7292 uentry_specOrDefName (old),
7293 uentryList_unparseAbbrev (fold)),
7294 uentry_whereDeclared (unew)))
7296 uentry_showWhereLastPlain (old);
7297 uentryList_showFieldDifference (fold, fnew);
7301 old->utype = unew->utype;
7306 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7309 ** requires old and new are enums
7312 ctype rold = ctype_realType (old->utype);
7313 ctype rnew = ctype_realType (unew->utype);
7314 enumNameList eold = ctype_elist (rold);
7315 enumNameList enew = ctype_elist (rnew);
7317 if (!enumNameList_match (eold, enew))
7321 message ("Enum %q declared with members { %q } but "
7322 "%s with members { %q }",
7323 uentry_getName (old),
7324 enumNameList_unparse (enew),
7325 uentry_specOrDefName (old),
7326 enumNameList_unparse (eold)),
7327 uentry_whereDeclared (unew)))
7329 uentry_showWhereSpecified (old);
7330 old->utype = unew->utype;
7336 ** either oldCurrent or newCurrent may be undefined!
7340 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7341 uentry unew, uentry newCurrent, ctype newType,
7344 bool hasError = FALSE;
7346 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7348 if (uentry_hasName (newCurrent))
7350 hasError = optgenerror
7352 message ("Parameter %d, %q, of function %q has inconsistent type: "
7353 "declared %t, %s %t",
7354 paramno + 1, uentry_getName (newCurrent),
7355 uentry_getName (unew),
7356 newType, uentry_specOrDefName (old), oldType),
7357 uentry_whereDeclared (newCurrent));
7361 hasError = optgenerror
7363 message ("Parameter %d of function %q has inconsistent type: "
7364 "declared %t, %s %t",
7365 paramno + 1, uentry_getName (unew),
7366 newType, uentry_specOrDefName (old), oldType),
7367 uentry_whereDeclared (newCurrent));
7369 DPRINTF (("type: %s / %s",
7370 ctype_unparse (newType),
7371 ctype_unparse (ctype_realType (newType))));
7376 if (uentry_isDeclared (unew))
7378 hasError = optgenerror
7380 message ("Parameter %d of function %s has inconsistent type: "
7381 "declared %t, %s %t",
7382 paramno + 1, unew->uname,
7383 newType, uentry_specOrDefName (old), oldType),
7384 uentry_whereDeclared (unew));
7388 hasError = optgenerror
7390 message ("Parameter %d of function %s has inconsistent type: "
7391 "declared %t, %s %t",
7392 paramno + 1, unew->uname,
7393 newType, uentry_specOrDefName (old), oldType),
7394 uentry_whereDeclared (unew));
7400 DPRINTF (("Here: %s / %s",
7401 uentry_unparseFull (oldCurrent),
7402 uentry_unparseFull (newCurrent)));
7404 if (!uentry_isUndefined (oldCurrent))
7406 if (!uentry_isUndefined (newCurrent)
7407 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7409 uentry_showWhereLast (oldCurrent);
7413 uentry_showWhereLastPlain (old);
7416 uentry_setType (oldCurrent, newType);
7420 uentry_showWhereLastPlain (old);
7426 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7430 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7432 uentry_isDeclared (old),
7433 uentryList_size (uentry_getParams (unew)),
7434 uentry_specOrDefName (old),
7435 uentryList_size (uentry_getParams (old))),
7436 uentry_whereDeclared (unew)))
7438 uentry_showWhereLastPlain (old);
7443 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7447 message ("Function %s inconsistently %rdeclared to return %t",
7449 uentry_isDeclared (old),
7450 ctype_getReturnType (unew->utype)),
7451 uentry_whereDeclared (unew)))
7453 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7457 static cstring paramStorageName (uentry ue)
7459 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7462 static cstring fcnErrName (uentry ue)
7464 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7467 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7469 if (uentry_isVar (ue))
7471 return (checkedName (ue->info->var->checked));
7475 return (cstring_makeLiteralTemp ("<checked invalid>"));
7479 static cstring checkedName (chkind checked)
7483 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7484 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7485 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7486 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7487 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7493 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7498 if (uentry_isVar (unew))
7500 llassert (uentry_isVar (old));
7502 oldState = old->info->var->nullstate;
7503 newState = unew->info->var->nullstate;
7507 oldState = sRef_getNullState (old->sref);
7508 newState = sRef_getNullState (unew->sref);
7511 if (oldState == NS_ABSNULL)
7513 if (uentry_isVar (old))
7515 old->info->var->nullstate = newState;
7518 sRef_mergeNullState (old->sref, newState);
7520 else if (newState == NS_UNKNOWN)
7522 if (completeConform && newState != oldState
7523 && uentry_isReallySpecified (old))
7527 message ("%s %q specified as %s, but declared without %s qualifier",
7528 ekind_capName (unew->ukind),
7529 uentry_getName (unew),
7530 nstate_unparse (oldState),
7531 nstate_unparse (oldState)),
7532 uentry_whereDeclared (unew)))
7534 uentry_showWhereSpecified (old);
7538 if (uentry_isVar (unew))
7540 unew->info->var->nullstate = oldState;
7543 sRef_mergeNullState (unew->sref, oldState);
7545 else if (newState == NS_POSNULL)
7547 if (oldState == NS_MNOTNULL
7548 && (ctype_isUA (unew->utype)
7549 || (uentry_isFunction (unew)
7550 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7552 if (uentry_isVar (unew))
7554 unew->info->var->nullstate = oldState;
7557 sRef_mergeNullState (unew->sref, oldState);
7561 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7562 || oldState == NS_UNKNOWN)
7569 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7571 uentry_ekindName (unew),
7572 uentry_getName (unew),
7573 uentry_isDeclared (old),
7575 uentry_specOrDefName (old),
7576 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7577 uentry_whereDeclared (unew)))
7579 uentry_showWhereSpecified (old);
7584 if (uentry_isVar (old))
7586 old->info->var->nullstate = newState;
7589 sRef_mergeNullState (old->sref, newState);
7592 else if (newState == NS_MNOTNULL)
7594 if (oldState != NS_MNOTNULL)
7600 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7601 "%s without notnull qualifier",
7602 uentry_ekindName (unew),
7603 uentry_getName (unew),
7604 uentry_isDeclared (old),
7606 uentry_specOrDefName (old)),
7607 uentry_whereDeclared (unew)))
7609 uentry_showWhereSpecified (old);
7613 if (uentry_isVar (old))
7615 old->info->var->nullstate = newState;
7618 sRef_mergeNullState (old->sref, newState);
7623 if (uentry_isVar (unew))
7625 unew->info->var->nullstate = oldState;
7628 sRef_mergeNullState (unew->sref, oldState);
7633 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7634 bool mustConform, bool completeConform)
7640 if (uentry_isVar (old) && uentry_isVar (unew))
7642 oldState = old->info->var->defstate;
7643 newState = unew->info->var->defstate;
7648 oldState = sRef_getDefState (old->sref);
7649 newState = sRef_getDefState (unew->sref);
7652 if (newState != oldState
7653 && newState != SS_UNKNOWN
7654 && newState != SS_DEFINED)
7660 message ("%s %q inconsistently %rdeclared %s %s %s, "
7662 uentry_ekindName (unew),
7663 uentry_getName (unew),
7664 uentry_isDeclared (old),
7666 sstate_unparse (newState),
7667 paramStorageName (unew),
7668 uentry_specOrDefName (old),
7670 sstate_unparse (oldState),
7671 paramStorageName (unew)),
7672 uentry_whereDeclared (unew)))
7674 uentry_showWhereSpecified (old);
7678 if (vars) old->info->var->defstate = newState;
7679 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7684 && (newState != oldState) && (oldState != SS_DEFINED)
7685 && uentry_isReallySpecified (old))
7689 message ("%s %q specified as %s, but declared without %s qualifier",
7690 ekind_capName (unew->ukind),
7691 uentry_getName (unew),
7692 sstate_unparse (oldState),
7693 sstate_unparse (oldState)),
7694 uentry_whereDeclared (unew)))
7696 uentry_showWhereSpecified (old);
7700 if (vars) unew->info->var->defstate = oldState;
7701 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7706 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7707 bool mustConform, bool completeConform)
7712 oldKind = sRef_getAliasKind (old->sref);
7713 newKind = sRef_getAliasKind (unew->sref);
7715 if (alkind_isImplicit (newKind)
7716 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7718 if (completeConform && !alkind_equal (newKind, oldKind)
7719 && uentry_isReallySpecified (old))
7723 message ("%s %q specified as %s, but declared without "
7724 "explicit alias qualifier",
7725 ekind_capName (unew->ukind),
7726 uentry_getName (unew),
7727 alkind_unparse (oldKind)),
7728 uentry_whereDeclared (unew)))
7730 uentry_showWhereSpecified (old);
7735 ** This really shouldn't be necessary, but it is!
7736 ** Function params (?) use new here.
7739 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7743 if (alkind_isKnown (newKind))
7745 if (!alkind_equal (oldKind, newKind))
7747 if (alkind_isKnown (oldKind))
7752 message ("%s %q inconsistently %rdeclared %s %s storage, "
7754 uentry_ekindName (unew),
7755 uentry_getName (unew),
7756 uentry_isDeclared (old),
7758 alkind_unparse (newKind),
7759 uentry_specOrDefName (old),
7760 alkind_unparse (oldKind)),
7761 uentry_whereDeclared (unew)))
7763 uentry_showWhereSpecified (old);
7765 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7766 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7767 sRef_setAliasKind (old->sref, AK_ERROR,
7768 uentry_whereDeclared (unew));
7772 sRef_setAliasKind (old->sref, newKind,
7773 uentry_whereDeclared (unew));
7778 if (!(alkind_isImplicit (newKind)))
7781 !uentry_isFunction (unew) &&
7784 message ("%s %q inconsistently %rdeclared %s %s storage, "
7785 "implicitly %s as temp storage",
7786 uentry_ekindName (unew),
7787 uentry_getName (unew),
7788 uentry_isDeclared (old),
7790 alkind_unparse (newKind),
7791 uentry_specOrDefName (old)),
7792 uentry_whereDeclared (unew)))
7794 uentry_showWhereSpecified (old);
7798 sRef_setAliasKind (old->sref, newKind,
7799 uentry_whereDeclared (unew));
7801 else /* newKind is temp or refcounted */
7808 else /* newKind unknown */
7815 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7816 bool mustConform, bool completeConform)
7821 oldKind = sRef_getExKind (old->sref);
7822 newKind = sRef_getExKind (unew->sref);
7824 if (exkind_isKnown (newKind))
7826 if (oldKind != newKind)
7828 if (exkind_isKnown (oldKind))
7833 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7834 uentry_ekindName (unew),
7835 uentry_getName (unew),
7836 uentry_isDeclared (old),
7838 exkind_unparse (newKind),
7839 uentry_specOrDefName (old),
7840 exkind_unparse (oldKind)),
7841 uentry_whereDeclared (unew)))
7843 uentry_showWhereSpecified (old);
7846 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7853 message ("%s %q inconsistently %rdeclared %s %s, "
7854 "implicitly %s without exposure qualifier",
7855 uentry_ekindName (unew),
7856 uentry_getName (unew),
7857 uentry_isDeclared (old),
7859 exkind_unparse (newKind),
7860 uentry_specOrDefName (old)),
7861 uentry_whereDeclared (unew)))
7863 uentry_showWhereSpecified (old);
7866 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7872 if (completeConform && exkind_isKnown (oldKind)
7873 && uentry_isReallySpecified (old))
7877 message ("%s %q specified as %s, but declared without "
7878 "exposure qualifier",
7879 ekind_capName (unew->ukind),
7880 uentry_getName (unew),
7881 exkind_unparse (oldKind)),
7882 uentry_whereDeclared (unew)))
7884 uentry_showWhereSpecified (old);
7888 /* yes, this is necessary! (if its a param) */
7889 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7894 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7895 bool mustConform, /*@unused@*/ bool completeConform)
7897 valueTable newvals = sRef_getValueTable (unew->sref);
7899 if (valueTable_isDefined (newvals))
7901 DPRINTF (("Check meta state: %s -> %s",
7902 uentry_unparseFull (old),
7903 uentry_unparseFull (unew)));
7905 DPRINTF (("Check meta state refs: %s -> %s",
7906 sRef_unparseFull (old->sref),
7907 sRef_unparseFull (unew->sref)));
7909 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7912 ** Copy the new values into the old ref
7915 valueTable_elements (newvals, key, newval)
7917 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7918 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7920 llassert (metaStateInfo_isDefined (msinfo));
7922 if (stateValue_isUndefined (oldval))
7924 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7928 if (stateValue_isError (oldval))
7930 if (!stateValue_isError (newval))
7932 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7936 ; /* No change necessary. */
7941 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7943 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7949 if (!stateValue_isError (newval)
7950 && !stateValue_isImplicit (newval))
7952 if (uentry_hasName (unew)
7953 || !sRef_isParam (uentry_getSref (unew)))
7958 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7959 uentry_ekindName (unew),
7960 uentry_getName (unew),
7961 uentry_isDeclared (old),
7963 stateValue_unparseValue (newval, msinfo),
7964 uentry_specOrDefName (old),
7965 stateValue_unparseValue (oldval, msinfo)),
7966 uentry_whereDeclared (unew)))
7968 uentry_showWhereSpecified (old);
7976 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7977 uentry_ekindName (unew),
7978 sRef_getParam (uentry_getSref (unew)),
7979 uentry_isDeclared (old),
7981 stateValue_unparseValue (newval, msinfo),
7982 uentry_specOrDefName (old),
7983 stateValue_unparseValue (oldval, msinfo)),
7984 uentry_whereDeclared (unew)))
7986 uentry_showWhereSpecified (old);
7992 DPRINTF (("Updating!"));
7993 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7997 DPRINTF (("Values match"));
8001 } end_valueTable_elements ;
8006 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8007 /*@notnull@*/ uentry unew,
8008 bool mustConform, bool completeConform)
8010 checkDefState (old, unew, mustConform, completeConform);
8011 checkNullState (old, unew, mustConform, completeConform);
8012 checkAliasState (old, unew, mustConform, completeConform);
8013 checkExpState (old, unew, mustConform, completeConform);
8014 checkMetaState (old, unew, mustConform, completeConform);
8016 sRef_storeState (old->sref);
8017 sRef_storeState (unew->sref);
8021 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8023 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8028 llassert (uentry_isVar (old));
8029 llassert (uentry_isVar (unew));
8031 if (cstring_isEmpty (old->uname))
8033 cstring_free (old->uname);
8034 old->uname = cstring_copy (unew->uname);
8037 if (unew->info->var->kind == VKRETPARAM
8038 || unew->info->var->kind == VKSEFRETPARAM)
8040 if (old->info->var->kind != VKRETPARAM
8041 && old->info->var->kind != VKSEFRETPARAM)
8045 message ("Parameter %q inconsistently %rdeclared as "
8046 "returned parameter",
8047 uentry_getName (unew),
8048 uentry_isDeclared (old)),
8049 uentry_whereDeclared (unew)))
8051 uentry_showWhereSpecified (old);
8052 old->info->var->kind = unew->info->var->kind;
8058 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8060 if (old->info->var->kind != VKSEFPARAM
8061 && old->info->var->kind != VKSEFRETPARAM)
8065 message ("Parameter %qinconsistently %rdeclared as "
8067 uentry_getOptName (unew),
8068 uentry_isDeclared (old)),
8069 uentry_whereDeclared (unew)))
8071 uentry_showWhereSpecified (old);
8072 old->info->var->kind = unew->info->var->kind;
8077 if (old->info->var->kind == VKSPEC)
8079 old->info->var->kind = unew->info->var->kind;
8083 unew->info->var->kind = old->info->var->kind;
8086 if (unew->info->var->checked != CH_UNKNOWN
8087 && unew->info->var->checked != old->info->var->checked)
8089 if (old->info->var->checked == CH_UNKNOWN
8090 && !fileloc_isUser (uentry_whereLast (old)))
8098 message ("Variable %q inconsistently %rdeclared as "
8099 "%s parameter (was %s)",
8100 uentry_getName (unew),
8101 uentry_isDeclared (old),
8102 checkedName (unew->info->var->checked),
8103 checkedName (old->info->var->checked)),
8104 uentry_whereDeclared (unew)))
8106 uentry_showWhereSpecified (old);
8110 old->info->var->checked = unew->info->var->checked;
8115 && (old->info->var->checked != CH_UNKNOWN)
8116 && uentry_isReallySpecified (old))
8120 message ("%s %q specified as %s, but declared without %s qualifier",
8121 ekind_capName (unew->ukind),
8122 uentry_getName (unew),
8123 checkedName (old->info->var->checked),
8124 checkedName (old->info->var->checked)),
8125 uentry_whereDeclared (unew)))
8127 uentry_showWhereSpecified (old);
8131 unew->info->var->checked = old->info->var->checked;
8134 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8137 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8139 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8144 llassert (uentry_isVar (u1));
8145 llassert (uentry_isVar (u2));
8147 if (u1->info->var->kind != u2->info->var->kind) {
8148 if (u1->info->var->kind == VKSEFRETPARAM) {
8149 if (u2->info->var->kind == VKRETPARAM) {
8152 message ("Function types are inconsistent. Parameter %d is "
8153 "sef parameter, but non-sef parameter in "
8154 "assigned function: %s",
8155 paramno, exprNode_unparse (e)),
8157 } else if (u2->info->var->kind == VKSEFPARAM) {
8160 message ("Function types are inconsistent. Parameter %d is "
8161 "returns parameter, but non-returns parameter in "
8162 "assigned function: %s",
8163 paramno, exprNode_unparse (e)),
8168 message ("Function types are inconsistent. Parameter %d is "
8169 "sef returns parameter, but non-sef returns parameter in "
8170 "assigned function: %s",
8171 paramno, exprNode_unparse (e)),
8174 } else if (u1->info->var->kind == VKRETPARAM) {
8177 message ("Function types are inconsistent. Parameter %d is "
8178 "returns parameter, but non-returns parameter in "
8179 "assigned function: %s",
8180 paramno, exprNode_unparse (e)),
8182 } else if (u1->info->var->kind == VKSEFPARAM) {
8185 message ("Function types are inconsistent. Parameter %d is "
8186 "sef parameter, but non-sef parameter in "
8187 "assigned function: %s",
8188 paramno, exprNode_unparse (e)),
8191 if (u2->info->var->kind == VKSEFRETPARAM) {
8194 message ("Function types are inconsistent. Parameter %d is "
8195 "normal parameter, but sef returns parameter in "
8196 "assigned function: %s",
8197 paramno, exprNode_unparse (e)),
8199 } else if (u2->info->var->kind == VKSEFPARAM) {
8202 message ("Function types are inconsistent. Parameter %d is "
8203 "normal parameter, but sef parameter in "
8204 "assigned function: %s",
8205 paramno, exprNode_unparse (e)),
8207 } else if (u2->info->var->kind == VKRETPARAM) {
8210 message ("Function types are inconsistent. Parameter %d is "
8211 "normal parameter, but returns parameter in "
8212 "assigned function: %s",
8213 paramno, exprNode_unparse (e)),
8221 if (u1->info->var->defstate != u2->info->var->defstate)
8225 message ("Function types are inconsistent. Parameter %d is "
8226 "%s, but %s in assigned function: %s",
8228 sstate_unparse (u1->info->var->defstate),
8229 sstate_unparse (u2->info->var->defstate),
8230 exprNode_unparse (e)),
8234 if (u1->info->var->nullstate != u2->info->var->nullstate)
8238 message ("Function types are inconsistent. Parameter %d is "
8239 "%s, but %s in assigned function: %s",
8241 nstate_unparse (u1->info->var->nullstate),
8242 nstate_unparse (u2->info->var->nullstate),
8243 exprNode_unparse (e)),
8247 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8251 message ("Function types are inconsistent. Parameter %d is "
8252 "%s, but %s in assigned function: %s",
8254 alkind_unparse (sRef_getAliasKind (u1->sref)),
8255 alkind_unparse (sRef_getAliasKind (u2->sref)),
8256 exprNode_unparse (e)),
8260 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8264 message ("Function types are inconsistent. Parameter %d is "
8265 "%s, but %s in assigned function: %s",
8267 exkind_unparse (sRef_getExKind (u1->sref)),
8268 exkind_unparse (sRef_getExKind (u2->sref)),
8269 exprNode_unparse (e)),
8275 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8276 /*@notnull@*/ uentry unew,
8277 bool mustConform, /*@unused@*/ bool completeConform)
8279 uentryList oldParams = uentry_getParams (old);
8280 uentryList newParams = uentry_getParams (unew);
8281 ctype newType = unew->utype;
8282 ctype oldType = ctype_realType (old->utype);
8283 ctype oldRetType = ctype_unknown;
8284 ctype newRetType = ctype_unknown;
8286 DPRINTF (("Function conform: %s ==> %s",
8287 uentry_unparseFull (old),
8288 uentry_unparseFull (unew)));
8290 if (uentry_isForward (old))
8292 mustConform = FALSE;
8293 uentry_updateInto (old, unew);
8298 ** check return values
8301 if (ctype_isKnown (oldType))
8303 llassert (ctype_isFunction (oldType));
8304 oldRetType = ctype_getReturnType (oldType);
8307 if (ctype_isKnown (newType))
8309 llassert (ctype_isFunction (newType));
8310 newRetType = ctype_getReturnType (newType);
8313 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8314 && !ctype_matchDef (newRetType, oldRetType))
8316 if (mustConform) returnValueError (old, unew);
8320 if (ctype_isConj (newRetType))
8322 if (ctype_isConj (oldRetType))
8324 if (!ctype_sameAltTypes (newRetType, oldRetType))
8328 message ("Function %q inconsistently %rdeclared to "
8329 "return alternate types %s "
8330 "(types match, but alternates are not identical, "
8331 "so checking may not be correct)",
8332 uentry_getName (unew),
8333 uentry_isDeclared (old),
8334 ctype_unparse (newRetType)),
8335 uentry_whereDeclared (unew)))
8337 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8343 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8348 DPRINTF (("Before state: %s",
8349 uentry_unparseFull (old)));
8350 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8351 DPRINTF (("After state: %s",
8352 uentry_unparseFull (old)));
8354 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8356 if (exitkind_isKnown (unew->info->fcn->exitCode))
8360 message ("Function %q inconsistently %rdeclared using %s",
8361 uentry_getName (unew),
8362 uentry_isDeclared (old),
8363 exitkind_unparse (unew->info->fcn->exitCode)),
8364 uentry_whereDeclared (unew)))
8366 uentry_showWhereSpecified (old);
8371 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8375 if (!qual_isUnknown (unew->info->fcn->nullPred))
8377 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8381 message ("Function %q inconsistently %rdeclared using %s",
8382 uentry_getName (unew),
8383 uentry_isDeclared (old),
8384 qual_unparse (unew->info->fcn->nullPred)),
8385 uentry_whereDeclared (unew)))
8387 uentry_showWhereSpecified (old);
8393 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8396 if (unew->info->fcn->specialCode != SPC_NONE)
8398 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8402 message ("Function %q inconsistently %rdeclared using %s",
8403 uentry_getName (unew),
8404 uentry_isDeclared (old),
8405 specCode_unparse (unew->info->fcn->specialCode)),
8406 uentry_whereDeclared (unew)))
8408 uentry_showWhereSpecified (old);
8414 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8421 if (!uentryList_sameObject (oldParams, newParams)
8422 && (!uentryList_isMissingParams (oldParams)))
8424 if (!uentryList_isMissingParams (newParams))
8427 int nparams = uentryList_size (oldParams);
8428 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8430 if (nparams != uentryList_size (newParams))
8432 nargsError (old, unew);
8435 if (uentryList_size (newParams) < nparams)
8437 nparams = uentryList_size (newParams);
8440 while (paramno < nparams)
8442 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8443 uentry newCurrent = uentryList_getN (newParams, paramno);
8444 ctype oldCurrentType = uentry_getType (oldCurrent);
8445 ctype newCurrentType = uentry_getType (newCurrent);
8447 llassert (uentry_isValid (oldCurrent)
8448 && uentry_isValid (newCurrent));
8450 if (!uentry_isElipsisMarker (oldCurrent)
8451 && !uentry_isElipsisMarker (newCurrent))
8453 checkVarConformance (oldCurrent, newCurrent,
8454 mustConform, completeConform);
8459 if (uentry_hasName (oldCurrent)
8460 && uentry_hasName (newCurrent))
8462 cstring oldname = uentry_getName (oldCurrent);
8463 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8465 cstring nname = uentry_getName (newCurrent);
8468 if (cstring_isDefined (pfx)
8469 && cstring_equalPrefix (oldname, pfx))
8471 oname = cstring_suffix (oldname, cstring_length (pfx));
8476 /*@-branchstate@*/ } /*@=branchstate@*/
8478 if (cstring_isDefined (pfx)
8479 && cstring_equalPrefix (nname, pfx))
8481 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8486 /*@-branchstate@*/ } /*@=branchstate@*/
8488 if (!cstring_equal (oname, nnamefix))
8491 (FLG_DECLPARAMMATCH,
8492 message ("Definition parameter name %s does not match "
8493 "name of corresponding parameter in "
8496 uentry_whereLast (newCurrent)))
8498 uentry_showWhereLastPlain (oldCurrent);
8502 cstring_free (oldname);
8503 cstring_free (nname);
8507 if (!ctype_match (oldCurrentType, newCurrentType))
8509 paramTypeError (old, oldCurrent, oldCurrentType,
8510 unew, newCurrent, newCurrentType, paramno);
8514 if (ctype_isMissingParamsMarker (newCurrentType)
8515 || ctype_isElips (newCurrentType)
8516 || ctype_isMissingParamsMarker (oldCurrentType)
8517 || ctype_isElips (oldCurrentType))
8523 if (ctype_isConj (newCurrentType))
8525 if (ctype_isConj (oldCurrentType))
8527 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8531 message ("Parameter %q inconsistently %rdeclared with "
8532 "alternate types %s "
8533 "(types match, but alternates are not identical, "
8534 "so checking may not be correct)",
8535 uentry_getName (newCurrent),
8536 uentry_isDeclared (oldCurrent),
8537 ctype_unparse (newCurrentType)),
8538 uentry_whereDeclared (unew)))
8540 uentry_showWhereLastVal (oldCurrent,
8541 ctype_unparse (oldCurrentType));
8549 message ("Parameter %q inconsistently %rdeclared with "
8550 "alternate types %s",
8551 uentry_getName (newCurrent),
8552 uentry_isDeclared (oldCurrent),
8553 ctype_unparse (newCurrentType)),
8554 uentry_whereDeclared (unew)))
8556 uentry_showWhereLastVal (oldCurrent,
8557 ctype_unparse (oldCurrentType));
8564 if (ctype_isConj (oldCurrentType))
8566 uentry_setType (newCurrent, oldCurrentType);
8574 ** Forgot this! detected by splint:
8575 ** uentry.c:1257,15: Suspected infinite loop
8581 if (!uentryList_isMissingParams (newParams))
8583 if (ctype_isConj (oldRetType))
8585 old->utype = ctype_makeFunction (oldRetType,
8586 uentryList_copy (newParams));
8590 old->utype = unew->utype;
8594 checkGlobalsConformance (old, unew, mustConform, completeConform);
8595 checkModifiesConformance (old, unew, mustConform, completeConform);
8597 DPRINTF (("Before list: %s",
8598 uentry_unparseFull (old)));
8600 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8602 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8607 message ("Function %q redeclared using special clauses (can only "
8608 "be used in first declaration)",
8609 uentry_getName (unew)),
8610 uentry_whereDeclared (unew)))
8612 uentry_showWhereLast (old);
8616 /*@i23 need checking @*/
8618 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8622 /*@i43 should be able to append? @*/
8624 stateClauseList_checkEqual (old, unew);
8625 stateClauseList_free (unew->info->fcn->specclauses);
8626 unew->info->fcn->specclauses = stateClauseList_undefined;
8630 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8632 if (fileloc_isUndefined (old->whereDeclared))
8634 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8636 else if (fileloc_isUndefined (unew->whereDeclared))
8638 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8647 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8651 llassert (uentry_isValid (ue));
8652 llassert (uentry_isEitherConstant (ue));
8654 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8655 uval = uentry_getConstantValue (ue);
8657 if (multiVal_isDefined (uval))
8659 if (multiVal_isDefined (m))
8661 if (!multiVal_equiv (uval, m))
8665 message ("%s %q defined with inconsistent value: %q",
8666 ekind_capName (ue->ukind),
8667 uentry_getName (ue),
8668 multiVal_unparse (m)),
8671 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8679 uentry_setConstantValue (ue, m);
8684 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8687 bool typeError = FALSE;
8689 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8691 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8695 DPRINTF (("Check struct conformance: %s / %s",
8696 uentry_unparseFull (old),
8697 uentry_unparseFull (unew)));
8698 checkStructConformance (old, unew);
8703 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8705 llbug (message ("struct tags: bad types: %t / %t",
8706 old->utype, unew->utype));
8710 else if (uentry_isEnumTag (old))
8712 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8714 if (mustConform) checkEnumConformance (old, unew);
8718 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8720 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8721 ctype_unparse (unew->utype)));
8725 else if (!ctype_match (old->utype, unew->utype))
8727 DPRINTF (("Type mismatch: %s / %s",
8728 ctype_unparse (old->utype),
8729 ctype_unparse (unew->utype)));
8731 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8733 ctype realt = ctype_realType (unew->utype);
8735 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8737 unew->utype = ctype_bool;
8743 typeError = optgenerror
8745 message ("%q defined as %s", uentry_getName (old),
8746 ctype_unparse (realt)),
8747 uentry_whereDeclared (unew));
8755 ctype oldr = ctype_realType (old->utype);
8756 ctype newr = ctype_realType (unew->utype);
8758 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8760 checkStructConformance (old, unew);
8762 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8764 checkStructConformance (old, unew);
8766 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8768 checkEnumConformance (old, unew);
8770 else if (uentry_isConstant (old)
8771 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8773 /* okay...for now! (should check the type is reset later... */
8777 DPRINTF (("YABA!"));
8780 message ("%s %q %rdeclared with inconsistent type: %t",
8781 ekind_capName (unew->ukind),
8782 uentry_getName (unew),
8783 uentry_isDeclared (old),
8785 uentry_whereDeclared (unew)))
8787 uentry_showWhereLast (old);
8803 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8804 /*@notnull@*/ uentry unew,
8805 bool mustConform, bool completeConform)
8807 if (ctype_isDefined (unew->info->datatype->type))
8810 ** bool is hard coded here, since it is built into LCL.
8811 ** For now, we're stuck with LCL's types.
8814 if (ctype_isDirectBool (old->utype) &&
8815 cstring_equalLit (unew->uname, "bool"))
8817 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8818 evs 2000-07-25: removed
8820 unew->utype = ctype_bool;
8823 if (ctype_isUnknown (old->info->datatype->type))
8825 old->info->datatype->type = unew->info->datatype->type;
8829 DPRINTF (("Old: %s / New: %s",
8830 uentry_unparseFull (old),
8831 uentry_unparseFull (unew)));
8832 DPRINTF (("Types: %s / %s",
8833 ctype_unparse (old->info->datatype->type),
8834 ctype_unparse (unew->info->datatype->type)));
8836 if (ctype_matchDef (old->info->datatype->type,
8837 unew->info->datatype->type))
8846 ("Type %q %s with inconsistent type: %t",
8847 uentry_getName (unew),
8848 uentry_reDefDecl (old, unew),
8849 unew->info->datatype->type),
8850 uentry_whereDeclared (unew)))
8852 uentry_showWhereLastExtra
8853 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8856 old->info->datatype->type = unew->info->datatype->type;
8861 if (unew->info->datatype->abs != MAYBE)
8863 if (ynm_isOff (old->info->datatype->abs)
8864 && ynm_isOn (unew->info->datatype->abs))
8866 if (!ctype_isDirectBool (old->utype))
8871 ("Datatype %q inconsistently %rdeclared as abstract type",
8872 uentry_getName (unew),
8873 uentry_isDeclared (old)),
8874 uentry_whereDeclared (unew)))
8876 uentry_showWhereLastPlain (old);
8880 else if (ynm_isOn (old->info->datatype->abs)
8881 && ynm_isOff (unew->info->datatype->abs))
8883 if (!ctype_isDirectBool (old->utype))
8888 ("Datatype %q inconsistently %rdeclared as concrete type",
8889 uentry_getName (unew),
8890 uentry_isDeclared (old)),
8891 uentry_whereDeclared (unew)))
8893 uentry_showWhereLastPlain (old);
8904 if (ynm_isOn (old->info->datatype->abs))
8906 old->sref = unew->sref;
8907 unew->info->datatype->mut = old->info->datatype->mut;
8910 && uentry_isReallySpecified (old))
8915 ("Datatype %q specified as abstract, "
8916 "but abstract annotation not used in declaration",
8917 uentry_getName (unew)),
8918 uentry_whereDeclared (unew)))
8920 uentry_showWhereLastPlain (old);
8926 unew->info->datatype->abs = old->info->datatype->abs;
8928 if (ynm_isMaybe (unew->info->datatype->mut))
8930 if (completeConform && ynm_isOff (old->info->datatype->mut)
8931 && uentry_isReallySpecified (old))
8936 ("Datatype %q specified as immutable, "
8937 "but immutable annotation not used in declaration",
8938 uentry_getName (unew)),
8939 uentry_whereDeclared (unew)))
8941 uentry_showWhereLastPlain (old);
8945 unew->info->datatype->mut = old->info->datatype->mut;
8947 else if (ynm_isMaybe (old->info->datatype->mut))
8949 old->info->datatype->mut = unew->info->datatype->mut;
8953 if (ynm_isOn (old->info->datatype->abs))
8955 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8959 message ("Datatype %q inconsistently %rdeclared as immutable",
8960 uentry_getName (unew),
8961 uentry_isDeclared (old)),
8962 uentry_whereDeclared (unew)))
8964 uentry_showWhereLastPlain (old);
8969 if (ynm_isOff (old->info->datatype->mut)
8970 && ynm_isOn (unew->info->datatype->mut))
8974 message ("Datatype %q inconsistently %rdeclared as mutable",
8975 uentry_getName (unew),
8976 uentry_isDeclared (old)),
8977 uentry_whereDeclared (unew)))
8979 uentry_showWhereLastPlain (old);
8984 old->info->datatype->mut = unew->info->datatype->mut;
8987 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8991 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8992 /*@notnull@*/ uentry unew,
8994 /*@unused@*/ bool completeConform)
8996 multiVal oldval = uentry_getConstantValue (old);
8997 multiVal newval = uentry_getConstantValue (unew);
8999 if (multiVal_isDefined (oldval))
9001 if (multiVal_isDefined (newval))
9003 if (!multiVal_equiv (oldval, newval))
9008 message ("%s %q %rdeclared with inconsistent value: %q",
9009 ekind_capName (unew->ukind),
9010 uentry_getName (unew),
9011 uentry_isDeclared (old),
9012 multiVal_unparse (newval)),
9013 uentry_whereDeclared (unew)))
9015 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9019 uentry_setConstantValue (unew, multiVal_copy (oldval));
9028 uentry_setConstantValue (old, multiVal_copy (newval));
9033 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9034 /*@notnull@*/ uentry unew, bool mustConform,
9035 bool completeConform)
9037 bool typeError = FALSE;
9038 bool fcnConformance = FALSE;
9040 if (!ekind_equal (unew->ukind, old->ukind))
9043 ** okay, only if one is a function and the other is
9044 ** a variable of type function.
9047 if (unew->ukind == KENUMCONST
9048 && old->ukind == KCONST)
9050 old->ukind = KENUMCONST;
9054 if (unew->ukind == KFCN
9055 && old->ukind == KCONST
9056 && ctype_isUnknown (old->utype))
9059 ** When a function is defined with an unparam macro
9062 uentry_updateInto (old, unew);
9066 if (uentry_isExpandedMacro (old)
9067 && uentry_isEitherConstant (unew))
9069 uentry_updateInto (old, unew);
9073 if (uentry_isEndIter (unew))
9075 if (ctype_isUnknown (old->utype))
9077 if (!uentry_isSpecified (old)
9078 && uentry_isCodeDefined (unew))
9080 if (!fileloc_withinLines (uentry_whereDefined (old),
9081 uentry_whereDeclared (unew), 2))
9082 { /* bogus! will give errors if there is too much whitespace */
9086 ("Iterator finalized name %q does not match name in "
9087 "previous iter declaration (should be end_%q). This iter "
9088 "is declared at %q",
9089 uentry_getName (unew),
9090 uentry_getName (old),
9091 fileloc_unparse (uentry_whereDefined (old))),
9092 uentry_whereDeclared (old));
9096 uentry_updateInto (old, unew);
9101 KindConformanceError (old, unew, mustConform);
9105 if (uentry_isFunction (unew))
9107 if (uentry_isVariable (old))
9109 if (!ctype_isUnknown (old->utype))
9111 if (ctype_isFunction (old->utype))
9113 uentry_makeVarFunction (old);
9114 checkFunctionConformance (old, unew, mustConform,
9116 fcnConformance = TRUE;
9120 KindConformanceError (old, unew, mustConform);
9125 if (uentry_isExpandedMacro (old))
9127 if (fileloc_isUndefined (unew->whereDefined))
9129 unew->whereDefined = fileloc_update (unew->whereDefined,
9133 uentry_updateInto (old, unew);
9134 old->used = unew->used = TRUE;
9139 /* undeclared identifier */
9140 old->utype = unew->utype;
9141 uentry_makeVarFunction (old);
9142 checkFunctionConformance (old, unew, FALSE, FALSE);
9143 fcnConformance = TRUE;
9149 KindConformanceError (old, unew, mustConform);
9152 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9154 if (!ctype_isUnknown (unew->utype))
9156 if (ctype_isFunction (unew->utype))
9158 uentry_makeVarFunction (unew);
9159 checkFunctionConformance (old, unew, mustConform, completeConform);
9160 fcnConformance = TRUE;
9164 KindConformanceError (old, unew, mustConform);
9169 KindConformanceError (old, unew, mustConform);
9174 KindConformanceError (old, unew, mustConform);
9180 ** check parameter lists for functions
9181 ** (before type errors, to get better messages
9184 if (uentry_isFunction (old))
9186 checkFunctionConformance (old, unew, mustConform, completeConform);
9187 fcnConformance = TRUE;
9191 if (!ctype_isUndefined (old->utype))
9193 typeError = checkTypeConformance (old, unew, mustConform);
9200 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9202 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9205 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9207 DPRINTF (("Check datatype: %s / %s",
9208 uentry_unparseFull (old),
9209 uentry_unparseFull (unew)));
9211 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9214 if (uentry_isVariable (old) && uentry_isVariable (unew))
9217 !ctype_matchDef (old->utype, unew->utype))
9222 ("Variable %q %s with inconsistent type (arrays and pointers are "
9223 "not identical in variable declarations): %t",
9224 uentry_getName (unew),
9225 uentry_reDefDecl (old, unew),
9227 uentry_whereDeclared (unew)))
9229 uentry_showWhereLast (old);
9232 ** Avoid repeated errors.
9235 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9237 old->whereDefined = fileloc_update (old->whereDefined,
9245 checkVarConformance (old, unew, mustConform, completeConform);
9250 /* old->utype = unew->utype; */
9254 if (ctype_isConj (old->utype))
9256 if (ctype_isConj (unew->utype))
9258 if (!ctype_sameAltTypes (old->utype, unew->utype))
9262 message ("%s %q inconsistently %rdeclared with "
9263 "alternate types %s "
9264 "(types match, but alternates are not identical, "
9265 "so checking may not be correct)",
9266 ekind_capName (uentry_getKind (old)),
9267 uentry_getName (unew),
9268 uentry_isDeclared (old),
9269 ctype_unparse (unew->utype)),
9270 uentry_whereDeclared (unew)))
9272 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9276 old->utype = unew->utype;
9283 if (ctype_isUnknown (old->utype))
9285 old->utype = unew->utype;
9290 if (unew->ukind == old->ukind)
9293 unew->info = uinfo_copy (old->info, old->ukind);
9296 sRef_storeState (old->sref);
9297 sRef_storeState (unew->sref);
9300 static void uentry_mergeConstraints (uentry spec, uentry def)
9302 if (uentry_isFunction (def))
9304 DPRINTF (("Here: %s / %s",
9305 uentry_unparseFull (spec),
9306 uentry_unparseFull (def)));
9307 /* evans 2001-07-21 */
9308 llassert (uentry_isFunction (spec));
9310 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9312 if (fileloc_isXHFile (uentry_whereLast (def)))
9314 llassert (uentry_isFunction (spec));
9315 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9316 def->info->fcn->preconditions);
9318 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9324 /* Check if the constraints are identical */
9329 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9330 uentry_getName (spec),
9331 functionConstraint_unparse (spec->info->fcn->preconditions)),
9332 uentry_whereLast (def)))
9334 uentry_showWhereSpecified (spec);
9337 functionConstraint_free (spec->info->fcn->preconditions);
9338 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9341 def->info->fcn->preconditions = functionConstraint_undefined;
9344 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9346 if (fileloc_isXHFile (uentry_whereLast (def)))
9348 llassert (uentry_isFunction (spec));
9349 DPRINTF (("Post: %s /++/ %s",
9350 functionConstraint_unparse (spec->info->fcn->postconditions),
9351 functionConstraint_unparse (def->info->fcn->postconditions)));
9352 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9353 def->info->fcn->postconditions);
9354 def->info->fcn->postconditions = functionConstraint_undefined;
9355 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9362 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9363 uentry_getName (spec),
9364 functionConstraint_unparse (spec->info->fcn->postconditions)),
9365 uentry_whereLast (def)))
9367 uentry_showWhereSpecified (spec);
9370 functionConstraint_free (spec->info->fcn->postconditions);
9371 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9372 def->info->fcn->postconditions = functionConstraint_undefined;
9379 ** modifies spec to reflect def, reports any inconsistencies
9383 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9385 llassert (uentry_isValid (spec));
9386 llassert (uentry_isValid (def));
9387 llassert (cstring_equal (spec->uname, def->uname));
9389 if (uentry_isFunction (def))
9391 if (uentry_isConstant (spec))
9393 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9394 uentry_makeConstantFunction (spec);
9398 uentry_convertVarFunction (spec);
9401 llassert (uentry_isFunction (spec));
9404 DPRINTF (("Merge entries: %s / %s",
9405 uentry_unparseFull (spec),
9406 uentry_unparseFull (def)));
9408 uentry_mergeConstraints (spec, def);
9410 uentry_checkConformance (spec, def, TRUE,
9411 context_getFlag (FLG_NEEDSPEC));
9413 DPRINTF (("Merge entries after conform: %s / %s",
9414 uentry_unparseFull (spec),
9415 uentry_unparseFull (def)));
9417 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9420 ** okay, declarations conform. Propagate extra information.
9423 uentry_setDefined (spec, uentry_whereDefined (def));
9424 uentry_setDeclared (spec, uentry_whereDeclared (def));
9426 if (uentry_isStatic (def))
9430 message ("%s %q specified, but declared as static",
9431 ekind_capName (def->ukind),
9432 uentry_getName (def)),
9433 uentry_whereDeclared (def)))
9435 uentry_showWhereSpecified (spec);
9440 spec->storageclass = def->storageclass;
9443 sRef_storeState (spec->sref);
9445 spec->used = def->used || spec->used;
9446 spec->hasNameError |= def->hasNameError;
9450 if (!spec->hasNameError)
9452 uentry_checkName (spec);
9461 ** Can't generate function redeclaration errors when the
9462 ** entries are merged, since we don't yet know if its the
9463 ** definition of the function.
9467 uentry_clearDecl (void)
9469 posRedeclared = uentry_undefined;
9470 fileloc_free (posLoc);
9471 posLoc = fileloc_undefined;
9475 uentry_checkDecl (void)
9477 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9479 llassert (fileloc_isDefined (posLoc));
9481 if (uentry_isCodeDefined (posRedeclared))
9483 if (optgenerror (FLG_REDECL,
9484 message ("%s %q declared after definition",
9485 ekind_capName (posRedeclared->ukind),
9486 uentry_getName (posRedeclared)),
9489 llgenindentmsg (message ("Definition of %q",
9490 uentry_getName (posRedeclared)),
9491 posRedeclared->whereDeclared);
9496 if (optgenerror (FLG_REDECL,
9497 message ("%s %q declared more than once",
9498 ekind_capName (posRedeclared->ukind),
9499 uentry_getName (posRedeclared)),
9502 llgenindentmsg (message ("Previous declaration of %q",
9503 uentry_getName (posRedeclared)),
9504 posRedeclared->whereDeclared);
9509 fileloc_free (posLoc);
9510 posLoc = fileloc_undefined;
9511 posRedeclared = uentry_undefined;
9515 ** Redefinition of old as unew.
9516 ** modifies old to reflect unew, reports any inconsistencies
9520 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9522 fileloc olddef = uentry_whereDeclared (old);
9523 fileloc unewdef = uentry_whereDeclared (unew);
9527 DPRINTF (("uentry merge: %s / %s",
9528 uentry_unparseFull (old),
9529 uentry_unparseFull (unew)));
9532 fileloc_isUndefined (olddef)
9533 && fileloc_isDefined (uentry_whereDefined (old))
9534 && !uentry_isExpandedMacro (old);
9536 if (!context_getFlag (FLG_INCONDEFSLIB)
9537 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9539 mustConform = FALSE;
9546 llassert (uentry_isValid (old));
9547 llassert (uentry_isValid (unew));
9548 llassert (cstring_equal (old->uname, unew->uname));
9550 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9552 if (uentry_isConstant (old))
9554 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9555 uentry_makeConstantFunction (old);
9559 uentry_convertVarFunction (old);
9562 llassert (uentry_isFunction (old));
9565 DPRINTF (("uentry merge: %s / %s",
9566 uentry_unparseFull (old),
9567 uentry_unparseFull (unew)));
9569 if (uentry_isExtern (unew))
9571 uentry_setUsed (old, unewdef);
9575 ** should check old one was extern!
9578 if (uentry_isStatic (old))
9580 if (!(uentry_isStatic (unew)))
9584 message ("%s %q shadows static declaration",
9585 ekind_capName (unew->ukind),
9586 uentry_getName (unew)),
9589 uentry_showWhereLast (old);
9594 uentry_setDeclDef (old, unewdef);
9597 else if (uentry_isStatic (unew))
9599 uentry_setDeclDef (old, unewdef);
9601 else if (uentry_isExtern (old))
9603 uentry_setDeclared (old, unewdef);
9607 if (!uentry_isExtern (unew)
9608 && !uentry_isForward (old)
9609 && !fileloc_equal (olddef, unewdef)
9610 && !fileloc_isUndefined (olddef)
9611 && !fileloc_isUndefined (unewdef)
9612 && !fileloc_isBuiltin (olddef)
9613 && !fileloc_isBuiltin (unewdef)
9614 && !uentry_isYield (old)
9615 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9617 if (uentry_isVariable (old) || uentry_isVariable (unew))
9619 ; /* will report redeclaration error later */
9623 if (fileloc_isDefined (uentry_whereDefined (old)))
9627 message ("%s %q defined more than once",
9628 ekind_capName (unew->ukind),
9629 uentry_getName (unew)),
9630 uentry_whereLast (unew)))
9633 (message ("Previous definition of %q",
9634 uentry_getName (old)),
9635 uentry_whereLast (old));
9638 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9640 uentry_updateInto (old, unew);
9641 old->sref = sRef_saveCopy (old->sref);
9649 if (fileloc_isLib (olddef)
9650 || fileloc_isUndefined (olddef)
9651 || fileloc_isImport (olddef))
9653 if (uentry_isExtern (unew))
9655 if (uentry_isExtern (old)
9656 || (fileloc_isDefined (uentry_whereDeclared (old))
9657 && (!fileloc_equal (uentry_whereDeclared (old),
9658 uentry_whereDefined (old)))))
9662 message ("%s %q declared more than once",
9663 ekind_capName (unew->ukind),
9664 uentry_getName (unew)),
9665 unew->whereDeclared))
9668 (message ("Previous declaration of %q",
9669 uentry_getName (old)),
9670 old->whereDeclared);
9674 uentry_setExtern (old);
9678 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9684 DPRINTF (("uentry merge: %s / %s",
9685 uentry_unparseFull (old),
9686 uentry_unparseFull (unew)));
9688 uentry_mergeConstraints (old, unew);
9689 DPRINTF (("uentry merge: %s / %s",
9690 uentry_unparseFull (old),
9691 uentry_unparseFull (unew)));
9693 uentry_checkConformance (old, unew, mustConform, FALSE);
9694 DPRINTF (("uentry merge: %s / %s",
9695 uentry_unparseFull (old),
9696 uentry_unparseFull (unew)));
9698 old->used = old->used || unew->used;
9699 old->uses = filelocList_append (old->uses, unew->uses);
9700 unew->uses = filelocList_undefined;
9702 sRef_storeState (old->sref);
9703 sRef_storeState (unew->sref);
9707 old->whereDefined = fileloc_update (old->whereDefined,
9711 DPRINTF (("here: %s", uentry_unparseFull (old)));
9714 ** No redeclaration errors for functions here, since we
9715 ** don't know if this is the definition of the function.
9718 if (fileloc_isUser (old->whereDeclared)
9719 && fileloc_isUser (unew->whereDeclared)
9720 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9721 && !fileloc_isDefined (unew->whereDefined))
9723 if (uentry_isFunction (old))
9725 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9726 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9730 if (optgenerror (FLG_REDECL,
9731 message ("%s %q declared more than once",
9732 ekind_capName (unew->ukind),
9733 uentry_getName (unew)),
9734 unew->whereDeclared))
9736 llgenindentmsg (message ("Previous declaration of %q",
9737 uentry_getName (old)),
9738 old->whereDeclared);
9743 if (fileloc_isUndefined (old->whereDefined))
9745 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9749 if (!context_processingMacros ()
9750 && fileloc_isUser (old->whereDefined)
9751 && fileloc_isUser (unew->whereDefined)
9752 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9754 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9756 if (uentry_isVariable (unew)
9757 && uentry_isExtern (unew))
9759 if (optgenerror (FLG_REDECL,
9760 message ("%s %q declared after definition",
9761 ekind_capName (unew->ukind),
9762 uentry_getName (unew)),
9763 unew->whereDeclared))
9765 llgenindentmsg (message ("Definition of %q",
9766 uentry_getName (old)),
9772 if (optgenerror (FLG_REDEF,
9773 message ("%s %q redefined",
9774 ekind_capName (unew->ukind),
9775 uentry_getName (unew)),
9776 unew->whereDefined))
9778 llgenindentmsg (message ("Previous definition of %q",
9779 uentry_getName (old)),
9787 if (uentry_isExternal (unew))
9789 old->whereDefined = fileloc_createExternal ();
9792 if (unew->hasNameError)
9794 old->hasNameError = TRUE;
9799 if (!old->hasNameError)
9801 uentry_checkName (old);
9804 DPRINTF (("After: %s", uentry_unparseFull (old)));
9805 llassert (!ctype_isUndefined (old->utype));
9809 uentry_copyState (uentry res, uentry other)
9811 llassert (uentry_isValid (res));
9812 llassert (uentry_isValid (other));
9814 res->used = other->used;
9816 res->info->var->kind = other->info->var->kind;
9817 res->info->var->defstate = other->info->var->defstate;
9818 res->info->var->nullstate = other->info->var->nullstate;
9819 res->info->var->checked = other->info->var->checked;
9821 sRef_copyState (res->sref, other->sref);
9825 uentry_sameKind (uentry u1, uentry u2)
9827 if (uentry_isValid (u1) && uentry_isValid (u2))
9829 if (uentry_isVar (u1) && uentry_isVar (u2))
9831 ctype c1 = u1->utype;
9832 ctype c2 = u2->utype;
9834 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9837 ** both functions, or both not functions
9840 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9844 return ((u1->ukind == u2->ukind));
9851 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9854 llassert (uentry_isValid (unew));
9855 llassert (uentry_isValid (old));
9857 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9858 okind = unew->ukind;
9859 unew->ukind = old->ukind;
9860 llassert (cstring_equal (unew->uname, old->uname));
9861 unew->utype = old->utype;
9863 if (fileloc_isDefined (unew->whereSpecified)
9864 && !fileloc_isDefined (old->whereSpecified))
9866 ; /* Keep the old value */
9870 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9871 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9874 if (fileloc_isDefined (unew->whereDefined)
9875 && !fileloc_isDefined (old->whereDefined))
9877 ; /* Keep the old value */
9881 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9882 unew->whereDefined = fileloc_copy (old->whereDefined);
9885 if (fileloc_isDefined (unew->whereDeclared)
9886 && !fileloc_isDefined (old->whereDeclared))
9888 ; /* Keep the old value */
9892 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9893 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9896 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9898 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9899 unew->used = old->used;
9901 unew->isPrivate = old->isPrivate;
9902 unew->hasNameError = old->hasNameError;
9903 unew->uses = filelocList_append (unew->uses, old->uses);
9904 old->uses = filelocList_undefined;
9906 unew->storageclass = old->storageclass;
9907 uinfo_free (unew->info, okind);
9908 unew->info = uinfo_copy (old->info, old->ukind);
9912 uentry_copyAux (uentry e, bool saveCopy)
9915 if (uentry_isValid (e))
9917 uentry enew = uentry_alloc ();
9918 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9919 enew->ukind = e->ukind;
9920 enew->uname = cstring_copy (e->uname);
9921 enew->utype = e->utype;
9923 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9924 enew->whereDefined = fileloc_copy (e->whereDefined);
9925 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9929 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9933 enew->sref = sRef_copy (e->sref);
9936 enew->used = e->used;
9938 enew->isPrivate = e->isPrivate;
9939 enew->hasNameError = e->hasNameError;
9940 enew->uses = filelocList_undefined;
9942 enew->storageclass = e->storageclass;
9943 enew->info = uinfo_copy (e->info, e->ukind);
9944 enew->warn = warnClause_copy (e->warn);
9946 DPRINTF (("Here we are..."));
9947 DPRINTF (("original: %s", uentry_unparseFull (e)));
9948 DPRINTF (("copy: %s", uentry_unparse (enew)));
9949 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9954 return uentry_undefined;
9959 uentry_copy (uentry e)
9961 return uentry_copyAux (e, TRUE);
9965 uentry_copyNoSave (uentry e)
9967 return uentry_copyAux (e, FALSE);
9971 uentry_setState (uentry res, uentry other)
9973 llassert (uentry_isValid (res));
9974 llassert (uentry_isValid (other));
9976 llassert (res->ukind == other->ukind);
9977 llassert (res->ukind == KVAR);
9979 res->sref = sRef_saveCopy (other->sref);
9980 res->used = other->used;
9981 filelocList_free (res->uses);
9982 res->uses = other->uses;
9983 other->uses = filelocList_undefined;
9984 res->lset = other->lset;
9988 uentry_mergeUses (uentry res, uentry other)
9990 llassert (uentry_isValid (res));
9991 llassert (uentry_isValid (other));
9993 res->used = other->used || res->used;
9994 res->lset = other->lset || res->lset;
9995 res->uses = filelocList_append (res->uses, other->uses);
9996 other->uses = filelocList_undefined;
10001 ** This is a really ugly routine.
10003 ** gack...fix this one day.
10008 ** >> res is the false branch, other is the true branch (or continuation)
10010 ** >> res is the true branch, other is the false branch (or continutation)
10017 ** References not effected by res are propagated from other.
10021 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10022 bool flip, clause cl, fileloc loc)
10026 message ("%s %q is %s %s, but %s %s.",
10027 ekind_capName (res->ukind), uentry_getName (res),
10028 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10029 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10032 if (sRef_isDead (res->sref))
10034 sRef_showStateInfo (res->sref);
10035 sRef_showStateInfo (other->sref);
10037 else if (sRef_isKept (res->sref))
10039 sRef_showAliasInfo (res->sref);
10040 sRef_showAliasInfo (other->sref);
10042 else /* dependent */
10044 sRef_showAliasInfo (res->sref);
10045 sRef_showAliasInfo (other->sref);
10048 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10052 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10054 alkind rk = sRef_getAliasKind (rs);
10055 alkind ok = sRef_getAliasKind (os);
10057 if (alkind_isError (rk) || alkind_isError (ok))
10063 return ((sRef_isDead (rs)
10064 || (alkind_isKept (rk) && !alkind_isKept (ok))
10065 || (alkind_isDependent (rk)
10066 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10067 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10072 branchStateAltError (/*@notnull@*/ uentry res,
10073 /*@notnull@*/ uentry other, bool flip,
10074 clause cl, fileloc loc)
10078 message ("%s %q is %s %s, but %s %s.",
10079 ekind_capName (res->ukind), uentry_getName (res),
10080 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10081 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10084 if (sRef_isDead (other->sref))
10086 sRef_showStateInfo (other->sref);
10090 sRef_showAliasInfo (other->sref);
10093 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10094 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10096 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10097 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10102 ** A reference is relevant for certain checks, only if it
10103 ** is not definitely null on this path (but not declared
10104 ** to always be null.)
10107 static bool uentry_relevantReference (sRef sr, bool flip)
10109 if (sRef_isKept (sr) || sRef_isDependent (sr))
10117 return !sRef_definitelyNullContext (sr);
10121 return !sRef_definitelyNullAltContext (sr);
10127 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10128 fileloc loc, bool mustReturn, bool flip, bool opt,
10131 sRef rs = res->sref;
10132 sRef os = other->sref;
10134 DPRINTF (("Merge alias states: %s / %s",
10135 uentry_unparseFull (res),
10136 uentry_unparseFull (other)));
10138 if (sRef_isValid (rs))
10142 if (uentry_incompatibleMemoryStates (rs, os))
10144 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10145 sRef_unparseFull (rs), sRef_unparseFull (os)));
10147 if (sRef_isThroughArrayFetch (rs)
10148 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10150 if (sRef_isKept (rs) || sRef_isKept (os))
10152 sRef_maybeKill (rs, loc);
10154 else if (sRef_isPossiblyDead (os))
10156 sRef_maybeKill (rs, loc);
10165 if (uentry_relevantReference (os, flip))
10167 if (sRef_isLocalParamVar (rs)
10168 && (sRef_isLocalState (os)
10169 || sRef_isDependent (os)))
10171 if (sRef_isDependent (rs))
10173 sRef_setDependent (os, loc);
10177 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10182 branchStateError (res, other, flip, cl, loc);
10187 if (sRef_isKept (rs))
10189 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10190 sRef_setKept (os, loc);
10195 if (uentry_incompatibleMemoryStates (os, rs))
10197 if (uentry_relevantReference (rs, !flip))
10199 if (sRef_isLocalParamVar (rs)
10200 && (sRef_isDependent (rs)
10201 || sRef_isLocalState (rs)))
10203 if (sRef_isDependent (os))
10205 sRef_setDependent (rs, loc);
10209 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10214 if (sRef_isParam (os))
10217 ** If the local variable associated
10218 ** with the param has the correct state,
10220 ** (e.g., free (s); s = new(); ...
10223 uentry uvar = usymtab_lookupSafe (other->uname);
10225 if (uentry_isValid (uvar)
10226 && ((sRef_isDead (os)
10227 && sRef_isOnly (uvar->sref))
10228 || (sRef_isDependent (os)
10229 && sRef_isOwned (uvar->sref))))
10235 branchStateAltError (res, other,
10241 DPRINTF (("Here: %s / %s",
10242 uentry_unparseFull (res),
10243 uentry_unparseFull (other)));
10245 branchStateAltError (res, other,
10252 if (sRef_isKept (os))
10254 sRef_setKept (rs, loc);
10260 DPRINTF (("Merge opt..."));
10261 sRef_mergeOptState (rs, os, cl, loc);
10262 DPRINTF (("Done!"));
10266 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10267 sRef_mergeState (rs, os, cl, loc);
10268 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10273 if (sRef_isModified (os))
10275 sRef_setModified (rs);
10280 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10284 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10285 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10287 valueTable rvalues;
10288 valueTable ovalues;
10290 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10298 rvalues = sRef_getValueTable (res->sref);
10299 ovalues = sRef_getValueTable (other->sref);
10301 if (valueTable_isUndefined (ovalues))
10303 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10306 else if (valueTable_isUndefined (rvalues))
10309 ** Copy values from other
10313 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10314 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10319 valueTable_elements (ovalues, fkey, fval) {
10321 metaStateInfo minfo;
10322 stateCombinationTable sctable;
10326 tval = valueTable_lookup (rvalues, fkey);
10328 DPRINTF (("Merge value: %s / %s X %s", fkey,
10329 stateValue_unparse (fval), stateValue_unparse (tval)));
10331 minfo = context_lookupMetaStateInfo (fkey);
10332 llassert (stateValue_isDefined (tval));
10334 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10336 DPRINTF (("Cannot find meta state for: %s", fkey));
10341 llassert (metaStateInfo_isDefined (minfo));
10343 if (stateValue_isError (fval)
10344 || sRef_definitelyNullContext (res->sref))
10346 sRef_setMetaStateValueComplete (res->sref,
10347 fkey, stateValue_getValue (fval),
10348 stateValue_getLoc (fval));
10349 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10351 else if (stateValue_isError (tval)
10352 || sRef_definitelyNullAltContext (other->sref))
10354 DPRINTF (("Other branch is definitely null!"));
10356 else if (sRef_isStateUndefined (res->sref)
10357 || sRef_isDead (res->sref))
10359 ; /* Combination state doesn't matter if it is undefined or dead */
10363 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10364 metaStateInfo_unparse (minfo),
10365 stateValue_unparse (fval),
10366 stateValue_unparse (tval)));
10368 DPRINTF (("state values: %d / %d",
10369 stateValue_getValue (fval), stateValue_getValue (tval)));
10371 sctable = metaStateInfo_getMergeTable (minfo);
10373 DPRINTF (("Merge table: %s",
10374 stateCombinationTable_unparse (sctable)));
10376 msg = cstring_undefined;
10378 nval = stateCombinationTable_lookup (sctable,
10379 stateValue_getValue (fval),
10380 stateValue_getValue (tval),
10383 DPRINTF (("nval: %d / %d / %d", nval,
10384 stateValue_getValue (fval), stateValue_getValue (tval)));
10386 if (nval == stateValue_error)
10388 /*@i32 print extra info for assignments@*/
10390 if (uentry_isGlobalMarker (res))
10395 ("Control branches merge with incompatible global states (%s and %s)%q",
10396 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10397 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10398 cstring_isDefined (msg)
10399 ? message (": %s", msg) : cstring_undefined),
10402 sRef_showMetaStateInfo (res->sref, fkey);
10403 sRef_showMetaStateInfo (other->sref, fkey);
10411 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10412 uentry_getName (res),
10413 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10414 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10415 cstring_isDefined (msg)
10416 ? message (": %s", msg) : cstring_undefined),
10419 sRef_showMetaStateInfo (res->sref, fkey);
10420 sRef_showMetaStateInfo (other->sref, fkey);
10421 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10422 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10423 DPRINTF (("Null: %s / %s",
10424 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10425 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10431 if (nval == stateValue_getValue (fval)
10432 && nval != stateValue_getValue (tval))
10434 loc = stateValue_getLoc (fval);
10436 else if (nval == stateValue_getValue (tval)
10437 && nval != stateValue_getValue (fval))
10439 loc = stateValue_getLoc (tval);
10446 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10447 && nval == stateValue_getValue (fval)
10448 && nval == stateValue_getValue (tval))
10454 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10458 } end_valueTable_elements ;
10464 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10465 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10466 bool flip, clause cl)
10468 if (cl == DOWHILECLAUSE)
10470 res->used = other->used || res->used;
10471 res->lset = other->lset || res->lset;
10472 res->uses = filelocList_append (res->uses, other->uses);
10473 other->uses = filelocList_undefined;
10477 if (sRef_isMacroParamRef (res->sref)
10478 && !uentry_isSefParam (other)
10479 && !uentry_isSefParam (res))
10481 bool hasError = FALSE;
10483 if (bool_equal (res->used, other->used))
10485 res->used = other->used;
10489 if (other->used && !flip)
10494 message ("Macro parameter %q used in true clause, "
10495 "but not in false clause",
10496 uentry_getName (res)),
10497 uentry_whereDeclared (res));
10504 message ("Macro parameter %q used in false clause, "
10505 "but not in true clause",
10506 uentry_getName (res)),
10507 uentry_whereDeclared (res));
10513 /* make it sef now, prevent more errors */
10514 res->info->var->kind = VKREFSEFPARAM;
10520 res->used = other->used || res->used;
10521 res->lset = other->lset || res->lset;
10522 res->uses = filelocList_append (res->uses, other->uses);
10523 other->uses = filelocList_undefined;
10529 uentry_mergeState (uentry res, uentry other, fileloc loc,
10530 bool mustReturn, bool flip, bool opt,
10533 llassert (uentry_isValid (res));
10534 llassert (uentry_isValid (other));
10536 llassert (res->ukind == other->ukind);
10537 llassert (res->ukind == KVAR);
10539 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10540 uentry_unparseFull (other)));
10542 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10543 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10544 uentry_mergeSetStates (res, other, loc, flip, cl);
10546 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10549 void uentry_setUsed (uentry e, fileloc loc)
10551 static bool firstTime = TRUE;
10552 static bool showUses = FALSE;
10553 static bool exportLocal = FALSE;
10555 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10559 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10561 showUses = context_getFlag (FLG_SHOWUSES);
10562 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10567 if (uentry_isValid (e))
10571 if (warnClause_isDefined (e->warn))
10573 flagSpec flg = warnClause_getFlag (e->warn);
10576 if (warnClause_hasMessage (e->warn))
10578 msg = cstring_copy (warnClause_getMessage (e->warn));
10582 msg = message ("Use of possibly dangerous %s",
10583 uentry_ekindNameLC (e));
10587 message ("%q: %q", msg, uentry_getName (e)),
10591 if (sRef_isMacroParamRef (e->sref))
10593 if (uentry_isYield (e) || uentry_isSefParam (e))
10599 if (context_inConditional ())
10603 message ("Macro parameter %q used in conditionally "
10604 "executed code (may or may not be "
10605 "evaluated exactly once)",
10606 uentry_getName (e)),
10609 e->info->var->kind = VKREFSEFPARAM;
10618 message ("Macro parameter %q used more than once",
10619 uentry_getName (e)),
10620 uentry_whereDeclared (e)))
10622 e->info->var->kind = VKREFSEFPARAM;
10629 if ((dp = uentry_directParamNo (e)) >= 0)
10631 uentry_setUsed (usymtab_getParam (dp), loc);
10636 if (!sRef_isLocalVar (e->sref))
10640 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10646 if (context_inMacro ())
10648 e->uses = filelocList_addUndefined (e->uses);
10652 e->uses = filelocList_addDifferentFile
10654 uentry_whereDeclared (e),
10663 bool uentry_isReturned (uentry u)
10665 return (uentry_isValid (u) && uentry_isVar (u)
10666 && (u->info->var->kind == VKRETPARAM
10667 || u->info->var->kind == VKSEFRETPARAM));
10672 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10674 llassert (uentry_isRealFunction (u));
10676 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10678 stateClauseList clauses = uentry_getStateClauseList (u);
10679 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10681 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10682 sRef_setAllocated (res, g_currentloc);
10684 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10685 stateClauseList_unparse (clauses)));
10688 ** This should be in exprNode_reflectEnsuresClause
10691 stateClauseList_postElements (clauses, cl)
10693 if (!stateClause_isGlobal (cl))
10695 sRefSet refs = stateClause_getRefs (cl);
10696 sRefMod modf = stateClause_getEffectFunction (cl);
10698 sRefSet_elements (refs, el)
10700 sRef base = sRef_getRootBase (el);
10702 if (sRef_isResult (base))
10706 sRef sr = sRef_fixBase (el, res);
10707 modf (sr, g_currentloc);
10714 } end_sRefSet_elements ;
10716 } end_stateClauseList_postElements ;
10724 sRefSet prefs = sRefSet_new ();
10725 sRef res = sRef_undefined;
10726 sRef tcref = sRef_undefined;
10727 sRef tref = sRef_undefined;
10730 params = uentry_getParams (u);
10733 ** Setting up aliases has to happen *after* setting null state!
10736 uentryList_elements (params, current)
10738 if (uentry_isReturned (current))
10740 if (exprNodeList_size (args) >= paramno)
10742 exprNode ecur = exprNodeList_nth (args, paramno);
10743 tref = exprNode_getSref (ecur);
10745 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10747 if (sRef_isValid (tref))
10749 tcref = sRef_copy (tref);
10751 if (sRef_isDead (tcref))
10753 sRef_setDefined (tcref, g_currentloc);
10754 sRef_setOnly (tcref, g_currentloc);
10757 if (sRef_isRefCounted (tcref))
10759 /* could be a new ref now (but only if its returned) */
10760 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10763 sRef_makeSafe (tcref);
10764 prefs = sRefSet_insert (prefs, tcref);
10770 } end_uentryList_elements ;
10772 if (sRefSet_size (prefs) > 0)
10774 nstate n = sRef_getNullState (u->sref);
10776 if (sRefSet_size (prefs) == 1)
10778 sRef rref = sRefSet_choose (prefs);
10780 res = sRef_makeType (sRef_getType (rref));
10781 sRef_copyState (res, tref);
10785 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10786 res = sRefSet_mergeIntoOne (prefs);
10789 if (nstate_isKnown (n))
10791 sRef_setNullState (res, n, g_currentloc);
10792 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10797 if (ctype_isFunction (u->utype))
10799 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10800 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10804 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10805 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10808 if (sRef_isRefCounted (res))
10810 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10814 if (sRef_getNullState (res) == NS_ABSNULL)
10816 ctype ct = ctype_realType (u->utype);
10818 if (ctype_isAbstract (ct))
10820 sRef_setNotNull (res, g_currentloc);
10824 if (ctype_isUser (ct))
10826 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10830 sRef_setNotNull (res, g_currentloc);
10835 if (sRef_isRefCounted (res))
10837 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10839 else if (sRef_isKillRef (res))
10841 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10848 ak = sRef_getAliasKind (res);
10850 if (alkind_isImplicit (ak))
10852 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10856 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10857 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10859 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10860 usymtab_addReallyForceMustAlias (res, tref);
10863 sRefSet_free (prefs);
10865 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10871 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
10873 llassert (uentry_isRealFunction (u));
10875 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10877 stateClauseList clauses = uentry_getStateClauseList (u);
10878 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10880 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10881 sRef_setAllocated (res, loc);
10883 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10884 stateClauseList_unparse (clauses)));
10887 ** This should be in exprNode_reflectEnsuresClause
10890 stateClauseList_postElements (clauses, cl)
10892 if (!stateClause_isGlobal (cl))
10894 sRefSet refs = stateClause_getRefs (cl);
10895 sRefMod modf = stateClause_getEffectFunction (cl);
10897 sRefSet_elements (refs, el)
10899 sRef base = sRef_getRootBase (el);
10901 if (sRef_isResult (base))
10905 sRef sr = sRef_fixBase (el, res);
10913 } end_sRefSet_elements ;
10915 } end_stateClauseList_postElements ;
10923 sRefSet prefs = sRefSet_new ();
10924 sRef res = sRef_undefined;
10927 params = uentry_getParams (u);
10929 uentryList_elements (params, current)
10931 if (uentry_isReturned (current))
10933 if (exprNodeList_size (args) >= paramno)
10935 exprNode ecur = exprNodeList_nth (args, paramno);
10936 sRef tref = exprNode_getSref (ecur);
10938 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10940 if (sRef_isValid (tref))
10942 sRef tcref = sRef_copy (tref);
10944 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10946 if (sRef_isNew (tcref))
10948 /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
10951 if (sRef_isDead (tcref))
10953 sRef_setDefined (tcref, loc);
10954 sRef_setOnly (tcref, loc);
10957 if (sRef_isRefCounted (tcref))
10959 /* could be a new ref now (but only if its returned) */
10960 sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
10963 sRef_makeSafe (tcref);
10964 DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
10965 prefs = sRefSet_insert (prefs, tcref);
10971 } end_uentryList_elements ;
10973 if (sRefSet_size (prefs) > 0)
10975 nstate n = sRef_getNullState (u->sref);
10977 if (sRefSet_size (prefs) == 1)
10979 res = sRefSet_choose (prefs);
10983 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10984 res = sRefSet_mergeIntoOne (prefs);
10987 if (nstate_isKnown (n))
10989 sRef_setNullState (res, n, loc);
10994 if (ctype_isFunction (u->utype))
10996 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10997 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
11001 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
11004 if (sRef_isRefCounted (res))
11006 sRef_setAliasKind (res, AK_NEWREF, loc);
11011 if (sRef_getNullState (res) == NS_ABSNULL)
11013 ctype ct = ctype_realType (u->utype);
11015 if (ctype_isAbstract (ct))
11017 sRef_setNotNull (res, loc);
11021 if (ctype_isUser (ct))
11023 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
11027 sRef_setNotNull (res, loc);
11032 if (sRef_isRefCounted (res))
11034 sRef_setAliasKind (res, AK_NEWREF, loc);
11036 else if (sRef_isKillRef (res))
11038 sRef_setAliasKind (res, AK_REFCOUNTED, loc);
11045 ak = sRef_getAliasKind (res);
11047 if (alkind_isImplicit (ak))
11049 sRef_setAliasKind (res,
11050 alkind_fixImplicit (ak),
11054 sRefSet_free (prefs);
11057 if (sRef_isOnly (res))
11059 sRef_setFresh (res, loc);
11063 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11068 static bool uentry_isRefCounted (uentry ue)
11070 ctype ct = uentry_getType (ue);
11072 if (ctype_isFunction (ct))
11074 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11078 return (ctype_isRefCounted (ct));
11083 ** old was declared yield in the specification.
11084 ** new is declared in the iter implementation.
11087 void uentry_checkYieldParam (uentry old, uentry unew)
11091 llassert (uentry_isVariable (old));
11092 llassert (uentry_isVariable (unew));
11094 unew->info->var->kind = VKYIELDPARAM;
11095 (void) checkTypeConformance (old, unew, TRUE);
11096 checkVarConformance (old, unew, TRUE, FALSE);
11098 /* get rid of param marker */
11100 name = uentry_getName (unew);
11101 cstring_free (unew->uname);
11102 unew->uname = name;
11103 unew->info->var->kind = VKREFYIELDPARAM;
11105 uentry_setUsed (old, fileloc_undefined);
11106 uentry_setUsed (unew, fileloc_undefined);
11109 /*@observer@*/ cstring
11110 uentry_ekindName (uentry ue)
11112 if (uentry_isValid (ue))
11117 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11119 return cstring_makeLiteralTemp ("Datatype");
11121 return cstring_makeLiteralTemp ("Enum member");
11123 return cstring_makeLiteralTemp ("Constant");
11125 if (uentry_isParam (ue))
11127 return cstring_makeLiteralTemp ("Parameter");
11129 else if (uentry_isExpandedMacro (ue))
11131 return cstring_makeLiteralTemp ("Expanded macro");
11135 return cstring_makeLiteralTemp ("Variable");
11138 return cstring_makeLiteralTemp ("Function");
11140 return cstring_makeLiteralTemp ("Iterator");
11142 return cstring_makeLiteralTemp ("Iterator finalizer");
11144 return cstring_makeLiteralTemp ("Struct tag");
11146 return cstring_makeLiteralTemp ("Union tag");
11148 return cstring_makeLiteralTemp ("Enum tag");
11150 return cstring_makeLiteralTemp ("Optional parameters");
11155 return cstring_makeLiteralTemp ("<Undefined>");
11161 /*@observer@*/ cstring
11162 uentry_ekindNameLC (uentry ue)
11164 if (uentry_isValid (ue))
11169 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11171 return cstring_makeLiteralTemp ("datatype");
11173 return cstring_makeLiteralTemp ("enum member");
11175 return cstring_makeLiteralTemp ("constant");
11177 if (uentry_isParam (ue))
11179 return cstring_makeLiteralTemp ("parameter");
11181 else if (uentry_isExpandedMacro (ue))
11183 return cstring_makeLiteralTemp ("expanded macro");
11187 return cstring_makeLiteralTemp ("variable");
11190 return cstring_makeLiteralTemp ("function");
11192 return cstring_makeLiteralTemp ("iterator");
11194 return cstring_makeLiteralTemp ("iterator finalizer");
11196 return cstring_makeLiteralTemp ("struct tag");
11198 return cstring_makeLiteralTemp ("union tag");
11200 return cstring_makeLiteralTemp ("enum tag");
11202 return cstring_makeLiteralTemp ("optional parameters");
11207 return cstring_makeLiteralTemp ("<Undefined>");
11213 void uentry_setHasNameError (uentry ue)
11215 llassert (uentry_isValid (ue));
11217 ue->hasNameError = TRUE;
11220 void uentry_checkName (uentry ue)
11222 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11223 uentry_observeRealName (ue),
11224 bool_unparse (uentry_isVisibleExternally (ue))));
11226 if (uentry_isValid (ue)
11227 && !context_inXHFile ()
11228 && uentry_hasName (ue)
11229 && !uentry_isElipsisMarker (ue)
11230 && context_getFlag (FLG_NAMECHECKS)
11231 && !ue->hasNameError
11232 && !uentry_isEndIter (ue)
11233 && !fileloc_isBuiltin (uentry_whereLast (ue))
11234 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11236 DPRINTF (("Here..."));
11238 if (uentry_isPriv (ue))
11240 ; /* any checks here? */
11242 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11244 ; /* no errors for externals */
11250 if (uentry_isExpandedMacro (ue))
11256 if (uentry_isExpandedMacro (ue))
11260 else if (uentry_isVariable (ue))
11262 sRef sr = uentry_getSref (ue);
11264 if (sRef_isValid (sr))
11266 scope = sRef_getScope (sr);
11273 else if (uentry_isFunction (ue)
11274 || uentry_isIter (ue)
11275 || uentry_isEndIter (ue)
11276 || uentry_isConstant (ue))
11278 scope = uentry_isStatic (ue) ? fileScope : globScope;
11280 else /* datatypes, etc. must be global */
11285 usymtab_checkDistinctName (ue, scope);
11288 if (context_getFlag (FLG_CPPNAMES))
11293 if (scope == globScope)
11295 checkExternalName (ue);
11297 else if (scope == fileScope)
11299 checkFileScopeName (ue);
11303 checkLocalName (ue);
11307 checkAnsiName (ue);
11312 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11318 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11321 if (!context_inMacro ())
11323 sRef_setGlobalScopeSafe ();
11326 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11327 uentry_setUsed (ue, loc);
11329 tloc = fileloc_createExternal ();
11330 uentry_setDefined (ue, tloc);
11331 fileloc_free (tloc);
11332 uentry_setHasNameError (ue);
11334 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11336 uentry_markOwned (ue);
11340 ue = usymtab_supReturnFileEntry (ue);
11343 if (!context_inMacro ())
11345 sRef_clearGlobalScopeSafe ();
11351 uentry uentry_makeGlobalMarker ()
11356 llassert (sRef_inGlobalScope ());
11358 ue = uentry_makeVariableAux
11359 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11360 sRef_makeGlobalMarker (),
11363 tloc = fileloc_createExternal ();
11364 uentry_setUsed (ue, tloc);
11365 uentry_setDefined (ue, tloc);
11366 fileloc_free (tloc);
11367 uentry_setHasNameError (ue);
11373 bool uentry_isGlobalMarker (uentry ue)
11375 return (uentry_isValid (ue)
11376 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11379 /* new start modifications */
11381 /* start modifications */
11383 requires: p_e is defined, is a ptr/array variable
11385 effects: sets the state of the variable
11389 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11391 llassert (uentry_isValid (p_e));
11393 if (p_e->info != NULL)
11395 if (p_e->info->var != NULL)
11397 llassert (p_e->info->var->bufinfo != NULL);
11398 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11399 sRef_setPossiblyNullTerminatedState (p_e->sref);
11405 requires: p_e is defined, is a ptr/array variable
11407 effects: sets the size of the buffer
11410 void uentry_setNullTerminatedState (uentry p_e) {
11411 llassert (uentry_isValid (p_e));
11413 if (p_e->info != NULL)
11415 if (p_e->info->var != NULL)
11417 llassert (p_e->info->var->bufinfo != NULL);
11418 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11419 sRef_setNullTerminatedState (p_e->sref);
11425 requires: p_e is defined, is a ptr/array variable
11427 effects: sets the size of the buffer
11430 void uentry_setSize (uentry p_e, int size)
11432 if (uentry_isValid (p_e))
11434 if (p_e->info != NULL)
11436 if (p_e->info->var != NULL)
11438 llassert (p_e->info->var->bufinfo != NULL);
11439 p_e->info->var->bufinfo->size = size;
11440 sRef_setSize (p_e->sref, size);
11447 requires: p_e is defined, is a ptr/array variable
11449 effects: sets the length of the buffer
11452 void uentry_setLen (uentry p_e, int len)
11454 if (uentry_isValid (p_e))
11456 if (p_e->info != NULL
11457 && p_e->info->var != NULL)
11459 llassert (p_e->info->var->bufinfo != NULL);
11460 p_e->info->var->bufinfo->len = len;
11461 sRef_setLen (p_e->sref, len);
11468 bool uentry_hasMetaStateEnsures (uentry e)
11470 if (uentry_isValid (e) && uentry_isFunction (e))
11472 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11480 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11482 llassert (uentry_isValid (e) && uentry_isFunction (e));
11483 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11486 # ifdef DEBUGSPLINT
11489 ** For debugging only
11492 void uentry_checkValid (uentry ue)
11494 if (uentry_isValid (ue))
11496 sRef_checkCompletelyReasonable (ue->sref);