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);
749 uentryList_elements (params, current)
753 if (uentry_isValid (current))
755 ctype ct = current->utype;
757 if (ctype_isFixedArray (ct))
759 if (ctype_isArray (ctype_baseArrayPtr (ct))
760 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
766 if (uentry_hasName (current))
769 (FLG_FIXEDFORMALARRAY,
770 message ("Function parameter %q declared as "
771 "manifest array (size constant is meaningless)",
772 uentry_getName (current)),
773 uentry_whereDeclared (current));
778 (FLG_FIXEDFORMALARRAY,
779 message ("Unnamed function parameter %d declared as "
780 "manifest array (size constant is meaningless)",
782 uentry_whereDeclared (current));
788 if (ctype_isArray (ct))
790 if (uentry_hasName (current))
794 message ("Function parameter %q declared as "
795 "array (treated as pointer)",
796 uentry_getName (current)),
797 uentry_whereDeclared (current));
803 message ("Unnamed function parameter %d declared as "
804 "array (treated as pointer)",
806 uentry_whereDeclared (current));
811 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
813 if (ctype_isAbstract (ct) &&
814 (isExt || (ctype_isAbstract (ctype_realType (ct))
815 && !context_hasFileAccess (ctype_typeId (ct)))))
820 ("Function %q declared with notnull parameter %q of abstract "
823 uentry_getName (current),
826 ("Since %s is an abstract type, notnull can only be "
827 "used for parameters if the function is static to a "
828 "module where %s is accessible.",
831 uentry_whereDeclared (current));
835 } end_uentryList_elements;
837 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
839 ctype ct = ue->utype;
841 if (ctype_isAbstract (ct)
842 && (isExt || (ctype_isAbstract (ctype_realType (ct))
843 && !context_hasFileAccess (ctype_typeId (ct)))))
848 ("%s %q declared %s notnull storage of abstract type %s",
849 ekind_capName (uentry_getKind (ue)),
854 ("Since %s is an abstract type, notnull can only be used "
855 "if it is static to a module where %s is accessible.",
858 uentry_whereDeclared (ue));
865 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
867 alkind ak = sRef_getAliasKind (ue->sref);
869 if (alkind_isRefCounted (ak))
871 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
875 if (alkind_isUnknown (ak))
877 exkind ek = sRef_getExKind (ue->sref);
879 if (exkind_isKnown (ek))
881 DPRINTF (("Setting imp dependent: %s",
882 uentry_unparseFull (ue)));
883 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
887 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
889 /* evans 2000-12-22 removed ctype_realType so it will
890 not apply to immutable abstract types. */
892 if (ctype_isVisiblySharable
893 (ctype_realType (ctype_getReturnType (ue->utype))))
895 if (uentryList_hasReturned (uentry_getParams (ue)))
901 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
903 ; /* Immutable objects are not shared. */
907 sRef_setAliasKind (ue->sref, AK_IMPONLY,
909 DPRINTF (("Ret imp only: %s",
910 ctype_unparse (ctype_getReturnType (ue->utype))));
920 static /*@notnull@*/ uentry
921 uentry_makeFunctionAux (cstring n, ctype t,
923 /*@only@*/ globSet globs,
924 /*@only@*/ sRefSet mods,
925 /*@only@*/ warnClause warn,
926 /*@keep@*/ fileloc f, bool priv,
927 /*@unused@*/ bool isForward)
929 uentry e = uentry_alloc ();
932 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
934 DPRINTF (("Make function: %s", n));
936 if (ctype_isFunction (t))
938 ret = ctype_getReturnType (t);
942 if (ctype_isKnown (t))
944 llbug (message ("not function: %s", ctype_unparse (t)));
951 if (fileloc_isSpec (f) || fileloc_isImport (f))
953 e->whereSpecified = f;
954 e->whereDeclared = fileloc_undefined;
958 e->whereSpecified = fileloc_undefined;
959 e->whereDeclared = f;
962 /* e->shallowCopy = FALSE; */
963 e->uname = cstring_copy (n);
965 e->storageclass = SCNONE;
967 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
969 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
971 if (ctype_isUA (ret))
973 sRef_setStateFromType (e->sref, ret);
978 e->uses = filelocList_new ();
980 e->hasNameError = FALSE;
984 e->info = (uinfo) dmalloc (sizeof (*e->info));
985 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
987 e->info->fcn->hasMods = sRefSet_isDefined (mods);
988 e->info->fcn->hasGlobs = globSet_isDefined (globs);
990 e->info->fcn->exitCode = XK_UNKNOWN;
991 e->info->fcn->nullPred = qual_createUnknown ();
992 e->info->fcn->specialCode = SPC_NONE;
994 e->info->fcn->access = access;
995 e->info->fcn->globs = globs;
996 e->info->fcn->defparams = uentryList_undefined;
998 sRef_setDefined (e->sref, f);
999 e->whereDefined = fileloc_undefined;
1001 e->info->fcn->mods = sRefSet_undefined;
1002 e->info->fcn->specclauses = NULL;
1005 e->info->fcn->preconditions = NULL;
1009 e->info->fcn->postconditions = NULL;
1012 checkGlobalsModifies (e, mods);
1013 e->info->fcn->mods = mods;
1018 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
1020 functionClauseList_elements (clauses, el)
1022 DPRINTF (("Reflect clause: %s on %s",
1023 functionClause_unparse (el), uentry_getName (ue)));
1025 if (functionClause_isNoMods (el))
1027 modifiesClause mel = functionClause_getModifies (el);
1029 if (uentry_hasGlobs (ue))
1034 ("No globals and modifies inconsistent to globals clause for %q: %q",
1035 uentry_getName (ue),
1036 globSet_unparse (uentry_getGlobs (ue))),
1037 modifiesClause_getLoc (mel));
1041 if (uentry_hasMods (ue))
1046 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1047 uentry_getName (ue),
1048 sRefSet_unparse (uentry_getMods (ue))),
1049 modifiesClause_getLoc (mel));
1052 uentry_setGlobals (ue, globSet_undefined);
1053 uentry_setModifies (ue, sRefSet_undefined);
1055 else if (functionClause_isGlobals (el))
1057 globalsClause glc = functionClause_getGlobals (el);
1059 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1060 globalsClause_unparse (glc)));
1062 if (uentry_hasGlobs (ue))
1067 ("Multiple globals clauses for %q: %q",
1068 uentry_getName (ue),
1069 globalsClause_unparse (glc)),
1070 globalsClause_getLoc (glc));
1071 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1075 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1076 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1077 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1080 else if (functionClause_isModifies (el))
1082 modifiesClause mlc = functionClause_getModifies (el);
1084 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1086 if (uentry_hasMods (ue))
1094 ("Multiple modifies clauses for %s: %s",
1095 uentry_getName (ue),
1096 modifiesClause_unparse (mlc)),
1097 modifiesClause_getLoc (mlc)))
1099 llhint (message ("Previous modifies clause: ",
1100 sRefSet_unparse (uentry_getMods (ue))));
1106 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1110 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1113 else if (functionClause_isEnsures (el))
1115 functionConstraint cl = functionClause_takeEnsures (el);
1116 DPRINTF (("Setting post: %s / %s",
1117 uentry_unparse (ue), functionConstraint_unparse (cl)));
1118 uentry_setPostconditions (ue, cl);
1120 else if (functionClause_isRequires (el))
1122 functionConstraint cl = functionClause_takeRequires (el);
1123 uentry_setPreconditions (ue, cl);
1125 else if (functionClause_isState (el))
1127 stateClause sc = functionClause_takeState (el);
1129 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1131 sRefSet rfs = stateClause_getRefs (sc);
1133 sRefSet_elements (rfs, s)
1135 if (sRef_isParam (s))
1138 ** Can't use requires on parameters
1142 (FLG_ANNOTATIONERROR,
1143 message ("Requires clauses for %q concerns parameters %q should be "
1144 "a parameter annotation instead: %q",
1145 uentry_unparse (ue),
1147 stateClause_unparse (sc)),
1148 stateClause_loc (sc));
1150 } end_sRefSet_elements ;
1153 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1154 uentry_addStateClause (ue, sc);
1156 else if (functionClause_isWarn (el))
1158 warnClause wc = functionClause_takeWarn (el);
1159 uentry_addWarning (ue, wc);
1163 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1165 } end_functionClauseList_elements ;
1167 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1168 stateClauseList_checkAll (ue);
1171 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1173 bool leaveFunc = FALSE;
1175 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1176 typeId_invalid, globSet_undefined,
1177 sRefSet_undefined, warnClause_undefined,
1180 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1183 ** This makes parameters names print out correctly.
1184 ** (But we might be a local variable declaration for a function type...)
1187 if (context_inFunctionLike ())
1189 DPRINTF (("Header: %s / %s",
1190 uentry_unparse (context_getHeader ()),
1191 idDecl_unparse (id)));
1195 context_enterFunctionDeclaration (ue);
1199 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1200 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1201 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1202 reflectImplicitFunctionQualifiers (ue, FALSE);
1203 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1204 uentry_reflectClauses (ue, idDecl_getClauses (id));
1205 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1207 if (!uentry_isStatic (ue)
1208 && cstring_equalLit (ue->uname, "main"))
1210 ctype typ = ue->utype;
1214 llassert (ctype_isFunction (typ));
1216 retval = ctype_getReturnType (typ);
1218 if (!ctype_isInt (retval))
1222 message ("Function main declared to return %s, should return int",
1223 ctype_unparse (retval)),
1224 uentry_whereDeclared (ue));
1227 args = ctype_argsFunction (typ);
1229 if (uentryList_isMissingParams (args)
1230 || uentryList_size (args) == 0)
1236 if (uentryList_size (args) != 2)
1240 message ("Function main declared with %d arg%&, "
1241 "should have 2 (int argc, char *argv[])",
1242 uentryList_size (args)),
1243 uentry_whereLast (ue));
1247 uentry arg = uentryList_getN (args, 0);
1248 ctype ct = uentry_getType (arg);
1250 if (!ctype_isInt (ct))
1254 message ("Parameter 1, %q, of function main declared "
1255 "with type %t, should have type int",
1256 uentry_getName (arg), ct),
1257 uentry_whereDeclared (arg));
1260 arg = uentryList_getN (args, 1);
1261 ct = uentry_getType (arg);
1263 if (ctype_isArrayPtr (ct)
1264 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1265 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1273 message ("Parameter 2, %q, of function main declared "
1274 "with type %t, should have type char **",
1275 uentry_getName (arg), ct),
1276 uentry_whereDeclared (arg));
1284 context_exitFunctionDeclaration ();
1290 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1292 alkind ak = sRef_getAliasKind (e->sref);
1294 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1295 && context_getFlag (FLG_PARAMIMPTEMP))
1297 exkind ek = sRef_getExKind (e->sref);
1299 if (exkind_isKnown (ek))
1301 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1302 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1303 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1307 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1308 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1313 static /*@only@*/ /*@notnull@*/ uentry
1314 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1315 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1317 cstring pname = makeParam (n);
1320 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1321 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1323 cstring_free (pname);
1324 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1325 uentry_implicitParamAnnots (e);
1326 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1328 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1330 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1331 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1332 e->info->var->defstate = defstate;
1335 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1341 uentry_setRefCounted (uentry e)
1343 if (uentry_isValid (e))
1345 uentry_setAliasKind (e, AK_REFCOUNTED);
1346 sRef_storeState (e->sref);
1352 uentry_setStatic (uentry c)
1354 if (uentry_isValid (c))
1356 alkind ak = sRef_getAliasKind (c->sref);
1357 c->storageclass = SCSTATIC;
1359 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1361 if (!alkind_isUnknown (ak)
1362 && !alkind_isStatic (ak))
1364 if (!(ctype_isRealPointer (uentry_getType (c)))
1365 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1366 && !alkind_isRefCounted (ak))
1368 if (alkind_isImplicit (ak)
1369 && alkind_isDependent (ak)
1370 && ctype_isArray (uentry_getType (c)))
1372 ; /* no error for observer arrays */
1378 message ("Static storage %q declared as %s",
1380 alkind_unparse (ak)),
1381 uentry_whereDeclared (c));
1387 if (alkind_isUnknown (ak)
1388 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1389 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1391 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1392 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1400 uentry_setExtern (uentry c)
1402 if (uentry_isValid (c))
1403 c->storageclass = SCEXTERN;
1407 uentry_setParamNo (uentry ue, int pno)
1409 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1410 sRef_setParamNo (ue->sref, pno);
1414 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1416 sRefSet_allElements (sr, el)
1418 sRef base = sRef_getRootBase (el);
1420 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1421 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1423 if (!globSet_member (ue->info->fcn->globs, base))
1425 if (uentry_hasGlobs (ue)
1426 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1429 (FLG_WARNMISSINGGLOBALS,
1431 ("Modifies list for %q uses global %q, "
1432 "not included in globals list.",
1433 uentry_getName (ue),
1434 sRef_unparse (base)),
1435 uentry_whereLast (ue)))
1437 uentry_showWhereSpecified (ue);
1441 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1443 if (sRef_isFileStatic (base))
1445 context_recordFileGlobals (ue->info->fcn->globs);
1449 } end_sRefSet_allElements;
1453 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1455 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1459 uentry_fixupSref (uentry ue)
1463 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1468 sr = uentry_getSref (ue);
1470 sRef_resetState (sr);
1471 sRef_clearDerived (sr);
1473 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1474 llassert (sRef_isValid (sr));
1476 if (uentry_isVariable (ue))
1479 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1480 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1481 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1485 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1488 ** Okay to allow multiple clauses of the same kind.
1489 */ /*@i834 is this true?@*/
1491 ue->info->fcn->specclauses =
1492 stateClauseList_add (ue->info->fcn->specclauses, sc);
1494 /* Will call checkAll to check later... */
1497 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1499 llassert (uentry_isFunction (ue));
1500 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1502 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1503 ue->info->fcn->specclauses = clauses;
1504 stateClauseList_checkAll (ue);
1505 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1509 ** Used for @modifies@ @endmodifies@ syntax.
1511 ** If ue is specified, sr must contain *only*:
1513 ** o file static globals
1514 ** o sRef's derived from modifies spec (i.e., more specific than
1515 ** what was specified)
1517 ** Otherwise, if sr has modifies it must match sr.
1519 ** If it doesn't have modifies, set them to sr.
1523 uentry_checkModifiesContext (void)
1525 if (sRef_modInFunction ())
1529 ("Modifies list not in function context. "
1530 "A modifies list can only appear following the parameter list "
1531 "in a function declaration or header."));
1540 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1542 if (!uentry_checkModifiesContext ())
1548 if (uentry_isValid (ue))
1550 if (uentry_isIter (ue))
1552 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1553 ue->info->iter->mods = sr;
1557 uentry_convertVarFunction (ue);
1558 llassertfatal (uentry_isFunction (ue));
1559 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1561 ue->info->fcn->mods = sr;
1562 ue->info->fcn->hasMods = TRUE;
1564 checkGlobalsModifies (ue, sr);
1567 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1569 ue->info->fcn->hasGlobs = TRUE;
1572 if (sRefSet_hasStatic (ue->info->fcn->mods))
1574 context_recordFileModifies (ue->info->fcn->mods);
1584 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1587 ** Function already has one modifies clause (possibly from
1588 ** a specification).
1591 if (!uentry_checkModifiesContext ())
1596 llassert (uentry_isValid (ue));
1598 if (uentry_isIter (ue))
1600 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1604 llassertfatal (uentry_isFunction (ue));
1605 llassert (ue->info->fcn->hasMods);
1607 checkGlobalsModifies (ue, sr);
1608 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1610 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1612 ue->info->fcn->hasGlobs = TRUE;
1616 if (sRefSet_hasStatic (ue->info->fcn->mods))
1618 context_recordFileModifies (ue->info->fcn->mods);
1622 bool uentry_hasWarning (uentry ue)
1624 return (uentry_isValid (ue)
1625 && warnClause_isDefined (ue->warn));
1628 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1630 llassert (uentry_isValid (ue));
1631 llassert (warnClause_isUndefined (ue->warn));
1636 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1638 if (sRef_modInFunction ())
1641 (message ("Precondition list not in function context. "
1642 "A precondition list can only appear following the parameter list "
1643 "in a function declaration or header."));
1645 /*@-mustfree@*/ return; /*@=mustfree@*/
1648 if (uentry_isValid (ue))
1650 uentry_convertVarFunction (ue);
1651 llassertfatal (uentry_isFunction (ue));
1653 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1656 I changed this so it didn't appear as a Splint bug
1657 among other things this gets triggered when there is
1658 a function with two requires clauses. Now Splint
1659 prints an error and tries to conjoin the lists.
1662 (message ("Duplicate precondition list"
1663 "Attemping the conjoin the requires clauses"
1667 /* should conjoin constraints? */
1669 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1673 ue->info->fcn->preconditions = preconditions;
1678 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1687 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1689 if (sRef_modInFunction ())
1692 (message ("Postcondition list not in function context. "
1693 "A postcondition list can only appear following the parameter list "
1694 "in a function declaration or header."));
1696 /*@-mustfree@*/ return; /*@=mustfree@*/
1699 if (uentry_isValid (ue))
1701 uentry_convertVarFunction (ue);
1702 llassertfatal (uentry_isFunction (ue));
1704 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1706 ue->info->fcn->postconditions = postconditions;
1710 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1715 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1720 ** requires: new and old are functions
1724 checkGlobalsConformance (/*@notnull@*/ uentry old,
1725 /*@notnull@*/ uentry unew,
1726 bool mustConform, bool completeConform)
1728 bool hasInternalState = FALSE;
1730 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1732 if (globSet_isDefined (unew->info->fcn->globs))
1734 globSet_allElements (unew->info->fcn->globs, el)
1736 if (sRef_isFileStatic (el))
1738 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1740 if (sRef_isInvalid (sr))
1742 bool hasError = FALSE;
1744 if (!hasInternalState
1745 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1746 sRef_makeInternalState ()))
1747 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1748 sRef_makeSpecState ())))
1751 && !uentry_isStatic (old)
1754 message ("Globals list for %q includes internal state, %q, "
1755 "but %s without globals internalState.",
1756 uentry_getName (old),
1758 uentry_specOrDefName (old)),
1759 uentry_whereLast (unew)))
1761 uentry_showWhereSpecified (old);
1765 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1766 sRef_makeInternalState ());
1767 hasInternalState = TRUE;
1771 && fileloc_sameFile (uentry_whereDeclared (unew),
1772 uentry_whereDeclared (old)))
1777 message ("Function %q inconsistently %rdeclared (in "
1778 "same file) with file static global %q in "
1780 uentry_getName (unew),
1781 uentry_isDeclared (old),
1783 uentry_whereDeclared (unew)))
1785 uentry_showWhereSpecified (old);
1790 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1791 context_recordFileGlobals (old->info->fcn->globs);
1795 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1797 if (sRef_isInvalid (sr))
1802 message ("Function %q inconsistently %rdeclared with "
1803 "%q in globals list",
1804 uentry_getName (unew),
1805 uentry_isDeclared (old),
1807 uentry_whereDeclared (unew)))
1809 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1810 uentry_showWhereSpecified (old);
1815 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1821 ("Function %q global %q inconsistently "
1822 "%rdeclared as %qout global",
1823 uentry_getName (unew),
1825 uentry_isDeclared (old),
1826 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1827 uentry_whereDeclared (unew)))
1829 uentry_showWhereSpecified (old);
1834 } end_globSet_allElements ;
1836 if (completeConform)
1838 globSet_allElements (old->info->fcn->globs, el)
1840 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1842 if (sRef_isInvalid (sr))
1845 && uentry_isReallySpecified (old)
1848 message ("Function %q specified with %q in globals list, "
1849 "but declared without %q",
1850 uentry_getName (unew),
1853 uentry_whereDeclared (unew)))
1855 uentry_showWhereSpecified (old);
1858 } end_globSet_allElements;
1863 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1865 if (uentry_isReallySpecified (old)
1868 message ("%s %q specified with globals list, but "
1869 "declared with no globals",
1870 ekind_capName (unew->ukind),
1871 uentry_getName (unew)),
1872 uentry_whereDeclared (unew)))
1875 (message ("Specification globals: %q",
1876 globSet_unparse (old->info->fcn->globs)),
1877 uentry_whereSpecified (old));
1881 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1882 old->info->fcn->globs);
1887 ** new modifies list must be included by old modifies list.
1889 ** file static state may be added to new, if old has internal.
1893 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1894 bool mustConform, bool completeConform)
1897 bool changedMods = FALSE;
1898 bool modInternal = FALSE;
1900 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1902 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1903 newMods = unew->info->fcn->mods;
1905 if (sRefSet_isEmpty (newMods))
1907 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1908 && uentry_isReallySpecified (old))
1912 message ("%s %q specified with modifies clause, "
1913 "but declared with no modifies clause",
1914 ekind_capName (unew->ukind),
1915 uentry_getName (unew)),
1916 uentry_whereDeclared (unew)))
1918 llgenindentmsg (message ("Specification has modifies %q",
1919 sRefSet_unparse (old->info->fcn->mods)),
1920 uentry_whereSpecified (old));
1927 sRefSet_allElements (newMods, current)
1929 if (sRef_isValid (current))
1931 sRef rb = sRef_getRootBase (current);
1933 if (sRef_isFileStatic (rb))
1937 if (!sRefSet_isSameMember (old->info->fcn->mods,
1938 sRef_makeInternalState ())
1939 && !sRefSet_isSameMember (old->info->fcn->mods,
1940 sRef_makeSpecState ()))
1943 && !uentry_isStatic (old)
1947 ("Modifies list for %q includes internal state, "
1948 "but %s without modifies internal.",
1949 uentry_getName (old),
1950 uentry_specOrDefName (old)),
1951 uentry_whereLast (unew)))
1953 uentry_showWhereSpecified (old);
1956 old->info->fcn->mods =
1957 sRefSet_insert (old->info->fcn->mods,
1958 sRef_makeInternalState ());
1963 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1969 if (sRef_canModifyVal (current, old->info->fcn->mods))
1971 int size = sRefSet_size (old->info->fcn->mods);
1973 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1976 if (sRefSet_size (old->info->fcn->mods) != size)
1987 ("Modifies list for %q contains %q, not modifiable "
1989 uentry_getName (old),
1990 sRef_unparse (current),
1991 uentry_specDeclName (old)),
1992 uentry_whereLast (unew)))
1994 uentry_showWhereSpecified (old);
1999 } end_sRefSet_allElements;
2001 if (completeConform && uentry_isReallySpecified (old))
2003 sRefSet_allElements (old->info->fcn->mods, el)
2005 if (sRef_canModify (el, newMods))
2014 ("Specification modifies clause for %q contains %q, "
2015 "not included in declaration modifies clause",
2016 uentry_getName (old),
2018 uentry_whereLast (unew)))
2020 uentry_showWhereSpecified (old);
2023 } end_sRefSet_allElements ;
2027 ** Make sure file static elements will be removed.
2032 context_recordFileModifies (old->info->fcn->mods);
2037 uentry_checkMutableType (uentry ue)
2039 ctype ct = uentry_getType (ue);
2041 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2043 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2045 voptgenerror (FLG_MUTREP,
2046 message ("Mutable abstract type %q declared without pointer "
2047 "indirection: %t (violates assignment semantics)",
2048 uentry_getName (ue), ct),
2049 uentry_whereDeclared (ue));
2054 uentry_setMutable (uentry e)
2056 llassert (uentry_isDatatype (e));
2057 e->info->datatype->mut = YES;
2061 uentry_checkIterArgs (uentry ue)
2063 bool hasYield = FALSE;
2066 llassert (uentry_isIter (ue));
2068 args = uentry_getParams (ue);
2070 uentryList_elements (args, el)
2072 sstate ds = uentry_getDefState (el);
2074 if (uentry_isYield (el))
2079 if (sstate_isUnknown (ds))
2081 uentry_setDefState (el, SS_DEFINED);
2087 } end_uentryList_elements;
2091 voptgenerror (FLG_HASYIELD,
2092 message ("Iterator %q declared with no yield parameters",
2093 uentry_getName (ue)),
2094 uentry_whereDeclared (ue));
2099 chkind_fromQual (qual qel)
2101 if (qual_isChecked (qel))
2105 else if (qual_isCheckMod (qel))
2109 else if (qual_isCheckedStrict (qel))
2111 return CH_CHECKEDSTRICT;
2113 else if (qual_isUnchecked (qel))
2115 return CH_UNCHECKED;
2120 /*@notreached@*/ return CH_UNKNOWN;
2125 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2127 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2129 if (!uentry_isRefCounted (ue))
2132 (FLG_ANNOTATIONERROR,
2133 message ("Reference counting qualifier %s used on non-reference "
2134 "counted storage: %q",
2136 uentry_unparse (ue)),
2137 uentry_whereLast (ue));
2141 alkind ak = alkind_fromQual (qel);
2143 uentry_setAliasKind (ue, ak);
2146 else if (qual_isRefCounted (qel))
2148 ctype ct = ctype_realType (uentry_getType (ue));
2151 if (ctype_isPointer (ct)
2152 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2154 /* check there is a refs field */
2155 uentryList fields = ctype_getFields (rt);
2156 uentry refs = uentry_undefined;
2158 uentryList_elements (fields, field)
2160 if (uentry_isRefsField (field))
2162 if (uentry_isValid (refs))
2165 (FLG_ANNOTATIONERROR,
2166 message ("Reference counted structure type %s has "
2167 "multiple refs fields: %q and %q",
2169 uentry_getName (refs),
2170 uentry_getName (field)),
2171 uentry_whereLast (field));
2176 } end_uentryList_elements;
2178 if (uentry_isInvalid (refs))
2182 message ("Reference counted structure type %s has "
2184 ctype_unparse (ct)),
2186 ("To count reference, the structure must have a field named "
2187 "refs of type int."),
2190 else if (!ctype_isInt (uentry_getType (refs)))
2193 (FLG_ANNOTATIONERROR,
2194 message ("Reference counted structure type %s refs field has "
2195 "type %s (should be int)", ctype_unparse (ct),
2196 ctype_unparse (uentry_getType (refs))),
2197 uentry_whereLast (refs));
2201 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2202 uentry_whereDeclared (ue));
2207 if ((ctype_isPointer (ct)
2208 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2209 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2211 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2212 uentry_whereDeclared (ue));
2217 (FLG_ANNOTATIONERROR,
2218 message ("Non-pointer to structure type %s declared with "
2219 "refcounted qualifier",
2220 ctype_unparse (ct)),
2221 uentry_whereLast (ue));
2225 else if (qual_isRefs (qel))
2227 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2229 uentry_setAliasKind (ue, AK_REFS);
2234 (FLG_ANNOTATIONERROR,
2235 message ("Refs qualifier used on non-structure field: %q",
2236 uentry_unparse (ue)),
2237 uentry_whereLast (ue));
2240 else if (qual_isAliasQual (qel))
2242 alkind ak = alkind_fromQual (qel);
2244 alkind oldak = uentry_getAliasKind (ue);
2245 ctype ut = uentry_getType (ue);
2247 if (alkind_isImplicit (ak)
2248 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2250 /* ignore the implied qualifier */
2254 if (uentry_isEitherConstant (ue))
2257 (FLG_ANNOTATIONERROR,
2258 message ("Alias qualifier %s used on constant: %q",
2259 alkind_unparse (ak), uentry_unparse (ue)),
2260 uentry_whereLast (ue));
2265 if (ctype_isFunction (ut))
2267 ut = ctype_getReturnType (ut);
2270 if (!(ctype_isVisiblySharable (ut)
2271 || ctype_isRealArray (ut)
2272 || ctype_isRealSU (ut)))
2274 if (!qual_isImplied (qel))
2277 (FLG_ANNOTATIONERROR,
2278 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2279 alkind_unparse (ak), ut, uentry_getName (ue)),
2280 uentry_whereLast (ue));
2287 if (uentry_isRefCounted (ue))
2289 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2290 || qual_isExposed (qel)
2291 || qual_isObserver (qel)))
2293 if (!qual_isImplied (qel))
2296 (FLG_ANNOTATIONERROR,
2298 ("Alias qualifier %s used on reference counted storage: %q",
2299 alkind_unparse (ak),
2300 uentry_unparse (ue)),
2301 uentry_whereLast (ue));
2309 if (qual_isRefQual (qel))
2312 (FLG_ANNOTATIONERROR,
2313 message ("Qualifier %s used on non-reference counted storage: %q",
2314 alkind_unparse (ak), uentry_unparse (ue)),
2315 uentry_whereLast (ue));
2324 uentry_setAliasKind (ue, ak);
2327 else if (qual_isNull (qel))
2329 if (uentry_isConstant (ue))
2333 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2334 uentry_whereDeclared (ue));
2338 uentry_setNullState (ue, NS_POSNULL);
2341 else if (qual_isRelNull (qel))
2343 uentry_setNullState (ue, NS_RELNULL);
2345 else if (qual_isNotNull (qel))
2347 uentry_setNullState (ue, NS_MNOTNULL);
2349 else if (qual_isAbstract (qel)
2350 || qual_isConcrete (qel))
2352 if (!uentry_isDatatype (ue))
2355 (FLG_ANNOTATIONERROR,
2356 message ("Qualifier %s used with non-datatype",
2357 qual_unparse (qel)),
2358 uentry_whereLast (ue));
2362 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2365 else if (qual_isMutable (qel))
2367 if (!uentry_isDatatype (ue))
2370 (FLG_ANNOTATIONERROR,
2371 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2372 uentry_whereLast (ue));
2376 if (!ynm_isOn (ue->info->datatype->mut))
2378 uentry_checkMutableType (ue);
2381 ue->info->datatype->mut = YES;
2384 else if (qual_isImmutable (qel))
2386 if (!uentry_isDatatype (ue))
2388 voptgenerror (FLG_ANNOTATIONERROR,
2389 message ("Qualifier %s used with non-datatype",
2390 qual_unparse (qel)),
2391 uentry_whereLast (ue));
2395 ue->info->datatype->mut = NO;
2398 else if (qual_isNullPred (qel))
2400 uentry_convertVarFunction (ue);
2402 if (uentry_isFunction (ue))
2404 ctype typ = uentry_getType (ue);
2405 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2407 if (ctype_isRealBool (rtype))
2409 uentryList pl = ctype_argsFunction (typ);
2411 if (uentryList_size (pl) == 1)
2413 ue->info->fcn->nullPred = qel;
2417 voptgenerror (FLG_ANNOTATIONERROR,
2418 message ("Qualifier %s used with function having %d "
2419 "arguments (should have 1)",
2421 uentryList_size (pl)),
2422 uentry_whereLast (ue));
2427 voptgenerror (FLG_ANNOTATIONERROR,
2428 message ("Qualifier %s used with function returning %s "
2429 "(should return bool)",
2431 ctype_unparse (rtype)),
2432 uentry_whereLast (ue));
2437 voptgenerror (FLG_ANNOTATIONERROR,
2438 message ("Qualifier %s used with non-function",
2439 qual_unparse (qel)),
2440 uentry_whereLast (ue));
2443 else if (qual_isExitQual (qel))
2445 exitkind exk = exitkind_fromQual (qel);
2447 if (uentry_isFunction (ue))
2449 if (exitkind_isKnown (ue->info->fcn->exitCode))
2451 voptgenerror (FLG_ANNOTATIONERROR,
2452 message ("Multiple exit qualifiers used on function %q: %s, %s",
2453 uentry_getName (ue),
2454 exitkind_unparse (ue->info->fcn->exitCode),
2455 exitkind_unparse (exk)),
2456 uentry_whereLast (ue));
2459 ue->info->fcn->exitCode = exk;
2463 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2465 uentry_makeVarFunction (ue);
2466 ue->info->fcn->exitCode = exk;
2470 voptgenerror (FLG_ANNOTATIONERROR,
2471 message ("Exit qualifier %s used with non-function (type %s)",
2473 ctype_unparse (uentry_getType (ue))),
2474 uentry_whereLast (ue));
2478 else if (qual_isMetaState (qel))
2480 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2482 if (annotationInfo_matchesContext (ainfo, ue))
2484 DPRINTF (("Reflecting %s on %s",
2485 annotationInfo_unparse (ainfo),
2486 uentry_unparseFull (ue)));
2488 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2489 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2490 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2495 (FLG_ANNOTATIONERROR,
2496 message ("Attribute annotation %s used in inconsistent context: %q",
2498 uentry_unparse (ue)),
2499 uentry_whereLast (ue)))
2501 /*@i! annotationInfo_showContextError (ainfo, ue); */
2507 if (qual_isCQual (qel))
2513 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2519 uentry_reflectQualifiers (uentry ue, qualList q)
2521 llassert (uentry_isValid (ue));
2523 DPRINTF (("Reflect qualifiers: %s / %s",
2524 uentry_unparseFull (ue), qualList_unparse (q)));
2526 qualList_elements (q, qel)
2528 if (qual_isStatic (qel))
2530 uentry_setStatic (ue);
2532 else if (qual_isUnused (qel))
2534 uentry_setUsed (ue, fileloc_undefined);
2535 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2537 else if (qual_isExternal (qel))
2539 fileloc_free (ue->whereDefined);
2540 ue->whereDefined = fileloc_createExternal ();
2542 else if (qual_isSef (qel))
2544 if (uentry_isVariable (ue))
2546 vkind vk = ue->info->var->kind;
2548 llassert (vk != VKREFPARAM);
2550 if (vk == VKYIELDPARAM)
2553 (FLG_ANNOTATIONERROR,
2554 message ("Qualifier sef cannot be used with %s: %q",
2555 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2556 uentry_unparse (ue)),
2557 uentry_whereLast (ue));
2559 else if (vk == VKRETPARAM)
2561 ue->info->var->kind = VKSEFRETPARAM;
2565 ue->info->var->kind = VKSEFPARAM;
2571 (FLG_ANNOTATIONERROR,
2572 message ("Qualifier sef is meaningful only on parameters: %q",
2573 uentry_unparse (ue)),
2574 uentry_whereLast (ue));
2577 else if (qual_isExtern (qel))
2579 ue->storageclass = SCEXTERN;
2581 else if (qual_isGlobalQual (qel)) /* undef, killed */
2583 DPRINTF (("Reflecting qual: %s / %s",
2584 qual_unparse (qel), uentry_unparse (ue)));
2586 if (uentry_isVariable (ue))
2588 sstate oldstate = ue->info->var->defstate;
2589 sstate defstate = sstate_fromQual (qel);
2592 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2593 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2595 defstate = SS_UNDEFKILLED;
2602 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2603 ue->info->var->defstate = defstate;
2608 (FLG_ANNOTATIONERROR,
2609 message ("Qualifier %s used on non-variable: %q",
2610 qual_unparse (qel), uentry_unparse (ue)),
2611 uentry_whereLast (ue));
2614 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2616 /* start modifications */
2617 else if( qual_isBufQualifier(qel) ) {
2618 ctype ct = ctype_realType(uentry_getType(ue));
2619 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2621 if( uentry_hasBufStateInfo(ue) ) {
2622 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2624 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2625 /* If formal func param */
2626 uentry_setNullTerminatedState(ue);
2627 uentry_setLen (ue, 1);
2628 uentry_setSize (ue, 1);
2630 sRef_setNullTerminatedState(uentry_getSref(ue));
2631 sRef_setLen (uentry_getSref(ue), 1);
2632 sRef_setSize (uentry_getSref(ue), 1);
2634 uentry_setPossiblyNullTerminatedState(ue);
2636 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2640 /* put other BufState Qualifiers here */
2642 cstring s = uentry_getName(ue);
2643 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2644 struct for identifier %s\n", s) );
2646 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2648 sRef retSref = uentry_getSref (ue);
2649 ctype retType = sRef_getType (retSref);
2651 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2652 sRef_setNullTerminatedState (retSref);
2658 message ("Qualifier %s used on non-pointer on \
2659 function return: %q", qual_unparse (qel),
2660 uentry_unparse (ue)));
2667 message ("Qualifier %s used on non-pointer: %q",
2668 qual_unparse (qel), uentry_unparse (ue)));
2670 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2672 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2674 ctype realType = ctype_realType (ue->utype);
2675 sstate defstate = sstate_fromQual (qel);
2677 if (ctype_isFunction (realType))
2679 realType = ctype_realType (ctype_getReturnType (realType));
2682 if (qual_isRelDef (qel))
2684 ; /* okay anywhere */
2688 if (!ctype_isAP (realType)
2689 && !ctype_isSU (realType)
2690 && !ctype_isUnknown (realType)
2691 && !ctype_isAbstract (ue->utype))
2694 (FLG_ANNOTATIONERROR,
2695 message ("Qualifier %s used on non-pointer or struct: %q",
2696 qual_unparse (qel), uentry_unparse (ue)),
2697 uentry_whereLast (ue));
2701 uentry_setDefState (ue, defstate);
2703 if (sRef_isStateSpecial (ue->sref)
2704 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2706 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2709 else if (qual_isYield (qel))
2711 if (uentry_isVariable (ue))
2713 ue->info->var->kind = VKYIELDPARAM;
2718 (FLG_ANNOTATIONERROR,
2719 message ("Qualifier %s used on non-iterator parameter: %q",
2720 qual_unparse (qel), uentry_unparse (ue)),
2721 uentry_whereLast (ue));
2724 else if (qual_isExQual (qel))
2726 exkind ek = exkind_fromQual (qel);
2727 ctype ut = uentry_getType (ue);
2729 DPRINTF (("Reflect ex qual: %s / %s",
2730 uentry_unparse (ue), exkind_unparse (ek)));
2732 if (ctype_isFunction (ut))
2734 ut = ctype_getReturnType (ut);
2737 if (!(ctype_isVisiblySharable (ut))
2738 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2739 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2741 if (!qual_isImplied (qel))
2743 if (ctype_isImmutableAbstract (ut)) {
2745 (FLG_REDUNDANTSHAREQUAL,
2746 message ("Qualifier %s used on unsharable storage type %t: %q",
2747 exkind_unparse (ek), ut, uentry_getName (ue)),
2748 uentry_whereLast (ue));
2751 (FLG_MISPLACEDSHAREQUAL,
2752 message ("Qualifier %s used on unsharable storage type %t: %q",
2753 exkind_unparse (ek), ut, uentry_getName (ue)),
2754 uentry_whereLast (ue));
2760 alkind ak = sRef_getAliasKind (ue->sref);
2762 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2763 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2765 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2767 if (!alkind_isTemp (ak))
2769 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2770 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2773 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2774 || alkind_isOwned (ak))
2782 message ("Exposure qualifier %s used on %s storage (should "
2783 "be dependent): %q",
2785 alkind_unparse (ak),
2786 uentry_unparse (ue)));
2790 else if (qual_isGlobCheck (qel))
2792 if (uentry_isVariable (ue))
2794 chkind ch = chkind_fromQual (qel);
2796 if (ue->info->var->checked != CH_UNKNOWN)
2798 if (ch == ue->info->var->checked)
2800 llerror (FLG_SYNTAX,
2801 message ("Redundant %s qualifier on %q",
2803 uentry_getName (ue)));
2807 llerror (FLG_SYNTAX,
2809 ("Contradictory %s and %s qualifiers on %q",
2811 checkedName (ue->info->var->checked),
2812 uentry_getName (ue)));
2816 ue->info->var->checked = ch;
2822 message ("Qualifier %s used with non-variable",
2823 qual_unparse (qel)));
2826 else if (qual_isReturned (qel))
2828 if (uentry_isVariable (ue))
2830 ue->info->var->kind = VKRETPARAM;
2834 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2835 qual_unparse (qel)));
2840 uentry_reflectOtherQualifier (ue, qel);
2843 sRef_storeState (ue->sref);
2844 } end_qualList_elements;
2848 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2852 uentry_isOnly (uentry ue)
2854 return (!uentry_isUndefined (ue)
2855 && uentry_isVariable (ue)
2856 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2860 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2862 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2863 sRef_setOrigAliasKind (ue->sref, ak);
2867 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2869 if (uentry_isVariable (ue))
2871 ue->info->var->nullstate = ns;
2874 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2878 uentry_isUnique (uentry ue)
2880 return (!uentry_isUndefined (ue)
2881 && uentry_isVariable (ue)
2882 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2886 uentry_isFileStatic (uentry ue)
2888 return (uentry_isStatic (ue)
2889 && (!uentry_isVariable (ue)
2890 || sRef_isFileStatic (uentry_getSref (ue))));
2894 uentry_isExported (uentry ue)
2896 if (uentry_isValid (ue))
2898 if (uentry_isVariable (ue))
2900 return (sRef_isRealGlobal (uentry_getSref (ue)));
2904 return !uentry_isStatic (ue);
2912 uentry_isNonLocal (uentry ue)
2914 return (uentry_isValid (ue) && uentry_isVariable (ue)
2915 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2919 uentry_isGlobalVariable (uentry ue)
2921 return (uentry_isValid (ue) && uentry_isVariable (ue)
2922 && sRef_isFileOrGlobalScope (ue->sref));
2926 uentry_isVisibleExternally (uentry ue)
2928 return (uentry_isValid (ue)
2929 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2930 || (!uentry_isStatic (ue)
2931 && (uentry_isFunction (ue)
2932 || uentry_isIter (ue)
2933 || uentry_isEndIter (ue)
2934 || uentry_isConstant (ue)
2935 || uentry_isDatatype (ue)
2936 || uentry_isAnyTag (ue)))));
2940 uentry_isPrintfLike (uentry ue)
2942 return (uentry_isFunction (ue)
2943 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2947 uentry_isScanfLike (uentry ue)
2949 return (uentry_isFunction (ue)
2950 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2954 uentry_isMessageLike (uentry ue)
2956 return (uentry_isFunction (ue)
2957 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2960 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2962 uentryList args = uentry_getParams (ue);
2964 if (!uentryList_isMissingParams (args))
2966 uentry last = uentry_undefined;
2968 uentryList_elements (args, current)
2970 if (uentry_isElipsisMarker (current))
2972 if (uentry_isUndefined (last))
2976 message ("Function %q is marked %s, but has no format "
2977 "string argument before elipsis",
2978 uentry_getName (ue),
2979 specCode_unparse (ue->info->fcn->specialCode)),
2980 uentry_whereLast (ue));
2981 ue->info->fcn->specialCode = SPC_NONE;
2985 ctype rt = ctype_realType (uentry_getType (last));
2987 if (!ctype_match (rt, ctype_string))
2991 /* wchar_t * is okay too */
2992 if (ctype_isAP (rt))
2994 ctype base = ctype_baseArrayPtr (rt);
2996 if (ctype_isArbitraryIntegral (base))
3006 message ("Function %q is marked %s, but the argument "
3007 "before the elipsis has type %s (should be char *)",
3008 uentry_getName (ue),
3009 specCode_unparse (ue->info->fcn->specialCode),
3010 ctype_unparse (uentry_getType (last))),
3011 uentry_whereLast (ue));
3013 ue->info->fcn->specialCode = SPC_NONE;
3020 } end_uentryList_elements ;
3024 message ("Function %q is marked %s, but has no elipsis parameter",
3025 uentry_getName (ue),
3026 specCode_unparse (ue->info->fcn->specialCode)),
3027 uentry_whereLast (ue));
3029 ue->info->fcn->specialCode = SPC_NONE;
3034 uentry_setPrintfLike (uentry ue)
3036 uentry_convertVarFunction (ue);
3037 llassertfatal (uentry_isFunction (ue));
3038 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3039 checkSpecialFunction (ue);
3043 uentry_setScanfLike (uentry ue)
3045 uentry_convertVarFunction (ue);
3046 llassertfatal (uentry_isFunction (ue));
3047 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3048 checkSpecialFunction (ue);
3052 uentry_setMessageLike (uentry ue)
3054 uentry_convertVarFunction (ue);
3055 llassertfatal (uentry_isFunction (ue));
3056 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3057 checkSpecialFunction (ue);
3061 uentry_isSpecialFunction (uentry ue)
3063 return (uentry_isFunction (ue)
3064 && (ue->info->fcn->specialCode != SPC_NONE));
3067 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3069 ctype ct = idDecl_getCtype (t);
3071 fileloc loc = setLocation ();
3072 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3073 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3075 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3076 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3077 uentry_implicitParamAnnots (ue);
3079 /* Parameter type [][] or [x][] is invalid */
3081 while (ctype_isFixedArray (base)) {
3082 base = ctype_baseArrayPtr (base);
3085 if (ctype_isIncompleteArray (base)) {
3086 base = ctype_baseArrayPtr (base);
3088 if (ctype_isArray (base)) {
3089 if (!uentry_hasName (ue)) {
3090 (void) optgenerror (FLG_INCOMPLETETYPE,
3091 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3093 ctype_unparse (ct)),
3094 uentry_whereLast (ue));
3096 (void) optgenerror (FLG_INCOMPLETETYPE,
3097 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3098 uentry_getName (ue),
3099 ctype_unparse (ct)),
3100 uentry_whereLast (ue));
3105 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3109 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3111 ctype ct = idDecl_getCtype (t);
3113 if (ctype_isFunction (ct))
3115 return (uentry_makeIdFunction (t));
3119 fileloc loc = setLocation ();
3120 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3122 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3124 if (!uentry_isExtern (ue))
3126 uentry_setDefined (ue, loc);
3134 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3136 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3144 static /*@only@*/ /*@notnull@*/
3145 uentry uentry_makeConstantAux (cstring n, ctype t,
3146 /*@keep@*/ fileloc f, bool priv, bool macro,
3147 /*@only@*/ multiVal m)
3149 uentry e = uentry_alloc ();
3152 e->uname = cstring_copy (n);
3154 e->storageclass = SCNONE;
3156 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3158 e->sref = sRef_makeConst (t);
3163 e->uses = filelocList_new ();
3164 e->isPrivate = priv;
3165 e->hasNameError = FALSE;
3167 e->info = (uinfo) dmalloc (sizeof (*e->info));
3168 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3169 e->info->uconst->access = typeIdSet_undefined;
3170 e->info->uconst->macro = macro;
3172 uentry_setSpecDef (e, f);
3174 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3176 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3179 uentry_setConstantValue (e, m);
3184 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3186 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3190 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3192 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3196 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3198 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3202 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3204 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3205 idDecl_getCtype (t),
3208 llassert (fileloc_isUndefined (ue->whereDeclared));
3209 ue->whereDeclared = setLocation ();
3210 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3212 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3213 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3221 void uentry_setDefState (uentry ue, sstate defstate)
3223 if (uentry_isValid (ue))
3225 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3227 if (uentry_isVariable (ue))
3229 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3234 bool uentry_isCheckedUnknown (uentry ue)
3236 return (uentry_isVar (ue)
3237 && (ue->info->var->checked == CH_UNKNOWN));
3240 bool uentry_isCheckMod (uentry ue)
3242 return (uentry_isVar (ue)
3243 && (ue->info->var->checked == CH_CHECKMOD));
3246 bool uentry_isUnchecked (uentry ue)
3248 return (uentry_isVar (ue)
3249 && (ue->info->var->checked == CH_UNCHECKED));
3252 bool uentry_isChecked (uentry ue)
3254 return (uentry_isVar (ue)
3255 && (ue->info->var->checked == CH_CHECKED));
3258 bool uentry_isCheckedModify (uentry ue)
3260 return (uentry_isVar (ue)
3261 && (ue->info->var->checked == CH_CHECKED
3262 || ue->info->var->checked == CH_CHECKMOD
3263 || ue->info->var->checked == CH_CHECKEDSTRICT));
3266 bool uentry_isCheckedStrict (uentry ue)
3268 return (uentry_isVar (ue)
3269 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3272 void uentry_setUnchecked (uentry ue)
3274 llassert (uentry_isVar (ue));
3276 ue->info->var->checked = CH_UNCHECKED;
3279 void uentry_setChecked (uentry ue)
3281 llassert (uentry_isVar (ue));
3283 ue->info->var->checked = CH_CHECKED;
3286 void uentry_setCheckMod (uentry ue)
3288 llassert (uentry_isVar (ue));
3290 ue->info->var->checked = CH_CHECKMOD;
3293 void uentry_setCheckedStrict (uentry ue)
3295 llassert (uentry_isVar (ue));
3297 ue->info->var->checked = CH_CHECKEDSTRICT;
3300 static /*@only@*/ /*@notnull@*/
3301 uentry uentry_makeVariableAux (cstring n, ctype t,
3303 /*@exposed@*/ sRef s,
3304 bool priv, vkind kind)
3306 uentry e = uentry_alloc ();
3309 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3312 e->uname = cstring_copy (n);
3315 e->storageclass = SCNONE;
3317 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3324 e->uses = filelocList_new ();
3325 e->isPrivate = priv;
3326 e->hasNameError = FALSE;
3328 e->info = (uinfo) dmalloc (sizeof (*e->info));
3329 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3330 e->info->var->kind = kind;
3332 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3333 e->info->var->checked = CH_UNKNOWN;
3335 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3336 uentry_setSpecDef (e, f);
3337 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3339 if (ctype_isFunction (rt))
3341 rt = ctype_getReturnType (rt);
3344 if (ctype_isUA (rt))
3346 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3347 sRef_setStateFromType (e->sref, rt);
3350 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3351 e->info->var->defstate = sRef_getDefState (e->sref);
3352 e->info->var->nullstate = sRef_getNullState (e->sref);
3354 /* start modifications */
3355 /* This function sets the uentry for a pointer or array variable declaration,
3356 it allocates memory and sets the fields. We check if the type of the variable
3357 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3359 if (ctype_isArray (t) || ctype_isPointer(t))
3361 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3362 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3363 sRef_setNotNullTerminatedState (s);
3367 e->info->var->bufinfo = NULL;
3369 /* end modification */
3375 uentry_isYield (uentry ue)
3377 return (uentry_isVariable (ue)
3378 && (ue->info->var->kind == VKYIELDPARAM
3379 || ue->info->var->kind == VKREFYIELDPARAM));
3383 uentry_isRefsField (uentry ue)
3385 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3388 /*@only@*/ /*@notnull@*/
3389 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3391 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3392 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3399 void uentry_makeVarFunction (uentry ue)
3406 llassert (uentry_isValid (ue));
3407 llassert (!sRef_modInFunction ());
3409 ak = sRef_getOrigAliasKind (ue->sref);
3410 ek = sRef_getOrigExKind (ue->sref);
3412 llassert (uentry_isVariable (ue));
3413 oldInfo = ue->info->var;
3415 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3416 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3419 ** expanded macro is marked used
3422 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3425 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3426 ue->info->fcn->exitCode = XK_UNKNOWN;
3427 ue->info->fcn->nullPred = qual_createUnknown ();
3428 ue->info->fcn->specialCode = SPC_NONE;
3429 ue->info->fcn->access = typeIdSet_undefined;
3430 ue->info->fcn->hasGlobs = FALSE;
3431 ue->info->fcn->globs = globSet_undefined;
3432 ue->info->fcn->hasMods = FALSE;
3433 ue->info->fcn->mods = sRefSet_undefined;
3434 ue->info->fcn->specclauses = NULL;
3435 ue->info->fcn->defparams = uentryList_undefined;
3438 ue->info->fcn->preconditions = functionConstraint_undefined;
3442 ue->info->fcn->postconditions = functionConstraint_undefined;
3445 if (ctype_isFunction (ue->utype))
3447 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3451 ue->sref = sRef_makeType (ctype_unknown);
3454 if (sRef_isRefCounted (ue->sref))
3460 if (alkind_isUnknown (ak))
3462 if (exkind_isKnown (ek))
3464 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3465 ak = AK_IMPDEPENDENT;
3469 if (context_getFlag (FLG_RETIMPONLY))
3471 if (ctype_isFunction (ue->utype)
3472 && ctype_isVisiblySharable
3473 (ctype_realType (ctype_getReturnType (ue->utype))))
3475 if (uentryList_hasReturned (uentry_getParams (ue)))
3481 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3496 loc = ue->whereDeclared;
3498 sRef_setAliasKind (ue->sref, ak, loc);
3499 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3500 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3501 sRef_setExKind (ue->sref, ek, loc);
3503 if (oldInfo->kind == VKEXPMACRO)
3509 fileloc_free (ue->whereDefined);
3510 ue->whereDefined = fileloc_undefined;
3513 uvinfo_free (oldInfo);
3516 void uentry_makeConstantFunction (uentry ue)
3523 llassert (uentry_isValid (ue));
3524 llassert (!sRef_modInFunction ());
3526 ak = sRef_getOrigAliasKind (ue->sref);
3527 ek = sRef_getOrigExKind (ue->sref);
3529 llassert (uentry_isConstant (ue));
3530 oldInfo = ue->info->uconst;
3532 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3535 ** expanded macro is marked used (until I write a pre-processor)
3539 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3540 ue->info->fcn->exitCode = XK_UNKNOWN;
3541 ue->info->fcn->nullPred = qual_createUnknown ();
3542 ue->info->fcn->specialCode = SPC_NONE;
3543 ue->info->fcn->access = typeIdSet_undefined;
3544 ue->info->fcn->hasGlobs = FALSE;
3545 ue->info->fcn->globs = globSet_undefined;
3546 ue->info->fcn->hasMods = FALSE;
3547 ue->info->fcn->mods = sRefSet_undefined;
3548 ue->info->fcn->specclauses = NULL;
3549 ue->info->fcn->defparams = uentryList_undefined;
3552 ue->info->fcn->preconditions = functionConstraint_undefined;
3556 ue->info->fcn->postconditions = functionConstraint_undefined;
3560 if (ctype_isFunction (ue->utype))
3562 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3566 ue->sref = sRef_makeType (ctype_unknown);
3569 if (sRef_isRefCounted (ue->sref))
3575 if (alkind_isUnknown (ak))
3577 if (exkind_isKnown (ek))
3579 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3580 ak = AK_IMPDEPENDENT;
3584 if (context_getFlag (FLG_RETIMPONLY))
3586 if (ctype_isFunction (ue->utype)
3587 && ctype_isVisiblySharable
3588 (ctype_realType (ctype_getReturnType (ue->utype))))
3590 if (uentryList_hasReturned (uentry_getParams (ue)))
3596 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3611 loc = ue->whereDeclared;
3613 sRef_setAliasKind (ue->sref, ak, loc);
3614 sRef_setExKind (ue->sref, ek, loc);
3616 fileloc_free (ue->whereDefined);
3617 ue->whereDefined = fileloc_undefined;
3618 ucinfo_free (oldInfo);
3622 uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
3624 llassert (uentry_isValid (ue));
3626 globSet_markImmutable (globs);
3628 if (uentry_isIter (ue))
3630 ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
3634 uentry_convertVarFunction (ue);
3635 llassert (uentry_isFunction (ue));
3637 ue->info->fcn->hasGlobs = TRUE;
3638 ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
3641 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3643 ue->info->fcn->hasMods = TRUE;
3647 void uentry_addAccessType (uentry ue, typeId tid)
3649 if (uentry_isFunction (ue))
3651 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3653 else if (uentry_isEitherConstant (ue))
3655 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3657 else if (uentry_isIter (ue))
3659 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3661 else if (uentry_isEndIter (ue))
3663 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3667 llbug (message ("no access for: %q", uentry_unparse (ue)));
3671 /*@only@*/ /*@notnull@*/ uentry
3672 uentry_makeFunction (cstring n, ctype t,
3674 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3675 /*@only@*/ warnClause warn,
3678 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3679 return (uentry_makeFunctionAux (n, t,
3680 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3681 : typeIdSet_single (access)),
3688 /*@notnull@*/ uentry
3689 uentry_makePrivFunction2 (cstring n, ctype t,
3691 globSet globs, sRefSet mods,
3694 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3699 /*@notnull@*/ uentry
3700 uentry_makeSpecFunction (cstring n, ctype t,
3702 /*@only@*/ globSet globs,
3703 /*@only@*/ sRefSet mods,
3706 uentry ue = uentry_makeFunctionAux (n, t, access,
3707 globs, mods, warnClause_undefined,
3710 uentry_setHasGlobs (ue);
3711 uentry_setHasMods (ue);
3713 reflectImplicitFunctionQualifiers (ue, TRUE);
3718 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3720 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3721 sRef_undefined, FALSE, VKEXPMACRO);
3723 uentry_setDefined (ue, f);
3727 /*@notnull@*/ /*@notnull@*/ uentry
3728 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3730 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3731 typeIdSet_singleOpt (access),
3732 globSet_undefined, sRefSet_undefined,
3733 warnClause_undefined,
3737 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3741 bool uentry_isForward (uentry e)
3743 if (uentry_isValid (e))
3745 ctype ct = uentry_getType (e);
3747 return (ctype_isUnknown (ct)
3748 || (ctype_isFunction (ct)
3749 && ctype_isUnknown (ctype_getReturnType (ct))));
3756 /*@notnull@*/ uentry
3757 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3759 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3760 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3764 /*@notnull@*/ uentry
3765 uentry_makeUnspecFunction (cstring n, ctype t,
3769 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3770 sRefSet_undefined, warnClause_undefined,
3773 reflectImplicitFunctionQualifiers (ue, TRUE);
3782 /* is exported for use by usymtab_interface */
3784 /*@notnull@*/ uentry
3785 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3786 fileloc f, bool priv)
3788 uentry e = uentry_alloc ();
3790 DPRINTF (("Make datatype: %s / %s",
3791 n, ctype_unparse (t)));
3793 /* e->shallowCopy = FALSE; */
3794 e->ukind = KDATATYPE;
3795 e->uname = cstring_copy (n);
3797 e->storageclass = SCNONE;
3798 e->sref = sRef_makeUnknown ();
3802 sRef_setStateFromType (e->sref, t);
3805 uentry_setSpecDef (e, f);
3807 e->warn = warnClause_undefined; /*@i634@*/
3808 e->uses = filelocList_new ();
3809 e->isPrivate = priv;
3810 e->hasNameError = FALSE;
3815 e->info = (uinfo) dmalloc (sizeof (*e->info));
3816 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3817 e->info->datatype->abs = abstract;
3818 e->info->datatype->mut = mut;
3819 e->info->datatype->type = ctype_undefined;
3821 if (uentry_isDeclared (e))
3823 uentry_setDefined (e, f);
3826 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3828 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3834 /*@notnull@*/ uentry
3835 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3837 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3840 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3842 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3843 ctype_bool, NO, abstract,
3844 fileloc_getBuiltin (),
3847 ret->info->datatype->type = ctype_bool;
3855 static /*@only@*/ /*@notnull@*/ uentry
3856 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3857 /*@only@*/ fileloc f)
3859 uentry e = uentry_alloc ();
3862 e->uname = cstring_copy (n);
3864 e->sref = sRef_makeUnknown ();
3865 e->storageclass = SCNONE;
3869 uentry_setSpecDef (e, f);
3871 e->warn = warnClause_undefined; /*@i452@*/
3872 e->uses = filelocList_new ();
3873 e->isPrivate = FALSE;
3874 e->hasNameError = FALSE;
3876 e->info = (uinfo) dmalloc (sizeof (*e->info));
3877 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3878 e->info->iter->access = access;
3879 e->info->iter->mods = sRefSet_undefined;
3880 e->info->iter->globs = globSet_undefined;
3882 uentry_checkIterArgs (e);
3886 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3888 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3891 static /*@notnull@*/ uentry
3892 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3894 uentry e = uentry_alloc ();
3896 /* e->shallowCopy = FALSE; */
3897 e->ukind = KENDITER;
3898 e->storageclass = SCNONE;
3899 e->uname = message ("end_%s", n);
3900 e->utype = ctype_unknown;
3901 e->sref = sRef_makeUnknown ();
3903 uentry_setSpecDef (e, f);
3908 e->uses = filelocList_new ();
3909 e->isPrivate = FALSE;
3910 e->hasNameError = FALSE;
3912 e->info = (uinfo) dmalloc (sizeof (*e->info));
3913 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3915 e->info->enditer->access = access;
3917 e->warn = warnClause_undefined; /*@i452@*/
3921 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3923 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3930 static /*@only@*/ /*@notnull@*/ uentry
3931 uentry_makeTagAux (cstring n, ctype t,
3932 /*@only@*/ fileloc fl,
3933 bool priv, ekind kind)
3935 uentry e = uentry_alloc ();
3937 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3939 llbuglit ("uentry_makeTagAux: not a tag type");
3943 /* e->shallowCopy = FALSE; */
3944 e->uname = cstring_copy (n);
3947 e->sref = sRef_makeUnknown ();
3948 e->storageclass = SCNONE;
3950 uentry_setSpecDef (e, fl);
3955 e->uses = filelocList_new ();
3956 e->isPrivate = priv;
3957 e->hasNameError = FALSE;
3959 e->info = (uinfo) dmalloc (sizeof (*e->info));
3960 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3961 e->info->datatype->abs = NO;
3962 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3963 e->info->datatype->type = t;
3964 e->warn = warnClause_undefined; /*@i452@*/
3966 if (uentry_isDeclared (e))
3968 uentry_setDefined (e, fl);
3974 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3976 cstring sname = makeStruct (n);
3977 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3979 cstring_free (sname);
3984 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3986 cstring sname = makeStruct (n);
3987 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3989 cstring_free (sname);
3994 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3996 cstring uname = makeUnion (n);
3997 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3999 cstring_free (uname);
4005 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
4007 cstring ename = makeEnum (n);
4008 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
4010 cstring_free (ename);
4016 uentry_makeUnionTagLoc (cstring n, ctype t)
4018 cstring uname = makeUnion (n);
4019 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4021 cstring_free (uname);
4026 uentry_makeEnumTagLoc (cstring n, ctype t)
4028 cstring ename = makeEnum (n);
4029 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4031 cstring_free (ename);
4036 uentry_isStructTag (uentry ue)
4038 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4042 uentry_isUnionTag (uentry ue)
4044 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4048 uentry_isEnumTag (uentry ue)
4050 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4054 uentry_isAnyTag (uentry ue)
4056 return (uentry_isStructTag (ue)
4057 || uentry_isUnionTag (ue)
4058 || uentry_isEnumTag (ue));
4061 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4063 extern void uentry_destroyMod (void)
4064 /*@globals killed emarker@*/ /*@modifies emarker@*/
4066 static bool wasDestroyed = FALSE;
4068 llassert (!wasDestroyed);
4070 if (emarker != NULL)
4072 uentry_reallyFree (emarker);
4075 wasDestroyed = TRUE;
4079 uentry_makeElipsisMarker (void)
4081 if (emarker == NULL)
4083 emarker = uentry_alloc ();
4085 emarker->ukind = KELIPSMARKER;
4086 emarker->uname = cstring_makeLiteral ("...");
4087 emarker->utype = ctype_elipsMarker;
4088 emarker->sref = sRef_undefined;
4089 emarker->storageclass = SCNONE;
4090 emarker->used = FALSE;
4091 emarker->lset = FALSE;
4092 emarker->info = NULL;
4094 uentry_setSpecDef (emarker, fileloc_undefined);
4095 emarker->uses = filelocList_new ();
4096 emarker->isPrivate = FALSE;
4097 emarker->hasNameError = FALSE;
4100 /*@ignore@*/ return (emarker); /*@end@*/
4108 uentry_equiv (uentry p1, uentry p2)
4110 if (uentry_compare (p1, p2) != 0)
4121 uentry_xcomparealpha (uentry *p1, uentry *p2)
4125 if ((res = uentry_compare (*p1, *p2)) == 0) {
4126 if ((*p1 != NULL) && (*p2 != NULL)) {
4127 res = cstring_compare ((*p1)->uname,
4136 uentry_xcompareuses (uentry *p1, uentry *p2)
4141 if (uentry_isValid (u1))
4143 if (uentry_isValid (u2))
4145 return (-1 * int_compare (filelocList_size (u1->uses),
4146 filelocList_size (u2->uses)));
4155 if (uentry_isValid (u2))
4167 uentry_compareStrict (uentry v1, uentry v2)
4169 COMPARERETURN (uentry_compare (v1, v2));
4171 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4173 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4174 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4175 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4182 uentry_compare (uentry u1, uentry u2)
4184 if (u1 == u2) return 0;
4186 if (uentry_isInvalid (u1)) return -1;
4187 if (uentry_isInvalid (u2)) return 1;
4189 INTCOMPARERETURN (u1->ukind, u2->ukind);
4190 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4191 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4192 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4198 /* bug detected by splint:
4199 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4204 return (multiVal_compare (uentry_getConstantValue (u1),
4205 uentry_getConstantValue (u2)));
4209 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4211 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4212 uentry_accessType (u2)));
4213 return (uentryList_compareParams (uentry_getParams (u1),
4214 uentry_getParams (u2)));
4216 return (typeIdSet_compare (uentry_accessType (u1),
4217 uentry_accessType (u2)));
4220 ** Functions are never equivalent
4223 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4233 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4234 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4235 sRef_getOrigAliasKind (u2->sref)));
4236 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4237 sRef_getOrigExKind (u2->sref)));
4238 COMPARERETURN (generic_compare (u1->info->var->checked,
4239 u2->info->var->checked));
4240 COMPARERETURN (generic_compare (u1->info->var->defstate,
4241 u2->info->var->defstate));
4242 return (generic_compare (u1->info->var->nullstate,
4243 u2->info->var->nullstate));
4245 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4246 u2->info->datatype->type));
4247 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4248 u2->info->datatype->mut));
4249 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4258 ** all entries are: <type>[@<info>]*#<name>
4260 ** info depends on kind:
4264 advanceField (char **s)
4266 reader_checkChar (s, '@');
4270 advanceName (char **s)
4272 reader_checkChar (s, '#');
4276 vkind_fromInt (int i)
4278 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4280 llbuglit ("vkind_fromInt: out of range");
4287 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4288 typeIdSet access, nstate nullstate,
4289 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4291 uentry e = uentry_alloc ();
4296 e->sref = sRef_makeConst (ct);
4298 sRef_setNullState (e->sref, nullstate, loc);
4299 e->storageclass = SCNONE;
4301 if (fileloc_isSpec (loc))
4303 e->whereSpecified = loc;
4304 e->whereDeclared = fileloc_undefined;
4308 e->whereSpecified = fileloc_undefined;
4309 e->whereDeclared = loc;
4312 e->whereDefined = fileloc_undefined;
4313 e->uses = filelocList_new ();
4314 e->isPrivate = FALSE;
4315 e->hasNameError = FALSE;
4320 e->warn = warnClause_undefined; /*@i452@*/
4322 e->info = (uinfo) dmalloc (sizeof (*e->info));
4323 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4324 e->info->uconst->access = access;
4325 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4326 uentry_setConstantValue (e, m);
4327 sRef_storeState (e->sref);
4332 static /*@only@*/ uentry
4333 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4334 sstate defstate, nstate isnull, alkind aliased,
4335 exkind exp, chkind checked,
4336 /*@only@*/ fileloc loc)
4338 uentry e = uentry_alloc ();
4343 e->storageclass = SCNONE;
4345 e->sref = sRef_makeType (ct);
4346 sRef_setNullState (e->sref, isnull, loc);
4348 e->whereDefined = fileloc_undefined;
4350 if (fileloc_isSpec (loc))
4352 e->whereSpecified = loc;
4353 e->whereDeclared = fileloc_undefined;
4357 e->whereSpecified = fileloc_undefined;
4358 e->whereDeclared = loc;
4361 e->isPrivate = FALSE;
4362 e->hasNameError = FALSE;
4367 e->uses = filelocList_new ();
4368 e->warn = warnClause_undefined; /*@i452@*/
4370 e->info = (uinfo) dmalloc (sizeof (*e->info));
4371 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4372 e->info->var->kind = kind;
4373 e->info->var->checked = checked;
4374 e->info->var->defstate = defstate;
4376 sRef_setDefState (e->sref, defstate, loc);
4378 e->info->var->nullstate = sRef_getNullState (e->sref);
4380 sRef_setExKind (e->sref, exp, loc);
4381 sRef_setAliasKind (e->sref, aliased, loc);
4383 sRef_storeState (e->sref);
4385 /*DRL ADDED 9-1-2000 */
4386 e->info->var->bufinfo = NULL;
4391 static /*@only@*/ uentry
4392 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4393 ynm mut, ctype rtype, alkind ak, exkind exp,
4394 sstate defstate, nstate isnull,
4395 /*@only@*/ fileloc loc)
4397 uentry e = uentry_alloc ();
4399 e->ukind = KDATATYPE;
4400 /* e->shallowCopy = FALSE; */
4403 e->storageclass = SCNONE;
4404 e->sref = sRef_makeUnknown ();
4405 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4408 ** This is only setting null state. (I think?)
4411 if (ctype_isUA (ct))
4413 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4415 if (uentry_isValid (te))
4417 sRef_setStateFromUentry (e->sref, te);
4421 /* problem for recursive type definitions */
4425 sRef_setAliasKind (e->sref, ak, loc);
4426 sRef_setExKind (e->sref, exp, loc);
4428 sRef_setDefState (e->sref, defstate, loc);
4430 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4432 isnull = NS_ABSNULL;
4435 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4436 sRef_mergeNullState (e->sref, isnull);
4438 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4440 if (fileloc_isSpec (loc))
4442 e->whereSpecified = loc;
4443 e->whereDeclared = fileloc_undefined;
4447 e->whereSpecified = fileloc_undefined;
4448 e->whereDeclared = loc;
4451 e->isPrivate = FALSE;
4452 e->hasNameError = FALSE;
4454 e->warn = warnClause_undefined; /*@i452@*/
4458 e->uses = filelocList_new ();
4460 e->info = (uinfo) dmalloc (sizeof (*e->info));
4461 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4462 e->info->datatype->abs = abstract;
4463 e->info->datatype->mut = mut;
4464 e->info->datatype->type = rtype;
4466 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4467 sRef_storeState (e->sref);
4468 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4474 static void uentry_setHasGlobs (uentry ue)
4476 llassert (uentry_isFunction (ue));
4478 ue->info->fcn->hasGlobs = TRUE;
4481 static void uentry_setHasMods (uentry ue)
4483 llassert (uentry_isFunction (ue));
4485 ue->info->fcn->hasMods = TRUE;
4489 bool uentry_hasGlobs (uentry ue)
4491 if (uentry_isFunction (ue))
4493 return (ue->info->fcn->hasGlobs);
4499 bool uentry_hasStateClauseList (uentry ue)
4501 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4504 bool uentry_hasConditions (uentry ue)
4506 return (uentry_isFunction (ue)
4507 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4508 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4511 stateClauseList uentry_getStateClauseList (uentry ue)
4513 if (!uentry_isFunction (ue))
4515 llassert (uentry_isFunction (ue));
4516 return stateClauseList_undefined;
4519 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4520 return ue->info->fcn->specclauses;
4523 bool uentry_hasMods (uentry ue)
4525 if (uentry_isFunction (ue))
4527 return (ue->info->fcn->hasMods);
4534 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4536 bool hasGlobs, /*@only@*/ globSet globs,
4537 bool hasMods, /*@only@*/ sRefSet mods,
4538 alkind ak, exkind exp,
4539 sstate defstate, nstate isnull,
4543 /*@only@*/ stateClauseList specclauses,
4544 /*@only@*/ warnClause warnclause,
4545 /*@only@*/ fileloc loc)
4547 uentry e = uentry_alloc ();
4550 /* e->shallowCopy = FALSE; */
4554 e->storageclass = SCNONE;
4556 if (ctype_isFunction (ct))
4558 ret = ctype_getReturnType (ct);
4562 if (ctype_isKnown (ct))
4564 llbug (message ("not function: %s", ctype_unparse (ct)));
4567 ret = ctype_unknown;
4570 e->sref = sRef_makeType (ret);
4572 if (ctype_isUA (ret))
4574 sRef_setStateFromType (e->sref, ret);
4577 sRef_setDefined (e->sref, loc);
4578 sRef_setNullState (e->sref, isnull, loc);
4580 sRef_setAliasKind (e->sref, ak, loc);
4581 sRef_setExKind (e->sref, exp, loc);
4582 sRef_setDefState (e->sref, defstate, loc);
4584 e->whereSpecified = loc;
4585 e->whereDefined = fileloc_undefined;
4587 e->isPrivate = FALSE;
4588 e->hasNameError = FALSE;
4592 e->uses = filelocList_new ();
4593 e->warn = warnclause;
4595 e->info = (uinfo) dmalloc (sizeof (*e->info));
4596 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4598 e->info->fcn->exitCode = exitCode;
4599 e->info->fcn->specialCode = sCode;
4600 e->info->fcn->nullPred = nullPred;
4601 e->info->fcn->access = access;
4603 e->info->fcn->specclauses = specclauses;
4604 e->info->fcn->hasGlobs = hasGlobs;
4605 e->info->fcn->globs = globs;
4607 e->info->fcn->hasMods = hasMods;
4608 e->info->fcn->mods = mods;
4610 e->info->fcn->defparams = uentryList_undefined;
4611 e->whereDeclared = fileloc_undefined;
4613 sRef_storeState (e->sref);
4616 e->info->fcn->preconditions = NULL;
4620 e->info->fcn->postconditions = NULL;
4626 static /*@only@*/ uentry
4627 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4628 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4630 uentry e = uentry_alloc ();
4632 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4634 llbuglit ("uentry_makeTagBase: not a tag type");
4637 /* e->shallowCopy = FALSE; */
4641 e->sref = sRef_makeUnknown ();
4642 e->storageclass = SCNONE;
4644 if (fileloc_isSpec (loc))
4646 e->whereSpecified = loc;
4647 e->whereDeclared = fileloc_undefined;
4651 e->whereDeclared = loc;
4652 e->whereSpecified = fileloc_undefined;
4655 e->whereDefined = fileloc_undefined;
4657 e->isPrivate = FALSE;
4658 e->hasNameError = FALSE;
4662 e->uses = filelocList_new ();
4663 e->warn = warnClause_undefined; /*@i452@*/
4665 e->info = (uinfo) dmalloc (sizeof (*e->info));
4666 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4667 e->info->datatype->abs = NO;
4668 e->info->datatype->mut = MAYBE;
4669 e->info->datatype->type = rtype;
4671 sRef_storeState (e->sref);
4677 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4678 ctype ct, /*@only@*/ fileloc loc)
4680 uentry e = uentry_alloc ();
4682 /* e->shallowCopy = FALSE; */
4686 e->sref = sRef_makeUnknown ();
4687 e->storageclass = SCNONE;
4689 if (fileloc_isSpec (loc))
4691 e->whereSpecified = loc;
4692 e->whereDeclared = fileloc_undefined;
4696 e->whereDeclared = loc;
4697 e->whereSpecified = fileloc_undefined;
4700 e->whereDefined = fileloc_undefined;
4702 e->isPrivate = FALSE;
4703 e->hasNameError = FALSE;
4707 e->uses = filelocList_new ();
4708 e->warn = warnClause_undefined; /*@i452@*/
4710 e->info = (uinfo) dmalloc (sizeof (*e->info));
4711 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4712 e->info->iter->access = access;
4713 e->info->iter->mods = sRefSet_undefined;
4714 e->info->iter->globs = globSet_undefined;
4716 sRef_storeState (e->sref);
4721 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4722 /*@only@*/ fileloc loc)
4724 uentry e = uentry_alloc ();
4726 /* e->shallowCopy = FALSE; */
4727 e->ukind = KENDITER;
4728 e->storageclass = SCNONE;
4730 e->utype = ctype_unknown;
4731 e->sref = sRef_makeUnknown ();
4733 if (fileloc_isSpec (loc))
4735 e->whereSpecified = loc;
4736 e->whereDeclared = fileloc_undefined;
4740 e->whereDeclared = loc;
4741 e->whereSpecified = fileloc_undefined;
4744 e->whereDefined = fileloc_undefined;
4746 e->isPrivate = FALSE;
4747 e->hasNameError = FALSE;
4751 e->uses = filelocList_new ();
4752 e->warn = warnClause_undefined; /*@i452@*/
4754 e->info = (uinfo) dmalloc (sizeof (*e->info));
4755 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4756 e->info->enditer->access = access;
4757 sRef_storeState (e->sref);
4762 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4770 uentry_undump (ekind kind, fileloc loc, char **s)
4774 DPRINTF (("Uentry undump: %s", *s));
4778 reader_checkChar (s, '!');
4779 reader_checkChar (s, '.');
4780 ue = uentry_makeElipsisMarker ();
4784 ctype ct = ctype_undump (s);
4798 reader_checkChar (s, '|');
4800 if (reader_optCheckChar (s, '@'))
4802 tkind = vkind_fromInt (reader_getInt (s));
4803 reader_checkChar (s, '|');
4810 if (reader_optCheckChar (s, '$'))
4812 defstate = SS_UNKNOWN;
4813 isnull = NS_UNKNOWN;
4814 aliased = AK_IMPTEMP;
4816 checked = CH_UNKNOWN;
4818 else if (reader_optCheckChar (s, '&'))
4820 defstate = SS_DEFINED;
4821 isnull = NS_UNKNOWN;
4822 aliased = AK_IMPTEMP;
4824 checked = CH_UNKNOWN;
4826 else if (reader_optCheckChar (s, '^'))
4828 defstate = SS_UNKNOWN;
4829 isnull = NS_UNKNOWN;
4830 aliased = AK_IMPTEMP;
4832 checked = CH_UNKNOWN;
4836 defstate = sstate_fromInt (reader_getInt (s));
4837 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4838 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4840 if (reader_optCheckChar (s, '&'))
4843 checked = CH_UNKNOWN;
4847 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4848 advanceField (s); checked = (chkind) (reader_getInt (s));
4853 name = reader_getStringWord (s);
4855 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4857 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4858 isnull, aliased, exp,
4859 checked, fileloc_copy (loc));
4872 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4873 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4874 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4875 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4876 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4877 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4878 advanceField (s); rtype = ctype_undump (s);
4880 name = reader_getStringWord (s);
4881 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4882 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4883 aliased, exp, defstate, isnull,
4884 fileloc_copy (loc));
4901 stateClauseList specclauses = stateClauseList_undefined;
4902 warnClause warnclause = warnClause_undefined;
4904 if (reader_optCheckChar (s, '$'))
4906 defstate = SS_DEFINED;
4907 isnull = NS_UNKNOWN;
4908 exitCode = XK_UNKNOWN;
4910 nullPred = qual_createUnknown ();
4914 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4915 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4916 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4917 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4918 advanceField (s); nullPred = qual_undump (s);
4921 if (reader_optCheckChar (s, '$'))
4924 globs = globSet_undefined;
4926 mods = sRefSet_undefined;
4928 else if (reader_optCheckChar (s, '^'))
4931 globs = globSet_undefined;
4933 mods = sRefSet_undefined;
4937 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4938 advanceField (s); globs = globSet_undump (s);
4939 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4940 advanceField (s); mods = sRefSet_undump (s);
4943 if (reader_optCheckChar (s, '$'))
4950 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4951 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4954 advanceField (s); access = typeIdSet_undump (s);
4957 ** Optional clauses: Start with @<code>:
4960 while (reader_optCheckChar (s, '@'))
4962 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4964 reader_checkChar (s, ':');
4965 warnclause = warnClause_undump (s);
4967 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4969 reader_checkChar (s, ':');
4970 specclauses = stateClauseList_undump (s);
4978 advanceName (s); name = reader_getStringWord (s);
4980 ue = uentry_makeFunctionBase (name, ct, access,
4983 ak, exp, defstate, isnull,
4984 exitCode, specc, nullPred,
4987 fileloc_copy (loc));
4988 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4995 advanceField (s); access = typeIdSet_undump (s);
4996 advanceName (s); name = reader_getStringWord (s);
4998 ue = uentry_makeIterBase (name, access, ct,
4999 fileloc_copy (loc));
5006 advanceField (s); access = typeIdSet_undump (s);
5007 advanceName (s); name = reader_getStringWord (s);
5009 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5019 if (reader_optCheckChar (s, '$'))
5021 val = multiVal_undefined;
5022 access = typeIdSet_undefined;
5023 nullstate = NS_UNKNOWN;
5027 advanceField (s); val = multiVal_undump (s);
5028 advanceField (s); access = typeIdSet_undump (s);
5029 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5032 advanceName (s); name = reader_getStringWord (s);
5034 ue = uentry_makeConstantBase (name, ct, access,
5035 nullstate, fileloc_copy (loc), val);
5044 advanceField (s); rtype = ctype_undump (s);
5045 advanceName (s); name = reader_getStringWord (s);
5046 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5050 llcontbuglit ("uentry_undump: invalid");
5051 ue = uentry_undefined;
5054 llcontbuglit ("uentry_undump: elips marker");
5055 ue = uentry_undefined;
5064 uentry_dump (uentry v)
5066 return (uentry_dumpAux (v, FALSE));
5070 uentry_dumpParam (uentry v)
5072 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5073 ("dump: %s", uentry_unparseFull (v)));
5075 return (uentry_dumpAux (v, TRUE));
5079 uentry_dumpAux (uentry v, bool isParam)
5081 llassert (uentry_isValid (v));
5082 llassert (!uentry_isGlobalMarker (v));
5084 DPRINTF (("Dump uentry: [%p]", v));
5085 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5090 llcontbuglit ("uentry_dump: invalid entry");
5091 return cstring_undefined;
5093 return (message ("!."));
5097 vkind vk = v->info->var->kind;
5098 sstate dss = sRef_getDefState (v->sref);
5099 nstate nst = sRef_getNullState (v->sref);
5100 alkind alk = sRef_getAliasKind (v->sref);
5101 exkind exk = sRef_getExKind (v->sref);
5102 chkind chk = v->info->var->checked;
5104 DPRINTF (("Dumping var"));
5106 if (dss == SS_UNKNOWN
5107 && nst == NS_UNKNOWN
5108 && alk == AK_IMPTEMP
5109 && exk == XO_UNKNOWN
5110 && chk == CH_UNKNOWN)
5112 sdump = cstring_makeLiteral ("$");
5114 else if (dss == SS_DEFINED
5115 && nst == NS_UNKNOWN
5116 && alk == AK_IMPTEMP
5117 && exk == XO_UNKNOWN
5118 && chk == CH_UNKNOWN)
5120 sdump = cstring_makeLiteral ("&");
5122 else if (dss == SS_UNKNOWN
5123 && nst == NS_UNKNOWN
5124 && alk == AK_UNKNOWN
5125 && exk == XO_UNKNOWN
5126 && chk == CH_UNKNOWN)
5128 sdump = cstring_makeLiteral ("^");
5130 else if (exk == XO_UNKNOWN
5131 && chk == CH_UNKNOWN)
5133 sdump = message ("%d@%d@%d&",
5140 sdump = message ("%d@%d@%d@%d@%d",
5151 return (message ("%q|@%d|%q#%s",
5152 ctype_dump (v->utype),
5155 isParam ? cstring_undefined : v->uname));
5159 return (message ("%q|%q#%s",
5160 ctype_dump (v->utype),
5162 isParam ? cstring_undefined : v->uname));
5168 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5170 exkind_unparse (sRef_getExKind (v->sref)),
5171 ctype_unparse (v->utype), (int) v->utype));
5174 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5175 ctype_dump (v->utype),
5176 ynm_unparseCode (v->info->datatype->abs),
5177 ynm_unparseCode (v->info->datatype->mut),
5178 (int) sRef_getDefState (v->sref),
5179 (int) sRef_getNullState (v->sref),
5180 (int) sRef_getAliasKind (v->sref),
5181 (int) sRef_getExKind (v->sref),
5182 ctype_dump (v->info->datatype->type),
5186 cstring sdump, gdump, adump, xdump;
5187 alkind alk = sRef_getAliasKind (v->sref);
5188 exkind exk = sRef_getExKind (v->sref);
5190 if (sRef_getDefState (v->sref) == SS_DEFINED
5191 && !nstate_isKnown (sRef_getNullState (v->sref))
5192 && !exitkind_isKnown (v->info->fcn->exitCode)
5193 && v->info->fcn->specialCode == SPC_NONE
5194 && qual_isUnknown (v->info->fcn->nullPred))
5196 sdump = cstring_makeLiteral ("$");
5200 sdump = message ("@%d@%d@%d@%d@%x",
5201 (int) sRef_getDefState (v->sref),
5202 (int) sRef_getNullState (v->sref),
5203 (int) v->info->fcn->exitCode,
5204 (int) v->info->fcn->specialCode,
5205 qual_dump (v->info->fcn->nullPred));
5208 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5210 gdump = cstring_makeLiteral ("$");
5212 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5213 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5215 gdump = cstring_makeLiteral ("^");
5219 gdump = message ("@%s@%q@%s@%q",
5220 bool_dump (uentry_hasGlobs (v)),
5221 globSet_dump (uentry_getGlobs (v)),
5222 bool_dump (uentry_hasMods (v)),
5223 sRefSet_dump (uentry_getMods (v)));
5226 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5228 adump = cstring_makeLiteral ("$");
5232 adump = message ("@%d@%d", (int) alk, (int) exk);
5235 xdump = cstring_undefined;
5237 if (uentry_hasWarning (v))
5239 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5242 if (uentry_hasStateClauseList (v))
5244 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5247 return (message ("%q%q%q%q@%q%q#%s",
5248 ctype_dump (v->utype),
5252 typeIdSet_dump (uentry_accessType (v)),
5257 return (message ("%q@%q#%s",
5258 ctype_dump (v->utype),
5259 typeIdSet_dump (v->info->iter->access),
5262 return (message ("%q@%q#%s",
5263 ctype_dump (v->utype),
5264 typeIdSet_dump (uentry_accessType (v)),
5271 if (multiVal_isUnknown (uentry_getConstantValue (v))
5272 && typeIdSet_isEmpty (uentry_accessType (v))
5273 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5275 sdump = cstring_makeLiteral ("$");
5279 sdump = message ("@%q@%q@%d",
5280 multiVal_dump (uentry_getConstantValue (v)),
5281 typeIdSet_dump (uentry_accessType (v)),
5282 (int) sRef_getNullState (v->sref));
5285 return (message ("%q%q#%s",
5286 ctype_dump (v->utype),
5293 return (message ("%q@%q#%s",
5294 ctype_dump (v->utype),
5295 ctype_dump (v->info->datatype->type), v->uname));
5302 uentry_unparseAbbrev (uentry v)
5304 if (!uentry_isVariable (v))
5306 llcontbuglit ("uentry_unparseAbbrev: not variable");
5307 return uentry_unparse (v);
5310 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5314 uentry_unparse (uentry v)
5318 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5319 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5321 st = uentry_getName (v);
5323 if (cstring_isDefined (st))
5325 return (ctype_unparseDeclaration (v->utype, st));
5330 return (cstring_copy (ctype_unparse (v->utype)));
5335 uentry_unparseFull (uentry v)
5337 if (uentry_isUndefined (v))
5339 return (cstring_makeLiteral ("<undefined>"));
5345 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5346 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5347 ctype_unparse (v->utype),
5348 fileloc_unparse (uentry_whereSpecified (v)),
5349 fileloc_unparse (uentry_whereDeclared (v)),
5350 fileloc_unparse (uentry_whereDefined (v)));
5352 DPRINTF (("uentry: %s", res));
5354 if (uentry_isDatatype (v))
5356 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5359 (ctype_isDefined (v->info->datatype->type)
5360 ? v->info->datatype->type : ctype_unknown),
5361 ynm_unparse (v->info->datatype->mut),
5362 ynm_unparse (v->info->datatype->abs),
5363 sRef_unparseState (v->sref));
5365 else if (uentry_isFunction (v))
5367 res = message ("%q / sref: %q / mods: %q / "
5368 "globs: %q / clauses: %q / pre: %q / post: %q",
5370 sRef_unparseFull (v->sref),
5371 sRefSet_unparse (v->info->fcn->mods),
5372 globSet_unparse (v->info->fcn->globs),
5373 stateClauseList_unparse (v->info->fcn->specclauses),
5374 functionConstraint_unparse (v->info->fcn->preconditions),
5375 functionConstraint_unparse (v->info->fcn->postconditions));
5377 else if (uentry_isIter (v))
5379 res = message ("%q / sref: %q",
5381 sRef_unparseFull (v->sref));
5383 else if (uentry_isVariable (v))
5385 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5387 sRef_unparseFull (v->sref),
5388 (int) v->info->var->kind,
5389 (int) v->info->var->defstate,
5390 (int) v->info->var->nullstate,
5392 DPRINTF (("sref: [%p]", v->sref));
5393 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5394 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5396 else if (uentry_isConstant (v))
5398 res = message ("%q = %q / %q",
5399 res, multiVal_unparse (uentry_getConstantValue (v)),
5400 sRef_unparseFull (v->sref));
5404 res = message ("%q :: %q", res, uentry_unparse (v));
5411 bool uentry_hasAccessType (uentry e)
5413 if (uentry_isValid (e))
5418 return (!typeIdSet_isEmpty (e->info->iter->access));
5420 return (!typeIdSet_isEmpty (e->info->enditer->access));
5422 return (!typeIdSet_isEmpty (e->info->fcn->access));
5425 return (!typeIdSet_isEmpty (e->info->uconst->access));
5434 typeIdSet uentry_accessType (uentry e)
5436 if (uentry_isValid (e))
5441 return (e->info->iter->access);
5443 return (e->info->enditer->access);
5445 return (e->info->fcn->access);
5448 return (e->info->uconst->access);
5454 return typeIdSet_undefined;
5458 uentry_isVariable (uentry e)
5460 return (uentry_isVar (e));
5464 uentry_isSpecified (uentry e)
5466 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5470 uentry_isReallySpecified (uentry e)
5472 return (uentry_isValid (e)
5473 && fileloc_isRealSpec (e->whereSpecified));
5477 uentry_isVar (uentry e)
5479 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5483 uentry_isFakeTag (uentry e)
5485 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5489 uentry_isDatatype (uentry e)
5491 return (!uentry_isUndefined (e) &&
5492 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5493 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5497 uentry_setAbstract (uentry e)
5501 llassert (uentry_isDatatype (e)
5502 && (ynm_isMaybe (e->info->datatype->abs)));
5504 oldid = ctype_typeId (e->info->datatype->type);
5505 e->info->datatype->abs = YES;
5506 e->info->datatype->type = ctype_createAbstract (oldid);
5510 uentry_setConcrete (uentry e)
5512 llassert (uentry_isDatatype (e)
5513 && (ynm_isMaybe (e->info->datatype->abs)));
5515 e->info->datatype->abs = NO;
5519 uentry_isAbstractDatatype (uentry e)
5521 return (uentry_isDatatype (e)
5522 && (ynm_isOn (e->info->datatype->abs)));
5526 uentry_isMaybeAbstract (uentry e)
5528 return (uentry_isDatatype (e)
5529 && (ynm_isMaybe (e->info->datatype->abs)));
5533 uentry_isMutableDatatype (uentry e)
5535 bool res = uentry_isDatatype (e)
5536 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5542 uentry_isRefCountedDatatype (uentry e)
5544 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5548 uentry_isParam (uentry u)
5550 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5551 || u->info->var->kind == VKYIELDPARAM));
5555 uentry_isExpandedMacro (uentry u)
5557 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5561 uentry_isSefParam (uentry u)
5563 return (uentry_isVariable (u)
5564 && (u->info->var->kind == VKSEFPARAM
5565 || u->info->var->kind == VKREFSEFPARAM
5566 || u->info->var->kind == VKSEFRETPARAM
5567 || u->info->var->kind == VKREFSEFRETPARAM));
5571 uentry_isRefParam (uentry u)
5573 return (uentry_isVariable (u)
5574 && (u->info->var->kind == VKREFPARAM
5575 || u->info->var->kind == VKREFYIELDPARAM
5576 || u->info->var->kind == VKREFSEFPARAM
5577 || u->info->var->kind == VKREFSEFRETPARAM));
5581 uentry_isAnyParam (uentry u)
5583 return (uentry_isVariable (u)
5584 && ((u->info->var->kind == VKPARAM)
5585 || (u->info->var->kind == VKSEFPARAM)
5586 || (u->info->var->kind == VKYIELDPARAM)
5587 || (u->info->var->kind == VKRETPARAM)
5588 || (u->info->var->kind == VKSEFRETPARAM)));
5592 uentry_getDefState (uentry u)
5594 if (uentry_isValid (u))
5596 return (sRef_getDefState (u->sref));
5600 return (SS_UNKNOWN);
5605 uentry_isOut (uentry u)
5607 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5608 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5612 uentry_isPartial (uentry u)
5614 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5615 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5619 uentry_isStateSpecial (uentry u)
5621 return ((uentry_isVariable (u)
5622 && (u->info->var->defstate == SS_SPECIAL))
5623 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5626 exitkind uentry_getExitCode (uentry ue)
5628 if (uentry_isFunction (ue))
5630 return ue->info->fcn->exitCode;
5638 qual uentry_nullPred (uentry u)
5640 llassert (uentry_isRealFunction (u));
5642 if (uentry_isFunction (u))
5644 return (u->info->fcn->nullPred);
5648 return qual_createUnknown ();
5653 ** Note for variables, this is checking the declared state, not the current state.
5657 uentry_possiblyNull (uentry u)
5659 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5660 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5664 uentry_getAliasKind (uentry u)
5666 if (uentry_isValid (u))
5668 return (sRef_getAliasKind (uentry_getSref (u)));
5677 uentry_getExpKind (uentry u)
5679 if (uentry_isValid (u))
5681 return (sRef_getExKind (uentry_getSref (u)));
5690 uentry_isIter (uentry e)
5692 return (!uentry_isUndefined (e) && e->ukind == KITER);
5696 uentry_isEndIter (uentry e)
5698 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5702 uentry_isRealFunction (uentry e)
5704 return (uentry_isFunction (e) ||
5705 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5709 uentry_hasName (uentry e)
5711 if (uentry_isValid (e))
5713 cstring s = e->uname;
5715 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5716 || uentry_isFakeTag (e)));
5725 ** Returns true for fake tags.
5726 ** This is used for dumping the library
5729 bool uentry_hasRealName (uentry e)
5731 return (uentry_isValid (e)
5732 && cstring_isNonEmpty (e->uname)
5733 && !uentry_isGlobalMarker (e));
5737 /*@observer@*/ globSet
5738 uentry_getGlobs (uentry l)
5740 if (uentry_isInvalid (l))
5742 return globSet_undefined;
5745 if (l->ukind != KFCN)
5747 if (l->ukind != KITER && l->ukind != KENDITER)
5749 if (l->ukind == KVAR)
5751 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5753 ekind_unparse (l->ukind)));
5757 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5759 ekind_unparse (l->ukind)));
5762 return globSet_undefined;
5765 return l->info->fcn->globs;
5768 /*@observer@*/ sRefSet
5769 uentry_getMods (uentry l)
5771 llassert (uentry_isValid (l));
5773 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5775 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5776 return sRefSet_undefined;
5779 return l->info->fcn->mods;
5783 uentry_getKind (uentry e)
5785 llassert (uentry_isValid (e));
5790 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5792 llassert (uentry_isEitherConstant (e));
5793 return (sRef_getValue (e->sref));
5796 /*@observer@*/ uentryList
5797 uentry_getParams (uentry l)
5799 if (uentry_isInvalid (l)) return uentryList_undefined;
5806 ctype ct = l->utype;
5808 if (ctype_isFunction (ct))
5810 return (ctype_argsFunction (ct));
5814 return uentryList_undefined;
5819 ctype ct = l->utype;
5821 llassert (ctype_isFunction (ct));
5822 return (ctype_argsFunction (ct));
5829 /*@observer@*/ cstring
5830 uentry_rawName (uentry e)
5832 if (uentry_isValid (e))
5838 return cstring_undefined;
5843 uentry_getOptName (uentry e)
5845 cstring s = uentry_getName (e);
5847 if (cstring_isDefined (s))
5849 s = cstring_appendChar (s, ' ');
5856 uentry_getName (uentry e)
5858 cstring ret = cstring_undefined;
5860 if (uentry_isValid (e))
5862 if (uentry_isAnyTag (e))
5864 ret = fixTagName (e->uname);
5866 else if (uentry_isAnyParam (e))
5868 ret = cstring_copy (fixParamName (e->uname));
5872 ret = cstring_copy (e->uname);
5879 cstring uentry_observeRealName (uentry e)
5881 cstring ret = cstring_undefined;
5883 if (uentry_isValid (e))
5885 if (uentry_isAnyTag (e))
5887 if (isFakeTag (e->uname))
5889 ret = cstring_undefined;
5893 ret = plainTagName (e->uname);
5896 else if (uentry_isAnyParam (e))
5898 ret = fixParamName (e->uname);
5909 cstring uentry_getRealName (uentry e)
5911 if (uentry_isValid (e))
5913 if (uentry_isAnyTag (e))
5915 return (cstring_undefined);
5922 return cstring_undefined;
5925 ctype uentry_getType (uentry e)
5927 if (uentry_isValid (e))
5933 return ctype_unknown;
5937 fileloc uentry_whereLast (uentry e)
5941 if (uentry_isInvalid (e))
5943 return fileloc_undefined;
5946 loc = e->whereDefined;
5948 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5953 loc = uentry_whereDeclared (e);
5955 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5960 loc = uentry_whereSpecified (e);
5964 fileloc uentry_whereEither (uentry e)
5966 if (uentry_isInvalid (e)) return fileloc_undefined;
5968 if (fileloc_isDefined (e->whereDefined)
5969 && !fileloc_isExternal (e->whereDefined))
5971 return e->whereDefined;
5973 else if (fileloc_isDefined (e->whereDeclared))
5975 return e->whereDeclared;
5979 return e->whereSpecified;
5983 fileloc uentry_whereSpecified (uentry e)
5985 if (uentry_isInvalid (e)) return fileloc_undefined;
5987 return (e->whereSpecified);
5990 fileloc uentry_whereDefined (uentry e)
5992 if (uentry_isInvalid (e)) return fileloc_undefined;
5994 return (e->whereDefined);
5997 fileloc uentry_whereDeclared (uentry e)
5999 if (uentry_isInvalid (e)) return fileloc_undefined;
6001 return (e->whereDeclared);
6004 /*@observer@*/ fileloc
6005 uentry_whereEarliest (uentry e)
6007 if (uentry_isInvalid (e)) return fileloc_undefined;
6009 if (fileloc_isDefined (e->whereSpecified))
6011 return (e->whereSpecified);
6013 else if (fileloc_isDefined (e->whereDeclared))
6015 return (e->whereDeclared);
6019 return e->whereDefined;
6024 uentry_setFunctionDefined (uentry e, fileloc loc)
6026 if (uentry_isValid (e))
6028 llassert (uentry_isFunction (e));
6030 if (fileloc_isUndefined (e->whereDeclared))
6032 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6035 if (!fileloc_isDefined (e->whereDefined))
6037 e->whereDefined = fileloc_update (e->whereDefined, loc);
6043 uentry_setDeclDef (uentry e, fileloc f)
6045 uentry_setDeclared (e, f);
6047 if (!uentry_isFunction (e)
6048 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6050 uentry_setDefined (e, f);
6055 uentry_setDeclaredForce (uentry e, fileloc f)
6057 llassert (uentry_isValid (e));
6058 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6062 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6064 llassert (uentry_isValid (e));
6065 fileloc_free (e->whereDeclared);
6066 e->whereDeclared = f;
6070 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6074 llassert (uentry_isValid (e));
6075 oldloc = e->whereDeclared;
6077 if (fileloc_isDefined (oldloc))
6079 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6081 e->whereDeclared = f;
6082 fileloc_free (oldloc);
6091 e->whereDeclared = f;
6092 fileloc_free (oldloc);
6097 uentry_setDeclared (uentry e, fileloc f)
6101 llassert (uentry_isValid (e));
6102 oldloc = e->whereDeclared;
6104 if (fileloc_isDefined (oldloc))
6106 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6108 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6117 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6122 uentry_clearDefined (uentry e)
6124 if (uentry_isValid (e))
6126 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6131 uentry_setDefined (uentry e, fileloc f)
6135 llassert (uentry_isValid (e));
6136 oldloc = e->whereDefined;
6138 if (fileloc_isDefined (oldloc))
6140 if (fileloc_isLib (oldloc)
6141 || fileloc_isImport (oldloc)
6142 || fileloc_isBuiltin (oldloc)
6143 || fileloc_isPreproc (oldloc))
6145 e->whereDefined = fileloc_update (e->whereDefined, f);
6149 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6155 if (optgenerror (FLG_REDEF,
6156 message ("%s %q redefined",
6157 ekind_capName (e->ukind),
6158 uentry_getName (e)),
6161 llgenindentmsg (message ("Previous definition of %q",
6162 uentry_getName (e)),
6170 e->whereDefined = fileloc_update (e->whereDefined, f);
6175 uentry_isCodeDefined (uentry e)
6177 llassert (uentry_isValid (e));
6179 return (fileloc_isDefined (e->whereDefined));
6183 uentry_isDeclared (uentry e)
6185 if (uentry_isValid (e))
6187 return (fileloc_isDefined (e->whereDeclared));
6193 sRef uentry_getSref (uentry e)
6195 /* not true, used for functions too (but shouldn't be? */
6196 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6198 if (uentry_isInvalid (e)) return sRef_undefined;
6203 sRef uentry_getOrigSref (uentry e)
6205 /*@i523*/ /* evans 2001-09-09 - need to fix this
6206 if (uentry_isValid (e))
6208 if (uentry_isVariable (e))
6210 return e->info->var->origsref;
6214 sRef sr = sRef_copy (uentry_getSref (e));
6216 sRef_resetState (sr);
6217 sRef_clearDerived (sr);
6223 return sRef_undefined;
6227 if (uentry_isValid (e))
6229 sRef sr = sRef_copy (uentry_getSref (e));
6231 sRef_resetState (sr);
6232 sRef_clearDerived (sr);
6234 if (uentry_isVariable (e))
6236 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6237 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6244 return sRef_undefined;
6249 ** requires: uentry e is not in a hashed symbol table
6253 uentry_setName (uentry e, /*@only@*/ cstring n)
6255 llassert (uentry_isValid (e));
6257 cstring_free (e->uname);
6262 uentry_setType (uentry e, ctype t)
6264 if (uentry_isValid (e))
6267 sRef_setType (e->sref, t);
6272 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6275 ctype rettype = ctype_unknown;
6277 llassert (uentry_isValid (ue));
6279 uentry_convertVarFunction (ue);
6280 llassert (uentry_isFunction (ue));
6282 rct = ctype_realType (ue->utype);
6284 if (ctype_isFunction (rct))
6286 rettype = ctype_getReturnType (rct);
6289 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6293 uentry_setRefParam (uentry e)
6295 if (!uentry_isVar (e))
6297 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6301 if (e->info->var->kind == VKSEFPARAM)
6303 e->info->var->kind = VKREFSEFPARAM;
6305 else if (e->info->var->kind == VKSEFRETPARAM)
6307 e->info->var->kind = VKREFSEFRETPARAM;
6309 else if (e->info->var->kind == VKYIELDPARAM)
6311 e->info->var->kind = VKREFYIELDPARAM;
6315 e->info->var->kind = VKREFPARAM;
6321 uentry_setParam (uentry e)
6323 if (!uentry_isVar (e))
6325 if (uentry_isElipsisMarker (e))
6331 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6338 if (e->info->var->kind == VKYIELDPARAM
6339 || e->info->var->kind == VKSEFPARAM
6340 || e->info->var->kind == VKSEFRETPARAM)
6346 e->info->var->kind = VKPARAM;
6350 e->uname = makeParam (e->uname);
6351 cstring_free (oldname);
6356 uentry_setSref (uentry e, sRef s)
6358 if (uentry_isValid (e))
6360 if (sRef_isValid (e->sref))
6362 sRef_mergeStateQuietReverse (e->sref, s);
6366 e->sref = sRef_saveCopy (s);
6372 uentry_getAbstractType (uentry e)
6374 llassert (uentry_isDatatype (e));
6377 ** This assertion removed.
6378 ** Okay to have undefined type, for system types
6380 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6381 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6386 if (ctype_isUndefined (e->info->datatype->type))
6388 return ctype_unknown;
6392 ** Sadly, a kludge...
6395 if (ctype_isUserBool (e->info->datatype->type)) {
6399 return e->info->datatype->type;
6402 ctype uentry_getRealType (uentry e)
6405 typeId uid = USYMIDINVALID;
6407 if (uentry_isInvalid (e))
6409 return ctype_unknown;
6412 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6414 if (uentry_isAnyTag (e))
6419 if (uentry_isAbstractType (e))
6421 ct = uentry_getAbstractType (e);
6423 if (ctype_isManifestBool (ct)) {
6427 llassert (ctype_isUA (ct));
6429 uid = ctype_typeId (ct);
6431 if (!context_hasAccess (uid))
6437 ct = uentry_getType (e);
6439 /* if (ctype_isUserBool (ct)) return ct; */
6441 if (ctype_isManifestBool (ct)) {
6445 if (ctype_isUA (ct))
6447 usymId iid = ctype_typeId (ct);
6449 if (usymId_equal (iid, uid))
6451 llcontbug (message ("uentry_getRealType: recursive type! %s",
6452 ctype_unparse (ct)));
6457 /* evs 2000-07-25: possible infinite recursion ? */
6458 uentry ue2 = usymtab_getTypeEntry (iid);
6462 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6463 return ctype_unknown;
6466 return uentry_getRealType (ue2);
6475 ctype uentry_getForceRealType (uentry e)
6478 typeId uid = USYMIDINVALID;
6480 if (uentry_isInvalid (e))
6482 return ctype_unknown;
6485 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6487 if (uentry_isAnyTag (e))
6492 if (uentry_isAbstractType (e))
6494 ct = uentry_getAbstractType (e);
6495 llassert (ctype_isUA (ct));
6497 uid = ctype_typeId (ct);
6498 /* no check for access! */
6501 ct = uentry_getType (e);
6503 /* evs 2000-07-25 */
6504 /* if (ctype_isUserBool (ct)) return ct; */
6506 if (ctype_isManifestBool (ct)) {
6510 if (ctype_isUA (ct))
6512 usymId iid = ctype_typeId (ct);
6514 if (usymId_equal (iid, uid))
6516 llcontbug (message ("uentry_getRealType: recursive type! %s",
6517 ctype_unparse (ct)));
6522 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6531 uentry uentry_nameCopy (cstring name, uentry e)
6533 uentry enew = uentry_alloc ();
6535 llassert (uentry_isValid (e));
6537 /* enew->shallowCopy = FALSE; */
6538 enew->ukind = e->ukind;
6540 enew->utype = e->utype;
6541 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6542 enew->whereDefined = fileloc_copy (e->whereDefined);
6543 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6544 enew->sref = sRef_copy (e->sref);
6545 enew->used = e->used;
6547 enew->isPrivate = e->isPrivate;
6548 enew->hasNameError = FALSE;
6550 enew->uses = filelocList_new ();
6551 enew->warn = warnClause_undefined;
6553 enew->storageclass = e->storageclass;
6554 enew->info = uinfo_copy (e->info, e->ukind);
6560 uentry_setDatatype (uentry e, usymId uid)
6562 llassert (uentry_isDatatype (e));
6564 if (uentry_isAbstractType (e))
6566 e->info->datatype->type = ctype_createAbstract (uid);
6570 e->info->datatype->type = ctype_createUser (uid);
6575 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6576 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6579 llassert (uentry_isValid (e));
6581 if (fileloc_isSpec (f) || fileloc_isImport (f))
6583 e->whereSpecified = f;
6584 e->whereDeclared = fileloc_undefined;
6585 e->whereDefined = fileloc_undefined;
6589 e->whereSpecified = fileloc_undefined;
6590 e->whereDeclared = f;
6591 e->whereDefined = fileloc_undefined;
6594 llassert (fileloc_storable (f));
6598 ucinfo_free (/*@only@*/ ucinfo u)
6604 uvinfo_free (/*@only@*/ uvinfo u)
6606 /*drl7x added 6/29/01 */
6607 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6612 udinfo_free (/*@only@*/ udinfo u)
6618 ufinfo_free (/*@only@*/ ufinfo u)
6620 globSet_free (u->globs);
6621 sRefSet_free (u->mods);
6622 stateClauseList_free (u->specclauses);
6627 uiinfo_free (/*@only@*/ uiinfo u)
6633 ueinfo_free (/*@only@*/ ueinfo u)
6638 static /*@only@*/ ucinfo
6639 ucinfo_copy (ucinfo u)
6641 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6642 ret->access = u->access;
6643 ret->macro = u->macro;
6647 static /*@only@*/ uvinfo
6648 uvinfo_copy (uvinfo u)
6650 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6652 ret->kind = u->kind;
6653 ret->nullstate = u->nullstate;
6654 ret->defstate = u->defstate;
6655 ret->checked = u->checked;
6657 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6659 /* drl added 07-02-001 */
6660 /* copy null terminated information */
6662 if (u->bufinfo != NULL)
6664 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6665 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6666 ret->bufinfo->size = u->bufinfo->size;
6667 ret->bufinfo->len = u->bufinfo->len;
6672 ret->bufinfo = NULL;
6678 static /*@only@*/ udinfo
6679 udinfo_copy (udinfo u)
6681 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6685 ret->type = u->type;
6690 static /*@only@*/ ufinfo
6691 ufinfo_copy (ufinfo u)
6693 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6695 ret->hasGlobs = u->hasGlobs;
6696 ret->hasMods = u->hasMods;
6697 ret->exitCode = u->exitCode;
6698 ret->specialCode = u->specialCode;
6699 ret->nullPred = u->nullPred;
6700 ret->access = u->access;
6701 ret->globs = globSet_newCopy (u->globs);
6702 ret->mods = sRefSet_newCopy (u->mods);
6703 ret->defparams = u->defparams;
6704 ret->specclauses = stateClauseList_copy (u->specclauses);
6706 ret->preconditions = functionConstraint_copy (u->preconditions);
6707 ret->postconditions = functionConstraint_copy (u->postconditions);
6712 static /*@only@*/ uiinfo
6713 uiinfo_copy (uiinfo u)
6715 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6717 ret->access = u->access;
6718 ret->globs = globSet_newCopy (u->globs);
6719 ret->mods = sRefSet_newCopy (u->mods);
6724 static /*@only@*/ ueinfo
6725 ueinfo_copy (ueinfo u)
6727 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6729 ret->access = u->access;
6734 uinfo_free (uinfo u, ekind kind)
6739 case KCONST: ucinfo_free (u->uconst); break;
6740 case KVAR: uvinfo_free (u->var); break;
6744 case KDATATYPE: udinfo_free (u->datatype); break;
6745 case KFCN: ufinfo_free (u->fcn); break;
6746 case KITER: uiinfo_free (u->iter); break;
6747 case KENDITER: ueinfo_free (u->enditer); break;
6748 case KELIPSMARKER: break;
6749 case KINVALID: break;
6755 static /*@only@*/ /*@null@*/ uinfo
6756 uinfo_copy (uinfo u, ekind kind)
6758 if (kind == KELIPSMARKER || kind == KINVALID)
6764 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6769 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6770 case KVAR: ret->var = uvinfo_copy (u->var); break;
6774 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6775 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6776 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6777 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6785 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6787 filelocList_free (e->uses);
6788 cstring_free (e->uname);
6790 uinfo_free (e->info, e->ukind);
6792 fileloc_free (e->whereSpecified);
6793 fileloc_free (e->whereDefined);
6794 fileloc_free (e->whereDeclared);
6796 warnClause_free (e->warn);
6802 extern void uentry_markOwned (/*@owned@*/ uentry u)
6804 sfreeEventually (u);
6808 uentry_free (/*@only@*/ uentry e)
6810 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6812 uentry_reallyFree (e);
6817 ** For uentry's in the global or file scope
6821 uentry_freeComplete (/*@only@*/ uentry e)
6823 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6825 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6826 /*@i@*/ sRef_free (e->sref);
6827 e->sref = sRef_undefined;
6828 uentry_reallyFree (e);
6833 ** requires old->kind != new->kind, old->uname = new->uname
6837 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6839 llassert (uentry_isValid (old));
6840 llassert (uentry_isValid (unew));
6842 if (uentry_isEitherConstant (unew)
6843 && (fileloc_isPreproc (uentry_whereDeclared (old))
6844 || ctype_isUnknown (old->utype))
6845 && !uentry_isSpecified (old))
6853 if (!uentry_isDeclared (old))
6855 if (uentry_isSpecified (old))
6857 if (uentry_isSpecified (unew))
6859 llbuglit ("Respecification!");
6861 else if (uentry_isDeclared (unew))
6865 message ("%s %q inconsistently declared as %s: %t",
6866 ekind_capName (old->ukind),
6867 uentry_getName (unew),
6868 ekind_unparseLong (unew->ukind),
6870 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6872 uentry_showWhereLastKind (old);
6884 message ("%s %q inconsistently declared as %s: %t",
6885 ekind_capName (old->ukind),
6886 uentry_getName (unew),
6887 ekind_unparseLong (unew->ukind),
6889 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6891 uentry_showWhereLastKind (old);
6897 llassert (uentry_isDeclared (unew));
6899 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6900 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6904 message ("%s %q inconsistently redeclared as %s",
6905 ekind_capName (old->ukind),
6906 uentry_getName (unew),
6907 ekind_unparseLong (unew->ukind)),
6908 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6910 uentry_showWhereLastKind (old);
6916 uentry_updateInto (old, unew);
6920 ** def is the definition of spec, modifies spec
6922 ** reports any inconsistencies
6923 ** returns the summary of all available information
6924 ** if spec and def are inconsistent, def is returned
6928 uentry_showWhereLast (uentry spec)
6930 if (uentry_isValid (spec))
6932 if (fileloc_isDefined (spec->whereDefined)
6933 && !fileloc_isLib (spec->whereDefined)
6934 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6936 llgenindentmsg (message ("Previous definition of %q: %t",
6937 uentry_getName (spec),
6938 uentry_getType (spec)),
6939 uentry_whereDefined (spec));
6941 else if (uentry_isDeclared (spec))
6943 llgenindentmsg (message ("Previous declaration of %q: %t",
6944 uentry_getName (spec),
6945 uentry_getType (spec)),
6946 uentry_whereDeclared (spec));
6948 else if (uentry_isSpecified (spec))
6950 if (uentry_hasName (spec))
6952 llgenindentmsg (message ("Specification of %q: %t",
6953 uentry_getName (spec),
6954 uentry_getType (spec)),
6955 uentry_whereSpecified (spec));
6959 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6960 uentry_whereSpecified (spec));
6965 /* nothing to show */
6971 uentry_showWhereLastKind (uentry spec)
6973 if (uentry_isValid (spec))
6975 if (fileloc_isDefined (spec->whereDefined)
6976 && !fileloc_isLib (spec->whereDefined)
6977 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6979 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6980 uentry_getName (spec),
6981 ekind_unparseLong (spec->ukind),
6982 uentry_getType (spec)),
6983 uentry_whereDefined (spec));
6985 else if (uentry_isDeclared (spec))
6987 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6988 uentry_getName (spec),
6989 ekind_unparseLong (spec->ukind),
6990 uentry_getType (spec)),
6991 uentry_whereDeclared (spec));
6993 else if (uentry_isSpecified (spec))
6995 if (uentry_hasName (spec))
6997 llgenindentmsg (message ("Specification of %q as %s: %t",
6998 uentry_getName (spec),
6999 ekind_unparseLong (spec->ukind),
7000 uentry_getType (spec)),
7001 uentry_whereSpecified (spec));
7005 llgenindentmsg (message ("Specification as %s: %t",
7006 ekind_unparseLong (spec->ukind),
7007 uentry_getType (spec)),
7008 uentry_whereSpecified (spec));
7013 /* nothing to show */
7019 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7021 fileloc loc = uentry_whereDefined (ce);
7023 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7025 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7029 loc = uentry_whereSpecified (ce);
7031 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7033 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7038 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7040 if (uentry_isDeclared (spec))
7042 llgenindentmsg (message ("Previous declaration of %q: %q",
7043 uentry_getName (spec), extra),
7044 uentry_whereDeclared (spec));
7046 else if (uentry_isSpecified (spec))
7048 llgenindentmsg (message ("Specification of %q: %q",
7049 uentry_getName (spec), extra),
7050 uentry_whereSpecified (spec));
7054 cstring_free (extra);
7059 uentry_showWhereDeclared (uentry spec)
7061 if (uentry_isDeclared (spec))
7063 if (uentry_hasName (spec))
7065 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7066 uentry_whereDeclared (spec));
7070 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7073 else if (uentry_isSpecified (spec))
7075 if (uentry_hasName (spec))
7077 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7078 uentry_whereSpecified (spec));
7082 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7087 /* nothing to show */
7093 uentry_showWhereAny (uentry spec)
7095 if (uentry_isDeclared (spec))
7097 if (uentry_hasName (spec))
7099 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7100 uentry_whereDeclared (spec));
7104 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7107 else if (uentry_isSpecified (spec))
7109 if (uentry_hasName (spec))
7111 llgenindentmsg (message ("Specification of %q",
7112 uentry_getName (spec)),
7113 uentry_whereSpecified (spec));
7117 llgenindentmsg (cstring_makeLiteral ("Specification"),
7118 uentry_whereSpecified (spec));
7121 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7123 if (uentry_hasName (spec))
7125 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7126 uentry_whereDefined (spec));
7130 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7135 /* nothing to show */
7140 uentry_showWhereDefined (uentry spec)
7142 if (uentry_isCodeDefined (spec))
7144 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7145 uentry_whereDefined (spec));
7150 uentry_showWhereLastPlain (uentry spec)
7152 if (uentry_isDeclared (spec))
7154 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7155 uentry_whereDeclared (spec));
7157 else if (uentry_isSpecified (spec))
7159 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7160 uentry_whereSpecified (spec));
7168 uentry_showWhereLastVal (uentry spec, cstring val)
7170 if (uentry_isDeclared (spec))
7172 llgenindentmsg (message ("Previous declaration of %q: %s",
7173 uentry_getName (spec), val),
7174 uentry_whereDeclared (spec));
7176 else if (uentry_isSpecified (spec))
7178 llgenindentmsg (message ("Specification of %q: %s",
7179 uentry_getName (spec), val),
7180 uentry_whereSpecified (spec));
7188 uentry_showWhereSpecified (uentry spec)
7190 if (uentry_isSpecified (spec))
7192 if (uentry_hasName (spec))
7194 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7195 uentry_whereSpecified (spec));
7199 llgenindentmsg (cstring_makeLiteral ("Specification"),
7200 uentry_whereSpecified (spec));
7203 else if (uentry_isDeclared (spec))
7205 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7206 uentry_whereDeclared (spec));
7210 /* nothing to show */
7215 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7217 if (uentry_isSpecified (spec))
7219 if (uentry_hasName (spec))
7221 llgenindentmsg (message ("Specification of %q: %q",
7222 uentry_getName (spec), s),
7223 uentry_whereSpecified (spec));
7227 llgenindentmsg (message ("Specification: %q", s),
7228 uentry_whereSpecified (spec));
7231 else if (uentry_isDeclared (spec))
7233 llgenindentmsg (message ("Declaration of %q: %q",
7234 uentry_getName (spec), s),
7235 uentry_whereDeclared (spec));
7239 llgenindentmsg (message ("Previous: %q", s),
7240 uentry_whereLast (spec));
7249 checkStructConformance (uentry old, uentry unew)
7252 uentryList fold, fnew;
7255 ** requires: types of old and new are structs or unions
7258 llassert (uentry_isValid (old));
7259 llassert (uentry_isValid (unew));
7261 oldr = ctype_realType (old->utype);
7262 fold = ctype_getFields (oldr);
7264 newr = ctype_realType (unew->utype);
7265 fnew = ctype_getFields (newr);
7267 if (!uentryList_matchFields (fold, fnew))
7269 if (fileloc_equal (uentry_whereLast (old),
7270 uentry_whereLast (unew)))
7278 message ("%q %q %rdeclared with fields { %q }, %s "
7279 "with fields { %q }",
7280 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7281 uentry_getName (old),
7282 uentry_isDeclared (old),
7283 uentryList_unparseAbbrev (fnew),
7284 uentry_specOrDefName (old),
7285 uentryList_unparseAbbrev (fold)),
7286 uentry_whereDeclared (unew)))
7288 uentry_showWhereLastPlain (old);
7289 uentryList_showFieldDifference (fold, fnew);
7293 old->utype = unew->utype;
7298 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7301 ** requires old and new are enums
7304 ctype rold = ctype_realType (old->utype);
7305 ctype rnew = ctype_realType (unew->utype);
7306 enumNameList eold = ctype_elist (rold);
7307 enumNameList enew = ctype_elist (rnew);
7309 if (!enumNameList_match (eold, enew))
7313 message ("Enum %q declared with members { %q } but "
7314 "specified with members { %q }",
7315 uentry_getName (old),
7316 enumNameList_unparse (enew),
7317 enumNameList_unparse (eold)),
7318 uentry_whereDeclared (unew)))
7320 uentry_showWhereSpecified (old);
7321 old->utype = unew->utype;
7327 ** either oldCurrent or newCurrent may be undefined!
7331 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7332 uentry unew, uentry newCurrent, ctype newType,
7335 bool hasError = FALSE;
7337 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7339 if (uentry_hasName (newCurrent))
7341 hasError = optgenerror
7343 message ("Parameter %d, %q, of function %q has inconsistent type: "
7344 "declared %t, %s %t",
7345 paramno + 1, uentry_getName (newCurrent),
7346 uentry_getName (unew),
7347 newType, uentry_specOrDefName (old), oldType),
7348 uentry_whereDeclared (newCurrent));
7352 hasError = optgenerror
7354 message ("Parameter %d of function %q has inconsistent type: "
7355 "declared %t, %s %t",
7356 paramno + 1, uentry_getName (unew),
7357 newType, uentry_specOrDefName (old), oldType),
7358 uentry_whereDeclared (newCurrent));
7360 DPRINTF (("type: %s / %s",
7361 ctype_unparse (newType),
7362 ctype_unparse (ctype_realType (newType))));
7367 if (uentry_isDeclared (unew))
7369 hasError = optgenerror
7371 message ("Parameter %d of function %s has inconsistent type: "
7372 "declared %t, %s %t",
7373 paramno + 1, unew->uname,
7374 newType, uentry_specOrDefName (old), oldType),
7375 uentry_whereDeclared (unew));
7379 hasError = optgenerror
7381 message ("Parameter %d of function %s has inconsistent type: "
7382 "declared %t, %s %t",
7383 paramno + 1, unew->uname,
7384 newType, uentry_specOrDefName (old), oldType),
7385 uentry_whereDeclared (unew));
7391 DPRINTF (("Here: %s / %s",
7392 uentry_unparseFull (oldCurrent),
7393 uentry_unparseFull (newCurrent)));
7395 if (!uentry_isUndefined (oldCurrent))
7397 if (!uentry_isUndefined (newCurrent)
7398 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7400 uentry_showWhereLast (oldCurrent);
7404 uentry_showWhereLastPlain (old);
7407 uentry_setType (oldCurrent, newType);
7411 uentry_showWhereLastPlain (old);
7417 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7421 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7423 uentry_isDeclared (old),
7424 uentryList_size (uentry_getParams (unew)),
7425 uentry_specOrDefName (old),
7426 uentryList_size (uentry_getParams (old))),
7427 uentry_whereDeclared (unew)))
7429 uentry_showWhereLastPlain (old);
7434 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7438 message ("Function %s inconsistently %rdeclared to return %t",
7440 uentry_isDeclared (old),
7441 ctype_getReturnType (unew->utype)),
7442 uentry_whereDeclared (unew)))
7444 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7448 static cstring paramStorageName (uentry ue)
7450 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7453 static cstring fcnErrName (uentry ue)
7455 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7458 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7460 if (uentry_isVar (ue))
7462 return (checkedName (ue->info->var->checked));
7466 return (cstring_makeLiteralTemp ("<checked invalid>"));
7470 static cstring checkedName (chkind checked)
7474 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7475 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7476 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7477 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7478 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7484 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7489 if (uentry_isVar (unew))
7491 llassert (uentry_isVar (old));
7493 oldState = old->info->var->nullstate;
7494 newState = unew->info->var->nullstate;
7498 oldState = sRef_getNullState (old->sref);
7499 newState = sRef_getNullState (unew->sref);
7502 if (oldState == NS_ABSNULL)
7504 if (uentry_isVar (old))
7506 old->info->var->nullstate = newState;
7509 sRef_mergeNullState (old->sref, newState);
7511 else if (newState == NS_UNKNOWN)
7513 if (completeConform && newState != oldState
7514 && uentry_isReallySpecified (old))
7518 message ("%s %q specified as %s, but declared without %s qualifier",
7519 ekind_capName (unew->ukind),
7520 uentry_getName (unew),
7521 nstate_unparse (oldState),
7522 nstate_unparse (oldState)),
7523 uentry_whereDeclared (unew)))
7525 uentry_showWhereSpecified (old);
7529 if (uentry_isVar (unew))
7531 unew->info->var->nullstate = oldState;
7534 sRef_mergeNullState (unew->sref, oldState);
7536 else if (newState == NS_POSNULL)
7538 if (oldState == NS_MNOTNULL
7539 && (ctype_isUA (unew->utype)
7540 || (uentry_isFunction (unew)
7541 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7543 if (uentry_isVar (unew))
7545 unew->info->var->nullstate = oldState;
7548 sRef_mergeNullState (unew->sref, oldState);
7552 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7553 || oldState == NS_UNKNOWN)
7560 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7562 uentry_ekindName (unew),
7563 uentry_getName (unew),
7564 uentry_isDeclared (old),
7566 uentry_specOrDefName (old),
7567 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7568 uentry_whereDeclared (unew)))
7570 uentry_showWhereSpecified (old);
7575 if (uentry_isVar (old))
7577 old->info->var->nullstate = newState;
7580 sRef_mergeNullState (old->sref, newState);
7583 else if (newState == NS_MNOTNULL)
7585 if (oldState != NS_MNOTNULL)
7591 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7592 "%s without notnull qualifier",
7593 uentry_ekindName (unew),
7594 uentry_getName (unew),
7595 uentry_isDeclared (old),
7597 uentry_specOrDefName (old)),
7598 uentry_whereDeclared (unew)))
7600 uentry_showWhereSpecified (old);
7604 if (uentry_isVar (old))
7606 old->info->var->nullstate = newState;
7609 sRef_mergeNullState (old->sref, newState);
7614 if (uentry_isVar (unew))
7616 unew->info->var->nullstate = oldState;
7619 sRef_mergeNullState (unew->sref, oldState);
7624 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7625 bool mustConform, bool completeConform)
7631 if (uentry_isVar (old) && uentry_isVar (unew))
7633 oldState = old->info->var->defstate;
7634 newState = unew->info->var->defstate;
7639 oldState = sRef_getDefState (old->sref);
7640 newState = sRef_getDefState (unew->sref);
7643 if (newState != oldState
7644 && newState != SS_UNKNOWN
7645 && newState != SS_DEFINED)
7651 message ("%s %q inconsistently %rdeclared %s %s %s, "
7653 uentry_ekindName (unew),
7654 uentry_getName (unew),
7655 uentry_isDeclared (old),
7657 sstate_unparse (newState),
7658 paramStorageName (unew),
7659 uentry_specOrDefName (old),
7661 sstate_unparse (oldState),
7662 paramStorageName (unew)),
7663 uentry_whereDeclared (unew)))
7665 uentry_showWhereSpecified (old);
7669 if (vars) old->info->var->defstate = newState;
7670 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7675 && (newState != oldState) && (oldState != SS_DEFINED)
7676 && uentry_isReallySpecified (old))
7680 message ("%s %q specified as %s, but declared without %s qualifier",
7681 ekind_capName (unew->ukind),
7682 uentry_getName (unew),
7683 sstate_unparse (oldState),
7684 sstate_unparse (oldState)),
7685 uentry_whereDeclared (unew)))
7687 uentry_showWhereSpecified (old);
7691 if (vars) unew->info->var->defstate = oldState;
7692 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7697 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7698 bool mustConform, bool completeConform)
7703 oldKind = sRef_getAliasKind (old->sref);
7704 newKind = sRef_getAliasKind (unew->sref);
7706 if (alkind_isImplicit (newKind)
7707 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7709 if (completeConform && !alkind_equal (newKind, oldKind)
7710 && uentry_isReallySpecified (old))
7714 message ("%s %q specified as %s, but declared without "
7715 "explicit alias qualifier",
7716 ekind_capName (unew->ukind),
7717 uentry_getName (unew),
7718 alkind_unparse (oldKind)),
7719 uentry_whereDeclared (unew)))
7721 uentry_showWhereSpecified (old);
7726 ** This really shouldn't be necessary, but it is!
7727 ** Function params (?) use new here.
7730 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7734 if (alkind_isKnown (newKind))
7736 if (!alkind_equal (oldKind, newKind))
7738 if (alkind_isKnown (oldKind))
7743 message ("%s %q inconsistently %rdeclared %s %s storage, "
7745 uentry_ekindName (unew),
7746 uentry_getName (unew),
7747 uentry_isDeclared (old),
7749 alkind_unparse (newKind),
7750 uentry_specOrDefName (old),
7751 alkind_unparse (oldKind)),
7752 uentry_whereDeclared (unew)))
7754 uentry_showWhereSpecified (old);
7756 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7757 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7758 sRef_setAliasKind (old->sref, AK_ERROR,
7759 uentry_whereDeclared (unew));
7763 sRef_setAliasKind (old->sref, newKind,
7764 uentry_whereDeclared (unew));
7769 if (!(alkind_isImplicit (newKind)))
7772 !uentry_isFunction (unew) &&
7775 message ("%s %q inconsistently %rdeclared %s %s storage, "
7776 "implicitly %s as temp storage",
7777 uentry_ekindName (unew),
7778 uentry_getName (unew),
7779 uentry_isDeclared (old),
7781 alkind_unparse (newKind),
7782 uentry_specOrDefName (old)),
7783 uentry_whereDeclared (unew)))
7785 uentry_showWhereSpecified (old);
7789 sRef_setAliasKind (old->sref, newKind,
7790 uentry_whereDeclared (unew));
7792 else /* newKind is temp or refcounted */
7799 else /* newKind unknown */
7806 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7807 bool mustConform, bool completeConform)
7812 oldKind = sRef_getExKind (old->sref);
7813 newKind = sRef_getExKind (unew->sref);
7815 if (exkind_isKnown (newKind))
7817 if (oldKind != newKind)
7819 if (exkind_isKnown (oldKind))
7824 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7825 uentry_ekindName (unew),
7826 uentry_getName (unew),
7827 uentry_isDeclared (old),
7829 exkind_unparse (newKind),
7830 uentry_specOrDefName (old),
7831 exkind_unparse (oldKind)),
7832 uentry_whereDeclared (unew)))
7834 uentry_showWhereSpecified (old);
7837 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7844 message ("%s %q inconsistently %rdeclared %s %s, "
7845 "implicitly %s without exposure qualifier",
7846 uentry_ekindName (unew),
7847 uentry_getName (unew),
7848 uentry_isDeclared (old),
7850 exkind_unparse (newKind),
7851 uentry_specOrDefName (old)),
7852 uentry_whereDeclared (unew)))
7854 uentry_showWhereSpecified (old);
7857 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7863 if (completeConform && exkind_isKnown (oldKind)
7864 && uentry_isReallySpecified (old))
7868 message ("%s %q specified as %s, but declared without "
7869 "exposure qualifier",
7870 ekind_capName (unew->ukind),
7871 uentry_getName (unew),
7872 exkind_unparse (oldKind)),
7873 uentry_whereDeclared (unew)))
7875 uentry_showWhereSpecified (old);
7879 /* yes, this is necessary! (if its a param) */
7880 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7885 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7886 bool mustConform, /*@unused@*/ bool completeConform)
7888 valueTable newvals = sRef_getValueTable (unew->sref);
7890 if (valueTable_isDefined (newvals))
7892 DPRINTF (("Check meta state: %s -> %s",
7893 uentry_unparseFull (old),
7894 uentry_unparseFull (unew)));
7896 DPRINTF (("Check meta state refs: %s -> %s",
7897 sRef_unparseFull (old->sref),
7898 sRef_unparseFull (unew->sref)));
7900 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7903 ** Copy the new values into the old ref
7906 valueTable_elements (newvals, key, newval)
7908 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7909 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7911 llassert (metaStateInfo_isDefined (msinfo));
7913 if (stateValue_isUndefined (oldval))
7915 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7919 if (stateValue_isError (oldval))
7921 if (!stateValue_isError (newval))
7923 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7927 ; /* No change necessary. */
7932 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7934 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7940 if (!stateValue_isError (newval)
7941 && !stateValue_isImplicit (newval))
7943 if (uentry_hasName (unew)
7944 || !sRef_isParam (uentry_getSref (unew)))
7949 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7950 uentry_ekindName (unew),
7951 uentry_getName (unew),
7952 uentry_isDeclared (old),
7954 stateValue_unparseValue (newval, msinfo),
7955 uentry_specOrDefName (old),
7956 stateValue_unparseValue (oldval, msinfo)),
7957 uentry_whereDeclared (unew)))
7959 uentry_showWhereSpecified (old);
7967 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7968 uentry_ekindName (unew),
7969 sRef_getParam (uentry_getSref (unew)),
7970 uentry_isDeclared (old),
7972 stateValue_unparseValue (newval, msinfo),
7973 uentry_specOrDefName (old),
7974 stateValue_unparseValue (oldval, msinfo)),
7975 uentry_whereDeclared (unew)))
7977 uentry_showWhereSpecified (old);
7983 DPRINTF (("Updating!"));
7984 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7988 DPRINTF (("Values match"));
7992 } end_valueTable_elements ;
7997 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7998 /*@notnull@*/ uentry unew,
7999 bool mustConform, bool completeConform)
8001 checkDefState (old, unew, mustConform, completeConform);
8002 checkNullState (old, unew, mustConform, completeConform);
8003 checkAliasState (old, unew, mustConform, completeConform);
8004 checkExpState (old, unew, mustConform, completeConform);
8005 checkMetaState (old, unew, mustConform, completeConform);
8007 sRef_storeState (old->sref);
8008 sRef_storeState (unew->sref);
8012 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8014 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8019 llassert (uentry_isVar (old));
8020 llassert (uentry_isVar (unew));
8022 if (cstring_isEmpty (old->uname))
8024 cstring_free (old->uname);
8025 old->uname = cstring_copy (unew->uname);
8028 if (unew->info->var->kind == VKRETPARAM
8029 || unew->info->var->kind == VKSEFRETPARAM)
8031 if (old->info->var->kind != VKRETPARAM
8032 && old->info->var->kind != VKSEFRETPARAM)
8036 message ("Parameter %q inconsistently %rdeclared as "
8037 "returned parameter",
8038 uentry_getName (unew),
8039 uentry_isDeclared (old)),
8040 uentry_whereDeclared (unew)))
8042 uentry_showWhereSpecified (old);
8043 old->info->var->kind = unew->info->var->kind;
8049 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8051 if (old->info->var->kind != VKSEFPARAM
8052 && old->info->var->kind != VKSEFRETPARAM)
8056 message ("Parameter %qinconsistently %rdeclared as "
8058 uentry_getOptName (unew),
8059 uentry_isDeclared (old)),
8060 uentry_whereDeclared (unew)))
8062 uentry_showWhereSpecified (old);
8063 old->info->var->kind = unew->info->var->kind;
8068 if (old->info->var->kind == VKSPEC)
8070 old->info->var->kind = unew->info->var->kind;
8074 unew->info->var->kind = old->info->var->kind;
8077 if (unew->info->var->checked != CH_UNKNOWN
8078 && unew->info->var->checked != old->info->var->checked)
8080 if (old->info->var->checked == CH_UNKNOWN
8081 && !fileloc_isUser (uentry_whereLast (old)))
8089 message ("Variable %q inconsistently %rdeclared as "
8090 "%s parameter (was %s)",
8091 uentry_getName (unew),
8092 uentry_isDeclared (old),
8093 checkedName (unew->info->var->checked),
8094 checkedName (old->info->var->checked)),
8095 uentry_whereDeclared (unew)))
8097 uentry_showWhereSpecified (old);
8101 old->info->var->checked = unew->info->var->checked;
8106 && (old->info->var->checked != CH_UNKNOWN)
8107 && uentry_isReallySpecified (old))
8111 message ("%s %q specified as %s, but declared without %s qualifier",
8112 ekind_capName (unew->ukind),
8113 uentry_getName (unew),
8114 checkedName (old->info->var->checked),
8115 checkedName (old->info->var->checked)),
8116 uentry_whereDeclared (unew)))
8118 uentry_showWhereSpecified (old);
8122 unew->info->var->checked = old->info->var->checked;
8125 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8128 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8130 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8135 llassert (uentry_isVar (u1));
8136 llassert (uentry_isVar (u2));
8138 if (u1->info->var->kind != u2->info->var->kind) {
8139 if (u1->info->var->kind == VKSEFRETPARAM) {
8140 if (u2->info->var->kind == VKRETPARAM) {
8143 message ("Function types are inconsistent. Parameter %d is "
8144 "sef parameter, but non-sef parameter in "
8145 "assigned function: %s",
8146 paramno, exprNode_unparse (e)),
8148 } else if (u2->info->var->kind == VKSEFPARAM) {
8151 message ("Function types are inconsistent. Parameter %d is "
8152 "returns parameter, but non-returns parameter in "
8153 "assigned function: %s",
8154 paramno, exprNode_unparse (e)),
8159 message ("Function types are inconsistent. Parameter %d is "
8160 "sef returns parameter, but non-sef returns parameter in "
8161 "assigned function: %s",
8162 paramno, exprNode_unparse (e)),
8165 } else if (u1->info->var->kind == VKRETPARAM) {
8168 message ("Function types are inconsistent. Parameter %d is "
8169 "returns parameter, but non-returns parameter in "
8170 "assigned function: %s",
8171 paramno, exprNode_unparse (e)),
8173 } else if (u1->info->var->kind == VKSEFPARAM) {
8176 message ("Function types are inconsistent. Parameter %d is "
8177 "sef parameter, but non-sef parameter in "
8178 "assigned function: %s",
8179 paramno, exprNode_unparse (e)),
8182 if (u2->info->var->kind == VKSEFRETPARAM) {
8185 message ("Function types are inconsistent. Parameter %d is "
8186 "normal parameter, but sef returns parameter in "
8187 "assigned function: %s",
8188 paramno, exprNode_unparse (e)),
8190 } else if (u2->info->var->kind == VKSEFPARAM) {
8193 message ("Function types are inconsistent. Parameter %d is "
8194 "normal parameter, but sef parameter in "
8195 "assigned function: %s",
8196 paramno, exprNode_unparse (e)),
8198 } else if (u2->info->var->kind == VKRETPARAM) {
8201 message ("Function types are inconsistent. Parameter %d is "
8202 "normal parameter, but returns parameter in "
8203 "assigned function: %s",
8204 paramno, exprNode_unparse (e)),
8212 if (u1->info->var->defstate != u2->info->var->defstate)
8216 message ("Function types are inconsistent. Parameter %d is "
8217 "%s, but %s in assigned function: %s",
8219 sstate_unparse (u1->info->var->defstate),
8220 sstate_unparse (u2->info->var->defstate),
8221 exprNode_unparse (e)),
8225 if (u1->info->var->nullstate != u2->info->var->nullstate)
8229 message ("Function types are inconsistent. Parameter %d is "
8230 "%s, but %s in assigned function: %s",
8232 nstate_unparse (u1->info->var->nullstate),
8233 nstate_unparse (u2->info->var->nullstate),
8234 exprNode_unparse (e)),
8238 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8242 message ("Function types are inconsistent. Parameter %d is "
8243 "%s, but %s in assigned function: %s",
8245 alkind_unparse (sRef_getAliasKind (u1->sref)),
8246 alkind_unparse (sRef_getAliasKind (u2->sref)),
8247 exprNode_unparse (e)),
8251 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8255 message ("Function types are inconsistent. Parameter %d is "
8256 "%s, but %s in assigned function: %s",
8258 exkind_unparse (sRef_getExKind (u1->sref)),
8259 exkind_unparse (sRef_getExKind (u2->sref)),
8260 exprNode_unparse (e)),
8266 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8267 /*@notnull@*/ uentry unew,
8268 bool mustConform, /*@unused@*/ bool completeConform)
8270 uentryList oldParams = uentry_getParams (old);
8271 uentryList newParams = uentry_getParams (unew);
8272 ctype newType = unew->utype;
8273 ctype oldType = ctype_realType (old->utype);
8274 ctype oldRetType = ctype_unknown;
8275 ctype newRetType = ctype_unknown;
8277 DPRINTF (("Function conform: %s ==> %s",
8278 uentry_unparseFull (old),
8279 uentry_unparseFull (unew)));
8281 if (uentry_isForward (old))
8283 mustConform = FALSE;
8284 uentry_updateInto (old, unew);
8289 ** check return values
8292 if (ctype_isKnown (oldType))
8294 llassert (ctype_isFunction (oldType));
8295 oldRetType = ctype_getReturnType (oldType);
8298 if (ctype_isKnown (newType))
8300 llassert (ctype_isFunction (newType));
8301 newRetType = ctype_getReturnType (newType);
8304 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8305 && !ctype_matchDef (newRetType, oldRetType))
8307 if (mustConform) returnValueError (old, unew);
8311 if (ctype_isConj (newRetType))
8313 if (ctype_isConj (oldRetType))
8315 if (!ctype_sameAltTypes (newRetType, oldRetType))
8319 message ("Function %q inconsistently %rdeclared to "
8320 "return alternate types %s "
8321 "(types match, but alternates are not identical, "
8322 "so checking may not be correct)",
8323 uentry_getName (unew),
8324 uentry_isDeclared (old),
8325 ctype_unparse (newRetType)),
8326 uentry_whereDeclared (unew)))
8328 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8334 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8339 DPRINTF (("Before state: %s",
8340 uentry_unparseFull (old)));
8341 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8342 DPRINTF (("After state: %s",
8343 uentry_unparseFull (old)));
8345 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8347 if (exitkind_isKnown (unew->info->fcn->exitCode))
8351 message ("Function %q inconsistently %rdeclared using %s",
8352 uentry_getName (unew),
8353 uentry_isDeclared (old),
8354 exitkind_unparse (unew->info->fcn->exitCode)),
8355 uentry_whereDeclared (unew)))
8357 uentry_showWhereSpecified (old);
8362 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8366 if (!qual_isUnknown (unew->info->fcn->nullPred))
8368 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8372 message ("Function %q inconsistently %rdeclared using %s",
8373 uentry_getName (unew),
8374 uentry_isDeclared (old),
8375 qual_unparse (unew->info->fcn->nullPred)),
8376 uentry_whereDeclared (unew)))
8378 uentry_showWhereSpecified (old);
8384 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8387 if (unew->info->fcn->specialCode != SPC_NONE)
8389 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8393 message ("Function %q inconsistently %rdeclared using %s",
8394 uentry_getName (unew),
8395 uentry_isDeclared (old),
8396 specCode_unparse (unew->info->fcn->specialCode)),
8397 uentry_whereDeclared (unew)))
8399 uentry_showWhereSpecified (old);
8405 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8412 if (!uentryList_sameObject (oldParams, newParams)
8413 && (!uentryList_isMissingParams (oldParams)))
8415 if (!uentryList_isMissingParams (newParams))
8418 int nparams = uentryList_size (oldParams);
8419 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8421 if (nparams != uentryList_size (newParams))
8423 nargsError (old, unew);
8426 if (uentryList_size (newParams) < nparams)
8428 nparams = uentryList_size (newParams);
8431 while (paramno < nparams)
8433 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8434 uentry newCurrent = uentryList_getN (newParams, paramno);
8435 ctype oldCurrentType = uentry_getType (oldCurrent);
8436 ctype newCurrentType = uentry_getType (newCurrent);
8438 llassert (uentry_isValid (oldCurrent)
8439 && uentry_isValid (newCurrent));
8441 if (!uentry_isElipsisMarker (oldCurrent)
8442 && !uentry_isElipsisMarker (newCurrent))
8444 checkVarConformance (oldCurrent, newCurrent,
8445 mustConform, completeConform);
8450 if (uentry_hasName (oldCurrent)
8451 && uentry_hasName (newCurrent))
8453 cstring oldname = uentry_getName (oldCurrent);
8454 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8456 cstring nname = uentry_getName (newCurrent);
8459 if (cstring_isDefined (pfx)
8460 && cstring_equalPrefix (oldname, pfx))
8462 oname = cstring_suffix (oldname, cstring_length (pfx));
8467 /*@-branchstate@*/ } /*@=branchstate@*/
8469 if (cstring_isDefined (pfx)
8470 && cstring_equalPrefix (nname, pfx))
8472 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8477 /*@-branchstate@*/ } /*@=branchstate@*/
8479 if (!cstring_equal (oname, nnamefix))
8482 (FLG_DECLPARAMMATCH,
8483 message ("Definition parameter name %s does not match "
8484 "name of corresponding parameter in "
8487 uentry_whereLast (newCurrent)))
8489 uentry_showWhereLastPlain (oldCurrent);
8493 cstring_free (oldname);
8494 cstring_free (nname);
8498 if (!ctype_match (oldCurrentType, newCurrentType))
8500 paramTypeError (old, oldCurrent, oldCurrentType,
8501 unew, newCurrent, newCurrentType, paramno);
8505 if (ctype_isMissingParamsMarker (newCurrentType)
8506 || ctype_isElips (newCurrentType)
8507 || ctype_isMissingParamsMarker (oldCurrentType)
8508 || ctype_isElips (oldCurrentType))
8514 if (ctype_isConj (newCurrentType))
8516 if (ctype_isConj (oldCurrentType))
8518 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8522 message ("Parameter %q inconsistently %rdeclared with "
8523 "alternate types %s "
8524 "(types match, but alternates are not identical, "
8525 "so checking may not be correct)",
8526 uentry_getName (newCurrent),
8527 uentry_isDeclared (oldCurrent),
8528 ctype_unparse (newCurrentType)),
8529 uentry_whereDeclared (unew)))
8531 uentry_showWhereLastVal (oldCurrent,
8532 ctype_unparse (oldCurrentType));
8540 message ("Parameter %q inconsistently %rdeclared with "
8541 "alternate types %s",
8542 uentry_getName (newCurrent),
8543 uentry_isDeclared (oldCurrent),
8544 ctype_unparse (newCurrentType)),
8545 uentry_whereDeclared (unew)))
8547 uentry_showWhereLastVal (oldCurrent,
8548 ctype_unparse (oldCurrentType));
8555 if (ctype_isConj (oldCurrentType))
8557 uentry_setType (newCurrent, oldCurrentType);
8565 ** Forgot this! detected by splint:
8566 ** uentry.c:1257,15: Suspected infinite loop
8572 if (!uentryList_isMissingParams (newParams))
8574 if (ctype_isConj (oldRetType))
8576 old->utype = ctype_makeFunction (oldRetType,
8577 uentryList_copy (newParams));
8581 old->utype = unew->utype;
8585 checkGlobalsConformance (old, unew, mustConform, completeConform);
8586 checkModifiesConformance (old, unew, mustConform, completeConform);
8588 DPRINTF (("Before list: %s",
8589 uentry_unparseFull (old)));
8591 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8593 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8598 message ("Function %q redeclared using special clauses (can only "
8599 "be used in first declaration)",
8600 uentry_getName (unew)),
8601 uentry_whereDeclared (unew)))
8603 uentry_showWhereLast (old);
8607 /*@i23 need checking @*/
8609 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8613 /*@i43 should be able to append? @*/
8615 stateClauseList_checkEqual (old, unew);
8616 stateClauseList_free (unew->info->fcn->specclauses);
8617 unew->info->fcn->specclauses = stateClauseList_undefined;
8621 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8623 if (fileloc_isUndefined (old->whereDeclared))
8625 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8627 else if (fileloc_isUndefined (unew->whereDeclared))
8629 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8638 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8642 llassert (uentry_isValid (ue));
8643 llassert (uentry_isEitherConstant (ue));
8645 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8646 uval = uentry_getConstantValue (ue);
8648 if (multiVal_isDefined (uval))
8650 if (multiVal_isDefined (m))
8652 if (!multiVal_equiv (uval, m))
8656 message ("%s %q defined with inconsistent value: %q",
8657 ekind_capName (ue->ukind),
8658 uentry_getName (ue),
8659 multiVal_unparse (m)),
8662 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8670 uentry_setConstantValue (ue, m);
8675 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8678 bool typeError = FALSE;
8680 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8682 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8686 DPRINTF (("Check struct conformance: %s / %s",
8687 uentry_unparseFull (old),
8688 uentry_unparseFull (unew)));
8689 checkStructConformance (old, unew);
8694 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8696 llbug (message ("struct tags: bad types: %t / %t",
8697 old->utype, unew->utype));
8701 else if (uentry_isEnumTag (old))
8703 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8705 if (mustConform) checkEnumConformance (old, unew);
8709 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8711 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8712 ctype_unparse (unew->utype)));
8716 else if (!ctype_match (old->utype, unew->utype))
8718 DPRINTF (("Type mismatch: %s / %s",
8719 ctype_unparse (old->utype),
8720 ctype_unparse (unew->utype)));
8722 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8724 ctype realt = ctype_realType (unew->utype);
8726 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8728 unew->utype = ctype_bool;
8734 typeError = optgenerror
8736 message ("%q defined as %s", uentry_getName (old),
8737 ctype_unparse (realt)),
8738 uentry_whereDeclared (unew));
8746 ctype oldr = ctype_realType (old->utype);
8747 ctype newr = ctype_realType (unew->utype);
8749 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8751 checkStructConformance (old, unew);
8753 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8755 checkStructConformance (old, unew);
8757 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8759 checkEnumConformance (old, unew);
8761 else if (uentry_isConstant (old)
8762 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8764 /* okay...for now! (should check the type is reset later... */
8768 DPRINTF (("YABA!"));
8771 message ("%s %q %rdeclared with inconsistent type: %t",
8772 ekind_capName (unew->ukind),
8773 uentry_getName (unew),
8774 uentry_isDeclared (old),
8776 uentry_whereDeclared (unew)))
8778 uentry_showWhereLast (old);
8794 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8795 /*@notnull@*/ uentry unew,
8796 bool mustConform, bool completeConform)
8798 if (ctype_isDefined (unew->info->datatype->type))
8801 ** bool is hard coded here, since it is built into LCL.
8802 ** For now, we're stuck with LCL's types.
8805 if (ctype_isDirectBool (old->utype) &&
8806 cstring_equalLit (unew->uname, "bool"))
8808 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8809 evs 2000-07-25: removed
8811 unew->utype = ctype_bool;
8814 if (ctype_isUnknown (old->info->datatype->type))
8816 old->info->datatype->type = unew->info->datatype->type;
8820 DPRINTF (("Old: %s / New: %s",
8821 uentry_unparseFull (old),
8822 uentry_unparseFull (unew)));
8823 DPRINTF (("Types: %s / %s",
8824 ctype_unparse (old->info->datatype->type),
8825 ctype_unparse (unew->info->datatype->type)));
8827 if (ctype_matchDef (old->info->datatype->type,
8828 unew->info->datatype->type))
8837 ("Type %q %s with inconsistent type: %t",
8838 uentry_getName (unew),
8839 uentry_reDefDecl (old, unew),
8840 unew->info->datatype->type),
8841 uentry_whereDeclared (unew)))
8843 uentry_showWhereLastExtra
8844 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8847 old->info->datatype->type = unew->info->datatype->type;
8852 if (unew->info->datatype->abs != MAYBE)
8854 if (ynm_isOff (old->info->datatype->abs)
8855 && ynm_isOn (unew->info->datatype->abs))
8857 if (!ctype_isDirectBool (old->utype))
8862 ("Datatype %q inconsistently %rdeclared as abstract type",
8863 uentry_getName (unew),
8864 uentry_isDeclared (old)),
8865 uentry_whereDeclared (unew)))
8867 uentry_showWhereLastPlain (old);
8871 else if (ynm_isOn (old->info->datatype->abs)
8872 && ynm_isOff (unew->info->datatype->abs))
8874 if (!ctype_isDirectBool (old->utype))
8879 ("Datatype %q inconsistently %rdeclared as concrete type",
8880 uentry_getName (unew),
8881 uentry_isDeclared (old)),
8882 uentry_whereDeclared (unew)))
8884 uentry_showWhereLastPlain (old);
8895 if (ynm_isOn (old->info->datatype->abs))
8897 old->sref = unew->sref;
8898 unew->info->datatype->mut = old->info->datatype->mut;
8901 && uentry_isReallySpecified (old))
8906 ("Datatype %q specified as abstract, "
8907 "but abstract annotation not used in declaration",
8908 uentry_getName (unew)),
8909 uentry_whereDeclared (unew)))
8911 uentry_showWhereLastPlain (old);
8917 unew->info->datatype->abs = old->info->datatype->abs;
8919 if (ynm_isMaybe (unew->info->datatype->mut))
8921 if (completeConform && ynm_isOff (old->info->datatype->mut)
8922 && uentry_isReallySpecified (old))
8927 ("Datatype %q specified as immutable, "
8928 "but immutable annotation not used in declaration",
8929 uentry_getName (unew)),
8930 uentry_whereDeclared (unew)))
8932 uentry_showWhereLastPlain (old);
8936 unew->info->datatype->mut = old->info->datatype->mut;
8938 else if (ynm_isMaybe (old->info->datatype->mut))
8940 old->info->datatype->mut = unew->info->datatype->mut;
8944 if (ynm_isOn (old->info->datatype->abs))
8946 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8950 message ("Datatype %q inconsistently %rdeclared as immutable",
8951 uentry_getName (unew),
8952 uentry_isDeclared (old)),
8953 uentry_whereDeclared (unew)))
8955 uentry_showWhereLastPlain (old);
8960 if (ynm_isOff (old->info->datatype->mut)
8961 && ynm_isOn (unew->info->datatype->mut))
8965 message ("Datatype %q inconsistently %rdeclared as mutable",
8966 uentry_getName (unew),
8967 uentry_isDeclared (old)),
8968 uentry_whereDeclared (unew)))
8970 uentry_showWhereLastPlain (old);
8975 old->info->datatype->mut = unew->info->datatype->mut;
8978 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8982 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8983 /*@notnull@*/ uentry unew,
8985 /*@unused@*/ bool completeConform)
8987 multiVal oldval = uentry_getConstantValue (old);
8988 multiVal newval = uentry_getConstantValue (unew);
8990 if (multiVal_isDefined (oldval))
8992 if (multiVal_isDefined (newval))
8994 if (!multiVal_equiv (oldval, newval))
8999 message ("%s %q %rdeclared with inconsistent value: %q",
9000 ekind_capName (unew->ukind),
9001 uentry_getName (unew),
9002 uentry_isDeclared (old),
9003 multiVal_unparse (newval)),
9004 uentry_whereDeclared (unew)))
9006 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9010 uentry_setConstantValue (unew, multiVal_copy (oldval));
9019 uentry_setConstantValue (old, multiVal_copy (newval));
9024 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9025 /*@notnull@*/ uentry unew, bool mustConform,
9026 bool completeConform)
9028 bool typeError = FALSE;
9029 bool fcnConformance = FALSE;
9031 if (!ekind_equal (unew->ukind, old->ukind))
9034 ** okay, only if one is a function and the other is
9035 ** a variable of type function.
9038 if (unew->ukind == KENUMCONST
9039 && old->ukind == KCONST)
9041 old->ukind = KENUMCONST;
9045 if (unew->ukind == KFCN
9046 && old->ukind == KCONST
9047 && ctype_isUnknown (old->utype))
9050 ** When a function is defined with an unparam macro
9053 uentry_updateInto (old, unew);
9057 if (uentry_isExpandedMacro (old)
9058 && uentry_isEitherConstant (unew))
9060 uentry_updateInto (old, unew);
9064 if (uentry_isEndIter (unew))
9066 if (ctype_isUnknown (old->utype))
9068 if (!uentry_isSpecified (old)
9069 && uentry_isCodeDefined (unew))
9071 if (!fileloc_withinLines (uentry_whereDefined (old),
9072 uentry_whereDeclared (unew), 2))
9073 { /* bogus! will give errors if there is too much whitespace */
9077 ("Iterator finalized name %q does not match name in "
9078 "previous iter declaration (should be end_%q). This iter "
9079 "is declared at %q",
9080 uentry_getName (unew),
9081 uentry_getName (old),
9082 fileloc_unparse (uentry_whereDefined (old))),
9083 uentry_whereDeclared (old));
9087 uentry_updateInto (old, unew);
9092 KindConformanceError (old, unew, mustConform);
9096 if (uentry_isFunction (unew))
9098 if (uentry_isVariable (old))
9100 if (!ctype_isUnknown (old->utype))
9102 if (ctype_isFunction (old->utype))
9104 uentry_makeVarFunction (old);
9105 checkFunctionConformance (old, unew, mustConform,
9107 fcnConformance = TRUE;
9111 KindConformanceError (old, unew, mustConform);
9116 if (uentry_isExpandedMacro (old))
9118 if (fileloc_isUndefined (unew->whereDefined))
9120 unew->whereDefined = fileloc_update (unew->whereDefined,
9124 uentry_updateInto (old, unew);
9125 old->used = unew->used = TRUE;
9130 /* undeclared identifier */
9131 old->utype = unew->utype;
9132 uentry_makeVarFunction (old);
9133 checkFunctionConformance (old, unew, FALSE, FALSE);
9134 fcnConformance = TRUE;
9140 KindConformanceError (old, unew, mustConform);
9143 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9145 if (!ctype_isUnknown (unew->utype))
9147 if (ctype_isFunction (unew->utype))
9149 uentry_makeVarFunction (unew);
9150 checkFunctionConformance (old, unew, mustConform, completeConform);
9151 fcnConformance = TRUE;
9155 KindConformanceError (old, unew, mustConform);
9160 KindConformanceError (old, unew, mustConform);
9165 KindConformanceError (old, unew, mustConform);
9171 ** check parameter lists for functions
9172 ** (before type errors, to get better messages
9175 if (uentry_isFunction (old))
9177 checkFunctionConformance (old, unew, mustConform, completeConform);
9178 fcnConformance = TRUE;
9182 if (!ctype_isUndefined (old->utype))
9184 typeError = checkTypeConformance (old, unew, mustConform);
9191 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9193 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9196 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9198 DPRINTF (("Check datatype: %s / %s",
9199 uentry_unparseFull (old),
9200 uentry_unparseFull (unew)));
9202 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9205 if (uentry_isVariable (old) && uentry_isVariable (unew))
9208 !ctype_matchDef (old->utype, unew->utype))
9213 ("Variable %q %s with inconsistent type (arrays and pointers are "
9214 "not identical in variable declarations): %t",
9215 uentry_getName (unew),
9216 uentry_reDefDecl (old, unew),
9218 uentry_whereDeclared (unew)))
9220 uentry_showWhereLast (old);
9223 ** Avoid repeated errors.
9226 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9228 old->whereDefined = fileloc_update (old->whereDefined,
9236 checkVarConformance (old, unew, mustConform, completeConform);
9241 /* old->utype = unew->utype; */
9245 if (ctype_isConj (old->utype))
9247 if (ctype_isConj (unew->utype))
9249 if (!ctype_sameAltTypes (old->utype, unew->utype))
9253 message ("%s %q inconsistently %rdeclared with "
9254 "alternate types %s "
9255 "(types match, but alternates are not identical, "
9256 "so checking may not be correct)",
9257 ekind_capName (uentry_getKind (old)),
9258 uentry_getName (unew),
9259 uentry_isDeclared (old),
9260 ctype_unparse (unew->utype)),
9261 uentry_whereDeclared (unew)))
9263 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9267 old->utype = unew->utype;
9274 if (ctype_isUnknown (old->utype))
9276 old->utype = unew->utype;
9281 if (unew->ukind == old->ukind)
9284 unew->info = uinfo_copy (old->info, old->ukind);
9287 sRef_storeState (old->sref);
9288 sRef_storeState (unew->sref);
9291 static void uentry_mergeConstraints (uentry spec, uentry def)
9293 if (uentry_isFunction (def))
9295 DPRINTF (("Here: %s / %s",
9296 uentry_unparseFull (spec),
9297 uentry_unparseFull (def)));
9298 /* evans 2001-07-21 */
9299 llassert (uentry_isFunction (spec));
9301 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9303 if (fileloc_isXHFile (uentry_whereLast (def)))
9305 llassert (uentry_isFunction (spec));
9306 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9307 def->info->fcn->preconditions);
9309 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9315 /* Check if the constraints are identical */
9320 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9321 uentry_getName (spec),
9322 functionConstraint_unparse (spec->info->fcn->preconditions)),
9323 uentry_whereLast (def)))
9325 uentry_showWhereSpecified (spec);
9328 functionConstraint_free (spec->info->fcn->preconditions);
9329 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9332 def->info->fcn->preconditions = functionConstraint_undefined;
9335 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9337 if (fileloc_isXHFile (uentry_whereLast (def)))
9339 llassert (uentry_isFunction (spec));
9340 DPRINTF (("Post: %s /++/ %s",
9341 functionConstraint_unparse (spec->info->fcn->postconditions),
9342 functionConstraint_unparse (def->info->fcn->postconditions)));
9343 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9344 def->info->fcn->postconditions);
9345 def->info->fcn->postconditions = functionConstraint_undefined;
9346 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9353 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9354 uentry_getName (spec),
9355 functionConstraint_unparse (spec->info->fcn->postconditions)),
9356 uentry_whereLast (def)))
9358 uentry_showWhereSpecified (spec);
9361 functionConstraint_free (spec->info->fcn->postconditions);
9362 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9363 def->info->fcn->postconditions = functionConstraint_undefined;
9370 ** modifies spec to reflect def, reports any inconsistencies
9374 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9376 llassert (uentry_isValid (spec));
9377 llassert (uentry_isValid (def));
9378 llassert (cstring_equal (spec->uname, def->uname));
9380 if (uentry_isFunction (def))
9382 if (uentry_isConstant (spec))
9384 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9385 uentry_makeConstantFunction (spec);
9389 uentry_convertVarFunction (spec);
9392 llassert (uentry_isFunction (spec));
9395 DPRINTF (("Merge entries: %s / %s",
9396 uentry_unparseFull (spec),
9397 uentry_unparseFull (def)));
9399 uentry_mergeConstraints (spec, def);
9401 uentry_checkConformance (spec, def, TRUE,
9402 context_getFlag (FLG_NEEDSPEC));
9404 DPRINTF (("Merge entries after conform: %s / %s",
9405 uentry_unparseFull (spec),
9406 uentry_unparseFull (def)));
9408 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9411 ** okay, declarations conform. Propagate extra information.
9414 uentry_setDefined (spec, uentry_whereDefined (def));
9415 uentry_setDeclared (spec, uentry_whereDeclared (def));
9417 if (uentry_isStatic (def))
9421 message ("%s %q specified, but declared as static",
9422 ekind_capName (def->ukind),
9423 uentry_getName (def)),
9424 uentry_whereDeclared (def)))
9426 uentry_showWhereSpecified (spec);
9431 spec->storageclass = def->storageclass;
9434 sRef_storeState (spec->sref);
9436 spec->used = def->used || spec->used;
9437 spec->hasNameError |= def->hasNameError;
9441 if (!spec->hasNameError)
9443 uentry_checkName (spec);
9452 ** Can't generate function redeclaration errors when the
9453 ** entries are merged, since we don't yet know if its the
9454 ** definition of the function.
9458 uentry_clearDecl (void)
9460 posRedeclared = uentry_undefined;
9461 fileloc_free (posLoc);
9462 posLoc = fileloc_undefined;
9466 uentry_checkDecl (void)
9468 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9470 llassert (fileloc_isDefined (posLoc));
9472 if (uentry_isCodeDefined (posRedeclared))
9474 if (optgenerror (FLG_REDECL,
9475 message ("%s %q declared after definition",
9476 ekind_capName (posRedeclared->ukind),
9477 uentry_getName (posRedeclared)),
9480 llgenindentmsg (message ("Definition of %q",
9481 uentry_getName (posRedeclared)),
9482 posRedeclared->whereDeclared);
9487 if (optgenerror (FLG_REDECL,
9488 message ("%s %q declared more than once",
9489 ekind_capName (posRedeclared->ukind),
9490 uentry_getName (posRedeclared)),
9493 llgenindentmsg (message ("Previous declaration of %q",
9494 uentry_getName (posRedeclared)),
9495 posRedeclared->whereDeclared);
9500 fileloc_free (posLoc);
9501 posLoc = fileloc_undefined;
9502 posRedeclared = uentry_undefined;
9506 ** Redefinition of old as unew.
9507 ** modifies old to reflect unew, reports any inconsistencies
9511 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9513 fileloc olddef = uentry_whereDeclared (old);
9514 fileloc unewdef = uentry_whereDeclared (unew);
9518 DPRINTF (("uentry merge: %s / %s",
9519 uentry_unparseFull (old),
9520 uentry_unparseFull (unew)));
9523 fileloc_isUndefined (olddef)
9524 && fileloc_isDefined (uentry_whereDefined (old))
9525 && !uentry_isExpandedMacro (old);
9527 if (!context_getFlag (FLG_INCONDEFSLIB)
9528 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9530 mustConform = FALSE;
9537 llassert (uentry_isValid (old));
9538 llassert (uentry_isValid (unew));
9539 llassert (cstring_equal (old->uname, unew->uname));
9541 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9543 if (uentry_isConstant (old))
9545 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9546 uentry_makeConstantFunction (old);
9550 uentry_convertVarFunction (old);
9553 llassert (uentry_isFunction (old));
9556 DPRINTF (("uentry merge: %s / %s",
9557 uentry_unparseFull (old),
9558 uentry_unparseFull (unew)));
9560 if (uentry_isExtern (unew))
9562 uentry_setUsed (old, unewdef);
9566 ** should check old one was extern!
9569 if (uentry_isStatic (old))
9571 if (!(uentry_isStatic (unew)))
9575 message ("%s %q shadows static declaration",
9576 ekind_capName (unew->ukind),
9577 uentry_getName (unew)),
9580 uentry_showWhereLast (old);
9585 uentry_setDeclDef (old, unewdef);
9588 else if (uentry_isStatic (unew))
9590 uentry_setDeclDef (old, unewdef);
9592 else if (uentry_isExtern (old))
9594 uentry_setDeclared (old, unewdef);
9598 if (!uentry_isExtern (unew)
9599 && !uentry_isForward (old)
9600 && !fileloc_equal (olddef, unewdef)
9601 && !fileloc_isUndefined (olddef)
9602 && !fileloc_isUndefined (unewdef)
9603 && !fileloc_isBuiltin (olddef)
9604 && !fileloc_isBuiltin (unewdef)
9605 && !uentry_isYield (old)
9606 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9608 if (uentry_isVariable (old) || uentry_isVariable (unew))
9610 ; /* will report redeclaration error later */
9614 if (fileloc_isDefined (uentry_whereDefined (old)))
9618 message ("%s %q defined more than once",
9619 ekind_capName (unew->ukind),
9620 uentry_getName (unew)),
9621 uentry_whereLast (unew)))
9624 (message ("Previous definition of %q",
9625 uentry_getName (old)),
9626 uentry_whereLast (old));
9629 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9631 uentry_updateInto (old, unew);
9632 old->sref = sRef_saveCopy (old->sref);
9640 if (fileloc_isLib (olddef)
9641 || fileloc_isUndefined (olddef)
9642 || fileloc_isImport (olddef))
9644 if (uentry_isExtern (unew))
9646 if (uentry_isExtern (old)
9647 || (fileloc_isDefined (uentry_whereDeclared (old))
9648 && (!fileloc_equal (uentry_whereDeclared (old),
9649 uentry_whereDefined (old)))))
9653 message ("%s %q declared more than once",
9654 ekind_capName (unew->ukind),
9655 uentry_getName (unew)),
9656 unew->whereDeclared))
9659 (message ("Previous declaration of %q",
9660 uentry_getName (old)),
9661 old->whereDeclared);
9665 uentry_setExtern (old);
9669 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9675 DPRINTF (("uentry merge: %s / %s",
9676 uentry_unparseFull (old),
9677 uentry_unparseFull (unew)));
9679 uentry_mergeConstraints (old, unew);
9680 DPRINTF (("uentry merge: %s / %s",
9681 uentry_unparseFull (old),
9682 uentry_unparseFull (unew)));
9684 uentry_checkConformance (old, unew, mustConform, FALSE);
9685 DPRINTF (("uentry merge: %s / %s",
9686 uentry_unparseFull (old),
9687 uentry_unparseFull (unew)));
9689 old->used = old->used || unew->used;
9690 old->uses = filelocList_append (old->uses, unew->uses);
9691 unew->uses = filelocList_undefined;
9693 sRef_storeState (old->sref);
9694 sRef_storeState (unew->sref);
9698 old->whereDefined = fileloc_update (old->whereDefined,
9702 DPRINTF (("here: %s", uentry_unparseFull (old)));
9705 ** No redeclaration errors for functions here, since we
9706 ** don't know if this is the definition of the function.
9709 if (fileloc_isUser (old->whereDeclared)
9710 && fileloc_isUser (unew->whereDeclared)
9711 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9712 && !fileloc_isDefined (unew->whereDefined))
9714 if (uentry_isFunction (old))
9716 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9717 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9721 if (optgenerror (FLG_REDECL,
9722 message ("%s %q declared more than once",
9723 ekind_capName (unew->ukind),
9724 uentry_getName (unew)),
9725 unew->whereDeclared))
9727 llgenindentmsg (message ("Previous declaration of %q",
9728 uentry_getName (old)),
9729 old->whereDeclared);
9734 if (fileloc_isUndefined (old->whereDefined))
9736 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9740 if (!context_processingMacros ()
9741 && fileloc_isUser (old->whereDefined)
9742 && fileloc_isUser (unew->whereDefined)
9743 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9745 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9747 if (uentry_isVariable (unew)
9748 && uentry_isExtern (unew))
9750 if (optgenerror (FLG_REDECL,
9751 message ("%s %q declared after definition",
9752 ekind_capName (unew->ukind),
9753 uentry_getName (unew)),
9754 unew->whereDeclared))
9756 llgenindentmsg (message ("Definition of %q",
9757 uentry_getName (old)),
9763 if (optgenerror (FLG_REDEF,
9764 message ("%s %q redefined",
9765 ekind_capName (unew->ukind),
9766 uentry_getName (unew)),
9767 unew->whereDefined))
9769 llgenindentmsg (message ("Previous definition of %q",
9770 uentry_getName (old)),
9778 if (uentry_isExternal (unew))
9780 old->whereDefined = fileloc_createExternal ();
9783 if (unew->hasNameError)
9785 old->hasNameError = TRUE;
9790 if (!old->hasNameError)
9792 uentry_checkName (old);
9795 DPRINTF (("After: %s", uentry_unparseFull (old)));
9796 llassert (!ctype_isUndefined (old->utype));
9800 uentry_copyState (uentry res, uentry other)
9802 llassert (uentry_isValid (res));
9803 llassert (uentry_isValid (other));
9805 res->used = other->used;
9807 res->info->var->kind = other->info->var->kind;
9808 res->info->var->defstate = other->info->var->defstate;
9809 res->info->var->nullstate = other->info->var->nullstate;
9810 res->info->var->checked = other->info->var->checked;
9812 sRef_copyState (res->sref, other->sref);
9816 uentry_sameKind (uentry u1, uentry u2)
9818 if (uentry_isValid (u1) && uentry_isValid (u2))
9820 if (uentry_isVar (u1) && uentry_isVar (u2))
9822 ctype c1 = u1->utype;
9823 ctype c2 = u2->utype;
9825 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9828 ** both functions, or both not functions
9831 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9835 return ((u1->ukind == u2->ukind));
9842 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9845 llassert (uentry_isValid (unew));
9846 llassert (uentry_isValid (old));
9848 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9849 okind = unew->ukind;
9850 unew->ukind = old->ukind;
9851 llassert (cstring_equal (unew->uname, old->uname));
9852 unew->utype = old->utype;
9854 if (fileloc_isDefined (unew->whereSpecified)
9855 && !fileloc_isDefined (old->whereSpecified))
9857 ; /* Keep the old value */
9861 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9862 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9865 if (fileloc_isDefined (unew->whereDefined)
9866 && !fileloc_isDefined (old->whereDefined))
9868 ; /* Keep the old value */
9872 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9873 unew->whereDefined = fileloc_copy (old->whereDefined);
9876 if (fileloc_isDefined (unew->whereDeclared)
9877 && !fileloc_isDefined (old->whereDeclared))
9879 ; /* Keep the old value */
9883 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9884 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9887 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9889 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9890 unew->used = old->used;
9892 unew->isPrivate = old->isPrivate;
9893 unew->hasNameError = old->hasNameError;
9894 unew->uses = filelocList_append (unew->uses, old->uses);
9895 old->uses = filelocList_undefined;
9897 unew->storageclass = old->storageclass;
9898 uinfo_free (unew->info, okind);
9899 unew->info = uinfo_copy (old->info, old->ukind);
9904 uentry_copy (uentry e)
9906 if (uentry_isValid (e))
9908 uentry enew = uentry_alloc ();
9909 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9910 enew->ukind = e->ukind;
9911 enew->uname = cstring_copy (e->uname);
9912 enew->utype = e->utype;
9914 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9915 enew->whereDefined = fileloc_copy (e->whereDefined);
9916 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9918 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9919 enew->used = e->used;
9921 enew->isPrivate = e->isPrivate;
9922 enew->hasNameError = e->hasNameError;
9923 enew->uses = filelocList_undefined;
9925 enew->storageclass = e->storageclass;
9926 enew->info = uinfo_copy (e->info, e->ukind);
9927 enew->warn = warnClause_copy (e->warn);
9929 DPRINTF (("Here we are..."));
9930 DPRINTF (("original: %s", uentry_unparseFull (e)));
9931 DPRINTF (("copy: %s", uentry_unparse (enew)));
9932 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9937 return uentry_undefined;
9942 uentry_setState (uentry res, uentry other)
9944 llassert (uentry_isValid (res));
9945 llassert (uentry_isValid (other));
9947 llassert (res->ukind == other->ukind);
9948 llassert (res->ukind == KVAR);
9950 res->sref = sRef_saveCopy (other->sref);
9951 res->used = other->used;
9952 filelocList_free (res->uses);
9953 res->uses = other->uses;
9954 other->uses = filelocList_undefined;
9955 res->lset = other->lset;
9959 uentry_mergeUses (uentry res, uentry other)
9961 llassert (uentry_isValid (res));
9962 llassert (uentry_isValid (other));
9964 res->used = other->used || res->used;
9965 res->lset = other->lset || res->lset;
9966 res->uses = filelocList_append (res->uses, other->uses);
9967 other->uses = filelocList_undefined;
9972 ** This is a really ugly routine.
9974 ** gack...fix this one day.
9979 ** >> res is the false branch, other is the true branch (or continuation)
9981 ** >> res is the true branch, other is the false branch (or continutation)
9988 ** References not effected by res are propagated from other.
9992 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9993 bool flip, clause cl, fileloc loc)
9997 message ("%s %q is %s %s, but %s %s.",
9998 ekind_capName (res->ukind), uentry_getName (res),
9999 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10000 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10003 if (sRef_isDead (res->sref))
10005 sRef_showStateInfo (res->sref);
10006 sRef_showStateInfo (other->sref);
10008 else if (sRef_isKept (res->sref))
10010 sRef_showAliasInfo (res->sref);
10011 sRef_showAliasInfo (other->sref);
10013 else /* dependent */
10015 sRef_showAliasInfo (res->sref);
10016 sRef_showAliasInfo (other->sref);
10019 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10023 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10025 alkind rk = sRef_getAliasKind (rs);
10026 alkind ok = sRef_getAliasKind (os);
10028 if (alkind_isError (rk) || alkind_isError (ok))
10034 return ((sRef_isDead (rs)
10035 || (alkind_isKept (rk) && !alkind_isKept (ok))
10036 || (alkind_isDependent (rk)
10037 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10038 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10043 branchStateAltError (/*@notnull@*/ uentry res,
10044 /*@notnull@*/ uentry other, bool flip,
10045 clause cl, fileloc loc)
10049 message ("%s %q is %s %s, but %s %s.",
10050 ekind_capName (res->ukind), uentry_getName (res),
10051 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10052 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10055 if (sRef_isDead (other->sref))
10057 sRef_showStateInfo (other->sref);
10061 sRef_showAliasInfo (other->sref);
10064 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10065 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10067 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10068 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10073 ** A reference is relevant for certain checks, only if it
10074 ** is not definitely null on this path (but not declared
10075 ** to always be null.)
10078 static bool uentry_relevantReference (sRef sr, bool flip)
10080 if (sRef_isKept (sr) || sRef_isDependent (sr))
10088 return !sRef_definitelyNullContext (sr);
10092 return !sRef_definitelyNullAltContext (sr);
10098 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10099 fileloc loc, bool mustReturn, bool flip, bool opt,
10102 sRef rs = res->sref;
10103 sRef os = other->sref;
10105 DPRINTF (("Merge alias states: %s / %s",
10106 uentry_unparseFull (res),
10107 uentry_unparseFull (other)));
10109 if (sRef_isValid (rs))
10113 if (uentry_incompatibleMemoryStates (rs, os))
10115 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10116 sRef_unparseFull (rs), sRef_unparseFull (os)));
10118 if (sRef_isThroughArrayFetch (rs)
10119 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10121 if (sRef_isKept (rs) || sRef_isKept (os))
10123 sRef_maybeKill (rs, loc);
10125 else if (sRef_isPossiblyDead (os))
10127 sRef_maybeKill (rs, loc);
10136 if (uentry_relevantReference (os, flip))
10138 if (sRef_isLocalParamVar (rs)
10139 && (sRef_isLocalState (os)
10140 || sRef_isDependent (os)))
10142 if (sRef_isDependent (rs))
10144 sRef_setDependent (os, loc);
10148 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10153 branchStateError (res, other, flip, cl, loc);
10158 if (sRef_isKept (rs))
10160 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10161 sRef_setKept (os, loc);
10166 if (uentry_incompatibleMemoryStates (os, rs))
10168 if (uentry_relevantReference (rs, !flip))
10170 if (sRef_isLocalParamVar (rs)
10171 && (sRef_isDependent (rs)
10172 || sRef_isLocalState (rs)))
10174 if (sRef_isDependent (os))
10176 sRef_setDependent (rs, loc);
10180 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10185 if (sRef_isParam (os))
10188 ** If the local variable associated
10189 ** with the param has the correct state,
10191 ** (e.g., free (s); s = new(); ...
10194 uentry uvar = usymtab_lookupSafe (other->uname);
10196 if (uentry_isValid (uvar)
10197 && ((sRef_isDead (os)
10198 && sRef_isOnly (uvar->sref))
10199 || (sRef_isDependent (os)
10200 && sRef_isOwned (uvar->sref))))
10206 branchStateAltError (res, other,
10212 DPRINTF (("Here: %s / %s",
10213 uentry_unparseFull (res),
10214 uentry_unparseFull (other)));
10216 branchStateAltError (res, other,
10223 if (sRef_isKept (os))
10225 sRef_setKept (rs, loc);
10231 DPRINTF (("Merge opt..."));
10232 sRef_mergeOptState (rs, os, cl, loc);
10233 DPRINTF (("Done!"));
10237 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10238 sRef_mergeState (rs, os, cl, loc);
10239 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10244 if (sRef_isModified (os))
10246 sRef_setModified (rs);
10251 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10255 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10256 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10258 valueTable rvalues;
10259 valueTable ovalues;
10261 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10269 rvalues = sRef_getValueTable (res->sref);
10270 ovalues = sRef_getValueTable (other->sref);
10272 if (valueTable_isUndefined (ovalues))
10274 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10277 else if (valueTable_isUndefined (rvalues))
10280 ** Copy values from other
10284 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10285 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10290 valueTable_elements (ovalues, fkey, fval) {
10292 metaStateInfo minfo;
10293 stateCombinationTable sctable;
10297 tval = valueTable_lookup (rvalues, fkey);
10299 DPRINTF (("Merge value: %s / %s X %s", fkey,
10300 stateValue_unparse (fval), stateValue_unparse (tval)));
10302 minfo = context_lookupMetaStateInfo (fkey);
10303 llassert (stateValue_isDefined (tval));
10305 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10307 DPRINTF (("Cannot find meta state for: %s", fkey));
10312 llassert (metaStateInfo_isDefined (minfo));
10314 if (stateValue_isError (fval)
10315 || sRef_definitelyNullContext (res->sref))
10317 sRef_setMetaStateValueComplete (res->sref,
10318 fkey, stateValue_getValue (fval),
10319 stateValue_getLoc (fval));
10320 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10322 else if (stateValue_isError (tval)
10323 || sRef_definitelyNullAltContext (other->sref))
10325 DPRINTF (("Other branch is definitely null!"));
10327 else if (sRef_isStateUndefined (res->sref)
10328 || sRef_isDead (res->sref))
10330 ; /* Combination state doesn't matter if it is undefined or dead */
10334 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10335 metaStateInfo_unparse (minfo),
10336 stateValue_unparse (fval),
10337 stateValue_unparse (tval)));
10339 DPRINTF (("state values: %d / %d",
10340 stateValue_getValue (fval), stateValue_getValue (tval)));
10342 sctable = metaStateInfo_getMergeTable (minfo);
10344 DPRINTF (("Merge table: %s",
10345 stateCombinationTable_unparse (sctable)));
10347 msg = cstring_undefined;
10349 nval = stateCombinationTable_lookup (sctable,
10350 stateValue_getValue (fval),
10351 stateValue_getValue (tval),
10354 DPRINTF (("nval: %d / %d / %d", nval,
10355 stateValue_getValue (fval), stateValue_getValue (tval)));
10357 if (nval == stateValue_error)
10359 /*@i32 print extra info for assignments@*/
10361 if (uentry_isGlobalMarker (res))
10366 ("Control branches merge with incompatible global states (%s and %s)%q",
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);
10382 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10383 uentry_getName (res),
10384 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10385 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10386 cstring_isDefined (msg)
10387 ? message (": %s", msg) : cstring_undefined),
10390 sRef_showMetaStateInfo (res->sref, fkey);
10391 sRef_showMetaStateInfo (other->sref, fkey);
10392 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10393 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10394 DPRINTF (("Null: %s / %s",
10395 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10396 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10402 if (nval == stateValue_getValue (fval)
10403 && nval != stateValue_getValue (tval))
10405 loc = stateValue_getLoc (fval);
10407 else if (nval == stateValue_getValue (tval)
10408 && nval != stateValue_getValue (fval))
10410 loc = stateValue_getLoc (tval);
10417 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10418 && nval == stateValue_getValue (fval)
10419 && nval == stateValue_getValue (tval))
10425 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10429 } end_valueTable_elements ;
10435 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10436 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10437 bool flip, clause cl)
10439 if (cl == DOWHILECLAUSE)
10441 res->used = other->used || res->used;
10442 res->lset = other->lset || res->lset;
10443 res->uses = filelocList_append (res->uses, other->uses);
10444 other->uses = filelocList_undefined;
10448 if (sRef_isMacroParamRef (res->sref)
10449 && !uentry_isSefParam (other)
10450 && !uentry_isSefParam (res))
10452 bool hasError = FALSE;
10454 if (bool_equal (res->used, other->used))
10456 res->used = other->used;
10460 if (other->used && !flip)
10465 message ("Macro parameter %q used in true clause, "
10466 "but not in false clause",
10467 uentry_getName (res)),
10468 uentry_whereDeclared (res));
10475 message ("Macro parameter %q used in false clause, "
10476 "but not in true clause",
10477 uentry_getName (res)),
10478 uentry_whereDeclared (res));
10484 /* make it sef now, prevent more errors */
10485 res->info->var->kind = VKREFSEFPARAM;
10491 res->used = other->used || res->used;
10492 res->lset = other->lset || res->lset;
10493 res->uses = filelocList_append (res->uses, other->uses);
10494 other->uses = filelocList_undefined;
10500 uentry_mergeState (uentry res, uentry other, fileloc loc,
10501 bool mustReturn, bool flip, bool opt,
10504 llassert (uentry_isValid (res));
10505 llassert (uentry_isValid (other));
10507 llassert (res->ukind == other->ukind);
10508 llassert (res->ukind == KVAR);
10510 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10511 uentry_unparseFull (other)));
10513 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10514 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10515 uentry_mergeSetStates (res, other, loc, flip, cl);
10517 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10520 void uentry_setUsed (uentry e, fileloc loc)
10522 static bool firstTime = TRUE;
10523 static bool showUses = FALSE;
10524 static bool exportLocal = FALSE;
10526 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10530 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10532 showUses = context_getFlag (FLG_SHOWUSES);
10533 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10538 if (uentry_isValid (e))
10542 if (warnClause_isDefined (e->warn))
10544 flagSpec flg = warnClause_getFlag (e->warn);
10547 if (warnClause_hasMessage (e->warn))
10549 msg = cstring_copy (warnClause_getMessage (e->warn));
10553 msg = message ("Use of possibly dangerous %s",
10554 uentry_ekindNameLC (e));
10558 message ("%q: %q", msg, uentry_getName (e)),
10562 if (sRef_isMacroParamRef (e->sref))
10564 if (uentry_isYield (e) || uentry_isSefParam (e))
10570 if (context_inConditional ())
10574 message ("Macro parameter %q used in conditionally "
10575 "executed code (may or may not be "
10576 "evaluated exactly once)",
10577 uentry_getName (e)),
10580 e->info->var->kind = VKREFSEFPARAM;
10589 message ("Macro parameter %q used more than once",
10590 uentry_getName (e)),
10591 uentry_whereDeclared (e)))
10593 e->info->var->kind = VKREFSEFPARAM;
10600 if ((dp = uentry_directParamNo (e)) >= 0)
10602 uentry_setUsed (usymtab_getParam (dp), loc);
10607 if (!sRef_isLocalVar (e->sref))
10611 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10617 if (context_inMacro ())
10619 e->uses = filelocList_addUndefined (e->uses);
10623 e->uses = filelocList_addDifferentFile
10625 uentry_whereDeclared (e),
10634 bool uentry_isReturned (uentry u)
10636 return (uentry_isValid (u) && uentry_isVar (u)
10637 && (u->info->var->kind == VKRETPARAM
10638 || u->info->var->kind == VKSEFRETPARAM));
10643 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10645 llassert (uentry_isRealFunction (u));
10647 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10649 stateClauseList clauses = uentry_getStateClauseList (u);
10650 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10652 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10653 sRef_setAllocated (res, g_currentloc);
10655 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10656 stateClauseList_unparse (clauses)));
10659 ** This should be in exprNode_reflectEnsuresClause
10662 stateClauseList_postElements (clauses, cl)
10664 if (!stateClause_isGlobal (cl))
10666 sRefSet refs = stateClause_getRefs (cl);
10667 sRefMod modf = stateClause_getEffectFunction (cl);
10669 sRefSet_elements (refs, el)
10671 sRef base = sRef_getRootBase (el);
10673 if (sRef_isResult (base))
10677 sRef sr = sRef_fixBase (el, res);
10678 modf (sr, g_currentloc);
10685 } end_sRefSet_elements ;
10687 } end_stateClauseList_postElements ;
10695 sRefSet prefs = sRefSet_new ();
10696 sRef res = sRef_undefined;
10697 sRef tcref = sRef_undefined;
10698 sRef tref = sRef_undefined;
10701 params = uentry_getParams (u);
10704 ** Setting up aliases has to happen *after* setting null state!
10707 uentryList_elements (params, current)
10709 if (uentry_isReturned (current))
10711 if (exprNodeList_size (args) >= paramno)
10713 exprNode ecur = exprNodeList_nth (args, paramno);
10714 tref = exprNode_getSref (ecur);
10716 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10718 if (sRef_isValid (tref))
10720 tcref = sRef_copy (tref);
10722 if (sRef_isDead (tcref))
10724 sRef_setDefined (tcref, g_currentloc);
10725 sRef_setOnly (tcref, g_currentloc);
10728 if (sRef_isRefCounted (tcref))
10730 /* could be a new ref now (but only if its returned) */
10731 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10734 sRef_makeSafe (tcref);
10735 prefs = sRefSet_insert (prefs, tcref);
10741 } end_uentryList_elements ;
10743 if (sRefSet_size (prefs) > 0)
10745 nstate n = sRef_getNullState (u->sref);
10747 if (sRefSet_size (prefs) == 1)
10749 sRef rref = sRefSet_choose (prefs);
10751 res = sRef_makeType (sRef_getType (rref));
10752 sRef_copyState (res, tref);
10756 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10757 res = sRefSet_mergeIntoOne (prefs);
10760 if (nstate_isKnown (n))
10762 sRef_setNullState (res, n, g_currentloc);
10763 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10768 if (ctype_isFunction (u->utype))
10770 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10771 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10775 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10776 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10779 if (sRef_isRefCounted (res))
10781 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10785 if (sRef_getNullState (res) == NS_ABSNULL)
10787 ctype ct = ctype_realType (u->utype);
10789 if (ctype_isAbstract (ct))
10791 sRef_setNotNull (res, g_currentloc);
10795 if (ctype_isUser (ct))
10797 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10801 sRef_setNotNull (res, g_currentloc);
10806 if (sRef_isRefCounted (res))
10808 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10810 else if (sRef_isKillRef (res))
10812 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10819 ak = sRef_getAliasKind (res);
10821 if (alkind_isImplicit (ak))
10823 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10827 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10828 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10830 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10831 usymtab_addReallyForceMustAlias (res, tref);
10834 sRefSet_free (prefs);
10836 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10842 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10844 llassert (uentry_isRealFunction (u));
10846 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10848 stateClauseList clauses = uentry_getStateClauseList (u);
10849 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10851 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10852 sRef_setAllocated (res, g_currentloc);
10854 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10855 stateClauseList_unparse (clauses)));
10858 ** This should be in exprNode_reflectEnsuresClause
10861 stateClauseList_postElements (clauses, cl)
10863 if (!stateClause_isGlobal (cl))
10865 sRefSet refs = stateClause_getRefs (cl);
10866 sRefMod modf = stateClause_getEffectFunction (cl);
10868 sRefSet_elements (refs, el)
10870 sRef base = sRef_getRootBase (el);
10872 if (sRef_isResult (base))
10876 sRef sr = sRef_fixBase (el, res);
10877 modf (sr, g_currentloc);
10884 } end_sRefSet_elements ;
10886 } end_stateClauseList_postElements ;
10894 sRefSet prefs = sRefSet_new ();
10895 sRef res = sRef_undefined;
10898 params = uentry_getParams (u);
10900 uentryList_elements (params, current)
10902 if (uentry_isReturned (current))
10904 if (exprNodeList_size (args) >= paramno)
10906 exprNode ecur = exprNodeList_nth (args, paramno);
10907 sRef tref = exprNode_getSref (ecur);
10909 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10911 if (sRef_isValid (tref))
10913 sRef tcref = sRef_copy (tref);
10915 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10917 if (sRef_isDead (tcref))
10919 sRef_setDefined (tcref, g_currentloc);
10920 sRef_setOnly (tcref, g_currentloc);
10923 if (sRef_isRefCounted (tcref))
10925 /* could be a new ref now (but only if its returned) */
10926 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10929 sRef_makeSafe (tcref);
10930 prefs = sRefSet_insert (prefs, tcref);
10936 } end_uentryList_elements ;
10938 if (sRefSet_size (prefs) > 0)
10940 nstate n = sRef_getNullState (u->sref);
10942 if (sRefSet_size (prefs) == 1)
10944 res = sRefSet_choose (prefs);
10948 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10949 res = sRefSet_mergeIntoOne (prefs);
10952 if (nstate_isKnown (n))
10954 sRef_setNullState (res, n, g_currentloc);
10959 if (ctype_isFunction (u->utype))
10961 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10962 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10966 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10969 if (sRef_isRefCounted (res))
10971 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10976 if (sRef_getNullState (res) == NS_ABSNULL)
10978 ctype ct = ctype_realType (u->utype);
10980 if (ctype_isAbstract (ct))
10982 sRef_setNotNull (res, g_currentloc);
10986 if (ctype_isUser (ct))
10988 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10992 sRef_setNotNull (res, g_currentloc);
10997 if (sRef_isRefCounted (res))
10999 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
11001 else if (sRef_isKillRef (res))
11003 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
11010 ak = sRef_getAliasKind (res);
11012 if (alkind_isImplicit (ak))
11014 sRef_setAliasKind (res,
11015 alkind_fixImplicit (ak),
11019 sRefSet_free (prefs);
11021 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11026 static bool uentry_isRefCounted (uentry ue)
11028 ctype ct = uentry_getType (ue);
11030 if (ctype_isFunction (ct))
11032 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11036 return (ctype_isRefCounted (ct));
11041 ** old was declared yield in the specification.
11042 ** new is declared in the iter implementation.
11045 void uentry_checkYieldParam (uentry old, uentry unew)
11049 llassert (uentry_isVariable (old));
11050 llassert (uentry_isVariable (unew));
11052 unew->info->var->kind = VKYIELDPARAM;
11053 (void) checkTypeConformance (old, unew, TRUE);
11054 checkVarConformance (old, unew, TRUE, FALSE);
11056 /* get rid of param marker */
11058 name = uentry_getName (unew);
11059 cstring_free (unew->uname);
11060 unew->uname = name;
11061 unew->info->var->kind = VKREFYIELDPARAM;
11063 uentry_setUsed (old, fileloc_undefined);
11064 uentry_setUsed (unew, fileloc_undefined);
11067 /*@observer@*/ cstring
11068 uentry_ekindName (uentry ue)
11070 if (uentry_isValid (ue))
11075 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11077 return cstring_makeLiteralTemp ("Datatype");
11079 return cstring_makeLiteralTemp ("Enum member");
11081 return cstring_makeLiteralTemp ("Constant");
11083 if (uentry_isParam (ue))
11085 return cstring_makeLiteralTemp ("Parameter");
11087 else if (uentry_isExpandedMacro (ue))
11089 return cstring_makeLiteralTemp ("Expanded macro");
11093 return cstring_makeLiteralTemp ("Variable");
11096 return cstring_makeLiteralTemp ("Function");
11098 return cstring_makeLiteralTemp ("Iterator");
11100 return cstring_makeLiteralTemp ("Iterator finalizer");
11102 return cstring_makeLiteralTemp ("Struct tag");
11104 return cstring_makeLiteralTemp ("Union tag");
11106 return cstring_makeLiteralTemp ("Enum tag");
11108 return cstring_makeLiteralTemp ("Optional parameters");
11113 return cstring_makeLiteralTemp ("<Undefined>");
11119 /*@observer@*/ cstring
11120 uentry_ekindNameLC (uentry ue)
11122 if (uentry_isValid (ue))
11127 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11129 return cstring_makeLiteralTemp ("datatype");
11131 return cstring_makeLiteralTemp ("enum member");
11133 return cstring_makeLiteralTemp ("constant");
11135 if (uentry_isParam (ue))
11137 return cstring_makeLiteralTemp ("parameter");
11139 else if (uentry_isExpandedMacro (ue))
11141 return cstring_makeLiteralTemp ("expanded macro");
11145 return cstring_makeLiteralTemp ("variable");
11148 return cstring_makeLiteralTemp ("function");
11150 return cstring_makeLiteralTemp ("iterator");
11152 return cstring_makeLiteralTemp ("iterator finalizer");
11154 return cstring_makeLiteralTemp ("struct tag");
11156 return cstring_makeLiteralTemp ("union tag");
11158 return cstring_makeLiteralTemp ("enum tag");
11160 return cstring_makeLiteralTemp ("optional parameters");
11165 return cstring_makeLiteralTemp ("<Undefined>");
11171 void uentry_setHasNameError (uentry ue)
11173 llassert (uentry_isValid (ue));
11175 ue->hasNameError = TRUE;
11178 void uentry_checkName (uentry ue)
11180 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11181 uentry_observeRealName (ue),
11182 bool_unparse (uentry_isVisibleExternally (ue))));
11184 if (uentry_isValid (ue)
11185 && !context_inXHFile ()
11186 && uentry_hasName (ue)
11187 && !uentry_isElipsisMarker (ue)
11188 && context_getFlag (FLG_NAMECHECKS)
11189 && !ue->hasNameError
11190 && !uentry_isEndIter (ue)
11191 && !fileloc_isBuiltin (uentry_whereLast (ue))
11192 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11194 DPRINTF (("Here..."));
11196 if (uentry_isPriv (ue))
11198 ; /* any checks here? */
11200 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11202 ; /* no errors for externals */
11208 if (uentry_isExpandedMacro (ue))
11214 if (uentry_isExpandedMacro (ue))
11218 else if (uentry_isVariable (ue))
11220 sRef sr = uentry_getSref (ue);
11222 if (sRef_isValid (sr))
11224 scope = sRef_getScope (sr);
11231 else if (uentry_isFunction (ue)
11232 || uentry_isIter (ue)
11233 || uentry_isEndIter (ue)
11234 || uentry_isConstant (ue))
11236 scope = uentry_isStatic (ue) ? fileScope : globScope;
11238 else /* datatypes, etc. must be global */
11243 usymtab_checkDistinctName (ue, scope);
11246 if (context_getFlag (FLG_CPPNAMES))
11251 if (scope == globScope)
11253 checkExternalName (ue);
11255 else if (scope == fileScope)
11257 checkFileScopeName (ue);
11261 checkLocalName (ue);
11265 checkAnsiName (ue);
11270 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11276 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11279 if (!context_inMacro ())
11281 sRef_setGlobalScopeSafe ();
11284 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11285 uentry_setUsed (ue, loc);
11287 tloc = fileloc_createExternal ();
11288 uentry_setDefined (ue, tloc);
11289 fileloc_free (tloc);
11290 uentry_setHasNameError (ue);
11292 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11294 uentry_markOwned (ue);
11298 ue = usymtab_supReturnFileEntry (ue);
11301 if (!context_inMacro ())
11303 sRef_clearGlobalScopeSafe ();
11309 uentry uentry_makeGlobalMarker ()
11314 llassert (sRef_inGlobalScope ());
11316 ue = uentry_makeVariableAux
11317 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11318 sRef_makeGlobalMarker (),
11321 tloc = fileloc_createExternal ();
11322 uentry_setUsed (ue, tloc);
11323 uentry_setDefined (ue, tloc);
11324 fileloc_free (tloc);
11325 uentry_setHasNameError (ue);
11331 bool uentry_isGlobalMarker (uentry ue)
11333 return (uentry_isValid (ue)
11334 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11337 /* new start modifications */
11339 /* start modifications */
11341 requires: p_e is defined, is a ptr/array variable
11343 effects: sets the state of the variable
11347 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11349 llassert (uentry_isValid (p_e));
11351 if (p_e->info != NULL)
11353 if (p_e->info->var != NULL)
11355 llassert (p_e->info->var->bufinfo != NULL);
11356 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11357 sRef_setPossiblyNullTerminatedState (p_e->sref);
11363 requires: p_e is defined, is a ptr/array variable
11365 effects: sets the size of the buffer
11368 void uentry_setNullTerminatedState (uentry p_e) {
11369 llassert (uentry_isValid (p_e));
11371 if (p_e->info != NULL)
11373 if (p_e->info->var != NULL)
11375 llassert (p_e->info->var->bufinfo != NULL);
11376 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11377 sRef_setNullTerminatedState (p_e->sref);
11383 requires: p_e is defined, is a ptr/array variable
11385 effects: sets the size of the buffer
11388 void uentry_setSize (uentry p_e, int size)
11390 if (uentry_isValid (p_e))
11392 if (p_e->info != NULL)
11394 if (p_e->info->var != NULL)
11396 llassert (p_e->info->var->bufinfo != NULL);
11397 p_e->info->var->bufinfo->size = size;
11398 sRef_setSize (p_e->sref, size);
11405 requires: p_e is defined, is a ptr/array variable
11407 effects: sets the length of the buffer
11410 void uentry_setLen (uentry p_e, int len)
11412 if (uentry_isValid (p_e))
11414 if (p_e->info != NULL
11415 && p_e->info->var != NULL)
11417 llassert (p_e->info->var->bufinfo != NULL);
11418 p_e->info->var->bufinfo->len = len;
11419 sRef_setLen (p_e->sref, len);
11426 bool uentry_hasMetaStateEnsures (uentry e)
11428 if (uentry_isValid (e) && uentry_isFunction (e))
11430 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11438 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11440 llassert (uentry_isValid (e) && uentry_isFunction (e));
11441 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11444 # ifdef DEBUGSPLINT
11447 ** For debugging only
11450 void uentry_checkValid (uentry ue)
11452 if (uentry_isValid (ue))
11454 sRef_checkCompletelyReasonable (ue->sref);