2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
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, qual_createUnknown (),
718 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
720 if (!qual_isEitherAbstract (ue->info->datatype->abs))
722 if (ctype_isUnknown (ct))
724 ue->info->datatype->mut = MAYBE;
728 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
735 void uentry_checkParams (uentry ue)
737 if (uentry_isValid (ue))
739 bool isExt = uentry_isExtern (ue);
741 if (uentry_isRealFunction (ue))
743 uentryList params = uentry_getParams (ue);
746 uentryList_elements (params, current)
750 if (uentry_isValid (current))
752 ctype ct = current->utype;
754 if (ctype_isFixedArray (ct))
756 if (ctype_isArray (ctype_baseArrayPtr (ct))
757 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
763 if (uentry_hasName (current))
766 (FLG_FIXEDFORMALARRAY,
767 message ("Function parameter %q declared as "
768 "manifest array (size constant is meaningless)",
769 uentry_getName (current)),
770 uentry_whereDeclared (current));
775 (FLG_FIXEDFORMALARRAY,
776 message ("Unnamed function parameter %d declared as "
777 "manifest array (size constant is meaningless)",
779 uentry_whereDeclared (current));
785 if (ctype_isArray (ct))
787 if (uentry_hasName (current))
791 message ("Function parameter %q declared as "
792 "array (treated as pointer)",
793 uentry_getName (current)),
794 uentry_whereDeclared (current));
800 message ("Unnamed function parameter %d declared as "
801 "array (treated as pointer)",
803 uentry_whereDeclared (current));
808 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
810 if (ctype_isAbstract (ct) &&
811 (isExt || (ctype_isAbstract (ctype_realType (ct))
812 && !context_hasFileAccess (ctype_typeId (ct)))))
817 ("Function %q declared with notnull parameter %q of abstract "
820 uentry_getName (current),
823 ("Since %s is an abstract type, notnull can only be "
824 "used for parameters if the function is static to a "
825 "module where %s is accessible.",
828 uentry_whereDeclared (current));
832 } end_uentryList_elements;
834 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
836 ctype ct = ue->utype;
838 if (ctype_isAbstract (ct)
839 && (isExt || (ctype_isAbstract (ctype_realType (ct))
840 && !context_hasFileAccess (ctype_typeId (ct)))))
845 ("%s %q declared %s notnull storage of abstract type %s",
846 ekind_capName (uentry_getKind (ue)),
851 ("Since %s is an abstract type, notnull can only be used "
852 "if it is static to a module where %s is accessible.",
855 uentry_whereDeclared (ue));
862 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
864 alkind ak = sRef_getAliasKind (ue->sref);
866 if (alkind_isRefCounted (ak))
868 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
872 if (alkind_isUnknown (ak))
874 exkind ek = sRef_getExKind (ue->sref);
876 if (exkind_isKnown (ek))
878 DPRINTF (("Setting imp dependent: %s",
879 uentry_unparseFull (ue)));
880 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
884 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
886 /* evans 2000-12-22 removed ctype_realType so it will
887 not apply to immutable abstract types. */
889 if (ctype_isVisiblySharable
890 (ctype_realType (ctype_getReturnType (ue->utype))))
892 if (uentryList_hasReturned (uentry_getParams (ue)))
898 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
900 ; /* Immutable objects are not shared. */
904 sRef_setAliasKind (ue->sref, AK_IMPONLY,
906 DPRINTF (("Ret imp only: %s",
907 ctype_unparse (ctype_getReturnType (ue->utype))));
917 static /*@notnull@*/ uentry
918 uentry_makeFunctionAux (cstring n, ctype t,
920 /*@only@*/ globSet globs,
921 /*@only@*/ sRefSet mods,
922 /*@only@*/ warnClause warn,
923 /*@keep@*/ fileloc f, bool priv,
924 /*@unused@*/ bool isForward)
926 uentry e = uentry_alloc ();
929 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
931 DPRINTF (("Make function: %s", n));
933 if (ctype_isFunction (t))
935 ret = ctype_getReturnType (t);
939 if (ctype_isKnown (t))
941 llbug (message ("not function: %s", ctype_unparse (t)));
948 if (fileloc_isSpec (f) || fileloc_isImport (f))
950 e->whereSpecified = f;
951 e->whereDeclared = fileloc_undefined;
955 e->whereSpecified = fileloc_undefined;
956 e->whereDeclared = f;
959 /* e->shallowCopy = FALSE; */
960 e->uname = cstring_copy (n);
962 e->storageclass = SCNONE;
964 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
966 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
968 if (ctype_isUA (ret))
970 sRef_setStateFromType (e->sref, ret);
975 e->uses = filelocList_new ();
977 e->hasNameError = FALSE;
981 e->info = (uinfo) dmalloc (sizeof (*e->info));
982 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
984 e->info->fcn->hasMods = sRefSet_isDefined (mods);
985 e->info->fcn->hasGlobs = globSet_isDefined (globs);
987 e->info->fcn->exitCode = XK_UNKNOWN;
988 e->info->fcn->nullPred = qual_createUnknown ();
989 e->info->fcn->specialCode = SPC_NONE;
991 e->info->fcn->access = access;
992 e->info->fcn->globs = globs;
993 e->info->fcn->defparams = uentryList_undefined;
995 sRef_setDefined (e->sref, f);
996 e->whereDefined = fileloc_undefined;
998 e->info->fcn->mods = sRefSet_undefined;
999 e->info->fcn->specclauses = NULL;
1002 e->info->fcn->preconditions = NULL;
1006 e->info->fcn->postconditions = NULL;
1009 checkGlobalsModifies (e, mods);
1010 e->info->fcn->mods = mods;
1015 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
1017 functionClauseList_elements (clauses, el)
1019 DPRINTF (("Reflect clause: %s on %s",
1020 functionClause_unparse (el), uentry_getName (ue)));
1022 if (functionClause_isNoMods (el))
1024 modifiesClause mel = functionClause_getModifies (el);
1026 if (uentry_hasGlobs (ue))
1031 ("No globals and modifies inconsistent to globals clause for %q: %q",
1032 uentry_getName (ue),
1033 globSet_unparse (uentry_getGlobs (ue))),
1034 modifiesClause_getLoc (mel));
1038 if (uentry_hasMods (ue))
1043 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1044 uentry_getName (ue),
1045 sRefSet_unparse (uentry_getMods (ue))),
1046 modifiesClause_getLoc (mel));
1049 uentry_setGlobals (ue, globSet_undefined);
1050 uentry_setModifies (ue, sRefSet_undefined);
1052 else if (functionClause_isGlobals (el))
1054 globalsClause glc = functionClause_getGlobals (el);
1056 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1057 globalsClause_unparse (glc)));
1059 if (uentry_hasGlobs (ue))
1064 ("Multiple globals clauses for %q: %q",
1065 uentry_getName (ue),
1066 globalsClause_unparse (glc)),
1067 cstring_makeLiteral ("Only one globals clause may be used. The second globals clause is ignored."),
1068 globalsClause_getLoc (glc));
1071 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1076 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1077 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1078 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1081 else if (functionClause_isModifies (el))
1083 modifiesClause mlc = functionClause_getModifies (el);
1085 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1087 if (uentry_hasMods (ue))
1095 ("Multiple modifies clauses for %s: %s",
1096 uentry_getName (ue),
1097 modifiesClause_unparse (mlc)),
1098 modifiesClause_getLoc (mlc)))
1100 llhint (message ("Previous modifies clause: ",
1101 sRefSet_unparse (uentry_getMods (ue))));
1107 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1111 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1114 else if (functionClause_isEnsures (el))
1116 functionConstraint cl = functionClause_takeEnsures (el);
1117 DPRINTF (("Setting post: %s / %s",
1118 uentry_unparse (ue), functionConstraint_unparse (cl)));
1119 uentry_setPostconditions (ue, cl);
1121 else if (functionClause_isRequires (el))
1123 functionConstraint cl = functionClause_takeRequires (el);
1124 uentry_setPreconditions (ue, cl);
1126 else if (functionClause_isState (el))
1128 stateClause sc = functionClause_takeState (el);
1130 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1132 sRefSet rfs = stateClause_getRefs (sc);
1134 sRefSet_elements (rfs, s)
1136 if (sRef_isParam (s))
1139 ** Can't use requires on parameters
1143 (FLG_ANNOTATIONERROR,
1144 message ("Requires clauses for %q concerns parameters %q should be "
1145 "a parameter annotation instead: %q",
1146 uentry_unparse (ue),
1148 stateClause_unparse (sc)),
1149 stateClause_loc (sc));
1151 } end_sRefSet_elements ;
1154 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1155 uentry_addStateClause (ue, sc);
1157 else if (functionClause_isWarn (el))
1159 warnClause wc = functionClause_takeWarn (el);
1160 uentry_addWarning (ue, wc);
1164 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1166 } end_functionClauseList_elements ;
1168 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1169 stateClauseList_checkAll (ue);
1172 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1174 bool leaveFunc = FALSE;
1176 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1177 typeId_invalid, globSet_undefined,
1178 sRefSet_undefined, warnClause_undefined,
1181 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1184 ** This makes parameters names print out correctly.
1185 ** (But we might be a local variable declaration for a function type...)
1188 if (context_inFunctionLike ())
1190 DPRINTF (("Header: %s / %s",
1191 uentry_unparse (context_getHeader ()),
1192 idDecl_unparse (id)));
1196 context_enterFunctionDeclaration (ue);
1200 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1201 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1202 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1203 reflectImplicitFunctionQualifiers (ue, FALSE);
1204 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1205 uentry_reflectClauses (ue, idDecl_getClauses (id));
1206 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1208 if (!uentry_isStatic (ue)
1209 && cstring_equalLit (ue->uname, "main"))
1211 ctype typ = ue->utype;
1215 llassert (ctype_isFunction (typ));
1217 retval = ctype_getReturnType (typ);
1219 if (!ctype_isInt (retval))
1223 message ("Function main declared to return %s, should return int",
1224 ctype_unparse (retval)),
1225 uentry_whereDeclared (ue));
1228 args = ctype_argsFunction (typ);
1230 if (uentryList_isMissingParams (args)
1231 || uentryList_size (args) == 0)
1237 if (uentryList_size (args) != 2)
1241 message ("Function main declared with %d arg%&, "
1242 "should have 2 (int argc, char *argv[])",
1243 uentryList_size (args)),
1244 uentry_whereLast (ue));
1248 uentry arg = uentryList_getN (args, 0);
1249 ctype ct = uentry_getType (arg);
1251 if (!ctype_isInt (ct))
1255 message ("Parameter 1, %q, of function main declared "
1256 "with type %t, should have type int",
1257 uentry_getName (arg), ct),
1258 uentry_whereDeclared (arg));
1261 arg = uentryList_getN (args, 1);
1262 ct = uentry_getType (arg);
1264 if (ctype_isArrayPtr (ct)
1265 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1266 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1274 message ("Parameter 2, %q, of function main declared "
1275 "with type %t, should have type char **",
1276 uentry_getName (arg), ct),
1277 uentry_whereDeclared (arg));
1285 context_exitFunctionDeclaration ();
1291 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1293 alkind ak = sRef_getAliasKind (e->sref);
1295 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1296 && context_getFlag (FLG_PARAMIMPTEMP))
1298 exkind ek = sRef_getExKind (e->sref);
1300 if (exkind_isKnown (ek))
1302 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1303 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1304 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1308 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1309 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1314 static /*@only@*/ /*@notnull@*/ uentry
1315 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1316 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1318 cstring pname = makeParam (n);
1321 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1322 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1324 cstring_free (pname);
1325 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1326 uentry_implicitParamAnnots (e);
1327 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1329 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1331 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1332 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1333 e->info->var->defstate = defstate;
1336 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1341 uentry_setRefCounted (uentry e)
1343 if (uentry_isValid (e))
1345 uentry_setAliasKind (e, AK_REFCOUNTED);
1346 sRef_storeState (e->sref);
1351 uentry_setStatic (uentry c)
1353 if (uentry_isValid (c))
1355 alkind ak = sRef_getAliasKind (c->sref);
1356 c->storageclass = SCSTATIC;
1358 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1360 if (!alkind_isUnknown (ak)
1361 && !alkind_isStatic (ak))
1363 if (!(ctype_isRealPointer (uentry_getType (c)))
1364 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1365 && !alkind_isRefCounted (ak))
1367 if (alkind_isImplicit (ak)
1368 && alkind_isDependent (ak)
1369 && ctype_isArray (uentry_getType (c)))
1371 ; /* no error for observer arrays */
1377 message ("Static storage %q declared as %s",
1379 alkind_unparse (ak)),
1380 uentry_whereDeclared (c));
1386 if (alkind_isUnknown (ak)
1387 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1388 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1390 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1391 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1399 uentry_setExtern (uentry c)
1401 if (uentry_isValid (c))
1402 c->storageclass = SCEXTERN;
1406 uentry_setParamNo (uentry ue, int pno)
1408 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1409 sRef_setParamNo (ue->sref, pno);
1413 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1415 sRefSet_allElements (sr, el)
1417 sRef base = sRef_getRootBase (el);
1419 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1420 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1422 if (!globSet_member (ue->info->fcn->globs, base))
1424 if (uentry_hasGlobs (ue)
1425 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1428 (FLG_WARNMISSINGGLOBALS,
1430 ("Modifies list for %q uses global %q, "
1431 "not included in globals list.",
1432 uentry_getName (ue),
1433 sRef_unparse (base)),
1434 uentry_whereLast (ue)))
1436 uentry_showWhereSpecified (ue);
1440 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1442 if (sRef_isFileStatic (base))
1444 context_recordFileGlobals (ue->info->fcn->globs);
1448 } end_sRefSet_allElements;
1452 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1454 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1458 uentry_fixupSref (uentry ue)
1462 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1467 sr = uentry_getSref (ue);
1469 sRef_resetState (sr);
1470 sRef_clearDerived (sr);
1472 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1473 llassert (sRef_isValid (sr));
1475 if (uentry_isVariable (ue))
1478 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1479 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1480 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1484 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1487 ** Okay to allow multiple clauses of the same kind.
1488 */ /*@i834 is this true?@*/
1490 ue->info->fcn->specclauses =
1491 stateClauseList_add (ue->info->fcn->specclauses, sc);
1493 /* Will call checkAll to check later... */
1496 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1498 llassert (uentry_isFunction (ue));
1499 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1501 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1502 ue->info->fcn->specclauses = clauses;
1503 stateClauseList_checkAll (ue);
1504 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1508 ** Used for @modifies@ @endmodifies@ syntax.
1510 ** If ue is specified, sr must contain *only*:
1512 ** o file static globals
1513 ** o sRef's derived from modifies spec (i.e., more specific than
1514 ** what was specified)
1516 ** Otherwise, if sr has modifies it must match sr.
1518 ** If it doesn't have modifies, set them to sr.
1522 uentry_checkModifiesContext (void)
1524 if (sRef_modInFunction ())
1528 ("Modifies list not in function context. "
1529 "A modifies list can only appear following the parameter list "
1530 "in a function declaration or header."));
1539 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1541 if (!uentry_checkModifiesContext ())
1547 if (uentry_isValid (ue))
1549 if (uentry_isIter (ue))
1551 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1552 ue->info->iter->mods = sr;
1556 uentry_convertVarFunction (ue);
1557 llassertfatal (uentry_isFunction (ue));
1558 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1560 ue->info->fcn->mods = sr;
1561 ue->info->fcn->hasMods = TRUE;
1563 checkGlobalsModifies (ue, sr);
1566 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1568 ue->info->fcn->hasGlobs = TRUE;
1571 if (sRefSet_hasStatic (ue->info->fcn->mods))
1573 context_recordFileModifies (ue->info->fcn->mods);
1583 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1586 ** Function already has one modifies clause (possibly from
1587 ** a specification).
1590 if (!uentry_checkModifiesContext ())
1595 llassert (uentry_isValid (ue));
1597 if (uentry_isIter (ue))
1599 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1603 llassertfatal (uentry_isFunction (ue));
1604 llassert (ue->info->fcn->hasMods);
1606 checkGlobalsModifies (ue, sr);
1607 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1609 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1611 ue->info->fcn->hasGlobs = TRUE;
1615 if (sRefSet_hasStatic (ue->info->fcn->mods))
1617 context_recordFileModifies (ue->info->fcn->mods);
1621 bool uentry_hasWarning (uentry ue)
1623 return (uentry_isValid (ue)
1624 && warnClause_isDefined (ue->warn));
1627 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1629 llassert (uentry_isValid (ue));
1630 llassert (warnClause_isUndefined (ue->warn));
1635 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1637 if (sRef_modInFunction ())
1640 (message ("Precondition list not in function context. "
1641 "A precondition list can only appear following the parameter list "
1642 "in a function declaration or header."));
1644 /*@-mustfree@*/ return; /*@=mustfree@*/
1647 if (uentry_isValid (ue))
1649 uentry_convertVarFunction (ue);
1650 llassertfatal (uentry_isFunction (ue));
1652 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1654 /*drl oops this date is wronge...*/
1656 I changed this so it didn't appear as a Splint bug
1657 among other things this gets triggered when there is
1658 a function with two requires clauses. Now Splint
1659 prints an error and tries to conjoin the lists.
1662 (message ("Duplicate precondition list"
1663 "Attemping the conjoin the requires clauses"
1667 /* should conjoin constraints? */
1669 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1673 ue->info->fcn->preconditions = preconditions;
1678 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1687 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1689 if (sRef_modInFunction ())
1692 (message ("Postcondition list not in function context. "
1693 "A postcondition list can only appear following the parameter list "
1694 "in a function declaration or header."));
1696 /*@-mustfree@*/ return; /*@=mustfree@*/
1699 if (uentry_isValid (ue))
1701 uentry_convertVarFunction (ue);
1702 llassertfatal (uentry_isFunction (ue));
1704 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1706 ue->info->fcn->postconditions = postconditions;
1710 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1715 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1720 ** requires: new and old are functions
1724 checkGlobalsConformance (/*@notnull@*/ uentry old,
1725 /*@notnull@*/ uentry unew,
1726 bool mustConform, bool completeConform)
1728 bool hasInternalState = FALSE;
1730 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1732 if (globSet_isDefined (unew->info->fcn->globs))
1734 globSet_allElements (unew->info->fcn->globs, el)
1736 if (sRef_isFileStatic (el))
1738 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1740 if (sRef_isInvalid (sr))
1742 bool hasError = FALSE;
1744 if (!hasInternalState
1745 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1746 sRef_makeInternalState ()))
1747 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1748 sRef_makeSpecState ())))
1751 && !uentry_isStatic (old)
1754 message ("Globals list for %q includes internal state, %q, "
1755 "but %s without globals internalState.",
1756 uentry_getName (old),
1758 uentry_specOrDefName (old)),
1759 uentry_whereLast (unew)))
1761 uentry_showWhereSpecified (old);
1765 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1766 sRef_makeInternalState ());
1767 hasInternalState = TRUE;
1771 && fileloc_sameFile (uentry_whereDeclared (unew),
1772 uentry_whereDeclared (old)))
1777 message ("Function %q inconsistently %rdeclared (in "
1778 "same file) with file static global %q in "
1780 uentry_getName (unew),
1781 uentry_isDeclared (old),
1783 uentry_whereDeclared (unew)))
1785 uentry_showWhereSpecified (old);
1790 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1791 context_recordFileGlobals (old->info->fcn->globs);
1795 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1797 if (sRef_isInvalid (sr))
1802 message ("Function %q inconsistently %rdeclared with "
1803 "%q in globals list",
1804 uentry_getName (unew),
1805 uentry_isDeclared (old),
1807 uentry_whereDeclared (unew)))
1809 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1810 uentry_showWhereSpecified (old);
1815 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1821 ("Function %q global %q inconsistently "
1822 "%rdeclared as %qout global",
1823 uentry_getName (unew),
1825 uentry_isDeclared (old),
1826 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1827 uentry_whereDeclared (unew)))
1829 uentry_showWhereSpecified (old);
1834 } end_globSet_allElements ;
1836 if (completeConform)
1838 globSet_allElements (old->info->fcn->globs, el)
1840 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1842 if (sRef_isInvalid (sr))
1845 && uentry_isReallySpecified (old)
1848 message ("Function %q specified with %q in globals list, "
1849 "but declared without %q",
1850 uentry_getName (unew),
1853 uentry_whereDeclared (unew)))
1855 uentry_showWhereSpecified (old);
1858 } end_globSet_allElements;
1863 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1865 if (uentry_isReallySpecified (old)
1868 message ("%s %q specified with globals list, but "
1869 "declared with no globals",
1870 ekind_capName (unew->ukind),
1871 uentry_getName (unew)),
1872 uentry_whereDeclared (unew)))
1875 (message ("Specification globals: %q",
1876 globSet_unparse (old->info->fcn->globs)),
1877 uentry_whereSpecified (old));
1881 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1882 old->info->fcn->globs);
1887 ** new modifies list must be included by old modifies list.
1889 ** file static state may be added to new, if old has internal.
1893 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1894 bool mustConform, bool completeConform)
1897 bool changedMods = FALSE;
1898 bool modInternal = FALSE;
1900 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1902 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1903 newMods = unew->info->fcn->mods;
1905 if (sRefSet_isEmpty (newMods))
1907 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1908 && uentry_isReallySpecified (old))
1912 message ("%s %q specified with modifies clause, "
1913 "but declared with no modifies clause",
1914 ekind_capName (unew->ukind),
1915 uentry_getName (unew)),
1916 uentry_whereDeclared (unew)))
1918 llgenindentmsg (message ("Specification has modifies %q",
1919 sRefSet_unparse (old->info->fcn->mods)),
1920 uentry_whereSpecified (old));
1927 sRefSet_allElements (newMods, current)
1929 if (sRef_isValid (current))
1931 sRef rb = sRef_getRootBase (current);
1933 if (sRef_isFileStatic (rb))
1937 if (!sRefSet_isSameMember (old->info->fcn->mods,
1938 sRef_makeInternalState ())
1939 && !sRefSet_isSameMember (old->info->fcn->mods,
1940 sRef_makeSpecState ()))
1943 && !uentry_isStatic (old)
1947 ("Modifies list for %q includes internal state, "
1948 "but %s without modifies internal.",
1949 uentry_getName (old),
1950 uentry_specOrDefName (old)),
1951 uentry_whereLast (unew)))
1953 uentry_showWhereSpecified (old);
1956 old->info->fcn->mods =
1957 sRefSet_insert (old->info->fcn->mods,
1958 sRef_makeInternalState ());
1963 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1969 if (sRef_canModifyVal (current, old->info->fcn->mods))
1971 int size = sRefSet_size (old->info->fcn->mods);
1973 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1976 if (sRefSet_size (old->info->fcn->mods) != size)
1987 ("Modifies list for %q contains %q, not modifiable "
1989 uentry_getName (old),
1990 sRef_unparse (current),
1991 uentry_specDeclName (old)),
1992 uentry_whereLast (unew)))
1994 uentry_showWhereSpecified (old);
1999 } end_sRefSet_allElements;
2001 if (completeConform && uentry_isReallySpecified (old))
2003 sRefSet_allElements (old->info->fcn->mods, el)
2005 if (sRef_canModify (el, newMods))
2014 ("Specification modifies clause for %q contains %q, "
2015 "not included in declaration modifies clause",
2016 uentry_getName (old),
2018 uentry_whereLast (unew)))
2020 uentry_showWhereSpecified (old);
2023 } end_sRefSet_allElements ;
2027 ** Make sure file static elements will be removed.
2032 context_recordFileModifies (old->info->fcn->mods);
2037 uentry_checkMutableType (uentry ue)
2039 ctype ct = uentry_getType (ue);
2041 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2043 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2045 voptgenerror (FLG_MUTREP,
2046 message ("Mutable abstract type %q declared without pointer "
2047 "indirection: %t (violates assignment semantics)",
2048 uentry_getName (ue), ct),
2049 uentry_whereDeclared (ue));
2054 uentry_setMutable (uentry e)
2056 llassert (uentry_isDatatype (e));
2057 e->info->datatype->mut = YES;
2061 uentry_checkIterArgs (uentry ue)
2063 bool hasYield = FALSE;
2066 llassert (uentry_isIter (ue));
2068 args = uentry_getParams (ue);
2070 uentryList_elements (args, el)
2072 sstate ds = uentry_getDefState (el);
2074 if (uentry_isYield (el))
2079 if (sstate_isUnknown (ds))
2081 uentry_setDefState (el, SS_DEFINED);
2087 } end_uentryList_elements;
2091 voptgenerror (FLG_HASYIELD,
2092 message ("Iterator %q declared with no yield parameters",
2093 uentry_getName (ue)),
2094 uentry_whereDeclared (ue));
2099 chkind_fromQual (qual qel)
2101 if (qual_isChecked (qel))
2105 else if (qual_isCheckMod (qel))
2109 else if (qual_isCheckedStrict (qel))
2111 return CH_CHECKEDSTRICT;
2113 else if (qual_isUnchecked (qel))
2115 return CH_UNCHECKED;
2120 /*@notreached@*/ return CH_UNKNOWN;
2125 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2127 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2129 if (!uentry_isRefCounted (ue))
2132 (FLG_ANNOTATIONERROR,
2133 message ("Reference counting qualifier %s used on non-reference "
2134 "counted storage: %q",
2136 uentry_unparse (ue)),
2137 uentry_whereLast (ue));
2141 alkind ak = alkind_fromQual (qel);
2143 uentry_setAliasKind (ue, ak);
2146 else if (qual_isRefCounted (qel))
2148 ctype ct = ctype_realType (uentry_getType (ue));
2151 if (ctype_isPointer (ct)
2152 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2154 /* check there is a refs field */
2155 uentryList fields = ctype_getFields (rt);
2156 uentry refs = uentry_undefined;
2158 uentryList_elements (fields, field)
2160 if (uentry_isRefsField (field))
2162 if (uentry_isValid (refs))
2165 (FLG_ANNOTATIONERROR,
2166 message ("Reference counted structure type %s has "
2167 "multiple refs fields: %q and %q",
2169 uentry_getName (refs),
2170 uentry_getName (field)),
2171 uentry_whereLast (field));
2176 } end_uentryList_elements;
2178 if (uentry_isInvalid (refs))
2182 message ("Reference counted structure type %s has "
2184 ctype_unparse (ct)),
2186 ("To count reference, the structure must have a field named "
2187 "refs of type int."),
2190 else if (!ctype_isInt (uentry_getType (refs)))
2193 (FLG_ANNOTATIONERROR,
2194 message ("Reference counted structure type %s refs field has "
2195 "type %s (should be int)", ctype_unparse (ct),
2196 ctype_unparse (uentry_getType (refs))),
2197 uentry_whereLast (refs));
2201 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2202 uentry_whereDeclared (ue));
2207 if ((ctype_isPointer (ct)
2208 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2209 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2211 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2212 uentry_whereDeclared (ue));
2217 (FLG_ANNOTATIONERROR,
2218 message ("Non-pointer to structure type %s declared with "
2219 "refcounted qualifier",
2220 ctype_unparse (ct)),
2221 uentry_whereLast (ue));
2225 else if (qual_isRefs (qel))
2227 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2229 uentry_setAliasKind (ue, AK_REFS);
2234 (FLG_ANNOTATIONERROR,
2235 message ("Refs qualifier used on non-structure field: %q",
2236 uentry_unparse (ue)),
2237 uentry_whereLast (ue));
2240 else if (qual_isAliasQual (qel))
2242 alkind ak = alkind_fromQual (qel);
2244 alkind oldak = uentry_getAliasKind (ue);
2245 ctype ut = uentry_getType (ue);
2247 if (alkind_isImplicit (ak)
2248 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2250 /* ignore the implied qualifier */
2254 if (uentry_isEitherConstant (ue))
2257 (FLG_ANNOTATIONERROR,
2258 message ("Alias qualifier %s used on constant: %q",
2259 alkind_unparse (ak), uentry_unparse (ue)),
2260 uentry_whereLast (ue));
2265 if (ctype_isFunction (ut))
2267 ut = ctype_getReturnType (ut);
2270 if (!(ctype_isVisiblySharable (ut)
2271 || ctype_isRealArray (ut)
2272 || ctype_isRealSU (ut)))
2274 if (!qual_isImplied (qel))
2277 (FLG_ANNOTATIONERROR,
2278 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2279 alkind_unparse (ak), ut, uentry_getName (ue)),
2280 uentry_whereLast (ue));
2287 if (uentry_isRefCounted (ue))
2289 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2290 || qual_isExposed (qel)
2291 || qual_isObserver (qel)))
2293 if (!qual_isImplied (qel))
2296 (FLG_ANNOTATIONERROR,
2298 ("Alias qualifier %s used on reference counted storage: %q",
2299 alkind_unparse (ak),
2300 uentry_unparse (ue)),
2301 uentry_whereLast (ue));
2309 if (qual_isRefQual (qel))
2312 (FLG_ANNOTATIONERROR,
2313 message ("Qualifier %s used on non-reference counted storage: %q",
2314 alkind_unparse (ak), uentry_unparse (ue)),
2315 uentry_whereLast (ue));
2324 uentry_setAliasKind (ue, ak);
2327 else if (qual_isNull (qel))
2329 if (uentry_isConstant (ue))
2333 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2334 uentry_whereDeclared (ue));
2338 uentry_setNullState (ue, NS_POSNULL);
2341 else if (qual_isRelNull (qel))
2343 uentry_setNullState (ue, NS_RELNULL);
2345 else if (qual_isNotNull (qel))
2347 uentry_setNullState (ue, NS_MNOTNULL);
2349 else if (qual_isAbstract (qel)
2350 || qual_isNumAbstract (qel)
2351 || qual_isConcrete (qel))
2353 if (!uentry_isDatatype (ue))
2356 (FLG_ANNOTATIONERROR,
2357 message ("Qualifier %s used with non-datatype",
2358 qual_unparse (qel)),
2359 uentry_whereLast (ue));
2363 ue->info->datatype->abs = qel;
2364 DPRINTF (("Setting abstract %s: %s",
2365 uentry_unparse (ue), qual_unparse (qel)));
2368 else if (qual_isMutable (qel))
2370 if (!uentry_isDatatype (ue))
2373 (FLG_ANNOTATIONERROR,
2374 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2375 uentry_whereLast (ue));
2379 if (!ynm_isOn (ue->info->datatype->mut))
2381 uentry_checkMutableType (ue);
2384 ue->info->datatype->mut = YES;
2387 else if (qual_isImmutable (qel))
2389 if (!uentry_isDatatype (ue))
2391 voptgenerror (FLG_ANNOTATIONERROR,
2392 message ("Qualifier %s used with non-datatype",
2393 qual_unparse (qel)),
2394 uentry_whereLast (ue));
2398 ue->info->datatype->mut = NO;
2401 else if (qual_isNullPred (qel))
2403 uentry_convertVarFunction (ue);
2405 if (uentry_isFunction (ue))
2407 ctype typ = uentry_getType (ue);
2408 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2410 if (ctype_isRealBool (rtype))
2412 uentryList pl = ctype_argsFunction (typ);
2414 if (uentryList_size (pl) == 1)
2416 ue->info->fcn->nullPred = qel;
2420 voptgenerror (FLG_ANNOTATIONERROR,
2421 message ("Qualifier %s used with function having %d "
2422 "arguments (should have 1)",
2424 uentryList_size (pl)),
2425 uentry_whereLast (ue));
2430 voptgenerror (FLG_ANNOTATIONERROR,
2431 message ("Qualifier %s used with function returning %s "
2432 "(should return bool)",
2434 ctype_unparse (rtype)),
2435 uentry_whereLast (ue));
2440 voptgenerror (FLG_ANNOTATIONERROR,
2441 message ("Qualifier %s used with non-function",
2442 qual_unparse (qel)),
2443 uentry_whereLast (ue));
2446 else if (qual_isExitQual (qel))
2448 exitkind exk = exitkind_fromQual (qel);
2450 if (uentry_isFunction (ue))
2452 if (exitkind_isKnown (ue->info->fcn->exitCode))
2454 voptgenerror (FLG_ANNOTATIONERROR,
2455 message ("Multiple exit qualifiers used on function %q: %s, %s",
2456 uentry_getName (ue),
2457 exitkind_unparse (ue->info->fcn->exitCode),
2458 exitkind_unparse (exk)),
2459 uentry_whereLast (ue));
2462 ue->info->fcn->exitCode = exk;
2466 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2468 uentry_makeVarFunction (ue);
2469 ue->info->fcn->exitCode = exk;
2473 voptgenerror (FLG_ANNOTATIONERROR,
2474 message ("Exit qualifier %s used with non-function (type %s)",
2476 ctype_unparse (uentry_getType (ue))),
2477 uentry_whereLast (ue));
2481 else if (qual_isMetaState (qel))
2483 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2485 if (annotationInfo_matchesContext (ainfo, ue))
2487 DPRINTF (("Reflecting %s on %s",
2488 annotationInfo_unparse (ainfo),
2489 uentry_unparseFull (ue)));
2491 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2492 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2493 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2498 (FLG_ANNOTATIONERROR,
2499 message ("Attribute annotation %s used in inconsistent context: %q",
2501 uentry_unparse (ue)),
2502 uentry_whereLast (ue)))
2504 /*@i! annotationInfo_showContextError (ainfo, ue); */
2510 if (qual_isCQual (qel))
2516 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2522 uentry_reflectQualifiers (uentry ue, qualList q)
2524 llassert (uentry_isValid (ue));
2526 DPRINTF (("Reflect qualifiers: %s / %s",
2527 uentry_unparseFull (ue), qualList_unparse (q)));
2529 qualList_elements (q, qel)
2531 if (qual_isStatic (qel))
2533 uentry_setStatic (ue);
2535 else if (qual_isUnused (qel))
2537 uentry_setUsed (ue, fileloc_undefined);
2538 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2540 else if (qual_isExternal (qel))
2542 fileloc_free (ue->whereDefined);
2543 ue->whereDefined = fileloc_createExternal ();
2545 else if (qual_isSef (qel))
2547 if (uentry_isVariable (ue))
2549 vkind vk = ue->info->var->kind;
2551 llassert (vk != VKREFPARAM);
2553 if (vk == VKYIELDPARAM)
2556 (FLG_ANNOTATIONERROR,
2557 message ("Qualifier sef cannot be used with %s: %q",
2558 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2559 uentry_unparse (ue)),
2560 uentry_whereLast (ue));
2562 else if (vk == VKRETPARAM)
2564 ue->info->var->kind = VKSEFRETPARAM;
2568 ue->info->var->kind = VKSEFPARAM;
2574 (FLG_ANNOTATIONERROR,
2575 message ("Qualifier sef is meaningful only on parameters: %q",
2576 uentry_unparse (ue)),
2577 uentry_whereLast (ue));
2580 else if (qual_isExtern (qel))
2582 ue->storageclass = SCEXTERN;
2584 else if (qual_isGlobalQual (qel)) /* undef, killed */
2586 DPRINTF (("Reflecting qual: %s / %s",
2587 qual_unparse (qel), uentry_unparse (ue)));
2589 if (uentry_isVariable (ue))
2591 sstate oldstate = ue->info->var->defstate;
2592 sstate defstate = sstate_fromQual (qel);
2595 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2596 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2598 defstate = SS_UNDEFKILLED;
2605 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2606 ue->info->var->defstate = defstate;
2611 (FLG_ANNOTATIONERROR,
2612 message ("Qualifier %s used on non-variable: %q",
2613 qual_unparse (qel), uentry_unparse (ue)),
2614 uentry_whereLast (ue));
2617 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2619 /* start modifications */
2620 else if( qual_isBufQualifier(qel) ) {
2621 ctype ct = ctype_realType(uentry_getType(ue));
2622 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2624 if( uentry_hasBufStateInfo(ue) ) {
2625 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2627 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2628 /* If formal func param */
2629 uentry_setNullTerminatedState(ue);
2630 uentry_setLen (ue, 1);
2631 uentry_setSize (ue, 1);
2633 sRef_setNullTerminatedState(uentry_getSref(ue));
2634 sRef_setLen (uentry_getSref(ue), 1);
2635 sRef_setSize (uentry_getSref(ue), 1);
2637 uentry_setPossiblyNullTerminatedState(ue);
2639 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2643 /* put other BufState Qualifiers here */
2645 cstring s = uentry_getName(ue);
2646 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2647 struct for identifier %s\n", s) );
2649 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2651 sRef retSref = uentry_getSref (ue);
2652 ctype retType = sRef_getType (retSref);
2654 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2655 sRef_setNullTerminatedState (retSref);
2661 message ("Qualifier %s used on non-pointer on \
2662 function return: %q", qual_unparse (qel),
2663 uentry_unparse (ue)));
2670 message ("Qualifier %s used on non-pointer: %q",
2671 qual_unparse (qel), uentry_unparse (ue)));
2673 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2675 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2677 ctype realType = ctype_realType (ue->utype);
2678 sstate defstate = sstate_fromQual (qel);
2680 if (ctype_isFunction (realType))
2682 realType = ctype_realType (ctype_getReturnType (realType));
2685 if (qual_isRelDef (qel))
2687 ; /* okay anywhere */
2691 if (!ctype_isAP (realType)
2692 && !ctype_isSU (realType)
2693 && !ctype_isUnknown (realType)
2694 && !ctype_isAbstract (ue->utype))
2697 (FLG_ANNOTATIONERROR,
2698 message ("Qualifier %s used on non-pointer or struct: %q",
2699 qual_unparse (qel), uentry_unparse (ue)),
2700 uentry_whereLast (ue));
2704 uentry_setDefState (ue, defstate);
2706 if (sRef_isStateSpecial (ue->sref)
2707 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2709 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2712 else if (qual_isYield (qel))
2714 if (uentry_isVariable (ue))
2716 ue->info->var->kind = VKYIELDPARAM;
2721 (FLG_ANNOTATIONERROR,
2722 message ("Qualifier %s used on non-iterator parameter: %q",
2723 qual_unparse (qel), uentry_unparse (ue)),
2724 uentry_whereLast (ue));
2727 else if (qual_isExQual (qel))
2729 exkind ek = exkind_fromQual (qel);
2730 ctype ut = uentry_getType (ue);
2732 DPRINTF (("Reflect ex qual: %s / %s",
2733 uentry_unparse (ue), exkind_unparse (ek)));
2735 if (ctype_isFunction (ut))
2737 ut = ctype_getReturnType (ut);
2740 if (!(ctype_isVisiblySharable (ut))
2741 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2742 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2744 if (!qual_isImplied (qel))
2746 if (ctype_isImmutableAbstract (ut)) {
2748 (FLG_REDUNDANTSHAREQUAL,
2749 message ("Qualifier %s used on unsharable storage type %t: %q",
2750 exkind_unparse (ek), ut, uentry_getName (ue)),
2751 uentry_whereLast (ue));
2754 (FLG_MISPLACEDSHAREQUAL,
2755 message ("Qualifier %s used on unsharable storage type %t: %q",
2756 exkind_unparse (ek), ut, uentry_getName (ue)),
2757 uentry_whereLast (ue));
2763 alkind ak = sRef_getAliasKind (ue->sref);
2765 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2766 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2768 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2770 if (!alkind_isTemp (ak))
2772 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2773 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2776 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2777 || alkind_isOwned (ak))
2785 message ("Exposure qualifier %s used on %s storage (should "
2786 "be dependent): %q",
2788 alkind_unparse (ak),
2789 uentry_unparse (ue)));
2793 else if (qual_isGlobCheck (qel))
2795 if (uentry_isVariable (ue))
2797 chkind ch = chkind_fromQual (qel);
2799 if (ue->info->var->checked != CH_UNKNOWN)
2801 if (ch == ue->info->var->checked)
2803 llerror (FLG_SYNTAX,
2804 message ("Redundant %s qualifier on %q",
2806 uentry_getName (ue)));
2810 llerror (FLG_SYNTAX,
2812 ("Contradictory %s and %s qualifiers on %q",
2814 checkedName (ue->info->var->checked),
2815 uentry_getName (ue)));
2819 ue->info->var->checked = ch;
2825 message ("Qualifier %s used with non-variable",
2826 qual_unparse (qel)));
2829 else if (qual_isReturned (qel))
2831 if (uentry_isVariable (ue))
2833 ue->info->var->kind = VKRETPARAM;
2837 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2838 qual_unparse (qel)));
2843 uentry_reflectOtherQualifier (ue, qel);
2846 sRef_storeState (ue->sref);
2847 } end_qualList_elements;
2851 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2855 uentry_isOnly (uentry ue)
2857 return (!uentry_isUndefined (ue)
2858 && uentry_isVariable (ue)
2859 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2863 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2865 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2866 sRef_setOrigAliasKind (ue->sref, ak);
2870 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2872 if (uentry_isVariable (ue))
2874 ue->info->var->nullstate = ns;
2877 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2881 uentry_isUnique (uentry ue)
2883 return (!uentry_isUndefined (ue)
2884 && uentry_isVariable (ue)
2885 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2889 uentry_isFileStatic (uentry ue)
2891 return (uentry_isStatic (ue)
2892 && (!uentry_isVariable (ue)
2893 || sRef_isFileStatic (uentry_getSref (ue))));
2897 uentry_isExported (uentry ue)
2899 if (uentry_isValid (ue))
2901 if (uentry_isVariable (ue))
2903 return (sRef_isRealGlobal (uentry_getSref (ue)));
2907 return !uentry_isStatic (ue);
2915 uentry_isNonLocal (uentry ue)
2917 return (uentry_isValid (ue) && uentry_isVariable (ue)
2918 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2922 uentry_isGlobalVariable (uentry ue)
2924 return (uentry_isValid (ue) && uentry_isVariable (ue)
2925 && sRef_isFileOrGlobalScope (ue->sref));
2929 uentry_isVisibleExternally (uentry ue)
2931 return (uentry_isValid (ue)
2932 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2933 || (!uentry_isStatic (ue)
2934 && (uentry_isFunction (ue)
2935 || uentry_isIter (ue)
2936 || uentry_isEndIter (ue)
2937 || uentry_isConstant (ue)
2938 || uentry_isDatatype (ue)
2939 || uentry_isAnyTag (ue)))));
2943 uentry_isPrintfLike (uentry ue)
2945 return (uentry_isFunction (ue)
2946 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2950 uentry_isScanfLike (uentry ue)
2952 return (uentry_isFunction (ue)
2953 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2957 uentry_isMessageLike (uentry ue)
2959 return (uentry_isFunction (ue)
2960 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2963 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2965 uentryList args = uentry_getParams (ue);
2967 if (!uentryList_isMissingParams (args))
2969 uentry last = uentry_undefined;
2971 uentryList_elements (args, current)
2973 if (uentry_isElipsisMarker (current))
2975 if (uentry_isUndefined (last))
2979 message ("Function %q is marked %s, but has no format "
2980 "string argument before elipsis",
2981 uentry_getName (ue),
2982 specCode_unparse (ue->info->fcn->specialCode)),
2983 uentry_whereLast (ue));
2984 ue->info->fcn->specialCode = SPC_NONE;
2988 ctype rt = ctype_realType (uentry_getType (last));
2990 if (!ctype_match (rt, ctype_string))
2994 /* wchar_t * is okay too */
2995 if (ctype_isAP (rt))
2997 ctype base = ctype_baseArrayPtr (rt);
2999 if (ctype_isArbitraryIntegral (base))
3009 message ("Function %q is marked %s, but the argument "
3010 "before the elipsis has type %s (should be char *)",
3011 uentry_getName (ue),
3012 specCode_unparse (ue->info->fcn->specialCode),
3013 ctype_unparse (uentry_getType (last))),
3014 uentry_whereLast (ue));
3016 ue->info->fcn->specialCode = SPC_NONE;
3023 } end_uentryList_elements ;
3027 message ("Function %q is marked %s, but has no elipsis parameter",
3028 uentry_getName (ue),
3029 specCode_unparse (ue->info->fcn->specialCode)),
3030 uentry_whereLast (ue));
3032 ue->info->fcn->specialCode = SPC_NONE;
3037 uentry_setPrintfLike (uentry ue)
3039 uentry_convertVarFunction (ue);
3040 llassertfatal (uentry_isFunction (ue));
3041 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3042 checkSpecialFunction (ue);
3046 uentry_setScanfLike (uentry ue)
3048 uentry_convertVarFunction (ue);
3049 llassertfatal (uentry_isFunction (ue));
3050 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3051 checkSpecialFunction (ue);
3055 uentry_setMessageLike (uentry ue)
3057 uentry_convertVarFunction (ue);
3058 llassertfatal (uentry_isFunction (ue));
3059 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3060 checkSpecialFunction (ue);
3064 uentry_isSpecialFunction (uentry ue)
3066 return (uentry_isFunction (ue)
3067 && (ue->info->fcn->specialCode != SPC_NONE));
3070 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3072 ctype ct = idDecl_getCtype (t);
3074 fileloc loc = setLocation ();
3075 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc, SA_CREATED));
3076 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3078 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3079 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3080 uentry_implicitParamAnnots (ue);
3082 /* Parameter type [][] or [x][] is invalid */
3084 while (ctype_isFixedArray (base)) {
3085 base = ctype_baseArrayPtr (base);
3088 if (ctype_isIncompleteArray (base)) {
3089 base = ctype_baseArrayPtr (base);
3091 if (ctype_isArray (base)) {
3092 if (!uentry_hasName (ue)) {
3093 (void) optgenerror (FLG_INCOMPLETETYPE,
3094 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3096 ctype_unparse (ct)),
3097 uentry_whereLast (ue));
3099 (void) optgenerror (FLG_INCOMPLETETYPE,
3100 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3101 uentry_getName (ue),
3102 ctype_unparse (ct)),
3103 uentry_whereLast (ue));
3108 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3112 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3114 ctype ct = idDecl_getCtype (t);
3116 if (ctype_isFunction (ct))
3118 return (uentry_makeIdFunction (t));
3122 fileloc loc = setLocation ();
3123 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3125 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3127 if (!uentry_isExtern (ue))
3129 uentry_setDefined (ue, loc);
3136 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3138 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3145 static /*@only@*/ /*@notnull@*/
3146 uentry uentry_makeConstantAux (cstring n, ctype t,
3147 /*@keep@*/ fileloc f, bool priv, bool macro,
3148 /*@only@*/ multiVal m)
3150 uentry e = uentry_alloc ();
3153 e->uname = cstring_copy (n);
3155 e->storageclass = SCNONE;
3157 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3159 e->sref = sRef_makeConst (t);
3164 e->uses = filelocList_new ();
3165 e->isPrivate = priv;
3166 e->hasNameError = FALSE;
3168 e->info = (uinfo) dmalloc (sizeof (*e->info));
3169 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3170 e->info->uconst->access = typeIdSet_undefined;
3171 e->info->uconst->macro = macro;
3173 uentry_setSpecDef (e, f);
3175 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3177 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3180 uentry_setConstantValue (e, m);
3185 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3187 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3191 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3193 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3197 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3199 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3203 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3205 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3206 idDecl_getCtype (t),
3209 llassert (fileloc_isUndefined (ue->whereDeclared));
3210 ue->whereDeclared = setLocation ();
3211 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3213 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3214 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3222 void uentry_setDefState (uentry ue, sstate defstate)
3224 if (uentry_isValid (ue))
3226 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3228 if (uentry_isVariable (ue))
3230 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3235 bool uentry_isCheckedUnknown (uentry ue)
3237 return (uentry_isVar (ue)
3238 && (ue->info->var->checked == CH_UNKNOWN));
3241 bool uentry_isCheckMod (uentry ue)
3243 return (uentry_isVar (ue)
3244 && (ue->info->var->checked == CH_CHECKMOD));
3247 bool uentry_isUnchecked (uentry ue)
3249 return (uentry_isVar (ue)
3250 && (ue->info->var->checked == CH_UNCHECKED));
3253 bool uentry_isChecked (uentry ue)
3255 return (uentry_isVar (ue)
3256 && (ue->info->var->checked == CH_CHECKED));
3259 bool uentry_isCheckedModify (uentry ue)
3261 return (uentry_isVar (ue)
3262 && (ue->info->var->checked == CH_CHECKED
3263 || ue->info->var->checked == CH_CHECKMOD
3264 || ue->info->var->checked == CH_CHECKEDSTRICT));
3267 bool uentry_isCheckedStrict (uentry ue)
3269 return (uentry_isVar (ue)
3270 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3273 void uentry_setUnchecked (uentry ue)
3275 llassert (uentry_isVar (ue));
3277 ue->info->var->checked = CH_UNCHECKED;
3280 void uentry_setChecked (uentry ue)
3282 llassert (uentry_isVar (ue));
3284 ue->info->var->checked = CH_CHECKED;
3287 void uentry_setCheckMod (uentry ue)
3289 llassert (uentry_isVar (ue));
3291 ue->info->var->checked = CH_CHECKMOD;
3294 void uentry_setCheckedStrict (uentry ue)
3296 llassert (uentry_isVar (ue));
3298 ue->info->var->checked = CH_CHECKEDSTRICT;
3301 static /*@only@*/ /*@notnull@*/
3302 uentry uentry_makeVariableAux (cstring n, ctype t,
3304 /*@exposed@*/ sRef s,
3305 bool priv, vkind kind)
3307 uentry e = uentry_alloc ();
3310 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3313 e->uname = cstring_copy (n);
3316 e->storageclass = SCNONE;
3318 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3325 e->uses = filelocList_new ();
3326 e->isPrivate = priv;
3327 e->hasNameError = FALSE;
3329 e->info = (uinfo) dmalloc (sizeof (*e->info));
3330 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3331 e->info->var->kind = kind;
3333 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3334 e->info->var->checked = CH_UNKNOWN;
3336 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3337 uentry_setSpecDef (e, f);
3338 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3340 if (ctype_isFunction (rt))
3342 rt = ctype_getReturnType (rt);
3345 if (ctype_isUA (rt))
3347 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3348 sRef_setStateFromType (e->sref, rt);
3351 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3352 e->info->var->defstate = sRef_getDefState (e->sref);
3353 e->info->var->nullstate = sRef_getNullState (e->sref);
3355 /* start modifications */
3356 /* This function sets the uentry for a pointer or array variable declaration,
3357 it allocates memory and sets the fields. We check if the type of the variable
3358 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3360 if (ctype_isArray (t) || ctype_isPointer(t))
3362 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3363 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3364 sRef_setNotNullTerminatedState (s);
3368 e->info->var->bufinfo = NULL;
3370 /* end modification */
3376 uentry_isYield (uentry ue)
3378 return (uentry_isVariable (ue)
3379 && (ue->info->var->kind == VKYIELDPARAM
3380 || ue->info->var->kind == VKREFYIELDPARAM));
3384 uentry_isRefsField (uentry ue)
3386 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3389 /*@only@*/ /*@notnull@*/
3390 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3392 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3393 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3400 void uentry_makeVarFunction (uentry ue)
3407 llassert (uentry_isValid (ue));
3408 llassert (!sRef_modInFunction ());
3410 ak = sRef_getOrigAliasKind (ue->sref);
3411 ek = sRef_getOrigExKind (ue->sref);
3413 llassert (uentry_isVariable (ue));
3414 oldInfo = ue->info->var;
3416 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3417 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3420 ** expanded macro is marked used
3423 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3426 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3427 ue->info->fcn->exitCode = XK_UNKNOWN;
3428 ue->info->fcn->nullPred = qual_createUnknown ();
3429 ue->info->fcn->specialCode = SPC_NONE;
3430 ue->info->fcn->access = typeIdSet_undefined;
3431 ue->info->fcn->hasGlobs = FALSE;
3432 ue->info->fcn->globs = globSet_undefined;
3433 ue->info->fcn->hasMods = FALSE;
3434 ue->info->fcn->mods = sRefSet_undefined;
3435 ue->info->fcn->specclauses = NULL;
3436 ue->info->fcn->defparams = uentryList_undefined;
3439 ue->info->fcn->preconditions = functionConstraint_undefined;
3443 ue->info->fcn->postconditions = functionConstraint_undefined;
3446 if (ctype_isFunction (ue->utype))
3448 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3452 ue->sref = sRef_makeType (ctype_unknown);
3455 if (sRef_isRefCounted (ue->sref))
3461 if (alkind_isUnknown (ak))
3463 if (exkind_isKnown (ek))
3465 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3466 ak = AK_IMPDEPENDENT;
3470 if (context_getFlag (FLG_RETIMPONLY))
3472 if (ctype_isFunction (ue->utype)
3473 && ctype_isVisiblySharable
3474 (ctype_realType (ctype_getReturnType (ue->utype))))
3476 if (uentryList_hasReturned (uentry_getParams (ue)))
3482 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3497 loc = ue->whereDeclared;
3499 sRef_setAliasKind (ue->sref, ak, loc);
3500 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3501 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3502 sRef_setExKind (ue->sref, ek, loc);
3504 if (oldInfo->kind == VKEXPMACRO)
3510 fileloc_free (ue->whereDefined);
3511 ue->whereDefined = fileloc_undefined;
3514 uvinfo_free (oldInfo);
3517 void uentry_makeConstantFunction (uentry ue)
3524 llassert (uentry_isValid (ue));
3525 llassert (!sRef_modInFunction ());
3527 ak = sRef_getOrigAliasKind (ue->sref);
3528 ek = sRef_getOrigExKind (ue->sref);
3530 llassert (uentry_isConstant (ue));
3531 oldInfo = ue->info->uconst;
3533 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3536 ** expanded macro is marked used (until I write a pre-processor)
3540 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3541 ue->info->fcn->exitCode = XK_UNKNOWN;
3542 ue->info->fcn->nullPred = qual_createUnknown ();
3543 ue->info->fcn->specialCode = SPC_NONE;
3544 ue->info->fcn->access = typeIdSet_undefined;
3545 ue->info->fcn->hasGlobs = FALSE;
3546 ue->info->fcn->globs = globSet_undefined;
3547 ue->info->fcn->hasMods = FALSE;
3548 ue->info->fcn->mods = sRefSet_undefined;
3549 ue->info->fcn->specclauses = NULL;
3550 ue->info->fcn->defparams = uentryList_undefined;
3553 ue->info->fcn->preconditions = functionConstraint_undefined;
3557 ue->info->fcn->postconditions = functionConstraint_undefined;
3561 if (ctype_isFunction (ue->utype))
3563 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3567 ue->sref = sRef_makeType (ctype_unknown);
3570 if (sRef_isRefCounted (ue->sref))
3576 if (alkind_isUnknown (ak))
3578 if (exkind_isKnown (ek))
3580 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3581 ak = AK_IMPDEPENDENT;
3585 if (context_getFlag (FLG_RETIMPONLY))
3587 if (ctype_isFunction (ue->utype)
3588 && ctype_isVisiblySharable
3589 (ctype_realType (ctype_getReturnType (ue->utype))))
3591 if (uentryList_hasReturned (uentry_getParams (ue)))
3597 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3612 loc = ue->whereDeclared;
3614 sRef_setAliasKind (ue->sref, ak, loc);
3615 sRef_setExKind (ue->sref, ek, loc);
3617 fileloc_free (ue->whereDefined);
3618 ue->whereDefined = fileloc_undefined;
3619 ucinfo_free (oldInfo);
3623 uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
3625 llassert (uentry_isValid (ue));
3627 globSet_markImmutable (globs);
3629 if (uentry_isIter (ue))
3631 ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
3635 uentry_convertVarFunction (ue);
3636 llassert (uentry_isFunction (ue));
3638 ue->info->fcn->hasGlobs = TRUE;
3639 ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
3642 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3644 ue->info->fcn->hasMods = TRUE;
3648 void uentry_addAccessType (uentry ue, typeId tid)
3650 if (uentry_isFunction (ue))
3652 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3654 else if (uentry_isEitherConstant (ue))
3656 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3658 else if (uentry_isIter (ue))
3660 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3662 else if (uentry_isEndIter (ue))
3664 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3668 llbug (message ("no access for: %q", uentry_unparse (ue)));
3672 /*@only@*/ /*@notnull@*/ uentry
3673 uentry_makeFunction (cstring n, ctype t,
3675 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3676 /*@only@*/ warnClause warn,
3679 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3680 return (uentry_makeFunctionAux (n, t,
3681 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3682 : typeIdSet_single (access)),
3688 /*@notnull@*/ uentry
3689 uentry_makePrivFunction2 (cstring n, ctype t,
3691 globSet globs, sRefSet mods,
3694 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3699 /*@notnull@*/ uentry
3700 uentry_makeSpecFunction (cstring n, ctype t,
3702 /*@only@*/ globSet globs,
3703 /*@only@*/ sRefSet mods,
3706 uentry ue = uentry_makeFunctionAux (n, t, access,
3707 globs, mods, warnClause_undefined,
3710 uentry_setHasGlobs (ue);
3711 uentry_setHasMods (ue);
3713 reflectImplicitFunctionQualifiers (ue, TRUE);
3717 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3719 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3720 sRef_undefined, FALSE, VKEXPMACRO);
3722 uentry_setDefined (ue, f);
3726 /*@notnull@*/ /*@notnull@*/ uentry
3727 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3729 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3730 typeIdSet_singleOpt (access),
3731 globSet_undefined, sRefSet_undefined,
3732 warnClause_undefined,
3736 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3740 bool uentry_isForward (uentry e)
3742 if (uentry_isValid (e))
3744 ctype ct = uentry_getType (e);
3746 return (ctype_isUnknown (ct)
3747 || (ctype_isFunction (ct)
3748 && ctype_isUnknown (ctype_getReturnType (ct))));
3754 /*@notnull@*/ uentry
3755 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3757 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3758 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3762 /*@notnull@*/ uentry
3763 uentry_makeUnspecFunction (cstring n, ctype t,
3767 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3768 sRefSet_undefined, warnClause_undefined,
3771 reflectImplicitFunctionQualifiers (ue, TRUE);
3779 /* is exported for use by usymtab_interface */
3781 /*@notnull@*/ uentry
3782 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, qual abstract,
3783 fileloc f, bool priv)
3785 uentry e = uentry_alloc ();
3787 DPRINTF (("Make datatype: %s / %s",
3788 n, ctype_unparse (t)));
3790 /* e->shallowCopy = FALSE; */
3791 e->ukind = KDATATYPE;
3792 e->uname = cstring_copy (n);
3794 e->storageclass = SCNONE;
3795 e->sref = sRef_makeUnknown ();
3799 sRef_setStateFromType (e->sref, t);
3802 uentry_setSpecDef (e, f);
3804 e->warn = warnClause_undefined; /*@i634@*/
3805 e->uses = filelocList_new ();
3806 e->isPrivate = priv;
3807 e->hasNameError = FALSE;
3812 e->info = (uinfo) dmalloc (sizeof (*e->info));
3813 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3814 e->info->datatype->abs = abstract;
3815 e->info->datatype->mut = mut;
3816 e->info->datatype->type = ctype_undefined;
3818 if (uentry_isDeclared (e))
3820 uentry_setDefined (e, f);
3823 if (qual_isAbstract (abstract) && !(uentry_isCodeDefined (e)))
3825 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3831 /*@notnull@*/ uentry
3832 uentry_makeDatatype (cstring n, ctype t, ynm mut, qual abstract, fileloc f)
3834 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3837 /*@notnull@*/ uentry uentry_makeBoolDatatype (qual abstract)
3839 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3840 ctype_bool, NO, abstract,
3841 fileloc_getBuiltin (),
3844 ret->info->datatype->type = ctype_bool;
3852 static /*@only@*/ /*@notnull@*/ uentry
3853 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3854 /*@only@*/ fileloc f)
3856 uentry e = uentry_alloc ();
3859 e->uname = cstring_copy (n);
3861 e->sref = sRef_makeUnknown ();
3862 e->storageclass = SCNONE;
3866 uentry_setSpecDef (e, f);
3868 e->warn = warnClause_undefined; /*@i452@*/
3869 e->uses = filelocList_new ();
3870 e->isPrivate = FALSE;
3871 e->hasNameError = FALSE;
3873 e->info = (uinfo) dmalloc (sizeof (*e->info));
3874 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3875 e->info->iter->access = access;
3876 e->info->iter->mods = sRefSet_undefined;
3877 e->info->iter->globs = globSet_undefined;
3879 uentry_checkIterArgs (e);
3883 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3885 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3888 static /*@notnull@*/ uentry
3889 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3891 uentry e = uentry_alloc ();
3893 /* e->shallowCopy = FALSE; */
3894 e->ukind = KENDITER;
3895 e->storageclass = SCNONE;
3896 e->uname = message ("end_%s", n);
3897 e->utype = ctype_unknown;
3898 e->sref = sRef_makeUnknown ();
3900 uentry_setSpecDef (e, f);
3905 e->uses = filelocList_new ();
3906 e->isPrivate = FALSE;
3907 e->hasNameError = FALSE;
3909 e->info = (uinfo) dmalloc (sizeof (*e->info));
3910 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3912 e->info->enditer->access = access;
3914 e->warn = warnClause_undefined; /*@i452@*/
3918 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3920 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3927 static /*@only@*/ /*@notnull@*/ uentry
3928 uentry_makeTagAux (cstring n, ctype t,
3929 /*@only@*/ fileloc fl,
3930 bool priv, ekind kind)
3932 uentry e = uentry_alloc ();
3934 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3936 llbuglit ("uentry_makeTagAux: not a tag type");
3940 /* e->shallowCopy = FALSE; */
3941 e->uname = cstring_copy (n);
3944 e->sref = sRef_makeUnknown ();
3945 e->storageclass = SCNONE;
3947 uentry_setSpecDef (e, fl);
3952 e->uses = filelocList_new ();
3953 e->isPrivate = priv;
3954 e->hasNameError = FALSE;
3956 e->info = (uinfo) dmalloc (sizeof (*e->info));
3957 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3958 e->info->datatype->abs = qual_createUnknown ();
3959 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3960 e->info->datatype->type = t;
3961 e->warn = warnClause_undefined; /*@i452@*/
3963 if (uentry_isDeclared (e))
3965 uentry_setDefined (e, fl);
3971 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3973 cstring sname = makeStruct (n);
3974 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3976 cstring_free (sname);
3981 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3983 cstring sname = makeStruct (n);
3984 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3986 cstring_free (sname);
3991 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3993 cstring uname = makeUnion (n);
3994 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3996 cstring_free (uname);
4001 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
4003 cstring ename = makeEnum (n);
4004 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
4006 cstring_free (ename);
4011 uentry_makeUnionTagLoc (cstring n, ctype t)
4013 cstring uname = makeUnion (n);
4014 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4016 cstring_free (uname);
4021 uentry_makeEnumTagLoc (cstring n, ctype t)
4023 cstring ename = makeEnum (n);
4024 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4026 cstring_free (ename);
4031 uentry_isStructTag (uentry ue)
4033 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4037 uentry_isUnionTag (uentry ue)
4039 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4043 uentry_isEnumTag (uentry ue)
4045 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4049 uentry_isAnyTag (uentry ue)
4051 return (uentry_isStructTag (ue)
4052 || uentry_isUnionTag (ue)
4053 || uentry_isEnumTag (ue));
4056 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4058 extern void uentry_destroyMod (void)
4059 /*@globals killed emarker@*/ /*@modifies emarker@*/
4061 static bool wasDestroyed = FALSE;
4063 llassert (!wasDestroyed);
4065 if (emarker != NULL)
4067 uentry_reallyFree (emarker);
4070 wasDestroyed = TRUE;
4074 uentry_makeElipsisMarker (void)
4076 if (emarker == NULL)
4078 emarker = uentry_alloc ();
4080 emarker->ukind = KELIPSMARKER;
4081 emarker->uname = cstring_makeLiteral ("...");
4082 emarker->utype = ctype_elipsMarker;
4083 emarker->sref = sRef_undefined;
4084 emarker->storageclass = SCNONE;
4085 emarker->used = FALSE;
4086 emarker->lset = FALSE;
4087 emarker->info = NULL;
4089 uentry_setSpecDef (emarker, fileloc_undefined);
4090 emarker->uses = filelocList_new ();
4091 emarker->isPrivate = FALSE;
4092 emarker->hasNameError = FALSE;
4095 /*@ignore@*/ return (emarker); /*@end@*/
4103 uentry_equiv (uentry p1, uentry p2)
4105 if (uentry_compare (p1, p2) != 0)
4116 uentry_xcomparealpha (uentry *p1, uentry *p2)
4120 if ((res = uentry_compare (*p1, *p2)) == 0) {
4121 if ((*p1 != NULL) && (*p2 != NULL)) {
4122 res = cstring_compare ((*p1)->uname,
4131 uentry_xcompareuses (uentry *p1, uentry *p2)
4136 if (uentry_isValid (u1))
4138 if (uentry_isValid (u2))
4140 return (-1 * int_compare (filelocList_size (u1->uses),
4141 filelocList_size (u2->uses)));
4150 if (uentry_isValid (u2))
4162 uentry_compareStrict (uentry v1, uentry v2)
4164 COMPARERETURN (uentry_compare (v1, v2));
4166 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4168 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4169 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4170 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4177 uentry_compare (uentry u1, uentry u2)
4179 if (u1 == u2) return 0;
4181 if (uentry_isInvalid (u1)) return -1;
4182 if (uentry_isInvalid (u2)) return 1;
4184 INTCOMPARERETURN (u1->ukind, u2->ukind);
4185 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4186 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4187 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4193 /* bug detected by splint:
4194 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4199 return (multiVal_compare (uentry_getConstantValue (u1),
4200 uentry_getConstantValue (u2)));
4204 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4206 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4207 uentry_accessType (u2)));
4208 return (uentryList_compareParams (uentry_getParams (u1),
4209 uentry_getParams (u2)));
4211 return (typeIdSet_compare (uentry_accessType (u1),
4212 uentry_accessType (u2)));
4215 ** Functions are never equivalent
4218 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4228 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4229 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4230 sRef_getOrigAliasKind (u2->sref)));
4231 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4232 sRef_getOrigExKind (u2->sref)));
4233 COMPARERETURN (generic_compare (u1->info->var->checked,
4234 u2->info->var->checked));
4235 COMPARERETURN (generic_compare (u1->info->var->defstate,
4236 u2->info->var->defstate));
4237 return (generic_compare (u1->info->var->nullstate,
4238 u2->info->var->nullstate));
4240 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4241 u2->info->datatype->type));
4242 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4243 u2->info->datatype->mut));
4244 return (generic_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4253 ** all entries are: <type>[@<info>]*#<name>
4255 ** info depends on kind:
4259 advanceField (char **s)
4261 reader_checkChar (s, '@');
4265 advanceName (char **s)
4267 reader_checkChar (s, '#');
4271 vkind_fromInt (int i)
4273 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4275 llbuglit ("vkind_fromInt: out of range");
4282 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4283 typeIdSet access, nstate nullstate,
4284 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4286 uentry e = uentry_alloc ();
4291 e->sref = sRef_makeConst (ct);
4293 sRef_setNullState (e->sref, nullstate, loc);
4294 e->storageclass = SCNONE;
4296 if (fileloc_isSpec (loc))
4298 e->whereSpecified = loc;
4299 e->whereDeclared = fileloc_undefined;
4303 e->whereSpecified = fileloc_undefined;
4304 e->whereDeclared = loc;
4307 e->whereDefined = fileloc_undefined;
4308 e->uses = filelocList_new ();
4309 e->isPrivate = FALSE;
4310 e->hasNameError = FALSE;
4315 e->warn = warnClause_undefined; /*@i452@*/
4317 e->info = (uinfo) dmalloc (sizeof (*e->info));
4318 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4319 e->info->uconst->access = access;
4320 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4321 uentry_setConstantValue (e, m);
4322 sRef_storeState (e->sref);
4327 static /*@only@*/ uentry
4328 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4329 sstate defstate, nstate isnull, alkind aliased,
4330 exkind exp, chkind checked,
4331 /*@only@*/ fileloc loc)
4333 uentry e = uentry_alloc ();
4338 e->storageclass = SCNONE;
4340 e->sref = sRef_makeType (ct);
4341 sRef_setNullState (e->sref, isnull, loc);
4343 e->whereDefined = fileloc_undefined;
4345 if (fileloc_isSpec (loc))
4347 e->whereSpecified = loc;
4348 e->whereDeclared = fileloc_undefined;
4352 e->whereSpecified = fileloc_undefined;
4353 e->whereDeclared = loc;
4356 e->isPrivate = FALSE;
4357 e->hasNameError = FALSE;
4362 e->uses = filelocList_new ();
4363 e->warn = warnClause_undefined; /*@i452@*/
4365 e->info = (uinfo) dmalloc (sizeof (*e->info));
4366 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4367 e->info->var->kind = kind;
4368 e->info->var->checked = checked;
4369 e->info->var->defstate = defstate;
4371 sRef_setDefState (e->sref, defstate, loc);
4373 e->info->var->nullstate = sRef_getNullState (e->sref);
4375 sRef_setExKind (e->sref, exp, loc);
4376 sRef_setAliasKind (e->sref, aliased, loc);
4378 sRef_storeState (e->sref);
4380 /*DRL ADDED 9-1-2000 */
4381 e->info->var->bufinfo = NULL;
4386 static /*@only@*/ uentry
4387 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, qual abstract,
4388 ynm mut, ctype rtype, alkind ak, exkind exp,
4389 sstate defstate, nstate isnull,
4390 /*@only@*/ fileloc loc)
4392 uentry e = uentry_alloc ();
4394 e->ukind = KDATATYPE;
4395 /* e->shallowCopy = FALSE; */
4398 e->storageclass = SCNONE;
4399 e->sref = sRef_makeUnknown ();
4400 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4403 ** This is only setting null state. (I think?)
4406 if (ctype_isUA (ct))
4408 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4410 if (uentry_isValid (te))
4412 sRef_setStateFromUentry (e->sref, te);
4416 /* problem for recursive type definitions */
4420 sRef_setAliasKind (e->sref, ak, loc);
4421 sRef_setExKind (e->sref, exp, loc);
4423 sRef_setDefState (e->sref, defstate, loc);
4425 if (qual_isEitherAbstract (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4427 isnull = NS_ABSNULL;
4430 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4431 sRef_mergeNullState (e->sref, isnull);
4433 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4435 if (fileloc_isSpec (loc))
4437 e->whereSpecified = loc;
4438 e->whereDeclared = fileloc_undefined;
4442 e->whereSpecified = fileloc_undefined;
4443 e->whereDeclared = loc;
4446 e->isPrivate = FALSE;
4447 e->hasNameError = FALSE;
4449 e->warn = warnClause_undefined; /*@i452@*/
4453 e->uses = filelocList_new ();
4455 e->info = (uinfo) dmalloc (sizeof (*e->info));
4456 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4457 e->info->datatype->abs = abstract;
4458 e->info->datatype->mut = mut;
4459 e->info->datatype->type = rtype;
4461 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4462 sRef_storeState (e->sref);
4463 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4468 static void uentry_setHasGlobs (uentry ue)
4470 llassert (uentry_isFunction (ue));
4472 ue->info->fcn->hasGlobs = TRUE;
4475 static void uentry_setHasMods (uentry ue)
4477 llassert (uentry_isFunction (ue));
4479 ue->info->fcn->hasMods = TRUE;
4482 bool uentry_hasGlobs (uentry ue)
4484 if (uentry_isFunction (ue))
4486 return (ue->info->fcn->hasGlobs);
4492 bool uentry_hasStateClauseList (uentry ue)
4494 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4497 bool uentry_hasConditions (uentry ue)
4499 return (uentry_isFunction (ue)
4500 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4501 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4504 stateClauseList uentry_getStateClauseList (uentry ue)
4506 if (!uentry_isFunction (ue))
4508 llassert (uentry_isFunction (ue));
4509 return stateClauseList_undefined;
4512 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4513 return ue->info->fcn->specclauses;
4516 bool uentry_hasMods (uentry ue)
4518 if (uentry_isFunction (ue))
4520 return (ue->info->fcn->hasMods);
4527 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4529 bool hasGlobs, /*@only@*/ globSet globs,
4530 bool hasMods, /*@only@*/ sRefSet mods,
4531 alkind ak, exkind exp,
4532 sstate defstate, nstate isnull,
4536 /*@only@*/ stateClauseList specclauses,
4537 /*@only@*/ warnClause warnclause,
4538 /*@only@*/ fileloc loc)
4540 uentry e = uentry_alloc ();
4543 /* e->shallowCopy = FALSE; */
4547 e->storageclass = SCNONE;
4549 if (ctype_isFunction (ct))
4551 ret = ctype_getReturnType (ct);
4555 if (ctype_isKnown (ct))
4557 llbug (message ("not function: %s", ctype_unparse (ct)));
4560 ret = ctype_unknown;
4563 e->sref = sRef_makeType (ret);
4565 if (ctype_isUA (ret))
4567 sRef_setStateFromType (e->sref, ret);
4570 sRef_setDefined (e->sref, loc);
4571 sRef_setNullState (e->sref, isnull, loc);
4573 sRef_setAliasKind (e->sref, ak, loc);
4574 sRef_setExKind (e->sref, exp, loc);
4575 sRef_setDefState (e->sref, defstate, loc);
4577 e->whereSpecified = loc;
4578 e->whereDefined = fileloc_undefined;
4580 e->isPrivate = FALSE;
4581 e->hasNameError = FALSE;
4585 e->uses = filelocList_new ();
4586 e->warn = warnclause;
4588 e->info = (uinfo) dmalloc (sizeof (*e->info));
4589 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4591 e->info->fcn->exitCode = exitCode;
4592 e->info->fcn->specialCode = sCode;
4593 e->info->fcn->nullPred = nullPred;
4594 e->info->fcn->access = access;
4596 e->info->fcn->specclauses = specclauses;
4597 e->info->fcn->hasGlobs = hasGlobs;
4598 e->info->fcn->globs = globs;
4600 e->info->fcn->hasMods = hasMods;
4601 e->info->fcn->mods = mods;
4603 e->info->fcn->defparams = uentryList_undefined;
4604 e->whereDeclared = fileloc_undefined;
4606 sRef_storeState (e->sref);
4609 e->info->fcn->preconditions = NULL;
4613 e->info->fcn->postconditions = NULL;
4619 static /*@only@*/ uentry
4620 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4621 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4623 uentry e = uentry_alloc ();
4625 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4627 llbuglit ("uentry_makeTagBase: not a tag type");
4630 /* e->shallowCopy = FALSE; */
4634 e->sref = sRef_makeUnknown ();
4635 e->storageclass = SCNONE;
4637 if (fileloc_isSpec (loc))
4639 e->whereSpecified = loc;
4640 e->whereDeclared = fileloc_undefined;
4644 e->whereDeclared = loc;
4645 e->whereSpecified = fileloc_undefined;
4648 e->whereDefined = fileloc_undefined;
4650 e->isPrivate = FALSE;
4651 e->hasNameError = FALSE;
4655 e->uses = filelocList_new ();
4656 e->warn = warnClause_undefined; /*@i452@*/
4658 e->info = (uinfo) dmalloc (sizeof (*e->info));
4659 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4660 e->info->datatype->abs = qual_createUnknown ();
4661 e->info->datatype->mut = MAYBE;
4662 e->info->datatype->type = rtype;
4664 sRef_storeState (e->sref);
4670 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4671 ctype ct, /*@only@*/ fileloc loc)
4673 uentry e = uentry_alloc ();
4675 /* e->shallowCopy = FALSE; */
4679 e->sref = sRef_makeUnknown ();
4680 e->storageclass = SCNONE;
4682 if (fileloc_isSpec (loc))
4684 e->whereSpecified = loc;
4685 e->whereDeclared = fileloc_undefined;
4689 e->whereDeclared = loc;
4690 e->whereSpecified = fileloc_undefined;
4693 e->whereDefined = fileloc_undefined;
4695 e->isPrivate = FALSE;
4696 e->hasNameError = FALSE;
4700 e->uses = filelocList_new ();
4701 e->warn = warnClause_undefined; /*@i452@*/
4703 e->info = (uinfo) dmalloc (sizeof (*e->info));
4704 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4705 e->info->iter->access = access;
4706 e->info->iter->mods = sRefSet_undefined;
4707 e->info->iter->globs = globSet_undefined;
4709 sRef_storeState (e->sref);
4714 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4715 /*@only@*/ fileloc loc)
4717 uentry e = uentry_alloc ();
4719 /* e->shallowCopy = FALSE; */
4720 e->ukind = KENDITER;
4721 e->storageclass = SCNONE;
4723 e->utype = ctype_unknown;
4724 e->sref = sRef_makeUnknown ();
4726 if (fileloc_isSpec (loc))
4728 e->whereSpecified = loc;
4729 e->whereDeclared = fileloc_undefined;
4733 e->whereDeclared = loc;
4734 e->whereSpecified = fileloc_undefined;
4737 e->whereDefined = fileloc_undefined;
4739 e->isPrivate = FALSE;
4740 e->hasNameError = FALSE;
4744 e->uses = filelocList_new ();
4745 e->warn = warnClause_undefined; /*@i452@*/
4747 e->info = (uinfo) dmalloc (sizeof (*e->info));
4748 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4749 e->info->enditer->access = access;
4750 sRef_storeState (e->sref);
4755 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4763 uentry_undump (ekind kind, fileloc loc, char **s)
4767 DPRINTF (("Uentry undump: %s", *s));
4771 reader_checkChar (s, '!');
4772 reader_checkChar (s, '.');
4773 ue = uentry_makeElipsisMarker ();
4777 ctype ct = ctype_undump (s);
4791 reader_checkChar (s, '|');
4793 if (reader_optCheckChar (s, '@'))
4795 tkind = vkind_fromInt (reader_getInt (s));
4796 reader_checkChar (s, '|');
4803 if (reader_optCheckChar (s, '$'))
4805 defstate = SS_UNKNOWN;
4806 isnull = NS_UNKNOWN;
4807 aliased = AK_IMPTEMP;
4809 checked = CH_UNKNOWN;
4811 else if (reader_optCheckChar (s, '&'))
4813 defstate = SS_DEFINED;
4814 isnull = NS_UNKNOWN;
4815 aliased = AK_IMPTEMP;
4817 checked = CH_UNKNOWN;
4819 else if (reader_optCheckChar (s, '^'))
4821 defstate = SS_UNKNOWN;
4822 isnull = NS_UNKNOWN;
4823 aliased = AK_IMPTEMP;
4825 checked = CH_UNKNOWN;
4829 defstate = sstate_fromInt (reader_getInt (s));
4830 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4831 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4833 if (reader_optCheckChar (s, '&'))
4836 checked = CH_UNKNOWN;
4840 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4841 advanceField (s); checked = (chkind) (reader_getInt (s));
4846 name = reader_getStringWord (s);
4848 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4850 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4851 isnull, aliased, exp,
4852 checked, fileloc_copy (loc));
4865 advanceField (s); abstract = qual_abstractFromCodeChar (reader_loadChar (s));
4866 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4867 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4868 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4869 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4870 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4871 advanceField (s); rtype = ctype_undump (s);
4873 name = reader_getStringWord (s);
4874 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4875 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4876 aliased, exp, defstate, isnull,
4877 fileloc_copy (loc));
4894 stateClauseList specclauses = stateClauseList_undefined;
4895 warnClause warnclause = warnClause_undefined;
4897 if (reader_optCheckChar (s, '$'))
4899 defstate = SS_DEFINED;
4900 isnull = NS_UNKNOWN;
4901 exitCode = XK_UNKNOWN;
4903 nullPred = qual_createUnknown ();
4907 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4908 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4909 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4910 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4911 advanceField (s); nullPred = qual_undump (s);
4914 if (reader_optCheckChar (s, '$'))
4917 globs = globSet_undefined;
4919 mods = sRefSet_undefined;
4921 else if (reader_optCheckChar (s, '^'))
4924 globs = globSet_undefined;
4926 mods = sRefSet_undefined;
4930 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4931 advanceField (s); globs = globSet_undump (s);
4932 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4933 advanceField (s); mods = sRefSet_undump (s);
4936 if (reader_optCheckChar (s, '$'))
4943 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4944 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4947 advanceField (s); access = typeIdSet_undump (s);
4950 ** Optional clauses: Start with @<code>:
4953 while (reader_optCheckChar (s, '@'))
4955 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4957 reader_checkChar (s, ':');
4958 warnclause = warnClause_undump (s);
4960 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4962 reader_checkChar (s, ':');
4963 specclauses = stateClauseList_undump (s);
4971 advanceName (s); name = reader_getStringWord (s);
4973 ue = uentry_makeFunctionBase (name, ct, access,
4976 ak, exp, defstate, isnull,
4977 exitCode, specc, nullPred,
4980 fileloc_copy (loc));
4981 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4988 advanceField (s); access = typeIdSet_undump (s);
4989 advanceName (s); name = reader_getStringWord (s);
4991 ue = uentry_makeIterBase (name, access, ct,
4992 fileloc_copy (loc));
4999 advanceField (s); access = typeIdSet_undump (s);
5000 advanceName (s); name = reader_getStringWord (s);
5002 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5012 if (reader_optCheckChar (s, '$'))
5014 val = multiVal_undefined;
5015 access = typeIdSet_undefined;
5016 nullstate = NS_UNKNOWN;
5020 advanceField (s); val = multiVal_undump (s);
5021 advanceField (s); access = typeIdSet_undump (s);
5022 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5025 advanceName (s); name = reader_getStringWord (s);
5027 ue = uentry_makeConstantBase (name, ct, access,
5028 nullstate, fileloc_copy (loc), val);
5037 advanceField (s); rtype = ctype_undump (s);
5038 advanceName (s); name = reader_getStringWord (s);
5039 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5043 llcontbuglit ("uentry_undump: invalid");
5044 ue = uentry_undefined;
5047 llcontbuglit ("uentry_undump: elips marker");
5048 ue = uentry_undefined;
5057 uentry_dump (uentry v)
5059 return (uentry_dumpAux (v, FALSE));
5063 uentry_dumpParam (uentry v)
5065 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5066 ("dump: %s", uentry_unparseFull (v)));
5068 return (uentry_dumpAux (v, TRUE));
5072 uentry_dumpAux (uentry v, bool isParam)
5074 llassert (uentry_isValid (v));
5075 llassert (!uentry_isGlobalMarker (v));
5077 DPRINTF (("Dump uentry: [%p]", v));
5078 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5083 llcontbuglit ("uentry_dump: invalid entry");
5084 return cstring_undefined;
5086 return (message ("!."));
5090 vkind vk = v->info->var->kind;
5091 sstate dss = sRef_getDefState (v->sref);
5092 nstate nst = sRef_getNullState (v->sref);
5093 alkind alk = sRef_getAliasKind (v->sref);
5094 exkind exk = sRef_getExKind (v->sref);
5095 chkind chk = v->info->var->checked;
5097 DPRINTF (("Dumping var"));
5099 if (dss == SS_UNKNOWN
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_DEFINED
5108 && nst == NS_UNKNOWN
5109 && alk == AK_IMPTEMP
5110 && exk == XO_UNKNOWN
5111 && chk == CH_UNKNOWN)
5113 sdump = cstring_makeLiteral ("&");
5115 else if (dss == SS_UNKNOWN
5116 && nst == NS_UNKNOWN
5117 && alk == AK_UNKNOWN
5118 && exk == XO_UNKNOWN
5119 && chk == CH_UNKNOWN)
5121 sdump = cstring_makeLiteral ("^");
5123 else if (exk == XO_UNKNOWN
5124 && chk == CH_UNKNOWN)
5126 sdump = message ("%d@%d@%d&",
5133 sdump = message ("%d@%d@%d@%d@%d",
5144 return (message ("%q|@%d|%q#%s",
5145 ctype_dump (v->utype),
5148 isParam ? cstring_undefined : v->uname));
5152 return (message ("%q|%q#%s",
5153 ctype_dump (v->utype),
5155 isParam ? cstring_undefined : v->uname));
5161 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5163 exkind_unparse (sRef_getExKind (v->sref)),
5164 ctype_unparse (v->utype), (int) v->utype));
5167 return (message ("%q@%c@%s@%d@%d@%d@%d@%q#%s",
5168 ctype_dump (v->utype),
5169 qual_abstractCode (v->info->datatype->abs),
5170 ynm_unparseCode (v->info->datatype->mut),
5171 (int) sRef_getDefState (v->sref),
5172 (int) sRef_getNullState (v->sref),
5173 (int) sRef_getAliasKind (v->sref),
5174 (int) sRef_getExKind (v->sref),
5175 ctype_dump (v->info->datatype->type),
5179 cstring sdump, gdump, adump, xdump;
5180 alkind alk = sRef_getAliasKind (v->sref);
5181 exkind exk = sRef_getExKind (v->sref);
5183 if (sRef_getDefState (v->sref) == SS_DEFINED
5184 && !nstate_isKnown (sRef_getNullState (v->sref))
5185 && !exitkind_isKnown (v->info->fcn->exitCode)
5186 && v->info->fcn->specialCode == SPC_NONE
5187 && qual_isUnknown (v->info->fcn->nullPred))
5189 sdump = cstring_makeLiteral ("$");
5193 sdump = message ("@%d@%d@%d@%d@%x",
5194 (int) sRef_getDefState (v->sref),
5195 (int) sRef_getNullState (v->sref),
5196 (int) v->info->fcn->exitCode,
5197 (int) v->info->fcn->specialCode,
5198 qual_dump (v->info->fcn->nullPred));
5201 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5203 gdump = cstring_makeLiteral ("$");
5205 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5206 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5208 gdump = cstring_makeLiteral ("^");
5212 gdump = message ("@%s@%q@%s@%q",
5213 bool_dump (uentry_hasGlobs (v)),
5214 globSet_dump (uentry_getGlobs (v)),
5215 bool_dump (uentry_hasMods (v)),
5216 sRefSet_dump (uentry_getMods (v)));
5219 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5221 adump = cstring_makeLiteral ("$");
5225 adump = message ("@%d@%d", (int) alk, (int) exk);
5228 xdump = cstring_undefined;
5230 if (uentry_hasWarning (v))
5232 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5235 if (uentry_hasStateClauseList (v))
5237 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5240 return (message ("%q%q%q%q@%q%q#%s",
5241 ctype_dump (v->utype),
5245 typeIdSet_dump (uentry_accessType (v)),
5250 return (message ("%q@%q#%s",
5251 ctype_dump (v->utype),
5252 typeIdSet_dump (v->info->iter->access),
5255 return (message ("%q@%q#%s",
5256 ctype_dump (v->utype),
5257 typeIdSet_dump (uentry_accessType (v)),
5264 if (multiVal_isUnknown (uentry_getConstantValue (v))
5265 && typeIdSet_isEmpty (uentry_accessType (v))
5266 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5268 sdump = cstring_makeLiteral ("$");
5272 sdump = message ("@%q@%q@%d",
5273 multiVal_dump (uentry_getConstantValue (v)),
5274 typeIdSet_dump (uentry_accessType (v)),
5275 (int) sRef_getNullState (v->sref));
5278 return (message ("%q%q#%s",
5279 ctype_dump (v->utype),
5286 return (message ("%q@%q#%s",
5287 ctype_dump (v->utype),
5288 ctype_dump (v->info->datatype->type), v->uname));
5295 uentry_unparseAbbrev (uentry v)
5297 if (!uentry_isVariable (v))
5299 llcontbuglit ("uentry_unparseAbbrev: not variable");
5300 return uentry_unparse (v);
5303 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5307 uentry_unparse (uentry v)
5311 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5312 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5314 st = uentry_getName (v);
5316 if (cstring_isDefined (st))
5318 return (ctype_unparseDeclaration (v->utype, st));
5323 return (cstring_copy (ctype_unparse (v->utype)));
5328 uentry_unparseFull (uentry v)
5330 if (uentry_isUndefined (v))
5332 return (cstring_makeLiteral ("<undefined>"));
5338 res = message ("[%p] %s %s: %s [spec: %q; decl: %q; def: %q]",
5339 v, ekind_unparse (v->ukind), v->uname,
5340 ctype_unparse (v->utype),
5341 fileloc_unparse (uentry_whereSpecified (v)),
5342 fileloc_unparse (uentry_whereDeclared (v)),
5343 fileloc_unparse (uentry_whereDefined (v)));
5345 DPRINTF (("uentry: %s", res));
5347 if (uentry_isDatatype (v))
5349 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5352 (ctype_isDefined (v->info->datatype->type)
5353 ? v->info->datatype->type : ctype_unknown),
5354 ynm_unparse (v->info->datatype->mut),
5355 qual_unparse (v->info->datatype->abs),
5356 sRef_unparseState (v->sref));
5358 else if (uentry_isFunction (v))
5360 res = message ("%q / sref: %q / mods: %q / "
5361 "globs: %q / clauses: %q / pre: %q / post: %q",
5363 sRef_unparseFull (v->sref),
5364 sRefSet_unparse (v->info->fcn->mods),
5365 globSet_unparse (v->info->fcn->globs),
5366 stateClauseList_unparse (v->info->fcn->specclauses),
5367 functionConstraint_unparse (v->info->fcn->preconditions),
5368 functionConstraint_unparse (v->info->fcn->postconditions));
5370 else if (uentry_isIter (v))
5372 res = message ("%q / sref: %q",
5374 sRef_unparseFull (v->sref));
5376 else if (uentry_isVariable (v))
5378 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5380 sRef_unparseFull (v->sref),
5381 (int) v->info->var->kind,
5382 (int) v->info->var->defstate,
5383 (int) v->info->var->nullstate,
5385 DPRINTF (("sref: [%p]", v->sref));
5386 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5387 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5389 else if (uentry_isConstant (v))
5391 res = message ("%q = %q / %q",
5392 res, multiVal_unparse (uentry_getConstantValue (v)),
5393 sRef_unparseFull (v->sref));
5397 res = message ("%q :: %q", res, uentry_unparse (v));
5404 bool uentry_hasAccessType (uentry e)
5406 if (uentry_isValid (e))
5411 return (!typeIdSet_isEmpty (e->info->iter->access));
5413 return (!typeIdSet_isEmpty (e->info->enditer->access));
5415 return (!typeIdSet_isEmpty (e->info->fcn->access));
5418 return (!typeIdSet_isEmpty (e->info->uconst->access));
5427 typeIdSet uentry_accessType (uentry e)
5429 if (uentry_isValid (e))
5434 return (e->info->iter->access);
5436 return (e->info->enditer->access);
5438 return (e->info->fcn->access);
5441 return (e->info->uconst->access);
5447 return typeIdSet_undefined;
5451 uentry_isVariable (uentry e)
5453 return (uentry_isVar (e));
5457 uentry_isSpecified (uentry e)
5459 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5463 uentry_isReallySpecified (uentry e)
5465 return (uentry_isValid (e)
5466 && fileloc_isRealSpec (e->whereSpecified));
5470 uentry_isVar (uentry e)
5472 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5476 uentry_isFakeTag (uentry e)
5478 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5482 uentry_isDatatype (uentry e)
5484 return (!uentry_isUndefined (e) &&
5485 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5486 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5490 uentry_setAbstract (uentry e)
5494 llassert (uentry_isDatatype (e)
5495 && (qual_isUnknown (e->info->datatype->abs)));
5497 oldid = ctype_typeId (e->info->datatype->type);
5498 e->info->datatype->abs = qual_createAbstract ();
5499 e->info->datatype->type = ctype_createAbstract (oldid);
5503 uentry_setConcrete (uentry e)
5505 llassert (uentry_isDatatype (e)
5506 && (qual_isUnknown (e->info->datatype->abs)
5507 || qual_isConcrete (e->info->datatype->abs)));
5509 e->info->datatype->abs = qual_createConcrete ();
5513 uentry_isAbstractDatatype (uentry e)
5515 return (uentry_isDatatype (e)
5516 && (qual_isEitherAbstract (e->info->datatype->abs)));
5520 uentry_isMaybeAbstract (uentry e)
5522 return (uentry_isDatatype (e)
5523 && (!qual_isConcrete (e->info->datatype->abs)));
5527 uentry_isMutableDatatype (uentry e)
5529 bool res = uentry_isDatatype (e)
5530 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5536 uentry_isRefCountedDatatype (uentry e)
5538 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5542 uentry_isParam (uentry u)
5544 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5545 || u->info->var->kind == VKYIELDPARAM));
5549 uentry_isExpandedMacro (uentry u)
5551 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5555 uentry_isSefParam (uentry u)
5557 return (uentry_isVariable (u)
5558 && (u->info->var->kind == VKSEFPARAM
5559 || u->info->var->kind == VKREFSEFPARAM
5560 || u->info->var->kind == VKSEFRETPARAM
5561 || u->info->var->kind == VKREFSEFRETPARAM));
5565 uentry_isRefParam (uentry u)
5567 return (uentry_isVariable (u)
5568 && (u->info->var->kind == VKREFPARAM
5569 || u->info->var->kind == VKREFYIELDPARAM
5570 || u->info->var->kind == VKREFSEFPARAM
5571 || u->info->var->kind == VKREFSEFRETPARAM));
5575 uentry_isAnyParam (uentry u)
5577 return (uentry_isVariable (u)
5578 && ((u->info->var->kind == VKPARAM)
5579 || (u->info->var->kind == VKSEFPARAM)
5580 || (u->info->var->kind == VKYIELDPARAM)
5581 || (u->info->var->kind == VKRETPARAM)
5582 || (u->info->var->kind == VKSEFRETPARAM)));
5586 uentry_getDefState (uentry u)
5588 if (uentry_isValid (u))
5590 return (sRef_getDefState (u->sref));
5594 return (SS_UNKNOWN);
5599 uentry_isOut (uentry u)
5601 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5602 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5606 uentry_isPartial (uentry u)
5608 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5609 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5613 uentry_isStateSpecial (uentry u)
5615 return ((uentry_isVariable (u)
5616 && (u->info->var->defstate == SS_SPECIAL))
5617 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5620 exitkind uentry_getExitCode (uentry ue)
5622 if (uentry_isFunction (ue))
5624 return ue->info->fcn->exitCode;
5632 qual uentry_nullPred (uentry u)
5634 llassert (uentry_isRealFunction (u));
5636 if (uentry_isFunction (u))
5638 return (u->info->fcn->nullPred);
5642 return qual_createUnknown ();
5647 ** Note for variables, this is checking the declared state, not the current state.
5651 uentry_possiblyNull (uentry u)
5653 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5654 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5658 uentry_getAliasKind (uentry u)
5660 if (uentry_isValid (u))
5662 return (sRef_getAliasKind (uentry_getSref (u)));
5671 uentry_getExpKind (uentry u)
5673 if (uentry_isValid (u))
5675 return (sRef_getExKind (uentry_getSref (u)));
5684 uentry_isIter (uentry e)
5686 return (!uentry_isUndefined (e) && e->ukind == KITER);
5690 uentry_isEndIter (uentry e)
5692 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5696 uentry_isRealFunction (uentry e)
5698 return (uentry_isFunction (e) ||
5699 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5703 uentry_hasName (uentry e)
5705 if (uentry_isValid (e))
5707 cstring s = e->uname;
5709 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5710 || uentry_isFakeTag (e)));
5719 ** Returns true for fake tags.
5720 ** This is used for dumping the library
5723 bool uentry_hasRealName (uentry e)
5725 return (uentry_isValid (e)
5726 && cstring_isNonEmpty (e->uname)
5727 && !uentry_isGlobalMarker (e));
5731 /*@observer@*/ globSet
5732 uentry_getGlobs (uentry l)
5734 if (uentry_isInvalid (l))
5736 return globSet_undefined;
5739 if (uentry_isFunction (l))
5741 return l->info->fcn->globs;
5743 else if (uentry_isIter (l))
5745 return l->info->iter->globs;
5747 else if (uentry_isEndIter (l))
5749 return globSet_undefined;
5753 if (l->ukind == KVAR)
5755 llcontbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5757 ekind_unparse (l->ukind)));
5761 llcontbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5763 ekind_unparse (l->ukind)));
5766 return globSet_undefined;
5770 /*@observer@*/ sRefSet
5771 uentry_getMods (uentry l)
5773 llassert (uentry_isValid (l));
5775 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5777 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5778 return sRefSet_undefined;
5781 if (uentry_isFunction (l))
5783 return l->info->fcn->mods;
5785 else if (uentry_isIter (l))
5787 return l->info->iter->mods;
5789 else if (uentry_isEndIter (l))
5791 return sRefSet_undefined;
5798 /* Make Microsoft VC++ happy */
5799 # pragma warning (disable:4715)
5804 # pragma warning (enable:4715)
5808 uentry_getKind (uentry e)
5810 llassert (uentry_isValid (e));
5815 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5817 llassert (uentry_isEitherConstant (e));
5818 return (sRef_getValue (e->sref));
5821 /*@observer@*/ uentryList
5822 uentry_getParams (uentry l)
5824 if (uentry_isInvalid (l)) return uentryList_undefined;
5831 ctype ct = l->utype;
5833 if (ctype_isFunction (ct))
5835 return (ctype_argsFunction (ct));
5839 return uentryList_undefined;
5844 ctype ct = l->utype;
5846 /*drl 12/10/2002 changed to fix bug involving multiple redefines of library functions in macros. Bug was reported by Malcolm Parsons
5848 Old code was simplly llassert (ctype_isFunction (ct) );
5851 llassert (ctype_isFunction (ct) || context_inMacro() );
5853 return (ctype_argsFunction (ct));
5860 /*@observer@*/ cstring
5861 uentry_rawName (uentry e)
5863 if (uentry_isValid (e))
5869 return cstring_undefined;
5874 uentry_getOptName (uentry e)
5876 cstring s = uentry_getName (e);
5878 if (cstring_isDefined (s))
5880 s = cstring_appendChar (s, ' ');
5887 uentry_getName (uentry e)
5889 cstring ret = cstring_undefined;
5891 if (uentry_isValid (e))
5893 if (uentry_isAnyTag (e))
5895 ret = fixTagName (e->uname);
5897 else if (uentry_isAnyParam (e))
5899 ret = cstring_copy (fixParamName (e->uname));
5903 ret = cstring_copy (e->uname);
5910 cstring uentry_observeRealName (uentry e)
5912 cstring ret = cstring_undefined;
5914 if (uentry_isValid (e))
5916 if (uentry_isAnyTag (e))
5918 if (isFakeTag (e->uname))
5920 ret = cstring_undefined;
5924 ret = plainTagName (e->uname);
5927 else if (uentry_isAnyParam (e))
5929 ret = fixParamName (e->uname);
5940 cstring uentry_getRealName (uentry e)
5942 if (uentry_isValid (e))
5944 if (uentry_isAnyTag (e))
5946 return (cstring_undefined);
5953 return cstring_undefined;
5956 ctype uentry_getType (uentry e)
5958 if (uentry_isValid (e))
5964 return ctype_unknown;
5968 fileloc uentry_whereLast (uentry e)
5972 if (uentry_isInvalid (e))
5974 return fileloc_undefined;
5977 loc = e->whereDefined;
5979 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5984 loc = uentry_whereDeclared (e);
5986 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5991 loc = uentry_whereSpecified (e);
5995 fileloc uentry_whereEither (uentry e)
5997 if (uentry_isInvalid (e)) return fileloc_undefined;
5999 if (fileloc_isDefined (e->whereDefined)
6000 && !fileloc_isExternal (e->whereDefined))
6002 return e->whereDefined;
6004 else if (fileloc_isDefined (e->whereDeclared))
6006 return e->whereDeclared;
6010 return e->whereSpecified;
6014 fileloc uentry_whereSpecified (uentry e)
6016 if (uentry_isInvalid (e)) return fileloc_undefined;
6018 return (e->whereSpecified);
6021 fileloc uentry_whereDefined (uentry e)
6023 if (uentry_isInvalid (e)) return fileloc_undefined;
6025 return (e->whereDefined);
6028 fileloc uentry_whereDeclared (uentry e)
6030 if (uentry_isInvalid (e)) return fileloc_undefined;
6032 return (e->whereDeclared);
6035 /*@observer@*/ fileloc
6036 uentry_whereEarliest (uentry e)
6038 if (uentry_isInvalid (e)) return fileloc_undefined;
6040 if (fileloc_isDefined (e->whereSpecified))
6042 return (e->whereSpecified);
6044 else if (fileloc_isDefined (e->whereDeclared))
6046 return (e->whereDeclared);
6050 return e->whereDefined;
6055 uentry_setFunctionDefined (uentry e, fileloc loc)
6057 if (uentry_isValid (e))
6059 llassert (uentry_isFunction (e));
6061 if (fileloc_isUndefined (e->whereDeclared))
6063 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6066 if (!fileloc_isDefined (e->whereDefined))
6068 e->whereDefined = fileloc_update (e->whereDefined, loc);
6074 uentry_setDeclDef (uentry e, fileloc f)
6076 uentry_setDeclared (e, f);
6078 if (!uentry_isFunction (e)
6079 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6081 uentry_setDefined (e, f);
6086 uentry_setDeclaredForce (uentry e, fileloc f)
6088 llassert (uentry_isValid (e));
6089 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6093 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6095 llassert (uentry_isValid (e));
6096 fileloc_free (e->whereDeclared);
6097 e->whereDeclared = f;
6101 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6105 llassert (uentry_isValid (e));
6106 oldloc = e->whereDeclared;
6108 if (fileloc_isDefined (oldloc))
6110 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6112 e->whereDeclared = f;
6113 fileloc_free (oldloc);
6122 e->whereDeclared = f;
6123 fileloc_free (oldloc);
6128 uentry_setDeclared (uentry e, fileloc f)
6132 llassert (uentry_isValid (e));
6133 oldloc = e->whereDeclared;
6135 if (fileloc_isDefined (oldloc))
6137 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6139 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6148 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6153 uentry_clearDefined (uentry e)
6155 if (uentry_isValid (e))
6157 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6162 uentry_setDefined (uentry e, fileloc f)
6166 llassert (uentry_isValid (e));
6167 oldloc = e->whereDefined;
6169 if (fileloc_isDefined (oldloc))
6171 if (fileloc_isLib (oldloc)
6172 || fileloc_isImport (oldloc)
6173 || fileloc_isBuiltin (oldloc)
6174 || fileloc_isPreproc (oldloc))
6176 e->whereDefined = fileloc_update (e->whereDefined, f);
6180 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6186 if (optgenerror (FLG_REDEF,
6187 message ("%s %q redefined",
6188 ekind_capName (e->ukind),
6189 uentry_getName (e)),
6192 llgenindentmsg (message ("Previous definition of %q",
6193 uentry_getName (e)),
6201 e->whereDefined = fileloc_update (e->whereDefined, f);
6206 uentry_isCodeDefined (uentry e)
6208 llassert (uentry_isValid (e));
6210 return (fileloc_isDefined (e->whereDefined));
6214 uentry_isDeclared (uentry e)
6216 if (uentry_isValid (e))
6218 return (fileloc_isDefined (e->whereDeclared));
6224 sRef uentry_getSref (uentry e)
6226 /* not true, used for functions too (but shouldn't be? */
6227 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6229 if (uentry_isInvalid (e)) return sRef_undefined;
6234 sRef uentry_getOrigSref (uentry e)
6236 /*@i523*/ /* evans 2001-09-09 - need to fix this
6237 if (uentry_isValid (e))
6239 if (uentry_isVariable (e))
6241 return e->info->var->origsref;
6245 sRef sr = sRef_copy (uentry_getSref (e));
6247 sRef_resetState (sr);
6248 sRef_clearDerived (sr);
6254 return sRef_undefined;
6258 if (uentry_isValid (e))
6260 sRef sr = sRef_copy (uentry_getSref (e));
6262 sRef_resetState (sr);
6263 sRef_clearDerived (sr);
6265 if (uentry_isVariable (e))
6267 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6268 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6275 return sRef_undefined;
6280 ** requires: uentry e is not in a hashed symbol table
6284 uentry_setName (uentry e, /*@only@*/ cstring n)
6286 llassert (uentry_isValid (e));
6288 cstring_free (e->uname);
6293 uentry_setType (uentry e, ctype t)
6295 if (uentry_isValid (e))
6298 sRef_setType (e->sref, t);
6303 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6306 ctype rettype = ctype_unknown;
6308 llassert (uentry_isValid (ue));
6310 uentry_convertVarFunction (ue);
6311 llassert (uentry_isFunction (ue));
6313 rct = ctype_realType (ue->utype);
6315 if (ctype_isFunction (rct))
6317 rettype = ctype_getReturnType (rct);
6320 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6324 uentry_setRefParam (uentry e)
6326 if (!uentry_isVar (e))
6328 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6332 if (e->info->var->kind == VKSEFPARAM)
6334 e->info->var->kind = VKREFSEFPARAM;
6336 else if (e->info->var->kind == VKSEFRETPARAM)
6338 e->info->var->kind = VKREFSEFRETPARAM;
6340 else if (e->info->var->kind == VKYIELDPARAM)
6342 e->info->var->kind = VKREFYIELDPARAM;
6346 e->info->var->kind = VKREFPARAM;
6352 uentry_setParam (uentry e)
6354 if (!uentry_isVar (e))
6356 if (uentry_isElipsisMarker (e))
6362 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6369 if (e->info->var->kind == VKYIELDPARAM
6370 || e->info->var->kind == VKSEFPARAM
6371 || e->info->var->kind == VKSEFRETPARAM)
6377 e->info->var->kind = VKPARAM;
6381 e->uname = makeParam (e->uname);
6382 cstring_free (oldname);
6387 uentry_setSref (uentry e, sRef s)
6389 if (uentry_isValid (e))
6391 if (sRef_isValid (e->sref))
6393 sRef_mergeStateQuietReverse (e->sref, s);
6397 e->sref = sRef_saveCopy (s);
6403 uentry_getAbstractType (uentry e)
6405 llassert (uentry_isDatatype (e));
6408 ** This assertion removed.
6409 ** Okay to have undefined type, for system types
6411 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6412 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6417 if (ctype_isUndefined (e->info->datatype->type))
6419 return ctype_unknown;
6423 ** Sadly, a kludge...
6426 if (ctype_isUserBool (e->info->datatype->type)) {
6430 return e->info->datatype->type;
6433 ctype uentry_getRealType (uentry e)
6436 typeId uid = USYMIDINVALID;
6438 if (uentry_isInvalid (e))
6440 return ctype_unknown;
6443 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6445 if (uentry_isAnyTag (e))
6450 if (uentry_isAbstractType (e))
6452 ct = uentry_getAbstractType (e);
6454 if (ctype_isManifestBool (ct)) {
6458 llassert (ctype_isUA (ct));
6460 uid = ctype_typeId (ct);
6462 if (!context_hasAccess (uid))
6468 ct = uentry_getType (e);
6470 /* if (ctype_isUserBool (ct)) return ct; */
6472 if (ctype_isManifestBool (ct)) {
6476 if (ctype_isUA (ct))
6478 usymId iid = ctype_typeId (ct);
6480 if (usymId_equal (iid, uid))
6482 llcontbug (message ("uentry_getRealType: recursive type! %s",
6483 ctype_unparse (ct)));
6488 /* evs 2000-07-25: possible infinite recursion ? */
6489 uentry ue2 = usymtab_getTypeEntry (iid);
6493 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6494 return ctype_unknown;
6497 return uentry_getRealType (ue2);
6506 ctype uentry_getForceRealType (uentry e)
6509 typeId uid = USYMIDINVALID;
6511 if (uentry_isInvalid (e))
6513 return ctype_unknown;
6516 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6518 if (uentry_isAnyTag (e))
6523 if (uentry_isAbstractType (e))
6525 ct = uentry_getAbstractType (e);
6526 llassert (ctype_isUA (ct));
6528 uid = ctype_typeId (ct);
6529 /* no check for access! */
6532 ct = uentry_getType (e);
6534 /* evs 2000-07-25 */
6535 /* if (ctype_isUserBool (ct)) return ct; */
6537 if (ctype_isManifestBool (ct)) {
6541 if (ctype_isUA (ct))
6543 usymId iid = ctype_typeId (ct);
6545 if (usymId_equal (iid, uid))
6547 llcontbug (message ("uentry_getRealType: recursive type! %s",
6548 ctype_unparse (ct)));
6553 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6562 uentry uentry_nameCopy (cstring name, uentry e)
6564 uentry enew = uentry_alloc ();
6566 llassert (uentry_isValid (e));
6568 /* enew->shallowCopy = FALSE; */
6569 enew->ukind = e->ukind;
6571 enew->utype = e->utype;
6572 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6573 enew->whereDefined = fileloc_copy (e->whereDefined);
6574 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6575 enew->sref = sRef_copy (e->sref);
6576 enew->used = e->used;
6578 enew->isPrivate = e->isPrivate;
6579 enew->hasNameError = FALSE;
6581 enew->uses = filelocList_new ();
6582 enew->warn = warnClause_undefined;
6584 enew->storageclass = e->storageclass;
6585 enew->info = uinfo_copy (e->info, e->ukind);
6591 uentry_setDatatype (uentry e, usymId uid)
6593 llassert (uentry_isDatatype (e));
6595 if (uentry_isAbstractType (e))
6597 if (qual_isNumAbstract (e->info->datatype->abs))
6599 e->info->datatype->type = ctype_createNumAbstract (uid);
6603 llassert (qual_isAbstract (e->info->datatype->abs));
6604 e->info->datatype->type = ctype_createAbstract (uid);
6609 e->info->datatype->type = ctype_createUser (uid);
6614 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6615 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6618 llassert (uentry_isValid (e));
6620 if (fileloc_isSpec (f) || fileloc_isImport (f))
6622 e->whereSpecified = f;
6623 e->whereDeclared = fileloc_undefined;
6624 e->whereDefined = fileloc_undefined;
6628 e->whereSpecified = fileloc_undefined;
6629 e->whereDeclared = f;
6630 e->whereDefined = fileloc_undefined;
6633 llassert (fileloc_storable (f));
6637 ucinfo_free (/*@only@*/ ucinfo u)
6643 uvinfo_free (/*@only@*/ uvinfo u)
6645 /*drl7x added 6/29/01 */
6646 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6651 udinfo_free (/*@only@*/ udinfo u)
6657 ufinfo_free (/*@only@*/ ufinfo u)
6659 globSet_free (u->globs);
6660 sRefSet_free (u->mods);
6661 stateClauseList_free (u->specclauses);
6666 uiinfo_free (/*@only@*/ uiinfo u)
6672 ueinfo_free (/*@only@*/ ueinfo u)
6677 static /*@only@*/ ucinfo
6678 ucinfo_copy (ucinfo u)
6680 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6681 ret->access = u->access;
6682 ret->macro = u->macro;
6686 static /*@only@*/ uvinfo
6687 uvinfo_copy (uvinfo u)
6689 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6691 ret->kind = u->kind;
6692 ret->nullstate = u->nullstate;
6693 ret->defstate = u->defstate;
6694 ret->checked = u->checked;
6696 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6698 /* drl added 07-02-001 */
6699 /* copy null terminated information */
6701 if (u->bufinfo != NULL)
6703 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6704 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6705 ret->bufinfo->size = u->bufinfo->size;
6706 ret->bufinfo->len = u->bufinfo->len;
6711 ret->bufinfo = NULL;
6717 static /*@only@*/ udinfo
6718 udinfo_copy (udinfo u)
6720 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6724 ret->type = u->type;
6729 static /*@only@*/ ufinfo
6730 ufinfo_copy (ufinfo u)
6732 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6734 ret->hasGlobs = u->hasGlobs;
6735 ret->hasMods = u->hasMods;
6736 ret->exitCode = u->exitCode;
6737 ret->specialCode = u->specialCode;
6738 ret->nullPred = u->nullPred;
6739 ret->access = u->access;
6740 ret->globs = globSet_newCopy (u->globs);
6741 ret->mods = sRefSet_newCopy (u->mods);
6742 ret->defparams = u->defparams;
6743 ret->specclauses = stateClauseList_copy (u->specclauses);
6745 ret->preconditions = functionConstraint_copy (u->preconditions);
6746 ret->postconditions = functionConstraint_copy (u->postconditions);
6751 static /*@only@*/ uiinfo
6752 uiinfo_copy (uiinfo u)
6754 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6756 ret->access = u->access;
6757 ret->globs = globSet_newCopy (u->globs);
6758 ret->mods = sRefSet_newCopy (u->mods);
6763 static /*@only@*/ ueinfo
6764 ueinfo_copy (ueinfo u)
6766 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6768 ret->access = u->access;
6773 uinfo_free (uinfo u, ekind kind)
6778 case KCONST: ucinfo_free (u->uconst); break;
6779 case KVAR: uvinfo_free (u->var); break;
6783 case KDATATYPE: udinfo_free (u->datatype); break;
6784 case KFCN: ufinfo_free (u->fcn); break;
6785 case KITER: uiinfo_free (u->iter); break;
6786 case KENDITER: ueinfo_free (u->enditer); break;
6787 case KELIPSMARKER: break;
6788 case KINVALID: break;
6794 static /*@only@*/ /*@null@*/ uinfo
6795 uinfo_copy (uinfo u, ekind kind)
6797 if (kind == KELIPSMARKER || kind == KINVALID)
6803 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6808 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6809 case KVAR: ret->var = uvinfo_copy (u->var); break;
6813 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6814 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6815 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6816 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6824 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6826 filelocList_free (e->uses);
6827 cstring_free (e->uname);
6829 uinfo_free (e->info, e->ukind);
6831 fileloc_free (e->whereSpecified);
6832 fileloc_free (e->whereDefined);
6833 fileloc_free (e->whereDeclared);
6835 warnClause_free (e->warn);
6841 extern void uentry_markOwned (/*@owned@*/ uentry u)
6843 sfreeEventually (u);
6847 uentry_free (/*@only@*/ uentry e)
6849 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6851 uentry_reallyFree (e);
6856 ** For uentry's in the global or file scope
6860 uentry_freeComplete (/*@only@*/ uentry e)
6862 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6864 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6865 /*@i@*/ sRef_free (e->sref);
6866 e->sref = sRef_undefined;
6867 uentry_reallyFree (e);
6872 ** requires old->kind != new->kind, old->uname = new->uname
6876 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6878 llassert (uentry_isValid (old));
6879 llassert (uentry_isValid (unew));
6881 if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
6882 && (fileloc_isPreproc (uentry_whereDeclared (old))
6883 || ctype_isUnknown (old->utype))
6884 && !uentry_isSpecified (old))
6892 if (!uentry_isDeclared (old))
6894 if (uentry_isSpecified (old))
6896 if (uentry_isSpecified (unew))
6898 llbuglit ("Respecification!");
6900 else if (uentry_isDeclared (unew))
6904 message ("%s %q inconsistently declared as %s: %t",
6905 ekind_capName (old->ukind),
6906 uentry_getName (unew),
6907 ekind_unparseLong (unew->ukind),
6909 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6911 uentry_showWhereLastKind (old);
6923 message ("%s %q inconsistently declared as %s: %t",
6924 ekind_capName (old->ukind),
6925 uentry_getName (unew),
6926 ekind_unparseLong (unew->ukind),
6928 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6930 uentry_showWhereLastKind (old);
6936 llassert (uentry_isDeclared (unew));
6938 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6939 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6943 message ("%s %q inconsistently redeclared as %s",
6944 ekind_capName (old->ukind),
6945 uentry_getName (unew),
6946 ekind_unparseLong (unew->ukind)),
6947 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6949 uentry_showWhereLastKind (old);
6955 uentry_updateInto (old, unew);
6959 ** def is the definition of spec, modifies spec
6961 ** reports any inconsistencies
6962 ** returns the summary of all available information
6963 ** if spec and def are inconsistent, def is returned
6967 uentry_showWhereLast (uentry spec)
6969 if (uentry_isValid (spec))
6971 if (fileloc_isDefined (spec->whereDefined)
6972 && !fileloc_isLib (spec->whereDefined)
6973 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6975 llgenindentmsg (message ("Previous definition of %q: %t",
6976 uentry_getName (spec),
6977 uentry_getType (spec)),
6978 uentry_whereDefined (spec));
6980 else if (uentry_isDeclared (spec))
6982 llgenindentmsg (message ("Previous declaration of %q: %t",
6983 uentry_getName (spec),
6984 uentry_getType (spec)),
6985 uentry_whereDeclared (spec));
6987 else if (uentry_isSpecified (spec))
6989 if (uentry_hasName (spec))
6991 llgenindentmsg (message ("Specification of %q: %t",
6992 uentry_getName (spec),
6993 uentry_getType (spec)),
6994 uentry_whereSpecified (spec));
6998 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6999 uentry_whereSpecified (spec));
7004 /* nothing to show */
7010 uentry_showWhereLastKind (uentry spec)
7012 if (uentry_isValid (spec))
7014 if (fileloc_isDefined (spec->whereDefined)
7015 && !fileloc_isLib (spec->whereDefined)
7016 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
7018 llgenindentmsg (message ("Previous definition of %q as %s: %t",
7019 uentry_getName (spec),
7020 ekind_unparseLong (spec->ukind),
7021 uentry_getType (spec)),
7022 uentry_whereDefined (spec));
7024 else if (uentry_isDeclared (spec))
7026 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
7027 uentry_getName (spec),
7028 ekind_unparseLong (spec->ukind),
7029 uentry_getType (spec)),
7030 uentry_whereDeclared (spec));
7032 else if (uentry_isSpecified (spec))
7034 if (uentry_hasName (spec))
7036 llgenindentmsg (message ("Specification of %q as %s: %t",
7037 uentry_getName (spec),
7038 ekind_unparseLong (spec->ukind),
7039 uentry_getType (spec)),
7040 uentry_whereSpecified (spec));
7044 llgenindentmsg (message ("Specification as %s: %t",
7045 ekind_unparseLong (spec->ukind),
7046 uentry_getType (spec)),
7047 uentry_whereSpecified (spec));
7052 /* nothing to show */
7058 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7060 fileloc loc = uentry_whereDefined (ce);
7062 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7064 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7068 loc = uentry_whereSpecified (ce);
7070 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7072 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7077 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7079 if (uentry_isDeclared (spec))
7081 llgenindentmsg (message ("Previous declaration of %q: %q",
7082 uentry_getName (spec), extra),
7083 uentry_whereDeclared (spec));
7085 else if (uentry_isSpecified (spec))
7087 llgenindentmsg (message ("Specification of %q: %q",
7088 uentry_getName (spec), extra),
7089 uentry_whereSpecified (spec));
7093 cstring_free (extra);
7098 uentry_showWhereDeclared (uentry spec)
7100 if (uentry_isDeclared (spec))
7102 if (uentry_hasName (spec))
7104 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7105 uentry_whereDeclared (spec));
7109 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7112 else if (uentry_isSpecified (spec))
7114 if (uentry_hasName (spec))
7116 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7117 uentry_whereSpecified (spec));
7121 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7126 /* nothing to show */
7132 uentry_showWhereAny (uentry spec)
7134 if (uentry_isDeclared (spec))
7136 if (uentry_hasName (spec))
7138 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7139 uentry_whereDeclared (spec));
7143 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7146 else if (uentry_isSpecified (spec))
7148 if (uentry_hasName (spec))
7150 llgenindentmsg (message ("Specification of %q",
7151 uentry_getName (spec)),
7152 uentry_whereSpecified (spec));
7156 llgenindentmsg (cstring_makeLiteral ("Specification"),
7157 uentry_whereSpecified (spec));
7160 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7162 if (uentry_hasName (spec))
7164 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7165 uentry_whereDefined (spec));
7169 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7174 /* nothing to show */
7179 uentry_showWhereDefined (uentry spec)
7181 if (uentry_isCodeDefined (spec))
7183 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7184 uentry_whereDefined (spec));
7189 uentry_showWhereLastPlain (uentry spec)
7191 if (uentry_isDeclared (spec))
7193 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7194 uentry_whereDeclared (spec));
7196 else if (uentry_isSpecified (spec))
7198 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7199 uentry_whereSpecified (spec));
7207 uentry_showWhereLastVal (uentry spec, cstring val)
7209 if (uentry_isDeclared (spec))
7211 llgenindentmsg (message ("Previous declaration of %q: %s",
7212 uentry_getName (spec), val),
7213 uentry_whereDeclared (spec));
7215 else if (uentry_isSpecified (spec))
7217 llgenindentmsg (message ("Specification of %q: %s",
7218 uentry_getName (spec), val),
7219 uentry_whereSpecified (spec));
7227 uentry_showWhereSpecified (uentry spec)
7229 if (uentry_isSpecified (spec))
7231 if (uentry_hasName (spec))
7233 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7234 uentry_whereSpecified (spec));
7238 llgenindentmsg (cstring_makeLiteral ("Specification"),
7239 uentry_whereSpecified (spec));
7242 else if (uentry_isDeclared (spec))
7244 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7245 uentry_whereDeclared (spec));
7249 /* nothing to show */
7254 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7256 if (uentry_isSpecified (spec))
7258 if (uentry_hasName (spec))
7260 llgenindentmsg (message ("Specification of %q: %q",
7261 uentry_getName (spec), s),
7262 uentry_whereSpecified (spec));
7266 llgenindentmsg (message ("Specification: %q", s),
7267 uentry_whereSpecified (spec));
7270 else if (uentry_isDeclared (spec))
7272 llgenindentmsg (message ("Declaration of %q: %q",
7273 uentry_getName (spec), s),
7274 uentry_whereDeclared (spec));
7278 llgenindentmsg (message ("Previous: %q", s),
7279 uentry_whereLast (spec));
7288 checkStructConformance (uentry old, uentry unew)
7291 uentryList fold, fnew;
7294 ** requires: types of old and new are structs or unions
7297 llassert (uentry_isValid (old));
7298 llassert (uentry_isValid (unew));
7300 oldr = ctype_realType (old->utype);
7301 fold = ctype_getFields (oldr);
7303 newr = ctype_realType (unew->utype);
7304 fnew = ctype_getFields (newr);
7306 if (!uentryList_matchFields (fold, fnew))
7308 if (fileloc_equal (uentry_whereLast (old),
7309 uentry_whereLast (unew)))
7317 message ("%q %q %rdeclared with fields { %q }, %s "
7318 "with fields { %q }",
7319 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7320 uentry_getName (old),
7321 uentry_isDeclared (old),
7322 uentryList_unparseAbbrev (fnew),
7323 uentry_specOrDefName (old),
7324 uentryList_unparseAbbrev (fold)),
7325 uentry_whereDeclared (unew)))
7327 uentry_showWhereLastPlain (old);
7328 uentryList_showFieldDifference (fold, fnew);
7332 old->utype = unew->utype;
7337 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7340 ** requires old and new are enums
7343 ctype rold = ctype_realType (old->utype);
7344 ctype rnew = ctype_realType (unew->utype);
7345 enumNameList eold = ctype_elist (rold);
7346 enumNameList enew = ctype_elist (rnew);
7348 if (!enumNameList_match (eold, enew))
7352 message ("Enum %q declared with members { %q } but "
7353 "%s with members { %q }",
7354 uentry_getName (old),
7355 enumNameList_unparse (enew),
7356 uentry_specOrDefName (old),
7357 enumNameList_unparse (eold)),
7358 uentry_whereDeclared (unew)))
7360 uentry_showWhereSpecified (old);
7361 old->utype = unew->utype;
7367 ** either oldCurrent or newCurrent may be undefined!
7371 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7372 uentry unew, uentry newCurrent, ctype newType,
7375 bool hasError = FALSE;
7377 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7379 if (uentry_hasName (newCurrent))
7381 hasError = optgenerror
7383 message ("Parameter %d, %q, of function %q has inconsistent type: "
7384 "declared %t, %s %t",
7385 paramno + 1, uentry_getName (newCurrent),
7386 uentry_getName (unew),
7387 newType, uentry_specOrDefName (old), oldType),
7388 uentry_whereDeclared (newCurrent));
7392 hasError = optgenerror
7394 message ("Parameter %d of function %q has inconsistent type: "
7395 "declared %t, %s %t",
7396 paramno + 1, uentry_getName (unew),
7397 newType, uentry_specOrDefName (old), oldType),
7398 uentry_whereDeclared (newCurrent));
7400 DPRINTF (("type: %s / %s",
7401 ctype_unparse (newType),
7402 ctype_unparse (ctype_realType (newType))));
7407 if (uentry_isDeclared (unew))
7409 hasError = optgenerror
7411 message ("Parameter %d of function %s has inconsistent type: "
7412 "declared %t, %s %t",
7413 paramno + 1, unew->uname,
7414 newType, uentry_specOrDefName (old), oldType),
7415 uentry_whereDeclared (unew));
7419 hasError = optgenerror
7421 message ("Parameter %d of function %s has inconsistent type: "
7422 "declared %t, %s %t",
7423 paramno + 1, unew->uname,
7424 newType, uentry_specOrDefName (old), oldType),
7425 uentry_whereDeclared (unew));
7431 DPRINTF (("Here: %s / %s",
7432 uentry_unparseFull (oldCurrent),
7433 uentry_unparseFull (newCurrent)));
7435 if (!uentry_isUndefined (oldCurrent))
7437 if (!uentry_isUndefined (newCurrent)
7438 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7440 uentry_showWhereLast (oldCurrent);
7444 uentry_showWhereLastPlain (old);
7447 uentry_setType (oldCurrent, newType);
7451 uentry_showWhereLastPlain (old);
7457 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7461 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7463 uentry_isDeclared (old),
7464 uentryList_size (uentry_getParams (unew)),
7465 uentry_specOrDefName (old),
7466 uentryList_size (uentry_getParams (old))),
7467 uentry_whereDeclared (unew)))
7469 uentry_showWhereLastPlain (old);
7474 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7478 message ("Function %s inconsistently %rdeclared to return %t",
7480 uentry_isDeclared (old),
7481 ctype_getReturnType (unew->utype)),
7482 uentry_whereDeclared (unew)))
7484 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7488 static cstring paramStorageName (uentry ue)
7490 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7493 static cstring fcnErrName (uentry ue)
7495 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7498 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7500 if (uentry_isVar (ue))
7502 return (checkedName (ue->info->var->checked));
7506 return (cstring_makeLiteralTemp ("<checked invalid>"));
7510 static cstring checkedName (chkind checked)
7514 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7515 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7516 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7517 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7518 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7524 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7529 if (uentry_isVar (unew))
7531 llassert (uentry_isVar (old));
7533 oldState = old->info->var->nullstate;
7534 newState = unew->info->var->nullstate;
7538 oldState = sRef_getNullState (old->sref);
7539 newState = sRef_getNullState (unew->sref);
7542 if (oldState == NS_ABSNULL)
7544 if (uentry_isVar (old))
7546 old->info->var->nullstate = newState;
7549 sRef_mergeNullState (old->sref, newState);
7551 else if (newState == NS_UNKNOWN)
7553 if (completeConform && newState != oldState
7554 && uentry_isReallySpecified (old))
7558 message ("%s %q specified as %s, but declared without %s qualifier",
7559 ekind_capName (unew->ukind),
7560 uentry_getName (unew),
7561 nstate_unparse (oldState),
7562 nstate_unparse (oldState)),
7563 uentry_whereDeclared (unew)))
7565 uentry_showWhereSpecified (old);
7569 if (uentry_isVar (unew))
7571 unew->info->var->nullstate = oldState;
7574 sRef_mergeNullState (unew->sref, oldState);
7576 else if (newState == NS_POSNULL)
7578 if (oldState == NS_MNOTNULL
7579 && (ctype_isUA (unew->utype)
7580 || (uentry_isFunction (unew)
7581 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7583 if (uentry_isVar (unew))
7585 unew->info->var->nullstate = oldState;
7588 sRef_mergeNullState (unew->sref, oldState);
7592 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7593 || oldState == NS_UNKNOWN)
7600 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7602 uentry_ekindName (unew),
7603 uentry_getName (unew),
7604 uentry_isDeclared (old),
7606 uentry_specOrDefName (old),
7607 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7608 uentry_whereDeclared (unew)))
7610 uentry_showWhereSpecified (old);
7615 if (uentry_isVar (old))
7617 old->info->var->nullstate = newState;
7620 sRef_mergeNullState (old->sref, newState);
7623 else if (newState == NS_MNOTNULL)
7625 if (oldState != NS_MNOTNULL)
7631 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7632 "%s without notnull qualifier",
7633 uentry_ekindName (unew),
7634 uentry_getName (unew),
7635 uentry_isDeclared (old),
7637 uentry_specOrDefName (old)),
7638 uentry_whereDeclared (unew)))
7640 uentry_showWhereSpecified (old);
7644 if (uentry_isVar (old))
7646 old->info->var->nullstate = newState;
7649 sRef_mergeNullState (old->sref, newState);
7654 if (uentry_isVar (unew))
7656 unew->info->var->nullstate = oldState;
7659 sRef_mergeNullState (unew->sref, oldState);
7664 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7665 bool mustConform, bool completeConform)
7671 if (uentry_isVar (old) && uentry_isVar (unew))
7673 oldState = old->info->var->defstate;
7674 newState = unew->info->var->defstate;
7679 oldState = sRef_getDefState (old->sref);
7680 newState = sRef_getDefState (unew->sref);
7683 if (newState != oldState
7684 && newState != SS_UNKNOWN
7685 && newState != SS_DEFINED)
7691 message ("%s %q inconsistently %rdeclared %s %s %s, "
7693 uentry_ekindName (unew),
7694 uentry_getName (unew),
7695 uentry_isDeclared (old),
7697 sstate_unparse (newState),
7698 paramStorageName (unew),
7699 uentry_specOrDefName (old),
7701 sstate_unparse (oldState),
7702 paramStorageName (unew)),
7703 uentry_whereDeclared (unew)))
7705 uentry_showWhereSpecified (old);
7709 if (vars) old->info->var->defstate = newState;
7710 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7715 && (newState != oldState) && (oldState != SS_DEFINED)
7716 && uentry_isReallySpecified (old))
7720 message ("%s %q specified as %s, but declared without %s qualifier",
7721 ekind_capName (unew->ukind),
7722 uentry_getName (unew),
7723 sstate_unparse (oldState),
7724 sstate_unparse (oldState)),
7725 uentry_whereDeclared (unew)))
7727 uentry_showWhereSpecified (old);
7731 if (vars) unew->info->var->defstate = oldState;
7732 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7737 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7738 bool mustConform, bool completeConform)
7743 oldKind = sRef_getAliasKind (old->sref);
7744 newKind = sRef_getAliasKind (unew->sref);
7746 if (alkind_isImplicit (newKind)
7747 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7749 if (completeConform && !alkind_equal (newKind, oldKind)
7750 && uentry_isReallySpecified (old))
7754 message ("%s %q specified as %s, but declared without "
7755 "explicit alias qualifier",
7756 ekind_capName (unew->ukind),
7757 uentry_getName (unew),
7758 alkind_unparse (oldKind)),
7759 uentry_whereDeclared (unew)))
7761 uentry_showWhereSpecified (old);
7766 ** This really shouldn't be necessary, but it is!
7767 ** Function params (?) use new here.
7770 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7774 if (alkind_isKnown (newKind))
7776 if (!alkind_equal (oldKind, newKind))
7778 if (alkind_isKnown (oldKind))
7783 message ("%s %q inconsistently %rdeclared %s %s storage, "
7785 uentry_ekindName (unew),
7786 uentry_getName (unew),
7787 uentry_isDeclared (old),
7789 alkind_unparse (newKind),
7790 uentry_specOrDefName (old),
7791 alkind_unparse (oldKind)),
7792 uentry_whereDeclared (unew)))
7794 uentry_showWhereSpecified (old);
7796 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7797 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7798 sRef_setAliasKind (old->sref, AK_ERROR,
7799 uentry_whereDeclared (unew));
7803 sRef_setAliasKind (old->sref, newKind,
7804 uentry_whereDeclared (unew));
7809 if (!(alkind_isImplicit (newKind)))
7812 !uentry_isFunction (unew) &&
7815 message ("%s %q inconsistently %rdeclared %s %s storage, "
7816 "implicitly %s as temp storage",
7817 uentry_ekindName (unew),
7818 uentry_getName (unew),
7819 uentry_isDeclared (old),
7821 alkind_unparse (newKind),
7822 uentry_specOrDefName (old)),
7823 uentry_whereDeclared (unew)))
7825 uentry_showWhereSpecified (old);
7829 sRef_setAliasKind (old->sref, newKind,
7830 uentry_whereDeclared (unew));
7832 else /* newKind is temp or refcounted */
7839 else /* newKind unknown */
7846 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7847 bool mustConform, bool completeConform)
7852 oldKind = sRef_getExKind (old->sref);
7853 newKind = sRef_getExKind (unew->sref);
7855 if (exkind_isKnown (newKind))
7857 if (oldKind != newKind)
7859 if (exkind_isKnown (oldKind))
7864 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7865 uentry_ekindName (unew),
7866 uentry_getName (unew),
7867 uentry_isDeclared (old),
7869 exkind_unparse (newKind),
7870 uentry_specOrDefName (old),
7871 exkind_unparse (oldKind)),
7872 uentry_whereDeclared (unew)))
7874 uentry_showWhereSpecified (old);
7877 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7884 message ("%s %q inconsistently %rdeclared %s %s, "
7885 "implicitly %s without exposure qualifier",
7886 uentry_ekindName (unew),
7887 uentry_getName (unew),
7888 uentry_isDeclared (old),
7890 exkind_unparse (newKind),
7891 uentry_specOrDefName (old)),
7892 uentry_whereDeclared (unew)))
7894 uentry_showWhereSpecified (old);
7897 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7903 if (completeConform && exkind_isKnown (oldKind)
7904 && uentry_isReallySpecified (old))
7908 message ("%s %q specified as %s, but declared without "
7909 "exposure qualifier",
7910 ekind_capName (unew->ukind),
7911 uentry_getName (unew),
7912 exkind_unparse (oldKind)),
7913 uentry_whereDeclared (unew)))
7915 uentry_showWhereSpecified (old);
7919 /* yes, this is necessary! (if its a param) */
7920 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7925 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7926 bool mustConform, /*@unused@*/ bool completeConform)
7928 valueTable newvals = sRef_getValueTable (unew->sref);
7930 if (valueTable_isDefined (newvals))
7932 DPRINTF (("Check meta state: %s -> %s",
7933 uentry_unparseFull (old),
7934 uentry_unparseFull (unew)));
7936 DPRINTF (("Check meta state refs: %s -> %s",
7937 sRef_unparseFull (old->sref),
7938 sRef_unparseFull (unew->sref)));
7940 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7943 ** Copy the new values into the old ref
7946 valueTable_elements (newvals, key, newval)
7948 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7949 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7951 llassert (metaStateInfo_isDefined (msinfo));
7953 if (stateValue_isUndefined (oldval))
7955 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7959 if (stateValue_isError (oldval))
7961 if (!stateValue_isError (newval))
7963 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7967 ; /* No change necessary. */
7972 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7974 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7980 if (!stateValue_isError (newval)
7981 && !stateValue_isImplicit (newval))
7983 if (uentry_hasName (unew)
7984 || !sRef_isParam (uentry_getSref (unew)))
7989 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7990 uentry_ekindName (unew),
7991 uentry_getName (unew),
7992 uentry_isDeclared (old),
7994 stateValue_unparseValue (newval, msinfo),
7995 uentry_specOrDefName (old),
7996 stateValue_unparseValue (oldval, msinfo)),
7997 uentry_whereDeclared (unew)))
7999 uentry_showWhereSpecified (old);
8007 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
8008 uentry_ekindName (unew),
8009 sRef_getParam (uentry_getSref (unew)),
8010 uentry_isDeclared (old),
8012 stateValue_unparseValue (newval, msinfo),
8013 uentry_specOrDefName (old),
8014 stateValue_unparseValue (oldval, msinfo)),
8015 uentry_whereDeclared (unew)))
8017 uentry_showWhereSpecified (old);
8023 DPRINTF (("Updating!"));
8024 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8028 DPRINTF (("Values match"));
8032 } end_valueTable_elements ;
8037 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8038 /*@notnull@*/ uentry unew,
8039 bool mustConform, bool completeConform)
8041 checkDefState (old, unew, mustConform, completeConform);
8042 checkNullState (old, unew, mustConform, completeConform);
8043 checkAliasState (old, unew, mustConform, completeConform);
8044 checkExpState (old, unew, mustConform, completeConform);
8045 checkMetaState (old, unew, mustConform, completeConform);
8047 sRef_storeState (old->sref);
8048 sRef_storeState (unew->sref);
8052 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8054 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8059 llassert (uentry_isVar (old));
8060 llassert (uentry_isVar (unew));
8062 if (cstring_isEmpty (old->uname))
8064 cstring_free (old->uname);
8065 old->uname = cstring_copy (unew->uname);
8068 if (unew->info->var->kind == VKRETPARAM
8069 || unew->info->var->kind == VKSEFRETPARAM)
8071 if (old->info->var->kind != VKRETPARAM
8072 && old->info->var->kind != VKSEFRETPARAM)
8076 message ("Parameter %q inconsistently %rdeclared as "
8077 "returned parameter",
8078 uentry_getName (unew),
8079 uentry_isDeclared (old)),
8080 uentry_whereDeclared (unew)))
8082 uentry_showWhereSpecified (old);
8083 old->info->var->kind = unew->info->var->kind;
8089 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8091 if (old->info->var->kind != VKSEFPARAM
8092 && old->info->var->kind != VKSEFRETPARAM)
8096 message ("Parameter %qinconsistently %rdeclared as "
8098 uentry_getOptName (unew),
8099 uentry_isDeclared (old)),
8100 uentry_whereDeclared (unew)))
8102 uentry_showWhereSpecified (old);
8103 old->info->var->kind = unew->info->var->kind;
8108 if (old->info->var->kind == VKSPEC)
8110 old->info->var->kind = unew->info->var->kind;
8114 unew->info->var->kind = old->info->var->kind;
8117 if (unew->info->var->checked != CH_UNKNOWN
8118 && unew->info->var->checked != old->info->var->checked)
8120 if (old->info->var->checked == CH_UNKNOWN
8121 && !fileloc_isUser (uentry_whereLast (old)))
8129 message ("Variable %q inconsistently %rdeclared as "
8130 "%s parameter (was %s)",
8131 uentry_getName (unew),
8132 uentry_isDeclared (old),
8133 checkedName (unew->info->var->checked),
8134 checkedName (old->info->var->checked)),
8135 uentry_whereDeclared (unew)))
8137 uentry_showWhereSpecified (old);
8141 old->info->var->checked = unew->info->var->checked;
8146 && (old->info->var->checked != CH_UNKNOWN)
8147 && uentry_isReallySpecified (old))
8151 message ("%s %q specified as %s, but declared without %s qualifier",
8152 ekind_capName (unew->ukind),
8153 uentry_getName (unew),
8154 checkedName (old->info->var->checked),
8155 checkedName (old->info->var->checked)),
8156 uentry_whereDeclared (unew)))
8158 uentry_showWhereSpecified (old);
8162 unew->info->var->checked = old->info->var->checked;
8165 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8168 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8170 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8175 llassert (uentry_isVar (u1));
8176 llassert (uentry_isVar (u2));
8178 if (u1->info->var->kind != u2->info->var->kind) {
8179 if (u1->info->var->kind == VKSEFRETPARAM) {
8180 if (u2->info->var->kind == VKRETPARAM) {
8183 message ("Function types are inconsistent. Parameter %d is "
8184 "sef parameter, but non-sef parameter in "
8185 "assigned function: %s",
8186 paramno, exprNode_unparse (e)),
8188 } else if (u2->info->var->kind == VKSEFPARAM) {
8191 message ("Function types are inconsistent. Parameter %d is "
8192 "returns parameter, but non-returns parameter in "
8193 "assigned function: %s",
8194 paramno, exprNode_unparse (e)),
8199 message ("Function types are inconsistent. Parameter %d is "
8200 "sef returns parameter, but non-sef returns parameter in "
8201 "assigned function: %s",
8202 paramno, exprNode_unparse (e)),
8205 } else if (u1->info->var->kind == VKRETPARAM) {
8208 message ("Function types are inconsistent. Parameter %d is "
8209 "returns parameter, but non-returns parameter in "
8210 "assigned function: %s",
8211 paramno, exprNode_unparse (e)),
8213 } else if (u1->info->var->kind == VKSEFPARAM) {
8216 message ("Function types are inconsistent. Parameter %d is "
8217 "sef parameter, but non-sef parameter in "
8218 "assigned function: %s",
8219 paramno, exprNode_unparse (e)),
8222 if (u2->info->var->kind == VKSEFRETPARAM) {
8225 message ("Function types are inconsistent. Parameter %d is "
8226 "normal parameter, but sef returns parameter in "
8227 "assigned function: %s",
8228 paramno, exprNode_unparse (e)),
8230 } else if (u2->info->var->kind == VKSEFPARAM) {
8233 message ("Function types are inconsistent. Parameter %d is "
8234 "normal parameter, but sef parameter in "
8235 "assigned function: %s",
8236 paramno, exprNode_unparse (e)),
8238 } else if (u2->info->var->kind == VKRETPARAM) {
8241 message ("Function types are inconsistent. Parameter %d is "
8242 "normal parameter, but returns parameter in "
8243 "assigned function: %s",
8244 paramno, exprNode_unparse (e)),
8252 if (u1->info->var->defstate != u2->info->var->defstate)
8256 message ("Function types are inconsistent. Parameter %d is "
8257 "%s, but %s in assigned function: %s",
8259 sstate_unparse (u1->info->var->defstate),
8260 sstate_unparse (u2->info->var->defstate),
8261 exprNode_unparse (e)),
8265 if (u1->info->var->nullstate != u2->info->var->nullstate)
8269 message ("Function types are inconsistent. Parameter %d is "
8270 "%s, but %s in assigned function: %s",
8272 nstate_unparse (u1->info->var->nullstate),
8273 nstate_unparse (u2->info->var->nullstate),
8274 exprNode_unparse (e)),
8278 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8282 message ("Function types are inconsistent. Parameter %d is "
8283 "%s, but %s in assigned function: %s",
8285 alkind_unparse (sRef_getAliasKind (u1->sref)),
8286 alkind_unparse (sRef_getAliasKind (u2->sref)),
8287 exprNode_unparse (e)),
8291 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8295 message ("Function types are inconsistent. Parameter %d is "
8296 "%s, but %s in assigned function: %s",
8298 exkind_unparse (sRef_getExKind (u1->sref)),
8299 exkind_unparse (sRef_getExKind (u2->sref)),
8300 exprNode_unparse (e)),
8306 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8307 /*@notnull@*/ uentry unew,
8308 bool mustConform, /*@unused@*/ bool completeConform)
8310 uentryList oldParams = uentry_getParams (old);
8311 uentryList newParams = uentry_getParams (unew);
8312 ctype newType = unew->utype;
8313 ctype oldType = ctype_realType (old->utype);
8314 ctype oldRetType = ctype_unknown;
8315 ctype newRetType = ctype_unknown;
8317 DPRINTF (("Function conform: %s ==> %s",
8318 uentry_unparseFull (old),
8319 uentry_unparseFull (unew)));
8321 if (uentry_isForward (old))
8323 mustConform = FALSE;
8324 uentry_updateInto (old, unew);
8329 ** check return values
8332 if (ctype_isKnown (oldType))
8334 llassert (ctype_isFunction (oldType));
8335 oldRetType = ctype_getReturnType (oldType);
8338 if (ctype_isKnown (newType))
8340 llassert (ctype_isFunction (newType));
8341 newRetType = ctype_getReturnType (newType);
8344 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8345 && !ctype_matchDef (newRetType, oldRetType))
8347 if (mustConform) returnValueError (old, unew);
8351 if (ctype_isConj (newRetType))
8353 if (ctype_isConj (oldRetType))
8355 if (!ctype_sameAltTypes (newRetType, oldRetType))
8359 message ("Function %q inconsistently %rdeclared to "
8360 "return alternate types %s "
8361 "(types match, but alternates are not identical, "
8362 "so checking may not be correct)",
8363 uentry_getName (unew),
8364 uentry_isDeclared (old),
8365 ctype_unparse (newRetType)),
8366 uentry_whereDeclared (unew)))
8368 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8374 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8379 DPRINTF (("Before state: %s",
8380 uentry_unparseFull (old)));
8381 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8382 DPRINTF (("After state: %s",
8383 uentry_unparseFull (old)));
8385 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8387 if (exitkind_isKnown (unew->info->fcn->exitCode))
8391 message ("Function %q inconsistently %rdeclared using %s",
8392 uentry_getName (unew),
8393 uentry_isDeclared (old),
8394 exitkind_unparse (unew->info->fcn->exitCode)),
8395 uentry_whereDeclared (unew)))
8397 uentry_showWhereSpecified (old);
8402 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8406 if (!qual_isUnknown (unew->info->fcn->nullPred))
8408 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8412 message ("Function %q inconsistently %rdeclared using %s",
8413 uentry_getName (unew),
8414 uentry_isDeclared (old),
8415 qual_unparse (unew->info->fcn->nullPred)),
8416 uentry_whereDeclared (unew)))
8418 uentry_showWhereSpecified (old);
8424 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8427 if (unew->info->fcn->specialCode != SPC_NONE)
8429 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8433 message ("Function %q inconsistently %rdeclared using %s",
8434 uentry_getName (unew),
8435 uentry_isDeclared (old),
8436 specCode_unparse (unew->info->fcn->specialCode)),
8437 uentry_whereDeclared (unew)))
8439 uentry_showWhereSpecified (old);
8445 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8452 if (!uentryList_sameObject (oldParams, newParams)
8453 && (!uentryList_isMissingParams (oldParams)))
8455 if (!uentryList_isMissingParams (newParams))
8458 int nparams = uentryList_size (oldParams);
8459 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8461 if (nparams != uentryList_size (newParams))
8463 nargsError (old, unew);
8466 if (uentryList_size (newParams) < nparams)
8468 nparams = uentryList_size (newParams);
8471 while (paramno < nparams)
8473 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8474 uentry newCurrent = uentryList_getN (newParams, paramno);
8475 ctype oldCurrentType = uentry_getType (oldCurrent);
8476 ctype newCurrentType = uentry_getType (newCurrent);
8478 llassert (uentry_isValid (oldCurrent)
8479 && uentry_isValid (newCurrent));
8481 if (!uentry_isElipsisMarker (oldCurrent)
8482 && !uentry_isElipsisMarker (newCurrent))
8484 checkVarConformance (oldCurrent, newCurrent,
8485 mustConform, completeConform);
8490 if (uentry_hasName (oldCurrent)
8491 && uentry_hasName (newCurrent))
8493 cstring oldname = uentry_getName (oldCurrent);
8494 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8496 cstring nname = uentry_getName (newCurrent);
8499 if (cstring_isDefined (pfx)
8500 && cstring_equalPrefix (oldname, pfx))
8502 oname = cstring_suffix (oldname, cstring_length (pfx));
8507 /*@-branchstate@*/ } /*@=branchstate@*/
8509 if (cstring_isDefined (pfx)
8510 && cstring_equalPrefix (nname, pfx))
8512 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8517 /*@-branchstate@*/ } /*@=branchstate@*/
8519 if (!cstring_equal (oname, nnamefix))
8522 (FLG_DECLPARAMMATCH,
8523 message ("Definition parameter name %s does not match "
8524 "name of corresponding parameter in "
8527 uentry_whereLast (newCurrent)))
8529 uentry_showWhereLastPlain (oldCurrent);
8533 cstring_free (oldname);
8534 cstring_free (nname);
8538 if (!ctype_match (oldCurrentType, newCurrentType))
8540 paramTypeError (old, oldCurrent, oldCurrentType,
8541 unew, newCurrent, newCurrentType, paramno);
8545 if (ctype_isMissingParamsMarker (newCurrentType)
8546 || ctype_isElips (newCurrentType)
8547 || ctype_isMissingParamsMarker (oldCurrentType)
8548 || ctype_isElips (oldCurrentType))
8554 if (ctype_isConj (newCurrentType))
8556 if (ctype_isConj (oldCurrentType))
8558 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8562 message ("Parameter %q inconsistently %rdeclared with "
8563 "alternate types %s "
8564 "(types match, but alternates are not identical, "
8565 "so checking may not be correct)",
8566 uentry_getName (newCurrent),
8567 uentry_isDeclared (oldCurrent),
8568 ctype_unparse (newCurrentType)),
8569 uentry_whereDeclared (unew)))
8571 uentry_showWhereLastVal (oldCurrent,
8572 ctype_unparse (oldCurrentType));
8580 message ("Parameter %q inconsistently %rdeclared with "
8581 "alternate types %s",
8582 uentry_getName (newCurrent),
8583 uentry_isDeclared (oldCurrent),
8584 ctype_unparse (newCurrentType)),
8585 uentry_whereDeclared (unew)))
8587 uentry_showWhereLastVal (oldCurrent,
8588 ctype_unparse (oldCurrentType));
8595 if (ctype_isConj (oldCurrentType))
8597 uentry_setType (newCurrent, oldCurrentType);
8605 ** Forgot this! detected by splint:
8606 ** uentry.c:1257,15: Suspected infinite loop
8612 if (!uentryList_isMissingParams (newParams))
8614 if (ctype_isConj (oldRetType))
8616 old->utype = ctype_makeFunction (oldRetType,
8617 uentryList_copy (newParams));
8621 old->utype = unew->utype;
8625 checkGlobalsConformance (old, unew, mustConform, completeConform);
8626 checkModifiesConformance (old, unew, mustConform, completeConform);
8628 DPRINTF (("Before list: %s",
8629 uentry_unparseFull (old)));
8631 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8633 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8638 message ("Function %q redeclared using special clauses (can only "
8639 "be used in first declaration)",
8640 uentry_getName (unew)),
8641 uentry_whereDeclared (unew)))
8643 uentry_showWhereLast (old);
8647 /*@i23 need checking @*/
8649 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8653 /*@i43 should be able to append? @*/
8655 stateClauseList_checkEqual (old, unew);
8656 stateClauseList_free (unew->info->fcn->specclauses);
8657 unew->info->fcn->specclauses = stateClauseList_undefined;
8661 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8663 if (fileloc_isUndefined (old->whereDeclared))
8665 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8667 else if (fileloc_isUndefined (unew->whereDeclared))
8669 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8678 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8682 llassert (uentry_isValid (ue));
8683 llassert (uentry_isEitherConstant (ue));
8685 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8686 uval = uentry_getConstantValue (ue);
8688 if (multiVal_isDefined (uval))
8690 if (multiVal_isDefined (m))
8692 if (!multiVal_equiv (uval, m))
8696 message ("%s %q defined with inconsistent value: %q",
8697 ekind_capName (ue->ukind),
8698 uentry_getName (ue),
8699 multiVal_unparse (m)),
8702 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8710 uentry_setConstantValue (ue, m);
8715 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8718 bool typeError = FALSE;
8720 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8722 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8726 DPRINTF (("Check struct conformance: %s / %s",
8727 uentry_unparseFull (old),
8728 uentry_unparseFull (unew)));
8729 checkStructConformance (old, unew);
8734 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8736 llbug (message ("struct tags: bad types: %t / %t",
8737 old->utype, unew->utype));
8741 else if (uentry_isEnumTag (old))
8743 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8745 if (mustConform) checkEnumConformance (old, unew);
8749 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8751 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8752 ctype_unparse (unew->utype)));
8756 else if (!ctype_match (old->utype, unew->utype))
8758 DPRINTF (("Type mismatch: %s / %s",
8759 ctype_unparse (old->utype),
8760 ctype_unparse (unew->utype)));
8762 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8764 ctype realt = ctype_realType (unew->utype);
8766 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8768 unew->utype = ctype_bool;
8774 typeError = optgenerror
8776 message ("%q defined as %s", uentry_getName (old),
8777 ctype_unparse (realt)),
8778 uentry_whereDeclared (unew));
8786 ctype oldr = ctype_realType (old->utype);
8787 ctype newr = ctype_realType (unew->utype);
8789 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8791 checkStructConformance (old, unew);
8793 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8795 checkStructConformance (old, unew);
8797 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8799 checkEnumConformance (old, unew);
8801 else if (uentry_isConstant (old)
8802 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8804 /* okay...for now! (should check the type is reset later... */
8808 DPRINTF (("YABA!"));
8811 message ("%s %q %rdeclared with inconsistent type: %t",
8812 ekind_capName (unew->ukind),
8813 uentry_getName (unew),
8814 uentry_isDeclared (old),
8816 uentry_whereDeclared (unew)))
8818 uentry_showWhereLast (old);
8834 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8835 /*@notnull@*/ uentry unew,
8836 bool mustConform, bool completeConform)
8838 if (ctype_isDefined (unew->info->datatype->type))
8841 ** bool is hard coded here, since it is built into LCL.
8842 ** For now, we're stuck with LCL's types.
8845 if (ctype_isDirectBool (old->utype) &&
8846 cstring_equalLit (unew->uname, "bool"))
8848 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8849 evs 2000-07-25: removed
8851 unew->utype = ctype_bool;
8854 if (ctype_isUnknown (old->info->datatype->type))
8856 old->info->datatype->type = unew->info->datatype->type;
8860 DPRINTF (("Old: %s / New: %s",
8861 uentry_unparseFull (old),
8862 uentry_unparseFull (unew)));
8863 DPRINTF (("Types: %s / %s",
8864 ctype_unparse (old->info->datatype->type),
8865 ctype_unparse (unew->info->datatype->type)));
8867 if (ctype_matchDef (old->info->datatype->type,
8868 unew->info->datatype->type))
8877 ("Type %q %s with inconsistent type: %t",
8878 uentry_getName (unew),
8879 uentry_reDefDecl (old, unew),
8880 unew->info->datatype->type),
8881 uentry_whereDeclared (unew)))
8883 uentry_showWhereLastExtra
8884 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8887 old->info->datatype->type = unew->info->datatype->type;
8892 if (!qual_isUnknown (unew->info->datatype->abs))
8894 if (qual_isConcrete (old->info->datatype->abs)
8895 && qual_isEitherAbstract (unew->info->datatype->abs))
8897 if (!ctype_isDirectBool (old->utype))
8902 ("Datatype %q inconsistently %rdeclared as abstract type",
8903 uentry_getName (unew),
8904 uentry_isDeclared (old)),
8905 uentry_whereDeclared (unew)))
8907 uentry_showWhereLastPlain (old);
8911 else if (qual_isEitherAbstract (old->info->datatype->abs)
8912 && qual_isConcrete (unew->info->datatype->abs))
8914 if (!ctype_isDirectBool (old->utype))
8919 ("Datatype %q inconsistently %rdeclared as concrete type",
8920 uentry_getName (unew),
8921 uentry_isDeclared (old)),
8922 uentry_whereDeclared (unew)))
8924 uentry_showWhereLastPlain (old);
8935 if (qual_isEitherAbstract (old->info->datatype->abs))
8937 old->sref = unew->sref;
8938 unew->info->datatype->mut = old->info->datatype->mut;
8941 && uentry_isReallySpecified (old))
8946 ("Datatype %q specified as abstract, "
8947 "but abstract annotation not used in declaration",
8948 uentry_getName (unew)),
8949 uentry_whereDeclared (unew)))
8951 uentry_showWhereLastPlain (old);
8957 unew->info->datatype->abs = old->info->datatype->abs;
8959 if (ynm_isMaybe (unew->info->datatype->mut))
8961 if (completeConform && ynm_isOff (old->info->datatype->mut)
8962 && uentry_isReallySpecified (old))
8967 ("Datatype %q specified as immutable, "
8968 "but immutable annotation not used in declaration",
8969 uentry_getName (unew)),
8970 uentry_whereDeclared (unew)))
8972 uentry_showWhereLastPlain (old);
8976 unew->info->datatype->mut = old->info->datatype->mut;
8978 else if (ynm_isMaybe (old->info->datatype->mut))
8980 old->info->datatype->mut = unew->info->datatype->mut;
8984 if (qual_isEitherAbstract (old->info->datatype->abs))
8986 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8990 message ("Datatype %q inconsistently %rdeclared as immutable",
8991 uentry_getName (unew),
8992 uentry_isDeclared (old)),
8993 uentry_whereDeclared (unew)))
8995 uentry_showWhereLastPlain (old);
9000 if (ynm_isOff (old->info->datatype->mut)
9001 && ynm_isOn (unew->info->datatype->mut))
9005 message ("Datatype %q inconsistently %rdeclared as mutable",
9006 uentry_getName (unew),
9007 uentry_isDeclared (old)),
9008 uentry_whereDeclared (unew)))
9010 uentry_showWhereLastPlain (old);
9015 old->info->datatype->mut = unew->info->datatype->mut;
9018 uentry_checkStateConformance (old, unew, mustConform, completeConform);
9022 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
9023 /*@notnull@*/ uentry unew,
9025 /*@unused@*/ bool completeConform)
9027 multiVal oldval = uentry_getConstantValue (old);
9028 multiVal newval = uentry_getConstantValue (unew);
9030 if (multiVal_isDefined (oldval))
9032 if (multiVal_isDefined (newval))
9034 if (!multiVal_equiv (oldval, newval))
9039 message ("%s %q %rdeclared with inconsistent value: %q",
9040 ekind_capName (unew->ukind),
9041 uentry_getName (unew),
9042 uentry_isDeclared (old),
9043 multiVal_unparse (newval)),
9044 uentry_whereDeclared (unew)))
9046 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9050 uentry_setConstantValue (unew, multiVal_copy (oldval));
9059 uentry_setConstantValue (old, multiVal_copy (newval));
9064 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9065 /*@notnull@*/ uentry unew, bool mustConform,
9066 bool completeConform)
9068 bool typeError = FALSE;
9069 bool fcnConformance = FALSE;
9071 if (!ekind_equal (unew->ukind, old->ukind))
9074 ** okay, only if one is a function and the other is
9075 ** a variable of type function.
9078 if (unew->ukind == KENUMCONST
9079 && old->ukind == KCONST)
9081 old->ukind = KENUMCONST;
9085 if (unew->ukind == KFCN
9086 && old->ukind == KCONST
9087 && ctype_isUnknown (old->utype))
9090 ** When a function is defined with an unparam macro
9093 uentry_updateInto (old, unew);
9097 if (uentry_isExpandedMacro (old)
9098 && uentry_isEitherConstant (unew))
9100 uentry_updateInto (old, unew);
9104 if (uentry_isEndIter (unew))
9106 if (ctype_isUnknown (old->utype))
9108 if (!uentry_isSpecified (old)
9109 && uentry_isCodeDefined (unew))
9111 if (!fileloc_withinLines (uentry_whereDefined (old),
9112 uentry_whereDeclared (unew), 2))
9113 { /* bogus! will give errors if there is too much whitespace */
9117 ("Iterator finalized name %q does not match name in "
9118 "previous iter declaration (should be end_%q). This iter "
9119 "is declared at %q",
9120 uentry_getName (unew),
9121 uentry_getName (old),
9122 fileloc_unparse (uentry_whereDefined (old))),
9123 uentry_whereDeclared (old));
9127 uentry_updateInto (old, unew);
9132 KindConformanceError (old, unew, mustConform);
9136 if (uentry_isFunction (unew))
9138 if (uentry_isVariable (old))
9140 if (!ctype_isUnknown (old->utype))
9142 if (ctype_isFunction (old->utype))
9144 uentry_makeVarFunction (old);
9145 checkFunctionConformance (old, unew, mustConform,
9147 fcnConformance = TRUE;
9151 KindConformanceError (old, unew, mustConform);
9156 if (uentry_isExpandedMacro (old))
9158 if (fileloc_isUndefined (unew->whereDefined))
9160 unew->whereDefined = fileloc_update (unew->whereDefined,
9164 uentry_updateInto (old, unew);
9165 old->used = unew->used = TRUE;
9170 /* undeclared identifier */
9171 old->utype = unew->utype;
9172 uentry_makeVarFunction (old);
9173 checkFunctionConformance (old, unew, FALSE, FALSE);
9174 fcnConformance = TRUE;
9180 KindConformanceError (old, unew, mustConform);
9183 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9185 if (!ctype_isUnknown (unew->utype))
9187 if (ctype_isFunction (unew->utype))
9189 uentry_makeVarFunction (unew);
9190 checkFunctionConformance (old, unew, mustConform, completeConform);
9191 fcnConformance = TRUE;
9195 KindConformanceError (old, unew, mustConform);
9200 KindConformanceError (old, unew, mustConform);
9205 KindConformanceError (old, unew, mustConform);
9211 ** check parameter lists for functions
9212 ** (before type errors, to get better messages
9215 if (uentry_isFunction (old))
9217 checkFunctionConformance (old, unew, mustConform, completeConform);
9218 fcnConformance = TRUE;
9222 if (!ctype_isUndefined (old->utype))
9224 typeError = checkTypeConformance (old, unew, mustConform);
9231 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9233 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9236 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9238 DPRINTF (("Check datatype: %s / %s",
9239 uentry_unparseFull (old),
9240 uentry_unparseFull (unew)));
9242 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9245 if (uentry_isVariable (old) && uentry_isVariable (unew))
9248 !ctype_matchDef (old->utype, unew->utype))
9253 ("Variable %q %s with inconsistent type (arrays and pointers are "
9254 "not identical in variable declarations): %t",
9255 uentry_getName (unew),
9256 uentry_reDefDecl (old, unew),
9258 uentry_whereDeclared (unew)))
9260 uentry_showWhereLast (old);
9263 ** Avoid repeated errors.
9266 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9268 old->whereDefined = fileloc_update (old->whereDefined,
9276 checkVarConformance (old, unew, mustConform, completeConform);
9281 /* old->utype = unew->utype; */
9285 if (ctype_isConj (old->utype))
9287 if (ctype_isConj (unew->utype))
9289 if (!ctype_sameAltTypes (old->utype, unew->utype))
9293 message ("%s %q inconsistently %rdeclared with "
9294 "alternate types %s "
9295 "(types match, but alternates are not identical, "
9296 "so checking may not be correct)",
9297 ekind_capName (uentry_getKind (old)),
9298 uentry_getName (unew),
9299 uentry_isDeclared (old),
9300 ctype_unparse (unew->utype)),
9301 uentry_whereDeclared (unew)))
9303 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9307 old->utype = unew->utype;
9314 if (ctype_isUnknown (old->utype))
9316 old->utype = unew->utype;
9321 if (unew->ukind == old->ukind)
9324 unew->info = uinfo_copy (old->info, old->ukind);
9327 sRef_storeState (old->sref);
9328 sRef_storeState (unew->sref);
9331 static void uentry_mergeConstraints (uentry spec, uentry def)
9333 if (uentry_isFunction (def))
9335 DPRINTF (("Here: %s / %s",
9336 uentry_unparseFull (spec),
9337 uentry_unparseFull (def)));
9338 /* evans 2001-07-21 */
9339 llassert (uentry_isFunction (spec));
9341 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9343 if (fileloc_isXHFile (uentry_whereLast (def)))
9345 llassert (uentry_isFunction (spec));
9346 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9347 def->info->fcn->preconditions);
9349 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9355 /* Check if the constraints are identical */
9360 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9361 uentry_getName (spec),
9362 functionConstraint_unparse (spec->info->fcn->preconditions)),
9363 uentry_whereLast (def)))
9365 uentry_showWhereSpecified (spec);
9368 functionConstraint_free (spec->info->fcn->preconditions);
9369 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9372 def->info->fcn->preconditions = functionConstraint_undefined;
9375 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9377 if (fileloc_isXHFile (uentry_whereLast (def)))
9379 llassert (uentry_isFunction (spec));
9380 DPRINTF (("Post: %s /++/ %s",
9381 functionConstraint_unparse (spec->info->fcn->postconditions),
9382 functionConstraint_unparse (def->info->fcn->postconditions)));
9383 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9384 def->info->fcn->postconditions);
9385 def->info->fcn->postconditions = functionConstraint_undefined;
9386 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9393 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9394 uentry_getName (spec),
9395 functionConstraint_unparse (spec->info->fcn->postconditions)),
9396 uentry_whereLast (def)))
9398 uentry_showWhereSpecified (spec);
9401 functionConstraint_free (spec->info->fcn->postconditions);
9402 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9403 def->info->fcn->postconditions = functionConstraint_undefined;
9410 ** modifies spec to reflect def, reports any inconsistencies
9414 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9416 llassert (uentry_isValid (spec));
9417 llassert (uentry_isValid (def));
9418 llassert (cstring_equal (spec->uname, def->uname));
9420 if (uentry_isFunction (def))
9422 if (uentry_isConstant (spec))
9424 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9425 uentry_makeConstantFunction (spec);
9429 uentry_convertVarFunction (spec);
9432 llassert (uentry_isFunction (spec));
9435 DPRINTF (("Merge entries: %s / %s",
9436 uentry_unparseFull (spec),
9437 uentry_unparseFull (def)));
9439 uentry_mergeConstraints (spec, def);
9441 uentry_checkConformance (spec, def, TRUE,
9442 context_getFlag (FLG_NEEDSPEC));
9444 DPRINTF (("Merge entries after conform: %s / %s",
9445 uentry_unparseFull (spec),
9446 uentry_unparseFull (def)));
9448 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9451 ** okay, declarations conform. Propagate extra information.
9454 uentry_setDefined (spec, uentry_whereDefined (def));
9455 uentry_setDeclared (spec, uentry_whereDeclared (def));
9457 if (uentry_isStatic (def))
9461 message ("%s %q specified, but declared as static",
9462 ekind_capName (def->ukind),
9463 uentry_getName (def)),
9464 uentry_whereDeclared (def)))
9466 uentry_showWhereSpecified (spec);
9471 spec->storageclass = def->storageclass;
9474 sRef_storeState (spec->sref);
9476 spec->used = def->used || spec->used;
9477 spec->hasNameError |= def->hasNameError;
9481 if (!spec->hasNameError)
9483 uentry_checkName (spec);
9492 ** Can't generate function redeclaration errors when the
9493 ** entries are merged, since we don't yet know if its the
9494 ** definition of the function.
9498 uentry_clearDecl (void)
9500 posRedeclared = uentry_undefined;
9501 fileloc_free (posLoc);
9502 posLoc = fileloc_undefined;
9506 uentry_checkDecl (void)
9508 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9510 llassert (fileloc_isDefined (posLoc));
9512 if (uentry_isCodeDefined (posRedeclared))
9514 if (optgenerror (FLG_REDECL,
9515 message ("%s %q declared after definition",
9516 ekind_capName (posRedeclared->ukind),
9517 uentry_getName (posRedeclared)),
9520 llgenindentmsg (message ("Definition of %q",
9521 uentry_getName (posRedeclared)),
9522 posRedeclared->whereDeclared);
9527 if (optgenerror (FLG_REDECL,
9528 message ("%s %q declared more than once",
9529 ekind_capName (posRedeclared->ukind),
9530 uentry_getName (posRedeclared)),
9533 llgenindentmsg (message ("Previous declaration of %q",
9534 uentry_getName (posRedeclared)),
9535 posRedeclared->whereDeclared);
9540 fileloc_free (posLoc);
9541 posLoc = fileloc_undefined;
9542 posRedeclared = uentry_undefined;
9546 ** Redefinition of old as unew.
9547 ** modifies old to reflect unew, reports any inconsistencies
9551 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9553 fileloc olddef = uentry_whereDeclared (old);
9554 fileloc unewdef = uentry_whereDeclared (unew);
9558 DPRINTF (("uentry merge: %s / %s",
9559 uentry_unparseFull (old),
9560 uentry_unparseFull (unew)));
9563 fileloc_isUndefined (olddef)
9564 && fileloc_isDefined (uentry_whereDefined (old))
9565 && !uentry_isExpandedMacro (old);
9567 if (!context_getFlag (FLG_INCONDEFSLIB)
9568 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9570 mustConform = FALSE;
9577 llassert (uentry_isValid (old));
9578 llassert (uentry_isValid (unew));
9579 llassert (cstring_equal (old->uname, unew->uname));
9581 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9583 if (uentry_isConstant (old))
9585 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9586 uentry_makeConstantFunction (old);
9590 uentry_convertVarFunction (old);
9593 llassert (uentry_isFunction (old));
9596 DPRINTF (("uentry merge: %s / %s",
9597 uentry_unparseFull (old),
9598 uentry_unparseFull (unew)));
9600 if (uentry_isExtern (unew))
9602 uentry_setUsed (old, unewdef);
9606 ** should check old one was extern!
9609 if (uentry_isStatic (old))
9611 if (!(uentry_isStatic (unew)))
9615 message ("%s %q shadows static declaration",
9616 ekind_capName (unew->ukind),
9617 uentry_getName (unew)),
9620 uentry_showWhereLast (old);
9625 uentry_setDeclDef (old, unewdef);
9628 else if (uentry_isStatic (unew))
9630 uentry_setDeclDef (old, unewdef);
9632 else if (uentry_isExtern (old))
9634 uentry_setDeclared (old, unewdef);
9638 if (!uentry_isExtern (unew)
9639 && !uentry_isForward (old)
9640 && !fileloc_equal (olddef, unewdef)
9641 && !fileloc_isUndefined (olddef)
9642 && !fileloc_isUndefined (unewdef)
9643 && !fileloc_isBuiltin (olddef)
9644 && !fileloc_isBuiltin (unewdef)
9645 && !uentry_isYield (old)
9646 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9648 if (uentry_isVariable (old) || uentry_isVariable (unew))
9650 ; /* will report redeclaration error later */
9654 if (fileloc_isDefined (uentry_whereDefined (old)))
9658 message ("%s %q defined more than once",
9659 ekind_capName (unew->ukind),
9660 uentry_getName (unew)),
9661 uentry_whereLast (unew)))
9664 (message ("Previous definition of %q",
9665 uentry_getName (old)),
9666 uentry_whereLast (old));
9669 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9671 uentry_updateInto (old, unew);
9672 old->sref = sRef_saveCopy (old->sref);
9680 if (fileloc_isLib (olddef)
9681 || fileloc_isUndefined (olddef)
9682 || fileloc_isImport (olddef))
9684 if (uentry_isExtern (unew))
9686 if (uentry_isExtern (old)
9687 || (fileloc_isDefined (uentry_whereDeclared (old))
9688 && (!fileloc_equal (uentry_whereDeclared (old),
9689 uentry_whereDefined (old)))))
9693 message ("%s %q declared more than once",
9694 ekind_capName (unew->ukind),
9695 uentry_getName (unew)),
9696 unew->whereDeclared))
9699 (message ("Previous declaration of %q",
9700 uentry_getName (old)),
9701 old->whereDeclared);
9705 uentry_setExtern (old);
9709 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9715 DPRINTF (("uentry merge: %s / %s",
9716 uentry_unparseFull (old),
9717 uentry_unparseFull (unew)));
9719 uentry_mergeConstraints (old, unew);
9720 DPRINTF (("uentry merge: %s / %s",
9721 uentry_unparseFull (old),
9722 uentry_unparseFull (unew)));
9724 uentry_checkConformance (old, unew, mustConform, FALSE);
9725 DPRINTF (("uentry merge: %s / %s",
9726 uentry_unparseFull (old),
9727 uentry_unparseFull (unew)));
9729 old->used = old->used || unew->used;
9730 old->uses = filelocList_append (old->uses, unew->uses);
9731 unew->uses = filelocList_undefined;
9733 sRef_storeState (old->sref);
9734 sRef_storeState (unew->sref);
9738 old->whereDefined = fileloc_update (old->whereDefined,
9742 DPRINTF (("here: %s", uentry_unparseFull (old)));
9745 ** No redeclaration errors for functions here, since we
9746 ** don't know if this is the definition of the function.
9749 if (fileloc_isUser (old->whereDeclared)
9750 && fileloc_isUser (unew->whereDeclared)
9751 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9752 && !fileloc_isDefined (unew->whereDefined))
9754 if (uentry_isFunction (old))
9756 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9757 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9761 if (optgenerror (FLG_REDECL,
9762 message ("%s %q declared more than once",
9763 ekind_capName (unew->ukind),
9764 uentry_getName (unew)),
9765 unew->whereDeclared))
9767 llgenindentmsg (message ("Previous declaration of %q",
9768 uentry_getName (old)),
9769 old->whereDeclared);
9774 if (fileloc_isUndefined (old->whereDefined))
9776 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9780 if (!context_processingMacros ()
9781 && fileloc_isUser (old->whereDefined)
9782 && fileloc_isUser (unew->whereDefined)
9783 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9785 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9787 if (uentry_isVariable (unew)
9788 && uentry_isExtern (unew))
9790 if (optgenerror (FLG_REDECL,
9791 message ("%s %q declared after definition",
9792 ekind_capName (unew->ukind),
9793 uentry_getName (unew)),
9794 unew->whereDeclared))
9796 llgenindentmsg (message ("Definition of %q",
9797 uentry_getName (old)),
9803 if (optgenerror (FLG_REDEF,
9804 message ("%s %q redefined",
9805 ekind_capName (unew->ukind),
9806 uentry_getName (unew)),
9807 unew->whereDefined))
9809 llgenindentmsg (message ("Previous definition of %q",
9810 uentry_getName (old)),
9818 if (uentry_isExternal (unew))
9820 old->whereDefined = fileloc_createExternal ();
9823 if (unew->hasNameError)
9825 old->hasNameError = TRUE;
9830 if (!old->hasNameError)
9832 uentry_checkName (old);
9835 DPRINTF (("After: %s", uentry_unparseFull (old)));
9836 llassert (!ctype_isUndefined (old->utype));
9840 uentry_copyState (uentry res, uentry other)
9842 llassert (uentry_isValid (res));
9843 llassert (uentry_isValid (other));
9845 res->used = other->used;
9847 res->info->var->kind = other->info->var->kind;
9848 res->info->var->defstate = other->info->var->defstate;
9849 res->info->var->nullstate = other->info->var->nullstate;
9850 res->info->var->checked = other->info->var->checked;
9852 sRef_copyState (res->sref, other->sref);
9856 uentry_sameKind (uentry u1, uentry u2)
9858 if (uentry_isValid (u1) && uentry_isValid (u2))
9860 if (uentry_isVar (u1) && uentry_isVar (u2))
9862 ctype c1 = u1->utype;
9863 ctype c2 = u2->utype;
9865 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9868 ** both functions, or both not functions
9871 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9875 return ((u1->ukind == u2->ukind));
9882 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9885 llassert (uentry_isValid (unew));
9886 llassert (uentry_isValid (old));
9888 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9889 okind = unew->ukind;
9890 unew->ukind = old->ukind;
9891 llassert (cstring_equal (unew->uname, old->uname));
9892 unew->utype = old->utype;
9894 if (fileloc_isDefined (unew->whereSpecified)
9895 && !fileloc_isDefined (old->whereSpecified))
9897 ; /* Keep the old value */
9901 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9902 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9905 if (fileloc_isDefined (unew->whereDefined)
9906 && !fileloc_isDefined (old->whereDefined))
9908 ; /* Keep the old value */
9912 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9913 unew->whereDefined = fileloc_copy (old->whereDefined);
9916 if (fileloc_isDefined (unew->whereDeclared)
9917 && !fileloc_isDefined (old->whereDeclared))
9919 ; /* Keep the old value */
9923 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9924 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9927 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9929 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9930 unew->used = old->used;
9932 unew->isPrivate = old->isPrivate;
9933 unew->hasNameError = old->hasNameError;
9934 unew->uses = filelocList_append (unew->uses, old->uses);
9935 old->uses = filelocList_undefined;
9937 unew->storageclass = old->storageclass;
9938 uinfo_free (unew->info, okind);
9939 unew->info = uinfo_copy (old->info, old->ukind);
9943 uentry_copyAux (uentry e, bool saveCopy)
9946 if (uentry_isValid (e))
9948 uentry enew = uentry_alloc ();
9949 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9950 enew->ukind = e->ukind;
9951 enew->uname = cstring_copy (e->uname);
9952 enew->utype = e->utype;
9954 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9955 enew->whereDefined = fileloc_copy (e->whereDefined);
9956 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9960 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9964 enew->sref = sRef_copy (e->sref);
9967 enew->used = e->used;
9969 enew->isPrivate = e->isPrivate;
9970 enew->hasNameError = e->hasNameError;
9971 enew->uses = filelocList_undefined;
9973 enew->storageclass = e->storageclass;
9974 enew->info = uinfo_copy (e->info, e->ukind);
9975 enew->warn = warnClause_copy (e->warn);
9977 DPRINTF (("Here we are..."));
9978 DPRINTF (("original: %s", uentry_unparseFull (e)));
9979 DPRINTF (("copy: %s", uentry_unparse (enew)));
9980 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9985 return uentry_undefined;
9990 uentry_copy (uentry e)
9992 return uentry_copyAux (e, TRUE);
9996 uentry_copyNoSave (uentry e)
9998 return uentry_copyAux (e, FALSE);
10002 uentry_setState (uentry res, uentry other)
10004 llassert (uentry_isValid (res));
10005 llassert (uentry_isValid (other));
10007 llassert (res->ukind == other->ukind);
10008 llassert (res->ukind == KVAR);
10010 res->sref = sRef_saveCopy (other->sref);
10011 res->used = other->used;
10012 filelocList_free (res->uses);
10013 res->uses = other->uses;
10014 other->uses = filelocList_undefined;
10015 res->lset = other->lset;
10019 uentry_mergeUses (uentry res, uentry other)
10021 llassert (uentry_isValid (res));
10022 llassert (uentry_isValid (other));
10024 res->used = other->used || res->used;
10025 res->lset = other->lset || res->lset;
10026 res->uses = filelocList_append (res->uses, other->uses);
10027 other->uses = filelocList_undefined;
10032 ** This is a really ugly routine.
10034 ** gack...fix this one day.
10039 ** >> res is the false branch, other is the true branch (or continuation)
10041 ** >> res is the true branch, other is the false branch (or continutation)
10048 ** References not effected by res are propagated from other.
10052 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10053 bool flip, clause cl, fileloc loc)
10057 message ("%s %q is %s %s, but %s %s.",
10058 ekind_capName (res->ukind), uentry_getName (res),
10059 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10060 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10063 DPRINTF (("Here: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10065 if (sRef_isDead (res->sref))
10067 if (sRef_hasStateInfoLoc (res->sref)) {
10068 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10069 sRef_showStateInfo (res->sref);
10072 if (sRef_hasStateInfoLoc (other->sref)) {
10073 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10074 sRef_showStateInfo (other->sref);
10077 else if (sRef_isKept (res->sref))
10079 if (sRef_hasAliasInfoLoc (res->sref)) {
10080 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10081 sRef_showAliasInfo (res->sref);
10084 if (sRef_hasAliasInfoLoc (other->sref)) {
10085 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10086 sRef_showAliasInfo (other->sref);
10089 else /* dependent */
10091 if (sRef_hasAliasInfoLoc (res->sref)) {
10092 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10093 sRef_showAliasInfo (res->sref);
10096 if (sRef_hasAliasInfoLoc (other->sref)) {
10097 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10098 sRef_showAliasInfo (other->sref);
10102 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10106 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10108 alkind rk = sRef_getAliasKind (rs);
10109 alkind ok = sRef_getAliasKind (os);
10111 if (alkind_isError (rk) || alkind_isError (ok))
10117 return ((sRef_isDead (rs)
10118 || (alkind_isKept (rk) && !alkind_isKept (ok))
10119 || (alkind_isDependent (rk)
10120 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10121 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10126 branchStateAltError (/*@notnull@*/ uentry res,
10127 /*@notnull@*/ uentry other, bool flip,
10128 clause cl, fileloc loc)
10132 message ("%s %q is %s %s, but %s %s.",
10133 ekind_capName (res->ukind), uentry_getName (res),
10134 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10135 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10138 if (sRef_isDead (other->sref))
10140 if (sRef_hasStateInfoLoc (other->sref)) {
10141 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10142 sRef_showStateInfo (other->sref);
10145 if (sRef_hasStateInfoLoc (res->sref)) {
10146 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10147 sRef_showStateInfo (res->sref);
10152 if (sRef_hasAliasInfoLoc (other->sref)) {
10153 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10154 sRef_showAliasInfo (other->sref);
10157 if (sRef_hasAliasInfoLoc (res->sref)) {
10158 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10159 sRef_showAliasInfo (res->sref);
10163 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10164 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10166 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10167 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10172 ** A reference is relevant for certain checks, only if it
10173 ** is not definitely null on this path (but not declared
10174 ** to always be null.)
10177 static bool uentry_relevantReference (sRef sr, bool flip)
10179 if (sRef_isKept (sr) || sRef_isDependent (sr))
10187 return !sRef_definitelyNullContext (sr);
10191 return !sRef_definitelyNullAltContext (sr);
10197 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10198 fileloc loc, bool mustReturn, bool flip, bool opt,
10201 sRef rs = res->sref;
10202 sRef os = other->sref;
10204 DPRINTF (("Merge alias states: %s / %s",
10205 uentry_unparseFull (res),
10206 uentry_unparseFull (other)));
10208 if (sRef_isValid (rs))
10212 if (uentry_incompatibleMemoryStates (rs, os))
10214 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10215 sRef_unparseFull (rs), sRef_unparseFull (os)));
10217 if (sRef_isThroughArrayFetch (rs)
10218 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10220 if (sRef_isKept (rs) || sRef_isKept (os))
10222 sRef_maybeKill (rs, loc);
10224 else if (sRef_isPossiblyDead (os))
10226 sRef_maybeKill (rs, loc);
10235 if (uentry_relevantReference (os, flip))
10237 if (sRef_isLocalParamVar (rs)
10238 && (sRef_isLocalState (os)
10239 || sRef_isDependent (os)))
10241 if (sRef_isDependent (rs))
10243 sRef_setDependent (os, loc);
10247 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10252 branchStateError (res, other, !flip, cl, loc); /* evans 2002-12-15: changed flip to !flip */
10257 if (sRef_isKept (rs))
10259 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10260 sRef_setKept (os, loc);
10265 if (uentry_incompatibleMemoryStates (os, rs))
10267 if (uentry_relevantReference (rs, !flip))
10269 if (sRef_isLocalParamVar (rs)
10270 && (sRef_isDependent (rs)
10271 || sRef_isLocalState (rs)))
10273 if (sRef_isDependent (os))
10275 sRef_setDependent (rs, loc);
10279 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10284 if (sRef_isParam (os))
10287 ** If the local variable associated
10288 ** with the param has the correct state,
10290 ** (e.g., free (s); s = new(); ...
10293 uentry uvar = usymtab_lookupSafe (other->uname);
10295 if (uentry_isValid (uvar)
10296 && ((sRef_isDead (os)
10297 && sRef_isOnly (uvar->sref))
10298 || (sRef_isDependent (os)
10299 && sRef_isOwned (uvar->sref))))
10305 branchStateAltError (res, other,
10311 DPRINTF (("Here: %s / %s",
10312 uentry_unparseFull (res),
10313 uentry_unparseFull (other)));
10315 branchStateAltError (res, other,
10322 if (sRef_isKept (os))
10324 sRef_setKept (rs, loc);
10330 DPRINTF (("Merge opt..."));
10331 sRef_mergeOptState (rs, os, cl, loc);
10332 DPRINTF (("Done!"));
10336 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10337 sRef_mergeState (rs, os, cl, loc);
10338 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10343 if (sRef_isModified (os))
10345 sRef_setModified (rs);
10350 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10354 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10355 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10357 valueTable rvalues;
10358 valueTable ovalues;
10360 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10368 rvalues = sRef_getValueTable (res->sref);
10369 ovalues = sRef_getValueTable (other->sref);
10371 if (valueTable_isUndefined (ovalues))
10373 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10376 else if (valueTable_isUndefined (rvalues))
10379 ** Copy values from other
10383 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10384 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10389 valueTable_elements (ovalues, fkey, fval) {
10391 metaStateInfo minfo;
10392 stateCombinationTable sctable;
10396 tval = valueTable_lookup (rvalues, fkey);
10398 DPRINTF (("Merge value: %s / %s X %s", fkey,
10399 stateValue_unparse (fval), stateValue_unparse (tval)));
10401 minfo = context_lookupMetaStateInfo (fkey);
10402 llassert (stateValue_isDefined (tval));
10404 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10406 DPRINTF (("Cannot find meta state for: %s", fkey));
10411 llassert (metaStateInfo_isDefined (minfo));
10413 if (stateValue_isError (fval)
10414 || sRef_definitelyNullContext (res->sref))
10416 sRef_setMetaStateValueComplete (res->sref,
10417 fkey, stateValue_getValue (fval),
10418 stateValue_getLoc (fval));
10419 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10421 else if (stateValue_isError (tval)
10422 || sRef_definitelyNullAltContext (other->sref))
10424 DPRINTF (("Other branch is definitely null!"));
10426 else if (sRef_isStateUndefined (res->sref)
10427 || sRef_isDead (res->sref))
10429 ; /* Combination state doesn't matter if it is undefined or dead */
10433 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10434 metaStateInfo_unparse (minfo),
10435 stateValue_unparse (fval),
10436 stateValue_unparse (tval)));
10438 DPRINTF (("state values: %d / %d",
10439 stateValue_getValue (fval), stateValue_getValue (tval)));
10441 sctable = metaStateInfo_getMergeTable (minfo);
10443 DPRINTF (("Merge table: %s",
10444 stateCombinationTable_unparse (sctable)));
10446 msg = cstring_undefined;
10448 nval = stateCombinationTable_lookup (sctable,
10449 stateValue_getValue (fval),
10450 stateValue_getValue (tval),
10453 DPRINTF (("nval: %d / %d / %d", nval,
10454 stateValue_getValue (fval), stateValue_getValue (tval)));
10456 if (nval == stateValue_error)
10458 /*@i32 print extra info for assignments@*/
10460 if (uentry_isGlobalMarker (res))
10465 ("Control branches merge with incompatible global states (%s and %s)%q",
10466 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10467 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10468 cstring_isDefined (msg)
10469 ? message (": %s", msg) : cstring_undefined),
10472 sRef_showMetaStateInfo (res->sref, fkey);
10473 sRef_showMetaStateInfo (other->sref, fkey);
10481 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10482 uentry_getName (res),
10483 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10484 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10485 cstring_isDefined (msg)
10486 ? message (": %s", msg) : cstring_undefined),
10489 sRef_showMetaStateInfo (res->sref, fkey);
10490 sRef_showMetaStateInfo (other->sref, fkey);
10491 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10492 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10493 DPRINTF (("Null: %s / %s",
10494 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10495 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10501 if (nval == stateValue_getValue (fval)
10502 && nval != stateValue_getValue (tval))
10504 loc = stateValue_getLoc (fval);
10506 else if (nval == stateValue_getValue (tval)
10507 && nval != stateValue_getValue (fval))
10509 loc = stateValue_getLoc (tval);
10516 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10517 && nval == stateValue_getValue (fval)
10518 && nval == stateValue_getValue (tval))
10524 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10528 } end_valueTable_elements ;
10534 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10535 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10536 bool flip, clause cl)
10538 if (cl == DOWHILECLAUSE)
10540 res->used = other->used || res->used;
10541 res->lset = other->lset || res->lset;
10542 res->uses = filelocList_append (res->uses, other->uses);
10543 other->uses = filelocList_undefined;
10547 if (sRef_isMacroParamRef (res->sref)
10548 && !uentry_isSefParam (other)
10549 && !uentry_isSefParam (res))
10551 bool hasError = FALSE;
10553 if (bool_equal (res->used, other->used))
10555 res->used = other->used;
10559 if (other->used && !flip)
10564 message ("Macro parameter %q used in true clause, "
10565 "but not in false clause",
10566 uentry_getName (res)),
10567 uentry_whereDeclared (res));
10574 message ("Macro parameter %q used in false clause, "
10575 "but not in true clause",
10576 uentry_getName (res)),
10577 uentry_whereDeclared (res));
10583 /* make it sef now, prevent more errors */
10584 res->info->var->kind = VKREFSEFPARAM;
10590 res->used = other->used || res->used;
10591 res->lset = other->lset || res->lset;
10592 res->uses = filelocList_append (res->uses, other->uses);
10593 other->uses = filelocList_undefined;
10599 uentry_mergeState (uentry res, uentry other, fileloc loc,
10600 bool mustReturn, bool flip, bool opt,
10603 llassert (uentry_isValid (res));
10604 llassert (uentry_isValid (other));
10606 llassert (res->ukind == other->ukind);
10607 llassert (res->ukind == KVAR);
10609 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10610 uentry_unparseFull (other)));
10612 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10613 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10614 uentry_mergeSetStates (res, other, loc, flip, cl);
10616 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10619 void uentry_setUsed (uentry e, fileloc loc)
10621 static bool firstTime = TRUE;
10622 static bool showUses = FALSE;
10623 static bool exportLocal = FALSE;
10625 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10629 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10631 showUses = context_getFlag (FLG_SHOWUSES);
10632 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10637 if (uentry_isValid (e))
10641 if (warnClause_isDefined (e->warn))
10643 flagSpec flg = warnClause_getFlag (e->warn);
10646 if (warnClause_hasMessage (e->warn))
10648 msg = cstring_copy (warnClause_getMessage (e->warn));
10652 msg = message ("Use of possibly dangerous %s",
10653 uentry_ekindNameLC (e));
10657 message ("%q: %q", msg, uentry_getName (e)),
10661 if (sRef_isMacroParamRef (e->sref))
10663 if (uentry_isYield (e) || uentry_isSefParam (e))
10669 if (context_inConditional ())
10673 message ("Macro parameter %q used in conditionally "
10674 "executed code (may or may not be "
10675 "evaluated exactly once)",
10676 uentry_getName (e)),
10679 e->info->var->kind = VKREFSEFPARAM;
10688 message ("Macro parameter %q used more than once",
10689 uentry_getName (e)),
10690 uentry_whereDeclared (e)))
10692 e->info->var->kind = VKREFSEFPARAM;
10699 if ((dp = uentry_directParamNo (e)) >= 0)
10701 uentry_setUsed (usymtab_getParam (dp), loc);
10706 if (!sRef_isLocalVar (e->sref))
10710 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10716 if (context_inMacro ())
10718 e->uses = filelocList_addUndefined (e->uses);
10722 e->uses = filelocList_addDifferentFile
10724 uentry_whereDeclared (e),
10733 bool uentry_isReturned (uentry u)
10735 return (uentry_isValid (u) && uentry_isVar (u)
10736 && (u->info->var->kind == VKRETPARAM
10737 || u->info->var->kind == VKSEFRETPARAM));
10742 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10744 llassert (uentry_isRealFunction (u));
10746 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10748 stateClauseList clauses = uentry_getStateClauseList (u);
10749 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10751 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10752 sRef_setAllocated (res, g_currentloc);
10754 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10755 stateClauseList_unparse (clauses)));
10758 ** This should be in exprNode_reflectEnsuresClause
10761 stateClauseList_postElements (clauses, cl)
10763 if (!stateClause_isGlobal (cl))
10765 sRefSet refs = stateClause_getRefs (cl);
10766 sRefMod modf = stateClause_getEffectFunction (cl);
10768 sRefSet_elements (refs, el)
10770 sRef base = sRef_getRootBase (el);
10772 if (sRef_isResult (base))
10776 sRef sr = sRef_fixBase (el, res);
10777 modf (sr, g_currentloc);
10784 } end_sRefSet_elements ;
10786 } end_stateClauseList_postElements ;
10794 sRefSet prefs = sRefSet_new ();
10795 sRef res = sRef_undefined;
10796 sRef tcref = sRef_undefined;
10797 sRef tref = sRef_undefined;
10800 params = uentry_getParams (u);
10803 ** Setting up aliases has to happen *after* setting null state!
10806 uentryList_elements (params, current)
10808 if (uentry_isReturned (current))
10810 if (exprNodeList_size (args) >= paramno)
10812 exprNode ecur = exprNodeList_nth (args, paramno);
10813 tref = exprNode_getSref (ecur);
10815 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10817 if (sRef_isValid (tref))
10819 tcref = sRef_copy (tref);
10821 if (sRef_isDead (tcref))
10823 sRef_setDefined (tcref, g_currentloc);
10824 sRef_setOnly (tcref, g_currentloc);
10827 if (sRef_isRefCounted (tcref))
10829 /* could be a new ref now (but only if its returned) */
10830 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10833 sRef_makeSafe (tcref);
10834 prefs = sRefSet_insert (prefs, tcref);
10840 } end_uentryList_elements ;
10842 if (sRefSet_size (prefs) > 0)
10844 nstate n = sRef_getNullState (u->sref);
10846 if (sRefSet_size (prefs) == 1)
10848 sRef rref = sRefSet_choose (prefs);
10850 res = sRef_makeType (sRef_getType (rref));
10851 sRef_copyState (res, tref);
10855 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10856 res = sRefSet_mergeIntoOne (prefs);
10859 if (nstate_isKnown (n))
10861 sRef_setNullState (res, n, g_currentloc);
10862 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10867 if (ctype_isFunction (u->utype))
10869 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10870 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10874 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10875 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10878 if (sRef_isRefCounted (res))
10880 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10884 if (sRef_getNullState (res) == NS_ABSNULL)
10886 ctype ct = ctype_realType (u->utype);
10888 if (ctype_isAbstract (ct))
10890 sRef_setNotNull (res, g_currentloc);
10894 if (ctype_isUser (ct))
10896 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10900 sRef_setNotNull (res, g_currentloc);
10905 if (sRef_isRefCounted (res))
10907 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10909 else if (sRef_isKillRef (res))
10911 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10918 ak = sRef_getAliasKind (res);
10920 if (alkind_isImplicit (ak))
10922 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10926 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10927 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10929 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10930 usymtab_addReallyForceMustAlias (res, tref);
10933 sRefSet_free (prefs);
10935 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10941 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
10943 llassert (uentry_isRealFunction (u));
10945 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10947 stateClauseList clauses = uentry_getStateClauseList (u);
10948 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10950 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10951 sRef_setAllocated (res, loc);
10953 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10954 stateClauseList_unparse (clauses)));
10957 ** This should be in exprNode_reflectEnsuresClause
10960 stateClauseList_postElements (clauses, cl)
10962 if (!stateClause_isGlobal (cl))
10964 sRefSet refs = stateClause_getRefs (cl);
10965 sRefMod modf = stateClause_getEffectFunction (cl);
10967 sRefSet_elements (refs, el)
10969 sRef base = sRef_getRootBase (el);
10971 if (sRef_isResult (base))
10975 sRef sr = sRef_fixBase (el, res);
10983 } end_sRefSet_elements ;
10985 } end_stateClauseList_postElements ;
10993 sRefSet prefs = sRefSet_new ();
10994 sRef res = sRef_undefined;
10997 params = uentry_getParams (u);
10999 uentryList_elements (params, current)
11001 if (uentry_isReturned (current))
11003 if (exprNodeList_size (args) >= paramno)
11005 exprNode ecur = exprNodeList_nth (args, paramno);
11006 sRef tref = exprNode_getSref (ecur);
11008 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
11010 if (sRef_isValid (tref))
11012 sRef tcref = sRef_copy (tref);
11014 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
11016 if (sRef_isNew (tcref))
11018 /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
11021 if (sRef_isDead (tcref))
11023 sRef_setDefined (tcref, loc);
11024 sRef_setOnly (tcref, loc);
11027 if (sRef_isRefCounted (tcref))
11029 /* could be a new ref now (but only if its returned) */
11030 sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
11033 sRef_makeSafe (tcref);
11034 DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
11035 prefs = sRefSet_insert (prefs, tcref);
11041 } end_uentryList_elements ;
11043 if (sRefSet_size (prefs) > 0)
11045 nstate n = sRef_getNullState (u->sref);
11047 if (sRefSet_size (prefs) == 1)
11049 res = sRefSet_choose (prefs);
11053 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
11054 res = sRefSet_mergeIntoOne (prefs);
11057 if (nstate_isKnown (n))
11059 sRef_setNullState (res, n, loc);
11064 if (ctype_isFunction (u->utype))
11066 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
11067 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
11071 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
11074 if (sRef_isRefCounted (res))
11076 sRef_setAliasKind (res, AK_NEWREF, loc);
11081 if (sRef_getNullState (res) == NS_ABSNULL)
11083 ctype ct = ctype_realType (u->utype);
11085 if (ctype_isAbstract (ct))
11087 sRef_setNotNull (res, loc);
11091 if (ctype_isUser (ct))
11093 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
11097 sRef_setNotNull (res, loc);
11102 if (sRef_isRefCounted (res))
11104 sRef_setAliasKind (res, AK_NEWREF, loc);
11106 else if (sRef_isKillRef (res))
11108 sRef_setAliasKind (res, AK_REFCOUNTED, loc);
11115 ak = sRef_getAliasKind (res);
11117 if (alkind_isImplicit (ak))
11119 sRef_setAliasKind (res,
11120 alkind_fixImplicit (ak),
11124 sRefSet_free (prefs);
11127 if (sRef_isOnly (res))
11129 sRef_setFresh (res, loc);
11133 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11138 static bool uentry_isRefCounted (uentry ue)
11140 ctype ct = uentry_getType (ue);
11142 if (ctype_isFunction (ct))
11144 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11148 return (ctype_isRefCounted (ct));
11153 ** old was declared yield in the specification.
11154 ** new is declared in the iter implementation.
11157 void uentry_checkYieldParam (uentry old, uentry unew)
11161 llassert (uentry_isVariable (old));
11162 llassert (uentry_isVariable (unew));
11164 unew->info->var->kind = VKYIELDPARAM;
11165 (void) checkTypeConformance (old, unew, TRUE);
11166 checkVarConformance (old, unew, TRUE, FALSE);
11168 /* get rid of param marker */
11170 name = uentry_getName (unew);
11171 cstring_free (unew->uname);
11172 unew->uname = name;
11173 unew->info->var->kind = VKREFYIELDPARAM;
11175 uentry_setUsed (old, fileloc_undefined);
11176 uentry_setUsed (unew, fileloc_undefined);
11179 /*@observer@*/ cstring
11180 uentry_ekindName (uentry ue)
11182 if (uentry_isValid (ue))
11187 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11189 return cstring_makeLiteralTemp ("Datatype");
11191 return cstring_makeLiteralTemp ("Enum member");
11193 return cstring_makeLiteralTemp ("Constant");
11195 if (uentry_isParam (ue))
11197 return cstring_makeLiteralTemp ("Parameter");
11199 else if (uentry_isExpandedMacro (ue))
11201 return cstring_makeLiteralTemp ("Expanded macro");
11205 return cstring_makeLiteralTemp ("Variable");
11208 return cstring_makeLiteralTemp ("Function");
11210 return cstring_makeLiteralTemp ("Iterator");
11212 return cstring_makeLiteralTemp ("Iterator finalizer");
11214 return cstring_makeLiteralTemp ("Struct tag");
11216 return cstring_makeLiteralTemp ("Union tag");
11218 return cstring_makeLiteralTemp ("Enum tag");
11220 return cstring_makeLiteralTemp ("Optional parameters");
11225 return cstring_makeLiteralTemp ("<Undefined>");
11231 /*@observer@*/ cstring
11232 uentry_ekindNameLC (uentry ue)
11234 if (uentry_isValid (ue))
11239 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11241 return cstring_makeLiteralTemp ("datatype");
11243 return cstring_makeLiteralTemp ("enum member");
11245 return cstring_makeLiteralTemp ("constant");
11247 if (uentry_isParam (ue))
11249 return cstring_makeLiteralTemp ("parameter");
11251 else if (uentry_isExpandedMacro (ue))
11253 return cstring_makeLiteralTemp ("expanded macro");
11257 return cstring_makeLiteralTemp ("variable");
11260 return cstring_makeLiteralTemp ("function");
11262 return cstring_makeLiteralTemp ("iterator");
11264 return cstring_makeLiteralTemp ("iterator finalizer");
11266 return cstring_makeLiteralTemp ("struct tag");
11268 return cstring_makeLiteralTemp ("union tag");
11270 return cstring_makeLiteralTemp ("enum tag");
11272 return cstring_makeLiteralTemp ("optional parameters");
11277 return cstring_makeLiteralTemp ("<Undefined>");
11283 void uentry_setHasNameError (uentry ue)
11285 llassert (uentry_isValid (ue));
11287 ue->hasNameError = TRUE;
11290 void uentry_checkName (uentry ue)
11292 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11293 uentry_observeRealName (ue),
11294 bool_unparse (uentry_isVisibleExternally (ue))));
11296 if (uentry_isValid (ue)
11297 && !context_inXHFile ()
11298 && uentry_hasName (ue)
11299 && !uentry_isElipsisMarker (ue)
11300 && context_getFlag (FLG_NAMECHECKS)
11301 && !ue->hasNameError
11302 && !uentry_isEndIter (ue)
11303 && !fileloc_isBuiltin (uentry_whereLast (ue))
11304 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11306 DPRINTF (("Here..."));
11308 if (uentry_isPriv (ue))
11310 ; /* any checks here? */
11312 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11314 ; /* no errors for externals */
11320 if (uentry_isExpandedMacro (ue))
11326 if (uentry_isExpandedMacro (ue))
11330 else if (uentry_isVariable (ue))
11332 sRef sr = uentry_getSref (ue);
11334 if (sRef_isValid (sr))
11336 scope = sRef_getScope (sr);
11343 else if (uentry_isFunction (ue)
11344 || uentry_isIter (ue)
11345 || uentry_isEndIter (ue)
11346 || uentry_isConstant (ue))
11348 scope = uentry_isStatic (ue) ? fileScope : globScope;
11350 else /* datatypes, etc. must be global */
11355 usymtab_checkDistinctName (ue, scope);
11358 if (context_getFlag (FLG_CPPNAMES))
11363 if (scope == globScope)
11365 checkExternalName (ue);
11367 else if (scope == fileScope)
11369 checkFileScopeName (ue);
11373 checkLocalName (ue);
11377 checkAnsiName (ue);
11382 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11388 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11391 if (!context_inMacro ())
11393 sRef_setGlobalScopeSafe ();
11396 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11397 uentry_setUsed (ue, loc);
11399 tloc = fileloc_createExternal ();
11400 uentry_setDefined (ue, tloc);
11401 fileloc_free (tloc);
11402 uentry_setHasNameError (ue);
11404 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldStyleScope()))
11406 uentry_markOwned (ue);
11410 ue = usymtab_supReturnFileEntry (ue);
11413 if (!context_inMacro ())
11415 sRef_clearGlobalScopeSafe ();
11421 uentry uentry_makeGlobalMarker ()
11426 llassert (sRef_inGlobalScope ());
11428 ue = uentry_makeVariableAux
11429 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11430 sRef_makeGlobalMarker (),
11433 tloc = fileloc_createExternal ();
11434 uentry_setUsed (ue, tloc);
11435 uentry_setDefined (ue, tloc);
11436 fileloc_free (tloc);
11437 uentry_setHasNameError (ue);
11443 bool uentry_isGlobalMarker (uentry ue)
11445 return (uentry_isValid (ue)
11446 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11449 /* new start modifications */
11451 /* start modifications */
11453 requires: p_e is defined, is a ptr/array variable
11455 effects: sets the state of the variable
11459 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11461 llassert (uentry_isValid (p_e));
11463 if (p_e->info != NULL)
11465 if (p_e->info->var != NULL)
11467 llassert (p_e->info->var->bufinfo != NULL);
11468 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11469 sRef_setPossiblyNullTerminatedState (p_e->sref);
11475 requires: p_e is defined, is a ptr/array variable
11477 effects: sets the size of the buffer
11480 void uentry_setNullTerminatedState (uentry p_e) {
11481 llassert (uentry_isValid (p_e));
11483 if (p_e->info != NULL)
11485 if (p_e->info->var != NULL)
11487 llassert (p_e->info->var->bufinfo != NULL);
11488 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11489 sRef_setNullTerminatedState (p_e->sref);
11495 requires: p_e is defined, is a ptr/array variable
11497 effects: sets the size of the buffer
11500 void uentry_setSize (uentry p_e, int size)
11502 if (uentry_isValid (p_e))
11504 if (p_e->info != NULL)
11506 if (p_e->info->var != NULL)
11508 llassert (p_e->info->var->bufinfo != NULL);
11509 p_e->info->var->bufinfo->size = size;
11510 sRef_setSize (p_e->sref, size);
11517 requires: p_e is defined, is a ptr/array variable
11519 effects: sets the length of the buffer
11522 void uentry_setLen (uentry p_e, int len)
11524 if (uentry_isValid (p_e))
11526 if (p_e->info != NULL
11527 && p_e->info->var != NULL)
11529 llassert (p_e->info->var->bufinfo != NULL);
11530 p_e->info->var->bufinfo->len = len;
11531 sRef_setLen (p_e->sref, len);
11538 bool uentry_hasMetaStateEnsures (uentry e)
11540 if (uentry_isValid (e) && uentry_isFunction (e))
11542 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11550 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11552 llassert (uentry_isValid (e) && uentry_isFunction (e));
11553 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11556 # ifdef DEBUGSPLINT
11559 ** For debugging only
11562 void uentry_checkValid (uentry ue)
11564 if (uentry_isValid (ue))
11566 sRef_checkCompletelyReasonable (ue->sref);