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 e->cQuals = qualList_undefined;
1014 checkGlobalsModifies (e, mods);
1015 e->info->fcn->mods = mods;
1020 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
1022 functionClauseList_elements (clauses, el)
1024 DPRINTF (("Reflect clause: %s on %s",
1025 functionClause_unparse (el), uentry_getName (ue)));
1027 if (functionClause_isNoMods (el))
1029 modifiesClause mel = functionClause_getModifies (el);
1031 if (uentry_hasGlobs (ue))
1036 ("No globals and modifies inconsistent to globals clause for %q: %q",
1037 uentry_getName (ue),
1038 globSet_unparse (uentry_getGlobs (ue))),
1039 modifiesClause_getLoc (mel));
1043 if (uentry_hasMods (ue))
1048 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1049 uentry_getName (ue),
1050 sRefSet_unparse (uentry_getMods (ue))),
1051 modifiesClause_getLoc (mel));
1054 uentry_setGlobals (ue, globSet_undefined);
1055 uentry_setModifies (ue, sRefSet_undefined);
1057 else if (functionClause_isGlobals (el))
1059 globalsClause glc = functionClause_getGlobals (el);
1061 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1062 globalsClause_unparse (glc)));
1064 if (uentry_hasGlobs (ue))
1069 ("Multiple globals clauses for %q: %q",
1070 uentry_getName (ue),
1071 globalsClause_unparse (glc)),
1072 globalsClause_getLoc (glc));
1073 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1077 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1078 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1079 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1082 else if (functionClause_isModifies (el))
1084 modifiesClause mlc = functionClause_getModifies (el);
1086 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1088 if (uentry_hasMods (ue))
1096 ("Multiple modifies clauses for %s: %s",
1097 uentry_getName (ue),
1098 modifiesClause_unparse (mlc)),
1099 modifiesClause_getLoc (mlc)))
1101 llhint (message ("Previous modifies clause: ",
1102 sRefSet_unparse (uentry_getMods (ue))));
1108 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1112 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1115 else if (functionClause_isEnsures (el))
1117 functionConstraint cl = functionClause_takeEnsures (el);
1118 DPRINTF (("Setting post: %s / %s",
1119 uentry_unparse (ue), functionConstraint_unparse (cl)));
1120 uentry_setPostconditions (ue, cl);
1122 else if (functionClause_isRequires (el))
1124 functionConstraint cl = functionClause_takeRequires (el);
1125 uentry_setPreconditions (ue, cl);
1127 else if (functionClause_isState (el))
1129 stateClause sc = functionClause_takeState (el);
1131 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1133 sRefSet rfs = stateClause_getRefs (sc);
1135 sRefSet_elements (rfs, s)
1137 if (sRef_isParam (s))
1140 ** Can't use requires on parameters
1144 (FLG_ANNOTATIONERROR,
1145 message ("Requires clauses for %q concerns parameters %q should be "
1146 "a parameter annotation instead: %q",
1147 uentry_unparse (ue),
1149 stateClause_unparse (sc)),
1150 stateClause_loc (sc));
1152 } end_sRefSet_elements ;
1155 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1156 uentry_addStateClause (ue, sc);
1158 else if (functionClause_isWarn (el))
1160 warnClause wc = functionClause_takeWarn (el);
1161 uentry_addWarning (ue, wc);
1165 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1167 } end_functionClauseList_elements ;
1169 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1170 stateClauseList_checkAll (ue);
1173 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1175 bool leaveFunc = FALSE;
1177 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1178 typeId_invalid, globSet_undefined,
1179 sRefSet_undefined, warnClause_undefined,
1182 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1185 ** This makes parameters names print out correctly.
1186 ** (But we might be a local variable declaration for a function type...)
1189 if (context_inFunctionLike ())
1191 DPRINTF (("Header: %s / %s",
1192 uentry_unparse (context_getHeader ()),
1193 idDecl_unparse (id)));
1197 context_enterFunctionDeclaration (ue);
1201 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1202 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1203 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1204 reflectImplicitFunctionQualifiers (ue, FALSE);
1205 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1206 uentry_reflectClauses (ue, idDecl_getClauses (id));
1207 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1209 if (!uentry_isStatic (ue)
1210 && cstring_equalLit (ue->uname, "main"))
1212 ctype typ = ue->utype;
1216 llassert (ctype_isFunction (typ));
1218 retval = ctype_getReturnType (typ);
1220 if (!ctype_isInt (retval))
1224 message ("Function main declared to return %s, should return int",
1225 ctype_unparse (retval)),
1226 uentry_whereDeclared (ue));
1229 args = ctype_argsFunction (typ);
1231 if (uentryList_isMissingParams (args)
1232 || uentryList_size (args) == 0)
1238 if (uentryList_size (args) != 2)
1242 message ("Function main declared with %d arg%&, "
1243 "should have 2 (int argc, char *argv[])",
1244 uentryList_size (args)),
1245 uentry_whereLast (ue));
1249 uentry arg = uentryList_getN (args, 0);
1250 ctype ct = uentry_getType (arg);
1252 if (!ctype_isInt (ct))
1256 message ("Parameter 1, %q, of function main declared "
1257 "with type %t, should have type int",
1258 uentry_getName (arg), ct),
1259 uentry_whereDeclared (arg));
1262 arg = uentryList_getN (args, 1);
1263 ct = uentry_getType (arg);
1265 if (ctype_isArrayPtr (ct)
1266 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1267 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1275 message ("Parameter 2, %q, of function main declared "
1276 "with type %t, should have type char **",
1277 uentry_getName (arg), ct),
1278 uentry_whereDeclared (arg));
1286 context_exitFunctionDeclaration ();
1292 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1294 alkind ak = sRef_getAliasKind (e->sref);
1296 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1297 && context_getFlag (FLG_PARAMIMPTEMP))
1299 exkind ek = sRef_getExKind (e->sref);
1301 if (exkind_isKnown (ek))
1303 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1304 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1305 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1309 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1310 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1315 static /*@only@*/ /*@notnull@*/ uentry
1316 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1317 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1319 cstring pname = makeParam (n);
1322 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1323 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1325 cstring_free (pname);
1326 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1327 uentry_implicitParamAnnots (e);
1328 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1330 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1332 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1333 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1334 e->info->var->defstate = defstate;
1337 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1343 uentry_setRefCounted (uentry e)
1345 if (uentry_isValid (e))
1347 uentry_setAliasKind (e, AK_REFCOUNTED);
1348 sRef_storeState (e->sref);
1354 uentry_setStatic (uentry c)
1356 if (uentry_isValid (c))
1358 alkind ak = sRef_getAliasKind (c->sref);
1359 c->storageclass = SCSTATIC;
1361 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1363 if (!alkind_isUnknown (ak)
1364 && !alkind_isStatic (ak))
1366 if (!(ctype_isRealPointer (uentry_getType (c)))
1367 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1368 && !alkind_isRefCounted (ak))
1370 if (alkind_isImplicit (ak)
1371 && alkind_isDependent (ak)
1372 && ctype_isArray (uentry_getType (c)))
1374 ; /* no error for observer arrays */
1380 message ("Static storage %q declared as %s",
1382 alkind_unparse (ak)),
1383 uentry_whereDeclared (c));
1389 if (alkind_isUnknown (ak)
1390 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1391 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1393 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1394 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1402 uentry_setExtern (uentry c)
1404 if (uentry_isValid (c))
1405 c->storageclass = SCEXTERN;
1409 uentry_setParamNo (uentry ue, int pno)
1411 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1412 sRef_setParamNo (ue->sref, pno);
1416 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1418 sRefSet_allElements (sr, el)
1420 sRef base = sRef_getRootBase (el);
1422 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1423 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1425 if (!globSet_member (ue->info->fcn->globs, base))
1427 if (uentry_hasGlobs (ue)
1428 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1431 (FLG_WARNMISSINGGLOBALS,
1433 ("Modifies list for %q uses global %q, "
1434 "not included in globals list.",
1435 uentry_getName (ue),
1436 sRef_unparse (base)),
1437 uentry_whereLast (ue)))
1439 uentry_showWhereSpecified (ue);
1443 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1445 if (sRef_isFileStatic (base))
1447 context_recordFileGlobals (ue->info->fcn->globs);
1451 } end_sRefSet_allElements;
1455 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1457 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1461 uentry_fixupSref (uentry ue)
1465 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1470 sr = uentry_getSref (ue);
1472 sRef_resetState (sr);
1473 sRef_clearDerived (sr);
1475 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1476 llassert (sRef_isValid (sr));
1478 if (uentry_isVariable (ue))
1481 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1482 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1483 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1487 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1490 ** Okay to allow multiple clauses of the same kind.
1491 */ /*@i834 is this true?@*/
1493 ue->info->fcn->specclauses =
1494 stateClauseList_add (ue->info->fcn->specclauses, sc);
1496 /* Will call checkAll to check later... */
1499 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1501 llassert (uentry_isFunction (ue));
1502 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1504 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1505 ue->info->fcn->specclauses = clauses;
1506 stateClauseList_checkAll (ue);
1507 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1511 ** Used for @modifies@ @endmodifies@ syntax.
1513 ** If ue is specified, sr must contain *only*:
1515 ** o file static globals
1516 ** o sRef's derived from modifies spec (i.e., more specific than
1517 ** what was specified)
1519 ** Otherwise, if sr has modifies it must match sr.
1521 ** If it doesn't have modifies, set them to sr.
1525 uentry_checkModifiesContext (void)
1527 if (sRef_modInFunction ())
1531 ("Modifies list not in function context. "
1532 "A modifies list can only appear following the parameter list "
1533 "in a function declaration or header."));
1542 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1544 if (!uentry_checkModifiesContext ())
1550 if (uentry_isValid (ue))
1552 if (uentry_isIter (ue))
1554 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1555 ue->info->iter->mods = sr;
1559 uentry_convertVarFunction (ue);
1560 llassertfatal (uentry_isFunction (ue));
1561 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1563 ue->info->fcn->mods = sr;
1564 ue->info->fcn->hasMods = TRUE;
1566 checkGlobalsModifies (ue, sr);
1569 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1571 ue->info->fcn->hasGlobs = TRUE;
1574 if (sRefSet_hasStatic (ue->info->fcn->mods))
1576 context_recordFileModifies (ue->info->fcn->mods);
1586 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1589 ** Function already has one modifies clause (possibly from
1590 ** a specification).
1593 if (!uentry_checkModifiesContext ())
1598 llassert (uentry_isValid (ue));
1600 if (uentry_isIter (ue))
1602 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1606 llassertfatal (uentry_isFunction (ue));
1607 llassert (ue->info->fcn->hasMods);
1609 checkGlobalsModifies (ue, sr);
1610 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1612 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1614 ue->info->fcn->hasGlobs = TRUE;
1618 if (sRefSet_hasStatic (ue->info->fcn->mods))
1620 context_recordFileModifies (ue->info->fcn->mods);
1624 bool uentry_hasWarning (uentry ue)
1626 return (uentry_isValid (ue)
1627 && warnClause_isDefined (ue->warn));
1630 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1632 llassert (uentry_isValid (ue));
1633 llassert (warnClause_isUndefined (ue->warn));
1638 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1640 if (sRef_modInFunction ())
1643 (message ("Precondition list not in function context. "
1644 "A precondition list can only appear following the parameter list "
1645 "in a function declaration or header."));
1647 /*@-mustfree@*/ return; /*@=mustfree@*/
1650 if (uentry_isValid (ue))
1652 uentry_convertVarFunction (ue);
1653 llassertfatal (uentry_isFunction (ue));
1655 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1658 I changed this so it didn't appear as a Splint bug
1659 among other things this gets triggered when there is
1660 a function with two requires clauses. Now Splint
1661 prints an error and tries to conjoin the lists.
1664 (message ("Duplicate precondition list"
1665 "Attemping the conjoin the requires clauses"
1669 /* should conjoin constraints? */
1671 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1675 ue->info->fcn->preconditions = preconditions;
1680 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1689 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1691 if (sRef_modInFunction ())
1694 (message ("Postcondition list not in function context. "
1695 "A postcondition list can only appear following the parameter list "
1696 "in a function declaration or header."));
1698 /*@-mustfree@*/ return; /*@=mustfree@*/
1701 if (uentry_isValid (ue))
1703 uentry_convertVarFunction (ue);
1704 llassertfatal (uentry_isFunction (ue));
1706 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1708 ue->info->fcn->postconditions = postconditions;
1712 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1717 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1722 ** requires: new and old are functions
1726 checkGlobalsConformance (/*@notnull@*/ uentry old,
1727 /*@notnull@*/ uentry unew,
1728 bool mustConform, bool completeConform)
1730 bool hasInternalState = FALSE;
1732 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1734 if (globSet_isDefined (unew->info->fcn->globs))
1736 globSet_allElements (unew->info->fcn->globs, el)
1738 if (sRef_isFileStatic (el))
1740 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1742 if (sRef_isInvalid (sr))
1744 bool hasError = FALSE;
1746 if (!hasInternalState
1747 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1748 sRef_makeInternalState ()))
1749 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1750 sRef_makeSpecState ())))
1753 && !uentry_isStatic (old)
1756 message ("Globals list for %q includes internal state, %q, "
1757 "but %s without globals internalState.",
1758 uentry_getName (old),
1760 uentry_specOrDefName (old)),
1761 uentry_whereLast (unew)))
1763 uentry_showWhereSpecified (old);
1767 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1768 sRef_makeInternalState ());
1769 hasInternalState = TRUE;
1773 && fileloc_sameFile (uentry_whereDeclared (unew),
1774 uentry_whereDeclared (old)))
1779 message ("Function %q inconsistently %rdeclared (in "
1780 "same file) with file static global %q in "
1782 uentry_getName (unew),
1783 uentry_isDeclared (old),
1785 uentry_whereDeclared (unew)))
1787 uentry_showWhereSpecified (old);
1792 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1793 context_recordFileGlobals (old->info->fcn->globs);
1797 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1799 if (sRef_isInvalid (sr))
1804 message ("Function %q inconsistently %rdeclared with "
1805 "%q in globals list",
1806 uentry_getName (unew),
1807 uentry_isDeclared (old),
1809 uentry_whereDeclared (unew)))
1811 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1812 uentry_showWhereSpecified (old);
1817 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1823 ("Function %q global %q inconsistently "
1824 "%rdeclared as %qout global",
1825 uentry_getName (unew),
1827 uentry_isDeclared (old),
1828 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1829 uentry_whereDeclared (unew)))
1831 uentry_showWhereSpecified (old);
1836 } end_globSet_allElements ;
1838 if (completeConform)
1840 globSet_allElements (old->info->fcn->globs, el)
1842 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1844 if (sRef_isInvalid (sr))
1847 && uentry_isReallySpecified (old)
1850 message ("Function %q specified with %q in globals list, "
1851 "but declared without %q",
1852 uentry_getName (unew),
1855 uentry_whereDeclared (unew)))
1857 uentry_showWhereSpecified (old);
1860 } end_globSet_allElements;
1865 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1867 if (uentry_isReallySpecified (old)
1870 message ("%s %q specified with globals list, but "
1871 "declared with no globals",
1872 ekind_capName (unew->ukind),
1873 uentry_getName (unew)),
1874 uentry_whereDeclared (unew)))
1877 (message ("Specification globals: %q",
1878 globSet_unparse (old->info->fcn->globs)),
1879 uentry_whereSpecified (old));
1883 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1884 old->info->fcn->globs);
1889 ** new modifies list must be included by old modifies list.
1891 ** file static state may be added to new, if old has internal.
1895 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1896 bool mustConform, bool completeConform)
1899 bool changedMods = FALSE;
1900 bool modInternal = FALSE;
1902 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1904 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1905 newMods = unew->info->fcn->mods;
1907 if (sRefSet_isEmpty (newMods))
1909 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1910 && uentry_isReallySpecified (old))
1914 message ("%s %q specified with modifies clause, "
1915 "but declared with no modifies clause",
1916 ekind_capName (unew->ukind),
1917 uentry_getName (unew)),
1918 uentry_whereDeclared (unew)))
1920 llgenindentmsg (message ("Specification has modifies %q",
1921 sRefSet_unparse (old->info->fcn->mods)),
1922 uentry_whereSpecified (old));
1929 sRefSet_allElements (newMods, current)
1931 if (sRef_isValid (current))
1933 sRef rb = sRef_getRootBase (current);
1935 if (sRef_isFileStatic (rb))
1939 if (!sRefSet_isSameMember (old->info->fcn->mods,
1940 sRef_makeInternalState ())
1941 && !sRefSet_isSameMember (old->info->fcn->mods,
1942 sRef_makeSpecState ()))
1945 && !uentry_isStatic (old)
1949 ("Modifies list for %q includes internal state, "
1950 "but %s without modifies internal.",
1951 uentry_getName (old),
1952 uentry_specOrDefName (old)),
1953 uentry_whereLast (unew)))
1955 uentry_showWhereSpecified (old);
1958 old->info->fcn->mods =
1959 sRefSet_insert (old->info->fcn->mods,
1960 sRef_makeInternalState ());
1965 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1971 if (sRef_canModifyVal (current, old->info->fcn->mods))
1973 int size = sRefSet_size (old->info->fcn->mods);
1975 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1978 if (sRefSet_size (old->info->fcn->mods) != size)
1989 ("Modifies list for %q contains %q, not modifiable "
1991 uentry_getName (old),
1992 sRef_unparse (current),
1993 uentry_specDeclName (old)),
1994 uentry_whereLast (unew)))
1996 uentry_showWhereSpecified (old);
2001 } end_sRefSet_allElements;
2003 if (completeConform && uentry_isReallySpecified (old))
2005 sRefSet_allElements (old->info->fcn->mods, el)
2007 if (sRef_canModify (el, newMods))
2016 ("Specification modifies clause for %q contains %q, "
2017 "not included in declaration modifies clause",
2018 uentry_getName (old),
2020 uentry_whereLast (unew)))
2022 uentry_showWhereSpecified (old);
2025 } end_sRefSet_allElements ;
2029 ** Make sure file static elements will be removed.
2034 context_recordFileModifies (old->info->fcn->mods);
2039 uentry_checkMutableType (uentry ue)
2041 ctype ct = uentry_getType (ue);
2043 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2045 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2047 voptgenerror (FLG_MUTREP,
2048 message ("Mutable abstract type %q declared without pointer "
2049 "indirection: %t (violates assignment semantics)",
2050 uentry_getName (ue), ct),
2051 uentry_whereDeclared (ue));
2056 uentry_setMutable (uentry e)
2058 llassert (uentry_isDatatype (e));
2059 e->info->datatype->mut = YES;
2063 uentry_checkIterArgs (uentry ue)
2065 bool hasYield = FALSE;
2068 llassert (uentry_isIter (ue));
2070 args = uentry_getParams (ue);
2072 uentryList_elements (args, el)
2074 sstate ds = uentry_getDefState (el);
2076 if (uentry_isYield (el))
2081 if (sstate_isUnknown (ds))
2083 uentry_setDefState (el, SS_DEFINED);
2089 } end_uentryList_elements;
2093 voptgenerror (FLG_HASYIELD,
2094 message ("Iterator %q declared with no yield parameters",
2095 uentry_getName (ue)),
2096 uentry_whereDeclared (ue));
2101 chkind_fromQual (qual qel)
2103 if (qual_isChecked (qel))
2107 else if (qual_isCheckMod (qel))
2111 else if (qual_isCheckedStrict (qel))
2113 return CH_CHECKEDSTRICT;
2115 else if (qual_isUnchecked (qel))
2117 return CH_UNCHECKED;
2122 /*@notreached@*/ return CH_UNKNOWN;
2127 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2129 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2131 if (!uentry_isRefCounted (ue))
2134 (FLG_ANNOTATIONERROR,
2135 message ("Reference counting qualifier %s used on non-reference "
2136 "counted storage: %q",
2138 uentry_unparse (ue)),
2139 uentry_whereLast (ue));
2143 alkind ak = alkind_fromQual (qel);
2145 uentry_setAliasKind (ue, ak);
2148 else if (qual_isRefCounted (qel))
2150 ctype ct = ctype_realType (uentry_getType (ue));
2153 if (ctype_isPointer (ct)
2154 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2156 /* check there is a refs field */
2157 uentryList fields = ctype_getFields (rt);
2158 uentry refs = uentry_undefined;
2160 uentryList_elements (fields, field)
2162 if (uentry_isRefsField (field))
2164 if (uentry_isValid (refs))
2167 (FLG_ANNOTATIONERROR,
2168 message ("Reference counted structure type %s has "
2169 "multiple refs fields: %q and %q",
2171 uentry_getName (refs),
2172 uentry_getName (field)),
2173 uentry_whereLast (field));
2178 } end_uentryList_elements;
2180 if (uentry_isInvalid (refs))
2184 message ("Reference counted structure type %s has "
2186 ctype_unparse (ct)),
2188 ("To count reference, the structure must have a field named "
2189 "refs of type int."),
2192 else if (!ctype_isInt (uentry_getType (refs)))
2195 (FLG_ANNOTATIONERROR,
2196 message ("Reference counted structure type %s refs field has "
2197 "type %s (should be int)", ctype_unparse (ct),
2198 ctype_unparse (uentry_getType (refs))),
2199 uentry_whereLast (refs));
2203 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2204 uentry_whereDeclared (ue));
2209 if ((ctype_isPointer (ct)
2210 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2211 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2213 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2214 uentry_whereDeclared (ue));
2219 (FLG_ANNOTATIONERROR,
2220 message ("Non-pointer to structure type %s declared with "
2221 "refcounted qualifier",
2222 ctype_unparse (ct)),
2223 uentry_whereLast (ue));
2227 else if (qual_isRefs (qel))
2229 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2231 uentry_setAliasKind (ue, AK_REFS);
2236 (FLG_ANNOTATIONERROR,
2237 message ("Refs qualifier used on non-structure field: %q",
2238 uentry_unparse (ue)),
2239 uentry_whereLast (ue));
2242 else if (qual_isAliasQual (qel))
2244 alkind ak = alkind_fromQual (qel);
2246 alkind oldak = uentry_getAliasKind (ue);
2247 ctype ut = uentry_getType (ue);
2249 if (alkind_isImplicit (ak)
2250 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2252 /* ignore the implied qualifier */
2256 if (uentry_isEitherConstant (ue))
2259 (FLG_ANNOTATIONERROR,
2260 message ("Alias qualifier %s used on constant: %q",
2261 alkind_unparse (ak), uentry_unparse (ue)),
2262 uentry_whereLast (ue));
2267 if (ctype_isFunction (ut))
2269 ut = ctype_getReturnType (ut);
2272 if (!(ctype_isVisiblySharable (ut)
2273 || ctype_isRealArray (ut)
2274 || ctype_isRealSU (ut)))
2276 if (!qual_isImplied (qel))
2279 (FLG_ANNOTATIONERROR,
2280 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2281 alkind_unparse (ak), ut, uentry_getName (ue)),
2282 uentry_whereLast (ue));
2289 if (uentry_isRefCounted (ue))
2291 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2292 || qual_isExposed (qel)
2293 || qual_isObserver (qel)))
2295 if (!qual_isImplied (qel))
2298 (FLG_ANNOTATIONERROR,
2300 ("Alias qualifier %s used on reference counted storage: %q",
2301 alkind_unparse (ak),
2302 uentry_unparse (ue)),
2303 uentry_whereLast (ue));
2311 if (qual_isRefQual (qel))
2314 (FLG_ANNOTATIONERROR,
2315 message ("Qualifier %s used on non-reference counted storage: %q",
2316 alkind_unparse (ak), uentry_unparse (ue)),
2317 uentry_whereLast (ue));
2326 uentry_setAliasKind (ue, ak);
2329 else if (qual_isNull (qel))
2331 if (uentry_isConstant (ue))
2335 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2336 uentry_whereDeclared (ue));
2340 uentry_setNullState (ue, NS_POSNULL);
2343 else if (qual_isRelNull (qel))
2345 uentry_setNullState (ue, NS_RELNULL);
2347 else if (qual_isNotNull (qel))
2349 uentry_setNullState (ue, NS_MNOTNULL);
2351 else if (qual_isAbstract (qel)
2352 || qual_isConcrete (qel))
2354 if (!uentry_isDatatype (ue))
2357 (FLG_ANNOTATIONERROR,
2358 message ("Qualifier %s used with non-datatype",
2359 qual_unparse (qel)),
2360 uentry_whereLast (ue));
2364 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2367 else if (qual_isMutable (qel))
2369 if (!uentry_isDatatype (ue))
2372 (FLG_ANNOTATIONERROR,
2373 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2374 uentry_whereLast (ue));
2378 if (!ynm_isOn (ue->info->datatype->mut))
2380 uentry_checkMutableType (ue);
2383 ue->info->datatype->mut = YES;
2386 else if (qual_isImmutable (qel))
2388 if (!uentry_isDatatype (ue))
2390 voptgenerror (FLG_ANNOTATIONERROR,
2391 message ("Qualifier %s used with non-datatype",
2392 qual_unparse (qel)),
2393 uentry_whereLast (ue));
2397 ue->info->datatype->mut = NO;
2400 else if (qual_isNullPred (qel))
2402 uentry_convertVarFunction (ue);
2404 if (uentry_isFunction (ue))
2406 ctype typ = uentry_getType (ue);
2407 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2409 if (ctype_isRealBool (rtype))
2411 uentryList pl = ctype_argsFunction (typ);
2413 if (uentryList_size (pl) == 1)
2415 ue->info->fcn->nullPred = qel;
2419 voptgenerror (FLG_ANNOTATIONERROR,
2420 message ("Qualifier %s used with function having %d "
2421 "arguments (should have 1)",
2423 uentryList_size (pl)),
2424 uentry_whereLast (ue));
2429 voptgenerror (FLG_ANNOTATIONERROR,
2430 message ("Qualifier %s used with function returning %s "
2431 "(should return bool)",
2433 ctype_unparse (rtype)),
2434 uentry_whereLast (ue));
2439 voptgenerror (FLG_ANNOTATIONERROR,
2440 message ("Qualifier %s used with non-function",
2441 qual_unparse (qel)),
2442 uentry_whereLast (ue));
2445 else if (qual_isExitQual (qel))
2447 exitkind exk = exitkind_fromQual (qel);
2449 if (uentry_isFunction (ue))
2451 if (exitkind_isKnown (ue->info->fcn->exitCode))
2453 voptgenerror (FLG_ANNOTATIONERROR,
2454 message ("Multiple exit qualifiers used on function %q: %s, %s",
2455 uentry_getName (ue),
2456 exitkind_unparse (ue->info->fcn->exitCode),
2457 exitkind_unparse (exk)),
2458 uentry_whereLast (ue));
2461 ue->info->fcn->exitCode = exk;
2465 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2467 uentry_makeVarFunction (ue);
2468 ue->info->fcn->exitCode = exk;
2472 voptgenerror (FLG_ANNOTATIONERROR,
2473 message ("Exit qualifier %s used with non-function (type %s)",
2475 ctype_unparse (uentry_getType (ue))),
2476 uentry_whereLast (ue));
2480 else if (qual_isMetaState (qel))
2482 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2484 if (annotationInfo_matchesContext (ainfo, ue))
2486 DPRINTF (("Reflecting %s on %s",
2487 annotationInfo_unparse (ainfo),
2488 uentry_unparseFull (ue)));
2490 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2491 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2492 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2497 (FLG_ANNOTATIONERROR,
2498 message ("Attribute annotation %s used in inconsistent context: %q",
2500 uentry_unparse (ue)),
2501 uentry_whereLast (ue)))
2503 /*@i! annotationInfo_showContextError (ainfo, ue); */
2509 if (qual_isCQual (qel))
2512 I'm now storing the C qualifiers in the uentry
2513 This was necessary to get code generation to work
2515 ue->cQuals = qualList_add(ue->cQuals, qel);
2519 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2525 uentry_reflectQualifiers (uentry ue, qualList q)
2527 llassert (uentry_isValid (ue));
2529 DPRINTF (("Reflect qualifiers: %s / %s",
2530 uentry_unparseFull (ue), qualList_unparse (q)));
2532 qualList_elements (q, qel)
2534 if (qual_isStatic (qel))
2536 uentry_setStatic (ue);
2538 else if (qual_isUnused (qel))
2540 uentry_setUsed (ue, fileloc_undefined);
2541 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2543 else if (qual_isExternal (qel))
2545 fileloc_free (ue->whereDefined);
2546 ue->whereDefined = fileloc_createExternal ();
2548 else if (qual_isSef (qel))
2550 if (uentry_isVariable (ue))
2552 vkind vk = ue->info->var->kind;
2554 llassert (vk != VKREFPARAM);
2556 if (vk == VKYIELDPARAM)
2559 (FLG_ANNOTATIONERROR,
2560 message ("Qualifier sef cannot be used with %s: %q",
2561 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2562 uentry_unparse (ue)),
2563 uentry_whereLast (ue));
2565 else if (vk == VKRETPARAM)
2567 ue->info->var->kind = VKSEFRETPARAM;
2571 ue->info->var->kind = VKSEFPARAM;
2577 (FLG_ANNOTATIONERROR,
2578 message ("Qualifier sef is meaningful only on parameters: %q",
2579 uentry_unparse (ue)),
2580 uentry_whereLast (ue));
2583 else if (qual_isExtern (qel))
2585 ue->storageclass = SCEXTERN;
2587 else if (qual_isGlobalQual (qel)) /* undef, killed */
2589 DPRINTF (("Reflecting qual: %s / %s",
2590 qual_unparse (qel), uentry_unparse (ue)));
2592 if (uentry_isVariable (ue))
2594 sstate oldstate = ue->info->var->defstate;
2595 sstate defstate = sstate_fromQual (qel);
2598 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2599 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2601 defstate = SS_UNDEFKILLED;
2608 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2609 ue->info->var->defstate = defstate;
2614 (FLG_ANNOTATIONERROR,
2615 message ("Qualifier %s used on non-variable: %q",
2616 qual_unparse (qel), uentry_unparse (ue)),
2617 uentry_whereLast (ue));
2620 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2622 /* start modifications */
2623 else if( qual_isBufQualifier(qel) ) {
2624 ctype ct = ctype_realType(uentry_getType(ue));
2625 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2627 if( uentry_hasBufStateInfo(ue) ) {
2628 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2630 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2631 /* If formal func param */
2632 uentry_setNullTerminatedState(ue);
2633 uentry_setLen (ue, 1);
2634 uentry_setSize (ue, 1);
2636 sRef_setNullTerminatedState(uentry_getSref(ue));
2637 sRef_setLen (uentry_getSref(ue), 1);
2638 sRef_setSize (uentry_getSref(ue), 1);
2640 uentry_setPossiblyNullTerminatedState(ue);
2642 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2646 /* put other BufState Qualifiers here */
2648 cstring s = uentry_getName(ue);
2649 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2650 struct for identifier %s\n", s) );
2652 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2654 sRef retSref = uentry_getSref (ue);
2655 ctype retType = sRef_getType (retSref);
2657 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2658 sRef_setNullTerminatedState (retSref);
2664 message ("Qualifier %s used on non-pointer on \
2665 function return: %q", qual_unparse (qel),
2666 uentry_unparse (ue)));
2673 message ("Qualifier %s used on non-pointer: %q",
2674 qual_unparse (qel), uentry_unparse (ue)));
2676 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2678 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2680 ctype realType = ctype_realType (ue->utype);
2681 sstate defstate = sstate_fromQual (qel);
2683 if (ctype_isFunction (realType))
2685 realType = ctype_realType (ctype_getReturnType (realType));
2688 if (qual_isRelDef (qel))
2690 ; /* okay anywhere */
2694 if (!ctype_isAP (realType)
2695 && !ctype_isSU (realType)
2696 && !ctype_isUnknown (realType)
2697 && !ctype_isAbstract (ue->utype))
2700 (FLG_ANNOTATIONERROR,
2701 message ("Qualifier %s used on non-pointer or struct: %q",
2702 qual_unparse (qel), uentry_unparse (ue)),
2703 uentry_whereLast (ue));
2707 uentry_setDefState (ue, defstate);
2709 if (sRef_isStateSpecial (ue->sref)
2710 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2712 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2715 else if (qual_isYield (qel))
2717 if (uentry_isVariable (ue))
2719 ue->info->var->kind = VKYIELDPARAM;
2724 (FLG_ANNOTATIONERROR,
2725 message ("Qualifier %s used on non-iterator parameter: %q",
2726 qual_unparse (qel), uentry_unparse (ue)),
2727 uentry_whereLast (ue));
2730 else if (qual_isExQual (qel))
2732 exkind ek = exkind_fromQual (qel);
2733 ctype ut = uentry_getType (ue);
2735 DPRINTF (("Reflect ex qual: %s / %s",
2736 uentry_unparse (ue), exkind_unparse (ek)));
2738 if (ctype_isFunction (ut))
2740 ut = ctype_getReturnType (ut);
2743 if (!(ctype_isVisiblySharable (ut))
2744 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2745 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2747 if (!qual_isImplied (qel))
2749 if (ctype_isImmutableAbstract (ut)) {
2751 (FLG_REDUNDANTSHAREQUAL,
2752 message ("Qualifier %s used on unsharable storage type %t: %q",
2753 exkind_unparse (ek), ut, uentry_getName (ue)),
2754 uentry_whereLast (ue));
2757 (FLG_MISPLACEDSHAREQUAL,
2758 message ("Qualifier %s used on unsharable storage type %t: %q",
2759 exkind_unparse (ek), ut, uentry_getName (ue)),
2760 uentry_whereLast (ue));
2766 alkind ak = sRef_getAliasKind (ue->sref);
2768 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2769 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2771 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2773 if (!alkind_isTemp (ak))
2775 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2776 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2779 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2780 || alkind_isOwned (ak))
2788 message ("Exposure qualifier %s used on %s storage (should "
2789 "be dependent): %q",
2791 alkind_unparse (ak),
2792 uentry_unparse (ue)));
2796 else if (qual_isGlobCheck (qel))
2798 if (uentry_isVariable (ue))
2800 chkind ch = chkind_fromQual (qel);
2802 if (ue->info->var->checked != CH_UNKNOWN)
2804 if (ch == ue->info->var->checked)
2806 llerror (FLG_SYNTAX,
2807 message ("Redundant %s qualifier on %q",
2809 uentry_getName (ue)));
2813 llerror (FLG_SYNTAX,
2815 ("Contradictory %s and %s qualifiers on %q",
2817 checkedName (ue->info->var->checked),
2818 uentry_getName (ue)));
2822 ue->info->var->checked = ch;
2828 message ("Qualifier %s used with non-variable",
2829 qual_unparse (qel)));
2832 else if (qual_isReturned (qel))
2834 if (uentry_isVariable (ue))
2836 ue->info->var->kind = VKRETPARAM;
2840 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2841 qual_unparse (qel)));
2846 uentry_reflectOtherQualifier (ue, qel);
2849 sRef_storeState (ue->sref);
2850 } end_qualList_elements;
2854 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2858 uentry_isOnly (uentry ue)
2860 return (!uentry_isUndefined (ue)
2861 && uentry_isVariable (ue)
2862 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2866 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2868 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2869 sRef_setOrigAliasKind (ue->sref, ak);
2873 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2875 if (uentry_isVariable (ue))
2877 ue->info->var->nullstate = ns;
2880 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2884 uentry_isUnique (uentry ue)
2886 return (!uentry_isUndefined (ue)
2887 && uentry_isVariable (ue)
2888 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2892 uentry_isFileStatic (uentry ue)
2894 return (uentry_isStatic (ue)
2895 && (!uentry_isVariable (ue)
2896 || sRef_isFileStatic (uentry_getSref (ue))));
2900 uentry_isExported (uentry ue)
2902 if (uentry_isValid (ue))
2904 if (uentry_isVariable (ue))
2906 return (sRef_isRealGlobal (uentry_getSref (ue)));
2910 return !uentry_isStatic (ue);
2918 uentry_isNonLocal (uentry ue)
2920 return (uentry_isValid (ue) && uentry_isVariable (ue)
2921 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2925 uentry_isGlobalVariable (uentry ue)
2927 return (uentry_isValid (ue) && uentry_isVariable (ue)
2928 && sRef_isFileOrGlobalScope (ue->sref));
2932 uentry_isVisibleExternally (uentry ue)
2934 return (uentry_isValid (ue)
2935 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2936 || (!uentry_isStatic (ue)
2937 && (uentry_isFunction (ue)
2938 || uentry_isIter (ue)
2939 || uentry_isEndIter (ue)
2940 || uentry_isConstant (ue)
2941 || uentry_isDatatype (ue)
2942 || uentry_isAnyTag (ue)))));
2946 uentry_isPrintfLike (uentry ue)
2948 return (uentry_isFunction (ue)
2949 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2953 uentry_isScanfLike (uentry ue)
2955 return (uentry_isFunction (ue)
2956 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2960 uentry_isMessageLike (uentry ue)
2962 return (uentry_isFunction (ue)
2963 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2966 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2968 uentryList args = uentry_getParams (ue);
2970 if (!uentryList_isMissingParams (args))
2972 uentry last = uentry_undefined;
2974 uentryList_elements (args, current)
2976 if (uentry_isElipsisMarker (current))
2978 if (uentry_isUndefined (last))
2982 message ("Function %q is marked %s, but has no format "
2983 "string argument before elipsis",
2984 uentry_getName (ue),
2985 specCode_unparse (ue->info->fcn->specialCode)),
2986 uentry_whereLast (ue));
2987 ue->info->fcn->specialCode = SPC_NONE;
2991 ctype rt = ctype_realType (uentry_getType (last));
2993 if (!ctype_match (rt, ctype_string))
2997 /* wchar_t * is okay too */
2998 if (ctype_isAP (rt))
3000 ctype base = ctype_baseArrayPtr (rt);
3002 if (ctype_isArbitraryIntegral (base))
3012 message ("Function %q is marked %s, but the argument "
3013 "before the elipsis has type %s (should be char *)",
3014 uentry_getName (ue),
3015 specCode_unparse (ue->info->fcn->specialCode),
3016 ctype_unparse (uentry_getType (last))),
3017 uentry_whereLast (ue));
3019 ue->info->fcn->specialCode = SPC_NONE;
3026 } end_uentryList_elements ;
3030 message ("Function %q is marked %s, but has no elipsis parameter",
3031 uentry_getName (ue),
3032 specCode_unparse (ue->info->fcn->specialCode)),
3033 uentry_whereLast (ue));
3035 ue->info->fcn->specialCode = SPC_NONE;
3040 uentry_setPrintfLike (uentry ue)
3042 uentry_convertVarFunction (ue);
3043 llassertfatal (uentry_isFunction (ue));
3044 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3045 checkSpecialFunction (ue);
3049 uentry_setScanfLike (uentry ue)
3051 uentry_convertVarFunction (ue);
3052 llassertfatal (uentry_isFunction (ue));
3053 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3054 checkSpecialFunction (ue);
3058 uentry_setMessageLike (uentry ue)
3060 uentry_convertVarFunction (ue);
3061 llassertfatal (uentry_isFunction (ue));
3062 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3063 checkSpecialFunction (ue);
3067 uentry_isSpecialFunction (uentry ue)
3069 return (uentry_isFunction (ue)
3070 && (ue->info->fcn->specialCode != SPC_NONE));
3073 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3075 ctype ct = idDecl_getCtype (t);
3077 fileloc loc = setLocation ();
3078 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3079 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3081 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3082 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3083 uentry_implicitParamAnnots (ue);
3085 /* Parameter type [][] or [x][] is invalid */
3087 while (ctype_isFixedArray (base)) {
3088 base = ctype_baseArrayPtr (base);
3091 if (ctype_isIncompleteArray (base)) {
3092 base = ctype_baseArrayPtr (base);
3094 if (ctype_isArray (base)) {
3095 if (!uentry_hasName (ue)) {
3096 (void) optgenerror (FLG_INCOMPLETETYPE,
3097 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3099 ctype_unparse (ct)),
3100 uentry_whereLast (ue));
3102 (void) optgenerror (FLG_INCOMPLETETYPE,
3103 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3104 uentry_getName (ue),
3105 ctype_unparse (ct)),
3106 uentry_whereLast (ue));
3111 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3115 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3117 ctype ct = idDecl_getCtype (t);
3119 if (ctype_isFunction (ct))
3121 return (uentry_makeIdFunction (t));
3125 fileloc loc = setLocation ();
3126 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3128 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3130 if (!uentry_isExtern (ue))
3132 uentry_setDefined (ue, loc);
3140 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3142 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3150 static /*@only@*/ /*@notnull@*/
3151 uentry uentry_makeConstantAux (cstring n, ctype t,
3152 /*@keep@*/ fileloc f, bool priv, bool macro,
3153 /*@only@*/ multiVal m)
3155 uentry e = uentry_alloc ();
3158 e->uname = cstring_copy (n);
3160 e->storageclass = SCNONE;
3162 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3164 e->sref = sRef_makeConst (t);
3169 e->uses = filelocList_new ();
3170 e->isPrivate = priv;
3171 e->hasNameError = FALSE;
3173 e->info = (uinfo) dmalloc (sizeof (*e->info));
3174 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3175 e->info->uconst->access = typeIdSet_undefined;
3176 e->info->uconst->macro = macro;
3178 e->cQuals = qualList_undefined;
3180 uentry_setSpecDef (e, f);
3182 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3184 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3187 uentry_setConstantValue (e, m);
3192 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3194 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3198 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3200 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3204 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3206 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3210 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3212 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3213 idDecl_getCtype (t),
3216 llassert (fileloc_isUndefined (ue->whereDeclared));
3217 ue->whereDeclared = setLocation ();
3218 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3220 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3221 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3229 void uentry_setDefState (uentry ue, sstate defstate)
3231 if (uentry_isValid (ue))
3233 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3235 if (uentry_isVariable (ue))
3237 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3242 bool uentry_isCheckedUnknown (uentry ue)
3244 return (uentry_isVar (ue)
3245 && (ue->info->var->checked == CH_UNKNOWN));
3248 bool uentry_isCheckMod (uentry ue)
3250 return (uentry_isVar (ue)
3251 && (ue->info->var->checked == CH_CHECKMOD));
3254 bool uentry_isUnchecked (uentry ue)
3256 return (uentry_isVar (ue)
3257 && (ue->info->var->checked == CH_UNCHECKED));
3260 bool uentry_isChecked (uentry ue)
3262 return (uentry_isVar (ue)
3263 && (ue->info->var->checked == CH_CHECKED));
3266 bool uentry_isCheckedModify (uentry ue)
3268 return (uentry_isVar (ue)
3269 && (ue->info->var->checked == CH_CHECKED
3270 || ue->info->var->checked == CH_CHECKMOD
3271 || ue->info->var->checked == CH_CHECKEDSTRICT));
3274 bool uentry_isCheckedStrict (uentry ue)
3276 return (uentry_isVar (ue)
3277 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3280 void uentry_setUnchecked (uentry ue)
3282 llassert (uentry_isVar (ue));
3284 ue->info->var->checked = CH_UNCHECKED;
3287 void uentry_setChecked (uentry ue)
3289 llassert (uentry_isVar (ue));
3291 ue->info->var->checked = CH_CHECKED;
3294 void uentry_setCheckMod (uentry ue)
3296 llassert (uentry_isVar (ue));
3298 ue->info->var->checked = CH_CHECKMOD;
3301 void uentry_setCheckedStrict (uentry ue)
3303 llassert (uentry_isVar (ue));
3305 ue->info->var->checked = CH_CHECKEDSTRICT;
3308 static /*@only@*/ /*@notnull@*/
3309 uentry uentry_makeVariableAux (cstring n, ctype t,
3311 /*@exposed@*/ sRef s,
3312 bool priv, vkind kind)
3314 uentry e = uentry_alloc ();
3317 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3320 e->uname = cstring_copy (n);
3323 e->storageclass = SCNONE;
3325 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3332 e->uses = filelocList_new ();
3333 e->isPrivate = priv;
3334 e->hasNameError = FALSE;
3336 e->info = (uinfo) dmalloc (sizeof (*e->info));
3337 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3338 e->info->var->kind = kind;
3340 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3341 e->info->var->checked = CH_UNKNOWN;
3343 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3344 uentry_setSpecDef (e, f);
3345 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3347 if (ctype_isFunction (rt))
3349 rt = ctype_getReturnType (rt);
3352 if (ctype_isUA (rt))
3354 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3355 sRef_setStateFromType (e->sref, rt);
3358 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3359 e->info->var->defstate = sRef_getDefState (e->sref);
3360 e->info->var->nullstate = sRef_getNullState (e->sref);
3362 /* start modifications */
3363 /* This function sets the uentry for a pointer or array variable declaration,
3364 it allocates memory and sets the fields. We check if the type of the variable
3365 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3367 if (ctype_isArray (t) || ctype_isPointer(t))
3369 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3370 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3371 sRef_setNotNullTerminatedState (s);
3375 e->info->var->bufinfo = NULL;
3377 /* end modification */
3379 e->cQuals = qualList_undefined;
3385 uentry_isYield (uentry ue)
3387 return (uentry_isVariable (ue)
3388 && (ue->info->var->kind == VKYIELDPARAM
3389 || ue->info->var->kind == VKREFYIELDPARAM));
3393 uentry_isRefsField (uentry ue)
3395 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3398 /*@only@*/ /*@notnull@*/
3399 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3401 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3402 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3409 void uentry_makeVarFunction (uentry ue)
3416 llassert (uentry_isValid (ue));
3417 llassert (!sRef_modInFunction ());
3419 ak = sRef_getOrigAliasKind (ue->sref);
3420 ek = sRef_getOrigExKind (ue->sref);
3422 llassert (uentry_isVariable (ue));
3423 oldInfo = ue->info->var;
3425 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3426 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3429 ** expanded macro is marked used
3432 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3435 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3436 ue->info->fcn->exitCode = XK_UNKNOWN;
3437 ue->info->fcn->nullPred = qual_createUnknown ();
3438 ue->info->fcn->specialCode = SPC_NONE;
3439 ue->info->fcn->access = typeIdSet_undefined;
3440 ue->info->fcn->hasGlobs = FALSE;
3441 ue->info->fcn->globs = globSet_undefined;
3442 ue->info->fcn->hasMods = FALSE;
3443 ue->info->fcn->mods = sRefSet_undefined;
3444 ue->info->fcn->specclauses = NULL;
3445 ue->info->fcn->defparams = uentryList_undefined;
3448 ue->info->fcn->preconditions = functionConstraint_undefined;
3452 ue->info->fcn->postconditions = functionConstraint_undefined;
3455 if (ctype_isFunction (ue->utype))
3457 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3461 ue->sref = sRef_makeType (ctype_unknown);
3464 if (sRef_isRefCounted (ue->sref))
3470 if (alkind_isUnknown (ak))
3472 if (exkind_isKnown (ek))
3474 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3475 ak = AK_IMPDEPENDENT;
3479 if (context_getFlag (FLG_RETIMPONLY))
3481 if (ctype_isFunction (ue->utype)
3482 && ctype_isVisiblySharable
3483 (ctype_realType (ctype_getReturnType (ue->utype))))
3485 if (uentryList_hasReturned (uentry_getParams (ue)))
3491 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3506 loc = ue->whereDeclared;
3508 sRef_setAliasKind (ue->sref, ak, loc);
3509 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3510 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3511 sRef_setExKind (ue->sref, ek, loc);
3513 if (oldInfo->kind == VKEXPMACRO)
3519 fileloc_free (ue->whereDefined);
3520 ue->whereDefined = fileloc_undefined;
3523 uvinfo_free (oldInfo);
3526 void uentry_makeConstantFunction (uentry ue)
3533 llassert (uentry_isValid (ue));
3534 llassert (!sRef_modInFunction ());
3536 ak = sRef_getOrigAliasKind (ue->sref);
3537 ek = sRef_getOrigExKind (ue->sref);
3539 llassert (uentry_isConstant (ue));
3540 oldInfo = ue->info->uconst;
3542 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3545 ** expanded macro is marked used (until I write a pre-processor)
3549 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3550 ue->info->fcn->exitCode = XK_UNKNOWN;
3551 ue->info->fcn->nullPred = qual_createUnknown ();
3552 ue->info->fcn->specialCode = SPC_NONE;
3553 ue->info->fcn->access = typeIdSet_undefined;
3554 ue->info->fcn->hasGlobs = FALSE;
3555 ue->info->fcn->globs = globSet_undefined;
3556 ue->info->fcn->hasMods = FALSE;
3557 ue->info->fcn->mods = sRefSet_undefined;
3558 ue->info->fcn->specclauses = NULL;
3559 ue->info->fcn->defparams = uentryList_undefined;
3562 ue->info->fcn->preconditions = functionConstraint_undefined;
3566 ue->info->fcn->postconditions = functionConstraint_undefined;
3570 if (ctype_isFunction (ue->utype))
3572 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3576 ue->sref = sRef_makeType (ctype_unknown);
3579 if (sRef_isRefCounted (ue->sref))
3585 if (alkind_isUnknown (ak))
3587 if (exkind_isKnown (ek))
3589 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3590 ak = AK_IMPDEPENDENT;
3594 if (context_getFlag (FLG_RETIMPONLY))
3596 if (ctype_isFunction (ue->utype)
3597 && ctype_isVisiblySharable
3598 (ctype_realType (ctype_getReturnType (ue->utype))))
3600 if (uentryList_hasReturned (uentry_getParams (ue)))
3606 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3621 loc = ue->whereDeclared;
3623 sRef_setAliasKind (ue->sref, ak, loc);
3624 sRef_setExKind (ue->sref, ek, loc);
3626 fileloc_free (ue->whereDefined);
3627 ue->whereDefined = fileloc_undefined;
3628 ucinfo_free (oldInfo);
3632 uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
3634 llassert (uentry_isValid (ue));
3636 globSet_markImmutable (globs);
3638 if (uentry_isIter (ue))
3640 ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
3644 uentry_convertVarFunction (ue);
3645 llassert (uentry_isFunction (ue));
3647 ue->info->fcn->hasGlobs = TRUE;
3648 ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
3651 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3653 ue->info->fcn->hasMods = TRUE;
3657 void uentry_addAccessType (uentry ue, typeId tid)
3659 if (uentry_isFunction (ue))
3661 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3663 else if (uentry_isEitherConstant (ue))
3665 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3667 else if (uentry_isIter (ue))
3669 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3671 else if (uentry_isEndIter (ue))
3673 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3677 llbug (message ("no access for: %q", uentry_unparse (ue)));
3681 /*@only@*/ /*@notnull@*/ uentry
3682 uentry_makeFunction (cstring n, ctype t,
3684 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3685 /*@only@*/ warnClause warn,
3688 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3689 return (uentry_makeFunctionAux (n, t,
3690 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3691 : typeIdSet_single (access)),
3698 /*@notnull@*/ uentry
3699 uentry_makePrivFunction2 (cstring n, ctype t,
3701 globSet globs, sRefSet mods,
3704 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3709 /*@notnull@*/ uentry
3710 uentry_makeSpecFunction (cstring n, ctype t,
3712 /*@only@*/ globSet globs,
3713 /*@only@*/ sRefSet mods,
3716 uentry ue = uentry_makeFunctionAux (n, t, access,
3717 globs, mods, warnClause_undefined,
3720 uentry_setHasGlobs (ue);
3721 uentry_setHasMods (ue);
3723 reflectImplicitFunctionQualifiers (ue, TRUE);
3728 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3730 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3731 sRef_undefined, FALSE, VKEXPMACRO);
3733 uentry_setDefined (ue, f);
3737 /*@notnull@*/ /*@notnull@*/ uentry
3738 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3740 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3741 typeIdSet_singleOpt (access),
3742 globSet_undefined, sRefSet_undefined,
3743 warnClause_undefined,
3747 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3751 bool uentry_isForward (uentry e)
3753 if (uentry_isValid (e))
3755 ctype ct = uentry_getType (e);
3757 return (ctype_isUnknown (ct)
3758 || (ctype_isFunction (ct)
3759 && ctype_isUnknown (ctype_getReturnType (ct))));
3766 /*@notnull@*/ uentry
3767 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3769 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3770 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3774 /*@notnull@*/ uentry
3775 uentry_makeUnspecFunction (cstring n, ctype t,
3779 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3780 sRefSet_undefined, warnClause_undefined,
3783 reflectImplicitFunctionQualifiers (ue, TRUE);
3792 /* is exported for use by usymtab_interface */
3794 /*@notnull@*/ uentry
3795 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3796 fileloc f, bool priv)
3798 uentry e = uentry_alloc ();
3800 DPRINTF (("Make datatype: %s / %s",
3801 n, ctype_unparse (t)));
3803 /* e->shallowCopy = FALSE; */
3804 e->ukind = KDATATYPE;
3805 e->uname = cstring_copy (n);
3807 e->storageclass = SCNONE;
3808 e->sref = sRef_makeUnknown ();
3812 sRef_setStateFromType (e->sref, t);
3815 uentry_setSpecDef (e, f);
3817 e->warn = warnClause_undefined; /*@i634@*/
3818 e->uses = filelocList_new ();
3819 e->isPrivate = priv;
3820 e->hasNameError = FALSE;
3825 e->info = (uinfo) dmalloc (sizeof (*e->info));
3826 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3827 e->info->datatype->abs = abstract;
3828 e->info->datatype->mut = mut;
3829 e->info->datatype->type = ctype_undefined;
3831 e->cQuals = qualList_undefined;
3833 if (uentry_isDeclared (e))
3835 uentry_setDefined (e, f);
3838 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3840 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3846 /*@notnull@*/ uentry
3847 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3849 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3852 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3854 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3855 ctype_bool, NO, abstract,
3856 fileloc_getBuiltin (),
3859 ret->info->datatype->type = ctype_bool;
3867 static /*@only@*/ /*@notnull@*/ uentry
3868 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3869 /*@only@*/ fileloc f)
3871 uentry e = uentry_alloc ();
3874 e->uname = cstring_copy (n);
3876 e->sref = sRef_makeUnknown ();
3877 e->storageclass = SCNONE;
3881 uentry_setSpecDef (e, f);
3883 e->warn = warnClause_undefined; /*@i452@*/
3884 e->uses = filelocList_new ();
3885 e->isPrivate = FALSE;
3886 e->hasNameError = FALSE;
3888 e->info = (uinfo) dmalloc (sizeof (*e->info));
3889 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3890 e->info->iter->access = access;
3891 e->info->iter->mods = sRefSet_undefined;
3892 e->info->iter->globs = globSet_undefined;
3894 e->cQuals = qualList_undefined;
3896 uentry_checkIterArgs (e);
3900 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3902 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3905 static /*@notnull@*/ uentry
3906 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3908 uentry e = uentry_alloc ();
3910 /* e->shallowCopy = FALSE; */
3911 e->ukind = KENDITER;
3912 e->storageclass = SCNONE;
3913 e->uname = message ("end_%s", n);
3914 e->utype = ctype_unknown;
3915 e->sref = sRef_makeUnknown ();
3917 uentry_setSpecDef (e, f);
3922 e->uses = filelocList_new ();
3923 e->isPrivate = FALSE;
3924 e->hasNameError = FALSE;
3926 e->info = (uinfo) dmalloc (sizeof (*e->info));
3927 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3929 e->info->enditer->access = access;
3931 e->warn = warnClause_undefined; /*@i452@*/
3933 e->cQuals = qualList_undefined;
3938 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3940 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3947 static /*@only@*/ /*@notnull@*/ uentry
3948 uentry_makeTagAux (cstring n, ctype t,
3949 /*@only@*/ fileloc fl,
3950 bool priv, ekind kind)
3952 uentry e = uentry_alloc ();
3954 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3956 llbuglit ("uentry_makeTagAux: not a tag type");
3960 /* e->shallowCopy = FALSE; */
3961 e->uname = cstring_copy (n);
3964 e->sref = sRef_makeUnknown ();
3965 e->storageclass = SCNONE;
3967 uentry_setSpecDef (e, fl);
3972 e->uses = filelocList_new ();
3973 e->isPrivate = priv;
3974 e->hasNameError = FALSE;
3976 e->info = (uinfo) dmalloc (sizeof (*e->info));
3977 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3978 e->info->datatype->abs = NO;
3979 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3980 e->info->datatype->type = t;
3981 e->warn = warnClause_undefined; /*@i452@*/
3983 e->cQuals = qualList_undefined;
3985 if (uentry_isDeclared (e))
3987 uentry_setDefined (e, fl);
3993 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3995 cstring sname = makeStruct (n);
3996 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3998 cstring_free (sname);
4003 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
4005 cstring sname = makeStruct (n);
4006 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
4008 cstring_free (sname);
4013 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
4015 cstring uname = makeUnion (n);
4016 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
4018 cstring_free (uname);
4024 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
4026 cstring ename = makeEnum (n);
4027 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
4029 cstring_free (ename);
4035 uentry_makeUnionTagLoc (cstring n, ctype t)
4037 cstring uname = makeUnion (n);
4038 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4040 cstring_free (uname);
4045 uentry_makeEnumTagLoc (cstring n, ctype t)
4047 cstring ename = makeEnum (n);
4048 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4050 cstring_free (ename);
4055 uentry_isStructTag (uentry ue)
4057 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4061 uentry_isUnionTag (uentry ue)
4063 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4067 uentry_isEnumTag (uentry ue)
4069 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4073 uentry_isAnyTag (uentry ue)
4075 return (uentry_isStructTag (ue)
4076 || uentry_isUnionTag (ue)
4077 || uentry_isEnumTag (ue));
4080 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4082 extern void uentry_destroyMod (void)
4083 /*@globals killed emarker@*/ /*@modifies emarker@*/
4085 static bool wasDestroyed = FALSE;
4087 llassert (!wasDestroyed);
4089 if (emarker != NULL)
4091 uentry_reallyFree (emarker);
4094 wasDestroyed = TRUE;
4098 uentry_makeElipsisMarker (void)
4100 if (emarker == NULL)
4102 emarker = uentry_alloc ();
4104 emarker->ukind = KELIPSMARKER;
4105 emarker->uname = cstring_makeLiteral ("...");
4106 emarker->utype = ctype_elipsMarker;
4107 emarker->sref = sRef_undefined;
4108 emarker->storageclass = SCNONE;
4109 emarker->used = FALSE;
4110 emarker->lset = FALSE;
4111 emarker->info = NULL;
4113 uentry_setSpecDef (emarker, fileloc_undefined);
4114 emarker->uses = filelocList_new ();
4115 emarker->isPrivate = FALSE;
4116 emarker->hasNameError = FALSE;
4119 /*@ignore@*/ return (emarker); /*@end@*/
4127 uentry_equiv (uentry p1, uentry p2)
4129 if (uentry_compare (p1, p2) != 0)
4140 uentry_xcomparealpha (uentry *p1, uentry *p2)
4144 if ((res = uentry_compare (*p1, *p2)) == 0) {
4145 if ((*p1 != NULL) && (*p2 != NULL)) {
4146 res = cstring_compare ((*p1)->uname,
4155 uentry_xcompareuses (uentry *p1, uentry *p2)
4160 if (uentry_isValid (u1))
4162 if (uentry_isValid (u2))
4164 return (-1 * int_compare (filelocList_size (u1->uses),
4165 filelocList_size (u2->uses)));
4174 if (uentry_isValid (u2))
4186 uentry_compareStrict (uentry v1, uentry v2)
4188 COMPARERETURN (uentry_compare (v1, v2));
4190 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4192 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4193 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4194 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4201 uentry_compare (uentry u1, uentry u2)
4203 if (u1 == u2) return 0;
4205 if (uentry_isInvalid (u1)) return -1;
4206 if (uentry_isInvalid (u2)) return 1;
4208 INTCOMPARERETURN (u1->ukind, u2->ukind);
4209 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4210 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4211 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4217 /* bug detected by splint:
4218 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4223 return (multiVal_compare (uentry_getConstantValue (u1),
4224 uentry_getConstantValue (u2)));
4228 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4230 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4231 uentry_accessType (u2)));
4232 return (uentryList_compareParams (uentry_getParams (u1),
4233 uentry_getParams (u2)));
4235 return (typeIdSet_compare (uentry_accessType (u1),
4236 uentry_accessType (u2)));
4239 ** Functions are never equivalent
4242 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4252 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4253 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4254 sRef_getOrigAliasKind (u2->sref)));
4255 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4256 sRef_getOrigExKind (u2->sref)));
4257 COMPARERETURN (generic_compare (u1->info->var->checked,
4258 u2->info->var->checked));
4259 COMPARERETURN (generic_compare (u1->info->var->defstate,
4260 u2->info->var->defstate));
4261 return (generic_compare (u1->info->var->nullstate,
4262 u2->info->var->nullstate));
4264 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4265 u2->info->datatype->type));
4266 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4267 u2->info->datatype->mut));
4268 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4277 ** all entries are: <type>[@<info>]*#<name>
4279 ** info depends on kind:
4283 advanceField (char **s)
4285 reader_checkChar (s, '@');
4289 advanceName (char **s)
4291 reader_checkChar (s, '#');
4295 vkind_fromInt (int i)
4297 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4299 llbuglit ("vkind_fromInt: out of range");
4306 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4307 typeIdSet access, nstate nullstate,
4308 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4310 uentry e = uentry_alloc ();
4315 e->sref = sRef_makeConst (ct);
4317 sRef_setNullState (e->sref, nullstate, loc);
4318 e->storageclass = SCNONE;
4320 if (fileloc_isSpec (loc))
4322 e->whereSpecified = loc;
4323 e->whereDeclared = fileloc_undefined;
4327 e->whereSpecified = fileloc_undefined;
4328 e->whereDeclared = loc;
4331 e->whereDefined = fileloc_undefined;
4332 e->uses = filelocList_new ();
4333 e->isPrivate = FALSE;
4334 e->hasNameError = FALSE;
4339 e->warn = warnClause_undefined; /*@i452@*/
4341 e->info = (uinfo) dmalloc (sizeof (*e->info));
4342 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4343 e->info->uconst->access = access;
4344 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4346 e->cQuals = qualList_undefined;
4348 uentry_setConstantValue (e, m);
4349 sRef_storeState (e->sref);
4354 static /*@only@*/ uentry
4355 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4356 sstate defstate, nstate isnull, alkind aliased,
4357 exkind exp, chkind checked,
4358 /*@only@*/ fileloc loc)
4360 uentry e = uentry_alloc ();
4365 e->storageclass = SCNONE;
4367 e->sref = sRef_makeType (ct);
4368 sRef_setNullState (e->sref, isnull, loc);
4370 e->whereDefined = fileloc_undefined;
4372 if (fileloc_isSpec (loc))
4374 e->whereSpecified = loc;
4375 e->whereDeclared = fileloc_undefined;
4379 e->whereSpecified = fileloc_undefined;
4380 e->whereDeclared = loc;
4383 e->isPrivate = FALSE;
4384 e->hasNameError = FALSE;
4389 e->uses = filelocList_new ();
4390 e->warn = warnClause_undefined; /*@i452@*/
4392 e->info = (uinfo) dmalloc (sizeof (*e->info));
4393 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4394 e->info->var->kind = kind;
4395 e->info->var->checked = checked;
4396 e->info->var->defstate = defstate;
4398 sRef_setDefState (e->sref, defstate, loc);
4400 e->info->var->nullstate = sRef_getNullState (e->sref);
4402 sRef_setExKind (e->sref, exp, loc);
4403 sRef_setAliasKind (e->sref, aliased, loc);
4405 sRef_storeState (e->sref);
4407 /*DRL ADDED 9-1-2000 */
4408 e->info->var->bufinfo = NULL;
4410 e->cQuals = qualList_undefined;
4415 static /*@only@*/ uentry
4416 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4417 ynm mut, ctype rtype, alkind ak, exkind exp,
4418 sstate defstate, nstate isnull,
4419 /*@only@*/ fileloc loc)
4421 uentry e = uentry_alloc ();
4423 e->ukind = KDATATYPE;
4424 /* e->shallowCopy = FALSE; */
4427 e->storageclass = SCNONE;
4428 e->sref = sRef_makeUnknown ();
4429 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4432 ** This is only setting null state. (I think?)
4435 if (ctype_isUA (ct))
4437 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4439 if (uentry_isValid (te))
4441 sRef_setStateFromUentry (e->sref, te);
4445 /* problem for recursive type definitions */
4449 sRef_setAliasKind (e->sref, ak, loc);
4450 sRef_setExKind (e->sref, exp, loc);
4452 sRef_setDefState (e->sref, defstate, loc);
4454 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4456 isnull = NS_ABSNULL;
4459 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4460 sRef_mergeNullState (e->sref, isnull);
4462 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4464 if (fileloc_isSpec (loc))
4466 e->whereSpecified = loc;
4467 e->whereDeclared = fileloc_undefined;
4471 e->whereSpecified = fileloc_undefined;
4472 e->whereDeclared = loc;
4475 e->isPrivate = FALSE;
4476 e->hasNameError = FALSE;
4478 e->warn = warnClause_undefined; /*@i452@*/
4482 e->uses = filelocList_new ();
4484 e->info = (uinfo) dmalloc (sizeof (*e->info));
4485 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4486 e->info->datatype->abs = abstract;
4487 e->info->datatype->mut = mut;
4488 e->info->datatype->type = rtype;
4490 e->cQuals = qualList_undefined;
4492 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4493 sRef_storeState (e->sref);
4494 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4500 static void uentry_setHasGlobs (uentry ue)
4502 llassert (uentry_isFunction (ue));
4504 ue->info->fcn->hasGlobs = TRUE;
4507 static void uentry_setHasMods (uentry ue)
4509 llassert (uentry_isFunction (ue));
4511 ue->info->fcn->hasMods = TRUE;
4515 bool uentry_hasGlobs (uentry ue)
4517 if (uentry_isFunction (ue))
4519 return (ue->info->fcn->hasGlobs);
4525 bool uentry_hasStateClauseList (uentry ue)
4527 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4530 bool uentry_hasConditions (uentry ue)
4532 return (uentry_isFunction (ue)
4533 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4534 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4537 stateClauseList uentry_getStateClauseList (uentry ue)
4539 if (!uentry_isFunction (ue))
4541 llassert (uentry_isFunction (ue));
4542 return stateClauseList_undefined;
4545 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4546 return ue->info->fcn->specclauses;
4549 bool uentry_hasMods (uentry ue)
4551 if (uentry_isFunction (ue))
4553 return (ue->info->fcn->hasMods);
4560 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4562 bool hasGlobs, /*@only@*/ globSet globs,
4563 bool hasMods, /*@only@*/ sRefSet mods,
4564 alkind ak, exkind exp,
4565 sstate defstate, nstate isnull,
4569 /*@only@*/ stateClauseList specclauses,
4570 /*@only@*/ warnClause warnclause,
4571 /*@only@*/ fileloc loc)
4573 uentry e = uentry_alloc ();
4576 /* e->shallowCopy = FALSE; */
4580 e->storageclass = SCNONE;
4582 if (ctype_isFunction (ct))
4584 ret = ctype_getReturnType (ct);
4588 if (ctype_isKnown (ct))
4590 llbug (message ("not function: %s", ctype_unparse (ct)));
4593 ret = ctype_unknown;
4596 e->sref = sRef_makeType (ret);
4598 if (ctype_isUA (ret))
4600 sRef_setStateFromType (e->sref, ret);
4603 sRef_setDefined (e->sref, loc);
4604 sRef_setNullState (e->sref, isnull, loc);
4606 sRef_setAliasKind (e->sref, ak, loc);
4607 sRef_setExKind (e->sref, exp, loc);
4608 sRef_setDefState (e->sref, defstate, loc);
4610 e->whereSpecified = loc;
4611 e->whereDefined = fileloc_undefined;
4613 e->isPrivate = FALSE;
4614 e->hasNameError = FALSE;
4618 e->uses = filelocList_new ();
4619 e->warn = warnclause;
4621 e->info = (uinfo) dmalloc (sizeof (*e->info));
4622 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4624 e->info->fcn->exitCode = exitCode;
4625 e->info->fcn->specialCode = sCode;
4626 e->info->fcn->nullPred = nullPred;
4627 e->info->fcn->access = access;
4629 e->info->fcn->specclauses = specclauses;
4630 e->info->fcn->hasGlobs = hasGlobs;
4631 e->info->fcn->globs = globs;
4633 e->info->fcn->hasMods = hasMods;
4634 e->info->fcn->mods = mods;
4636 e->info->fcn->defparams = uentryList_undefined;
4637 e->whereDeclared = fileloc_undefined;
4639 sRef_storeState (e->sref);
4642 e->info->fcn->preconditions = NULL;
4646 e->info->fcn->postconditions = NULL;
4649 e->cQuals = qualList_undefined;
4654 static /*@only@*/ uentry
4655 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4656 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4658 uentry e = uentry_alloc ();
4660 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4662 llbuglit ("uentry_makeTagBase: not a tag type");
4665 /* e->shallowCopy = FALSE; */
4669 e->sref = sRef_makeUnknown ();
4670 e->storageclass = SCNONE;
4672 if (fileloc_isSpec (loc))
4674 e->whereSpecified = loc;
4675 e->whereDeclared = fileloc_undefined;
4679 e->whereDeclared = loc;
4680 e->whereSpecified = fileloc_undefined;
4683 e->whereDefined = fileloc_undefined;
4685 e->isPrivate = FALSE;
4686 e->hasNameError = FALSE;
4690 e->uses = filelocList_new ();
4691 e->warn = warnClause_undefined; /*@i452@*/
4693 e->info = (uinfo) dmalloc (sizeof (*e->info));
4694 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4695 e->info->datatype->abs = NO;
4696 e->info->datatype->mut = MAYBE;
4697 e->info->datatype->type = rtype;
4699 e->cQuals = qualList_undefined;
4701 sRef_storeState (e->sref);
4707 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4708 ctype ct, /*@only@*/ fileloc loc)
4710 uentry e = uentry_alloc ();
4712 /* e->shallowCopy = FALSE; */
4716 e->sref = sRef_makeUnknown ();
4717 e->storageclass = SCNONE;
4719 if (fileloc_isSpec (loc))
4721 e->whereSpecified = loc;
4722 e->whereDeclared = fileloc_undefined;
4726 e->whereDeclared = loc;
4727 e->whereSpecified = fileloc_undefined;
4730 e->whereDefined = fileloc_undefined;
4732 e->isPrivate = FALSE;
4733 e->hasNameError = FALSE;
4737 e->uses = filelocList_new ();
4738 e->warn = warnClause_undefined; /*@i452@*/
4740 e->info = (uinfo) dmalloc (sizeof (*e->info));
4741 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4742 e->info->iter->access = access;
4743 e->info->iter->mods = sRefSet_undefined;
4744 e->info->iter->globs = globSet_undefined;
4746 e->cQuals = qualList_undefined;
4748 sRef_storeState (e->sref);
4753 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4754 /*@only@*/ fileloc loc)
4756 uentry e = uentry_alloc ();
4758 /* e->shallowCopy = FALSE; */
4759 e->ukind = KENDITER;
4760 e->storageclass = SCNONE;
4762 e->utype = ctype_unknown;
4763 e->sref = sRef_makeUnknown ();
4765 if (fileloc_isSpec (loc))
4767 e->whereSpecified = loc;
4768 e->whereDeclared = fileloc_undefined;
4772 e->whereDeclared = loc;
4773 e->whereSpecified = fileloc_undefined;
4776 e->whereDefined = fileloc_undefined;
4778 e->isPrivate = FALSE;
4779 e->hasNameError = FALSE;
4783 e->uses = filelocList_new ();
4784 e->warn = warnClause_undefined; /*@i452@*/
4786 e->info = (uinfo) dmalloc (sizeof (*e->info));
4787 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4788 e->info->enditer->access = access;
4790 e->cQuals = qualList_undefined;
4792 sRef_storeState (e->sref);
4797 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4805 uentry_undump (ekind kind, fileloc loc, char **s)
4809 DPRINTF (("Uentry undump: %s", *s));
4813 reader_checkChar (s, '!');
4814 reader_checkChar (s, '.');
4815 ue = uentry_makeElipsisMarker ();
4819 ctype ct = ctype_undump (s);
4833 reader_checkChar (s, '|');
4835 if (reader_optCheckChar (s, '@'))
4837 tkind = vkind_fromInt (reader_getInt (s));
4838 reader_checkChar (s, '|');
4845 if (reader_optCheckChar (s, '$'))
4847 defstate = SS_UNKNOWN;
4848 isnull = NS_UNKNOWN;
4849 aliased = AK_IMPTEMP;
4851 checked = CH_UNKNOWN;
4853 else if (reader_optCheckChar (s, '&'))
4855 defstate = SS_DEFINED;
4856 isnull = NS_UNKNOWN;
4857 aliased = AK_IMPTEMP;
4859 checked = CH_UNKNOWN;
4861 else if (reader_optCheckChar (s, '^'))
4863 defstate = SS_UNKNOWN;
4864 isnull = NS_UNKNOWN;
4865 aliased = AK_IMPTEMP;
4867 checked = CH_UNKNOWN;
4871 defstate = sstate_fromInt (reader_getInt (s));
4872 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4873 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4875 if (reader_optCheckChar (s, '&'))
4878 checked = CH_UNKNOWN;
4882 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4883 advanceField (s); checked = (chkind) (reader_getInt (s));
4888 name = reader_getStringWord (s);
4890 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4892 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4893 isnull, aliased, exp,
4894 checked, fileloc_copy (loc));
4907 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4908 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4909 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4910 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4911 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4912 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4913 advanceField (s); rtype = ctype_undump (s);
4915 name = reader_getStringWord (s);
4916 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4917 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4918 aliased, exp, defstate, isnull,
4919 fileloc_copy (loc));
4936 stateClauseList specclauses = stateClauseList_undefined;
4937 warnClause warnclause = warnClause_undefined;
4939 if (reader_optCheckChar (s, '$'))
4941 defstate = SS_DEFINED;
4942 isnull = NS_UNKNOWN;
4943 exitCode = XK_UNKNOWN;
4945 nullPred = qual_createUnknown ();
4949 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4950 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4951 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4952 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4953 advanceField (s); nullPred = qual_undump (s);
4956 if (reader_optCheckChar (s, '$'))
4959 globs = globSet_undefined;
4961 mods = sRefSet_undefined;
4963 else if (reader_optCheckChar (s, '^'))
4966 globs = globSet_undefined;
4968 mods = sRefSet_undefined;
4972 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4973 advanceField (s); globs = globSet_undump (s);
4974 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4975 advanceField (s); mods = sRefSet_undump (s);
4978 if (reader_optCheckChar (s, '$'))
4985 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4986 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4989 advanceField (s); access = typeIdSet_undump (s);
4992 ** Optional clauses: Start with @<code>:
4995 while (reader_optCheckChar (s, '@'))
4997 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4999 reader_checkChar (s, ':');
5000 warnclause = warnClause_undump (s);
5002 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
5004 reader_checkChar (s, ':');
5005 specclauses = stateClauseList_undump (s);
5013 advanceName (s); name = reader_getStringWord (s);
5015 ue = uentry_makeFunctionBase (name, ct, access,
5018 ak, exp, defstate, isnull,
5019 exitCode, specc, nullPred,
5022 fileloc_copy (loc));
5023 DPRINTF (("Undump: %s", uentry_unparse (ue)));
5030 advanceField (s); access = typeIdSet_undump (s);
5031 advanceName (s); name = reader_getStringWord (s);
5033 ue = uentry_makeIterBase (name, access, ct,
5034 fileloc_copy (loc));
5041 advanceField (s); access = typeIdSet_undump (s);
5042 advanceName (s); name = reader_getStringWord (s);
5044 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5054 if (reader_optCheckChar (s, '$'))
5056 val = multiVal_undefined;
5057 access = typeIdSet_undefined;
5058 nullstate = NS_UNKNOWN;
5062 advanceField (s); val = multiVal_undump (s);
5063 advanceField (s); access = typeIdSet_undump (s);
5064 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5067 advanceName (s); name = reader_getStringWord (s);
5069 ue = uentry_makeConstantBase (name, ct, access,
5070 nullstate, fileloc_copy (loc), val);
5079 advanceField (s); rtype = ctype_undump (s);
5080 advanceName (s); name = reader_getStringWord (s);
5081 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5085 llcontbuglit ("uentry_undump: invalid");
5086 ue = uentry_undefined;
5089 llcontbuglit ("uentry_undump: elips marker");
5090 ue = uentry_undefined;
5099 uentry_dump (uentry v)
5101 return (uentry_dumpAux (v, FALSE));
5105 uentry_dumpParam (uentry v)
5107 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5108 ("dump: %s", uentry_unparseFull (v)));
5110 return (uentry_dumpAux (v, TRUE));
5114 uentry_dumpAux (uentry v, bool isParam)
5116 llassert (uentry_isValid (v));
5117 llassert (!uentry_isGlobalMarker (v));
5119 DPRINTF (("Dump uentry: [%p]", v));
5120 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5125 llcontbuglit ("uentry_dump: invalid entry");
5126 return cstring_undefined;
5128 return (message ("!."));
5132 vkind vk = v->info->var->kind;
5133 sstate dss = sRef_getDefState (v->sref);
5134 nstate nst = sRef_getNullState (v->sref);
5135 alkind alk = sRef_getAliasKind (v->sref);
5136 exkind exk = sRef_getExKind (v->sref);
5137 chkind chk = v->info->var->checked;
5139 DPRINTF (("Dumping var"));
5141 if (dss == SS_UNKNOWN
5142 && nst == NS_UNKNOWN
5143 && alk == AK_IMPTEMP
5144 && exk == XO_UNKNOWN
5145 && chk == CH_UNKNOWN)
5147 sdump = cstring_makeLiteral ("$");
5149 else if (dss == SS_DEFINED
5150 && nst == NS_UNKNOWN
5151 && alk == AK_IMPTEMP
5152 && exk == XO_UNKNOWN
5153 && chk == CH_UNKNOWN)
5155 sdump = cstring_makeLiteral ("&");
5157 else if (dss == SS_UNKNOWN
5158 && nst == NS_UNKNOWN
5159 && alk == AK_UNKNOWN
5160 && exk == XO_UNKNOWN
5161 && chk == CH_UNKNOWN)
5163 sdump = cstring_makeLiteral ("^");
5165 else if (exk == XO_UNKNOWN
5166 && chk == CH_UNKNOWN)
5168 sdump = message ("%d@%d@%d&",
5175 sdump = message ("%d@%d@%d@%d@%d",
5186 return (message ("%q|@%d|%q#%s",
5187 ctype_dump (v->utype),
5190 isParam ? cstring_undefined : v->uname));
5194 return (message ("%q|%q#%s",
5195 ctype_dump (v->utype),
5197 isParam ? cstring_undefined : v->uname));
5203 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5205 exkind_unparse (sRef_getExKind (v->sref)),
5206 ctype_unparse (v->utype), (int) v->utype));
5209 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5210 ctype_dump (v->utype),
5211 ynm_unparseCode (v->info->datatype->abs),
5212 ynm_unparseCode (v->info->datatype->mut),
5213 (int) sRef_getDefState (v->sref),
5214 (int) sRef_getNullState (v->sref),
5215 (int) sRef_getAliasKind (v->sref),
5216 (int) sRef_getExKind (v->sref),
5217 ctype_dump (v->info->datatype->type),
5221 cstring sdump, gdump, adump, xdump;
5222 alkind alk = sRef_getAliasKind (v->sref);
5223 exkind exk = sRef_getExKind (v->sref);
5225 if (sRef_getDefState (v->sref) == SS_DEFINED
5226 && !nstate_isKnown (sRef_getNullState (v->sref))
5227 && !exitkind_isKnown (v->info->fcn->exitCode)
5228 && v->info->fcn->specialCode == SPC_NONE
5229 && qual_isUnknown (v->info->fcn->nullPred))
5231 sdump = cstring_makeLiteral ("$");
5235 sdump = message ("@%d@%d@%d@%d@%x",
5236 (int) sRef_getDefState (v->sref),
5237 (int) sRef_getNullState (v->sref),
5238 (int) v->info->fcn->exitCode,
5239 (int) v->info->fcn->specialCode,
5240 qual_dump (v->info->fcn->nullPred));
5243 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5245 gdump = cstring_makeLiteral ("$");
5247 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5248 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5250 gdump = cstring_makeLiteral ("^");
5254 gdump = message ("@%s@%q@%s@%q",
5255 bool_dump (uentry_hasGlobs (v)),
5256 globSet_dump (uentry_getGlobs (v)),
5257 bool_dump (uentry_hasMods (v)),
5258 sRefSet_dump (uentry_getMods (v)));
5261 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5263 adump = cstring_makeLiteral ("$");
5267 adump = message ("@%d@%d", (int) alk, (int) exk);
5270 xdump = cstring_undefined;
5272 if (uentry_hasWarning (v))
5274 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5277 if (uentry_hasStateClauseList (v))
5279 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5282 return (message ("%q%q%q%q@%q%q#%s",
5283 ctype_dump (v->utype),
5287 typeIdSet_dump (uentry_accessType (v)),
5292 return (message ("%q@%q#%s",
5293 ctype_dump (v->utype),
5294 typeIdSet_dump (v->info->iter->access),
5297 return (message ("%q@%q#%s",
5298 ctype_dump (v->utype),
5299 typeIdSet_dump (uentry_accessType (v)),
5306 if (multiVal_isUnknown (uentry_getConstantValue (v))
5307 && typeIdSet_isEmpty (uentry_accessType (v))
5308 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5310 sdump = cstring_makeLiteral ("$");
5314 sdump = message ("@%q@%q@%d",
5315 multiVal_dump (uentry_getConstantValue (v)),
5316 typeIdSet_dump (uentry_accessType (v)),
5317 (int) sRef_getNullState (v->sref));
5320 return (message ("%q%q#%s",
5321 ctype_dump (v->utype),
5328 return (message ("%q@%q#%s",
5329 ctype_dump (v->utype),
5330 ctype_dump (v->info->datatype->type), v->uname));
5337 uentry_unparseAbbrev (uentry v)
5339 if (!uentry_isVariable (v))
5341 llcontbuglit ("uentry_unparseAbbrev: not variable");
5342 return uentry_unparse (v);
5345 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5349 uentry_unparseFunctionHeader (uentry v) /*@*/
5351 cstring st, cQuals, tmp, ret, storageSp;
5353 if (uentry_isUndefined (v))
5354 return cstring_undefined;
5356 llassert (uentry_isFunction(v));
5358 st = uentry_getName(v);
5359 tmp = ctype_unparseFunction (v->utype, st);
5360 if ( qualList_isDefined(v->cQuals) )
5362 cQuals = qualList_unparse(v->cQuals);
5366 cQuals = cstring_undefined;
5369 if (uentry_isStatic(v) )
5371 storageSp = cstring_makeLiteral("static");
5373 else if (uentry_isExtern(v) )
5375 storageSp = cstring_makeLiteral("extern");
5377 else if (uentry_isExtern(v) )
5379 storageSp = cstring_makeLiteral("");
5384 // // drl make sure this is a legal/legit case
5386 storageSp = cstring_makeLiteral("");
5389 ret = message("%q %q %q",storageSp, cQuals, tmp);
5391 // ctbase_unparseFunction (ctype_getCtbaseSafe (v->utype), st);
5396 uentry_unparse (uentry v)
5400 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5401 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5403 st = uentry_getName (v);
5405 if (cstring_isDefined (st))
5407 return (ctype_unparseDeclaration (v->utype, st));
5412 return (cstring_copy (ctype_unparse (v->utype)));
5417 uentry_unparseFull (uentry v)
5419 if (uentry_isUndefined (v))
5421 return (cstring_makeLiteral ("<undefined>"));
5427 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5428 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5429 ctype_unparse (v->utype),
5430 fileloc_unparse (uentry_whereSpecified (v)),
5431 fileloc_unparse (uentry_whereDeclared (v)),
5432 fileloc_unparse (uentry_whereDefined (v)));
5434 DPRINTF (("uentry: %s", res));
5436 if (uentry_isDatatype (v))
5438 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5441 (ctype_isDefined (v->info->datatype->type)
5442 ? v->info->datatype->type : ctype_unknown),
5443 ynm_unparse (v->info->datatype->mut),
5444 ynm_unparse (v->info->datatype->abs),
5445 sRef_unparseState (v->sref));
5447 else if (uentry_isFunction (v))
5449 res = message ("%q / sref: %q / mods: %q / "
5450 "globs: %q / clauses: %q / pre: %q / post: %q",
5452 sRef_unparseFull (v->sref),
5453 sRefSet_unparse (v->info->fcn->mods),
5454 globSet_unparse (v->info->fcn->globs),
5455 stateClauseList_unparse (v->info->fcn->specclauses),
5456 functionConstraint_unparse (v->info->fcn->preconditions),
5457 functionConstraint_unparse (v->info->fcn->postconditions));
5459 else if (uentry_isIter (v))
5461 res = message ("%q / sref: %q",
5463 sRef_unparseFull (v->sref));
5465 else if (uentry_isVariable (v))
5467 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5469 sRef_unparseFull (v->sref),
5470 (int) v->info->var->kind,
5471 (int) v->info->var->defstate,
5472 (int) v->info->var->nullstate,
5474 DPRINTF (("sref: [%p]", v->sref));
5475 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5476 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5478 else if (uentry_isConstant (v))
5480 res = message ("%q = %q / %q",
5481 res, multiVal_unparse (uentry_getConstantValue (v)),
5482 sRef_unparseFull (v->sref));
5486 res = message ("%q :: %q", res, uentry_unparse (v));
5493 bool uentry_hasAccessType (uentry e)
5495 if (uentry_isValid (e))
5500 return (!typeIdSet_isEmpty (e->info->iter->access));
5502 return (!typeIdSet_isEmpty (e->info->enditer->access));
5504 return (!typeIdSet_isEmpty (e->info->fcn->access));
5507 return (!typeIdSet_isEmpty (e->info->uconst->access));
5516 typeIdSet uentry_accessType (uentry e)
5518 if (uentry_isValid (e))
5523 return (e->info->iter->access);
5525 return (e->info->enditer->access);
5527 return (e->info->fcn->access);
5530 return (e->info->uconst->access);
5536 return typeIdSet_undefined;
5540 uentry_isVariable (uentry e)
5542 return (uentry_isVar (e));
5546 uentry_isSpecified (uentry e)
5548 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5552 uentry_isReallySpecified (uentry e)
5554 return (uentry_isValid (e)
5555 && fileloc_isRealSpec (e->whereSpecified));
5559 uentry_isVar (uentry e)
5561 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5565 uentry_isFakeTag (uentry e)
5567 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5571 uentry_isDatatype (uentry e)
5573 return (!uentry_isUndefined (e) &&
5574 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5575 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5579 uentry_setAbstract (uentry e)
5583 llassert (uentry_isDatatype (e)
5584 && (ynm_isMaybe (e->info->datatype->abs)));
5586 oldid = ctype_typeId (e->info->datatype->type);
5587 e->info->datatype->abs = YES;
5588 e->info->datatype->type = ctype_createAbstract (oldid);
5592 uentry_setConcrete (uentry e)
5594 llassert (uentry_isDatatype (e)
5595 && (ynm_isMaybe (e->info->datatype->abs)));
5597 e->info->datatype->abs = NO;
5601 uentry_isAbstractDatatype (uentry e)
5603 return (uentry_isDatatype (e)
5604 && (ynm_isOn (e->info->datatype->abs)));
5608 uentry_isMaybeAbstract (uentry e)
5610 return (uentry_isDatatype (e)
5611 && (ynm_isMaybe (e->info->datatype->abs)));
5615 uentry_isMutableDatatype (uentry e)
5617 bool res = uentry_isDatatype (e)
5618 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5624 uentry_isRefCountedDatatype (uentry e)
5626 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5630 uentry_isParam (uentry u)
5632 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5633 || u->info->var->kind == VKYIELDPARAM));
5637 uentry_isExpandedMacro (uentry u)
5639 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5643 uentry_isSefParam (uentry u)
5645 return (uentry_isVariable (u)
5646 && (u->info->var->kind == VKSEFPARAM
5647 || u->info->var->kind == VKREFSEFPARAM
5648 || u->info->var->kind == VKSEFRETPARAM
5649 || u->info->var->kind == VKREFSEFRETPARAM));
5653 uentry_isRefParam (uentry u)
5655 return (uentry_isVariable (u)
5656 && (u->info->var->kind == VKREFPARAM
5657 || u->info->var->kind == VKREFYIELDPARAM
5658 || u->info->var->kind == VKREFSEFPARAM
5659 || u->info->var->kind == VKREFSEFRETPARAM));
5663 uentry_isAnyParam (uentry u)
5665 return (uentry_isVariable (u)
5666 && ((u->info->var->kind == VKPARAM)
5667 || (u->info->var->kind == VKSEFPARAM)
5668 || (u->info->var->kind == VKYIELDPARAM)
5669 || (u->info->var->kind == VKRETPARAM)
5670 || (u->info->var->kind == VKSEFRETPARAM)));
5674 uentry_getDefState (uentry u)
5676 if (uentry_isValid (u))
5678 return (sRef_getDefState (u->sref));
5682 return (SS_UNKNOWN);
5687 uentry_isOut (uentry u)
5689 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5690 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5694 uentry_isPartial (uentry u)
5696 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5697 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5701 uentry_isStateSpecial (uentry u)
5703 return ((uentry_isVariable (u)
5704 && (u->info->var->defstate == SS_SPECIAL))
5705 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5708 exitkind uentry_getExitCode (uentry ue)
5710 if (uentry_isFunction (ue))
5712 return ue->info->fcn->exitCode;
5720 qual uentry_nullPred (uentry u)
5722 llassert (uentry_isRealFunction (u));
5724 if (uentry_isFunction (u))
5726 return (u->info->fcn->nullPred);
5730 return qual_createUnknown ();
5735 ** Note for variables, this is checking the declared state, not the current state.
5739 uentry_possiblyNull (uentry u)
5741 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5742 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5746 uentry_getAliasKind (uentry u)
5748 if (uentry_isValid (u))
5750 return (sRef_getAliasKind (uentry_getSref (u)));
5759 uentry_getExpKind (uentry u)
5761 if (uentry_isValid (u))
5763 return (sRef_getExKind (uentry_getSref (u)));
5772 uentry_isIter (uentry e)
5774 return (!uentry_isUndefined (e) && e->ukind == KITER);
5778 uentry_isEndIter (uentry e)
5780 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5784 uentry_isRealFunction (uentry e)
5786 return (uentry_isFunction (e) ||
5787 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5791 uentry_hasName (uentry e)
5793 if (uentry_isValid (e))
5795 cstring s = e->uname;
5797 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5798 || uentry_isFakeTag (e)));
5807 ** Returns true for fake tags.
5808 ** This is used for dumping the library
5811 bool uentry_hasRealName (uentry e)
5813 return (uentry_isValid (e)
5814 && cstring_isNonEmpty (e->uname)
5815 && !uentry_isGlobalMarker (e));
5819 /*@observer@*/ globSet
5820 uentry_getGlobs (uentry l)
5822 if (uentry_isInvalid (l))
5824 return globSet_undefined;
5827 if (l->ukind != KFCN)
5829 if (l->ukind != KITER && l->ukind != KENDITER)
5831 if (l->ukind == KVAR)
5833 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5835 ekind_unparse (l->ukind)));
5839 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5841 ekind_unparse (l->ukind)));
5844 return globSet_undefined;
5847 return l->info->fcn->globs;
5850 /*@observer@*/ sRefSet
5851 uentry_getMods (uentry l)
5853 llassert (uentry_isValid (l));
5855 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5857 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5858 return sRefSet_undefined;
5861 return l->info->fcn->mods;
5865 uentry_getKind (uentry e)
5867 llassert (uentry_isValid (e));
5872 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5874 llassert (uentry_isEitherConstant (e));
5875 return (sRef_getValue (e->sref));
5878 /*@observer@*/ uentryList
5879 uentry_getParams (uentry l)
5881 if (uentry_isInvalid (l)) return uentryList_undefined;
5888 ctype ct = l->utype;
5890 if (ctype_isFunction (ct))
5892 return (ctype_argsFunction (ct));
5896 return uentryList_undefined;
5901 ctype ct = l->utype;
5903 llassert (ctype_isFunction (ct));
5904 return (ctype_argsFunction (ct));
5911 /*@observer@*/ cstring
5912 uentry_rawName (uentry e)
5914 if (uentry_isValid (e))
5920 return cstring_undefined;
5925 uentry_getOptName (uentry e)
5927 cstring s = uentry_getName (e);
5929 if (cstring_isDefined (s))
5931 s = cstring_appendChar (s, ' ');
5938 uentry_getName (uentry e)
5940 cstring ret = cstring_undefined;
5942 if (uentry_isValid (e))
5944 if (uentry_isAnyTag (e))
5946 ret = fixTagName (e->uname);
5948 else if (uentry_isAnyParam (e))
5950 ret = cstring_copy (fixParamName (e->uname));
5954 ret = cstring_copy (e->uname);
5961 cstring uentry_observeRealName (uentry e)
5963 cstring ret = cstring_undefined;
5965 if (uentry_isValid (e))
5967 if (uentry_isAnyTag (e))
5969 if (isFakeTag (e->uname))
5971 ret = cstring_undefined;
5975 ret = plainTagName (e->uname);
5978 else if (uentry_isAnyParam (e))
5980 ret = fixParamName (e->uname);
5991 cstring uentry_getRealName (uentry e)
5993 if (uentry_isValid (e))
5995 if (uentry_isAnyTag (e))
5997 return (cstring_undefined);
6004 return cstring_undefined;
6007 ctype uentry_getType (uentry e)
6009 if (uentry_isValid (e))
6015 return ctype_unknown;
6019 fileloc uentry_whereLast (uentry e)
6023 if (uentry_isInvalid (e))
6025 return fileloc_undefined;
6028 loc = e->whereDefined;
6030 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
6035 loc = uentry_whereDeclared (e);
6037 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
6042 loc = uentry_whereSpecified (e);
6046 fileloc uentry_whereEither (uentry e)
6048 if (uentry_isInvalid (e)) return fileloc_undefined;
6050 if (fileloc_isDefined (e->whereDefined)
6051 && !fileloc_isExternal (e->whereDefined))
6053 return e->whereDefined;
6055 else if (fileloc_isDefined (e->whereDeclared))
6057 return e->whereDeclared;
6061 return e->whereSpecified;
6065 fileloc uentry_whereSpecified (uentry e)
6067 if (uentry_isInvalid (e)) return fileloc_undefined;
6069 return (e->whereSpecified);
6072 fileloc uentry_whereDefined (uentry e)
6074 if (uentry_isInvalid (e)) return fileloc_undefined;
6076 return (e->whereDefined);
6079 fileloc uentry_whereDeclared (uentry e)
6081 if (uentry_isInvalid (e)) return fileloc_undefined;
6083 return (e->whereDeclared);
6086 /*@observer@*/ fileloc
6087 uentry_whereEarliest (uentry e)
6089 if (uentry_isInvalid (e)) return fileloc_undefined;
6091 if (fileloc_isDefined (e->whereSpecified))
6093 return (e->whereSpecified);
6095 else if (fileloc_isDefined (e->whereDeclared))
6097 return (e->whereDeclared);
6101 return e->whereDefined;
6106 uentry_setFunctionDefined (uentry e, fileloc loc)
6108 if (uentry_isValid (e))
6110 llassert (uentry_isFunction (e));
6112 if (fileloc_isUndefined (e->whereDeclared))
6114 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6117 if (!fileloc_isDefined (e->whereDefined))
6119 e->whereDefined = fileloc_update (e->whereDefined, loc);
6125 uentry_setDeclDef (uentry e, fileloc f)
6127 uentry_setDeclared (e, f);
6129 if (!uentry_isFunction (e)
6130 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6132 uentry_setDefined (e, f);
6137 uentry_setDeclaredForce (uentry e, fileloc f)
6139 llassert (uentry_isValid (e));
6140 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6144 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6146 llassert (uentry_isValid (e));
6147 fileloc_free (e->whereDeclared);
6148 e->whereDeclared = f;
6152 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6156 llassert (uentry_isValid (e));
6157 oldloc = e->whereDeclared;
6159 if (fileloc_isDefined (oldloc))
6161 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6163 e->whereDeclared = f;
6164 fileloc_free (oldloc);
6173 e->whereDeclared = f;
6174 fileloc_free (oldloc);
6179 uentry_setDeclared (uentry e, fileloc f)
6183 llassert (uentry_isValid (e));
6184 oldloc = e->whereDeclared;
6186 if (fileloc_isDefined (oldloc))
6188 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6190 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6199 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6204 uentry_clearDefined (uentry e)
6206 if (uentry_isValid (e))
6208 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6213 uentry_setDefined (uentry e, fileloc f)
6217 llassert (uentry_isValid (e));
6218 oldloc = e->whereDefined;
6220 if (fileloc_isDefined (oldloc))
6222 if (fileloc_isLib (oldloc)
6223 || fileloc_isImport (oldloc)
6224 || fileloc_isBuiltin (oldloc)
6225 || fileloc_isPreproc (oldloc))
6227 e->whereDefined = fileloc_update (e->whereDefined, f);
6231 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6237 if (optgenerror (FLG_REDEF,
6238 message ("%s %q redefined",
6239 ekind_capName (e->ukind),
6240 uentry_getName (e)),
6243 llgenindentmsg (message ("Previous definition of %q",
6244 uentry_getName (e)),
6252 e->whereDefined = fileloc_update (e->whereDefined, f);
6257 uentry_isCodeDefined (uentry e)
6259 llassert (uentry_isValid (e));
6261 return (fileloc_isDefined (e->whereDefined));
6265 uentry_isDeclared (uentry e)
6267 if (uentry_isValid (e))
6269 return (fileloc_isDefined (e->whereDeclared));
6275 sRef uentry_getSref (uentry e)
6277 /* not true, used for functions too (but shouldn't be? */
6278 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6280 if (uentry_isInvalid (e)) return sRef_undefined;
6285 sRef uentry_getOrigSref (uentry e)
6287 /*@i523*/ /* evans 2001-09-09 - need to fix this
6288 if (uentry_isValid (e))
6290 if (uentry_isVariable (e))
6292 return e->info->var->origsref;
6296 sRef sr = sRef_copy (uentry_getSref (e));
6298 sRef_resetState (sr);
6299 sRef_clearDerived (sr);
6305 return sRef_undefined;
6309 if (uentry_isValid (e))
6311 sRef sr = sRef_copy (uentry_getSref (e));
6313 sRef_resetState (sr);
6314 sRef_clearDerived (sr);
6316 if (uentry_isVariable (e))
6318 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6319 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6326 return sRef_undefined;
6331 ** requires: uentry e is not in a hashed symbol table
6335 uentry_setName (uentry e, /*@only@*/ cstring n)
6337 llassert (uentry_isValid (e));
6339 cstring_free (e->uname);
6344 uentry_setType (uentry e, ctype t)
6346 if (uentry_isValid (e))
6349 sRef_setType (e->sref, t);
6354 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6357 ctype rettype = ctype_unknown;
6359 llassert (uentry_isValid (ue));
6361 uentry_convertVarFunction (ue);
6362 llassert (uentry_isFunction (ue));
6364 rct = ctype_realType (ue->utype);
6366 if (ctype_isFunction (rct))
6368 rettype = ctype_getReturnType (rct);
6371 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6375 uentry_setRefParam (uentry e)
6377 if (!uentry_isVar (e))
6379 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6383 if (e->info->var->kind == VKSEFPARAM)
6385 e->info->var->kind = VKREFSEFPARAM;
6387 else if (e->info->var->kind == VKSEFRETPARAM)
6389 e->info->var->kind = VKREFSEFRETPARAM;
6391 else if (e->info->var->kind == VKYIELDPARAM)
6393 e->info->var->kind = VKREFYIELDPARAM;
6397 e->info->var->kind = VKREFPARAM;
6403 uentry_setParam (uentry e)
6405 if (!uentry_isVar (e))
6407 if (uentry_isElipsisMarker (e))
6413 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6420 if (e->info->var->kind == VKYIELDPARAM
6421 || e->info->var->kind == VKSEFPARAM
6422 || e->info->var->kind == VKSEFRETPARAM)
6428 e->info->var->kind = VKPARAM;
6432 e->uname = makeParam (e->uname);
6433 cstring_free (oldname);
6438 uentry_setSref (uentry e, sRef s)
6440 if (uentry_isValid (e))
6442 if (sRef_isValid (e->sref))
6444 sRef_mergeStateQuietReverse (e->sref, s);
6448 e->sref = sRef_saveCopy (s);
6454 uentry_getAbstractType (uentry e)
6456 llassert (uentry_isDatatype (e));
6459 ** This assertion removed.
6460 ** Okay to have undefined type, for system types
6462 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6463 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6468 if (ctype_isUndefined (e->info->datatype->type))
6470 return ctype_unknown;
6474 ** Sadly, a kludge...
6477 if (ctype_isUserBool (e->info->datatype->type)) {
6481 return e->info->datatype->type;
6484 ctype uentry_getRealType (uentry e)
6487 typeId uid = USYMIDINVALID;
6489 if (uentry_isInvalid (e))
6491 return ctype_unknown;
6494 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6496 if (uentry_isAnyTag (e))
6501 if (uentry_isAbstractType (e))
6503 ct = uentry_getAbstractType (e);
6505 if (ctype_isManifestBool (ct)) {
6509 llassert (ctype_isUA (ct));
6511 uid = ctype_typeId (ct);
6513 if (!context_hasAccess (uid))
6519 ct = uentry_getType (e);
6521 /* if (ctype_isUserBool (ct)) return ct; */
6523 if (ctype_isManifestBool (ct)) {
6527 if (ctype_isUA (ct))
6529 usymId iid = ctype_typeId (ct);
6531 if (usymId_equal (iid, uid))
6533 llcontbug (message ("uentry_getRealType: recursive type! %s",
6534 ctype_unparse (ct)));
6539 /* evs 2000-07-25: possible infinite recursion ? */
6540 uentry ue2 = usymtab_getTypeEntry (iid);
6544 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6545 return ctype_unknown;
6548 return uentry_getRealType (ue2);
6557 ctype uentry_getForceRealType (uentry e)
6560 typeId uid = USYMIDINVALID;
6562 if (uentry_isInvalid (e))
6564 return ctype_unknown;
6567 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6569 if (uentry_isAnyTag (e))
6574 if (uentry_isAbstractType (e))
6576 ct = uentry_getAbstractType (e);
6577 llassert (ctype_isUA (ct));
6579 uid = ctype_typeId (ct);
6580 /* no check for access! */
6583 ct = uentry_getType (e);
6585 /* evs 2000-07-25 */
6586 /* if (ctype_isUserBool (ct)) return ct; */
6588 if (ctype_isManifestBool (ct)) {
6592 if (ctype_isUA (ct))
6594 usymId iid = ctype_typeId (ct);
6596 if (usymId_equal (iid, uid))
6598 llcontbug (message ("uentry_getRealType: recursive type! %s",
6599 ctype_unparse (ct)));
6604 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6613 uentry uentry_nameCopy (cstring name, uentry e)
6615 uentry enew = uentry_alloc ();
6617 llassert (uentry_isValid (e));
6619 /* enew->shallowCopy = FALSE; */
6620 enew->ukind = e->ukind;
6622 enew->utype = e->utype;
6623 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6624 enew->whereDefined = fileloc_copy (e->whereDefined);
6625 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6626 enew->sref = sRef_copy (e->sref);
6627 enew->used = e->used;
6629 enew->isPrivate = e->isPrivate;
6630 enew->hasNameError = FALSE;
6632 enew->uses = filelocList_new ();
6633 enew->warn = warnClause_undefined;
6635 enew->storageclass = e->storageclass;
6636 enew->info = uinfo_copy (e->info, e->ukind);
6638 enew->cQuals = qualList_copy(e->cQuals);
6645 uentry_setDatatype (uentry e, usymId uid)
6647 llassert (uentry_isDatatype (e));
6649 if (uentry_isAbstractType (e))
6651 e->info->datatype->type = ctype_createAbstract (uid);
6655 e->info->datatype->type = ctype_createUser (uid);
6660 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6661 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6664 llassert (uentry_isValid (e));
6666 if (fileloc_isSpec (f) || fileloc_isImport (f))
6668 e->whereSpecified = f;
6669 e->whereDeclared = fileloc_undefined;
6670 e->whereDefined = fileloc_undefined;
6674 e->whereSpecified = fileloc_undefined;
6675 e->whereDeclared = f;
6676 e->whereDefined = fileloc_undefined;
6679 llassert (fileloc_storable (f));
6683 ucinfo_free (/*@only@*/ ucinfo u)
6689 uvinfo_free (/*@only@*/ uvinfo u)
6691 /*drl7x added 6/29/01 */
6692 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6697 udinfo_free (/*@only@*/ udinfo u)
6703 ufinfo_free (/*@only@*/ ufinfo u)
6705 globSet_free (u->globs);
6706 sRefSet_free (u->mods);
6707 stateClauseList_free (u->specclauses);
6712 uiinfo_free (/*@only@*/ uiinfo u)
6718 ueinfo_free (/*@only@*/ ueinfo u)
6723 static /*@only@*/ ucinfo
6724 ucinfo_copy (ucinfo u)
6726 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6727 ret->access = u->access;
6728 ret->macro = u->macro;
6732 static /*@only@*/ uvinfo
6733 uvinfo_copy (uvinfo u)
6735 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6737 ret->kind = u->kind;
6738 ret->nullstate = u->nullstate;
6739 ret->defstate = u->defstate;
6740 ret->checked = u->checked;
6742 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6744 /* drl added 07-02-001 */
6745 /* copy null terminated information */
6747 if (u->bufinfo != NULL)
6749 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6750 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6751 ret->bufinfo->size = u->bufinfo->size;
6752 ret->bufinfo->len = u->bufinfo->len;
6757 ret->bufinfo = NULL;
6763 static /*@only@*/ udinfo
6764 udinfo_copy (udinfo u)
6766 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6770 ret->type = u->type;
6775 static /*@only@*/ ufinfo
6776 ufinfo_copy (ufinfo u)
6778 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6780 ret->hasGlobs = u->hasGlobs;
6781 ret->hasMods = u->hasMods;
6782 ret->exitCode = u->exitCode;
6783 ret->specialCode = u->specialCode;
6784 ret->nullPred = u->nullPred;
6785 ret->access = u->access;
6786 ret->globs = globSet_newCopy (u->globs);
6787 ret->mods = sRefSet_newCopy (u->mods);
6788 ret->defparams = u->defparams;
6789 ret->specclauses = stateClauseList_copy (u->specclauses);
6791 ret->preconditions = functionConstraint_copy (u->preconditions);
6792 ret->postconditions = functionConstraint_copy (u->postconditions);
6797 static /*@only@*/ uiinfo
6798 uiinfo_copy (uiinfo u)
6800 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6802 ret->access = u->access;
6803 ret->globs = globSet_newCopy (u->globs);
6804 ret->mods = sRefSet_newCopy (u->mods);
6809 static /*@only@*/ ueinfo
6810 ueinfo_copy (ueinfo u)
6812 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6814 ret->access = u->access;
6819 uinfo_free (uinfo u, ekind kind)
6824 case KCONST: ucinfo_free (u->uconst); break;
6825 case KVAR: uvinfo_free (u->var); break;
6829 case KDATATYPE: udinfo_free (u->datatype); break;
6830 case KFCN: ufinfo_free (u->fcn); break;
6831 case KITER: uiinfo_free (u->iter); break;
6832 case KENDITER: ueinfo_free (u->enditer); break;
6833 case KELIPSMARKER: break;
6834 case KINVALID: break;
6840 static /*@only@*/ /*@null@*/ uinfo
6841 uinfo_copy (uinfo u, ekind kind)
6843 if (kind == KELIPSMARKER || kind == KINVALID)
6849 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6854 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6855 case KVAR: ret->var = uvinfo_copy (u->var); break;
6859 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6860 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6861 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6862 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6870 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6872 filelocList_free (e->uses);
6873 cstring_free (e->uname);
6875 uinfo_free (e->info, e->ukind);
6877 fileloc_free (e->whereSpecified);
6878 fileloc_free (e->whereDefined);
6879 fileloc_free (e->whereDeclared);
6881 warnClause_free (e->warn);
6887 extern void uentry_markOwned (/*@owned@*/ uentry u)
6889 sfreeEventually (u);
6893 uentry_free (/*@only@*/ uentry e)
6895 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6897 uentry_reallyFree (e);
6902 ** For uentry's in the global or file scope
6906 uentry_freeComplete (/*@only@*/ uentry e)
6908 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6910 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6911 /*@i@*/ sRef_free (e->sref);
6912 e->sref = sRef_undefined;
6913 uentry_reallyFree (e);
6918 ** requires old->kind != new->kind, old->uname = new->uname
6922 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6924 llassert (uentry_isValid (old));
6925 llassert (uentry_isValid (unew));
6927 if (uentry_isEitherConstant (unew)
6928 && (fileloc_isPreproc (uentry_whereDeclared (old))
6929 || ctype_isUnknown (old->utype))
6930 && !uentry_isSpecified (old))
6938 if (!uentry_isDeclared (old))
6940 if (uentry_isSpecified (old))
6942 if (uentry_isSpecified (unew))
6944 llbuglit ("Respecification!");
6946 else if (uentry_isDeclared (unew))
6950 message ("%s %q inconsistently declared as %s: %t",
6951 ekind_capName (old->ukind),
6952 uentry_getName (unew),
6953 ekind_unparseLong (unew->ukind),
6955 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6957 uentry_showWhereLastKind (old);
6969 message ("%s %q inconsistently declared as %s: %t",
6970 ekind_capName (old->ukind),
6971 uentry_getName (unew),
6972 ekind_unparseLong (unew->ukind),
6974 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6976 uentry_showWhereLastKind (old);
6982 llassert (uentry_isDeclared (unew));
6984 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6985 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6989 message ("%s %q inconsistently redeclared as %s",
6990 ekind_capName (old->ukind),
6991 uentry_getName (unew),
6992 ekind_unparseLong (unew->ukind)),
6993 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6995 uentry_showWhereLastKind (old);
7001 uentry_updateInto (old, unew);
7005 ** def is the definition of spec, modifies spec
7007 ** reports any inconsistencies
7008 ** returns the summary of all available information
7009 ** if spec and def are inconsistent, def is returned
7013 uentry_showWhereLast (uentry spec)
7015 if (uentry_isValid (spec))
7017 if (fileloc_isDefined (spec->whereDefined)
7018 && !fileloc_isLib (spec->whereDefined)
7019 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
7021 llgenindentmsg (message ("Previous definition of %q: %t",
7022 uentry_getName (spec),
7023 uentry_getType (spec)),
7024 uentry_whereDefined (spec));
7026 else if (uentry_isDeclared (spec))
7028 llgenindentmsg (message ("Previous declaration of %q: %t",
7029 uentry_getName (spec),
7030 uentry_getType (spec)),
7031 uentry_whereDeclared (spec));
7033 else if (uentry_isSpecified (spec))
7035 if (uentry_hasName (spec))
7037 llgenindentmsg (message ("Specification of %q: %t",
7038 uentry_getName (spec),
7039 uentry_getType (spec)),
7040 uentry_whereSpecified (spec));
7044 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
7045 uentry_whereSpecified (spec));
7050 /* nothing to show */
7056 uentry_showWhereLastKind (uentry spec)
7058 if (uentry_isValid (spec))
7060 if (fileloc_isDefined (spec->whereDefined)
7061 && !fileloc_isLib (spec->whereDefined)
7062 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
7064 llgenindentmsg (message ("Previous definition of %q as %s: %t",
7065 uentry_getName (spec),
7066 ekind_unparseLong (spec->ukind),
7067 uentry_getType (spec)),
7068 uentry_whereDefined (spec));
7070 else if (uentry_isDeclared (spec))
7072 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
7073 uentry_getName (spec),
7074 ekind_unparseLong (spec->ukind),
7075 uentry_getType (spec)),
7076 uentry_whereDeclared (spec));
7078 else if (uentry_isSpecified (spec))
7080 if (uentry_hasName (spec))
7082 llgenindentmsg (message ("Specification of %q as %s: %t",
7083 uentry_getName (spec),
7084 ekind_unparseLong (spec->ukind),
7085 uentry_getType (spec)),
7086 uentry_whereSpecified (spec));
7090 llgenindentmsg (message ("Specification as %s: %t",
7091 ekind_unparseLong (spec->ukind),
7092 uentry_getType (spec)),
7093 uentry_whereSpecified (spec));
7098 /* nothing to show */
7104 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7106 fileloc loc = uentry_whereDefined (ce);
7108 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7110 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7114 loc = uentry_whereSpecified (ce);
7116 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7118 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7123 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7125 if (uentry_isDeclared (spec))
7127 llgenindentmsg (message ("Previous declaration of %q: %q",
7128 uentry_getName (spec), extra),
7129 uentry_whereDeclared (spec));
7131 else if (uentry_isSpecified (spec))
7133 llgenindentmsg (message ("Specification of %q: %q",
7134 uentry_getName (spec), extra),
7135 uentry_whereSpecified (spec));
7139 cstring_free (extra);
7144 uentry_showWhereDeclared (uentry spec)
7146 if (uentry_isDeclared (spec))
7148 if (uentry_hasName (spec))
7150 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7151 uentry_whereDeclared (spec));
7155 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7158 else if (uentry_isSpecified (spec))
7160 if (uentry_hasName (spec))
7162 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7163 uentry_whereSpecified (spec));
7167 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7172 /* nothing to show */
7178 uentry_showWhereAny (uentry spec)
7180 if (uentry_isDeclared (spec))
7182 if (uentry_hasName (spec))
7184 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7185 uentry_whereDeclared (spec));
7189 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7192 else if (uentry_isSpecified (spec))
7194 if (uentry_hasName (spec))
7196 llgenindentmsg (message ("Specification of %q",
7197 uentry_getName (spec)),
7198 uentry_whereSpecified (spec));
7202 llgenindentmsg (cstring_makeLiteral ("Specification"),
7203 uentry_whereSpecified (spec));
7206 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7208 if (uentry_hasName (spec))
7210 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7211 uentry_whereDefined (spec));
7215 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7220 /* nothing to show */
7225 uentry_showWhereDefined (uentry spec)
7227 if (uentry_isCodeDefined (spec))
7229 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7230 uentry_whereDefined (spec));
7235 uentry_showWhereLastPlain (uentry spec)
7237 if (uentry_isDeclared (spec))
7239 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7240 uentry_whereDeclared (spec));
7242 else if (uentry_isSpecified (spec))
7244 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7245 uentry_whereSpecified (spec));
7253 uentry_showWhereLastVal (uentry spec, cstring val)
7255 if (uentry_isDeclared (spec))
7257 llgenindentmsg (message ("Previous declaration of %q: %s",
7258 uentry_getName (spec), val),
7259 uentry_whereDeclared (spec));
7261 else if (uentry_isSpecified (spec))
7263 llgenindentmsg (message ("Specification of %q: %s",
7264 uentry_getName (spec), val),
7265 uentry_whereSpecified (spec));
7273 uentry_showWhereSpecified (uentry spec)
7275 if (uentry_isSpecified (spec))
7277 if (uentry_hasName (spec))
7279 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7280 uentry_whereSpecified (spec));
7284 llgenindentmsg (cstring_makeLiteral ("Specification"),
7285 uentry_whereSpecified (spec));
7288 else if (uentry_isDeclared (spec))
7290 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7291 uentry_whereDeclared (spec));
7295 /* nothing to show */
7300 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7302 if (uentry_isSpecified (spec))
7304 if (uentry_hasName (spec))
7306 llgenindentmsg (message ("Specification of %q: %q",
7307 uentry_getName (spec), s),
7308 uentry_whereSpecified (spec));
7312 llgenindentmsg (message ("Specification: %q", s),
7313 uentry_whereSpecified (spec));
7316 else if (uentry_isDeclared (spec))
7318 llgenindentmsg (message ("Declaration of %q: %q",
7319 uentry_getName (spec), s),
7320 uentry_whereDeclared (spec));
7324 llgenindentmsg (message ("Previous: %q", s),
7325 uentry_whereLast (spec));
7334 checkStructConformance (uentry old, uentry unew)
7337 uentryList fold, fnew;
7340 ** requires: types of old and new are structs or unions
7343 llassert (uentry_isValid (old));
7344 llassert (uentry_isValid (unew));
7346 oldr = ctype_realType (old->utype);
7347 fold = ctype_getFields (oldr);
7349 newr = ctype_realType (unew->utype);
7350 fnew = ctype_getFields (newr);
7352 if (!uentryList_matchFields (fold, fnew))
7354 if (fileloc_equal (uentry_whereLast (old),
7355 uentry_whereLast (unew)))
7363 message ("%q %q %rdeclared with fields { %q }, %s "
7364 "with fields { %q }",
7365 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7366 uentry_getName (old),
7367 uentry_isDeclared (old),
7368 uentryList_unparseAbbrev (fnew),
7369 uentry_specOrDefName (old),
7370 uentryList_unparseAbbrev (fold)),
7371 uentry_whereDeclared (unew)))
7373 uentry_showWhereLastPlain (old);
7374 uentryList_showFieldDifference (fold, fnew);
7378 old->utype = unew->utype;
7383 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7386 ** requires old and new are enums
7389 ctype rold = ctype_realType (old->utype);
7390 ctype rnew = ctype_realType (unew->utype);
7391 enumNameList eold = ctype_elist (rold);
7392 enumNameList enew = ctype_elist (rnew);
7394 if (!enumNameList_match (eold, enew))
7398 message ("Enum %q declared with members { %q } but "
7399 "specified with members { %q }",
7400 uentry_getName (old),
7401 enumNameList_unparse (enew),
7402 enumNameList_unparse (eold)),
7403 uentry_whereDeclared (unew)))
7405 uentry_showWhereSpecified (old);
7406 old->utype = unew->utype;
7412 ** either oldCurrent or newCurrent may be undefined!
7416 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7417 uentry unew, uentry newCurrent, ctype newType,
7420 bool hasError = FALSE;
7422 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7424 if (uentry_hasName (newCurrent))
7426 hasError = optgenerror
7428 message ("Parameter %d, %q, of function %q has inconsistent type: "
7429 "declared %t, %s %t",
7430 paramno + 1, uentry_getName (newCurrent),
7431 uentry_getName (unew),
7432 newType, uentry_specOrDefName (old), oldType),
7433 uentry_whereDeclared (newCurrent));
7437 hasError = optgenerror
7439 message ("Parameter %d of function %q has inconsistent type: "
7440 "declared %t, %s %t",
7441 paramno + 1, uentry_getName (unew),
7442 newType, uentry_specOrDefName (old), oldType),
7443 uentry_whereDeclared (newCurrent));
7445 DPRINTF (("type: %s / %s",
7446 ctype_unparse (newType),
7447 ctype_unparse (ctype_realType (newType))));
7452 if (uentry_isDeclared (unew))
7454 hasError = optgenerror
7456 message ("Parameter %d of function %s has inconsistent type: "
7457 "declared %t, %s %t",
7458 paramno + 1, unew->uname,
7459 newType, uentry_specOrDefName (old), oldType),
7460 uentry_whereDeclared (unew));
7464 hasError = optgenerror
7466 message ("Parameter %d of function %s has inconsistent type: "
7467 "declared %t, %s %t",
7468 paramno + 1, unew->uname,
7469 newType, uentry_specOrDefName (old), oldType),
7470 uentry_whereDeclared (unew));
7476 DPRINTF (("Here: %s / %s",
7477 uentry_unparseFull (oldCurrent),
7478 uentry_unparseFull (newCurrent)));
7480 if (!uentry_isUndefined (oldCurrent))
7482 if (!uentry_isUndefined (newCurrent)
7483 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7485 uentry_showWhereLast (oldCurrent);
7489 uentry_showWhereLastPlain (old);
7492 uentry_setType (oldCurrent, newType);
7496 uentry_showWhereLastPlain (old);
7502 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7506 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7508 uentry_isDeclared (old),
7509 uentryList_size (uentry_getParams (unew)),
7510 uentry_specOrDefName (old),
7511 uentryList_size (uentry_getParams (old))),
7512 uentry_whereDeclared (unew)))
7514 uentry_showWhereLastPlain (old);
7519 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7523 message ("Function %s inconsistently %rdeclared to return %t",
7525 uentry_isDeclared (old),
7526 ctype_getReturnType (unew->utype)),
7527 uentry_whereDeclared (unew)))
7529 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7533 static cstring paramStorageName (uentry ue)
7535 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7538 static cstring fcnErrName (uentry ue)
7540 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7543 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7545 if (uentry_isVar (ue))
7547 return (checkedName (ue->info->var->checked));
7551 return (cstring_makeLiteralTemp ("<checked invalid>"));
7555 static cstring checkedName (chkind checked)
7559 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7560 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7561 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7562 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7563 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7569 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7574 if (uentry_isVar (unew))
7576 llassert (uentry_isVar (old));
7578 oldState = old->info->var->nullstate;
7579 newState = unew->info->var->nullstate;
7583 oldState = sRef_getNullState (old->sref);
7584 newState = sRef_getNullState (unew->sref);
7587 if (oldState == NS_ABSNULL)
7589 if (uentry_isVar (old))
7591 old->info->var->nullstate = newState;
7594 sRef_mergeNullState (old->sref, newState);
7596 else if (newState == NS_UNKNOWN)
7598 if (completeConform && newState != oldState
7599 && uentry_isReallySpecified (old))
7603 message ("%s %q specified as %s, but declared without %s qualifier",
7604 ekind_capName (unew->ukind),
7605 uentry_getName (unew),
7606 nstate_unparse (oldState),
7607 nstate_unparse (oldState)),
7608 uentry_whereDeclared (unew)))
7610 uentry_showWhereSpecified (old);
7614 if (uentry_isVar (unew))
7616 unew->info->var->nullstate = oldState;
7619 sRef_mergeNullState (unew->sref, oldState);
7621 else if (newState == NS_POSNULL)
7623 if (oldState == NS_MNOTNULL
7624 && (ctype_isUA (unew->utype)
7625 || (uentry_isFunction (unew)
7626 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7628 if (uentry_isVar (unew))
7630 unew->info->var->nullstate = oldState;
7633 sRef_mergeNullState (unew->sref, oldState);
7637 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7638 || oldState == NS_UNKNOWN)
7645 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7647 uentry_ekindName (unew),
7648 uentry_getName (unew),
7649 uentry_isDeclared (old),
7651 uentry_specOrDefName (old),
7652 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7653 uentry_whereDeclared (unew)))
7655 uentry_showWhereSpecified (old);
7660 if (uentry_isVar (old))
7662 old->info->var->nullstate = newState;
7665 sRef_mergeNullState (old->sref, newState);
7668 else if (newState == NS_MNOTNULL)
7670 if (oldState != NS_MNOTNULL)
7676 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7677 "%s without notnull qualifier",
7678 uentry_ekindName (unew),
7679 uentry_getName (unew),
7680 uentry_isDeclared (old),
7682 uentry_specOrDefName (old)),
7683 uentry_whereDeclared (unew)))
7685 uentry_showWhereSpecified (old);
7689 if (uentry_isVar (old))
7691 old->info->var->nullstate = newState;
7694 sRef_mergeNullState (old->sref, newState);
7699 if (uentry_isVar (unew))
7701 unew->info->var->nullstate = oldState;
7704 sRef_mergeNullState (unew->sref, oldState);
7709 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7710 bool mustConform, bool completeConform)
7716 if (uentry_isVar (old) && uentry_isVar (unew))
7718 oldState = old->info->var->defstate;
7719 newState = unew->info->var->defstate;
7724 oldState = sRef_getDefState (old->sref);
7725 newState = sRef_getDefState (unew->sref);
7728 if (newState != oldState
7729 && newState != SS_UNKNOWN
7730 && newState != SS_DEFINED)
7736 message ("%s %q inconsistently %rdeclared %s %s %s, "
7738 uentry_ekindName (unew),
7739 uentry_getName (unew),
7740 uentry_isDeclared (old),
7742 sstate_unparse (newState),
7743 paramStorageName (unew),
7744 uentry_specOrDefName (old),
7746 sstate_unparse (oldState),
7747 paramStorageName (unew)),
7748 uentry_whereDeclared (unew)))
7750 uentry_showWhereSpecified (old);
7754 if (vars) old->info->var->defstate = newState;
7755 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7760 && (newState != oldState) && (oldState != SS_DEFINED)
7761 && uentry_isReallySpecified (old))
7765 message ("%s %q specified as %s, but declared without %s qualifier",
7766 ekind_capName (unew->ukind),
7767 uentry_getName (unew),
7768 sstate_unparse (oldState),
7769 sstate_unparse (oldState)),
7770 uentry_whereDeclared (unew)))
7772 uentry_showWhereSpecified (old);
7776 if (vars) unew->info->var->defstate = oldState;
7777 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7782 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7783 bool mustConform, bool completeConform)
7788 oldKind = sRef_getAliasKind (old->sref);
7789 newKind = sRef_getAliasKind (unew->sref);
7791 if (alkind_isImplicit (newKind)
7792 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7794 if (completeConform && !alkind_equal (newKind, oldKind)
7795 && uentry_isReallySpecified (old))
7799 message ("%s %q specified as %s, but declared without "
7800 "explicit alias qualifier",
7801 ekind_capName (unew->ukind),
7802 uentry_getName (unew),
7803 alkind_unparse (oldKind)),
7804 uentry_whereDeclared (unew)))
7806 uentry_showWhereSpecified (old);
7811 ** This really shouldn't be necessary, but it is!
7812 ** Function params (?) use new here.
7815 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7819 if (alkind_isKnown (newKind))
7821 if (!alkind_equal (oldKind, newKind))
7823 if (alkind_isKnown (oldKind))
7828 message ("%s %q inconsistently %rdeclared %s %s storage, "
7830 uentry_ekindName (unew),
7831 uentry_getName (unew),
7832 uentry_isDeclared (old),
7834 alkind_unparse (newKind),
7835 uentry_specOrDefName (old),
7836 alkind_unparse (oldKind)),
7837 uentry_whereDeclared (unew)))
7839 uentry_showWhereSpecified (old);
7841 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7842 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7843 sRef_setAliasKind (old->sref, AK_ERROR,
7844 uentry_whereDeclared (unew));
7848 sRef_setAliasKind (old->sref, newKind,
7849 uentry_whereDeclared (unew));
7854 if (!(alkind_isImplicit (newKind)))
7857 !uentry_isFunction (unew) &&
7860 message ("%s %q inconsistently %rdeclared %s %s storage, "
7861 "implicitly %s as temp storage",
7862 uentry_ekindName (unew),
7863 uentry_getName (unew),
7864 uentry_isDeclared (old),
7866 alkind_unparse (newKind),
7867 uentry_specOrDefName (old)),
7868 uentry_whereDeclared (unew)))
7870 uentry_showWhereSpecified (old);
7874 sRef_setAliasKind (old->sref, newKind,
7875 uentry_whereDeclared (unew));
7877 else /* newKind is temp or refcounted */
7884 else /* newKind unknown */
7891 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7892 bool mustConform, bool completeConform)
7897 oldKind = sRef_getExKind (old->sref);
7898 newKind = sRef_getExKind (unew->sref);
7900 if (exkind_isKnown (newKind))
7902 if (oldKind != newKind)
7904 if (exkind_isKnown (oldKind))
7909 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7910 uentry_ekindName (unew),
7911 uentry_getName (unew),
7912 uentry_isDeclared (old),
7914 exkind_unparse (newKind),
7915 uentry_specOrDefName (old),
7916 exkind_unparse (oldKind)),
7917 uentry_whereDeclared (unew)))
7919 uentry_showWhereSpecified (old);
7922 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7929 message ("%s %q inconsistently %rdeclared %s %s, "
7930 "implicitly %s without exposure qualifier",
7931 uentry_ekindName (unew),
7932 uentry_getName (unew),
7933 uentry_isDeclared (old),
7935 exkind_unparse (newKind),
7936 uentry_specOrDefName (old)),
7937 uentry_whereDeclared (unew)))
7939 uentry_showWhereSpecified (old);
7942 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7948 if (completeConform && exkind_isKnown (oldKind)
7949 && uentry_isReallySpecified (old))
7953 message ("%s %q specified as %s, but declared without "
7954 "exposure qualifier",
7955 ekind_capName (unew->ukind),
7956 uentry_getName (unew),
7957 exkind_unparse (oldKind)),
7958 uentry_whereDeclared (unew)))
7960 uentry_showWhereSpecified (old);
7964 /* yes, this is necessary! (if its a param) */
7965 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7970 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7971 bool mustConform, /*@unused@*/ bool completeConform)
7973 valueTable newvals = sRef_getValueTable (unew->sref);
7975 if (valueTable_isDefined (newvals))
7977 DPRINTF (("Check meta state: %s -> %s",
7978 uentry_unparseFull (old),
7979 uentry_unparseFull (unew)));
7981 DPRINTF (("Check meta state refs: %s -> %s",
7982 sRef_unparseFull (old->sref),
7983 sRef_unparseFull (unew->sref)));
7985 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7988 ** Copy the new values into the old ref
7991 valueTable_elements (newvals, key, newval)
7993 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7994 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7996 llassert (metaStateInfo_isDefined (msinfo));
7998 if (stateValue_isUndefined (oldval))
8000 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8004 if (stateValue_isError (oldval))
8006 if (!stateValue_isError (newval))
8008 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8012 ; /* No change necessary. */
8017 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
8019 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
8025 if (!stateValue_isError (newval)
8026 && !stateValue_isImplicit (newval))
8028 if (uentry_hasName (unew)
8029 || !sRef_isParam (uentry_getSref (unew)))
8034 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
8035 uentry_ekindName (unew),
8036 uentry_getName (unew),
8037 uentry_isDeclared (old),
8039 stateValue_unparseValue (newval, msinfo),
8040 uentry_specOrDefName (old),
8041 stateValue_unparseValue (oldval, msinfo)),
8042 uentry_whereDeclared (unew)))
8044 uentry_showWhereSpecified (old);
8052 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
8053 uentry_ekindName (unew),
8054 sRef_getParam (uentry_getSref (unew)),
8055 uentry_isDeclared (old),
8057 stateValue_unparseValue (newval, msinfo),
8058 uentry_specOrDefName (old),
8059 stateValue_unparseValue (oldval, msinfo)),
8060 uentry_whereDeclared (unew)))
8062 uentry_showWhereSpecified (old);
8068 DPRINTF (("Updating!"));
8069 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8073 DPRINTF (("Values match"));
8077 } end_valueTable_elements ;
8082 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8083 /*@notnull@*/ uentry unew,
8084 bool mustConform, bool completeConform)
8086 checkDefState (old, unew, mustConform, completeConform);
8087 checkNullState (old, unew, mustConform, completeConform);
8088 checkAliasState (old, unew, mustConform, completeConform);
8089 checkExpState (old, unew, mustConform, completeConform);
8090 checkMetaState (old, unew, mustConform, completeConform);
8092 sRef_storeState (old->sref);
8093 sRef_storeState (unew->sref);
8097 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8099 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8104 llassert (uentry_isVar (old));
8105 llassert (uentry_isVar (unew));
8107 if (cstring_isEmpty (old->uname))
8109 cstring_free (old->uname);
8110 old->uname = cstring_copy (unew->uname);
8113 if (unew->info->var->kind == VKRETPARAM
8114 || unew->info->var->kind == VKSEFRETPARAM)
8116 if (old->info->var->kind != VKRETPARAM
8117 && old->info->var->kind != VKSEFRETPARAM)
8121 message ("Parameter %q inconsistently %rdeclared as "
8122 "returned parameter",
8123 uentry_getName (unew),
8124 uentry_isDeclared (old)),
8125 uentry_whereDeclared (unew)))
8127 uentry_showWhereSpecified (old);
8128 old->info->var->kind = unew->info->var->kind;
8134 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8136 if (old->info->var->kind != VKSEFPARAM
8137 && old->info->var->kind != VKSEFRETPARAM)
8141 message ("Parameter %qinconsistently %rdeclared as "
8143 uentry_getOptName (unew),
8144 uentry_isDeclared (old)),
8145 uentry_whereDeclared (unew)))
8147 uentry_showWhereSpecified (old);
8148 old->info->var->kind = unew->info->var->kind;
8153 if (old->info->var->kind == VKSPEC)
8155 old->info->var->kind = unew->info->var->kind;
8159 unew->info->var->kind = old->info->var->kind;
8162 if (unew->info->var->checked != CH_UNKNOWN
8163 && unew->info->var->checked != old->info->var->checked)
8165 if (old->info->var->checked == CH_UNKNOWN
8166 && !fileloc_isUser (uentry_whereLast (old)))
8174 message ("Variable %q inconsistently %rdeclared as "
8175 "%s parameter (was %s)",
8176 uentry_getName (unew),
8177 uentry_isDeclared (old),
8178 checkedName (unew->info->var->checked),
8179 checkedName (old->info->var->checked)),
8180 uentry_whereDeclared (unew)))
8182 uentry_showWhereSpecified (old);
8186 old->info->var->checked = unew->info->var->checked;
8191 && (old->info->var->checked != CH_UNKNOWN)
8192 && uentry_isReallySpecified (old))
8196 message ("%s %q specified as %s, but declared without %s qualifier",
8197 ekind_capName (unew->ukind),
8198 uentry_getName (unew),
8199 checkedName (old->info->var->checked),
8200 checkedName (old->info->var->checked)),
8201 uentry_whereDeclared (unew)))
8203 uentry_showWhereSpecified (old);
8207 unew->info->var->checked = old->info->var->checked;
8210 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8213 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8215 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8220 llassert (uentry_isVar (u1));
8221 llassert (uentry_isVar (u2));
8223 if (u1->info->var->kind != u2->info->var->kind) {
8224 if (u1->info->var->kind == VKSEFRETPARAM) {
8225 if (u2->info->var->kind == VKRETPARAM) {
8228 message ("Function types are inconsistent. Parameter %d is "
8229 "sef parameter, but non-sef parameter in "
8230 "assigned function: %s",
8231 paramno, exprNode_unparse (e)),
8233 } else if (u2->info->var->kind == VKSEFPARAM) {
8236 message ("Function types are inconsistent. Parameter %d is "
8237 "returns parameter, but non-returns parameter in "
8238 "assigned function: %s",
8239 paramno, exprNode_unparse (e)),
8244 message ("Function types are inconsistent. Parameter %d is "
8245 "sef returns parameter, but non-sef returns parameter in "
8246 "assigned function: %s",
8247 paramno, exprNode_unparse (e)),
8250 } else if (u1->info->var->kind == VKRETPARAM) {
8253 message ("Function types are inconsistent. Parameter %d is "
8254 "returns parameter, but non-returns parameter in "
8255 "assigned function: %s",
8256 paramno, exprNode_unparse (e)),
8258 } else if (u1->info->var->kind == VKSEFPARAM) {
8261 message ("Function types are inconsistent. Parameter %d is "
8262 "sef parameter, but non-sef parameter in "
8263 "assigned function: %s",
8264 paramno, exprNode_unparse (e)),
8267 if (u2->info->var->kind == VKSEFRETPARAM) {
8270 message ("Function types are inconsistent. Parameter %d is "
8271 "normal parameter, but sef returns parameter in "
8272 "assigned function: %s",
8273 paramno, exprNode_unparse (e)),
8275 } else if (u2->info->var->kind == VKSEFPARAM) {
8278 message ("Function types are inconsistent. Parameter %d is "
8279 "normal parameter, but sef parameter in "
8280 "assigned function: %s",
8281 paramno, exprNode_unparse (e)),
8283 } else if (u2->info->var->kind == VKRETPARAM) {
8286 message ("Function types are inconsistent. Parameter %d is "
8287 "normal parameter, but returns parameter in "
8288 "assigned function: %s",
8289 paramno, exprNode_unparse (e)),
8297 if (u1->info->var->defstate != u2->info->var->defstate)
8301 message ("Function types are inconsistent. Parameter %d is "
8302 "%s, but %s in assigned function: %s",
8304 sstate_unparse (u1->info->var->defstate),
8305 sstate_unparse (u2->info->var->defstate),
8306 exprNode_unparse (e)),
8310 if (u1->info->var->nullstate != u2->info->var->nullstate)
8314 message ("Function types are inconsistent. Parameter %d is "
8315 "%s, but %s in assigned function: %s",
8317 nstate_unparse (u1->info->var->nullstate),
8318 nstate_unparse (u2->info->var->nullstate),
8319 exprNode_unparse (e)),
8323 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8327 message ("Function types are inconsistent. Parameter %d is "
8328 "%s, but %s in assigned function: %s",
8330 alkind_unparse (sRef_getAliasKind (u1->sref)),
8331 alkind_unparse (sRef_getAliasKind (u2->sref)),
8332 exprNode_unparse (e)),
8336 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8340 message ("Function types are inconsistent. Parameter %d is "
8341 "%s, but %s in assigned function: %s",
8343 exkind_unparse (sRef_getExKind (u1->sref)),
8344 exkind_unparse (sRef_getExKind (u2->sref)),
8345 exprNode_unparse (e)),
8351 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8352 /*@notnull@*/ uentry unew,
8353 bool mustConform, /*@unused@*/ bool completeConform)
8355 uentryList oldParams = uentry_getParams (old);
8356 uentryList newParams = uentry_getParams (unew);
8357 ctype newType = unew->utype;
8358 ctype oldType = ctype_realType (old->utype);
8359 ctype oldRetType = ctype_unknown;
8360 ctype newRetType = ctype_unknown;
8362 DPRINTF (("Function conform: %s ==> %s",
8363 uentry_unparseFull (old),
8364 uentry_unparseFull (unew)));
8366 if (uentry_isForward (old))
8368 mustConform = FALSE;
8369 uentry_updateInto (old, unew);
8374 ** check return values
8377 if (ctype_isKnown (oldType))
8379 llassert (ctype_isFunction (oldType));
8380 oldRetType = ctype_getReturnType (oldType);
8383 if (ctype_isKnown (newType))
8385 llassert (ctype_isFunction (newType));
8386 newRetType = ctype_getReturnType (newType);
8389 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8390 && !ctype_matchDef (newRetType, oldRetType))
8392 if (mustConform) returnValueError (old, unew);
8396 if (ctype_isConj (newRetType))
8398 if (ctype_isConj (oldRetType))
8400 if (!ctype_sameAltTypes (newRetType, oldRetType))
8404 message ("Function %q inconsistently %rdeclared to "
8405 "return alternate types %s "
8406 "(types match, but alternates are not identical, "
8407 "so checking may not be correct)",
8408 uentry_getName (unew),
8409 uentry_isDeclared (old),
8410 ctype_unparse (newRetType)),
8411 uentry_whereDeclared (unew)))
8413 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8419 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8424 DPRINTF (("Before state: %s",
8425 uentry_unparseFull (old)));
8426 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8427 DPRINTF (("After state: %s",
8428 uentry_unparseFull (old)));
8430 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8432 if (exitkind_isKnown (unew->info->fcn->exitCode))
8436 message ("Function %q inconsistently %rdeclared using %s",
8437 uentry_getName (unew),
8438 uentry_isDeclared (old),
8439 exitkind_unparse (unew->info->fcn->exitCode)),
8440 uentry_whereDeclared (unew)))
8442 uentry_showWhereSpecified (old);
8447 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8451 if (!qual_isUnknown (unew->info->fcn->nullPred))
8453 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8457 message ("Function %q inconsistently %rdeclared using %s",
8458 uentry_getName (unew),
8459 uentry_isDeclared (old),
8460 qual_unparse (unew->info->fcn->nullPred)),
8461 uentry_whereDeclared (unew)))
8463 uentry_showWhereSpecified (old);
8469 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8472 if (unew->info->fcn->specialCode != SPC_NONE)
8474 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8478 message ("Function %q inconsistently %rdeclared using %s",
8479 uentry_getName (unew),
8480 uentry_isDeclared (old),
8481 specCode_unparse (unew->info->fcn->specialCode)),
8482 uentry_whereDeclared (unew)))
8484 uentry_showWhereSpecified (old);
8490 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8497 if (!uentryList_sameObject (oldParams, newParams)
8498 && (!uentryList_isMissingParams (oldParams)))
8500 if (!uentryList_isMissingParams (newParams))
8503 int nparams = uentryList_size (oldParams);
8504 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8506 if (nparams != uentryList_size (newParams))
8508 nargsError (old, unew);
8511 if (uentryList_size (newParams) < nparams)
8513 nparams = uentryList_size (newParams);
8516 while (paramno < nparams)
8518 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8519 uentry newCurrent = uentryList_getN (newParams, paramno);
8520 ctype oldCurrentType = uentry_getType (oldCurrent);
8521 ctype newCurrentType = uentry_getType (newCurrent);
8523 llassert (uentry_isValid (oldCurrent)
8524 && uentry_isValid (newCurrent));
8526 if (!uentry_isElipsisMarker (oldCurrent)
8527 && !uentry_isElipsisMarker (newCurrent))
8529 checkVarConformance (oldCurrent, newCurrent,
8530 mustConform, completeConform);
8535 if (uentry_hasName (oldCurrent)
8536 && uentry_hasName (newCurrent))
8538 cstring oldname = uentry_getName (oldCurrent);
8539 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8541 cstring nname = uentry_getName (newCurrent);
8544 if (cstring_isDefined (pfx)
8545 && cstring_equalPrefix (oldname, pfx))
8547 oname = cstring_suffix (oldname, cstring_length (pfx));
8552 /*@-branchstate@*/ } /*@=branchstate@*/
8554 if (cstring_isDefined (pfx)
8555 && cstring_equalPrefix (nname, pfx))
8557 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8562 /*@-branchstate@*/ } /*@=branchstate@*/
8564 if (!cstring_equal (oname, nnamefix))
8567 (FLG_DECLPARAMMATCH,
8568 message ("Definition parameter name %s does not match "
8569 "name of corresponding parameter in "
8572 uentry_whereLast (newCurrent)))
8574 uentry_showWhereLastPlain (oldCurrent);
8578 cstring_free (oldname);
8579 cstring_free (nname);
8583 if (!ctype_match (oldCurrentType, newCurrentType))
8585 paramTypeError (old, oldCurrent, oldCurrentType,
8586 unew, newCurrent, newCurrentType, paramno);
8590 if (ctype_isMissingParamsMarker (newCurrentType)
8591 || ctype_isElips (newCurrentType)
8592 || ctype_isMissingParamsMarker (oldCurrentType)
8593 || ctype_isElips (oldCurrentType))
8599 if (ctype_isConj (newCurrentType))
8601 if (ctype_isConj (oldCurrentType))
8603 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8607 message ("Parameter %q inconsistently %rdeclared with "
8608 "alternate types %s "
8609 "(types match, but alternates are not identical, "
8610 "so checking may not be correct)",
8611 uentry_getName (newCurrent),
8612 uentry_isDeclared (oldCurrent),
8613 ctype_unparse (newCurrentType)),
8614 uentry_whereDeclared (unew)))
8616 uentry_showWhereLastVal (oldCurrent,
8617 ctype_unparse (oldCurrentType));
8625 message ("Parameter %q inconsistently %rdeclared with "
8626 "alternate types %s",
8627 uentry_getName (newCurrent),
8628 uentry_isDeclared (oldCurrent),
8629 ctype_unparse (newCurrentType)),
8630 uentry_whereDeclared (unew)))
8632 uentry_showWhereLastVal (oldCurrent,
8633 ctype_unparse (oldCurrentType));
8640 if (ctype_isConj (oldCurrentType))
8642 uentry_setType (newCurrent, oldCurrentType);
8650 ** Forgot this! detected by splint:
8651 ** uentry.c:1257,15: Suspected infinite loop
8657 if (!uentryList_isMissingParams (newParams))
8659 if (ctype_isConj (oldRetType))
8661 old->utype = ctype_makeFunction (oldRetType,
8662 uentryList_copy (newParams));
8666 old->utype = unew->utype;
8670 checkGlobalsConformance (old, unew, mustConform, completeConform);
8671 checkModifiesConformance (old, unew, mustConform, completeConform);
8673 DPRINTF (("Before list: %s",
8674 uentry_unparseFull (old)));
8676 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8678 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8683 message ("Function %q redeclared using special clauses (can only "
8684 "be used in first declaration)",
8685 uentry_getName (unew)),
8686 uentry_whereDeclared (unew)))
8688 uentry_showWhereLast (old);
8692 /*@i23 need checking @*/
8694 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8698 /*@i43 should be able to append? @*/
8700 stateClauseList_checkEqual (old, unew);
8701 stateClauseList_free (unew->info->fcn->specclauses);
8702 unew->info->fcn->specclauses = stateClauseList_undefined;
8706 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8708 if (fileloc_isUndefined (old->whereDeclared))
8710 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8712 else if (fileloc_isUndefined (unew->whereDeclared))
8714 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8723 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8727 llassert (uentry_isValid (ue));
8728 llassert (uentry_isEitherConstant (ue));
8730 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8731 uval = uentry_getConstantValue (ue);
8733 if (multiVal_isDefined (uval))
8735 if (multiVal_isDefined (m))
8737 if (!multiVal_equiv (uval, m))
8741 message ("%s %q defined with inconsistent value: %q",
8742 ekind_capName (ue->ukind),
8743 uentry_getName (ue),
8744 multiVal_unparse (m)),
8747 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8755 uentry_setConstantValue (ue, m);
8760 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8763 bool typeError = FALSE;
8765 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8767 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8771 DPRINTF (("Check struct conformance: %s / %s",
8772 uentry_unparseFull (old),
8773 uentry_unparseFull (unew)));
8774 checkStructConformance (old, unew);
8779 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8781 llbug (message ("struct tags: bad types: %t / %t",
8782 old->utype, unew->utype));
8786 else if (uentry_isEnumTag (old))
8788 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8790 if (mustConform) checkEnumConformance (old, unew);
8794 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8796 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8797 ctype_unparse (unew->utype)));
8801 else if (!ctype_match (old->utype, unew->utype))
8803 DPRINTF (("Type mismatch: %s / %s",
8804 ctype_unparse (old->utype),
8805 ctype_unparse (unew->utype)));
8807 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8809 ctype realt = ctype_realType (unew->utype);
8811 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8813 unew->utype = ctype_bool;
8819 typeError = optgenerror
8821 message ("%q defined as %s", uentry_getName (old),
8822 ctype_unparse (realt)),
8823 uentry_whereDeclared (unew));
8831 ctype oldr = ctype_realType (old->utype);
8832 ctype newr = ctype_realType (unew->utype);
8834 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8836 checkStructConformance (old, unew);
8838 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8840 checkStructConformance (old, unew);
8842 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8844 checkEnumConformance (old, unew);
8846 else if (uentry_isConstant (old)
8847 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8849 /* okay...for now! (should check the type is reset later... */
8853 DPRINTF (("YABA!"));
8856 message ("%s %q %rdeclared with inconsistent type: %t",
8857 ekind_capName (unew->ukind),
8858 uentry_getName (unew),
8859 uentry_isDeclared (old),
8861 uentry_whereDeclared (unew)))
8863 uentry_showWhereLast (old);
8879 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8880 /*@notnull@*/ uentry unew,
8881 bool mustConform, bool completeConform)
8883 if (ctype_isDefined (unew->info->datatype->type))
8886 ** bool is hard coded here, since it is built into LCL.
8887 ** For now, we're stuck with LCL's types.
8890 if (ctype_isDirectBool (old->utype) &&
8891 cstring_equalLit (unew->uname, "bool"))
8893 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8894 evs 2000-07-25: removed
8896 unew->utype = ctype_bool;
8899 if (ctype_isUnknown (old->info->datatype->type))
8901 old->info->datatype->type = unew->info->datatype->type;
8905 DPRINTF (("Old: %s / New: %s",
8906 uentry_unparseFull (old),
8907 uentry_unparseFull (unew)));
8908 DPRINTF (("Types: %s / %s",
8909 ctype_unparse (old->info->datatype->type),
8910 ctype_unparse (unew->info->datatype->type)));
8912 if (ctype_matchDef (old->info->datatype->type,
8913 unew->info->datatype->type))
8922 ("Type %q %s with inconsistent type: %t",
8923 uentry_getName (unew),
8924 uentry_reDefDecl (old, unew),
8925 unew->info->datatype->type),
8926 uentry_whereDeclared (unew)))
8928 uentry_showWhereLastExtra
8929 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8932 old->info->datatype->type = unew->info->datatype->type;
8937 if (unew->info->datatype->abs != MAYBE)
8939 if (ynm_isOff (old->info->datatype->abs)
8940 && ynm_isOn (unew->info->datatype->abs))
8942 if (!ctype_isDirectBool (old->utype))
8947 ("Datatype %q inconsistently %rdeclared as abstract type",
8948 uentry_getName (unew),
8949 uentry_isDeclared (old)),
8950 uentry_whereDeclared (unew)))
8952 uentry_showWhereLastPlain (old);
8956 else if (ynm_isOn (old->info->datatype->abs)
8957 && ynm_isOff (unew->info->datatype->abs))
8959 if (!ctype_isDirectBool (old->utype))
8964 ("Datatype %q inconsistently %rdeclared as concrete type",
8965 uentry_getName (unew),
8966 uentry_isDeclared (old)),
8967 uentry_whereDeclared (unew)))
8969 uentry_showWhereLastPlain (old);
8980 if (ynm_isOn (old->info->datatype->abs))
8982 old->sref = unew->sref;
8983 unew->info->datatype->mut = old->info->datatype->mut;
8986 && uentry_isReallySpecified (old))
8991 ("Datatype %q specified as abstract, "
8992 "but abstract annotation not used in declaration",
8993 uentry_getName (unew)),
8994 uentry_whereDeclared (unew)))
8996 uentry_showWhereLastPlain (old);
9002 unew->info->datatype->abs = old->info->datatype->abs;
9004 if (ynm_isMaybe (unew->info->datatype->mut))
9006 if (completeConform && ynm_isOff (old->info->datatype->mut)
9007 && uentry_isReallySpecified (old))
9012 ("Datatype %q specified as immutable, "
9013 "but immutable annotation not used in declaration",
9014 uentry_getName (unew)),
9015 uentry_whereDeclared (unew)))
9017 uentry_showWhereLastPlain (old);
9021 unew->info->datatype->mut = old->info->datatype->mut;
9023 else if (ynm_isMaybe (old->info->datatype->mut))
9025 old->info->datatype->mut = unew->info->datatype->mut;
9029 if (ynm_isOn (old->info->datatype->abs))
9031 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
9035 message ("Datatype %q inconsistently %rdeclared as immutable",
9036 uentry_getName (unew),
9037 uentry_isDeclared (old)),
9038 uentry_whereDeclared (unew)))
9040 uentry_showWhereLastPlain (old);
9045 if (ynm_isOff (old->info->datatype->mut)
9046 && ynm_isOn (unew->info->datatype->mut))
9050 message ("Datatype %q inconsistently %rdeclared as mutable",
9051 uentry_getName (unew),
9052 uentry_isDeclared (old)),
9053 uentry_whereDeclared (unew)))
9055 uentry_showWhereLastPlain (old);
9060 old->info->datatype->mut = unew->info->datatype->mut;
9063 uentry_checkStateConformance (old, unew, mustConform, completeConform);
9067 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
9068 /*@notnull@*/ uentry unew,
9070 /*@unused@*/ bool completeConform)
9072 multiVal oldval = uentry_getConstantValue (old);
9073 multiVal newval = uentry_getConstantValue (unew);
9075 if (multiVal_isDefined (oldval))
9077 if (multiVal_isDefined (newval))
9079 if (!multiVal_equiv (oldval, newval))
9084 message ("%s %q %rdeclared with inconsistent value: %q",
9085 ekind_capName (unew->ukind),
9086 uentry_getName (unew),
9087 uentry_isDeclared (old),
9088 multiVal_unparse (newval)),
9089 uentry_whereDeclared (unew)))
9091 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9095 uentry_setConstantValue (unew, multiVal_copy (oldval));
9104 uentry_setConstantValue (old, multiVal_copy (newval));
9109 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9110 /*@notnull@*/ uentry unew, bool mustConform,
9111 bool completeConform)
9113 bool typeError = FALSE;
9114 bool fcnConformance = FALSE;
9116 if (!ekind_equal (unew->ukind, old->ukind))
9119 ** okay, only if one is a function and the other is
9120 ** a variable of type function.
9123 if (unew->ukind == KENUMCONST
9124 && old->ukind == KCONST)
9126 old->ukind = KENUMCONST;
9130 if (unew->ukind == KFCN
9131 && old->ukind == KCONST
9132 && ctype_isUnknown (old->utype))
9135 ** When a function is defined with an unparam macro
9138 uentry_updateInto (old, unew);
9142 if (uentry_isExpandedMacro (old)
9143 && uentry_isEitherConstant (unew))
9145 uentry_updateInto (old, unew);
9149 if (uentry_isEndIter (unew))
9151 if (ctype_isUnknown (old->utype))
9153 if (!uentry_isSpecified (old)
9154 && uentry_isCodeDefined (unew))
9156 if (!fileloc_withinLines (uentry_whereDefined (old),
9157 uentry_whereDeclared (unew), 2))
9158 { /* bogus! will give errors if there is too much whitespace */
9162 ("Iterator finalized name %q does not match name in "
9163 "previous iter declaration (should be end_%q). This iter "
9164 "is declared at %q",
9165 uentry_getName (unew),
9166 uentry_getName (old),
9167 fileloc_unparse (uentry_whereDefined (old))),
9168 uentry_whereDeclared (old));
9172 uentry_updateInto (old, unew);
9177 KindConformanceError (old, unew, mustConform);
9181 if (uentry_isFunction (unew))
9183 if (uentry_isVariable (old))
9185 if (!ctype_isUnknown (old->utype))
9187 if (ctype_isFunction (old->utype))
9189 uentry_makeVarFunction (old);
9190 checkFunctionConformance (old, unew, mustConform,
9192 fcnConformance = TRUE;
9196 KindConformanceError (old, unew, mustConform);
9201 if (uentry_isExpandedMacro (old))
9203 if (fileloc_isUndefined (unew->whereDefined))
9205 unew->whereDefined = fileloc_update (unew->whereDefined,
9209 uentry_updateInto (old, unew);
9210 old->used = unew->used = TRUE;
9215 /* undeclared identifier */
9216 old->utype = unew->utype;
9217 uentry_makeVarFunction (old);
9218 checkFunctionConformance (old, unew, FALSE, FALSE);
9219 fcnConformance = TRUE;
9225 KindConformanceError (old, unew, mustConform);
9228 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9230 if (!ctype_isUnknown (unew->utype))
9232 if (ctype_isFunction (unew->utype))
9234 uentry_makeVarFunction (unew);
9235 checkFunctionConformance (old, unew, mustConform, completeConform);
9236 fcnConformance = TRUE;
9240 KindConformanceError (old, unew, mustConform);
9245 KindConformanceError (old, unew, mustConform);
9250 KindConformanceError (old, unew, mustConform);
9256 ** check parameter lists for functions
9257 ** (before type errors, to get better messages
9260 if (uentry_isFunction (old))
9262 checkFunctionConformance (old, unew, mustConform, completeConform);
9263 fcnConformance = TRUE;
9267 if (!ctype_isUndefined (old->utype))
9269 typeError = checkTypeConformance (old, unew, mustConform);
9276 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9278 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9281 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9283 DPRINTF (("Check datatype: %s / %s",
9284 uentry_unparseFull (old),
9285 uentry_unparseFull (unew)));
9287 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9290 if (uentry_isVariable (old) && uentry_isVariable (unew))
9293 !ctype_matchDef (old->utype, unew->utype))
9298 ("Variable %q %s with inconsistent type (arrays and pointers are "
9299 "not identical in variable declarations): %t",
9300 uentry_getName (unew),
9301 uentry_reDefDecl (old, unew),
9303 uentry_whereDeclared (unew)))
9305 uentry_showWhereLast (old);
9308 ** Avoid repeated errors.
9311 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9313 old->whereDefined = fileloc_update (old->whereDefined,
9321 checkVarConformance (old, unew, mustConform, completeConform);
9326 /* old->utype = unew->utype; */
9330 if (ctype_isConj (old->utype))
9332 if (ctype_isConj (unew->utype))
9334 if (!ctype_sameAltTypes (old->utype, unew->utype))
9338 message ("%s %q inconsistently %rdeclared with "
9339 "alternate types %s "
9340 "(types match, but alternates are not identical, "
9341 "so checking may not be correct)",
9342 ekind_capName (uentry_getKind (old)),
9343 uentry_getName (unew),
9344 uentry_isDeclared (old),
9345 ctype_unparse (unew->utype)),
9346 uentry_whereDeclared (unew)))
9348 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9352 old->utype = unew->utype;
9359 if (ctype_isUnknown (old->utype))
9361 old->utype = unew->utype;
9366 if (unew->ukind == old->ukind)
9369 unew->info = uinfo_copy (old->info, old->ukind);
9372 sRef_storeState (old->sref);
9373 sRef_storeState (unew->sref);
9376 static void uentry_mergeConstraints (uentry spec, uentry def)
9378 if (uentry_isFunction (def))
9380 DPRINTF (("Here: %s / %s",
9381 uentry_unparseFull (spec),
9382 uentry_unparseFull (def)));
9383 /* evans 2001-07-21 */
9384 llassert (uentry_isFunction (spec));
9386 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9388 if (fileloc_isXHFile (uentry_whereLast (def)))
9390 llassert (uentry_isFunction (spec));
9391 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9392 def->info->fcn->preconditions);
9394 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9400 /* Check if the constraints are identical */
9405 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9406 uentry_getName (spec),
9407 functionConstraint_unparse (spec->info->fcn->preconditions)),
9408 uentry_whereLast (def)))
9410 uentry_showWhereSpecified (spec);
9413 functionConstraint_free (spec->info->fcn->preconditions);
9414 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9417 def->info->fcn->preconditions = functionConstraint_undefined;
9420 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9422 if (fileloc_isXHFile (uentry_whereLast (def)))
9424 llassert (uentry_isFunction (spec));
9425 DPRINTF (("Post: %s /++/ %s",
9426 functionConstraint_unparse (spec->info->fcn->postconditions),
9427 functionConstraint_unparse (def->info->fcn->postconditions)));
9428 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9429 def->info->fcn->postconditions);
9430 def->info->fcn->postconditions = functionConstraint_undefined;
9431 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9438 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9439 uentry_getName (spec),
9440 functionConstraint_unparse (spec->info->fcn->postconditions)),
9441 uentry_whereLast (def)))
9443 uentry_showWhereSpecified (spec);
9446 functionConstraint_free (spec->info->fcn->postconditions);
9447 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9448 def->info->fcn->postconditions = functionConstraint_undefined;
9455 ** modifies spec to reflect def, reports any inconsistencies
9459 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9461 llassert (uentry_isValid (spec));
9462 llassert (uentry_isValid (def));
9463 llassert (cstring_equal (spec->uname, def->uname));
9465 if (uentry_isFunction (def))
9467 if (uentry_isConstant (spec))
9469 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9470 uentry_makeConstantFunction (spec);
9474 uentry_convertVarFunction (spec);
9477 llassert (uentry_isFunction (spec));
9480 DPRINTF (("Merge entries: %s / %s",
9481 uentry_unparseFull (spec),
9482 uentry_unparseFull (def)));
9484 uentry_mergeConstraints (spec, def);
9486 uentry_checkConformance (spec, def, TRUE,
9487 context_getFlag (FLG_NEEDSPEC));
9489 DPRINTF (("Merge entries after conform: %s / %s",
9490 uentry_unparseFull (spec),
9491 uentry_unparseFull (def)));
9493 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9496 ** okay, declarations conform. Propagate extra information.
9499 uentry_setDefined (spec, uentry_whereDefined (def));
9500 uentry_setDeclared (spec, uentry_whereDeclared (def));
9502 if (uentry_isStatic (def))
9506 message ("%s %q specified, but declared as static",
9507 ekind_capName (def->ukind),
9508 uentry_getName (def)),
9509 uentry_whereDeclared (def)))
9511 uentry_showWhereSpecified (spec);
9516 spec->storageclass = def->storageclass;
9519 sRef_storeState (spec->sref);
9521 spec->used = def->used || spec->used;
9522 spec->hasNameError |= def->hasNameError;
9526 if (!spec->hasNameError)
9528 uentry_checkName (spec);
9536 /*drl added 4/02/2002*/
9538 uentry_printDecl (void)
9541 if (context_getFlag(FLG_GENERATECODE) )
9544 if (fileloc_isDotH(g_currentloc) )
9548 st = message ("%s", uentry_unparse(posRedeclared));
9549 outputCode(message( "%s", st));
9555 ** Can't generate function redeclaration errors when the
9556 ** entries are merged, since we don't yet know if its the
9557 ** definition of the function.
9561 uentry_clearDecl (void)
9563 posRedeclared = uentry_undefined;
9564 fileloc_free (posLoc);
9565 posLoc = fileloc_undefined;
9569 uentry_checkDecl (void)
9571 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9573 llassert (fileloc_isDefined (posLoc));
9575 if (uentry_isCodeDefined (posRedeclared))
9577 if (optgenerror (FLG_REDECL,
9578 message ("%s %q declared after definition",
9579 ekind_capName (posRedeclared->ukind),
9580 uentry_getName (posRedeclared)),
9583 llgenindentmsg (message ("Definition of %q",
9584 uentry_getName (posRedeclared)),
9585 posRedeclared->whereDeclared);
9590 if (optgenerror (FLG_REDECL,
9591 message ("%s %q declared more than once",
9592 ekind_capName (posRedeclared->ukind),
9593 uentry_getName (posRedeclared)),
9596 llgenindentmsg (message ("Previous declaration of %q",
9597 uentry_getName (posRedeclared)),
9598 posRedeclared->whereDeclared);
9603 fileloc_free (posLoc);
9604 posLoc = fileloc_undefined;
9605 posRedeclared = uentry_undefined;
9609 ** Redefinition of old as unew.
9610 ** modifies old to reflect unew, reports any inconsistencies
9614 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9616 fileloc olddef = uentry_whereDeclared (old);
9617 fileloc unewdef = uentry_whereDeclared (unew);
9621 DPRINTF (("uentry merge: %s / %s",
9622 uentry_unparseFull (old),
9623 uentry_unparseFull (unew)));
9626 fileloc_isUndefined (olddef)
9627 && fileloc_isDefined (uentry_whereDefined (old))
9628 && !uentry_isExpandedMacro (old);
9630 if (!context_getFlag (FLG_INCONDEFSLIB)
9631 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9633 mustConform = FALSE;
9640 llassert (uentry_isValid (old));
9641 llassert (uentry_isValid (unew));
9642 llassert (cstring_equal (old->uname, unew->uname));
9644 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9646 if (uentry_isConstant (old))
9648 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9649 uentry_makeConstantFunction (old);
9653 uentry_convertVarFunction (old);
9656 llassert (uentry_isFunction (old));
9659 DPRINTF (("uentry merge: %s / %s",
9660 uentry_unparseFull (old),
9661 uentry_unparseFull (unew)));
9663 if (uentry_isExtern (unew))
9665 uentry_setUsed (old, unewdef);
9669 ** should check old one was extern!
9672 if (uentry_isStatic (old))
9674 if (!(uentry_isStatic (unew)))
9678 message ("%s %q shadows static declaration",
9679 ekind_capName (unew->ukind),
9680 uentry_getName (unew)),
9683 uentry_showWhereLast (old);
9688 uentry_setDeclDef (old, unewdef);
9691 else if (uentry_isStatic (unew))
9693 uentry_setDeclDef (old, unewdef);
9695 else if (uentry_isExtern (old))
9697 uentry_setDeclared (old, unewdef);
9701 if (!uentry_isExtern (unew)
9702 && !uentry_isForward (old)
9703 && !fileloc_equal (olddef, unewdef)
9704 && !fileloc_isUndefined (olddef)
9705 && !fileloc_isUndefined (unewdef)
9706 && !fileloc_isBuiltin (olddef)
9707 && !fileloc_isBuiltin (unewdef)
9708 && !uentry_isYield (old)
9709 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9711 if (uentry_isVariable (old) || uentry_isVariable (unew))
9713 ; /* will report redeclaration error later */
9717 if (fileloc_isDefined (uentry_whereDefined (old)))
9721 message ("%s %q defined more than once",
9722 ekind_capName (unew->ukind),
9723 uentry_getName (unew)),
9724 uentry_whereLast (unew)))
9727 (message ("Previous definition of %q",
9728 uentry_getName (old)),
9729 uentry_whereLast (old));
9732 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9734 uentry_updateInto (old, unew);
9735 old->sref = sRef_saveCopy (old->sref);
9743 if (fileloc_isLib (olddef)
9744 || fileloc_isUndefined (olddef)
9745 || fileloc_isImport (olddef))
9747 if (uentry_isExtern (unew))
9749 if (uentry_isExtern (old)
9750 || (fileloc_isDefined (uentry_whereDeclared (old))
9751 && (!fileloc_equal (uentry_whereDeclared (old),
9752 uentry_whereDefined (old)))))
9756 message ("%s %q declared more than once",
9757 ekind_capName (unew->ukind),
9758 uentry_getName (unew)),
9759 unew->whereDeclared))
9762 (message ("Previous declaration of %q",
9763 uentry_getName (old)),
9764 old->whereDeclared);
9768 uentry_setExtern (old);
9772 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9778 DPRINTF (("uentry merge: %s / %s",
9779 uentry_unparseFull (old),
9780 uentry_unparseFull (unew)));
9782 uentry_mergeConstraints (old, unew);
9783 DPRINTF (("uentry merge: %s / %s",
9784 uentry_unparseFull (old),
9785 uentry_unparseFull (unew)));
9787 uentry_checkConformance (old, unew, mustConform, FALSE);
9788 DPRINTF (("uentry merge: %s / %s",
9789 uentry_unparseFull (old),
9790 uentry_unparseFull (unew)));
9792 old->used = old->used || unew->used;
9793 old->uses = filelocList_append (old->uses, unew->uses);
9794 unew->uses = filelocList_undefined;
9796 sRef_storeState (old->sref);
9797 sRef_storeState (unew->sref);
9801 old->whereDefined = fileloc_update (old->whereDefined,
9805 DPRINTF (("here: %s", uentry_unparseFull (old)));
9808 ** No redeclaration errors for functions here, since we
9809 ** don't know if this is the definition of the function.
9812 if (fileloc_isUser (old->whereDeclared)
9813 && fileloc_isUser (unew->whereDeclared)
9814 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9815 && !fileloc_isDefined (unew->whereDefined))
9817 if (uentry_isFunction (old))
9819 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9820 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9824 if (optgenerror (FLG_REDECL,
9825 message ("%s %q declared more than once",
9826 ekind_capName (unew->ukind),
9827 uentry_getName (unew)),
9828 unew->whereDeclared))
9830 llgenindentmsg (message ("Previous declaration of %q",
9831 uentry_getName (old)),
9832 old->whereDeclared);
9837 if (fileloc_isUndefined (old->whereDefined))
9839 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9843 if (!context_processingMacros ()
9844 && fileloc_isUser (old->whereDefined)
9845 && fileloc_isUser (unew->whereDefined)
9846 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9848 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9850 if (uentry_isVariable (unew)
9851 && uentry_isExtern (unew))
9853 if (optgenerror (FLG_REDECL,
9854 message ("%s %q declared after definition",
9855 ekind_capName (unew->ukind),
9856 uentry_getName (unew)),
9857 unew->whereDeclared))
9859 llgenindentmsg (message ("Definition of %q",
9860 uentry_getName (old)),
9866 if (optgenerror (FLG_REDEF,
9867 message ("%s %q redefined",
9868 ekind_capName (unew->ukind),
9869 uentry_getName (unew)),
9870 unew->whereDefined))
9872 llgenindentmsg (message ("Previous definition of %q",
9873 uentry_getName (old)),
9881 if (uentry_isExternal (unew))
9883 old->whereDefined = fileloc_createExternal ();
9886 if (unew->hasNameError)
9888 old->hasNameError = TRUE;
9893 if (!old->hasNameError)
9895 uentry_checkName (old);
9898 DPRINTF (("After: %s", uentry_unparseFull (old)));
9899 llassert (!ctype_isUndefined (old->utype));
9903 uentry_copyState (uentry res, uentry other)
9905 llassert (uentry_isValid (res));
9906 llassert (uentry_isValid (other));
9908 res->used = other->used;
9910 res->info->var->kind = other->info->var->kind;
9911 res->info->var->defstate = other->info->var->defstate;
9912 res->info->var->nullstate = other->info->var->nullstate;
9913 res->info->var->checked = other->info->var->checked;
9915 sRef_copyState (res->sref, other->sref);
9919 uentry_sameKind (uentry u1, uentry u2)
9921 if (uentry_isValid (u1) && uentry_isValid (u2))
9923 if (uentry_isVar (u1) && uentry_isVar (u2))
9925 ctype c1 = u1->utype;
9926 ctype c2 = u2->utype;
9928 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9931 ** both functions, or both not functions
9934 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9938 return ((u1->ukind == u2->ukind));
9945 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9948 llassert (uentry_isValid (unew));
9949 llassert (uentry_isValid (old));
9951 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9952 okind = unew->ukind;
9953 unew->ukind = old->ukind;
9954 llassert (cstring_equal (unew->uname, old->uname));
9955 unew->utype = old->utype;
9957 if (fileloc_isDefined (unew->whereSpecified)
9958 && !fileloc_isDefined (old->whereSpecified))
9960 ; /* Keep the old value */
9964 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9965 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9968 if (fileloc_isDefined (unew->whereDefined)
9969 && !fileloc_isDefined (old->whereDefined))
9971 ; /* Keep the old value */
9975 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9976 unew->whereDefined = fileloc_copy (old->whereDefined);
9979 if (fileloc_isDefined (unew->whereDeclared)
9980 && !fileloc_isDefined (old->whereDeclared))
9982 ; /* Keep the old value */
9986 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9987 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9990 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9992 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9993 unew->used = old->used;
9995 unew->isPrivate = old->isPrivate;
9996 unew->hasNameError = old->hasNameError;
9997 unew->uses = filelocList_append (unew->uses, old->uses);
9998 old->uses = filelocList_undefined;
10000 unew->storageclass = old->storageclass;
10001 uinfo_free (unew->info, okind);
10002 unew->info = uinfo_copy (old->info, old->ukind);
10007 uentry_copy (uentry e)
10009 if (uentry_isValid (e))
10011 uentry enew = uentry_alloc ();
10012 DPRINTF (("copy: %s", uentry_unparseFull (e)));
10013 enew->ukind = e->ukind;
10014 enew->uname = cstring_copy (e->uname);
10015 enew->utype = e->utype;
10017 enew->whereSpecified = fileloc_copy (e->whereSpecified);
10018 enew->whereDefined = fileloc_copy (e->whereDefined);
10019 enew->whereDeclared = fileloc_copy (e->whereDeclared);
10021 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
10022 enew->used = e->used;
10023 enew->lset = FALSE;
10024 enew->isPrivate = e->isPrivate;
10025 enew->hasNameError = e->hasNameError;
10026 enew->uses = filelocList_undefined;
10028 enew->storageclass = e->storageclass;
10029 enew->info = uinfo_copy (e->info, e->ukind);
10030 enew->warn = warnClause_copy (e->warn);
10032 enew->cQuals = qualList_copy(e->cQuals);
10034 DPRINTF (("Here we are..."));
10035 DPRINTF (("original: %s", uentry_unparseFull (e)));
10036 DPRINTF (("copy: %s", uentry_unparse (enew)));
10037 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
10042 return uentry_undefined;
10047 uentry_setState (uentry res, uentry other)
10049 llassert (uentry_isValid (res));
10050 llassert (uentry_isValid (other));
10052 llassert (res->ukind == other->ukind);
10053 llassert (res->ukind == KVAR);
10055 res->sref = sRef_saveCopy (other->sref);
10056 res->used = other->used;
10057 filelocList_free (res->uses);
10058 res->uses = other->uses;
10059 other->uses = filelocList_undefined;
10060 res->lset = other->lset;
10064 uentry_mergeUses (uentry res, uentry other)
10066 llassert (uentry_isValid (res));
10067 llassert (uentry_isValid (other));
10069 res->used = other->used || res->used;
10070 res->lset = other->lset || res->lset;
10071 res->uses = filelocList_append (res->uses, other->uses);
10072 other->uses = filelocList_undefined;
10077 ** This is a really ugly routine.
10079 ** gack...fix this one day.
10084 ** >> res is the false branch, other is the true branch (or continuation)
10086 ** >> res is the true branch, other is the false branch (or continutation)
10093 ** References not effected by res are propagated from other.
10097 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10098 bool flip, clause cl, fileloc loc)
10102 message ("%s %q is %s %s, but %s %s.",
10103 ekind_capName (res->ukind), uentry_getName (res),
10104 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10105 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10108 if (sRef_isDead (res->sref))
10110 sRef_showStateInfo (res->sref);
10111 sRef_showStateInfo (other->sref);
10113 else if (sRef_isKept (res->sref))
10115 sRef_showAliasInfo (res->sref);
10116 sRef_showAliasInfo (other->sref);
10118 else /* dependent */
10120 sRef_showAliasInfo (res->sref);
10121 sRef_showAliasInfo (other->sref);
10124 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10128 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10130 alkind rk = sRef_getAliasKind (rs);
10131 alkind ok = sRef_getAliasKind (os);
10133 if (alkind_isError (rk) || alkind_isError (ok))
10139 return ((sRef_isDead (rs)
10140 || (alkind_isKept (rk) && !alkind_isKept (ok))
10141 || (alkind_isDependent (rk)
10142 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10143 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10148 branchStateAltError (/*@notnull@*/ uentry res,
10149 /*@notnull@*/ uentry other, bool flip,
10150 clause cl, fileloc loc)
10154 message ("%s %q is %s %s, but %s %s.",
10155 ekind_capName (res->ukind), uentry_getName (res),
10156 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10157 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10160 if (sRef_isDead (other->sref))
10162 sRef_showStateInfo (other->sref);
10166 sRef_showAliasInfo (other->sref);
10169 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10170 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10172 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10173 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10178 ** A reference is relevant for certain checks, only if it
10179 ** is not definitely null on this path (but not declared
10180 ** to always be null.)
10183 static bool uentry_relevantReference (sRef sr, bool flip)
10185 if (sRef_isKept (sr) || sRef_isDependent (sr))
10193 return !sRef_definitelyNullContext (sr);
10197 return !sRef_definitelyNullAltContext (sr);
10203 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10204 fileloc loc, bool mustReturn, bool flip, bool opt,
10207 sRef rs = res->sref;
10208 sRef os = other->sref;
10210 DPRINTF (("Merge alias states: %s / %s",
10211 uentry_unparseFull (res),
10212 uentry_unparseFull (other)));
10214 if (sRef_isValid (rs))
10218 if (uentry_incompatibleMemoryStates (rs, os))
10220 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10221 sRef_unparseFull (rs), sRef_unparseFull (os)));
10223 if (sRef_isThroughArrayFetch (rs)
10224 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10226 if (sRef_isKept (rs) || sRef_isKept (os))
10228 sRef_maybeKill (rs, loc);
10230 else if (sRef_isPossiblyDead (os))
10232 sRef_maybeKill (rs, loc);
10241 if (uentry_relevantReference (os, flip))
10243 if (sRef_isLocalParamVar (rs)
10244 && (sRef_isLocalState (os)
10245 || sRef_isDependent (os)))
10247 if (sRef_isDependent (rs))
10249 sRef_setDependent (os, loc);
10253 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10258 branchStateError (res, other, flip, cl, loc);
10263 if (sRef_isKept (rs))
10265 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10266 sRef_setKept (os, loc);
10271 if (uentry_incompatibleMemoryStates (os, rs))
10273 if (uentry_relevantReference (rs, !flip))
10275 if (sRef_isLocalParamVar (rs)
10276 && (sRef_isDependent (rs)
10277 || sRef_isLocalState (rs)))
10279 if (sRef_isDependent (os))
10281 sRef_setDependent (rs, loc);
10285 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10290 if (sRef_isParam (os))
10293 ** If the local variable associated
10294 ** with the param has the correct state,
10296 ** (e.g., free (s); s = new(); ...
10299 uentry uvar = usymtab_lookupSafe (other->uname);
10301 if (uentry_isValid (uvar)
10302 && ((sRef_isDead (os)
10303 && sRef_isOnly (uvar->sref))
10304 || (sRef_isDependent (os)
10305 && sRef_isOwned (uvar->sref))))
10311 branchStateAltError (res, other,
10317 DPRINTF (("Here: %s / %s",
10318 uentry_unparseFull (res),
10319 uentry_unparseFull (other)));
10321 branchStateAltError (res, other,
10328 if (sRef_isKept (os))
10330 sRef_setKept (rs, loc);
10336 DPRINTF (("Merge opt..."));
10337 sRef_mergeOptState (rs, os, cl, loc);
10338 DPRINTF (("Done!"));
10342 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10343 sRef_mergeState (rs, os, cl, loc);
10344 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10349 if (sRef_isModified (os))
10351 sRef_setModified (rs);
10356 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10360 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10361 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10363 valueTable rvalues;
10364 valueTable ovalues;
10366 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10374 rvalues = sRef_getValueTable (res->sref);
10375 ovalues = sRef_getValueTable (other->sref);
10377 if (valueTable_isUndefined (ovalues))
10379 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10382 else if (valueTable_isUndefined (rvalues))
10385 ** Copy values from other
10389 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10390 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10395 valueTable_elements (ovalues, fkey, fval) {
10397 metaStateInfo minfo;
10398 stateCombinationTable sctable;
10402 tval = valueTable_lookup (rvalues, fkey);
10404 DPRINTF (("Merge value: %s / %s X %s", fkey,
10405 stateValue_unparse (fval), stateValue_unparse (tval)));
10407 minfo = context_lookupMetaStateInfo (fkey);
10408 llassert (stateValue_isDefined (tval));
10410 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10412 DPRINTF (("Cannot find meta state for: %s", fkey));
10417 llassert (metaStateInfo_isDefined (minfo));
10419 if (stateValue_isError (fval)
10420 || sRef_definitelyNullContext (res->sref))
10422 sRef_setMetaStateValueComplete (res->sref,
10423 fkey, stateValue_getValue (fval),
10424 stateValue_getLoc (fval));
10425 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10427 else if (stateValue_isError (tval)
10428 || sRef_definitelyNullAltContext (other->sref))
10430 DPRINTF (("Other branch is definitely null!"));
10432 else if (sRef_isStateUndefined (res->sref)
10433 || sRef_isDead (res->sref))
10435 ; /* Combination state doesn't matter if it is undefined or dead */
10439 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10440 metaStateInfo_unparse (minfo),
10441 stateValue_unparse (fval),
10442 stateValue_unparse (tval)));
10444 DPRINTF (("state values: %d / %d",
10445 stateValue_getValue (fval), stateValue_getValue (tval)));
10447 sctable = metaStateInfo_getMergeTable (minfo);
10449 DPRINTF (("Merge table: %s",
10450 stateCombinationTable_unparse (sctable)));
10452 msg = cstring_undefined;
10454 nval = stateCombinationTable_lookup (sctable,
10455 stateValue_getValue (fval),
10456 stateValue_getValue (tval),
10459 DPRINTF (("nval: %d / %d / %d", nval,
10460 stateValue_getValue (fval), stateValue_getValue (tval)));
10462 if (nval == stateValue_error)
10464 /*@i32 print extra info for assignments@*/
10466 if (uentry_isGlobalMarker (res))
10471 ("Control branches merge with incompatible global states (%s and %s)%q",
10472 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10473 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10474 cstring_isDefined (msg)
10475 ? message (": %s", msg) : cstring_undefined),
10478 sRef_showMetaStateInfo (res->sref, fkey);
10479 sRef_showMetaStateInfo (other->sref, fkey);
10487 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10488 uentry_getName (res),
10489 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10490 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10491 cstring_isDefined (msg)
10492 ? message (": %s", msg) : cstring_undefined),
10495 sRef_showMetaStateInfo (res->sref, fkey);
10496 sRef_showMetaStateInfo (other->sref, fkey);
10497 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10498 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10499 DPRINTF (("Null: %s / %s",
10500 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10501 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10507 if (nval == stateValue_getValue (fval)
10508 && nval != stateValue_getValue (tval))
10510 loc = stateValue_getLoc (fval);
10512 else if (nval == stateValue_getValue (tval)
10513 && nval != stateValue_getValue (fval))
10515 loc = stateValue_getLoc (tval);
10522 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10523 && nval == stateValue_getValue (fval)
10524 && nval == stateValue_getValue (tval))
10530 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10534 } end_valueTable_elements ;
10540 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10541 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10542 bool flip, clause cl)
10544 if (cl == DOWHILECLAUSE)
10546 res->used = other->used || res->used;
10547 res->lset = other->lset || res->lset;
10548 res->uses = filelocList_append (res->uses, other->uses);
10549 other->uses = filelocList_undefined;
10553 if (sRef_isMacroParamRef (res->sref)
10554 && !uentry_isSefParam (other)
10555 && !uentry_isSefParam (res))
10557 bool hasError = FALSE;
10559 if (bool_equal (res->used, other->used))
10561 res->used = other->used;
10565 if (other->used && !flip)
10570 message ("Macro parameter %q used in true clause, "
10571 "but not in false clause",
10572 uentry_getName (res)),
10573 uentry_whereDeclared (res));
10580 message ("Macro parameter %q used in false clause, "
10581 "but not in true clause",
10582 uentry_getName (res)),
10583 uentry_whereDeclared (res));
10589 /* make it sef now, prevent more errors */
10590 res->info->var->kind = VKREFSEFPARAM;
10596 res->used = other->used || res->used;
10597 res->lset = other->lset || res->lset;
10598 res->uses = filelocList_append (res->uses, other->uses);
10599 other->uses = filelocList_undefined;
10605 uentry_mergeState (uentry res, uentry other, fileloc loc,
10606 bool mustReturn, bool flip, bool opt,
10609 llassert (uentry_isValid (res));
10610 llassert (uentry_isValid (other));
10612 llassert (res->ukind == other->ukind);
10613 llassert (res->ukind == KVAR);
10615 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10616 uentry_unparseFull (other)));
10618 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10619 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10620 uentry_mergeSetStates (res, other, loc, flip, cl);
10622 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10625 void uentry_setUsed (uentry e, fileloc loc)
10627 static bool firstTime = TRUE;
10628 static bool showUses = FALSE;
10629 static bool exportLocal = FALSE;
10631 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10635 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10637 showUses = context_getFlag (FLG_SHOWUSES);
10638 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10643 if (uentry_isValid (e))
10647 if (warnClause_isDefined (e->warn))
10649 flagSpec flg = warnClause_getFlag (e->warn);
10652 if (warnClause_hasMessage (e->warn))
10654 msg = cstring_copy (warnClause_getMessage (e->warn));
10658 msg = message ("Use of possibly dangerous %s",
10659 uentry_ekindNameLC (e));
10663 message ("%q: %q", msg, uentry_getName (e)),
10667 if (sRef_isMacroParamRef (e->sref))
10669 if (uentry_isYield (e) || uentry_isSefParam (e))
10675 if (context_inConditional ())
10679 message ("Macro parameter %q used in conditionally "
10680 "executed code (may or may not be "
10681 "evaluated exactly once)",
10682 uentry_getName (e)),
10685 e->info->var->kind = VKREFSEFPARAM;
10694 message ("Macro parameter %q used more than once",
10695 uentry_getName (e)),
10696 uentry_whereDeclared (e)))
10698 e->info->var->kind = VKREFSEFPARAM;
10705 if ((dp = uentry_directParamNo (e)) >= 0)
10707 uentry_setUsed (usymtab_getParam (dp), loc);
10712 if (!sRef_isLocalVar (e->sref))
10716 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10722 if (context_inMacro ())
10724 e->uses = filelocList_addUndefined (e->uses);
10728 e->uses = filelocList_addDifferentFile
10730 uentry_whereDeclared (e),
10739 bool uentry_isReturned (uentry u)
10741 return (uentry_isValid (u) && uentry_isVar (u)
10742 && (u->info->var->kind == VKRETPARAM
10743 || u->info->var->kind == VKSEFRETPARAM));
10748 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10750 llassert (uentry_isRealFunction (u));
10752 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10754 stateClauseList clauses = uentry_getStateClauseList (u);
10755 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10757 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10758 sRef_setAllocated (res, g_currentloc);
10760 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10761 stateClauseList_unparse (clauses)));
10764 ** This should be in exprNode_reflectEnsuresClause
10767 stateClauseList_postElements (clauses, cl)
10769 if (!stateClause_isGlobal (cl))
10771 sRefSet refs = stateClause_getRefs (cl);
10772 sRefMod modf = stateClause_getEffectFunction (cl);
10774 sRefSet_elements (refs, el)
10776 sRef base = sRef_getRootBase (el);
10778 if (sRef_isResult (base))
10782 sRef sr = sRef_fixBase (el, res);
10783 modf (sr, g_currentloc);
10790 } end_sRefSet_elements ;
10792 } end_stateClauseList_postElements ;
10800 sRefSet prefs = sRefSet_new ();
10801 sRef res = sRef_undefined;
10802 sRef tcref = sRef_undefined;
10803 sRef tref = sRef_undefined;
10806 params = uentry_getParams (u);
10809 ** Setting up aliases has to happen *after* setting null state!
10812 uentryList_elements (params, current)
10814 if (uentry_isReturned (current))
10816 if (exprNodeList_size (args) >= paramno)
10818 exprNode ecur = exprNodeList_nth (args, paramno);
10819 tref = exprNode_getSref (ecur);
10821 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10823 if (sRef_isValid (tref))
10825 tcref = sRef_copy (tref);
10827 if (sRef_isDead (tcref))
10829 sRef_setDefined (tcref, g_currentloc);
10830 sRef_setOnly (tcref, g_currentloc);
10833 if (sRef_isRefCounted (tcref))
10835 /* could be a new ref now (but only if its returned) */
10836 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10839 sRef_makeSafe (tcref);
10840 prefs = sRefSet_insert (prefs, tcref);
10846 } end_uentryList_elements ;
10848 if (sRefSet_size (prefs) > 0)
10850 nstate n = sRef_getNullState (u->sref);
10852 if (sRefSet_size (prefs) == 1)
10854 sRef rref = sRefSet_choose (prefs);
10856 res = sRef_makeType (sRef_getType (rref));
10857 sRef_copyState (res, tref);
10861 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10862 res = sRefSet_mergeIntoOne (prefs);
10865 if (nstate_isKnown (n))
10867 sRef_setNullState (res, n, g_currentloc);
10868 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10873 if (ctype_isFunction (u->utype))
10875 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10876 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10880 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10881 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10884 if (sRef_isRefCounted (res))
10886 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10890 if (sRef_getNullState (res) == NS_ABSNULL)
10892 ctype ct = ctype_realType (u->utype);
10894 if (ctype_isAbstract (ct))
10896 sRef_setNotNull (res, g_currentloc);
10900 if (ctype_isUser (ct))
10902 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10906 sRef_setNotNull (res, g_currentloc);
10911 if (sRef_isRefCounted (res))
10913 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10915 else if (sRef_isKillRef (res))
10917 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10924 ak = sRef_getAliasKind (res);
10926 if (alkind_isImplicit (ak))
10928 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10932 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10933 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10935 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10936 usymtab_addReallyForceMustAlias (res, tref);
10939 sRefSet_free (prefs);
10941 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10947 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10949 llassert (uentry_isRealFunction (u));
10951 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10953 stateClauseList clauses = uentry_getStateClauseList (u);
10954 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10956 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10957 sRef_setAllocated (res, g_currentloc);
10959 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10960 stateClauseList_unparse (clauses)));
10963 ** This should be in exprNode_reflectEnsuresClause
10966 stateClauseList_postElements (clauses, cl)
10968 if (!stateClause_isGlobal (cl))
10970 sRefSet refs = stateClause_getRefs (cl);
10971 sRefMod modf = stateClause_getEffectFunction (cl);
10973 sRefSet_elements (refs, el)
10975 sRef base = sRef_getRootBase (el);
10977 if (sRef_isResult (base))
10981 sRef sr = sRef_fixBase (el, res);
10982 modf (sr, g_currentloc);
10989 } end_sRefSet_elements ;
10991 } end_stateClauseList_postElements ;
10999 sRefSet prefs = sRefSet_new ();
11000 sRef res = sRef_undefined;
11003 params = uentry_getParams (u);
11005 uentryList_elements (params, current)
11007 if (uentry_isReturned (current))
11009 if (exprNodeList_size (args) >= paramno)
11011 exprNode ecur = exprNodeList_nth (args, paramno);
11012 sRef tref = exprNode_getSref (ecur);
11014 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
11016 if (sRef_isValid (tref))
11018 sRef tcref = sRef_copy (tref);
11020 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
11022 if (sRef_isDead (tcref))
11024 sRef_setDefined (tcref, g_currentloc);
11025 sRef_setOnly (tcref, g_currentloc);
11028 if (sRef_isRefCounted (tcref))
11030 /* could be a new ref now (but only if its returned) */
11031 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
11034 sRef_makeSafe (tcref);
11035 prefs = sRefSet_insert (prefs, tcref);
11041 } end_uentryList_elements ;
11043 if (sRefSet_size (prefs) > 0)
11045 nstate n = sRef_getNullState (u->sref);
11047 if (sRefSet_size (prefs) == 1)
11049 res = sRefSet_choose (prefs);
11053 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
11054 res = sRefSet_mergeIntoOne (prefs);
11057 if (nstate_isKnown (n))
11059 sRef_setNullState (res, n, g_currentloc);
11064 if (ctype_isFunction (u->utype))
11066 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
11067 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
11071 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
11074 if (sRef_isRefCounted (res))
11076 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
11081 if (sRef_getNullState (res) == NS_ABSNULL)
11083 ctype ct = ctype_realType (u->utype);
11085 if (ctype_isAbstract (ct))
11087 sRef_setNotNull (res, g_currentloc);
11091 if (ctype_isUser (ct))
11093 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
11097 sRef_setNotNull (res, g_currentloc);
11102 if (sRef_isRefCounted (res))
11104 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
11106 else if (sRef_isKillRef (res))
11108 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
11115 ak = sRef_getAliasKind (res);
11117 if (alkind_isImplicit (ak))
11119 sRef_setAliasKind (res,
11120 alkind_fixImplicit (ak),
11124 sRefSet_free (prefs);
11126 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11131 static bool uentry_isRefCounted (uentry ue)
11133 ctype ct = uentry_getType (ue);
11135 if (ctype_isFunction (ct))
11137 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11141 return (ctype_isRefCounted (ct));
11146 ** old was declared yield in the specification.
11147 ** new is declared in the iter implementation.
11150 void uentry_checkYieldParam (uentry old, uentry unew)
11154 llassert (uentry_isVariable (old));
11155 llassert (uentry_isVariable (unew));
11157 unew->info->var->kind = VKYIELDPARAM;
11158 (void) checkTypeConformance (old, unew, TRUE);
11159 checkVarConformance (old, unew, TRUE, FALSE);
11161 /* get rid of param marker */
11163 name = uentry_getName (unew);
11164 cstring_free (unew->uname);
11165 unew->uname = name;
11166 unew->info->var->kind = VKREFYIELDPARAM;
11168 uentry_setUsed (old, fileloc_undefined);
11169 uentry_setUsed (unew, fileloc_undefined);
11172 /*@observer@*/ cstring
11173 uentry_ekindName (uentry ue)
11175 if (uentry_isValid (ue))
11180 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11182 return cstring_makeLiteralTemp ("Datatype");
11184 return cstring_makeLiteralTemp ("Enum member");
11186 return cstring_makeLiteralTemp ("Constant");
11188 if (uentry_isParam (ue))
11190 return cstring_makeLiteralTemp ("Parameter");
11192 else if (uentry_isExpandedMacro (ue))
11194 return cstring_makeLiteralTemp ("Expanded macro");
11198 return cstring_makeLiteralTemp ("Variable");
11201 return cstring_makeLiteralTemp ("Function");
11203 return cstring_makeLiteralTemp ("Iterator");
11205 return cstring_makeLiteralTemp ("Iterator finalizer");
11207 return cstring_makeLiteralTemp ("Struct tag");
11209 return cstring_makeLiteralTemp ("Union tag");
11211 return cstring_makeLiteralTemp ("Enum tag");
11213 return cstring_makeLiteralTemp ("Optional parameters");
11218 return cstring_makeLiteralTemp ("<Undefined>");
11224 /*@observer@*/ cstring
11225 uentry_ekindNameLC (uentry ue)
11227 if (uentry_isValid (ue))
11232 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11234 return cstring_makeLiteralTemp ("datatype");
11236 return cstring_makeLiteralTemp ("enum member");
11238 return cstring_makeLiteralTemp ("constant");
11240 if (uentry_isParam (ue))
11242 return cstring_makeLiteralTemp ("parameter");
11244 else if (uentry_isExpandedMacro (ue))
11246 return cstring_makeLiteralTemp ("expanded macro");
11250 return cstring_makeLiteralTemp ("variable");
11253 return cstring_makeLiteralTemp ("function");
11255 return cstring_makeLiteralTemp ("iterator");
11257 return cstring_makeLiteralTemp ("iterator finalizer");
11259 return cstring_makeLiteralTemp ("struct tag");
11261 return cstring_makeLiteralTemp ("union tag");
11263 return cstring_makeLiteralTemp ("enum tag");
11265 return cstring_makeLiteralTemp ("optional parameters");
11270 return cstring_makeLiteralTemp ("<Undefined>");
11276 void uentry_setHasNameError (uentry ue)
11278 llassert (uentry_isValid (ue));
11280 ue->hasNameError = TRUE;
11283 void uentry_checkName (uentry ue)
11285 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11286 uentry_observeRealName (ue),
11287 bool_unparse (uentry_isVisibleExternally (ue))));
11289 if (uentry_isValid (ue)
11290 && !context_inXHFile ()
11291 && uentry_hasName (ue)
11292 && !uentry_isElipsisMarker (ue)
11293 && context_getFlag (FLG_NAMECHECKS)
11294 && !ue->hasNameError
11295 && !uentry_isEndIter (ue)
11296 && !fileloc_isBuiltin (uentry_whereLast (ue))
11297 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11299 DPRINTF (("Here..."));
11301 if (uentry_isPriv (ue))
11303 ; /* any checks here? */
11305 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11307 ; /* no errors for externals */
11313 if (uentry_isExpandedMacro (ue))
11319 if (uentry_isExpandedMacro (ue))
11323 else if (uentry_isVariable (ue))
11325 sRef sr = uentry_getSref (ue);
11327 if (sRef_isValid (sr))
11329 scope = sRef_getScope (sr);
11336 else if (uentry_isFunction (ue)
11337 || uentry_isIter (ue)
11338 || uentry_isEndIter (ue)
11339 || uentry_isConstant (ue))
11341 scope = uentry_isStatic (ue) ? fileScope : globScope;
11343 else /* datatypes, etc. must be global */
11348 usymtab_checkDistinctName (ue, scope);
11351 if (context_getFlag (FLG_CPPNAMES))
11356 if (scope == globScope)
11358 checkExternalName (ue);
11360 else if (scope == fileScope)
11362 checkFileScopeName (ue);
11366 checkLocalName (ue);
11370 checkAnsiName (ue);
11375 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11381 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11384 if (!context_inMacro ())
11386 sRef_setGlobalScopeSafe ();
11389 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11390 uentry_setUsed (ue, loc);
11392 tloc = fileloc_createExternal ();
11393 uentry_setDefined (ue, tloc);
11394 fileloc_free (tloc);
11395 uentry_setHasNameError (ue);
11397 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11399 uentry_markOwned (ue);
11403 ue = usymtab_supReturnFileEntry (ue);
11406 if (!context_inMacro ())
11408 sRef_clearGlobalScopeSafe ();
11414 uentry uentry_makeGlobalMarker ()
11419 llassert (sRef_inGlobalScope ());
11421 ue = uentry_makeVariableAux
11422 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11423 sRef_makeGlobalMarker (),
11426 tloc = fileloc_createExternal ();
11427 uentry_setUsed (ue, tloc);
11428 uentry_setDefined (ue, tloc);
11429 fileloc_free (tloc);
11430 uentry_setHasNameError (ue);
11436 bool uentry_isGlobalMarker (uentry ue)
11438 return (uentry_isValid (ue)
11439 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11442 /* new start modifications */
11444 /* start modifications */
11446 requires: p_e is defined, is a ptr/array variable
11448 effects: sets the state of the variable
11452 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11454 llassert (uentry_isValid (p_e));
11456 if (p_e->info != NULL)
11458 if (p_e->info->var != NULL)
11460 llassert (p_e->info->var->bufinfo != NULL);
11461 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11462 sRef_setPossiblyNullTerminatedState (p_e->sref);
11468 requires: p_e is defined, is a ptr/array variable
11470 effects: sets the size of the buffer
11473 void uentry_setNullTerminatedState (uentry p_e) {
11474 llassert (uentry_isValid (p_e));
11476 if (p_e->info != NULL)
11478 if (p_e->info->var != NULL)
11480 llassert (p_e->info->var->bufinfo != NULL);
11481 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11482 sRef_setNullTerminatedState (p_e->sref);
11488 requires: p_e is defined, is a ptr/array variable
11490 effects: sets the size of the buffer
11493 void uentry_setSize (uentry p_e, int size)
11495 if (uentry_isValid (p_e))
11497 if (p_e->info != NULL)
11499 if (p_e->info->var != NULL)
11501 llassert (p_e->info->var->bufinfo != NULL);
11502 p_e->info->var->bufinfo->size = size;
11503 sRef_setSize (p_e->sref, size);
11510 requires: p_e is defined, is a ptr/array variable
11512 effects: sets the length of the buffer
11515 void uentry_setLen (uentry p_e, int len)
11517 if (uentry_isValid (p_e))
11519 if (p_e->info != NULL
11520 && p_e->info->var != NULL)
11522 llassert (p_e->info->var->bufinfo != NULL);
11523 p_e->info->var->bufinfo->len = len;
11524 sRef_setLen (p_e->sref, len);
11531 bool uentry_hasMetaStateEnsures (uentry e)
11533 if (uentry_isValid (e) && uentry_isFunction (e))
11535 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11543 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11545 llassert (uentry_isValid (e) && uentry_isFunction (e));
11546 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11549 # ifdef DEBUGSPLINT
11552 ** For debugging only
11555 void uentry_checkValid (uentry ue)
11557 if (uentry_isValid (ue))
11559 sRef_checkCompletelyReasonable (ue->sref);