2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 # include "splintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
38 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43 static void uentry_checkIterArgs (uentry p_ue);
44 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
46 static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_warningstream@*/ ;
48 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
51 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
55 static void checkAliasState (/*@notnull@*/ uentry p_old,
56 /*@notnull@*/ uentry p_unew,
57 bool p_mustConform, bool p_completeConform)
58 /*@modifies p_old, p_unew@*/ ;
59 static void checkNullState (/*@notnull@*/ uentry p_old,
60 /*@notnull@*/ uentry p_unew,
61 bool p_mustConform, bool p_completeConform)
62 /*@modifies p_old, p_unew@*/ ;
64 static void checkVarConformance (/*@notnull@*/ uentry p_old,
65 /*@notnull@*/ uentry p_unew,
66 bool p_mustConform, bool p_completeConform)
67 /*@modifies p_old, p_unew@*/;
70 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
71 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
74 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
76 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
77 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
80 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
81 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
82 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
83 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
84 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
86 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
87 ctype p_oldType, /*@notnull@*/ uentry p_unew,
88 /*@notnull@*/ uentry p_newCurrent,
89 ctype p_newType, int p_paramno) /*@modifies g_warningstream@*/ ;
91 static /*@only@*/ /*@notnull@*/ uentry
92 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
93 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
95 static /*@only@*/ /*@notnull@*/ uentry
96 uentry_makeConstantAux (cstring p_n, ctype p_t,
97 /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
98 /*@only@*/ multiVal p_m) /*@*/ ;
100 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
102 if (uentry_isVariable (ue)
103 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
104 || ctype_isUnknown (uentry_getType (ue))))
106 uentry_makeVarFunction (ue);
110 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
112 uentry ue = (uentry) dmalloc (sizeof (*ue));
113 ue->warn = warnClause_undefined; /*@i32@*/
120 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
121 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
123 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
124 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
125 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
126 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
127 static void ucinfo_free (/*@only@*/ ucinfo p_u);
128 static void uvinfo_free (/*@only@*/ uvinfo p_u);
132 static /*@only@*/ cstring ancontext_unparse (ancontext an)
136 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
137 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
138 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
139 case AN_SUFIELD: return cstring_makeLiteral ("su field");
140 case AN_TDEFN: return cstring_makeLiteral ("type definition");
141 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
142 case AN_CONST: return cstring_makeLiteral ("constant");
148 static int annots[AN_LAST][QU_LAST];
149 static int decls[AN_LAST];
150 static int shdecls[AN_LAST];
151 static int idecls[AN_LAST];
157 for (i = AN_UNKNOWN; i < AN_LAST; i++)
163 for (j = QU_UNKNOWN; j < QU_LAST; j++)
170 static void tallyAnnot (ancontext ac, qual q)
184 for (j = QU_UNKNOWN; j < QU_LAST; j++)
189 for (i = AN_UNKNOWN; i < AN_LAST; i++)
195 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
196 ancontext_unparse (i),
197 decls[i], shdecls[i], idecls[i]);
199 totdecls += decls[i];
200 totshdecls += shdecls[i];
201 totidecls += idecls[i];
203 for (j = QU_UNKNOWN; j < QU_LAST; j++)
205 total[j] += annots[i][j];
206 alltotals += annots[i][j];
209 printf (" Allocation:\n");
213 for (j = QU_UNKNOWN; j < QU_LAST; j++)
215 if (qual_isAliasQual (j) && !qual_isUnique (j))
217 if (annots[i][j] > 0)
219 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
220 100.0 * (double)annots[i][j] / (double)decls[i]);
221 tmptot += annots[i][j];
226 printf (" Exposure:\n");
230 for (j = QU_UNKNOWN; j < QU_LAST; j++)
232 if (qual_isExQual (j))
234 if (annots[i][j] > 0)
236 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
237 100.0 * (double)annots[i][j] / (double)decls[i]);
238 tmptot += annots[i][j];
243 printf (" Definition:\n");
245 for (j = QU_UNKNOWN; j < QU_LAST; j++)
247 if (qual_isAllocQual (j))
249 if (annots[i][j] > 0)
251 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
252 100.0 * (double)annots[i][j] / (double)decls[i]);
259 for (j = QU_UNKNOWN; j < QU_LAST; j++)
261 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
263 if (annots[i][j] > 0)
265 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
266 100.0 * (double)annots[i][j] / (double)decls[i]);
275 for (j = QU_UNKNOWN; j < QU_LAST; j++)
279 for (i = AN_UNKNOWN; i < AN_LAST; i++)
281 if (annots[i][j] > 0)
290 printf ("Annotation: %s\n", qual_unparse (j));
292 for (i = AN_UNKNOWN; i < AN_LAST; i++)
294 if (annots[i][j] > 0)
296 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
303 printf ("All Contexts\n");
305 for (j = QU_UNKNOWN; j < QU_LAST; j++)
309 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
310 100.0 * (double)total[j] / (double)(totdecls));
315 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
317 extern void uentry_tallyAnnots (uentry u, ancontext kind)
319 alkind ak = sRef_getAliasKind (u->sref);
320 exkind ek = sRef_getExKind (u->sref);
321 nstate ns = sRef_getNullState (u->sref);
322 sstate ss = sRef_getDefState (u->sref);
323 bool recordUnknown = FALSE;
325 if (kind == AN_UNKNOWN)
333 else if (e == KCONST || e == KENUMCONST)
337 else if (e == KFCN || e == KITER)
339 uentryList params = uentry_getParams (u);
342 uentryList_elements (params, current)
344 if (uentry_isReturned (current))
348 if (!uentry_isElipsisMarker (current))
350 uentry_tallyAnnots (current, AN_FCNPARAM);
352 } end_uentryList_elements;
356 if (ctype_isFunction (u->utype)
358 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
360 recordUnknown = TRUE;
363 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
365 ctype t = ctype_realType (u->utype);
369 uentryList fields = ctype_getFields (t);
371 uentryList_elements (fields, current)
373 uentry_tallyAnnots (current, AN_SUFIELD);
375 } end_uentryList_elements;
379 if (ctype_isVisiblySharable (u->utype))
381 recordUnknown = TRUE;
389 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
391 recordUnknown = TRUE;
398 if (kind == AN_FCNRETURN)
412 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
417 if (ctype_isRealPointer (ctype_realType (u->utype)))
425 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
426 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
427 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
428 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
432 if (uentry_isReturned (u))
434 tallyAnnot (kind, QU_RETURNED);
440 if (ctype_isRefCounted (ctype_realType (u->utype))
441 || (ctype_isFunction (u->utype) &&
442 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
448 if (kind == AN_FCNPARAM)
450 tallyAnnot (kind, QU_TEMP);
452 else if (recordUnknown)
454 if (kind == AN_FCNRETURN)
457 tallyAnnot (kind, QU_UNKNOWN);
461 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
462 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
463 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
464 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
466 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
467 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
468 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
469 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
470 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
471 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
472 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
473 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
474 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
475 case AK_IMPDEPENDENT:
476 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
486 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
487 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
493 case NS_ERROR: break;
494 case NS_UNKNOWN: break;
495 case NS_NOTNULL: break;
496 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
497 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
498 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
499 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
501 case NS_ABSNULL: break;
507 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
511 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
512 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
513 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
514 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
515 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
521 static specCode specCode_fromInt (int i)
524 llassert (i >= SPC_NONE && i < SPC_LAST);
526 return ((specCode) i);
530 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
532 if (uentry_isDeclared (u))
534 return cstring_makeLiteralTemp ("previously declared");
538 return cstring_makeLiteralTemp ("specified");
542 /*@observer@*/ cstring uentry_specDeclName (uentry u)
544 if (uentry_isDeclared (u))
546 return cstring_makeLiteralTemp ("previous declaration");
550 return cstring_makeLiteralTemp ("specification");
554 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
556 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
558 return cstring_makeLiteralTemp ("redefined");
560 else if (uentry_isCodeDefined (unew))
562 return cstring_makeLiteralTemp ("defined");
564 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
566 return cstring_makeLiteralTemp ("redeclared");
570 return cstring_makeLiteralTemp ("declared");
574 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
576 if (uentry_isValid (ue))
578 functionConstraint constraint;
580 DPRINTF((message ("called uentry_getFcnPostconditions on %s",
581 uentry_unparse (ue) ) ) );
583 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
585 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
586 uentry_unparse (ue) ) ) );
587 if (!uentry_isFunction (ue) )
589 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
590 uentry_unparse (ue) ) ));
591 return constraintList_undefined;
595 return constraintList_undefined;
598 if (!uentry_isFunction(ue))
601 DPRINTF((message ("called uentry_getFunctionConditions on non function %s",
602 uentry_unparse (ue) ) ) );
603 return constraintList_undefined;
607 llassert (uentry_isFunction (ue));
611 constraint = ue->info->fcn->postconditions;
615 constraint = ue->info->fcn->preconditions;
618 return functionConstraint_getBufferConstraints (constraint);
621 return constraintList_undefined;
626 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
628 return uentry_getFunctionConditions (ue, FALSE);
635 constraintList uentry_getFcnPostconditions (uentry ue)
637 return uentry_getFunctionConditions (ue, TRUE);
640 static /*@only@*/ fileloc setLocation (void)
642 fileloc fl = context_getSaveLocation ();
644 if (fileloc_isDefined (fl))
650 return fileloc_copy (g_currentloc);
654 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
656 llassert (uentry_isEitherConstant (ue));
657 sRef_setValue (ue->sref, val);
660 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
662 fileloc loc = setLocation ();
663 uentry ue = uentry_makeConstant (n, t, loc);
665 ue->ukind = KENUMCONST;
666 uentry_setDefined (ue, loc);
670 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
672 fileloc loc = setLocation ();
673 uentry ue = uentry_makeConstant (n, t, loc);
674 ctype etype = exprNode_getType (expr);
676 if (!ctype_isRealInt (etype)) {
680 ("Value of enum member is not an integeral type (type %s): %s",
681 ctype_unparse (etype), exprNode_unparse (expr)),
682 exprNode_loc (expr));
685 ue->ukind = KENUMCONST;
686 uentry_setDefined (ue, loc);
691 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
693 uentry ue = uentry_makeConstant (n, t, loc);
695 ue->ukind = KENUMCONST;
700 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
702 return uentry_makeVariable (n, t, setLocation (), FALSE);
705 bool uentry_isUnnamedVariable (uentry ue)
707 return uentry_isVariable (ue) && cstring_isUndefined (ue->uname);
710 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
712 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
715 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
717 ctype ct = idDecl_getCtype (id);
718 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
719 MAYBE, MAYBE, setLocation ());
721 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
723 if (!ynm_isOn (ue->info->datatype->abs))
725 if (ctype_isUnknown (ct))
727 ue->info->datatype->mut = MAYBE;
731 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
738 void uentry_checkParams (uentry ue)
740 if (uentry_isValid (ue))
742 bool isExt = uentry_isExtern (ue);
744 if (uentry_isRealFunction (ue))
746 uentryList params = uentry_getParams (ue);
748 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)))
764 (FLG_FIXEDFORMALARRAY,
765 message ("Function parameter %q declared as "
766 "manifest array (size constant is meaningless)",
767 uentry_getName (current)),
768 uentry_whereDeclared (current));
773 if (ctype_isArray (ct))
777 message ("Function parameter %q declared as "
778 "array (treated as pointer)",
779 uentry_getName (current)),
780 uentry_whereDeclared (current));
784 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
786 if (ctype_isAbstract (ct) &&
787 (isExt || (ctype_isAbstract (ctype_realType (ct))
788 && !context_hasFileAccess (ctype_typeId (ct)))))
793 ("Function %q declared with notnull parameter %q of abstract "
796 uentry_getName (current),
799 ("Since %s is an abstract type, notnull can only be "
800 "used for parameters if the function is static to a "
801 "module where %s is accessible.",
804 uentry_whereDeclared (current));
808 } end_uentryList_elements;
810 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
812 ctype ct = ue->utype;
814 if (ctype_isAbstract (ct)
815 && (isExt || (ctype_isAbstract (ctype_realType (ct))
816 && !context_hasFileAccess (ctype_typeId (ct)))))
821 ("%s %q declared %s notnull storage of abstract type %s",
822 ekind_capName (uentry_getKind (ue)),
827 ("Since %s is an abstract type, notnull can only be used "
828 "if it is static to a module where %s is accessible.",
831 uentry_whereDeclared (ue));
838 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
840 alkind ak = sRef_getAliasKind (ue->sref);
842 if (alkind_isRefCounted (ak))
844 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
848 if (alkind_isUnknown (ak))
850 exkind ek = sRef_getExKind (ue->sref);
852 if (exkind_isKnown (ek))
854 DPRINTF (("Setting imp dependent: %s",
855 uentry_unparseFull (ue)));
856 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
860 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
862 /* evans 2000-12-22 removed ctype_realType so it will
863 not apply to immutable abstract types. */
865 if (ctype_isVisiblySharable
866 (ctype_realType (ctype_getReturnType (ue->utype))))
868 if (uentryList_hasReturned (uentry_getParams (ue)))
874 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
876 ; /* Immutable objects are not shared. */
880 sRef_setAliasKind (ue->sref, AK_IMPONLY,
882 DPRINTF (("Ret imp only: %s",
883 ctype_unparse (ctype_getReturnType (ue->utype))));
893 static /*@notnull@*/ uentry
894 uentry_makeFunctionAux (cstring n, ctype t,
896 /*@only@*/ globSet globs,
897 /*@only@*/ sRefSet mods,
898 /*@only@*/ warnClause warn,
899 /*@keep@*/ fileloc f, bool priv,
900 /*@unused@*/ bool isForward)
902 uentry e = uentry_alloc ();
905 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
907 DPRINTF (("Make function: %s", n));
909 if (ctype_isFunction (t))
911 ret = ctype_getReturnType (t);
915 if (ctype_isKnown (t))
917 llbug (message ("not function: %s", ctype_unparse (t)));
924 if (fileloc_isSpec (f) || fileloc_isImport (f))
926 e->whereSpecified = f;
927 e->whereDeclared = fileloc_undefined;
931 e->whereSpecified = fileloc_undefined;
932 e->whereDeclared = f;
935 /* e->shallowCopy = FALSE; */
936 e->uname = cstring_copy (n);
938 e->storageclass = SCNONE;
940 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
942 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
944 if (ctype_isUA (ret))
946 sRef_setStateFromType (e->sref, ret);
951 e->uses = filelocList_new ();
953 e->hasNameError = FALSE;
957 e->info = (uinfo) dmalloc (sizeof (*e->info));
958 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
960 e->info->fcn->hasMods = sRefSet_isDefined (mods);
961 e->info->fcn->hasGlobs = globSet_isDefined (globs);
963 e->info->fcn->exitCode = XK_UNKNOWN;
964 e->info->fcn->nullPred = qual_createUnknown ();
965 e->info->fcn->specialCode = SPC_NONE;
967 e->info->fcn->access = access;
968 e->info->fcn->globs = globs;
969 e->info->fcn->defparams = uentryList_undefined;
971 sRef_setDefined (e->sref, f);
972 e->whereDefined = fileloc_undefined;
974 e->info->fcn->mods = sRefSet_undefined;
975 e->info->fcn->specclauses = NULL;
978 e->info->fcn->preconditions = NULL;
982 e->info->fcn->postconditions = NULL;
985 checkGlobalsModifies (e, mods);
986 e->info->fcn->mods = mods;
991 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
993 functionClauseList_elements (clauses, el)
995 DPRINTF (("Reflect clause: %s on %s",
996 functionClause_unparse (el), uentry_getName (ue)));
998 if (functionClause_isNoMods (el))
1000 modifiesClause mel = functionClause_getModifies (el);
1002 if (uentry_hasGlobs (ue))
1007 ("No globals and modifies inconsistent to globals clause for %q: %q",
1008 uentry_getName (ue),
1009 globSet_unparse (uentry_getGlobs (ue))),
1010 modifiesClause_getLoc (mel));
1014 if (uentry_hasMods (ue))
1019 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1020 uentry_getName (ue),
1021 sRefSet_unparse (uentry_getMods (ue))),
1022 modifiesClause_getLoc (mel));
1025 uentry_setGlobals (ue, globSet_undefined);
1026 uentry_setModifies (ue, sRefSet_undefined);
1028 else if (functionClause_isGlobals (el))
1030 globalsClause glc = functionClause_getGlobals (el);
1032 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1033 globalsClause_unparse (glc)));
1035 if (uentry_hasGlobs (ue))
1040 ("Multiple globals clauses for %q: %q",
1041 uentry_getName (ue),
1042 globalsClause_unparse (glc)),
1043 globalsClause_getLoc (glc));
1044 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1048 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1049 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1050 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1053 else if (functionClause_isModifies (el))
1055 modifiesClause mlc = functionClause_getModifies (el);
1057 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1059 if (uentry_hasMods (ue))
1067 ("Multiple modifies clauses for %s: %s",
1068 uentry_getName (ue),
1069 modifiesClause_unparse (mlc)),
1070 modifiesClause_getLoc (mlc)))
1072 llhint (message ("Previous modifies clause: ",
1073 sRefSet_unparse (uentry_getMods (ue))));
1079 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1083 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1086 else if (functionClause_isEnsures (el))
1088 functionConstraint cl = functionClause_takeEnsures (el);
1089 DPRINTF (("Setting post: %s / %s",
1090 uentry_unparse (ue), functionConstraint_unparse (cl)));
1091 uentry_setPostconditions (ue, cl);
1093 else if (functionClause_isRequires (el))
1095 functionConstraint cl = functionClause_takeRequires (el);
1096 uentry_setPreconditions (ue, cl);
1098 else if (functionClause_isState (el))
1100 stateClause sc = functionClause_takeState (el);
1102 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1104 sRefSet rfs = stateClause_getRefs (sc);
1106 sRefSet_elements (rfs, s)
1108 if (sRef_isParam (s))
1111 ** Can't use requires on parameters
1115 (FLG_ANNOTATIONERROR,
1116 message ("Requires clauses for %q concerns parameters %q should be "
1117 "a parameter annotation instead: %q",
1118 uentry_unparse (ue),
1120 stateClause_unparse (sc)),
1121 stateClause_loc (sc));
1123 } end_sRefSet_elements ;
1126 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1127 uentry_addStateClause (ue, sc);
1129 else if (functionClause_isWarn (el))
1131 warnClause wc = functionClause_takeWarn (el);
1132 uentry_addWarning (ue, wc);
1136 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1138 } end_functionClauseList_elements ;
1140 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1141 stateClauseList_checkAll (ue);
1144 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1146 bool leaveFunc = FALSE;
1148 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1149 typeId_invalid, globSet_undefined,
1150 sRefSet_undefined, warnClause_undefined,
1153 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1156 ** This makes parameters names print out correctly.
1157 ** (But we might be a local variable declaration for a function type...)
1160 if (context_inFunctionLike ())
1162 DPRINTF (("Header: %s / %s",
1163 uentry_unparse (context_getHeader ()),
1164 idDecl_unparse (id)));
1168 context_enterFunctionDeclaration (ue);
1172 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1173 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1174 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1175 reflectImplicitFunctionQualifiers (ue, FALSE);
1176 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1177 uentry_reflectClauses (ue, idDecl_getClauses (id));
1178 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1180 if (!uentry_isStatic (ue)
1181 && cstring_equalLit (ue->uname, "main"))
1183 ctype typ = ue->utype;
1187 llassert (ctype_isFunction (typ));
1189 retval = ctype_getReturnType (typ);
1191 if (!ctype_isInt (retval))
1195 message ("Function main declared to return %s, should return int",
1196 ctype_unparse (retval)),
1197 uentry_whereDeclared (ue));
1200 args = ctype_argsFunction (typ);
1202 if (uentryList_isMissingParams (args)
1203 || uentryList_size (args) == 0)
1209 if (uentryList_size (args) != 2)
1213 message ("Function main declared with %d arg%&, "
1214 "should have 2 (int argc, char *argv[])",
1215 uentryList_size (args)),
1216 uentry_whereLast (ue));
1220 uentry arg = uentryList_getN (args, 0);
1221 ctype ct = uentry_getType (arg);
1223 if (!ctype_isInt (ct))
1227 message ("Parameter 1, %q, of function main declared "
1228 "with type %t, should have type int",
1229 uentry_getName (arg), ct),
1230 uentry_whereDeclared (arg));
1233 arg = uentryList_getN (args, 1);
1234 ct = uentry_getType (arg);
1236 if (ctype_isArrayPtr (ct)
1237 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1238 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1246 message ("Parameter 2, %q, of function main declared "
1247 "with type %t, should have type char **",
1248 uentry_getName (arg), ct),
1249 uentry_whereDeclared (arg));
1257 context_exitFunctionDeclaration ();
1263 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1265 alkind ak = sRef_getAliasKind (e->sref);
1267 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1268 && context_getFlag (FLG_PARAMIMPTEMP))
1270 exkind ek = sRef_getExKind (e->sref);
1272 if (exkind_isKnown (ek))
1274 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1275 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1276 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1280 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1281 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1286 static /*@only@*/ /*@notnull@*/ uentry
1287 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1288 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1290 cstring pname = makeParam (n);
1293 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1294 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1296 cstring_free (pname);
1297 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1298 uentry_implicitParamAnnots (e);
1299 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1301 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1303 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1304 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1305 e->info->var->defstate = defstate;
1308 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1314 uentry_setRefCounted (uentry e)
1316 if (uentry_isValid (e))
1318 uentry_setAliasKind (e, AK_REFCOUNTED);
1319 sRef_storeState (e->sref);
1325 uentry_setStatic (uentry c)
1327 if (uentry_isValid (c))
1329 alkind ak = sRef_getAliasKind (c->sref);
1330 c->storageclass = SCSTATIC;
1332 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1334 if (!alkind_isUnknown (ak)
1335 && !alkind_isStatic (ak))
1337 if (!(ctype_isRealPointer (uentry_getType (c)))
1338 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1339 && !alkind_isRefCounted (ak))
1341 if (alkind_isImplicit (ak)
1342 && alkind_isDependent (ak)
1343 && ctype_isArray (uentry_getType (c)))
1345 ; /* no error for observer arrays */
1351 message ("Static storage %q declared as %s",
1353 alkind_unparse (ak)),
1354 uentry_whereDeclared (c));
1360 if (alkind_isUnknown (ak)
1361 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1362 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1364 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1365 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1373 uentry_setExtern (uentry c)
1375 if (uentry_isValid (c))
1376 c->storageclass = SCEXTERN;
1380 uentry_setParamNo (uentry ue, int pno)
1382 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1383 sRef_setParamNo (ue->sref, pno);
1387 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1389 sRefSet_allElements (sr, el)
1391 sRef base = sRef_getRootBase (el);
1393 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1394 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1396 if (!globSet_member (ue->info->fcn->globs, base))
1398 if (uentry_hasGlobs (ue)
1399 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1402 (FLG_WARNMISSINGGLOBALS,
1404 ("Modifies list for %q uses global %q, "
1405 "not included in globals list.",
1406 uentry_getName (ue),
1407 sRef_unparse (base)),
1408 uentry_whereLast (ue)))
1410 uentry_showWhereSpecified (ue);
1414 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1416 if (sRef_isFileStatic (base))
1418 context_recordFileGlobals (ue->info->fcn->globs);
1422 } end_sRefSet_allElements;
1426 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1428 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1432 uentry_fixupSref (uentry ue)
1436 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1441 sr = uentry_getSref (ue);
1443 sRef_resetState (sr);
1444 sRef_clearDerived (sr);
1446 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1447 llassert (sRef_isValid (sr));
1449 if (uentry_isVariable (ue))
1452 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1453 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1454 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1458 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1461 ** Okay to allow multiple clauses of the same kind.
1462 */ /*@i834 is this true?@*/
1464 ue->info->fcn->specclauses =
1465 stateClauseList_add (ue->info->fcn->specclauses, sc);
1467 /* Will call checkAll to check later... */
1470 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1472 llassert (uentry_isFunction (ue));
1473 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1475 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1476 ue->info->fcn->specclauses = clauses;
1477 stateClauseList_checkAll (ue);
1478 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1482 ** Used for @modifies@ @endmodifies@ syntax.
1484 ** If ue is specified, sr must contain *only*:
1486 ** o file static globals
1487 ** o sRef's derived from modifies spec (i.e., more specific than
1488 ** what was specified)
1490 ** Otherwise, if sr has modifies it must match sr.
1492 ** If it doesn't have modifies, set them to sr.
1496 uentry_checkModifiesContext (void)
1498 if (sRef_modInFunction ())
1502 ("Modifies list not in function context. "
1503 "A modifies list can only appear following the parameter list "
1504 "in a function declaration or header."));
1513 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1515 if (!uentry_checkModifiesContext ())
1521 if (uentry_isValid (ue))
1523 if (uentry_isIter (ue))
1525 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1526 ue->info->iter->mods = sr;
1530 uentry_convertVarFunction (ue);
1531 llassertfatal (uentry_isFunction (ue));
1532 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1534 ue->info->fcn->mods = sr;
1535 ue->info->fcn->hasMods = TRUE;
1537 checkGlobalsModifies (ue, sr);
1540 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1542 ue->info->fcn->hasGlobs = TRUE;
1545 if (sRefSet_hasStatic (ue->info->fcn->mods))
1547 context_recordFileModifies (ue->info->fcn->mods);
1557 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1560 ** Function already has one modifies clause (possibly from
1561 ** a specification).
1564 if (!uentry_checkModifiesContext ())
1569 llassert (uentry_isValid (ue));
1571 if (uentry_isIter (ue))
1573 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1577 llassertfatal (uentry_isFunction (ue));
1578 llassert (ue->info->fcn->hasMods);
1580 checkGlobalsModifies (ue, sr);
1581 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1583 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1585 ue->info->fcn->hasGlobs = TRUE;
1589 if (sRefSet_hasStatic (ue->info->fcn->mods))
1591 context_recordFileModifies (ue->info->fcn->mods);
1595 bool uentry_hasWarning (uentry ue)
1597 return (uentry_isValid (ue)
1598 && warnClause_isDefined (ue->warn));
1601 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1603 llassert (uentry_isValid (ue));
1604 llassert (warnClause_isUndefined (ue->warn));
1609 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1611 if (sRef_modInFunction ())
1614 (message ("Precondition list not in function context. "
1615 "A precondition list can only appear following the parameter list "
1616 "in a function declaration or header."));
1618 /*@-mustfree@*/ return; /*@=mustfree@*/
1621 if (uentry_isValid (ue))
1623 uentry_convertVarFunction (ue);
1624 llassertfatal (uentry_isFunction (ue));
1626 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1629 I changed this so it didn't appear as a Splint bug
1630 among other things this gets triggered when there is
1631 a function with two requires clauses. Now Splint
1632 prints an error and tries to conjoin the lists.
1635 (message ("Duplicate precondition list"
1636 "Attemping the conjoin the requires clauses"
1640 /* should conjoin constraints? */
1642 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1646 ue->info->fcn->preconditions = preconditions;
1651 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1660 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1662 if (sRef_modInFunction ())
1665 (message ("Postcondition list not in function context. "
1666 "A postcondition list can only appear following the parameter list "
1667 "in a function declaration or header."));
1669 /*@-mustfree@*/ return; /*@=mustfree@*/
1672 if (uentry_isValid (ue))
1674 uentry_convertVarFunction (ue);
1675 llassertfatal (uentry_isFunction (ue));
1677 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1679 ue->info->fcn->postconditions = postconditions;
1683 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1688 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1693 ** requires: new and old are functions
1697 checkGlobalsConformance (/*@notnull@*/ uentry old,
1698 /*@notnull@*/ uentry unew,
1699 bool mustConform, bool completeConform)
1701 bool hasInternalState = FALSE;
1703 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1705 if (globSet_isDefined (unew->info->fcn->globs))
1707 globSet_allElements (unew->info->fcn->globs, el)
1709 if (sRef_isFileStatic (el))
1711 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1713 if (sRef_isInvalid (sr))
1715 bool hasError = FALSE;
1717 if (!hasInternalState
1718 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1719 sRef_makeInternalState ()))
1720 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1721 sRef_makeSpecState ())))
1724 && !uentry_isStatic (old)
1727 message ("Globals list for %q includes internal state, %q, "
1728 "but %s without globals internalState.",
1729 uentry_getName (old),
1731 uentry_specOrDefName (old)),
1732 uentry_whereLast (unew)))
1734 uentry_showWhereSpecified (old);
1738 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1739 sRef_makeInternalState ());
1740 hasInternalState = TRUE;
1744 && fileloc_sameFile (uentry_whereDeclared (unew),
1745 uentry_whereDeclared (old)))
1750 message ("Function %q inconsistently %rdeclared (in "
1751 "same file) with file static global %q in "
1753 uentry_getName (unew),
1754 uentry_isDeclared (old),
1756 uentry_whereDeclared (unew)))
1758 uentry_showWhereSpecified (old);
1763 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1764 context_recordFileGlobals (old->info->fcn->globs);
1768 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1770 if (sRef_isInvalid (sr))
1775 message ("Function %q inconsistently %rdeclared with "
1776 "%q in globals list",
1777 uentry_getName (unew),
1778 uentry_isDeclared (old),
1780 uentry_whereDeclared (unew)))
1782 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1783 uentry_showWhereSpecified (old);
1788 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1794 ("Function %q global %q inconsistently "
1795 "%rdeclared as %qout global",
1796 uentry_getName (unew),
1798 uentry_isDeclared (old),
1799 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1800 uentry_whereDeclared (unew)))
1802 uentry_showWhereSpecified (old);
1807 } end_globSet_allElements ;
1809 if (completeConform)
1811 globSet_allElements (old->info->fcn->globs, el)
1813 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1815 if (sRef_isInvalid (sr))
1818 && uentry_isReallySpecified (old)
1821 message ("Function %q specified with %q in globals list, "
1822 "but declared without %q",
1823 uentry_getName (unew),
1826 uentry_whereDeclared (unew)))
1828 uentry_showWhereSpecified (old);
1831 } end_globSet_allElements;
1836 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1838 if (uentry_isReallySpecified (old)
1841 message ("%s %q specified with globals list, but "
1842 "declared with no globals",
1843 ekind_capName (unew->ukind),
1844 uentry_getName (unew)),
1845 uentry_whereDeclared (unew)))
1848 (message ("Specification globals: %q",
1849 globSet_unparse (old->info->fcn->globs)),
1850 uentry_whereSpecified (old));
1854 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1855 old->info->fcn->globs);
1860 ** new modifies list must be included by old modifies list.
1862 ** file static state may be added to new, if old has internal.
1866 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1867 bool mustConform, bool completeConform)
1870 bool changedMods = FALSE;
1871 bool modInternal = FALSE;
1873 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1875 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1876 newMods = unew->info->fcn->mods;
1878 if (sRefSet_isEmpty (newMods))
1880 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1881 && uentry_isReallySpecified (old))
1885 message ("%s %q specified with modifies clause, "
1886 "but declared with no modifies clause",
1887 ekind_capName (unew->ukind),
1888 uentry_getName (unew)),
1889 uentry_whereDeclared (unew)))
1891 llgenindentmsg (message ("Specification has modifies %q",
1892 sRefSet_unparse (old->info->fcn->mods)),
1893 uentry_whereSpecified (old));
1900 sRefSet_allElements (newMods, current)
1902 if (sRef_isValid (current))
1904 sRef rb = sRef_getRootBase (current);
1906 if (sRef_isFileStatic (rb))
1910 if (!sRefSet_isSameMember (old->info->fcn->mods,
1911 sRef_makeInternalState ())
1912 && !sRefSet_isSameMember (old->info->fcn->mods,
1913 sRef_makeSpecState ()))
1916 && !uentry_isStatic (old)
1920 ("Modifies list for %q includes internal state, "
1921 "but %s without modifies internal.",
1922 uentry_getName (old),
1923 uentry_specOrDefName (old)),
1924 uentry_whereLast (unew)))
1926 uentry_showWhereSpecified (old);
1929 old->info->fcn->mods =
1930 sRefSet_insert (old->info->fcn->mods,
1931 sRef_makeInternalState ());
1936 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1942 if (sRef_canModifyVal (current, old->info->fcn->mods))
1944 int size = sRefSet_size (old->info->fcn->mods);
1946 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1949 if (sRefSet_size (old->info->fcn->mods) != size)
1960 ("Modifies list for %q contains %q, not modifiable "
1962 uentry_getName (old),
1963 sRef_unparse (current),
1964 uentry_specDeclName (old)),
1965 uentry_whereLast (unew)))
1967 uentry_showWhereSpecified (old);
1972 } end_sRefSet_allElements;
1974 if (completeConform && uentry_isReallySpecified (old))
1976 sRefSet_allElements (old->info->fcn->mods, el)
1978 if (sRef_canModify (el, newMods))
1987 ("Specification modifies clause for %q contains %q, "
1988 "not included in declaration modifies clause",
1989 uentry_getName (old),
1991 uentry_whereLast (unew)))
1993 uentry_showWhereSpecified (old);
1996 } end_sRefSet_allElements ;
2000 ** Make sure file static elements will be removed.
2005 context_recordFileModifies (old->info->fcn->mods);
2010 uentry_checkMutableType (uentry ue)
2012 ctype ct = uentry_getType (ue);
2014 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2016 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2018 voptgenerror (FLG_MUTREP,
2019 message ("Mutable abstract type %q declared without pointer "
2020 "indirection: %t (violates assignment semantics)",
2021 uentry_getName (ue), ct),
2022 uentry_whereDeclared (ue));
2027 uentry_setMutable (uentry e)
2029 llassert (uentry_isDatatype (e));
2030 e->info->datatype->mut = YES;
2034 uentry_checkIterArgs (uentry ue)
2036 bool hasYield = FALSE;
2039 llassert (uentry_isIter (ue));
2041 args = uentry_getParams (ue);
2043 uentryList_elements (args, el)
2045 sstate ds = uentry_getDefState (el);
2047 if (uentry_isYield (el))
2052 if (sstate_isUnknown (ds))
2054 uentry_setDefState (el, SS_DEFINED);
2060 } end_uentryList_elements;
2064 voptgenerror (FLG_HASYIELD,
2065 message ("Iterator %q declared with no yield parameters",
2066 uentry_getName (ue)),
2067 uentry_whereDeclared (ue));
2072 chkind_fromQual (qual qel)
2074 if (qual_isChecked (qel))
2078 else if (qual_isCheckMod (qel))
2082 else if (qual_isCheckedStrict (qel))
2084 return CH_CHECKEDSTRICT;
2086 else if (qual_isUnchecked (qel))
2088 return CH_UNCHECKED;
2093 /*@notreached@*/ return CH_UNKNOWN;
2098 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2100 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2102 if (!uentry_isRefCounted (ue))
2105 (FLG_ANNOTATIONERROR,
2106 message ("Reference counting qualifier %s used on non-reference "
2107 "counted storage: %q",
2109 uentry_unparse (ue)),
2110 uentry_whereLast (ue));
2114 alkind ak = alkind_fromQual (qel);
2116 uentry_setAliasKind (ue, ak);
2119 else if (qual_isRefCounted (qel))
2121 ctype ct = ctype_realType (uentry_getType (ue));
2124 if (ctype_isPointer (ct)
2125 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2127 /* check there is a refs field */
2128 uentryList fields = ctype_getFields (rt);
2129 uentry refs = uentry_undefined;
2131 uentryList_elements (fields, field)
2133 if (uentry_isRefsField (field))
2135 if (uentry_isValid (refs))
2138 (FLG_ANNOTATIONERROR,
2139 message ("Reference counted structure type %s has "
2140 "multiple refs fields: %q and %q",
2142 uentry_getName (refs),
2143 uentry_getName (field)),
2144 uentry_whereLast (field));
2149 } end_uentryList_elements;
2151 if (uentry_isInvalid (refs))
2155 message ("Reference counted structure type %s has "
2157 ctype_unparse (ct)),
2159 ("To count reference, the structure must have a field named "
2160 "refs of type int."),
2163 else if (!ctype_isInt (uentry_getType (refs)))
2166 (FLG_ANNOTATIONERROR,
2167 message ("Reference counted structure type %s refs field has "
2168 "type %s (should be int)", ctype_unparse (ct),
2169 ctype_unparse (uentry_getType (refs))),
2170 uentry_whereLast (refs));
2174 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2175 uentry_whereDeclared (ue));
2180 if ((ctype_isPointer (ct)
2181 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2182 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2184 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2185 uentry_whereDeclared (ue));
2190 (FLG_ANNOTATIONERROR,
2191 message ("Non-pointer to structure type %s declared with "
2192 "refcounted qualifier",
2193 ctype_unparse (ct)),
2194 uentry_whereLast (ue));
2198 else if (qual_isRefs (qel))
2200 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2202 uentry_setAliasKind (ue, AK_REFS);
2207 (FLG_ANNOTATIONERROR,
2208 message ("Refs qualifier used on non-structure field: %q",
2209 uentry_unparse (ue)),
2210 uentry_whereLast (ue));
2213 else if (qual_isAliasQual (qel))
2215 alkind ak = alkind_fromQual (qel);
2217 alkind oldak = uentry_getAliasKind (ue);
2218 ctype ut = uentry_getType (ue);
2220 if (alkind_isImplicit (ak)
2221 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2223 /* ignore the implied qualifier */
2227 if (uentry_isEitherConstant (ue))
2230 (FLG_ANNOTATIONERROR,
2231 message ("Alias qualifier %s used on constant: %q",
2232 alkind_unparse (ak), uentry_unparse (ue)),
2233 uentry_whereLast (ue));
2238 if (ctype_isFunction (ut))
2240 ut = ctype_getReturnType (ut);
2243 if (!(ctype_isVisiblySharable (ut)
2244 || ctype_isRealArray (ut)
2245 || ctype_isRealSU (ut)))
2247 if (!qual_isImplied (qel))
2250 (FLG_ANNOTATIONERROR,
2251 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2252 alkind_unparse (ak), ut, uentry_getName (ue)),
2253 uentry_whereLast (ue));
2260 if (uentry_isRefCounted (ue))
2262 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2263 || qual_isExposed (qel)
2264 || qual_isObserver (qel)))
2266 if (!qual_isImplied (qel))
2269 (FLG_ANNOTATIONERROR,
2271 ("Alias qualifier %s used on reference counted storage: %q",
2272 alkind_unparse (ak),
2273 uentry_unparse (ue)),
2274 uentry_whereLast (ue));
2282 if (qual_isRefQual (qel))
2285 (FLG_ANNOTATIONERROR,
2286 message ("Qualifier %s used on non-reference counted storage: %q",
2287 alkind_unparse (ak), uentry_unparse (ue)),
2288 uentry_whereLast (ue));
2297 uentry_setAliasKind (ue, ak);
2300 else if (qual_isNull (qel))
2302 if (uentry_isConstant (ue))
2306 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2307 uentry_whereDeclared (ue));
2311 uentry_setNullState (ue, NS_POSNULL);
2314 else if (qual_isRelNull (qel))
2316 uentry_setNullState (ue, NS_RELNULL);
2318 else if (qual_isNotNull (qel))
2320 uentry_setNullState (ue, NS_MNOTNULL);
2322 else if (qual_isAbstract (qel)
2323 || qual_isConcrete (qel))
2325 if (!uentry_isDatatype (ue))
2328 (FLG_ANNOTATIONERROR,
2329 message ("Qualifier %s used with non-datatype",
2330 qual_unparse (qel)),
2331 uentry_whereLast (ue));
2335 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2338 else if (qual_isMutable (qel))
2340 if (!uentry_isDatatype (ue))
2343 (FLG_ANNOTATIONERROR,
2344 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2345 uentry_whereLast (ue));
2349 if (!ynm_isOn (ue->info->datatype->mut))
2351 uentry_checkMutableType (ue);
2354 ue->info->datatype->mut = YES;
2357 else if (qual_isImmutable (qel))
2359 if (!uentry_isDatatype (ue))
2361 voptgenerror (FLG_ANNOTATIONERROR,
2362 message ("Qualifier %s used with non-datatype",
2363 qual_unparse (qel)),
2364 uentry_whereLast (ue));
2368 ue->info->datatype->mut = NO;
2371 else if (qual_isNullPred (qel))
2373 uentry_convertVarFunction (ue);
2375 if (uentry_isFunction (ue))
2377 ctype typ = uentry_getType (ue);
2378 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2380 if (ctype_isRealBool (rtype))
2382 uentryList pl = ctype_argsFunction (typ);
2384 if (uentryList_size (pl) == 1)
2386 ue->info->fcn->nullPred = qel;
2390 voptgenerror (FLG_ANNOTATIONERROR,
2391 message ("Qualifier %s used with function having %d "
2392 "arguments (should have 1)",
2394 uentryList_size (pl)),
2395 uentry_whereLast (ue));
2400 voptgenerror (FLG_ANNOTATIONERROR,
2401 message ("Qualifier %s used with function returning %s "
2402 "(should return bool)",
2404 ctype_unparse (rtype)),
2405 uentry_whereLast (ue));
2410 voptgenerror (FLG_ANNOTATIONERROR,
2411 message ("Qualifier %s used with non-function",
2412 qual_unparse (qel)),
2413 uentry_whereLast (ue));
2416 else if (qual_isExitQual (qel))
2418 exitkind exk = exitkind_fromQual (qel);
2420 if (uentry_isFunction (ue))
2422 if (exitkind_isKnown (ue->info->fcn->exitCode))
2424 voptgenerror (FLG_ANNOTATIONERROR,
2425 message ("Multiple exit qualifiers used on function %q: %s, %s",
2426 uentry_getName (ue),
2427 exitkind_unparse (ue->info->fcn->exitCode),
2428 exitkind_unparse (exk)),
2429 uentry_whereLast (ue));
2432 ue->info->fcn->exitCode = exk;
2436 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2438 uentry_makeVarFunction (ue);
2439 ue->info->fcn->exitCode = exk;
2443 voptgenerror (FLG_ANNOTATIONERROR,
2444 message ("Exit qualifier %s used with non-function (type %s)",
2446 ctype_unparse (uentry_getType (ue))),
2447 uentry_whereLast (ue));
2451 else if (qual_isMetaState (qel))
2453 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2455 if (annotationInfo_matchesContext (ainfo, ue))
2457 DPRINTF (("Reflecting %s on %s",
2458 annotationInfo_unparse (ainfo),
2459 uentry_unparseFull (ue)));
2461 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2462 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2463 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2468 (FLG_ANNOTATIONERROR,
2469 message ("Attribute annotation %s used in inconsistent context: %q",
2471 uentry_unparse (ue)),
2472 uentry_whereLast (ue)))
2474 /*@i! annotationInfo_showContextError (ainfo, ue); */
2480 if (qual_isCQual (qel))
2486 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2492 uentry_reflectQualifiers (uentry ue, qualList q)
2494 llassert (uentry_isValid (ue));
2496 DPRINTF (("Reflect qualifiers: %s / %s",
2497 uentry_unparseFull (ue), qualList_unparse (q)));
2499 qualList_elements (q, qel)
2501 if (qual_isStatic (qel))
2503 uentry_setStatic (ue);
2505 else if (qual_isUnused (qel))
2507 uentry_setUsed (ue, fileloc_undefined);
2508 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2510 else if (qual_isExternal (qel))
2512 fileloc_free (ue->whereDefined);
2513 ue->whereDefined = fileloc_createExternal ();
2515 else if (qual_isSef (qel))
2517 if (uentry_isVariable (ue))
2519 vkind vk = ue->info->var->kind;
2521 llassert (vk != VKREFPARAM);
2523 if (vk == VKYIELDPARAM)
2526 (FLG_ANNOTATIONERROR,
2527 message ("Qualifier sef cannot be used with %s: %q",
2528 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2529 uentry_unparse (ue)),
2530 uentry_whereLast (ue));
2532 else if (vk == VKRETPARAM)
2534 ue->info->var->kind = VKSEFRETPARAM;
2538 ue->info->var->kind = VKSEFPARAM;
2544 (FLG_ANNOTATIONERROR,
2545 message ("Qualifier sef is meaningful only on parameters: %q",
2546 uentry_unparse (ue)),
2547 uentry_whereLast (ue));
2550 else if (qual_isExtern (qel))
2552 ue->storageclass = SCEXTERN;
2554 else if (qual_isGlobalQual (qel)) /* undef, killed */
2556 DPRINTF (("Reflecting qual: %s / %s",
2557 qual_unparse (qel), uentry_unparse (ue)));
2559 if (uentry_isVariable (ue))
2561 sstate oldstate = ue->info->var->defstate;
2562 sstate defstate = sstate_fromQual (qel);
2565 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2566 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2568 defstate = SS_UNDEFKILLED;
2575 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2576 ue->info->var->defstate = defstate;
2581 (FLG_ANNOTATIONERROR,
2582 message ("Qualifier %s used on non-variable: %q",
2583 qual_unparse (qel), uentry_unparse (ue)),
2584 uentry_whereLast (ue));
2587 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2589 /* start modifications */
2590 else if( qual_isBufQualifier(qel) ) {
2591 ctype ct = ctype_realType(uentry_getType(ue));
2592 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2594 if( uentry_hasBufStateInfo(ue) ) {
2595 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2597 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2598 /* If formal func param */
2599 uentry_setNullTerminatedState(ue);
2600 uentry_setLen (ue, 1);
2601 uentry_setSize (ue, 1);
2603 sRef_setNullTerminatedState(uentry_getSref(ue));
2604 sRef_setLen (uentry_getSref(ue), 1);
2605 sRef_setSize (uentry_getSref(ue), 1);
2607 uentry_setPossiblyNullTerminatedState(ue);
2609 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2613 /* put other BufState Qualifiers here */
2615 cstring s = uentry_getName(ue);
2616 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2617 struct for identifier %s\n", s) );
2619 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2621 sRef retSref = uentry_getSref (ue);
2622 ctype retType = sRef_getType (retSref);
2624 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2625 sRef_setNullTerminatedState (retSref);
2631 message ("Qualifier %s used on non-pointer on \
2632 function return: %q", qual_unparse (qel),
2633 uentry_unparse (ue)));
2640 message ("Qualifier %s used on non-pointer: %q",
2641 qual_unparse (qel), uentry_unparse (ue)));
2643 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2645 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2647 ctype realType = ctype_realType (ue->utype);
2648 sstate defstate = sstate_fromQual (qel);
2650 if (ctype_isFunction (realType))
2652 realType = ctype_realType (ctype_getReturnType (realType));
2655 if (qual_isRelDef (qel))
2657 ; /* okay anywhere */
2661 if (!ctype_isAP (realType)
2662 && !ctype_isSU (realType)
2663 && !ctype_isUnknown (realType)
2664 && !ctype_isAbstract (ue->utype))
2667 (FLG_ANNOTATIONERROR,
2668 message ("Qualifier %s used on non-pointer or struct: %q",
2669 qual_unparse (qel), uentry_unparse (ue)),
2670 uentry_whereLast (ue));
2674 uentry_setDefState (ue, defstate);
2676 if (sRef_isStateSpecial (ue->sref)
2677 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2679 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2682 else if (qual_isYield (qel))
2684 if (uentry_isVariable (ue))
2686 ue->info->var->kind = VKYIELDPARAM;
2691 (FLG_ANNOTATIONERROR,
2692 message ("Qualifier %s used on non-iterator parameter: %q",
2693 qual_unparse (qel), uentry_unparse (ue)),
2694 uentry_whereLast (ue));
2697 else if (qual_isExQual (qel))
2699 exkind ek = exkind_fromQual (qel);
2700 ctype ut = uentry_getType (ue);
2702 DPRINTF (("Reflect ex qual: %s / %s",
2703 uentry_unparse (ue), exkind_unparse (ek)));
2705 if (ctype_isFunction (ut))
2707 ut = ctype_getReturnType (ut);
2710 if (!(ctype_isVisiblySharable (ut))
2711 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2712 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2714 if (!qual_isImplied (qel))
2716 if (ctype_isImmutableAbstract (ut)) {
2718 (FLG_REDUNDANTSHAREQUAL,
2719 message ("Qualifier %s used on unsharable storage type %t: %q",
2720 exkind_unparse (ek), ut, uentry_getName (ue)),
2721 uentry_whereLast (ue));
2724 (FLG_MISPLACEDSHAREQUAL,
2725 message ("Qualifier %s used on unsharable storage type %t: %q",
2726 exkind_unparse (ek), ut, uentry_getName (ue)),
2727 uentry_whereLast (ue));
2733 alkind ak = sRef_getAliasKind (ue->sref);
2735 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2736 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2738 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2740 if (!alkind_isTemp (ak))
2742 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2743 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2746 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2747 || alkind_isOwned (ak))
2755 message ("Exposure qualifier %s used on %s storage (should "
2756 "be dependent): %q",
2758 alkind_unparse (ak),
2759 uentry_unparse (ue)));
2763 else if (qual_isGlobCheck (qel))
2765 if (uentry_isVariable (ue))
2767 chkind ch = chkind_fromQual (qel);
2769 if (ue->info->var->checked != CH_UNKNOWN)
2771 if (ch == ue->info->var->checked)
2773 llerror (FLG_SYNTAX,
2774 message ("Redundant %s qualifier on %q",
2776 uentry_getName (ue)));
2780 llerror (FLG_SYNTAX,
2782 ("Contradictory %s and %s qualifiers on %q",
2784 checkedName (ue->info->var->checked),
2785 uentry_getName (ue)));
2789 ue->info->var->checked = ch;
2795 message ("Qualifier %s used with non-variable",
2796 qual_unparse (qel)));
2799 else if (qual_isReturned (qel))
2801 if (uentry_isVariable (ue))
2803 ue->info->var->kind = VKRETPARAM;
2807 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2808 qual_unparse (qel)));
2813 uentry_reflectOtherQualifier (ue, qel);
2816 sRef_storeState (ue->sref);
2817 } end_qualList_elements;
2821 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2825 uentry_isOnly (uentry ue)
2827 return (!uentry_isUndefined (ue)
2828 && uentry_isVariable (ue)
2829 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2833 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2835 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2836 sRef_setOrigAliasKind (ue->sref, ak);
2840 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2842 if (uentry_isVariable (ue))
2844 ue->info->var->nullstate = ns;
2847 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2851 uentry_isUnique (uentry ue)
2853 return (!uentry_isUndefined (ue)
2854 && uentry_isVariable (ue)
2855 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2859 uentry_isFileStatic (uentry ue)
2861 return (uentry_isStatic (ue)
2862 && (!uentry_isVariable (ue)
2863 || sRef_isFileStatic (uentry_getSref (ue))));
2867 uentry_isExported (uentry ue)
2869 if (uentry_isValid (ue))
2871 if (uentry_isVariable (ue))
2873 return (sRef_isRealGlobal (uentry_getSref (ue)));
2877 return !uentry_isStatic (ue);
2885 uentry_isNonLocal (uentry ue)
2887 return (uentry_isValid (ue) && uentry_isVariable (ue)
2888 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2892 uentry_isGlobalVariable (uentry ue)
2894 return (uentry_isValid (ue) && uentry_isVariable (ue)
2895 && sRef_isFileOrGlobalScope (ue->sref));
2899 uentry_isVisibleExternally (uentry ue)
2901 return (uentry_isValid (ue)
2902 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2903 || (!uentry_isStatic (ue)
2904 && (uentry_isFunction (ue)
2905 || uentry_isIter (ue)
2906 || uentry_isEndIter (ue)
2907 || uentry_isConstant (ue)
2908 || uentry_isDatatype (ue)
2909 || uentry_isAnyTag (ue)))));
2913 uentry_isPrintfLike (uentry ue)
2915 return (uentry_isFunction (ue)
2916 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2920 uentry_isScanfLike (uentry ue)
2922 return (uentry_isFunction (ue)
2923 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2927 uentry_isMessageLike (uentry ue)
2929 return (uentry_isFunction (ue)
2930 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2933 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2935 uentryList args = uentry_getParams (ue);
2937 if (!uentryList_isMissingParams (args))
2939 uentry last = uentry_undefined;
2941 uentryList_elements (args, current)
2943 if (uentry_isElipsisMarker (current))
2945 if (uentry_isUndefined (last))
2949 message ("Function %q is marked %s, but has no format "
2950 "string argument before elipsis",
2951 uentry_getName (ue),
2952 specCode_unparse (ue->info->fcn->specialCode)),
2953 uentry_whereLast (ue));
2954 ue->info->fcn->specialCode = SPC_NONE;
2958 ctype rt = ctype_realType (uentry_getType (last));
2960 if (!ctype_match (rt, ctype_string))
2964 /* wchar_t * is okay too */
2965 if (ctype_isAP (rt))
2967 ctype base = ctype_baseArrayPtr (rt);
2969 if (ctype_isArbitraryIntegral (base))
2979 message ("Function %q is marked %s, but the argument "
2980 "before the elipsis has type %s (should be char *)",
2981 uentry_getName (ue),
2982 specCode_unparse (ue->info->fcn->specialCode),
2983 ctype_unparse (uentry_getType (last))),
2984 uentry_whereLast (ue));
2986 ue->info->fcn->specialCode = SPC_NONE;
2993 } end_uentryList_elements ;
2997 message ("Function %q is marked %s, but has no elipsis parameter",
2998 uentry_getName (ue),
2999 specCode_unparse (ue->info->fcn->specialCode)),
3000 uentry_whereLast (ue));
3002 ue->info->fcn->specialCode = SPC_NONE;
3007 uentry_setPrintfLike (uentry ue)
3009 uentry_convertVarFunction (ue);
3010 llassertfatal (uentry_isFunction (ue));
3011 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3012 checkSpecialFunction (ue);
3016 uentry_setScanfLike (uentry ue)
3018 uentry_convertVarFunction (ue);
3019 llassertfatal (uentry_isFunction (ue));
3020 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3021 checkSpecialFunction (ue);
3025 uentry_setMessageLike (uentry ue)
3027 uentry_convertVarFunction (ue);
3028 llassertfatal (uentry_isFunction (ue));
3029 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3030 checkSpecialFunction (ue);
3034 uentry_isSpecialFunction (uentry ue)
3036 return (uentry_isFunction (ue)
3037 && (ue->info->fcn->specialCode != SPC_NONE));
3040 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3042 ctype ct = idDecl_getCtype (t);
3044 fileloc loc = setLocation ();
3045 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3046 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3048 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3049 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3050 uentry_implicitParamAnnots (ue);
3052 /* Parameter type [][] or [x][] is invalid */
3054 while (ctype_isFixedArray (base)) {
3055 base = ctype_baseArrayPtr (base);
3058 if (ctype_isIncompleteArray (base)) {
3059 base = ctype_baseArrayPtr (base);
3061 if (ctype_isArray (base)) {
3062 if (!uentry_hasName (ue)) {
3063 (void) optgenerror (FLG_INCOMPLETETYPE,
3064 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3066 ctype_unparse (ct)),
3067 uentry_whereLast (ue));
3069 (void) optgenerror (FLG_INCOMPLETETYPE,
3070 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3071 uentry_getName (ue),
3072 ctype_unparse (ct)),
3073 uentry_whereLast (ue));
3078 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3082 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3084 ctype ct = idDecl_getCtype (t);
3086 if (ctype_isFunction (ct))
3088 return (uentry_makeIdFunction (t));
3092 fileloc loc = setLocation ();
3093 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3095 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3097 if (!uentry_isExtern (ue))
3099 uentry_setDefined (ue, loc);
3107 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3109 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3117 static /*@only@*/ /*@notnull@*/
3118 uentry uentry_makeConstantAux (cstring n, ctype t,
3119 /*@keep@*/ fileloc f, bool priv, bool macro,
3120 /*@only@*/ multiVal m)
3122 uentry e = uentry_alloc ();
3125 e->uname = cstring_copy (n);
3127 e->storageclass = SCNONE;
3129 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3131 e->sref = sRef_makeConst (t);
3136 e->uses = filelocList_new ();
3137 e->isPrivate = priv;
3138 e->hasNameError = FALSE;
3140 e->info = (uinfo) dmalloc (sizeof (*e->info));
3141 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3142 e->info->uconst->access = typeIdSet_undefined;
3143 e->info->uconst->macro = macro;
3145 uentry_setSpecDef (e, f);
3147 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3149 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3152 uentry_setConstantValue (e, m);
3157 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3159 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3163 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3165 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3169 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3171 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3175 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3177 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3178 idDecl_getCtype (t),
3181 llassert (fileloc_isUndefined (ue->whereDeclared));
3182 ue->whereDeclared = setLocation ();
3183 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3185 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3186 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3194 void uentry_setDefState (uentry ue, sstate defstate)
3196 if (uentry_isValid (ue))
3198 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3200 if (uentry_isVariable (ue))
3202 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3207 bool uentry_isCheckedUnknown (uentry ue)
3209 return (uentry_isVar (ue)
3210 && (ue->info->var->checked == CH_UNKNOWN));
3213 bool uentry_isCheckMod (uentry ue)
3215 return (uentry_isVar (ue)
3216 && (ue->info->var->checked == CH_CHECKMOD));
3219 bool uentry_isUnchecked (uentry ue)
3221 return (uentry_isVar (ue)
3222 && (ue->info->var->checked == CH_UNCHECKED));
3225 bool uentry_isChecked (uentry ue)
3227 return (uentry_isVar (ue)
3228 && (ue->info->var->checked == CH_CHECKED));
3231 bool uentry_isCheckedModify (uentry ue)
3233 return (uentry_isVar (ue)
3234 && (ue->info->var->checked == CH_CHECKED
3235 || ue->info->var->checked == CH_CHECKMOD
3236 || ue->info->var->checked == CH_CHECKEDSTRICT));
3239 bool uentry_isCheckedStrict (uentry ue)
3241 return (uentry_isVar (ue)
3242 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3245 void uentry_setUnchecked (uentry ue)
3247 llassert (uentry_isVar (ue));
3249 ue->info->var->checked = CH_UNCHECKED;
3252 void uentry_setChecked (uentry ue)
3254 llassert (uentry_isVar (ue));
3256 ue->info->var->checked = CH_CHECKED;
3259 void uentry_setCheckMod (uentry ue)
3261 llassert (uentry_isVar (ue));
3263 ue->info->var->checked = CH_CHECKMOD;
3266 void uentry_setCheckedStrict (uentry ue)
3268 llassert (uentry_isVar (ue));
3270 ue->info->var->checked = CH_CHECKEDSTRICT;
3273 static /*@only@*/ /*@notnull@*/
3274 uentry uentry_makeVariableAux (cstring n, ctype t,
3276 /*@exposed@*/ sRef s,
3277 bool priv, vkind kind)
3279 uentry e = uentry_alloc ();
3282 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3285 e->uname = cstring_copy (n);
3288 e->storageclass = SCNONE;
3290 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3297 e->uses = filelocList_new ();
3298 e->isPrivate = priv;
3299 e->hasNameError = FALSE;
3301 e->info = (uinfo) dmalloc (sizeof (*e->info));
3302 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3303 e->info->var->kind = kind;
3305 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3306 e->info->var->checked = CH_UNKNOWN;
3308 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3309 uentry_setSpecDef (e, f);
3310 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3312 if (ctype_isFunction (rt))
3314 rt = ctype_getReturnType (rt);
3317 if (ctype_isUA (rt))
3319 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3320 sRef_setStateFromType (e->sref, rt);
3323 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3324 e->info->var->defstate = sRef_getDefState (e->sref);
3325 e->info->var->nullstate = sRef_getNullState (e->sref);
3327 /* start modifications */
3328 /* This function sets the uentry for a pointer or array variable declaration,
3329 it allocates memory and sets the fields. We check if the type of the variable
3330 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3332 if (ctype_isArray (t) || ctype_isPointer(t))
3334 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3335 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3336 sRef_setNotNullTerminatedState (s);
3340 e->info->var->bufinfo = NULL;
3342 /* end modification */
3348 uentry_isYield (uentry ue)
3350 return (uentry_isVariable (ue)
3351 && (ue->info->var->kind == VKYIELDPARAM
3352 || ue->info->var->kind == VKREFYIELDPARAM));
3356 uentry_isRefsField (uentry ue)
3358 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3361 /*@only@*/ /*@notnull@*/
3362 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3364 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3365 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3372 void uentry_makeVarFunction (uentry ue)
3379 llassert (uentry_isValid (ue));
3380 llassert (!sRef_modInFunction ());
3382 ak = sRef_getOrigAliasKind (ue->sref);
3383 ek = sRef_getOrigExKind (ue->sref);
3385 llassert (uentry_isVariable (ue));
3386 oldInfo = ue->info->var;
3388 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3389 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3392 ** expanded macro is marked used
3395 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3398 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3399 ue->info->fcn->exitCode = XK_UNKNOWN;
3400 ue->info->fcn->nullPred = qual_createUnknown ();
3401 ue->info->fcn->specialCode = SPC_NONE;
3402 ue->info->fcn->access = typeIdSet_undefined;
3403 ue->info->fcn->hasGlobs = FALSE;
3404 ue->info->fcn->globs = globSet_undefined;
3405 ue->info->fcn->hasMods = FALSE;
3406 ue->info->fcn->mods = sRefSet_undefined;
3407 ue->info->fcn->specclauses = NULL;
3408 ue->info->fcn->defparams = uentryList_undefined;
3411 ue->info->fcn->preconditions = functionConstraint_undefined;
3415 ue->info->fcn->postconditions = functionConstraint_undefined;
3418 if (ctype_isFunction (ue->utype))
3420 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3424 ue->sref = sRef_makeType (ctype_unknown);
3427 if (sRef_isRefCounted (ue->sref))
3433 if (alkind_isUnknown (ak))
3435 if (exkind_isKnown (ek))
3437 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3438 ak = AK_IMPDEPENDENT;
3442 if (context_getFlag (FLG_RETIMPONLY))
3444 if (ctype_isFunction (ue->utype)
3445 && ctype_isVisiblySharable
3446 (ctype_realType (ctype_getReturnType (ue->utype))))
3448 if (uentryList_hasReturned (uentry_getParams (ue)))
3454 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3469 loc = ue->whereDeclared;
3471 sRef_setAliasKind (ue->sref, ak, loc);
3472 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3473 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3474 sRef_setExKind (ue->sref, ek, loc);
3476 if (oldInfo->kind == VKEXPMACRO)
3482 fileloc_free (ue->whereDefined);
3483 ue->whereDefined = fileloc_undefined;
3486 uvinfo_free (oldInfo);
3489 void uentry_makeConstantFunction (uentry ue)
3496 llassert (uentry_isValid (ue));
3497 llassert (!sRef_modInFunction ());
3499 ak = sRef_getOrigAliasKind (ue->sref);
3500 ek = sRef_getOrigExKind (ue->sref);
3502 llassert (uentry_isConstant (ue));
3503 oldInfo = ue->info->uconst;
3505 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3508 ** expanded macro is marked used (until I write a pre-processor)
3512 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3513 ue->info->fcn->exitCode = XK_UNKNOWN;
3514 ue->info->fcn->nullPred = qual_createUnknown ();
3515 ue->info->fcn->specialCode = SPC_NONE;
3516 ue->info->fcn->access = typeIdSet_undefined;
3517 ue->info->fcn->hasGlobs = FALSE;
3518 ue->info->fcn->globs = globSet_undefined;
3519 ue->info->fcn->hasMods = FALSE;
3520 ue->info->fcn->mods = sRefSet_undefined;
3521 ue->info->fcn->specclauses = NULL;
3522 ue->info->fcn->defparams = uentryList_undefined;
3525 ue->info->fcn->preconditions = functionConstraint_undefined;
3529 ue->info->fcn->postconditions = functionConstraint_undefined;
3533 if (ctype_isFunction (ue->utype))
3535 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3539 ue->sref = sRef_makeType (ctype_unknown);
3542 if (sRef_isRefCounted (ue->sref))
3548 if (alkind_isUnknown (ak))
3550 if (exkind_isKnown (ek))
3552 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3553 ak = AK_IMPDEPENDENT;
3557 if (context_getFlag (FLG_RETIMPONLY))
3559 if (ctype_isFunction (ue->utype)
3560 && ctype_isVisiblySharable
3561 (ctype_realType (ctype_getReturnType (ue->utype))))
3563 if (uentryList_hasReturned (uentry_getParams (ue)))
3569 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3584 loc = ue->whereDeclared;
3586 sRef_setAliasKind (ue->sref, ak, loc);
3587 sRef_setExKind (ue->sref, ek, loc);
3589 fileloc_free (ue->whereDefined);
3590 ue->whereDefined = fileloc_undefined;
3591 ucinfo_free (oldInfo);
3595 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3597 llassert (uentry_isValid (ue));
3599 if (uentry_isIter (ue))
3601 llassert (globSet_isUndefined (ue->info->iter->globs));
3602 ue->info->iter->globs = globs;
3606 uentry_convertVarFunction (ue);
3608 llassert (uentry_isFunction (ue));
3609 llassert (!ue->info->fcn->hasGlobs
3610 && globSet_isUndefined (ue->info->fcn->globs));
3612 ue->info->fcn->hasGlobs = TRUE;
3613 globSet_markImmutable (globs);
3614 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3619 /* ??? - evans 2001-09-09 not sure what's going on here...?
3620 if (globSet_hasStatic (globs))
3622 context_recordFileGlobals (globs);
3626 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3628 ue->info->fcn->hasMods = TRUE;
3632 void uentry_addAccessType (uentry ue, typeId tid)
3634 if (uentry_isFunction (ue))
3636 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3638 else if (uentry_isEitherConstant (ue))
3640 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3642 else if (uentry_isIter (ue))
3644 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3646 else if (uentry_isEndIter (ue))
3648 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3652 llbug (message ("no access for: %q", uentry_unparse (ue)));
3656 /*@only@*/ /*@notnull@*/ uentry
3657 uentry_makeFunction (cstring n, ctype t,
3659 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3660 /*@only@*/ warnClause warn,
3663 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3664 return (uentry_makeFunctionAux (n, t,
3665 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3666 : typeIdSet_single (access)),
3673 /*@notnull@*/ uentry
3674 uentry_makePrivFunction2 (cstring n, ctype t,
3676 globSet globs, sRefSet mods,
3679 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3684 /*@notnull@*/ uentry
3685 uentry_makeSpecFunction (cstring n, ctype t,
3687 /*@only@*/ globSet globs,
3688 /*@only@*/ sRefSet mods,
3691 uentry ue = uentry_makeFunctionAux (n, t, access,
3692 globs, mods, warnClause_undefined,
3695 uentry_setHasGlobs (ue);
3696 uentry_setHasMods (ue);
3698 reflectImplicitFunctionQualifiers (ue, TRUE);
3703 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3705 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3706 sRef_undefined, FALSE, VKEXPMACRO);
3708 uentry_setDefined (ue, f);
3712 /*@notnull@*/ /*@notnull@*/ uentry
3713 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3715 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3716 typeIdSet_singleOpt (access),
3717 globSet_undefined, sRefSet_undefined,
3718 warnClause_undefined,
3722 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3726 bool uentry_isForward (uentry e)
3728 if (uentry_isValid (e))
3730 ctype ct = uentry_getType (e);
3732 return (ctype_isUnknown (ct)
3733 || (ctype_isFunction (ct)
3734 && ctype_isUnknown (ctype_getReturnType (ct))));
3741 /*@notnull@*/ uentry
3742 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3744 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3745 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3749 /*@notnull@*/ uentry
3750 uentry_makeUnspecFunction (cstring n, ctype t,
3754 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3755 sRefSet_undefined, warnClause_undefined,
3758 reflectImplicitFunctionQualifiers (ue, TRUE);
3767 /* is exported for use by usymtab_interface */
3769 /*@notnull@*/ uentry
3770 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3771 fileloc f, bool priv)
3773 uentry e = uentry_alloc ();
3775 DPRINTF (("Make datatype: %s / %s",
3776 n, ctype_unparse (t)));
3778 /* e->shallowCopy = FALSE; */
3779 e->ukind = KDATATYPE;
3780 e->uname = cstring_copy (n);
3782 e->storageclass = SCNONE;
3783 e->sref = sRef_makeUnknown ();
3787 sRef_setStateFromType (e->sref, t);
3790 uentry_setSpecDef (e, f);
3792 e->warn = warnClause_undefined; /*@i634@*/
3793 e->uses = filelocList_new ();
3794 e->isPrivate = priv;
3795 e->hasNameError = FALSE;
3800 e->info = (uinfo) dmalloc (sizeof (*e->info));
3801 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3802 e->info->datatype->abs = abstract;
3803 e->info->datatype->mut = mut;
3804 e->info->datatype->type = ctype_undefined;
3806 if (uentry_isDeclared (e))
3808 uentry_setDefined (e, f);
3811 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3813 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3819 /*@notnull@*/ uentry
3820 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3822 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3825 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3827 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3828 ctype_bool, NO, abstract,
3829 fileloc_getBuiltin (),
3832 ret->info->datatype->type = ctype_bool;
3840 static /*@only@*/ /*@notnull@*/ uentry
3841 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3842 /*@only@*/ fileloc f)
3844 uentry e = uentry_alloc ();
3847 e->uname = cstring_copy (n);
3849 e->sref = sRef_makeUnknown ();
3850 e->storageclass = SCNONE;
3854 uentry_setSpecDef (e, f);
3856 e->warn = warnClause_undefined; /*@i452@*/
3857 e->uses = filelocList_new ();
3858 e->isPrivate = FALSE;
3859 e->hasNameError = FALSE;
3861 e->info = (uinfo) dmalloc (sizeof (*e->info));
3862 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3863 e->info->iter->access = access;
3864 e->info->iter->mods = sRefSet_undefined;
3865 e->info->iter->globs = globSet_undefined;
3867 uentry_checkIterArgs (e);
3871 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3873 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3876 static /*@notnull@*/ uentry
3877 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3879 uentry e = uentry_alloc ();
3881 /* e->shallowCopy = FALSE; */
3882 e->ukind = KENDITER;
3883 e->storageclass = SCNONE;
3884 e->uname = message ("end_%s", n);
3885 e->utype = ctype_unknown;
3886 e->sref = sRef_makeUnknown ();
3888 uentry_setSpecDef (e, f);
3893 e->uses = filelocList_new ();
3894 e->isPrivate = FALSE;
3895 e->hasNameError = FALSE;
3897 e->info = (uinfo) dmalloc (sizeof (*e->info));
3898 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3900 e->info->enditer->access = access;
3902 e->warn = warnClause_undefined; /*@i452@*/
3906 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3908 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3915 static /*@only@*/ /*@notnull@*/ uentry
3916 uentry_makeTagAux (cstring n, ctype t,
3917 /*@only@*/ fileloc fl,
3918 bool priv, ekind kind)
3920 uentry e = uentry_alloc ();
3922 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3924 llbuglit ("uentry_makeTagAux: not a tag type");
3928 /* e->shallowCopy = FALSE; */
3929 e->uname = cstring_copy (n);
3932 e->sref = sRef_makeUnknown ();
3933 e->storageclass = SCNONE;
3935 uentry_setSpecDef (e, fl);
3940 e->uses = filelocList_new ();
3941 e->isPrivate = priv;
3942 e->hasNameError = FALSE;
3944 e->info = (uinfo) dmalloc (sizeof (*e->info));
3945 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3946 e->info->datatype->abs = NO;
3947 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3948 e->info->datatype->type = t;
3949 e->warn = warnClause_undefined; /*@i452@*/
3951 if (uentry_isDeclared (e))
3953 uentry_setDefined (e, fl);
3959 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3961 cstring sname = makeStruct (n);
3962 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3964 cstring_free (sname);
3969 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3971 cstring sname = makeStruct (n);
3972 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3974 cstring_free (sname);
3979 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3981 cstring uname = makeUnion (n);
3982 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3984 cstring_free (uname);
3990 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3992 cstring ename = makeEnum (n);
3993 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3995 cstring_free (ename);
4001 uentry_makeUnionTagLoc (cstring n, ctype t)
4003 cstring uname = makeUnion (n);
4004 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4006 cstring_free (uname);
4011 uentry_makeEnumTagLoc (cstring n, ctype t)
4013 cstring ename = makeEnum (n);
4014 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4016 cstring_free (ename);
4021 uentry_isStructTag (uentry ue)
4023 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4027 uentry_isUnionTag (uentry ue)
4029 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4033 uentry_isEnumTag (uentry ue)
4035 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4039 uentry_isAnyTag (uentry ue)
4041 return (uentry_isStructTag (ue)
4042 || uentry_isUnionTag (ue)
4043 || uentry_isEnumTag (ue));
4046 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4048 extern void uentry_destroyMod (void)
4049 /*@globals killed emarker@*/ /*@modifies emarker@*/
4051 static bool wasDestroyed = FALSE;
4053 llassert (!wasDestroyed);
4055 if (emarker != NULL)
4057 uentry_reallyFree (emarker);
4060 wasDestroyed = TRUE;
4064 uentry_makeElipsisMarker (void)
4066 if (emarker == NULL)
4068 emarker = uentry_alloc ();
4070 emarker->ukind = KELIPSMARKER;
4071 emarker->uname = cstring_makeLiteral ("...");
4072 emarker->utype = ctype_elipsMarker;
4073 emarker->sref = sRef_undefined;
4074 emarker->storageclass = SCNONE;
4075 emarker->used = FALSE;
4076 emarker->lset = FALSE;
4077 emarker->info = NULL;
4079 uentry_setSpecDef (emarker, fileloc_undefined);
4080 emarker->uses = filelocList_new ();
4081 emarker->isPrivate = FALSE;
4082 emarker->hasNameError = FALSE;
4085 /*@ignore@*/ return (emarker); /*@end@*/
4093 uentry_equiv (uentry p1, uentry p2)
4095 if (uentry_compare (p1, p2) != 0)
4106 uentry_xcomparealpha (uentry *p1, uentry *p2)
4110 if ((res = uentry_compare (*p1, *p2)) == 0) {
4111 if ((*p1 != NULL) && (*p2 != NULL)) {
4112 res = cstring_compare ((*p1)->uname,
4121 uentry_xcompareuses (uentry *p1, uentry *p2)
4126 if (uentry_isValid (u1))
4128 if (uentry_isValid (u2))
4130 return (-1 * int_compare (filelocList_size (u1->uses),
4131 filelocList_size (u2->uses)));
4140 if (uentry_isValid (u2))
4152 uentry_compareStrict (uentry v1, uentry v2)
4154 COMPARERETURN (uentry_compare (v1, v2));
4156 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4158 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4159 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4160 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4167 uentry_compare (uentry u1, uentry u2)
4169 if (u1 == u2) return 0;
4171 if (uentry_isInvalid (u1)) return -1;
4172 if (uentry_isInvalid (u2)) return 1;
4174 INTCOMPARERETURN (u1->ukind, u2->ukind);
4175 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4176 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4177 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4183 /* bug detected by splint:
4184 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4189 return (multiVal_compare (uentry_getConstantValue (u1),
4190 uentry_getConstantValue (u2)));
4194 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4196 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4197 uentry_accessType (u2)));
4198 return (uentryList_compareParams (uentry_getParams (u1),
4199 uentry_getParams (u2)));
4201 return (typeIdSet_compare (uentry_accessType (u1),
4202 uentry_accessType (u2)));
4205 ** Functions are never equivalent
4208 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4218 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4219 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4220 sRef_getOrigAliasKind (u2->sref)));
4221 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4222 sRef_getOrigExKind (u2->sref)));
4223 COMPARERETURN (generic_compare (u1->info->var->checked,
4224 u2->info->var->checked));
4225 COMPARERETURN (generic_compare (u1->info->var->defstate,
4226 u2->info->var->defstate));
4227 return (generic_compare (u1->info->var->nullstate,
4228 u2->info->var->nullstate));
4230 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4231 u2->info->datatype->type));
4232 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4233 u2->info->datatype->mut));
4234 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4243 ** all entries are: <type>[@<info>]*#<name>
4245 ** info depends on kind:
4249 advanceField (char **s)
4251 reader_checkChar (s, '@');
4255 advanceName (char **s)
4257 reader_checkChar (s, '#');
4261 vkind_fromInt (int i)
4263 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4265 llbuglit ("vkind_fromInt: out of range");
4272 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4273 typeIdSet access, nstate nullstate,
4274 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4276 uentry e = uentry_alloc ();
4281 e->sref = sRef_makeConst (ct);
4283 sRef_setNullState (e->sref, nullstate, loc);
4284 e->storageclass = SCNONE;
4286 if (fileloc_isSpec (loc))
4288 e->whereSpecified = loc;
4289 e->whereDeclared = fileloc_undefined;
4293 e->whereSpecified = fileloc_undefined;
4294 e->whereDeclared = loc;
4297 e->whereDefined = fileloc_undefined;
4298 e->uses = filelocList_new ();
4299 e->isPrivate = FALSE;
4300 e->hasNameError = FALSE;
4305 e->warn = warnClause_undefined; /*@i452@*/
4307 e->info = (uinfo) dmalloc (sizeof (*e->info));
4308 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4309 e->info->uconst->access = access;
4310 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4311 uentry_setConstantValue (e, m);
4312 sRef_storeState (e->sref);
4317 static /*@only@*/ uentry
4318 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4319 sstate defstate, nstate isnull, alkind aliased,
4320 exkind exp, chkind checked,
4321 /*@only@*/ fileloc loc)
4323 uentry e = uentry_alloc ();
4328 e->storageclass = SCNONE;
4330 e->sref = sRef_makeType (ct);
4331 sRef_setNullState (e->sref, isnull, loc);
4333 e->whereDefined = fileloc_undefined;
4335 if (fileloc_isSpec (loc))
4337 e->whereSpecified = loc;
4338 e->whereDeclared = fileloc_undefined;
4342 e->whereSpecified = fileloc_undefined;
4343 e->whereDeclared = loc;
4346 e->isPrivate = FALSE;
4347 e->hasNameError = FALSE;
4352 e->uses = filelocList_new ();
4353 e->warn = warnClause_undefined; /*@i452@*/
4355 e->info = (uinfo) dmalloc (sizeof (*e->info));
4356 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4357 e->info->var->kind = kind;
4358 e->info->var->checked = checked;
4359 e->info->var->defstate = defstate;
4361 sRef_setDefState (e->sref, defstate, loc);
4363 e->info->var->nullstate = sRef_getNullState (e->sref);
4365 sRef_setExKind (e->sref, exp, loc);
4366 sRef_setAliasKind (e->sref, aliased, loc);
4368 sRef_storeState (e->sref);
4370 /*DRL ADDED 9-1-2000 */
4371 e->info->var->bufinfo = NULL;
4376 static /*@only@*/ uentry
4377 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4378 ynm mut, ctype rtype, alkind ak, exkind exp,
4379 sstate defstate, nstate isnull,
4380 /*@only@*/ fileloc loc)
4382 uentry e = uentry_alloc ();
4384 e->ukind = KDATATYPE;
4385 /* e->shallowCopy = FALSE; */
4388 e->storageclass = SCNONE;
4389 e->sref = sRef_makeUnknown ();
4390 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4393 ** This is only setting null state. (I think?)
4396 if (ctype_isUA (ct))
4398 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4400 if (uentry_isValid (te))
4402 sRef_setStateFromUentry (e->sref, te);
4406 /* problem for recursive type definitions */
4410 sRef_setAliasKind (e->sref, ak, loc);
4411 sRef_setExKind (e->sref, exp, loc);
4413 sRef_setDefState (e->sref, defstate, loc);
4415 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4417 isnull = NS_ABSNULL;
4420 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4421 sRef_mergeNullState (e->sref, isnull);
4423 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4425 if (fileloc_isSpec (loc))
4427 e->whereSpecified = loc;
4428 e->whereDeclared = fileloc_undefined;
4432 e->whereSpecified = fileloc_undefined;
4433 e->whereDeclared = loc;
4436 e->isPrivate = FALSE;
4437 e->hasNameError = FALSE;
4439 e->warn = warnClause_undefined; /*@i452@*/
4443 e->uses = filelocList_new ();
4445 e->info = (uinfo) dmalloc (sizeof (*e->info));
4446 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4447 e->info->datatype->abs = abstract;
4448 e->info->datatype->mut = mut;
4449 e->info->datatype->type = rtype;
4451 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4452 sRef_storeState (e->sref);
4453 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4459 static void uentry_setHasGlobs (uentry ue)
4461 llassert (uentry_isFunction (ue));
4463 ue->info->fcn->hasGlobs = TRUE;
4466 static void uentry_setHasMods (uentry ue)
4468 llassert (uentry_isFunction (ue));
4470 ue->info->fcn->hasMods = TRUE;
4474 bool uentry_hasGlobs (uentry ue)
4476 if (uentry_isFunction (ue))
4478 return (ue->info->fcn->hasGlobs);
4484 bool uentry_hasStateClauseList (uentry ue)
4486 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4489 bool uentry_hasConditions (uentry ue)
4491 return (uentry_isFunction (ue)
4492 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4493 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4496 stateClauseList uentry_getStateClauseList (uentry ue)
4498 if (!uentry_isFunction (ue))
4500 llassert (uentry_isFunction (ue));
4501 return stateClauseList_undefined;
4504 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4505 return ue->info->fcn->specclauses;
4508 bool uentry_hasMods (uentry ue)
4510 if (uentry_isFunction (ue))
4512 return (ue->info->fcn->hasMods);
4519 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4521 bool hasGlobs, /*@only@*/ globSet globs,
4522 bool hasMods, /*@only@*/ sRefSet mods,
4523 alkind ak, exkind exp,
4524 sstate defstate, nstate isnull,
4528 /*@only@*/ stateClauseList specclauses,
4529 /*@only@*/ warnClause warnclause,
4530 /*@only@*/ fileloc loc)
4532 uentry e = uentry_alloc ();
4535 /* e->shallowCopy = FALSE; */
4539 e->storageclass = SCNONE;
4541 if (ctype_isFunction (ct))
4543 ret = ctype_getReturnType (ct);
4547 if (ctype_isKnown (ct))
4549 llbug (message ("not function: %s", ctype_unparse (ct)));
4552 ret = ctype_unknown;
4555 e->sref = sRef_makeType (ret);
4557 if (ctype_isUA (ret))
4559 sRef_setStateFromType (e->sref, ret);
4562 sRef_setDefined (e->sref, loc);
4563 sRef_setNullState (e->sref, isnull, loc);
4565 sRef_setAliasKind (e->sref, ak, loc);
4566 sRef_setExKind (e->sref, exp, loc);
4567 sRef_setDefState (e->sref, defstate, loc);
4569 e->whereSpecified = loc;
4570 e->whereDefined = fileloc_undefined;
4572 e->isPrivate = FALSE;
4573 e->hasNameError = FALSE;
4577 e->uses = filelocList_new ();
4578 e->warn = warnclause;
4580 e->info = (uinfo) dmalloc (sizeof (*e->info));
4581 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4583 e->info->fcn->exitCode = exitCode;
4584 e->info->fcn->specialCode = sCode;
4585 e->info->fcn->nullPred = nullPred;
4586 e->info->fcn->access = access;
4588 e->info->fcn->specclauses = specclauses;
4589 e->info->fcn->hasGlobs = hasGlobs;
4590 e->info->fcn->globs = globs;
4592 e->info->fcn->hasMods = hasMods;
4593 e->info->fcn->mods = mods;
4595 e->info->fcn->defparams = uentryList_undefined;
4596 e->whereDeclared = fileloc_undefined;
4598 sRef_storeState (e->sref);
4601 e->info->fcn->preconditions = NULL;
4605 e->info->fcn->postconditions = NULL;
4611 static /*@only@*/ uentry
4612 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4613 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4615 uentry e = uentry_alloc ();
4617 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4619 llbuglit ("uentry_makeTagBase: not a tag type");
4622 /* e->shallowCopy = FALSE; */
4626 e->sref = sRef_makeUnknown ();
4627 e->storageclass = SCNONE;
4629 if (fileloc_isSpec (loc))
4631 e->whereSpecified = loc;
4632 e->whereDeclared = fileloc_undefined;
4636 e->whereDeclared = loc;
4637 e->whereSpecified = fileloc_undefined;
4640 e->whereDefined = fileloc_undefined;
4642 e->isPrivate = FALSE;
4643 e->hasNameError = FALSE;
4647 e->uses = filelocList_new ();
4648 e->warn = warnClause_undefined; /*@i452@*/
4650 e->info = (uinfo) dmalloc (sizeof (*e->info));
4651 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4652 e->info->datatype->abs = NO;
4653 e->info->datatype->mut = MAYBE;
4654 e->info->datatype->type = rtype;
4656 sRef_storeState (e->sref);
4662 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4663 ctype ct, /*@only@*/ fileloc loc)
4665 uentry e = uentry_alloc ();
4667 /* e->shallowCopy = FALSE; */
4671 e->sref = sRef_makeUnknown ();
4672 e->storageclass = SCNONE;
4674 if (fileloc_isSpec (loc))
4676 e->whereSpecified = loc;
4677 e->whereDeclared = fileloc_undefined;
4681 e->whereDeclared = loc;
4682 e->whereSpecified = fileloc_undefined;
4685 e->whereDefined = fileloc_undefined;
4687 e->isPrivate = FALSE;
4688 e->hasNameError = FALSE;
4692 e->uses = filelocList_new ();
4693 e->warn = warnClause_undefined; /*@i452@*/
4695 e->info = (uinfo) dmalloc (sizeof (*e->info));
4696 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4697 e->info->iter->access = access;
4698 e->info->iter->mods = sRefSet_undefined;
4699 e->info->iter->globs = globSet_undefined;
4701 sRef_storeState (e->sref);
4706 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4707 /*@only@*/ fileloc loc)
4709 uentry e = uentry_alloc ();
4711 /* e->shallowCopy = FALSE; */
4712 e->ukind = KENDITER;
4713 e->storageclass = SCNONE;
4715 e->utype = ctype_unknown;
4716 e->sref = sRef_makeUnknown ();
4718 if (fileloc_isSpec (loc))
4720 e->whereSpecified = loc;
4721 e->whereDeclared = fileloc_undefined;
4725 e->whereDeclared = loc;
4726 e->whereSpecified = fileloc_undefined;
4729 e->whereDefined = fileloc_undefined;
4731 e->isPrivate = FALSE;
4732 e->hasNameError = FALSE;
4736 e->uses = filelocList_new ();
4737 e->warn = warnClause_undefined; /*@i452@*/
4739 e->info = (uinfo) dmalloc (sizeof (*e->info));
4740 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4741 e->info->enditer->access = access;
4742 sRef_storeState (e->sref);
4747 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4755 uentry_undump (ekind kind, fileloc loc, char **s)
4759 DPRINTF (("Uentry undump: %s", *s));
4763 reader_checkChar (s, '!');
4764 reader_checkChar (s, '.');
4765 ue = uentry_makeElipsisMarker ();
4769 ctype ct = ctype_undump (s);
4783 reader_checkChar (s, '|');
4785 if (reader_optCheckChar (s, '@'))
4787 tkind = vkind_fromInt (reader_getInt (s));
4788 reader_checkChar (s, '|');
4795 if (reader_optCheckChar (s, '$'))
4797 defstate = SS_UNKNOWN;
4798 isnull = NS_UNKNOWN;
4799 aliased = AK_IMPTEMP;
4801 checked = CH_UNKNOWN;
4803 else if (reader_optCheckChar (s, '&'))
4805 defstate = SS_DEFINED;
4806 isnull = NS_UNKNOWN;
4807 aliased = AK_IMPTEMP;
4809 checked = CH_UNKNOWN;
4811 else if (reader_optCheckChar (s, '^'))
4813 defstate = SS_UNKNOWN;
4814 isnull = NS_UNKNOWN;
4815 aliased = AK_IMPTEMP;
4817 checked = CH_UNKNOWN;
4821 defstate = sstate_fromInt (reader_getInt (s));
4822 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4823 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4825 if (reader_optCheckChar (s, '&'))
4828 checked = CH_UNKNOWN;
4832 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4833 advanceField (s); checked = (chkind) (reader_getInt (s));
4838 name = reader_getStringWord (s);
4840 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4842 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4843 isnull, aliased, exp,
4844 checked, fileloc_copy (loc));
4857 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4858 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4859 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4860 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4861 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4862 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4863 advanceField (s); rtype = ctype_undump (s);
4865 name = reader_getStringWord (s);
4866 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4867 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4868 aliased, exp, defstate, isnull,
4869 fileloc_copy (loc));
4886 stateClauseList specclauses = stateClauseList_undefined;
4887 warnClause warnclause = warnClause_undefined;
4889 if (reader_optCheckChar (s, '$'))
4891 defstate = SS_DEFINED;
4892 isnull = NS_UNKNOWN;
4893 exitCode = XK_UNKNOWN;
4895 nullPred = qual_createUnknown ();
4899 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4900 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4901 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4902 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4903 advanceField (s); nullPred = qual_undump (s);
4906 if (reader_optCheckChar (s, '$'))
4909 globs = globSet_undefined;
4911 mods = sRefSet_undefined;
4913 else if (reader_optCheckChar (s, '^'))
4916 globs = globSet_undefined;
4918 mods = sRefSet_undefined;
4922 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4923 advanceField (s); globs = globSet_undump (s);
4924 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4925 advanceField (s); mods = sRefSet_undump (s);
4928 if (reader_optCheckChar (s, '$'))
4935 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4936 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4939 advanceField (s); access = typeIdSet_undump (s);
4942 ** Optional clauses: Start with @<code>:
4945 while (reader_optCheckChar (s, '@'))
4947 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4949 reader_checkChar (s, ':');
4950 warnclause = warnClause_undump (s);
4952 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4954 reader_checkChar (s, ':');
4955 specclauses = stateClauseList_undump (s);
4963 advanceName (s); name = reader_getStringWord (s);
4965 ue = uentry_makeFunctionBase (name, ct, access,
4968 ak, exp, defstate, isnull,
4969 exitCode, specc, nullPred,
4972 fileloc_copy (loc));
4973 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4980 advanceField (s); access = typeIdSet_undump (s);
4981 advanceName (s); name = reader_getStringWord (s);
4983 ue = uentry_makeIterBase (name, access, ct,
4984 fileloc_copy (loc));
4991 advanceField (s); access = typeIdSet_undump (s);
4992 advanceName (s); name = reader_getStringWord (s);
4994 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5004 if (reader_optCheckChar (s, '$'))
5006 val = multiVal_undefined;
5007 access = typeIdSet_undefined;
5008 nullstate = NS_UNKNOWN;
5012 advanceField (s); val = multiVal_undump (s);
5013 advanceField (s); access = typeIdSet_undump (s);
5014 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5017 advanceName (s); name = reader_getStringWord (s);
5019 ue = uentry_makeConstantBase (name, ct, access,
5020 nullstate, fileloc_copy (loc), val);
5029 advanceField (s); rtype = ctype_undump (s);
5030 advanceName (s); name = reader_getStringWord (s);
5031 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5035 llcontbuglit ("uentry_undump: invalid");
5036 ue = uentry_undefined;
5039 llcontbuglit ("uentry_undump: elips marker");
5040 ue = uentry_undefined;
5049 uentry_dump (uentry v)
5051 return (uentry_dumpAux (v, FALSE));
5055 uentry_dumpParam (uentry v)
5057 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5058 ("dump: %s", uentry_unparseFull (v)));
5060 return (uentry_dumpAux (v, TRUE));
5064 uentry_dumpAux (uentry v, bool isParam)
5066 llassert (uentry_isValid (v));
5067 llassert (!uentry_isGlobalMarker (v));
5069 DPRINTF (("Dump uentry: [%p]", v));
5070 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5075 llcontbuglit ("uentry_dump: invalid entry");
5076 return cstring_undefined;
5078 return (message ("!."));
5082 vkind vk = v->info->var->kind;
5083 sstate dss = sRef_getDefState (v->sref);
5084 nstate nst = sRef_getNullState (v->sref);
5085 alkind alk = sRef_getAliasKind (v->sref);
5086 exkind exk = sRef_getExKind (v->sref);
5087 chkind chk = v->info->var->checked;
5089 DPRINTF (("Dumping var"));
5091 if (dss == SS_UNKNOWN
5092 && nst == NS_UNKNOWN
5093 && alk == AK_IMPTEMP
5094 && exk == XO_UNKNOWN
5095 && chk == CH_UNKNOWN)
5097 sdump = cstring_makeLiteral ("$");
5099 else if (dss == SS_DEFINED
5100 && nst == NS_UNKNOWN
5101 && alk == AK_IMPTEMP
5102 && exk == XO_UNKNOWN
5103 && chk == CH_UNKNOWN)
5105 sdump = cstring_makeLiteral ("&");
5107 else if (dss == SS_UNKNOWN
5108 && nst == NS_UNKNOWN
5109 && alk == AK_UNKNOWN
5110 && exk == XO_UNKNOWN
5111 && chk == CH_UNKNOWN)
5113 sdump = cstring_makeLiteral ("^");
5115 else if (exk == XO_UNKNOWN
5116 && chk == CH_UNKNOWN)
5118 sdump = message ("%d@%d@%d&",
5125 sdump = message ("%d@%d@%d@%d@%d",
5136 return (message ("%q|@%d|%q#%s",
5137 ctype_dump (v->utype),
5140 isParam ? cstring_undefined : v->uname));
5144 return (message ("%q|%q#%s",
5145 ctype_dump (v->utype),
5147 isParam ? cstring_undefined : v->uname));
5153 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5155 exkind_unparse (sRef_getExKind (v->sref)),
5156 ctype_unparse (v->utype), (int) v->utype));
5159 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5160 ctype_dump (v->utype),
5161 ynm_unparseCode (v->info->datatype->abs),
5162 ynm_unparseCode (v->info->datatype->mut),
5163 (int) sRef_getDefState (v->sref),
5164 (int) sRef_getNullState (v->sref),
5165 (int) sRef_getAliasKind (v->sref),
5166 (int) sRef_getExKind (v->sref),
5167 ctype_dump (v->info->datatype->type),
5171 cstring sdump, gdump, adump, xdump;
5172 alkind alk = sRef_getAliasKind (v->sref);
5173 exkind exk = sRef_getExKind (v->sref);
5175 if (sRef_getDefState (v->sref) == SS_DEFINED
5176 && !nstate_isKnown (sRef_getNullState (v->sref))
5177 && !exitkind_isKnown (v->info->fcn->exitCode)
5178 && v->info->fcn->specialCode == SPC_NONE
5179 && qual_isUnknown (v->info->fcn->nullPred))
5181 sdump = cstring_makeLiteral ("$");
5185 sdump = message ("@%d@%d@%d@%d@%x",
5186 (int) sRef_getDefState (v->sref),
5187 (int) sRef_getNullState (v->sref),
5188 (int) v->info->fcn->exitCode,
5189 (int) v->info->fcn->specialCode,
5190 qual_dump (v->info->fcn->nullPred));
5193 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5195 gdump = cstring_makeLiteral ("$");
5197 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5198 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5200 gdump = cstring_makeLiteral ("^");
5204 gdump = message ("@%s@%q@%s@%q",
5205 bool_dump (uentry_hasGlobs (v)),
5206 globSet_dump (uentry_getGlobs (v)),
5207 bool_dump (uentry_hasMods (v)),
5208 sRefSet_dump (uentry_getMods (v)));
5211 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5213 adump = cstring_makeLiteral ("$");
5217 adump = message ("@%d@%d", (int) alk, (int) exk);
5220 xdump = cstring_undefined;
5222 if (uentry_hasWarning (v))
5224 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5227 if (uentry_hasStateClauseList (v))
5229 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5232 return (message ("%q%q%q%q@%q%q#%s",
5233 ctype_dump (v->utype),
5237 typeIdSet_dump (uentry_accessType (v)),
5242 return (message ("%q@%q#%s",
5243 ctype_dump (v->utype),
5244 typeIdSet_dump (v->info->iter->access),
5247 return (message ("%q@%q#%s",
5248 ctype_dump (v->utype),
5249 typeIdSet_dump (uentry_accessType (v)),
5256 if (multiVal_isUnknown (uentry_getConstantValue (v))
5257 && typeIdSet_isEmpty (uentry_accessType (v))
5258 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5260 sdump = cstring_makeLiteral ("$");
5264 sdump = message ("@%q@%q@%d",
5265 multiVal_dump (uentry_getConstantValue (v)),
5266 typeIdSet_dump (uentry_accessType (v)),
5267 (int) sRef_getNullState (v->sref));
5270 return (message ("%q%q#%s",
5271 ctype_dump (v->utype),
5278 return (message ("%q@%q#%s",
5279 ctype_dump (v->utype),
5280 ctype_dump (v->info->datatype->type), v->uname));
5287 uentry_unparseAbbrev (uentry v)
5289 if (!uentry_isVariable (v))
5291 llcontbuglit ("uentry_unparseAbbrev: not variable");
5292 return uentry_unparse (v);
5295 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5299 uentry_unparse (uentry v)
5303 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5304 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5306 st = uentry_getName (v);
5308 if (cstring_isDefined (st))
5310 return (ctype_unparseDeclaration (v->utype, st));
5315 return (cstring_copy (ctype_unparse (v->utype)));
5320 uentry_unparseFull (uentry v)
5322 if (uentry_isUndefined (v))
5324 return (cstring_makeLiteral ("<undefined>"));
5330 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5331 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5332 ctype_unparse (v->utype),
5333 fileloc_unparse (uentry_whereSpecified (v)),
5334 fileloc_unparse (uentry_whereDeclared (v)),
5335 fileloc_unparse (uentry_whereDefined (v)));
5337 DPRINTF (("uentry: %s", res));
5339 if (uentry_isDatatype (v))
5341 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5344 (ctype_isDefined (v->info->datatype->type)
5345 ? v->info->datatype->type : ctype_unknown),
5346 ynm_unparse (v->info->datatype->mut),
5347 ynm_unparse (v->info->datatype->abs),
5348 sRef_unparseState (v->sref));
5350 else if (uentry_isFunction (v))
5352 res = message ("%q / sref: %q / mods: %q / "
5353 "globs: %q / clauses: %q / pre: %q / post: %q",
5355 sRef_unparseFull (v->sref),
5356 sRefSet_unparse (v->info->fcn->mods),
5357 globSet_unparse (v->info->fcn->globs),
5358 stateClauseList_unparse (v->info->fcn->specclauses),
5359 functionConstraint_unparse (v->info->fcn->preconditions),
5360 functionConstraint_unparse (v->info->fcn->postconditions));
5362 else if (uentry_isIter (v))
5364 res = message ("%q / sref: %q",
5366 sRef_unparseFull (v->sref));
5368 else if (uentry_isVariable (v))
5370 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5372 sRef_unparseFull (v->sref),
5373 (int) v->info->var->kind,
5374 (int) v->info->var->defstate,
5375 (int) v->info->var->nullstate,
5377 DPRINTF (("sref: [%p]", v->sref));
5378 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5379 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5381 else if (uentry_isConstant (v))
5383 res = message ("%q = %q / %q",
5384 res, multiVal_unparse (uentry_getConstantValue (v)),
5385 sRef_unparseFull (v->sref));
5389 res = message ("%q :: %q", res, uentry_unparse (v));
5396 bool uentry_hasAccessType (uentry e)
5398 if (uentry_isValid (e))
5403 return (!typeIdSet_isEmpty (e->info->iter->access));
5405 return (!typeIdSet_isEmpty (e->info->enditer->access));
5407 return (!typeIdSet_isEmpty (e->info->fcn->access));
5410 return (!typeIdSet_isEmpty (e->info->uconst->access));
5419 typeIdSet uentry_accessType (uentry e)
5421 if (uentry_isValid (e))
5426 return (e->info->iter->access);
5428 return (e->info->enditer->access);
5430 return (e->info->fcn->access);
5433 return (e->info->uconst->access);
5439 return typeIdSet_undefined;
5443 uentry_isVariable (uentry e)
5445 return (uentry_isVar (e));
5449 uentry_isSpecified (uentry e)
5451 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5455 uentry_isReallySpecified (uentry e)
5457 return (uentry_isValid (e)
5458 && fileloc_isRealSpec (e->whereSpecified));
5462 uentry_isVar (uentry e)
5464 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5468 uentry_isFakeTag (uentry e)
5470 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5474 uentry_isDatatype (uentry e)
5476 return (!uentry_isUndefined (e) &&
5477 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5478 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5482 uentry_setAbstract (uentry e)
5486 llassert (uentry_isDatatype (e)
5487 && (ynm_isMaybe (e->info->datatype->abs)));
5489 oldid = ctype_typeId (e->info->datatype->type);
5490 e->info->datatype->abs = YES;
5491 e->info->datatype->type = ctype_createAbstract (oldid);
5495 uentry_setConcrete (uentry e)
5497 llassert (uentry_isDatatype (e)
5498 && (ynm_isMaybe (e->info->datatype->abs)));
5500 e->info->datatype->abs = NO;
5504 uentry_isAbstractDatatype (uentry e)
5506 return (uentry_isDatatype (e)
5507 && (ynm_isOn (e->info->datatype->abs)));
5511 uentry_isMaybeAbstract (uentry e)
5513 return (uentry_isDatatype (e)
5514 && (ynm_isMaybe (e->info->datatype->abs)));
5518 uentry_isMutableDatatype (uentry e)
5520 bool res = uentry_isDatatype (e)
5521 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5527 uentry_isRefCountedDatatype (uentry e)
5529 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5533 uentry_isParam (uentry u)
5535 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5536 || u->info->var->kind == VKYIELDPARAM));
5540 uentry_isExpandedMacro (uentry u)
5542 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5546 uentry_isSefParam (uentry u)
5548 return (uentry_isVariable (u)
5549 && (u->info->var->kind == VKSEFPARAM
5550 || u->info->var->kind == VKREFSEFPARAM
5551 || u->info->var->kind == VKSEFRETPARAM
5552 || u->info->var->kind == VKREFSEFRETPARAM));
5556 uentry_isRefParam (uentry u)
5558 return (uentry_isVariable (u)
5559 && (u->info->var->kind == VKREFPARAM
5560 || u->info->var->kind == VKREFYIELDPARAM
5561 || u->info->var->kind == VKREFSEFPARAM
5562 || u->info->var->kind == VKREFSEFRETPARAM));
5566 uentry_isAnyParam (uentry u)
5568 return (uentry_isVariable (u)
5569 && ((u->info->var->kind == VKPARAM)
5570 || (u->info->var->kind == VKSEFPARAM)
5571 || (u->info->var->kind == VKYIELDPARAM)
5572 || (u->info->var->kind == VKRETPARAM)
5573 || (u->info->var->kind == VKSEFRETPARAM)));
5577 uentry_getDefState (uentry u)
5579 if (uentry_isValid (u))
5581 return (sRef_getDefState (u->sref));
5585 return (SS_UNKNOWN);
5590 uentry_isOut (uentry u)
5592 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5593 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5597 uentry_isPartial (uentry u)
5599 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5600 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5604 uentry_isStateSpecial (uentry u)
5606 return ((uentry_isVariable (u)
5607 && (u->info->var->defstate == SS_SPECIAL))
5608 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5611 exitkind uentry_getExitCode (uentry ue)
5613 if (uentry_isFunction (ue))
5615 return ue->info->fcn->exitCode;
5623 qual uentry_nullPred (uentry u)
5625 llassert (uentry_isRealFunction (u));
5627 if (uentry_isFunction (u))
5629 return (u->info->fcn->nullPred);
5633 return qual_createUnknown ();
5638 ** Note for variables, this is checking the declared state, not the current state.
5642 uentry_possiblyNull (uentry u)
5644 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5645 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5649 uentry_getAliasKind (uentry u)
5651 if (uentry_isValid (u))
5653 return (sRef_getAliasKind (uentry_getSref (u)));
5662 uentry_getExpKind (uentry u)
5664 if (uentry_isValid (u))
5666 return (sRef_getExKind (uentry_getSref (u)));
5675 uentry_isIter (uentry e)
5677 return (!uentry_isUndefined (e) && e->ukind == KITER);
5681 uentry_isEndIter (uentry e)
5683 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5687 uentry_isRealFunction (uentry e)
5689 return (uentry_isFunction (e) ||
5690 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5694 uentry_hasName (uentry e)
5696 if (uentry_isValid (e))
5698 cstring s = e->uname;
5700 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5701 || uentry_isFakeTag (e)));
5710 ** Returns true for fake tags.
5711 ** This is used for dumping the library
5714 bool uentry_hasRealName (uentry e)
5716 return (uentry_isValid (e)
5717 && cstring_isNonEmpty (e->uname)
5718 && !uentry_isGlobalMarker (e));
5722 /*@observer@*/ globSet
5723 uentry_getGlobs (uentry l)
5725 if (uentry_isInvalid (l))
5727 return globSet_undefined;
5730 if (l->ukind != KFCN)
5732 if (l->ukind != KITER && l->ukind != KENDITER)
5734 if (l->ukind == KVAR)
5736 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5738 ekind_unparse (l->ukind)));
5742 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5744 ekind_unparse (l->ukind)));
5747 return globSet_undefined;
5750 return l->info->fcn->globs;
5753 /*@observer@*/ sRefSet
5754 uentry_getMods (uentry l)
5756 llassert (uentry_isValid (l));
5758 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5760 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5761 return sRefSet_undefined;
5764 return l->info->fcn->mods;
5768 uentry_getKind (uentry e)
5770 llassert (uentry_isValid (e));
5775 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5777 llassert (uentry_isEitherConstant (e));
5778 return (sRef_getValue (e->sref));
5781 /*@observer@*/ uentryList
5782 uentry_getParams (uentry l)
5784 if (uentry_isInvalid (l)) return uentryList_undefined;
5791 ctype ct = l->utype;
5793 if (ctype_isFunction (ct))
5795 return (ctype_argsFunction (ct));
5799 return uentryList_undefined;
5804 ctype ct = l->utype;
5806 llassert (ctype_isFunction (ct));
5807 return (ctype_argsFunction (ct));
5814 /*@observer@*/ cstring
5815 uentry_rawName (uentry e)
5817 if (uentry_isValid (e))
5823 return cstring_undefined;
5828 uentry_getOptName (uentry e)
5830 cstring s = uentry_getName (e);
5832 if (cstring_isDefined (s))
5834 s = cstring_appendChar (s, ' ');
5841 uentry_getName (uentry e)
5843 cstring ret = cstring_undefined;
5845 if (uentry_isValid (e))
5847 if (uentry_isAnyTag (e))
5849 ret = fixTagName (e->uname);
5851 else if (uentry_isAnyParam (e))
5853 ret = cstring_copy (fixParamName (e->uname));
5857 ret = cstring_copy (e->uname);
5864 cstring uentry_observeRealName (uentry e)
5866 cstring ret = cstring_undefined;
5868 if (uentry_isValid (e))
5870 if (uentry_isAnyTag (e))
5872 if (isFakeTag (e->uname))
5874 ret = cstring_undefined;
5878 ret = plainTagName (e->uname);
5881 else if (uentry_isAnyParam (e))
5883 ret = fixParamName (e->uname);
5894 cstring uentry_getRealName (uentry e)
5896 if (uentry_isValid (e))
5898 if (uentry_isAnyTag (e))
5900 return (cstring_undefined);
5907 return cstring_undefined;
5910 ctype uentry_getType (uentry e)
5912 if (uentry_isValid (e))
5918 return ctype_unknown;
5922 fileloc uentry_whereLast (uentry e)
5926 if (uentry_isInvalid (e))
5928 return fileloc_undefined;
5931 loc = e->whereDefined;
5933 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5938 loc = uentry_whereDeclared (e);
5940 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5945 loc = uentry_whereSpecified (e);
5949 fileloc uentry_whereEither (uentry e)
5951 if (uentry_isInvalid (e)) return fileloc_undefined;
5953 if (fileloc_isDefined (e->whereDefined)
5954 && !fileloc_isExternal (e->whereDefined))
5956 return e->whereDefined;
5958 else if (fileloc_isDefined (e->whereDeclared))
5960 return e->whereDeclared;
5964 return e->whereSpecified;
5968 fileloc uentry_whereSpecified (uentry e)
5970 if (uentry_isInvalid (e)) return fileloc_undefined;
5972 return (e->whereSpecified);
5975 fileloc uentry_whereDefined (uentry e)
5977 if (uentry_isInvalid (e)) return fileloc_undefined;
5979 return (e->whereDefined);
5982 fileloc uentry_whereDeclared (uentry e)
5984 if (uentry_isInvalid (e)) return fileloc_undefined;
5986 return (e->whereDeclared);
5989 /*@observer@*/ fileloc
5990 uentry_whereEarliest (uentry e)
5992 if (uentry_isInvalid (e)) return fileloc_undefined;
5994 if (fileloc_isDefined (e->whereSpecified))
5996 return (e->whereSpecified);
5998 else if (fileloc_isDefined (e->whereDeclared))
6000 return (e->whereDeclared);
6004 return e->whereDefined;
6009 uentry_setFunctionDefined (uentry e, fileloc loc)
6011 if (uentry_isValid (e))
6013 llassert (uentry_isFunction (e));
6015 if (fileloc_isUndefined (e->whereDeclared))
6017 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6020 if (!fileloc_isDefined (e->whereDefined))
6022 e->whereDefined = fileloc_update (e->whereDefined, loc);
6028 uentry_setDeclDef (uentry e, fileloc f)
6030 uentry_setDeclared (e, f);
6032 if (!uentry_isFunction (e)
6033 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6035 uentry_setDefined (e, f);
6040 uentry_setDeclaredForce (uentry e, fileloc f)
6042 llassert (uentry_isValid (e));
6043 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6047 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6049 llassert (uentry_isValid (e));
6050 fileloc_free (e->whereDeclared);
6051 e->whereDeclared = f;
6055 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6059 llassert (uentry_isValid (e));
6060 oldloc = e->whereDeclared;
6062 if (fileloc_isDefined (oldloc))
6064 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6066 e->whereDeclared = f;
6067 fileloc_free (oldloc);
6076 e->whereDeclared = f;
6077 fileloc_free (oldloc);
6082 uentry_setDeclared (uentry e, fileloc f)
6086 llassert (uentry_isValid (e));
6087 oldloc = e->whereDeclared;
6089 if (fileloc_isDefined (oldloc))
6091 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6093 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6102 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6107 uentry_clearDefined (uentry e)
6109 if (uentry_isValid (e))
6111 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6116 uentry_setDefined (uentry e, fileloc f)
6120 llassert (uentry_isValid (e));
6121 oldloc = e->whereDefined;
6123 if (fileloc_isDefined (oldloc))
6125 if (fileloc_isLib (oldloc)
6126 || fileloc_isImport (oldloc)
6127 || fileloc_isBuiltin (oldloc)
6128 || fileloc_isPreproc (oldloc))
6130 e->whereDefined = fileloc_update (e->whereDefined, f);
6134 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6140 if (optgenerror (FLG_REDEF,
6141 message ("%s %q redefined",
6142 ekind_capName (e->ukind),
6143 uentry_getName (e)),
6146 llgenindentmsg (message ("Previous definition of %q",
6147 uentry_getName (e)),
6155 e->whereDefined = fileloc_update (e->whereDefined, f);
6160 uentry_isCodeDefined (uentry e)
6162 llassert (uentry_isValid (e));
6164 return (fileloc_isDefined (e->whereDefined));
6168 uentry_isDeclared (uentry e)
6170 if (uentry_isValid (e))
6172 return (fileloc_isDefined (e->whereDeclared));
6178 sRef uentry_getSref (uentry e)
6180 /* not true, used for functions too (but shouldn't be? */
6181 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6183 if (uentry_isInvalid (e)) return sRef_undefined;
6188 sRef uentry_getOrigSref (uentry e)
6190 /*@i523*/ /* evans 2001-09-09 - need to fix this
6191 if (uentry_isValid (e))
6193 if (uentry_isVariable (e))
6195 return e->info->var->origsref;
6199 sRef sr = sRef_copy (uentry_getSref (e));
6201 sRef_resetState (sr);
6202 sRef_clearDerived (sr);
6208 return sRef_undefined;
6212 if (uentry_isValid (e))
6214 sRef sr = sRef_copy (uentry_getSref (e));
6216 sRef_resetState (sr);
6217 sRef_clearDerived (sr);
6219 if (uentry_isVariable (e))
6221 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6222 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6229 return sRef_undefined;
6234 ** requires: uentry e is not in a hashed symbol table
6238 uentry_setName (uentry e, /*@only@*/ cstring n)
6240 llassert (uentry_isValid (e));
6242 cstring_free (e->uname);
6247 uentry_setType (uentry e, ctype t)
6249 if (uentry_isValid (e))
6252 sRef_setType (e->sref, t);
6257 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6260 ctype rettype = ctype_unknown;
6262 llassert (uentry_isValid (ue));
6264 uentry_convertVarFunction (ue);
6265 llassert (uentry_isFunction (ue));
6267 rct = ctype_realType (ue->utype);
6269 if (ctype_isFunction (rct))
6271 rettype = ctype_getReturnType (rct);
6274 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6278 uentry_setRefParam (uentry e)
6280 if (!uentry_isVar (e))
6282 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6286 if (e->info->var->kind == VKSEFPARAM)
6288 e->info->var->kind = VKREFSEFPARAM;
6290 else if (e->info->var->kind == VKSEFRETPARAM)
6292 e->info->var->kind = VKREFSEFRETPARAM;
6294 else if (e->info->var->kind == VKYIELDPARAM)
6296 e->info->var->kind = VKREFYIELDPARAM;
6300 e->info->var->kind = VKREFPARAM;
6306 uentry_setParam (uentry e)
6308 if (!uentry_isVar (e))
6310 if (uentry_isElipsisMarker (e))
6316 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6323 if (e->info->var->kind == VKYIELDPARAM
6324 || e->info->var->kind == VKSEFPARAM
6325 || e->info->var->kind == VKSEFRETPARAM)
6331 e->info->var->kind = VKPARAM;
6335 e->uname = makeParam (e->uname);
6336 cstring_free (oldname);
6341 uentry_setSref (uentry e, sRef s)
6343 if (uentry_isValid (e))
6345 if (sRef_isValid (e->sref))
6347 sRef_mergeStateQuietReverse (e->sref, s);
6351 e->sref = sRef_saveCopy (s);
6357 uentry_getAbstractType (uentry e)
6359 llassert (uentry_isDatatype (e));
6362 ** This assertion removed.
6363 ** Okay to have undefined type, for system types
6365 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6366 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6371 if (ctype_isUndefined (e->info->datatype->type))
6373 return ctype_unknown;
6377 ** Sadly, a kludge...
6380 if (ctype_isUserBool (e->info->datatype->type)) {
6384 return e->info->datatype->type;
6387 ctype uentry_getRealType (uentry e)
6390 typeId uid = USYMIDINVALID;
6392 if (uentry_isInvalid (e))
6394 return ctype_unknown;
6397 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6399 if (uentry_isAnyTag (e))
6404 if (uentry_isAbstractType (e))
6406 ct = uentry_getAbstractType (e);
6408 if (ctype_isManifestBool (ct)) {
6412 llassert (ctype_isUA (ct));
6414 uid = ctype_typeId (ct);
6416 if (!context_hasAccess (uid))
6422 ct = uentry_getType (e);
6424 /* if (ctype_isUserBool (ct)) return ct; */
6426 if (ctype_isManifestBool (ct)) {
6430 if (ctype_isUA (ct))
6432 usymId iid = ctype_typeId (ct);
6434 if (usymId_equal (iid, uid))
6436 llcontbug (message ("uentry_getRealType: recursive type! %s",
6437 ctype_unparse (ct)));
6442 /* evs 2000-07-25: possible infinite recursion ? */
6443 uentry ue2 = usymtab_getTypeEntry (iid);
6447 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6448 return ctype_unknown;
6451 return uentry_getRealType (ue2);
6460 ctype uentry_getForceRealType (uentry e)
6463 typeId uid = USYMIDINVALID;
6465 if (uentry_isInvalid (e))
6467 return ctype_unknown;
6470 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6472 if (uentry_isAnyTag (e))
6477 if (uentry_isAbstractType (e))
6479 ct = uentry_getAbstractType (e);
6480 llassert (ctype_isUA (ct));
6482 uid = ctype_typeId (ct);
6483 /* no check for access! */
6486 ct = uentry_getType (e);
6488 /* evs 2000-07-25 */
6489 /* if (ctype_isUserBool (ct)) return ct; */
6491 if (ctype_isManifestBool (ct)) {
6495 if (ctype_isUA (ct))
6497 usymId iid = ctype_typeId (ct);
6499 if (usymId_equal (iid, uid))
6501 llcontbug (message ("uentry_getRealType: recursive type! %s",
6502 ctype_unparse (ct)));
6507 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6516 uentry uentry_nameCopy (cstring name, uentry e)
6518 uentry enew = uentry_alloc ();
6520 llassert (uentry_isValid (e));
6522 /* enew->shallowCopy = FALSE; */
6523 enew->ukind = e->ukind;
6525 enew->utype = e->utype;
6526 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6527 enew->whereDefined = fileloc_copy (e->whereDefined);
6528 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6529 enew->sref = sRef_copy (e->sref);
6530 enew->used = e->used;
6532 enew->isPrivate = e->isPrivate;
6533 enew->hasNameError = FALSE;
6535 enew->uses = filelocList_new ();
6536 enew->warn = warnClause_undefined;
6538 enew->storageclass = e->storageclass;
6539 enew->info = uinfo_copy (e->info, e->ukind);
6545 uentry_setDatatype (uentry e, usymId uid)
6547 llassert (uentry_isDatatype (e));
6549 if (uentry_isAbstractType (e))
6551 e->info->datatype->type = ctype_createAbstract (uid);
6555 e->info->datatype->type = ctype_createUser (uid);
6560 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6561 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6564 llassert (uentry_isValid (e));
6566 if (fileloc_isSpec (f) || fileloc_isImport (f))
6568 e->whereSpecified = f;
6569 e->whereDeclared = fileloc_undefined;
6570 e->whereDefined = fileloc_undefined;
6574 e->whereSpecified = fileloc_undefined;
6575 e->whereDeclared = f;
6576 e->whereDefined = fileloc_undefined;
6579 llassert (fileloc_storable (f));
6583 ucinfo_free (/*@only@*/ ucinfo u)
6589 uvinfo_free (/*@only@*/ uvinfo u)
6591 /*drl7x added 6/29/01 */
6592 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6597 udinfo_free (/*@only@*/ udinfo u)
6603 ufinfo_free (/*@only@*/ ufinfo u)
6605 globSet_free (u->globs);
6606 sRefSet_free (u->mods);
6607 stateClauseList_free (u->specclauses);
6612 uiinfo_free (/*@only@*/ uiinfo u)
6618 ueinfo_free (/*@only@*/ ueinfo u)
6623 static /*@only@*/ ucinfo
6624 ucinfo_copy (ucinfo u)
6626 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6627 ret->access = u->access;
6628 ret->macro = u->macro;
6632 static /*@only@*/ uvinfo
6633 uvinfo_copy (uvinfo u)
6635 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6637 ret->kind = u->kind;
6638 ret->nullstate = u->nullstate;
6639 ret->defstate = u->defstate;
6640 ret->checked = u->checked;
6642 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6644 /* drl added 07-02-001 */
6645 /* copy null terminated information */
6647 if (u->bufinfo != NULL)
6649 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6650 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6651 ret->bufinfo->size = u->bufinfo->size;
6652 ret->bufinfo->len = u->bufinfo->len;
6657 ret->bufinfo = NULL;
6663 static /*@only@*/ udinfo
6664 udinfo_copy (udinfo u)
6666 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6670 ret->type = u->type;
6675 static /*@only@*/ ufinfo
6676 ufinfo_copy (ufinfo u)
6678 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6680 ret->hasGlobs = u->hasGlobs;
6681 ret->hasMods = u->hasMods;
6682 ret->exitCode = u->exitCode;
6683 ret->specialCode = u->specialCode;
6684 ret->nullPred = u->nullPred;
6685 ret->access = u->access;
6686 ret->globs = globSet_newCopy (u->globs);
6687 ret->mods = sRefSet_newCopy (u->mods);
6688 ret->defparams = u->defparams;
6689 ret->specclauses = stateClauseList_copy (u->specclauses);
6691 ret->preconditions = functionConstraint_copy (u->preconditions);
6692 ret->postconditions = functionConstraint_copy (u->postconditions);
6697 static /*@only@*/ uiinfo
6698 uiinfo_copy (uiinfo u)
6700 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6702 ret->access = u->access;
6703 ret->globs = globSet_newCopy (u->globs);
6704 ret->mods = sRefSet_newCopy (u->mods);
6709 static /*@only@*/ ueinfo
6710 ueinfo_copy (ueinfo u)
6712 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6714 ret->access = u->access;
6719 uinfo_free (uinfo u, ekind kind)
6724 case KCONST: ucinfo_free (u->uconst); break;
6725 case KVAR: uvinfo_free (u->var); break;
6729 case KDATATYPE: udinfo_free (u->datatype); break;
6730 case KFCN: ufinfo_free (u->fcn); break;
6731 case KITER: uiinfo_free (u->iter); break;
6732 case KENDITER: ueinfo_free (u->enditer); break;
6733 case KELIPSMARKER: break;
6734 case KINVALID: break;
6740 static /*@only@*/ /*@null@*/ uinfo
6741 uinfo_copy (uinfo u, ekind kind)
6743 if (kind == KELIPSMARKER || kind == KINVALID)
6749 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6754 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6755 case KVAR: ret->var = uvinfo_copy (u->var); break;
6759 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6760 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6761 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6762 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6770 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6772 filelocList_free (e->uses);
6773 cstring_free (e->uname);
6775 uinfo_free (e->info, e->ukind);
6777 fileloc_free (e->whereSpecified);
6778 fileloc_free (e->whereDefined);
6779 fileloc_free (e->whereDeclared);
6781 warnClause_free (e->warn);
6787 extern void uentry_markOwned (/*@owned@*/ uentry u)
6789 sfreeEventually (u);
6793 uentry_free (/*@only@*/ uentry e)
6795 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6797 uentry_reallyFree (e);
6802 ** For uentry's in the global or file scope
6806 uentry_freeComplete (/*@only@*/ uentry e)
6808 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6810 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6811 /*@i@*/ sRef_free (e->sref);
6812 e->sref = sRef_undefined;
6813 uentry_reallyFree (e);
6818 ** requires old->kind != new->kind, old->uname = new->uname
6822 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6824 llassert (uentry_isValid (old));
6825 llassert (uentry_isValid (unew));
6827 if (uentry_isEitherConstant (unew)
6828 && (fileloc_isPreproc (uentry_whereDeclared (old))
6829 || ctype_isUnknown (old->utype))
6830 && !uentry_isSpecified (old))
6838 if (!uentry_isDeclared (old))
6840 if (uentry_isSpecified (old))
6842 if (uentry_isSpecified (unew))
6844 llbuglit ("Respecification!");
6846 else if (uentry_isDeclared (unew))
6850 message ("%s %q inconsistently declared as %s: %t",
6851 ekind_capName (old->ukind),
6852 uentry_getName (unew),
6853 ekind_unparseLong (unew->ukind),
6855 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6857 uentry_showWhereLastKind (old);
6869 message ("%s %q inconsistently declared as %s: %t",
6870 ekind_capName (old->ukind),
6871 uentry_getName (unew),
6872 ekind_unparseLong (unew->ukind),
6874 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6876 uentry_showWhereLastKind (old);
6882 llassert (uentry_isDeclared (unew));
6884 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6885 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6889 message ("%s %q inconsistently redeclared as %s",
6890 ekind_capName (old->ukind),
6891 uentry_getName (unew),
6892 ekind_unparseLong (unew->ukind)),
6893 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6895 uentry_showWhereLastKind (old);
6901 uentry_updateInto (old, unew);
6905 ** def is the definition of spec, modifies spec
6907 ** reports any inconsistencies
6908 ** returns the summary of all available information
6909 ** if spec and def are inconsistent, def is returned
6913 uentry_showWhereLast (uentry spec)
6915 if (uentry_isValid (spec))
6917 if (fileloc_isDefined (spec->whereDefined)
6918 && !fileloc_isLib (spec->whereDefined)
6919 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6921 llgenindentmsg (message ("Previous definition of %q: %t",
6922 uentry_getName (spec),
6923 uentry_getType (spec)),
6924 uentry_whereDefined (spec));
6926 else if (uentry_isDeclared (spec))
6928 llgenindentmsg (message ("Previous declaration of %q: %t",
6929 uentry_getName (spec),
6930 uentry_getType (spec)),
6931 uentry_whereDeclared (spec));
6933 else if (uentry_isSpecified (spec))
6935 if (uentry_hasName (spec))
6937 llgenindentmsg (message ("Specification of %q: %t",
6938 uentry_getName (spec),
6939 uentry_getType (spec)),
6940 uentry_whereSpecified (spec));
6944 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6945 uentry_whereSpecified (spec));
6950 /* nothing to show */
6956 uentry_showWhereLastKind (uentry spec)
6958 if (uentry_isValid (spec))
6960 if (fileloc_isDefined (spec->whereDefined)
6961 && !fileloc_isLib (spec->whereDefined)
6962 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6964 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6965 uentry_getName (spec),
6966 ekind_unparseLong (spec->ukind),
6967 uentry_getType (spec)),
6968 uentry_whereDefined (spec));
6970 else if (uentry_isDeclared (spec))
6972 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6973 uentry_getName (spec),
6974 ekind_unparseLong (spec->ukind),
6975 uentry_getType (spec)),
6976 uentry_whereDeclared (spec));
6978 else if (uentry_isSpecified (spec))
6980 if (uentry_hasName (spec))
6982 llgenindentmsg (message ("Specification of %q as %s: %t",
6983 uentry_getName (spec),
6984 ekind_unparseLong (spec->ukind),
6985 uentry_getType (spec)),
6986 uentry_whereSpecified (spec));
6990 llgenindentmsg (message ("Specification as %s: %t",
6991 ekind_unparseLong (spec->ukind),
6992 uentry_getType (spec)),
6993 uentry_whereSpecified (spec));
6998 /* nothing to show */
7004 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7006 fileloc loc = uentry_whereDefined (ce);
7008 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7010 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7014 loc = uentry_whereSpecified (ce);
7016 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7018 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7023 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7025 if (uentry_isDeclared (spec))
7027 llgenindentmsg (message ("Previous declaration of %q: %q",
7028 uentry_getName (spec), extra),
7029 uentry_whereDeclared (spec));
7031 else if (uentry_isSpecified (spec))
7033 llgenindentmsg (message ("Specification of %q: %q",
7034 uentry_getName (spec), extra),
7035 uentry_whereSpecified (spec));
7039 cstring_free (extra);
7044 uentry_showWhereDeclared (uentry spec)
7046 if (uentry_isDeclared (spec))
7048 if (uentry_hasName (spec))
7050 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7051 uentry_whereDeclared (spec));
7055 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7058 else if (uentry_isSpecified (spec))
7060 if (uentry_hasName (spec))
7062 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7063 uentry_whereSpecified (spec));
7067 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7072 /* nothing to show */
7078 uentry_showWhereAny (uentry spec)
7080 if (uentry_isDeclared (spec))
7082 if (uentry_hasName (spec))
7084 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7085 uentry_whereDeclared (spec));
7089 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7092 else if (uentry_isSpecified (spec))
7094 if (uentry_hasName (spec))
7096 llgenindentmsg (message ("Specification of %q",
7097 uentry_getName (spec)),
7098 uentry_whereSpecified (spec));
7102 llgenindentmsg (cstring_makeLiteral ("Specification"),
7103 uentry_whereSpecified (spec));
7106 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7108 if (uentry_hasName (spec))
7110 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7111 uentry_whereDefined (spec));
7115 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7120 /* nothing to show */
7125 uentry_showWhereDefined (uentry spec)
7127 if (uentry_isCodeDefined (spec))
7129 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7130 uentry_whereDefined (spec));
7135 uentry_showWhereLastPlain (uentry spec)
7137 if (uentry_isDeclared (spec))
7139 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7140 uentry_whereDeclared (spec));
7142 else if (uentry_isSpecified (spec))
7144 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7145 uentry_whereSpecified (spec));
7153 uentry_showWhereLastVal (uentry spec, cstring val)
7155 if (uentry_isDeclared (spec))
7157 llgenindentmsg (message ("Previous declaration of %q: %s",
7158 uentry_getName (spec), val),
7159 uentry_whereDeclared (spec));
7161 else if (uentry_isSpecified (spec))
7163 llgenindentmsg (message ("Specification of %q: %s",
7164 uentry_getName (spec), val),
7165 uentry_whereSpecified (spec));
7173 uentry_showWhereSpecified (uentry spec)
7175 if (uentry_isSpecified (spec))
7177 if (uentry_hasName (spec))
7179 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7180 uentry_whereSpecified (spec));
7184 llgenindentmsg (cstring_makeLiteral ("Specification"),
7185 uentry_whereSpecified (spec));
7188 else if (uentry_isDeclared (spec))
7190 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7191 uentry_whereDeclared (spec));
7195 /* nothing to show */
7200 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7202 if (uentry_isSpecified (spec))
7204 if (uentry_hasName (spec))
7206 llgenindentmsg (message ("Specification of %q: %q",
7207 uentry_getName (spec), s),
7208 uentry_whereSpecified (spec));
7212 llgenindentmsg (message ("Specification: %q", s),
7213 uentry_whereSpecified (spec));
7216 else if (uentry_isDeclared (spec))
7218 llgenindentmsg (message ("Declaration of %q: %q",
7219 uentry_getName (spec), s),
7220 uentry_whereDeclared (spec));
7224 llgenindentmsg (message ("Previous: %q", s),
7225 uentry_whereLast (spec));
7234 checkStructConformance (uentry old, uentry unew)
7237 uentryList fold, fnew;
7240 ** requires: types of old and new are structs or unions
7243 llassert (uentry_isValid (old));
7244 llassert (uentry_isValid (unew));
7246 oldr = ctype_realType (old->utype);
7247 fold = ctype_getFields (oldr);
7249 newr = ctype_realType (unew->utype);
7250 fnew = ctype_getFields (newr);
7252 if (!uentryList_matchFields (fold, fnew))
7254 if (fileloc_equal (uentry_whereLast (old),
7255 uentry_whereLast (unew)))
7263 message ("%q %q %rdeclared with fields { %q }, %s "
7264 "with fields { %q }",
7265 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7266 uentry_getName (old),
7267 uentry_isDeclared (old),
7268 uentryList_unparseAbbrev (fnew),
7269 uentry_specOrDefName (old),
7270 uentryList_unparseAbbrev (fold)),
7271 uentry_whereDeclared (unew)))
7273 uentry_showWhereLastPlain (old);
7274 uentryList_showFieldDifference (fold, fnew);
7278 old->utype = unew->utype;
7283 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7286 ** requires old and new are enums
7289 ctype rold = ctype_realType (old->utype);
7290 ctype rnew = ctype_realType (unew->utype);
7291 enumNameList eold = ctype_elist (rold);
7292 enumNameList enew = ctype_elist (rnew);
7294 if (!enumNameList_match (eold, enew))
7298 message ("Enum %q declared with members { %q } but "
7299 "specified with members { %q }",
7300 uentry_getName (old),
7301 enumNameList_unparse (enew),
7302 enumNameList_unparse (eold)),
7303 uentry_whereDeclared (unew)))
7305 uentry_showWhereSpecified (old);
7306 old->utype = unew->utype;
7312 ** either oldCurrent or newCurrent may be undefined!
7316 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7317 uentry unew, uentry newCurrent, ctype newType,
7320 bool hasError = FALSE;
7322 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7324 if (uentry_hasName (newCurrent))
7326 hasError = optgenerror
7328 message ("Parameter %d, %q, of function %q has inconsistent type: "
7329 "declared %t, %s %t",
7330 paramno + 1, uentry_getName (newCurrent),
7331 uentry_getName (unew),
7332 newType, uentry_specOrDefName (old), oldType),
7333 uentry_whereDeclared (newCurrent));
7337 hasError = optgenerror
7339 message ("Parameter %d of function %q has inconsistent type: "
7340 "declared %t, %s %t",
7341 paramno + 1, uentry_getName (unew),
7342 newType, uentry_specOrDefName (old), oldType),
7343 uentry_whereDeclared (newCurrent));
7345 DPRINTF (("type: %s / %s",
7346 ctype_unparse (newType),
7347 ctype_unparse (ctype_realType (newType))));
7352 if (uentry_isDeclared (unew))
7354 hasError = optgenerror
7356 message ("Parameter %d of function %s has inconsistent type: "
7357 "declared %t, %s %t",
7358 paramno + 1, unew->uname,
7359 newType, uentry_specOrDefName (old), oldType),
7360 uentry_whereDeclared (unew));
7364 hasError = optgenerror
7366 message ("Parameter %d of function %s has inconsistent type: "
7367 "declared %t, %s %t",
7368 paramno + 1, unew->uname,
7369 newType, uentry_specOrDefName (old), oldType),
7370 uentry_whereDeclared (unew));
7376 DPRINTF (("Here: %s / %s",
7377 uentry_unparseFull (oldCurrent),
7378 uentry_unparseFull (newCurrent)));
7380 if (!uentry_isUndefined (oldCurrent))
7382 if (!uentry_isUndefined (newCurrent)
7383 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7385 uentry_showWhereLast (oldCurrent);
7389 uentry_showWhereLastPlain (old);
7392 uentry_setType (oldCurrent, newType);
7396 uentry_showWhereLastPlain (old);
7402 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7406 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7408 uentry_isDeclared (old),
7409 uentryList_size (uentry_getParams (unew)),
7410 uentry_specOrDefName (old),
7411 uentryList_size (uentry_getParams (old))),
7412 uentry_whereDeclared (unew)))
7414 uentry_showWhereLastPlain (old);
7419 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7423 message ("Function %s inconsistently %rdeclared to return %t",
7425 uentry_isDeclared (old),
7426 ctype_getReturnType (unew->utype)),
7427 uentry_whereDeclared (unew)))
7429 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7433 static cstring paramStorageName (uentry ue)
7435 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7438 static cstring fcnErrName (uentry ue)
7440 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7443 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7445 if (uentry_isVar (ue))
7447 return (checkedName (ue->info->var->checked));
7451 return (cstring_makeLiteralTemp ("<checked invalid>"));
7455 static cstring checkedName (chkind checked)
7459 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7460 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7461 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7462 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7463 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7469 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7474 if (uentry_isVar (unew))
7476 llassert (uentry_isVar (old));
7478 oldState = old->info->var->nullstate;
7479 newState = unew->info->var->nullstate;
7483 oldState = sRef_getNullState (old->sref);
7484 newState = sRef_getNullState (unew->sref);
7487 if (oldState == NS_ABSNULL)
7489 if (uentry_isVar (old))
7491 old->info->var->nullstate = newState;
7494 sRef_mergeNullState (old->sref, newState);
7496 else if (newState == NS_UNKNOWN)
7498 if (completeConform && newState != oldState
7499 && uentry_isReallySpecified (old))
7503 message ("%s %q specified as %s, but declared without %s qualifier",
7504 ekind_capName (unew->ukind),
7505 uentry_getName (unew),
7506 nstate_unparse (oldState),
7507 nstate_unparse (oldState)),
7508 uentry_whereDeclared (unew)))
7510 uentry_showWhereSpecified (old);
7514 if (uentry_isVar (unew))
7516 unew->info->var->nullstate = oldState;
7519 sRef_mergeNullState (unew->sref, oldState);
7521 else if (newState == NS_POSNULL)
7523 if (oldState == NS_MNOTNULL
7524 && (ctype_isUA (unew->utype)
7525 || (uentry_isFunction (unew)
7526 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7528 if (uentry_isVar (unew))
7530 unew->info->var->nullstate = oldState;
7533 sRef_mergeNullState (unew->sref, oldState);
7537 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7538 || oldState == NS_UNKNOWN)
7545 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7547 uentry_ekindName (unew),
7548 uentry_getName (unew),
7549 uentry_isDeclared (old),
7551 uentry_specOrDefName (old),
7552 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7553 uentry_whereDeclared (unew)))
7555 uentry_showWhereSpecified (old);
7560 if (uentry_isVar (old))
7562 old->info->var->nullstate = newState;
7565 sRef_mergeNullState (old->sref, newState);
7568 else if (newState == NS_MNOTNULL)
7570 if (oldState != NS_MNOTNULL)
7576 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7577 "%s without notnull qualifier",
7578 uentry_ekindName (unew),
7579 uentry_getName (unew),
7580 uentry_isDeclared (old),
7582 uentry_specOrDefName (old)),
7583 uentry_whereDeclared (unew)))
7585 uentry_showWhereSpecified (old);
7589 if (uentry_isVar (old))
7591 old->info->var->nullstate = newState;
7594 sRef_mergeNullState (old->sref, newState);
7599 if (uentry_isVar (unew))
7601 unew->info->var->nullstate = oldState;
7604 sRef_mergeNullState (unew->sref, oldState);
7609 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7610 bool mustConform, bool completeConform)
7616 if (uentry_isVar (old) && uentry_isVar (unew))
7618 oldState = old->info->var->defstate;
7619 newState = unew->info->var->defstate;
7624 oldState = sRef_getDefState (old->sref);
7625 newState = sRef_getDefState (unew->sref);
7628 if (newState != oldState
7629 && newState != SS_UNKNOWN
7630 && newState != SS_DEFINED)
7636 message ("%s %q inconsistently %rdeclared %s %s %s, "
7638 uentry_ekindName (unew),
7639 uentry_getName (unew),
7640 uentry_isDeclared (old),
7642 sstate_unparse (newState),
7643 paramStorageName (unew),
7644 uentry_specOrDefName (old),
7646 sstate_unparse (oldState),
7647 paramStorageName (unew)),
7648 uentry_whereDeclared (unew)))
7650 uentry_showWhereSpecified (old);
7654 if (vars) old->info->var->defstate = newState;
7655 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7660 && (newState != oldState) && (oldState != SS_DEFINED)
7661 && uentry_isReallySpecified (old))
7665 message ("%s %q specified as %s, but declared without %s qualifier",
7666 ekind_capName (unew->ukind),
7667 uentry_getName (unew),
7668 sstate_unparse (oldState),
7669 sstate_unparse (oldState)),
7670 uentry_whereDeclared (unew)))
7672 uentry_showWhereSpecified (old);
7676 if (vars) unew->info->var->defstate = oldState;
7677 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7682 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7683 bool mustConform, bool completeConform)
7688 oldKind = sRef_getAliasKind (old->sref);
7689 newKind = sRef_getAliasKind (unew->sref);
7691 if (alkind_isImplicit (newKind)
7692 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7694 if (completeConform && !alkind_equal (newKind, oldKind)
7695 && uentry_isReallySpecified (old))
7699 message ("%s %q specified as %s, but declared without "
7700 "explicit alias qualifier",
7701 ekind_capName (unew->ukind),
7702 uentry_getName (unew),
7703 alkind_unparse (oldKind)),
7704 uentry_whereDeclared (unew)))
7706 uentry_showWhereSpecified (old);
7711 ** This really shouldn't be necessary, but it is!
7712 ** Function params (?) use new here.
7715 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7719 if (alkind_isKnown (newKind))
7721 if (!alkind_equal (oldKind, newKind))
7723 if (alkind_isKnown (oldKind))
7728 message ("%s %q inconsistently %rdeclared %s %s storage, "
7730 uentry_ekindName (unew),
7731 uentry_getName (unew),
7732 uentry_isDeclared (old),
7734 alkind_unparse (newKind),
7735 uentry_specOrDefName (old),
7736 alkind_unparse (oldKind)),
7737 uentry_whereDeclared (unew)))
7739 uentry_showWhereSpecified (old);
7741 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7742 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7743 sRef_setAliasKind (old->sref, AK_ERROR,
7744 uentry_whereDeclared (unew));
7748 sRef_setAliasKind (old->sref, newKind,
7749 uentry_whereDeclared (unew));
7754 if (!(alkind_isImplicit (newKind)))
7757 !uentry_isFunction (unew) &&
7760 message ("%s %q inconsistently %rdeclared %s %s storage, "
7761 "implicitly %s as temp storage",
7762 uentry_ekindName (unew),
7763 uentry_getName (unew),
7764 uentry_isDeclared (old),
7766 alkind_unparse (newKind),
7767 uentry_specOrDefName (old)),
7768 uentry_whereDeclared (unew)))
7770 uentry_showWhereSpecified (old);
7774 sRef_setAliasKind (old->sref, newKind,
7775 uentry_whereDeclared (unew));
7777 else /* newKind is temp or refcounted */
7784 else /* newKind unknown */
7791 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7792 bool mustConform, bool completeConform)
7797 oldKind = sRef_getExKind (old->sref);
7798 newKind = sRef_getExKind (unew->sref);
7800 if (exkind_isKnown (newKind))
7802 if (oldKind != newKind)
7804 if (exkind_isKnown (oldKind))
7809 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7810 uentry_ekindName (unew),
7811 uentry_getName (unew),
7812 uentry_isDeclared (old),
7814 exkind_unparse (newKind),
7815 uentry_specOrDefName (old),
7816 exkind_unparse (oldKind)),
7817 uentry_whereDeclared (unew)))
7819 uentry_showWhereSpecified (old);
7822 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7829 message ("%s %q inconsistently %rdeclared %s %s, "
7830 "implicitly %s without exposure qualifier",
7831 uentry_ekindName (unew),
7832 uentry_getName (unew),
7833 uentry_isDeclared (old),
7835 exkind_unparse (newKind),
7836 uentry_specOrDefName (old)),
7837 uentry_whereDeclared (unew)))
7839 uentry_showWhereSpecified (old);
7842 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7848 if (completeConform && exkind_isKnown (oldKind)
7849 && uentry_isReallySpecified (old))
7853 message ("%s %q specified as %s, but declared without "
7854 "exposure qualifier",
7855 ekind_capName (unew->ukind),
7856 uentry_getName (unew),
7857 exkind_unparse (oldKind)),
7858 uentry_whereDeclared (unew)))
7860 uentry_showWhereSpecified (old);
7864 /* yes, this is necessary! (if its a param) */
7865 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7870 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7871 bool mustConform, /*@unused@*/ bool completeConform)
7873 valueTable newvals = sRef_getValueTable (unew->sref);
7875 if (valueTable_isDefined (newvals))
7877 DPRINTF (("Check meta state: %s -> %s",
7878 uentry_unparseFull (old),
7879 uentry_unparseFull (unew)));
7881 DPRINTF (("Check meta state refs: %s -> %s",
7882 sRef_unparseFull (old->sref),
7883 sRef_unparseFull (unew->sref)));
7885 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7888 ** Copy the new values into the old ref
7891 valueTable_elements (newvals, key, newval)
7893 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7894 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7896 llassert (metaStateInfo_isDefined (msinfo));
7898 if (stateValue_isUndefined (oldval))
7900 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7904 if (stateValue_isError (oldval))
7906 if (!stateValue_isError (newval))
7908 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7912 ; /* No change necessary. */
7917 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7919 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7925 if (!stateValue_isError (newval)
7926 && !stateValue_isImplicit (newval))
7928 if (uentry_hasName (unew)
7929 || !sRef_isParam (uentry_getSref (unew)))
7934 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7935 uentry_ekindName (unew),
7936 uentry_getName (unew),
7937 uentry_isDeclared (old),
7939 stateValue_unparseValue (newval, msinfo),
7940 uentry_specOrDefName (old),
7941 stateValue_unparseValue (oldval, msinfo)),
7942 uentry_whereDeclared (unew)))
7944 uentry_showWhereSpecified (old);
7952 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7953 uentry_ekindName (unew),
7954 sRef_getParam (uentry_getSref (unew)),
7955 uentry_isDeclared (old),
7957 stateValue_unparseValue (newval, msinfo),
7958 uentry_specOrDefName (old),
7959 stateValue_unparseValue (oldval, msinfo)),
7960 uentry_whereDeclared (unew)))
7962 uentry_showWhereSpecified (old);
7968 DPRINTF (("Updating!"));
7969 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7973 DPRINTF (("Values match"));
7977 } end_valueTable_elements ;
7982 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7983 /*@notnull@*/ uentry unew,
7984 bool mustConform, bool completeConform)
7986 checkDefState (old, unew, mustConform, completeConform);
7987 checkNullState (old, unew, mustConform, completeConform);
7988 checkAliasState (old, unew, mustConform, completeConform);
7989 checkExpState (old, unew, mustConform, completeConform);
7990 checkMetaState (old, unew, mustConform, completeConform);
7992 sRef_storeState (old->sref);
7993 sRef_storeState (unew->sref);
7997 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7999 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8004 llassert (uentry_isVar (old));
8005 llassert (uentry_isVar (unew));
8007 if (cstring_isEmpty (old->uname))
8009 cstring_free (old->uname);
8010 old->uname = cstring_copy (unew->uname);
8013 if (unew->info->var->kind == VKRETPARAM
8014 || unew->info->var->kind == VKSEFRETPARAM)
8016 if (old->info->var->kind != VKRETPARAM
8017 && old->info->var->kind != VKSEFRETPARAM)
8021 message ("Parameter %q inconsistently %rdeclared as "
8022 "returned parameter",
8023 uentry_getName (unew),
8024 uentry_isDeclared (old)),
8025 uentry_whereDeclared (unew)))
8027 uentry_showWhereSpecified (old);
8028 old->info->var->kind = unew->info->var->kind;
8034 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8036 if (old->info->var->kind != VKSEFPARAM
8037 && old->info->var->kind != VKSEFRETPARAM)
8041 message ("Parameter %qinconsistently %rdeclared as "
8043 uentry_getOptName (unew),
8044 uentry_isDeclared (old)),
8045 uentry_whereDeclared (unew)))
8047 uentry_showWhereSpecified (old);
8048 old->info->var->kind = unew->info->var->kind;
8053 if (old->info->var->kind == VKSPEC)
8055 old->info->var->kind = unew->info->var->kind;
8059 unew->info->var->kind = old->info->var->kind;
8062 if (unew->info->var->checked != CH_UNKNOWN
8063 && unew->info->var->checked != old->info->var->checked)
8065 if (old->info->var->checked == CH_UNKNOWN
8066 && !fileloc_isUser (uentry_whereLast (old)))
8074 message ("Variable %q inconsistently %rdeclared as "
8075 "%s parameter (was %s)",
8076 uentry_getName (unew),
8077 uentry_isDeclared (old),
8078 checkedName (unew->info->var->checked),
8079 checkedName (old->info->var->checked)),
8080 uentry_whereDeclared (unew)))
8082 uentry_showWhereSpecified (old);
8086 old->info->var->checked = unew->info->var->checked;
8091 && (old->info->var->checked != CH_UNKNOWN)
8092 && uentry_isReallySpecified (old))
8096 message ("%s %q specified as %s, but declared without %s qualifier",
8097 ekind_capName (unew->ukind),
8098 uentry_getName (unew),
8099 checkedName (old->info->var->checked),
8100 checkedName (old->info->var->checked)),
8101 uentry_whereDeclared (unew)))
8103 uentry_showWhereSpecified (old);
8107 unew->info->var->checked = old->info->var->checked;
8110 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8113 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8115 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8120 llassert (uentry_isVar (u1));
8121 llassert (uentry_isVar (u2));
8123 if (u1->info->var->kind != u2->info->var->kind) {
8124 if (u1->info->var->kind == VKSEFRETPARAM) {
8125 if (u2->info->var->kind == VKRETPARAM) {
8128 message ("Function types are inconsistent. Parameter %d is "
8129 "sef parameter, but non-sef parameter in "
8130 "assigned function: %s",
8131 paramno, exprNode_unparse (e)),
8133 } else if (u2->info->var->kind == VKSEFPARAM) {
8136 message ("Function types are inconsistent. Parameter %d is "
8137 "returns parameter, but non-returns parameter in "
8138 "assigned function: %s",
8139 paramno, exprNode_unparse (e)),
8144 message ("Function types are inconsistent. Parameter %d is "
8145 "sef returns parameter, but non-sef returns parameter in "
8146 "assigned function: %s",
8147 paramno, exprNode_unparse (e)),
8150 } else if (u1->info->var->kind == VKRETPARAM) {
8153 message ("Function types are inconsistent. Parameter %d is "
8154 "returns parameter, but non-returns parameter in "
8155 "assigned function: %s",
8156 paramno, exprNode_unparse (e)),
8158 } else if (u1->info->var->kind == VKSEFPARAM) {
8161 message ("Function types are inconsistent. Parameter %d is "
8162 "sef parameter, but non-sef parameter in "
8163 "assigned function: %s",
8164 paramno, exprNode_unparse (e)),
8167 if (u2->info->var->kind == VKSEFRETPARAM) {
8170 message ("Function types are inconsistent. Parameter %d is "
8171 "normal parameter, but sef returns parameter in "
8172 "assigned function: %s",
8173 paramno, exprNode_unparse (e)),
8175 } else if (u2->info->var->kind == VKSEFPARAM) {
8178 message ("Function types are inconsistent. Parameter %d is "
8179 "normal parameter, but sef parameter in "
8180 "assigned function: %s",
8181 paramno, exprNode_unparse (e)),
8183 } else if (u2->info->var->kind == VKRETPARAM) {
8186 message ("Function types are inconsistent. Parameter %d is "
8187 "normal parameter, but returns parameter in "
8188 "assigned function: %s",
8189 paramno, exprNode_unparse (e)),
8197 if (u1->info->var->defstate != u2->info->var->defstate)
8201 message ("Function types are inconsistent. Parameter %d is "
8202 "%s, but %s in assigned function: %s",
8204 sstate_unparse (u1->info->var->defstate),
8205 sstate_unparse (u2->info->var->defstate),
8206 exprNode_unparse (e)),
8210 if (u1->info->var->nullstate != u2->info->var->nullstate)
8214 message ("Function types are inconsistent. Parameter %d is "
8215 "%s, but %s in assigned function: %s",
8217 nstate_unparse (u1->info->var->nullstate),
8218 nstate_unparse (u2->info->var->nullstate),
8219 exprNode_unparse (e)),
8223 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8227 message ("Function types are inconsistent. Parameter %d is "
8228 "%s, but %s in assigned function: %s",
8230 alkind_unparse (sRef_getAliasKind (u1->sref)),
8231 alkind_unparse (sRef_getAliasKind (u2->sref)),
8232 exprNode_unparse (e)),
8236 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8240 message ("Function types are inconsistent. Parameter %d is "
8241 "%s, but %s in assigned function: %s",
8243 exkind_unparse (sRef_getExKind (u1->sref)),
8244 exkind_unparse (sRef_getExKind (u2->sref)),
8245 exprNode_unparse (e)),
8251 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8252 /*@notnull@*/ uentry unew,
8253 bool mustConform, /*@unused@*/ bool completeConform)
8255 uentryList oldParams = uentry_getParams (old);
8256 uentryList newParams = uentry_getParams (unew);
8257 ctype newType = unew->utype;
8258 ctype oldType = ctype_realType (old->utype);
8259 ctype oldRetType = ctype_unknown;
8260 ctype newRetType = ctype_unknown;
8262 DPRINTF (("Function conform: %s ==> %s",
8263 uentry_unparseFull (old),
8264 uentry_unparseFull (unew)));
8266 if (uentry_isForward (old))
8268 mustConform = FALSE;
8269 uentry_updateInto (old, unew);
8274 ** check return values
8277 if (ctype_isKnown (oldType))
8279 llassert (ctype_isFunction (oldType));
8280 oldRetType = ctype_getReturnType (oldType);
8283 if (ctype_isKnown (newType))
8285 llassert (ctype_isFunction (newType));
8286 newRetType = ctype_getReturnType (newType);
8289 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8290 && !ctype_matchDef (newRetType, oldRetType))
8292 if (mustConform) returnValueError (old, unew);
8296 if (ctype_isConj (newRetType))
8298 if (ctype_isConj (oldRetType))
8300 if (!ctype_sameAltTypes (newRetType, oldRetType))
8304 message ("Function %q inconsistently %rdeclared to "
8305 "return alternate types %s "
8306 "(types match, but alternates are not identical, "
8307 "so checking may not be correct)",
8308 uentry_getName (unew),
8309 uentry_isDeclared (old),
8310 ctype_unparse (newRetType)),
8311 uentry_whereDeclared (unew)))
8313 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8319 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8324 DPRINTF (("Before state: %s",
8325 uentry_unparseFull (old)));
8326 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8327 DPRINTF (("After state: %s",
8328 uentry_unparseFull (old)));
8330 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8332 if (exitkind_isKnown (unew->info->fcn->exitCode))
8336 message ("Function %q inconsistently %rdeclared using %s",
8337 uentry_getName (unew),
8338 uentry_isDeclared (old),
8339 exitkind_unparse (unew->info->fcn->exitCode)),
8340 uentry_whereDeclared (unew)))
8342 uentry_showWhereSpecified (old);
8347 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8351 if (!qual_isUnknown (unew->info->fcn->nullPred))
8353 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8357 message ("Function %q inconsistently %rdeclared using %s",
8358 uentry_getName (unew),
8359 uentry_isDeclared (old),
8360 qual_unparse (unew->info->fcn->nullPred)),
8361 uentry_whereDeclared (unew)))
8363 uentry_showWhereSpecified (old);
8369 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8372 if (unew->info->fcn->specialCode != SPC_NONE)
8374 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8378 message ("Function %q inconsistently %rdeclared using %s",
8379 uentry_getName (unew),
8380 uentry_isDeclared (old),
8381 specCode_unparse (unew->info->fcn->specialCode)),
8382 uentry_whereDeclared (unew)))
8384 uentry_showWhereSpecified (old);
8390 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8397 if (!uentryList_sameObject (oldParams, newParams)
8398 && (!uentryList_isMissingParams (oldParams)))
8400 if (!uentryList_isMissingParams (newParams))
8403 int nparams = uentryList_size (oldParams);
8404 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8406 if (nparams != uentryList_size (newParams))
8408 nargsError (old, unew);
8411 if (uentryList_size (newParams) < nparams)
8413 nparams = uentryList_size (newParams);
8416 while (paramno < nparams)
8418 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8419 uentry newCurrent = uentryList_getN (newParams, paramno);
8420 ctype oldCurrentType = uentry_getType (oldCurrent);
8421 ctype newCurrentType = uentry_getType (newCurrent);
8423 llassert (uentry_isValid (oldCurrent)
8424 && uentry_isValid (newCurrent));
8426 if (!uentry_isElipsisMarker (oldCurrent)
8427 && !uentry_isElipsisMarker (newCurrent))
8429 checkVarConformance (oldCurrent, newCurrent,
8430 mustConform, completeConform);
8435 if (uentry_hasName (oldCurrent)
8436 && uentry_hasName (newCurrent))
8438 cstring oldname = uentry_getName (oldCurrent);
8439 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8441 cstring nname = uentry_getName (newCurrent);
8444 if (cstring_isDefined (pfx)
8445 && cstring_equalPrefix (oldname, pfx))
8447 oname = cstring_suffix (oldname, cstring_length (pfx));
8452 /*@-branchstate@*/ } /*@=branchstate@*/
8454 if (cstring_isDefined (pfx)
8455 && cstring_equalPrefix (nname, pfx))
8457 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8462 /*@-branchstate@*/ } /*@=branchstate@*/
8464 if (!cstring_equal (oname, nnamefix))
8467 (FLG_DECLPARAMMATCH,
8468 message ("Definition parameter name %s does not match "
8469 "name of corresponding parameter in "
8472 uentry_whereLast (newCurrent)))
8474 uentry_showWhereLastPlain (oldCurrent);
8478 cstring_free (oldname);
8479 cstring_free (nname);
8483 if (!ctype_match (oldCurrentType, newCurrentType))
8485 paramTypeError (old, oldCurrent, oldCurrentType,
8486 unew, newCurrent, newCurrentType, paramno);
8490 if (ctype_isMissingParamsMarker (newCurrentType)
8491 || ctype_isElips (newCurrentType)
8492 || ctype_isMissingParamsMarker (oldCurrentType)
8493 || ctype_isElips (oldCurrentType))
8499 if (ctype_isConj (newCurrentType))
8501 if (ctype_isConj (oldCurrentType))
8503 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8507 message ("Parameter %q inconsistently %rdeclared with "
8508 "alternate types %s "
8509 "(types match, but alternates are not identical, "
8510 "so checking may not be correct)",
8511 uentry_getName (newCurrent),
8512 uentry_isDeclared (oldCurrent),
8513 ctype_unparse (newCurrentType)),
8514 uentry_whereDeclared (unew)))
8516 uentry_showWhereLastVal (oldCurrent,
8517 ctype_unparse (oldCurrentType));
8525 message ("Parameter %q inconsistently %rdeclared with "
8526 "alternate types %s",
8527 uentry_getName (newCurrent),
8528 uentry_isDeclared (oldCurrent),
8529 ctype_unparse (newCurrentType)),
8530 uentry_whereDeclared (unew)))
8532 uentry_showWhereLastVal (oldCurrent,
8533 ctype_unparse (oldCurrentType));
8540 if (ctype_isConj (oldCurrentType))
8542 uentry_setType (newCurrent, oldCurrentType);
8550 ** Forgot this! detected by splint:
8551 ** uentry.c:1257,15: Suspected infinite loop
8557 if (!uentryList_isMissingParams (newParams))
8559 if (ctype_isConj (oldRetType))
8561 old->utype = ctype_makeFunction (oldRetType,
8562 uentryList_copy (newParams));
8566 old->utype = unew->utype;
8570 checkGlobalsConformance (old, unew, mustConform, completeConform);
8571 checkModifiesConformance (old, unew, mustConform, completeConform);
8573 DPRINTF (("Before list: %s",
8574 uentry_unparseFull (old)));
8576 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8578 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8583 message ("Function %q redeclared using special clauses (can only "
8584 "be used in first declaration)",
8585 uentry_getName (unew)),
8586 uentry_whereDeclared (unew)))
8588 uentry_showWhereLast (old);
8592 /*@i23 need checking @*/
8594 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8598 /*@i43 should be able to append? @*/
8600 stateClauseList_checkEqual (old, unew);
8601 stateClauseList_free (unew->info->fcn->specclauses);
8602 unew->info->fcn->specclauses = stateClauseList_undefined;
8606 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8608 if (fileloc_isUndefined (old->whereDeclared))
8610 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8612 else if (fileloc_isUndefined (unew->whereDeclared))
8614 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8623 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8627 llassert (uentry_isValid (ue));
8628 llassert (uentry_isEitherConstant (ue));
8630 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8631 uval = uentry_getConstantValue (ue);
8633 if (multiVal_isDefined (uval))
8635 if (multiVal_isDefined (m))
8637 if (!multiVal_equiv (uval, m))
8641 message ("%s %q defined with inconsistent value: %q",
8642 ekind_capName (ue->ukind),
8643 uentry_getName (ue),
8644 multiVal_unparse (m)),
8647 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8655 uentry_setConstantValue (ue, m);
8660 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8663 bool typeError = FALSE;
8665 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8667 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8671 DPRINTF (("Check struct conformance: %s / %s",
8672 uentry_unparseFull (old),
8673 uentry_unparseFull (unew)));
8674 checkStructConformance (old, unew);
8679 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8681 llbug (message ("struct tags: bad types: %t / %t",
8682 old->utype, unew->utype));
8686 else if (uentry_isEnumTag (old))
8688 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8690 if (mustConform) checkEnumConformance (old, unew);
8694 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8696 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8697 ctype_unparse (unew->utype)));
8701 else if (!ctype_match (old->utype, unew->utype))
8703 DPRINTF (("Type mismatch: %s / %s",
8704 ctype_unparse (old->utype),
8705 ctype_unparse (unew->utype)));
8707 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8709 ctype realt = ctype_realType (unew->utype);
8711 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8713 unew->utype = ctype_bool;
8719 typeError = optgenerror
8721 message ("%q defined as %s", uentry_getName (old),
8722 ctype_unparse (realt)),
8723 uentry_whereDeclared (unew));
8731 ctype oldr = ctype_realType (old->utype);
8732 ctype newr = ctype_realType (unew->utype);
8734 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8736 checkStructConformance (old, unew);
8738 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8740 checkStructConformance (old, unew);
8742 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8744 checkEnumConformance (old, unew);
8746 else if (uentry_isConstant (old)
8747 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8749 /* okay...for now! (should check the type is reset later... */
8753 DPRINTF (("YABA!"));
8756 message ("%s %q %rdeclared with inconsistent type: %t",
8757 ekind_capName (unew->ukind),
8758 uentry_getName (unew),
8759 uentry_isDeclared (old),
8761 uentry_whereDeclared (unew)))
8763 uentry_showWhereLast (old);
8779 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8780 /*@notnull@*/ uentry unew,
8781 bool mustConform, bool completeConform)
8783 if (ctype_isDefined (unew->info->datatype->type))
8786 ** bool is hard coded here, since it is built into LCL.
8787 ** For now, we're stuck with LCL's types.
8790 if (ctype_isDirectBool (old->utype) &&
8791 cstring_equalLit (unew->uname, "bool"))
8793 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8794 evs 2000-07-25: removed
8796 unew->utype = ctype_bool;
8799 if (ctype_isUnknown (old->info->datatype->type))
8801 old->info->datatype->type = unew->info->datatype->type;
8805 DPRINTF (("Old: %s / New: %s",
8806 uentry_unparseFull (old),
8807 uentry_unparseFull (unew)));
8808 DPRINTF (("Types: %s / %s",
8809 ctype_unparse (old->info->datatype->type),
8810 ctype_unparse (unew->info->datatype->type)));
8812 if (ctype_matchDef (old->info->datatype->type,
8813 unew->info->datatype->type))
8822 ("Type %q %s with inconsistent type: %t",
8823 uentry_getName (unew),
8824 uentry_reDefDecl (old, unew),
8825 unew->info->datatype->type),
8826 uentry_whereDeclared (unew)))
8828 uentry_showWhereLastExtra
8829 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8832 old->info->datatype->type = unew->info->datatype->type;
8837 if (unew->info->datatype->abs != MAYBE)
8839 if (ynm_isOff (old->info->datatype->abs)
8840 && ynm_isOn (unew->info->datatype->abs))
8842 if (!ctype_isDirectBool (old->utype))
8847 ("Datatype %q inconsistently %rdeclared as abstract type",
8848 uentry_getName (unew),
8849 uentry_isDeclared (old)),
8850 uentry_whereDeclared (unew)))
8852 uentry_showWhereLastPlain (old);
8856 else if (ynm_isOn (old->info->datatype->abs)
8857 && ynm_isOff (unew->info->datatype->abs))
8859 if (!ctype_isDirectBool (old->utype))
8864 ("Datatype %q inconsistently %rdeclared as concrete type",
8865 uentry_getName (unew),
8866 uentry_isDeclared (old)),
8867 uentry_whereDeclared (unew)))
8869 uentry_showWhereLastPlain (old);
8880 if (ynm_isOn (old->info->datatype->abs))
8882 old->sref = unew->sref;
8883 unew->info->datatype->mut = old->info->datatype->mut;
8886 && uentry_isReallySpecified (old))
8891 ("Datatype %q specified as abstract, "
8892 "but abstract annotation not used in declaration",
8893 uentry_getName (unew)),
8894 uentry_whereDeclared (unew)))
8896 uentry_showWhereLastPlain (old);
8902 unew->info->datatype->abs = old->info->datatype->abs;
8904 if (ynm_isMaybe (unew->info->datatype->mut))
8906 if (completeConform && ynm_isOff (old->info->datatype->mut)
8907 && uentry_isReallySpecified (old))
8912 ("Datatype %q specified as immutable, "
8913 "but immutable annotation not used in declaration",
8914 uentry_getName (unew)),
8915 uentry_whereDeclared (unew)))
8917 uentry_showWhereLastPlain (old);
8921 unew->info->datatype->mut = old->info->datatype->mut;
8923 else if (ynm_isMaybe (old->info->datatype->mut))
8925 old->info->datatype->mut = unew->info->datatype->mut;
8929 if (ynm_isOn (old->info->datatype->abs))
8931 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8935 message ("Datatype %q inconsistently %rdeclared as immutable",
8936 uentry_getName (unew),
8937 uentry_isDeclared (old)),
8938 uentry_whereDeclared (unew)))
8940 uentry_showWhereLastPlain (old);
8945 if (ynm_isOff (old->info->datatype->mut)
8946 && ynm_isOn (unew->info->datatype->mut))
8950 message ("Datatype %q inconsistently %rdeclared as mutable",
8951 uentry_getName (unew),
8952 uentry_isDeclared (old)),
8953 uentry_whereDeclared (unew)))
8955 uentry_showWhereLastPlain (old);
8960 old->info->datatype->mut = unew->info->datatype->mut;
8963 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8967 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8968 /*@notnull@*/ uentry unew,
8970 /*@unused@*/ bool completeConform)
8972 multiVal oldval = uentry_getConstantValue (old);
8973 multiVal newval = uentry_getConstantValue (unew);
8975 if (multiVal_isDefined (oldval))
8977 if (multiVal_isDefined (newval))
8979 if (!multiVal_equiv (oldval, newval))
8984 message ("%s %q %rdeclared with inconsistent value: %q",
8985 ekind_capName (unew->ukind),
8986 uentry_getName (unew),
8987 uentry_isDeclared (old),
8988 multiVal_unparse (newval)),
8989 uentry_whereDeclared (unew)))
8991 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8995 uentry_setConstantValue (unew, multiVal_copy (oldval));
9004 uentry_setConstantValue (old, multiVal_copy (newval));
9009 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9010 /*@notnull@*/ uentry unew, bool mustConform,
9011 bool completeConform)
9013 bool typeError = FALSE;
9014 bool fcnConformance = FALSE;
9016 if (!ekind_equal (unew->ukind, old->ukind))
9019 ** okay, only if one is a function and the other is
9020 ** a variable of type function.
9023 if (unew->ukind == KENUMCONST
9024 && old->ukind == KCONST)
9026 old->ukind = KENUMCONST;
9030 if (unew->ukind == KFCN
9031 && old->ukind == KCONST
9032 && ctype_isUnknown (old->utype))
9035 ** When a function is defined with an unparam macro
9038 uentry_updateInto (old, unew);
9042 if (uentry_isExpandedMacro (old)
9043 && uentry_isEitherConstant (unew))
9045 uentry_updateInto (old, unew);
9049 if (uentry_isEndIter (unew))
9051 if (ctype_isUnknown (old->utype))
9053 if (!uentry_isSpecified (old)
9054 && uentry_isCodeDefined (unew))
9056 if (!fileloc_withinLines (uentry_whereDefined (old),
9057 uentry_whereDeclared (unew), 2))
9058 { /* bogus! will give errors if there is too much whitespace */
9062 ("Iterator finalized name %q does not match name in "
9063 "previous iter declaration (should be end_%q). This iter "
9064 "is declared at %q",
9065 uentry_getName (unew),
9066 uentry_getName (old),
9067 fileloc_unparse (uentry_whereDefined (old))),
9068 uentry_whereDeclared (old));
9072 uentry_updateInto (old, unew);
9077 KindConformanceError (old, unew, mustConform);
9081 if (uentry_isFunction (unew))
9083 if (uentry_isVariable (old))
9085 if (!ctype_isUnknown (old->utype))
9087 if (ctype_isFunction (old->utype))
9089 uentry_makeVarFunction (old);
9090 checkFunctionConformance (old, unew, mustConform,
9092 fcnConformance = TRUE;
9096 KindConformanceError (old, unew, mustConform);
9101 if (uentry_isExpandedMacro (old))
9103 if (fileloc_isUndefined (unew->whereDefined))
9105 unew->whereDefined = fileloc_update (unew->whereDefined,
9109 uentry_updateInto (old, unew);
9110 old->used = unew->used = TRUE;
9115 /* undeclared identifier */
9116 old->utype = unew->utype;
9117 uentry_makeVarFunction (old);
9118 checkFunctionConformance (old, unew, FALSE, FALSE);
9119 fcnConformance = TRUE;
9125 KindConformanceError (old, unew, mustConform);
9128 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9130 if (!ctype_isUnknown (unew->utype))
9132 if (ctype_isFunction (unew->utype))
9134 uentry_makeVarFunction (unew);
9135 checkFunctionConformance (old, unew, mustConform, completeConform);
9136 fcnConformance = TRUE;
9140 KindConformanceError (old, unew, mustConform);
9145 KindConformanceError (old, unew, mustConform);
9150 KindConformanceError (old, unew, mustConform);
9156 ** check parameter lists for functions
9157 ** (before type errors, to get better messages
9160 if (uentry_isFunction (old))
9162 checkFunctionConformance (old, unew, mustConform, completeConform);
9163 fcnConformance = TRUE;
9167 if (!ctype_isUndefined (old->utype))
9169 typeError = checkTypeConformance (old, unew, mustConform);
9176 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9178 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9181 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9183 DPRINTF (("Check datatype: %s / %s",
9184 uentry_unparseFull (old),
9185 uentry_unparseFull (unew)));
9187 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9190 if (uentry_isVariable (old) && uentry_isVariable (unew))
9193 !ctype_matchDef (old->utype, unew->utype))
9198 ("Variable %q %s with inconsistent type (arrays and pointers are "
9199 "not identical in variable declarations): %t",
9200 uentry_getName (unew),
9201 uentry_reDefDecl (old, unew),
9203 uentry_whereDeclared (unew)))
9205 uentry_showWhereLast (old);
9208 ** Avoid repeated errors.
9211 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9213 old->whereDefined = fileloc_update (old->whereDefined,
9221 checkVarConformance (old, unew, mustConform, completeConform);
9226 /* old->utype = unew->utype; */
9230 if (ctype_isConj (old->utype))
9232 if (ctype_isConj (unew->utype))
9234 if (!ctype_sameAltTypes (old->utype, unew->utype))
9238 message ("%s %q inconsistently %rdeclared with "
9239 "alternate types %s "
9240 "(types match, but alternates are not identical, "
9241 "so checking may not be correct)",
9242 ekind_capName (uentry_getKind (old)),
9243 uentry_getName (unew),
9244 uentry_isDeclared (old),
9245 ctype_unparse (unew->utype)),
9246 uentry_whereDeclared (unew)))
9248 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9252 old->utype = unew->utype;
9259 if (ctype_isUnknown (old->utype))
9261 old->utype = unew->utype;
9266 if (unew->ukind == old->ukind)
9269 unew->info = uinfo_copy (old->info, old->ukind);
9272 sRef_storeState (old->sref);
9273 sRef_storeState (unew->sref);
9276 static void uentry_mergeConstraints (uentry spec, uentry def)
9278 if (uentry_isFunction (def))
9280 DPRINTF (("Here: %s / %s",
9281 uentry_unparseFull (spec),
9282 uentry_unparseFull (def)));
9283 /* evans 2001-07-21 */
9284 llassert (uentry_isFunction (spec));
9286 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9288 if (fileloc_isXHFile (uentry_whereLast (def)))
9290 llassert (uentry_isFunction (spec));
9291 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9292 def->info->fcn->preconditions);
9294 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9300 /* Check if the constraints are identical */
9305 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9306 uentry_getName (spec),
9307 functionConstraint_unparse (spec->info->fcn->preconditions)),
9308 uentry_whereLast (def)))
9310 uentry_showWhereSpecified (spec);
9313 functionConstraint_free (spec->info->fcn->preconditions);
9314 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9317 def->info->fcn->preconditions = functionConstraint_undefined;
9320 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9322 if (fileloc_isXHFile (uentry_whereLast (def)))
9324 llassert (uentry_isFunction (spec));
9325 DPRINTF (("Post: %s /++/ %s",
9326 functionConstraint_unparse (spec->info->fcn->postconditions),
9327 functionConstraint_unparse (def->info->fcn->postconditions)));
9328 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9329 def->info->fcn->postconditions);
9330 def->info->fcn->postconditions = functionConstraint_undefined;
9331 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9338 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9339 uentry_getName (spec),
9340 functionConstraint_unparse (spec->info->fcn->postconditions)),
9341 uentry_whereLast (def)))
9343 uentry_showWhereSpecified (spec);
9346 functionConstraint_free (spec->info->fcn->postconditions);
9347 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9348 def->info->fcn->postconditions = functionConstraint_undefined;
9355 ** modifies spec to reflect def, reports any inconsistencies
9359 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9361 llassert (uentry_isValid (spec));
9362 llassert (uentry_isValid (def));
9363 llassert (cstring_equal (spec->uname, def->uname));
9365 if (uentry_isFunction (def))
9367 if (uentry_isConstant (spec))
9369 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9370 uentry_makeConstantFunction (spec);
9374 uentry_convertVarFunction (spec);
9377 llassert (uentry_isFunction (spec));
9380 DPRINTF (("Merge entries: %s / %s",
9381 uentry_unparseFull (spec),
9382 uentry_unparseFull (def)));
9384 uentry_mergeConstraints (spec, def);
9386 uentry_checkConformance (spec, def, TRUE,
9387 context_getFlag (FLG_NEEDSPEC));
9389 DPRINTF (("Merge entries after conform: %s / %s",
9390 uentry_unparseFull (spec),
9391 uentry_unparseFull (def)));
9393 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9396 ** okay, declarations conform. Propagate extra information.
9399 uentry_setDefined (spec, uentry_whereDefined (def));
9400 uentry_setDeclared (spec, uentry_whereDeclared (def));
9402 if (uentry_isStatic (def))
9406 message ("%s %q specified, but declared as static",
9407 ekind_capName (def->ukind),
9408 uentry_getName (def)),
9409 uentry_whereDeclared (def)))
9411 uentry_showWhereSpecified (spec);
9416 spec->storageclass = def->storageclass;
9419 sRef_storeState (spec->sref);
9421 spec->used = def->used || spec->used;
9422 spec->hasNameError |= def->hasNameError;
9426 if (!spec->hasNameError)
9428 uentry_checkName (spec);
9437 ** Can't generate function redeclaration errors when the
9438 ** entries are merged, since we don't yet know if its the
9439 ** definition of the function.
9443 uentry_clearDecl (void)
9445 posRedeclared = uentry_undefined;
9446 fileloc_free (posLoc);
9447 posLoc = fileloc_undefined;
9451 uentry_checkDecl (void)
9453 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9455 llassert (fileloc_isDefined (posLoc));
9457 if (uentry_isCodeDefined (posRedeclared))
9459 if (optgenerror (FLG_REDECL,
9460 message ("%s %q declared after definition",
9461 ekind_capName (posRedeclared->ukind),
9462 uentry_getName (posRedeclared)),
9465 llgenindentmsg (message ("Definition of %q",
9466 uentry_getName (posRedeclared)),
9467 posRedeclared->whereDeclared);
9472 if (optgenerror (FLG_REDECL,
9473 message ("%s %q declared more than once",
9474 ekind_capName (posRedeclared->ukind),
9475 uentry_getName (posRedeclared)),
9478 llgenindentmsg (message ("Previous declaration of %q",
9479 uentry_getName (posRedeclared)),
9480 posRedeclared->whereDeclared);
9485 fileloc_free (posLoc);
9486 posLoc = fileloc_undefined;
9487 posRedeclared = uentry_undefined;
9491 ** Redefinition of old as unew.
9492 ** modifies old to reflect unew, reports any inconsistencies
9496 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9498 fileloc olddef = uentry_whereDeclared (old);
9499 fileloc unewdef = uentry_whereDeclared (unew);
9503 DPRINTF (("uentry merge: %s / %s",
9504 uentry_unparseFull (old),
9505 uentry_unparseFull (unew)));
9508 fileloc_isUndefined (olddef)
9509 && fileloc_isDefined (uentry_whereDefined (old))
9510 && !uentry_isExpandedMacro (old);
9512 if (!context_getFlag (FLG_INCONDEFSLIB)
9513 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9515 mustConform = FALSE;
9522 llassert (uentry_isValid (old));
9523 llassert (uentry_isValid (unew));
9524 llassert (cstring_equal (old->uname, unew->uname));
9526 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9528 if (uentry_isConstant (old))
9530 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9531 uentry_makeConstantFunction (old);
9535 uentry_convertVarFunction (old);
9538 llassert (uentry_isFunction (old));
9541 DPRINTF (("uentry merge: %s / %s",
9542 uentry_unparseFull (old),
9543 uentry_unparseFull (unew)));
9545 if (uentry_isExtern (unew))
9547 uentry_setUsed (old, unewdef);
9551 ** should check old one was extern!
9554 if (uentry_isStatic (old))
9556 if (!(uentry_isStatic (unew)))
9560 message ("%s %q shadows static declaration",
9561 ekind_capName (unew->ukind),
9562 uentry_getName (unew)),
9565 uentry_showWhereLast (old);
9570 uentry_setDeclDef (old, unewdef);
9573 else if (uentry_isStatic (unew))
9575 uentry_setDeclDef (old, unewdef);
9577 else if (uentry_isExtern (old))
9579 uentry_setDeclared (old, unewdef);
9583 if (!uentry_isExtern (unew)
9584 && !uentry_isForward (old)
9585 && !fileloc_equal (olddef, unewdef)
9586 && !fileloc_isUndefined (olddef)
9587 && !fileloc_isUndefined (unewdef)
9588 && !fileloc_isBuiltin (olddef)
9589 && !fileloc_isBuiltin (unewdef)
9590 && !uentry_isYield (old)
9591 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9593 if (uentry_isVariable (old) || uentry_isVariable (unew))
9595 ; /* will report redeclaration error later */
9599 if (fileloc_isDefined (uentry_whereDefined (old)))
9603 message ("%s %q defined more than once",
9604 ekind_capName (unew->ukind),
9605 uentry_getName (unew)),
9606 uentry_whereLast (unew)))
9609 (message ("Previous definition of %q",
9610 uentry_getName (old)),
9611 uentry_whereLast (old));
9614 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9616 uentry_updateInto (old, unew);
9617 old->sref = sRef_saveCopy (old->sref);
9625 if (fileloc_isLib (olddef)
9626 || fileloc_isUndefined (olddef)
9627 || fileloc_isImport (olddef))
9629 if (uentry_isExtern (unew))
9631 if (uentry_isExtern (old)
9632 || (fileloc_isDefined (uentry_whereDeclared (old))
9633 && (!fileloc_equal (uentry_whereDeclared (old),
9634 uentry_whereDefined (old)))))
9638 message ("%s %q declared more than once",
9639 ekind_capName (unew->ukind),
9640 uentry_getName (unew)),
9641 unew->whereDeclared))
9644 (message ("Previous declaration of %q",
9645 uentry_getName (old)),
9646 old->whereDeclared);
9650 uentry_setExtern (old);
9654 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9660 DPRINTF (("uentry merge: %s / %s",
9661 uentry_unparseFull (old),
9662 uentry_unparseFull (unew)));
9664 uentry_mergeConstraints (old, unew);
9665 DPRINTF (("uentry merge: %s / %s",
9666 uentry_unparseFull (old),
9667 uentry_unparseFull (unew)));
9669 uentry_checkConformance (old, unew, mustConform, FALSE);
9670 DPRINTF (("uentry merge: %s / %s",
9671 uentry_unparseFull (old),
9672 uentry_unparseFull (unew)));
9674 old->used = old->used || unew->used;
9675 old->uses = filelocList_append (old->uses, unew->uses);
9676 unew->uses = filelocList_undefined;
9678 sRef_storeState (old->sref);
9679 sRef_storeState (unew->sref);
9683 old->whereDefined = fileloc_update (old->whereDefined,
9687 DPRINTF (("here: %s", uentry_unparseFull (old)));
9690 ** No redeclaration errors for functions here, since we
9691 ** don't know if this is the definition of the function.
9694 if (fileloc_isUser (old->whereDeclared)
9695 && fileloc_isUser (unew->whereDeclared)
9696 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9697 && !fileloc_isDefined (unew->whereDefined))
9699 if (uentry_isFunction (old))
9701 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9702 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9706 if (optgenerror (FLG_REDECL,
9707 message ("%s %q declared more than once",
9708 ekind_capName (unew->ukind),
9709 uentry_getName (unew)),
9710 unew->whereDeclared))
9712 llgenindentmsg (message ("Previous declaration of %q",
9713 uentry_getName (old)),
9714 old->whereDeclared);
9719 if (fileloc_isUndefined (old->whereDefined))
9721 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9725 if (!context_processingMacros ()
9726 && fileloc_isUser (old->whereDefined)
9727 && fileloc_isUser (unew->whereDefined)
9728 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9730 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9732 if (uentry_isVariable (unew)
9733 && uentry_isExtern (unew))
9735 if (optgenerror (FLG_REDECL,
9736 message ("%s %q declared after definition",
9737 ekind_capName (unew->ukind),
9738 uentry_getName (unew)),
9739 unew->whereDeclared))
9741 llgenindentmsg (message ("Definition of %q",
9742 uentry_getName (old)),
9748 if (optgenerror (FLG_REDEF,
9749 message ("%s %q redefined",
9750 ekind_capName (unew->ukind),
9751 uentry_getName (unew)),
9752 unew->whereDefined))
9754 llgenindentmsg (message ("Previous definition of %q",
9755 uentry_getName (old)),
9763 if (uentry_isExternal (unew))
9765 old->whereDefined = fileloc_createExternal ();
9768 if (unew->hasNameError)
9770 old->hasNameError = TRUE;
9775 if (!old->hasNameError)
9777 uentry_checkName (old);
9780 DPRINTF (("After: %s", uentry_unparseFull (old)));
9781 llassert (!ctype_isUndefined (old->utype));
9785 uentry_copyState (uentry res, uentry other)
9787 llassert (uentry_isValid (res));
9788 llassert (uentry_isValid (other));
9790 res->used = other->used;
9792 res->info->var->kind = other->info->var->kind;
9793 res->info->var->defstate = other->info->var->defstate;
9794 res->info->var->nullstate = other->info->var->nullstate;
9795 res->info->var->checked = other->info->var->checked;
9797 sRef_copyState (res->sref, other->sref);
9801 uentry_sameKind (uentry u1, uentry u2)
9803 if (uentry_isValid (u1) && uentry_isValid (u2))
9805 if (uentry_isVar (u1) && uentry_isVar (u2))
9807 ctype c1 = u1->utype;
9808 ctype c2 = u2->utype;
9810 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9813 ** both functions, or both not functions
9816 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9820 return ((u1->ukind == u2->ukind));
9827 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9830 llassert (uentry_isValid (unew));
9831 llassert (uentry_isValid (old));
9833 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9834 okind = unew->ukind;
9835 unew->ukind = old->ukind;
9836 llassert (cstring_equal (unew->uname, old->uname));
9837 unew->utype = old->utype;
9839 if (fileloc_isDefined (unew->whereSpecified)
9840 && !fileloc_isDefined (old->whereSpecified))
9842 ; /* Keep the old value */
9846 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9847 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9850 if (fileloc_isDefined (unew->whereDefined)
9851 && !fileloc_isDefined (old->whereDefined))
9853 ; /* Keep the old value */
9857 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9858 unew->whereDefined = fileloc_copy (old->whereDefined);
9861 if (fileloc_isDefined (unew->whereDeclared)
9862 && !fileloc_isDefined (old->whereDeclared))
9864 ; /* Keep the old value */
9868 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9869 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9872 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9874 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9875 unew->used = old->used;
9877 unew->isPrivate = old->isPrivate;
9878 unew->hasNameError = old->hasNameError;
9879 unew->uses = filelocList_append (unew->uses, old->uses);
9880 old->uses = filelocList_undefined;
9882 unew->storageclass = old->storageclass;
9883 uinfo_free (unew->info, okind);
9884 unew->info = uinfo_copy (old->info, old->ukind);
9889 uentry_copy (uentry e)
9891 if (uentry_isValid (e))
9893 uentry enew = uentry_alloc ();
9894 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9895 enew->ukind = e->ukind;
9896 enew->uname = cstring_copy (e->uname);
9897 enew->utype = e->utype;
9899 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9900 enew->whereDefined = fileloc_copy (e->whereDefined);
9901 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9903 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9904 enew->used = e->used;
9906 enew->isPrivate = e->isPrivate;
9907 enew->hasNameError = e->hasNameError;
9908 enew->uses = filelocList_undefined;
9910 enew->storageclass = e->storageclass;
9911 enew->info = uinfo_copy (e->info, e->ukind);
9912 enew->warn = warnClause_copy (e->warn);
9914 DPRINTF (("Here we are..."));
9915 DPRINTF (("original: %s", uentry_unparseFull (e)));
9916 DPRINTF (("copy: %s", uentry_unparse (enew)));
9917 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9922 return uentry_undefined;
9927 uentry_setState (uentry res, uentry other)
9929 llassert (uentry_isValid (res));
9930 llassert (uentry_isValid (other));
9932 llassert (res->ukind == other->ukind);
9933 llassert (res->ukind == KVAR);
9935 res->sref = sRef_saveCopy (other->sref);
9936 res->used = other->used;
9937 filelocList_free (res->uses);
9938 res->uses = other->uses;
9939 other->uses = filelocList_undefined;
9940 res->lset = other->lset;
9944 uentry_mergeUses (uentry res, uentry other)
9946 llassert (uentry_isValid (res));
9947 llassert (uentry_isValid (other));
9949 res->used = other->used || res->used;
9950 res->lset = other->lset || res->lset;
9951 res->uses = filelocList_append (res->uses, other->uses);
9952 other->uses = filelocList_undefined;
9957 ** This is a really ugly routine.
9959 ** gack...fix this one day.
9964 ** >> res is the false branch, other is the true branch (or continuation)
9966 ** >> res is the true branch, other is the false branch (or continutation)
9973 ** References not effected by res are propagated from other.
9977 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9978 bool flip, clause cl, fileloc loc)
9982 message ("%s %q is %s %s, but %s %s.",
9983 ekind_capName (res->ukind), uentry_getName (res),
9984 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9985 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9988 if (sRef_isDead (res->sref))
9990 sRef_showStateInfo (res->sref);
9992 else if (sRef_isKept (res->sref))
9994 sRef_showAliasInfo (res->sref);
9996 else /* dependent */
9998 sRef_showAliasInfo (res->sref);
9999 sRef_showAliasInfo (other->sref);
10002 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10006 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10008 alkind rk = sRef_getAliasKind (rs);
10009 alkind ok = sRef_getAliasKind (os);
10011 if (alkind_isError (rk) || alkind_isError (ok))
10017 return ((sRef_isDead (rs)
10018 || (alkind_isKept (rk) && !alkind_isKept (ok))
10019 || (alkind_isDependent (rk)
10020 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10021 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10026 branchStateAltError (/*@notnull@*/ uentry res,
10027 /*@notnull@*/ uentry other, bool flip,
10028 clause cl, fileloc loc)
10032 message ("%s %q is %s %s, but %s %s.",
10033 ekind_capName (res->ukind), uentry_getName (res),
10034 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10035 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10038 if (sRef_isDead (other->sref))
10040 sRef_showStateInfo (other->sref);
10044 sRef_showAliasInfo (other->sref);
10047 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10048 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10050 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10051 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10056 ** A reference is relevant for certain checks, only if it
10057 ** is not definitely null on this path (but not declared
10058 ** to always be null.)
10061 static bool uentry_relevantReference (sRef sr, bool flip)
10063 if (sRef_isKept (sr) || sRef_isDependent (sr))
10071 return !sRef_definitelyNullContext (sr);
10075 return !sRef_definitelyNullAltContext (sr);
10081 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10082 fileloc loc, bool mustReturn, bool flip, bool opt,
10085 sRef rs = res->sref;
10086 sRef os = other->sref;
10088 DPRINTF (("Merge alias states: %s / %s",
10089 uentry_unparseFull (res),
10090 uentry_unparseFull (other)));
10092 if (sRef_isValid (rs))
10096 if (uentry_incompatibleMemoryStates (rs, os))
10098 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10099 sRef_unparseFull (rs), sRef_unparseFull (os)));
10101 if (sRef_isThroughArrayFetch (rs)
10102 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10104 if (sRef_isKept (rs) || sRef_isKept (os))
10106 sRef_maybeKill (rs, loc);
10108 else if (sRef_isPossiblyDead (os))
10110 sRef_maybeKill (rs, loc);
10119 if (uentry_relevantReference (os, flip))
10121 if (sRef_isLocalParamVar (rs)
10122 && (sRef_isLocalState (os)
10123 || sRef_isDependent (os)))
10125 if (sRef_isDependent (rs))
10127 sRef_setDependent (os, loc);
10131 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10136 branchStateError (res, other, flip, cl, loc);
10141 if (sRef_isKept (rs))
10143 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10144 sRef_setKept (os, loc);
10149 if (uentry_incompatibleMemoryStates (os, rs))
10151 if (uentry_relevantReference (rs, !flip))
10153 if (sRef_isLocalParamVar (rs)
10154 && (sRef_isDependent (rs)
10155 || sRef_isLocalState (rs)))
10157 if (sRef_isDependent (os))
10159 sRef_setDependent (rs, loc);
10163 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10168 if (sRef_isParam (os))
10171 ** If the local variable associated
10172 ** with the param has the correct state,
10174 ** (e.g., free (s); s = new(); ...
10177 uentry uvar = usymtab_lookupSafe (other->uname);
10179 if (uentry_isValid (uvar)
10180 && ((sRef_isDead (os)
10181 && sRef_isOnly (uvar->sref))
10182 || (sRef_isDependent (os)
10183 && sRef_isOwned (uvar->sref))))
10189 branchStateAltError (res, other,
10195 DPRINTF (("Here: %s / %s",
10196 uentry_unparseFull (res),
10197 uentry_unparseFull (other)));
10199 branchStateAltError (res, other,
10206 if (sRef_isKept (os))
10208 sRef_setKept (rs, loc);
10214 DPRINTF (("Merge opt..."));
10215 sRef_mergeOptState (rs, os, cl, loc);
10216 DPRINTF (("Done!"));
10220 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10221 sRef_mergeState (rs, os, cl, loc);
10222 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10227 if (sRef_isModified (os))
10229 sRef_setModified (rs);
10234 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10238 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10239 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10241 valueTable rvalues;
10242 valueTable ovalues;
10244 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10252 rvalues = sRef_getValueTable (res->sref);
10253 ovalues = sRef_getValueTable (other->sref);
10255 if (valueTable_isUndefined (ovalues))
10257 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10260 else if (valueTable_isUndefined (rvalues))
10263 ** Copy values from other
10267 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10268 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10273 valueTable_elements (ovalues, fkey, fval) {
10275 metaStateInfo minfo;
10276 stateCombinationTable sctable;
10280 tval = valueTable_lookup (rvalues, fkey);
10282 DPRINTF (("Merge value: %s / %s X %s", fkey,
10283 stateValue_unparse (fval), stateValue_unparse (tval)));
10285 minfo = context_lookupMetaStateInfo (fkey);
10286 llassert (stateValue_isDefined (tval));
10288 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10290 DPRINTF (("Cannot find meta state for: %s", fkey));
10295 llassert (metaStateInfo_isDefined (minfo));
10297 if (stateValue_isError (fval)
10298 || sRef_definitelyNullContext (res->sref))
10300 sRef_setMetaStateValueComplete (res->sref,
10301 fkey, stateValue_getValue (fval),
10302 stateValue_getLoc (fval));
10303 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10305 else if (stateValue_isError (tval)
10306 || sRef_definitelyNullAltContext (other->sref))
10308 DPRINTF (("Other branch is definitely null!"));
10310 else if (sRef_isStateUndefined (res->sref)
10311 || sRef_isDead (res->sref))
10313 ; /* Combination state doesn't matter if it is undefined or dead */
10317 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10318 metaStateInfo_unparse (minfo),
10319 stateValue_unparse (fval),
10320 stateValue_unparse (tval)));
10322 DPRINTF (("state values: %d / %d",
10323 stateValue_getValue (fval), stateValue_getValue (tval)));
10325 sctable = metaStateInfo_getMergeTable (minfo);
10327 DPRINTF (("Merge table: %s",
10328 stateCombinationTable_unparse (sctable)));
10330 msg = cstring_undefined;
10332 nval = stateCombinationTable_lookup (sctable,
10333 stateValue_getValue (fval),
10334 stateValue_getValue (tval),
10337 DPRINTF (("nval: %d / %d / %d", nval,
10338 stateValue_getValue (fval), stateValue_getValue (tval)));
10340 if (nval == stateValue_error)
10342 /*@i32 print extra info for assignments@*/
10344 if (uentry_isGlobalMarker (res))
10349 ("Control branches merge with incompatible global states (%s and %s)%q",
10350 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10351 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10352 cstring_isDefined (msg)
10353 ? message (": %s", msg) : cstring_undefined),
10356 sRef_showMetaStateInfo (res->sref, fkey);
10357 sRef_showMetaStateInfo (other->sref, fkey);
10365 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10366 uentry_getName (res),
10367 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10368 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10369 cstring_isDefined (msg)
10370 ? message (": %s", msg) : cstring_undefined),
10373 sRef_showMetaStateInfo (res->sref, fkey);
10374 sRef_showMetaStateInfo (other->sref, fkey);
10375 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10376 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10377 DPRINTF (("Null: %s / %s",
10378 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10379 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10385 if (nval == stateValue_getValue (fval)
10386 && nval != stateValue_getValue (tval))
10388 loc = stateValue_getLoc (fval);
10390 else if (nval == stateValue_getValue (tval)
10391 && nval != stateValue_getValue (fval))
10393 loc = stateValue_getLoc (tval);
10400 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10401 && nval == stateValue_getValue (fval)
10402 && nval == stateValue_getValue (tval))
10408 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10412 } end_valueTable_elements ;
10418 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10419 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10420 bool flip, clause cl)
10422 if (cl == DOWHILECLAUSE)
10424 res->used = other->used || res->used;
10425 res->lset = other->lset || res->lset;
10426 res->uses = filelocList_append (res->uses, other->uses);
10427 other->uses = filelocList_undefined;
10431 if (sRef_isMacroParamRef (res->sref)
10432 && !uentry_isSefParam (other)
10433 && !uentry_isSefParam (res))
10435 bool hasError = FALSE;
10437 if (bool_equal (res->used, other->used))
10439 res->used = other->used;
10443 if (other->used && !flip)
10448 message ("Macro parameter %q used in true clause, "
10449 "but not in false clause",
10450 uentry_getName (res)),
10451 uentry_whereDeclared (res));
10458 message ("Macro parameter %q used in false clause, "
10459 "but not in true clause",
10460 uentry_getName (res)),
10461 uentry_whereDeclared (res));
10467 /* make it sef now, prevent more errors */
10468 res->info->var->kind = VKREFSEFPARAM;
10474 res->used = other->used || res->used;
10475 res->lset = other->lset || res->lset;
10476 res->uses = filelocList_append (res->uses, other->uses);
10477 other->uses = filelocList_undefined;
10483 uentry_mergeState (uentry res, uentry other, fileloc loc,
10484 bool mustReturn, bool flip, bool opt,
10487 llassert (uentry_isValid (res));
10488 llassert (uentry_isValid (other));
10490 llassert (res->ukind == other->ukind);
10491 llassert (res->ukind == KVAR);
10493 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10494 uentry_unparseFull (other)));
10496 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10497 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10498 uentry_mergeSetStates (res, other, loc, flip, cl);
10500 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10503 void uentry_setUsed (uentry e, fileloc loc)
10505 static bool firstTime = TRUE;
10506 static bool showUses = FALSE;
10507 static bool exportLocal = FALSE;
10509 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10513 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10515 showUses = context_getFlag (FLG_SHOWUSES);
10516 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10521 if (uentry_isValid (e))
10525 if (warnClause_isDefined (e->warn))
10527 flagSpec flg = warnClause_getFlag (e->warn);
10530 if (warnClause_hasMessage (e->warn))
10532 msg = cstring_copy (warnClause_getMessage (e->warn));
10536 msg = message ("Use of possibly dangerous %s",
10537 uentry_ekindNameLC (e));
10541 message ("%q: %q", msg, uentry_getName (e)),
10545 if (sRef_isMacroParamRef (e->sref))
10547 if (uentry_isYield (e) || uentry_isSefParam (e))
10553 if (context_inConditional ())
10557 message ("Macro parameter %q used in conditionally "
10558 "executed code (may or may not be "
10559 "evaluated exactly once)",
10560 uentry_getName (e)),
10563 e->info->var->kind = VKREFSEFPARAM;
10572 message ("Macro parameter %q used more than once",
10573 uentry_getName (e)),
10574 uentry_whereDeclared (e)))
10576 e->info->var->kind = VKREFSEFPARAM;
10583 if ((dp = uentry_directParamNo (e)) >= 0)
10585 uentry_setUsed (usymtab_getParam (dp), loc);
10590 if (!sRef_isLocalVar (e->sref))
10594 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10600 if (context_inMacro ())
10602 e->uses = filelocList_addUndefined (e->uses);
10606 e->uses = filelocList_addDifferentFile
10608 uentry_whereDeclared (e),
10617 bool uentry_isReturned (uentry u)
10619 return (uentry_isValid (u) && uentry_isVar (u)
10620 && (u->info->var->kind == VKRETPARAM
10621 || u->info->var->kind == VKSEFRETPARAM));
10626 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10628 llassert (uentry_isRealFunction (u));
10630 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10632 stateClauseList clauses = uentry_getStateClauseList (u);
10633 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10635 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10636 sRef_setAllocated (res, g_currentloc);
10638 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10639 stateClauseList_unparse (clauses)));
10642 ** This should be in exprNode_reflectEnsuresClause
10645 stateClauseList_postElements (clauses, cl)
10647 if (!stateClause_isGlobal (cl))
10649 sRefSet refs = stateClause_getRefs (cl);
10650 sRefMod modf = stateClause_getEffectFunction (cl);
10652 sRefSet_elements (refs, el)
10654 sRef base = sRef_getRootBase (el);
10656 if (sRef_isResult (base))
10660 sRef sr = sRef_fixBase (el, res);
10661 modf (sr, g_currentloc);
10668 } end_sRefSet_elements ;
10670 } end_stateClauseList_postElements ;
10678 sRefSet prefs = sRefSet_new ();
10679 sRef res = sRef_undefined;
10680 sRef tcref = sRef_undefined;
10681 sRef tref = sRef_undefined;
10684 params = uentry_getParams (u);
10687 ** Setting up aliases has to happen *after* setting null state!
10690 uentryList_elements (params, current)
10692 if (uentry_isReturned (current))
10694 if (exprNodeList_size (args) >= paramno)
10696 exprNode ecur = exprNodeList_nth (args, paramno);
10697 tref = exprNode_getSref (ecur);
10699 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10701 if (sRef_isValid (tref))
10703 tcref = sRef_copy (tref);
10705 if (sRef_isDead (tcref))
10707 sRef_setDefined (tcref, g_currentloc);
10708 sRef_setOnly (tcref, g_currentloc);
10711 if (sRef_isRefCounted (tcref))
10713 /* could be a new ref now (but only if its returned) */
10714 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10717 sRef_makeSafe (tcref);
10718 prefs = sRefSet_insert (prefs, tcref);
10724 } end_uentryList_elements ;
10726 if (sRefSet_size (prefs) > 0)
10728 nstate n = sRef_getNullState (u->sref);
10730 if (sRefSet_size (prefs) == 1)
10732 sRef rref = sRefSet_choose (prefs);
10734 res = sRef_makeType (sRef_getType (rref));
10735 sRef_copyState (res, tref);
10739 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10740 res = sRefSet_mergeIntoOne (prefs);
10743 if (nstate_isKnown (n))
10745 sRef_setNullState (res, n, g_currentloc);
10746 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10751 if (ctype_isFunction (u->utype))
10753 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10754 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10758 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10759 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10762 if (sRef_isRefCounted (res))
10764 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10768 if (sRef_getNullState (res) == NS_ABSNULL)
10770 ctype ct = ctype_realType (u->utype);
10772 if (ctype_isAbstract (ct))
10774 sRef_setNotNull (res, g_currentloc);
10778 if (ctype_isUser (ct))
10780 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10784 sRef_setNotNull (res, g_currentloc);
10789 if (sRef_isRefCounted (res))
10791 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10793 else if (sRef_isKillRef (res))
10795 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10802 ak = sRef_getAliasKind (res);
10804 if (alkind_isImplicit (ak))
10806 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10810 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10811 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10813 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10814 usymtab_addReallyForceMustAlias (res, tref);
10817 sRefSet_free (prefs);
10819 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10825 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10827 llassert (uentry_isRealFunction (u));
10829 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10831 stateClauseList clauses = uentry_getStateClauseList (u);
10832 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10834 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10835 sRef_setAllocated (res, g_currentloc);
10837 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10838 stateClauseList_unparse (clauses)));
10841 ** This should be in exprNode_reflectEnsuresClause
10844 stateClauseList_postElements (clauses, cl)
10846 if (!stateClause_isGlobal (cl))
10848 sRefSet refs = stateClause_getRefs (cl);
10849 sRefMod modf = stateClause_getEffectFunction (cl);
10851 sRefSet_elements (refs, el)
10853 sRef base = sRef_getRootBase (el);
10855 if (sRef_isResult (base))
10859 sRef sr = sRef_fixBase (el, res);
10860 modf (sr, g_currentloc);
10867 } end_sRefSet_elements ;
10869 } end_stateClauseList_postElements ;
10877 sRefSet prefs = sRefSet_new ();
10878 sRef res = sRef_undefined;
10881 params = uentry_getParams (u);
10883 uentryList_elements (params, current)
10885 if (uentry_isReturned (current))
10887 if (exprNodeList_size (args) >= paramno)
10889 exprNode ecur = exprNodeList_nth (args, paramno);
10890 sRef tref = exprNode_getSref (ecur);
10892 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10894 if (sRef_isValid (tref))
10896 sRef tcref = sRef_copy (tref);
10898 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10900 if (sRef_isDead (tcref))
10902 sRef_setDefined (tcref, g_currentloc);
10903 sRef_setOnly (tcref, g_currentloc);
10906 if (sRef_isRefCounted (tcref))
10908 /* could be a new ref now (but only if its returned) */
10909 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10912 sRef_makeSafe (tcref);
10913 prefs = sRefSet_insert (prefs, tcref);
10919 } end_uentryList_elements ;
10921 if (sRefSet_size (prefs) > 0)
10923 nstate n = sRef_getNullState (u->sref);
10925 if (sRefSet_size (prefs) == 1)
10927 res = sRefSet_choose (prefs);
10931 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10932 res = sRefSet_mergeIntoOne (prefs);
10935 if (nstate_isKnown (n))
10937 sRef_setNullState (res, n, g_currentloc);
10942 if (ctype_isFunction (u->utype))
10944 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10945 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10949 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10952 if (sRef_isRefCounted (res))
10954 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10959 if (sRef_getNullState (res) == NS_ABSNULL)
10961 ctype ct = ctype_realType (u->utype);
10963 if (ctype_isAbstract (ct))
10965 sRef_setNotNull (res, g_currentloc);
10969 if (ctype_isUser (ct))
10971 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10975 sRef_setNotNull (res, g_currentloc);
10980 if (sRef_isRefCounted (res))
10982 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10984 else if (sRef_isKillRef (res))
10986 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10993 ak = sRef_getAliasKind (res);
10995 if (alkind_isImplicit (ak))
10997 sRef_setAliasKind (res,
10998 alkind_fixImplicit (ak),
11002 sRefSet_free (prefs);
11004 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11009 static bool uentry_isRefCounted (uentry ue)
11011 ctype ct = uentry_getType (ue);
11013 if (ctype_isFunction (ct))
11015 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11019 return (ctype_isRefCounted (ct));
11024 ** old was declared yield in the specification.
11025 ** new is declared in the iter implementation.
11028 void uentry_checkYieldParam (uentry old, uentry unew)
11032 llassert (uentry_isVariable (old));
11033 llassert (uentry_isVariable (unew));
11035 unew->info->var->kind = VKYIELDPARAM;
11036 (void) checkTypeConformance (old, unew, TRUE);
11037 checkVarConformance (old, unew, TRUE, FALSE);
11039 /* get rid of param marker */
11041 name = uentry_getName (unew);
11042 cstring_free (unew->uname);
11043 unew->uname = name;
11044 unew->info->var->kind = VKREFYIELDPARAM;
11046 uentry_setUsed (old, fileloc_undefined);
11047 uentry_setUsed (unew, fileloc_undefined);
11050 /*@observer@*/ cstring
11051 uentry_ekindName (uentry ue)
11053 if (uentry_isValid (ue))
11058 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11060 return cstring_makeLiteralTemp ("Datatype");
11062 return cstring_makeLiteralTemp ("Enum member");
11064 return cstring_makeLiteralTemp ("Constant");
11066 if (uentry_isParam (ue))
11068 return cstring_makeLiteralTemp ("Parameter");
11070 else if (uentry_isExpandedMacro (ue))
11072 return cstring_makeLiteralTemp ("Expanded macro");
11076 return cstring_makeLiteralTemp ("Variable");
11079 return cstring_makeLiteralTemp ("Function");
11081 return cstring_makeLiteralTemp ("Iterator");
11083 return cstring_makeLiteralTemp ("Iterator finalizer");
11085 return cstring_makeLiteralTemp ("Struct tag");
11087 return cstring_makeLiteralTemp ("Union tag");
11089 return cstring_makeLiteralTemp ("Enum tag");
11091 return cstring_makeLiteralTemp ("Optional parameters");
11096 return cstring_makeLiteralTemp ("<Undefined>");
11102 /*@observer@*/ cstring
11103 uentry_ekindNameLC (uentry ue)
11105 if (uentry_isValid (ue))
11110 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11112 return cstring_makeLiteralTemp ("datatype");
11114 return cstring_makeLiteralTemp ("enum member");
11116 return cstring_makeLiteralTemp ("constant");
11118 if (uentry_isParam (ue))
11120 return cstring_makeLiteralTemp ("parameter");
11122 else if (uentry_isExpandedMacro (ue))
11124 return cstring_makeLiteralTemp ("expanded macro");
11128 return cstring_makeLiteralTemp ("variable");
11131 return cstring_makeLiteralTemp ("function");
11133 return cstring_makeLiteralTemp ("iterator");
11135 return cstring_makeLiteralTemp ("iterator finalizer");
11137 return cstring_makeLiteralTemp ("struct tag");
11139 return cstring_makeLiteralTemp ("union tag");
11141 return cstring_makeLiteralTemp ("enum tag");
11143 return cstring_makeLiteralTemp ("optional parameters");
11148 return cstring_makeLiteralTemp ("<Undefined>");
11154 void uentry_setHasNameError (uentry ue)
11156 llassert (uentry_isValid (ue));
11158 ue->hasNameError = TRUE;
11161 void uentry_checkName (uentry ue)
11163 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11164 uentry_observeRealName (ue),
11165 bool_unparse (uentry_isVisibleExternally (ue))));
11167 if (uentry_isValid (ue)
11168 && !context_inXHFile ()
11169 && uentry_hasName (ue)
11170 && !uentry_isElipsisMarker (ue)
11171 && context_getFlag (FLG_NAMECHECKS)
11172 && !ue->hasNameError
11173 && !uentry_isEndIter (ue)
11174 && !fileloc_isBuiltin (uentry_whereLast (ue))
11175 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11177 DPRINTF (("Here..."));
11179 if (uentry_isPriv (ue))
11181 ; /* any checks here? */
11183 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11185 ; /* no errors for externals */
11191 if (uentry_isExpandedMacro (ue))
11197 if (uentry_isExpandedMacro (ue))
11201 else if (uentry_isVariable (ue))
11203 sRef sr = uentry_getSref (ue);
11205 if (sRef_isValid (sr))
11207 scope = sRef_getScope (sr);
11214 else if (uentry_isFunction (ue)
11215 || uentry_isIter (ue)
11216 || uentry_isEndIter (ue)
11217 || uentry_isConstant (ue))
11219 scope = uentry_isStatic (ue) ? fileScope : globScope;
11221 else /* datatypes, etc. must be global */
11226 usymtab_checkDistinctName (ue, scope);
11229 if (context_getFlag (FLG_CPPNAMES))
11234 if (scope == globScope)
11236 checkExternalName (ue);
11238 else if (scope == fileScope)
11240 checkFileScopeName (ue);
11244 checkLocalName (ue);
11248 checkAnsiName (ue);
11253 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11259 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11262 if (!context_inMacro ())
11264 sRef_setGlobalScopeSafe ();
11267 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11268 uentry_setUsed (ue, loc);
11270 tloc = fileloc_createExternal ();
11271 uentry_setDefined (ue, tloc);
11272 fileloc_free (tloc);
11273 uentry_setHasNameError (ue);
11275 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11277 uentry_markOwned (ue);
11281 ue = usymtab_supReturnFileEntry (ue);
11284 if (!context_inMacro ())
11286 sRef_clearGlobalScopeSafe ();
11292 uentry uentry_makeGlobalMarker ()
11297 llassert (sRef_inGlobalScope ());
11299 ue = uentry_makeVariableAux
11300 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11301 sRef_makeGlobalMarker (),
11304 tloc = fileloc_createExternal ();
11305 uentry_setUsed (ue, tloc);
11306 uentry_setDefined (ue, tloc);
11307 fileloc_free (tloc);
11308 uentry_setHasNameError (ue);
11314 bool uentry_isGlobalMarker (uentry ue)
11316 return (uentry_isValid (ue)
11317 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11320 /* new start modifications */
11322 /* start modifications */
11324 requires: p_e is defined, is a ptr/array variable
11326 effects: sets the state of the variable
11330 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11332 llassert (uentry_isValid (p_e));
11334 if (p_e->info != NULL)
11336 if (p_e->info->var != NULL)
11338 llassert (p_e->info->var->bufinfo != NULL);
11339 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11340 sRef_setPossiblyNullTerminatedState (p_e->sref);
11346 requires: p_e is defined, is a ptr/array variable
11348 effects: sets the size of the buffer
11351 void uentry_setNullTerminatedState (uentry p_e) {
11352 llassert (uentry_isValid (p_e));
11354 if (p_e->info != NULL)
11356 if (p_e->info->var != NULL)
11358 llassert (p_e->info->var->bufinfo != NULL);
11359 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11360 sRef_setNullTerminatedState (p_e->sref);
11366 requires: p_e is defined, is a ptr/array variable
11368 effects: sets the size of the buffer
11371 void uentry_setSize (uentry p_e, int size)
11373 if (uentry_isValid (p_e))
11375 if (p_e->info != NULL)
11377 if (p_e->info->var != NULL)
11379 llassert (p_e->info->var->bufinfo != NULL);
11380 p_e->info->var->bufinfo->size = size;
11381 sRef_setSize (p_e->sref, size);
11388 requires: p_e is defined, is a ptr/array variable
11390 effects: sets the length of the buffer
11393 void uentry_setLen (uentry p_e, int len)
11395 if (uentry_isValid (p_e))
11397 if (p_e->info != NULL
11398 && p_e->info->var != NULL)
11400 llassert (p_e->info->var->bufinfo != NULL);
11401 p_e->info->var->bufinfo->len = len;
11402 sRef_setLen (p_e->sref, len);
11409 bool uentry_hasMetaStateEnsures (uentry e)
11411 if (uentry_isValid (e) && uentry_isFunction (e))
11413 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11421 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11423 llassert (uentry_isValid (e) && uentry_isFunction (e));
11424 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11427 # ifdef DEBUGSPLINT
11430 ** For debugging only
11433 void uentry_checkValid (uentry ue)
11435 if (uentry_isValid (ue))
11437 sRef_checkCompletelyReasonable (ue->sref);