2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 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 lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
28 # include "lclintMacros.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_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
49 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
53 static void checkAliasState (/*@notnull@*/ uentry p_old,
54 /*@notnull@*/ uentry p_unew,
55 bool p_mustConform, bool p_completeConform)
56 /*@modifies p_old, p_unew@*/ ;
57 static void checkNullState (/*@notnull@*/ uentry p_old,
58 /*@notnull@*/ uentry p_unew,
59 bool p_mustConform, bool p_completeConform)
60 /*@modifies p_old, p_unew@*/ ;
62 static void checkVarConformance (/*@notnull@*/ uentry p_old,
63 /*@notnull@*/ uentry p_unew,
64 bool p_mustConform, bool p_completeConform)
65 /*@modifies p_old, p_unew@*/;
68 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
69 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
72 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
74 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
75 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
78 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
79 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
80 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
81 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
82 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
84 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
85 ctype p_oldType, /*@notnull@*/ uentry p_unew,
86 /*@notnull@*/ uentry p_newCurrent,
87 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
89 static /*@only@*/ /*@notnull@*/ uentry
90 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
91 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
93 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
95 uentry ue = (uentry) dmalloc (sizeof (*ue));
96 ue->warn = warnClause_undefined; /*@i32@*/
103 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
104 static void uentry_copyInto (/*@out@*/ /*@unique@*/ uentry p_unew, uentry p_old);
105 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
106 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
107 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
108 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
109 static void uvinfo_free (/*@only@*/ uvinfo p_u);
113 static /*@only@*/ cstring ancontext_unparse (ancontext an)
117 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
118 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
119 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
120 case AN_SUFIELD: return cstring_makeLiteral ("su field");
121 case AN_TDEFN: return cstring_makeLiteral ("type definition");
122 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
123 case AN_CONST: return cstring_makeLiteral ("constant");
129 static int annots[AN_LAST][QU_LAST];
130 static int decls[AN_LAST];
131 static int shdecls[AN_LAST];
132 static int idecls[AN_LAST];
138 for (i = AN_UNKNOWN; i < AN_LAST; i++)
144 for (j = QU_UNKNOWN; j < QU_LAST; j++)
151 static void tallyAnnot (ancontext ac, qual q)
165 for (j = QU_UNKNOWN; j < QU_LAST; j++)
170 for (i = AN_UNKNOWN; i < AN_LAST; i++)
176 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
177 ancontext_unparse (i),
178 decls[i], shdecls[i], idecls[i]);
180 totdecls += decls[i];
181 totshdecls += shdecls[i];
182 totidecls += idecls[i];
184 for (j = QU_UNKNOWN; j < QU_LAST; j++)
186 total[j] += annots[i][j];
187 alltotals += annots[i][j];
190 printf (" Allocation:\n");
194 for (j = QU_UNKNOWN; j < QU_LAST; j++)
196 if (qual_isAliasQual (j) && !qual_isUnique (j))
198 if (annots[i][j] > 0)
200 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
201 100.0 * (double)annots[i][j] / (double)decls[i]);
202 tmptot += annots[i][j];
207 printf (" Exposure:\n");
211 for (j = QU_UNKNOWN; j < QU_LAST; j++)
213 if (qual_isExQual (j))
215 if (annots[i][j] > 0)
217 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
218 100.0 * (double)annots[i][j] / (double)decls[i]);
219 tmptot += annots[i][j];
224 printf (" Definition:\n");
226 for (j = QU_UNKNOWN; j < QU_LAST; j++)
228 if (qual_isAllocQual (j))
230 if (annots[i][j] > 0)
232 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
233 100.0 * (double)annots[i][j] / (double)decls[i]);
240 for (j = QU_UNKNOWN; j < QU_LAST; j++)
242 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
244 if (annots[i][j] > 0)
246 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
247 100.0 * (double)annots[i][j] / (double)decls[i]);
256 for (j = QU_UNKNOWN; j < QU_LAST; j++)
260 for (i = AN_UNKNOWN; i < AN_LAST; i++)
262 if (annots[i][j] > 0)
271 printf ("Annotation: %s\n", qual_unparse (j));
273 for (i = AN_UNKNOWN; i < AN_LAST; i++)
275 if (annots[i][j] > 0)
277 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
284 printf ("All Contexts\n");
286 for (j = QU_UNKNOWN; j < QU_LAST; j++)
290 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
291 100.0 * (double)total[j] / (double)(totdecls));
296 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
298 extern void uentry_tallyAnnots (uentry u, ancontext kind)
300 alkind ak = sRef_getAliasKind (u->sref);
301 exkind ek = sRef_getExKind (u->sref);
302 nstate ns = sRef_getNullState (u->sref);
303 sstate ss = sRef_getDefState (u->sref);
304 bool recordUnknown = FALSE;
306 if (kind == AN_UNKNOWN)
314 else if (e == KCONST || e == KENUMCONST)
318 else if (e == KFCN || e == KITER)
320 uentryList params = uentry_getParams (u);
323 uentryList_elements (params, current)
325 if (uentry_isReturned (current))
329 if (!uentry_isElipsisMarker (current))
331 uentry_tallyAnnots (current, AN_FCNPARAM);
333 } end_uentryList_elements;
337 if (ctype_isFunction (u->utype)
339 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
341 recordUnknown = TRUE;
344 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
346 ctype t = ctype_realType (u->utype);
350 uentryList fields = ctype_getFields (t);
352 uentryList_elements (fields, current)
354 uentry_tallyAnnots (current, AN_SUFIELD);
356 } end_uentryList_elements;
360 if (ctype_isVisiblySharable (u->utype))
362 recordUnknown = TRUE;
370 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
372 recordUnknown = TRUE;
379 if (kind == AN_FCNRETURN)
393 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
398 if (ctype_isRealPointer (ctype_realType (u->utype)))
406 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
407 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
408 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
409 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
413 if (uentry_isReturned (u))
415 tallyAnnot (kind, QU_RETURNED);
421 if (ctype_isRefCounted (ctype_realType (u->utype))
422 || (ctype_isFunction (u->utype) &&
423 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
429 if (kind == AN_FCNPARAM)
431 tallyAnnot (kind, QU_TEMP);
433 else if (recordUnknown)
435 if (kind == AN_FCNRETURN)
438 tallyAnnot (kind, QU_UNKNOWN);
442 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
443 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
444 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
445 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
447 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
448 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
449 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
450 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
451 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
452 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
453 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
454 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
455 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
456 case AK_IMPDEPENDENT:
457 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
467 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
468 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
474 case NS_ERROR: break;
475 case NS_UNKNOWN: break;
476 case NS_NOTNULL: break;
477 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
478 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
479 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
480 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
482 case NS_ABSNULL: break;
488 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
492 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
493 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
494 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
495 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
496 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
502 static specCode specCode_fromInt (int i)
505 llassert (i >= SPC_NONE && i < SPC_LAST);
507 return ((specCode) i);
511 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
513 if (uentry_isDeclared (u))
515 return cstring_makeLiteralTemp ("previously declared");
519 return cstring_makeLiteralTemp ("specified");
523 /*@observer@*/ cstring uentry_specDeclName (uentry u)
525 if (uentry_isDeclared (u))
527 return cstring_makeLiteralTemp ("previous declaration");
531 return cstring_makeLiteralTemp ("specification");
535 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
537 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
539 return cstring_makeLiteralTemp ("redefined");
541 else if (uentry_isCodeDefined (unew))
543 return cstring_makeLiteralTemp ("defined");
545 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
547 return cstring_makeLiteralTemp ("redeclared");
551 return cstring_makeLiteralTemp ("declared");
557 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
559 if (uentry_isValid (ue))
562 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
564 DPRINTF(( (message( "Function pointer %s not doing uentry_getFcnPreconditions", uentry_unparse(ue) )) ));
565 // uentry_makeVarFunction (ue);
568 //llassert (uentry_isFunction (ue));
569 //llassert ((ue->info->fcn->preconditions));
570 //llassert ((ue->info->fcn->preconditions));
571 if (!uentry_isFunction (ue))
573 DPRINTF( (message ("called uentry_getFcnPreconditions on nonfunction %s",
574 uentry_unparse (ue) ) ) );
575 if (!uentry_isSpecified (ue) )
577 DPRINTF((message ("called uentry_getFcnPreconditions on nonfunction %s",
578 uentry_unparse (ue) ) ));
579 return constraintList_undefined;
583 return constraintList_undefined;
586 if (constraintList_isDefined(ue->info->fcn->preconditions))
588 return constraintList_copy (ue->info->fcn->preconditions);
598 return constraintList_undefined;
608 constraintList uentry_getFcnPostconditions (uentry ue)
610 if (uentry_isValid (ue))
612 DPRINTF( (message ("called uentry_getFcnPostconditions on %s",
613 uentry_unparse (ue) ) ) );
615 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
617 DPRINTF( (message ("called uentry_getFcnPostconditions on nonfunction %s",
618 uentry_unparse (ue) ) ) );
619 if (!uentry_isFunction (ue) )
621 DPRINTF((message ("called uentry_getFcnPostconditions on nonfunction %s",
622 uentry_unparse (ue) ) ));
623 return constraintList_undefined;
627 return constraintList_undefined;
630 // llassert (uentry_isFunction (ue));
631 if (!uentry_isFunction(ue) )
634 DPRINTF( (message ("called uentry_getFcnPostconditions on non function %s",
635 uentry_unparse (ue) ) ) );
636 return constraintList_undefined;
639 if (constraintList_isDefined(ue->info->fcn->postconditions) )
641 DPRINTF((message ("called uentry_getFcnPostconditions on %s and returned %q",
643 constraintList_print(ue->info->fcn->postconditions) ) ));
644 return constraintList_copy (ue->info->fcn->postconditions);
654 return constraintList_undefined;
659 static /*@only@*/ fileloc setLocation (void)
661 fileloc fl = context_getSaveLocation ();
663 if (fileloc_isDefined (fl))
669 return fileloc_copy (g_currentloc);
673 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
675 fileloc loc = setLocation ();
676 uentry ue = uentry_makeConstant (n, t, loc);
678 ue->ukind = KENUMCONST;
679 uentry_setDefined (ue, loc);
683 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
685 fileloc loc = setLocation ();
686 uentry ue = uentry_makeConstant (n, t, loc);
687 ctype etype = exprNode_getType (expr);
689 if (!ctype_isRealInt (etype)) {
693 ("Value of enum member is not an integeral type (type %s): %s",
694 ctype_unparse (etype), exprNode_unparse (expr)),
695 exprNode_loc (expr));
698 ue->ukind = KENUMCONST;
699 uentry_setDefined (ue, loc);
704 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
706 uentry ue = uentry_makeConstant (n, t, loc);
708 ue->ukind = KENUMCONST;
713 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
715 return uentry_makeVariable (n, t, setLocation (), FALSE);
719 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
721 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
725 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
727 ctype ct = idDecl_getCtype (id);
728 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
729 MAYBE, MAYBE, setLocation ());
731 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
733 if (!ynm_isOn (ue->info->datatype->abs))
735 if (ctype_isUnknown (ct))
737 ue->info->datatype->mut = MAYBE;
741 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
748 void uentry_checkParams (uentry ue)
750 if (uentry_isValid (ue))
752 bool isExt = uentry_isExtern (ue);
754 if (uentry_isRealFunction (ue))
756 uentryList params = uentry_getParams (ue);
758 uentryList_elements (params, current)
760 if (uentry_isValid (current))
762 ctype ct = current->utype;
764 if (ctype_isFixedArray (ct))
766 if (ctype_isArray (ctype_baseArrayPtr (ct))
767 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
774 (FLG_FIXEDFORMALARRAY,
775 message ("Function parameter %q declared as "
776 "manifest array (size constant is meaningless)",
777 uentry_getName (current)),
778 uentry_whereDeclared (current));
783 if (ctype_isArray (ct))
787 message ("Function parameter %q declared as "
788 "array (treated as pointer)",
789 uentry_getName (current)),
790 uentry_whereDeclared (current));
794 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
796 if (ctype_isAbstract (ct) &&
797 (isExt || (ctype_isAbstract (ctype_realType (ct))
798 && !context_hasFileAccess (ctype_typeId (ct)))))
803 ("Function %q declared with notnull parameter %q of abstract "
806 uentry_getName (current),
809 ("Since %s is an abstract type, notnull can only be "
810 "used for parameters if the function is static to a "
811 "module where %s is accessible.",
814 uentry_whereDeclared (current));
818 } end_uentryList_elements;
820 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
822 ctype ct = ue->utype;
824 if (ctype_isAbstract (ct)
825 && (isExt || (ctype_isAbstract (ctype_realType (ct))
826 && !context_hasFileAccess (ctype_typeId (ct)))))
831 ("%s %q declared %s notnull storage of abstract type %s",
832 ekind_capName (uentry_getKind (ue)),
837 ("Since %s is an abstract type, notnull can only be used "
838 "if it is static to a module where %s is accessible.",
841 uentry_whereDeclared (ue));
848 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
850 alkind ak = sRef_getAliasKind (ue->sref);
852 if (alkind_isRefCounted (ak))
854 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
858 if (alkind_isUnknown (ak))
860 exkind ek = sRef_getExKind (ue->sref);
862 if (exkind_isKnown (ek))
864 DPRINTF (("Setting imp dependent: %s",
865 uentry_unparseFull (ue)));
866 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
870 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
872 /* evans 2000-12-22 removed ctype_realType so it will
873 not apply to immutable abstract types. */
875 if (ctype_isVisiblySharable
876 (ctype_realType (ctype_getReturnType (ue->utype))))
878 if (uentryList_hasReturned (uentry_getParams (ue)))
884 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
886 ; /* Immutable objects are not shared. */
890 sRef_setAliasKind (ue->sref, AK_IMPONLY,
892 DPRINTF (("Ret imp only: %s",
893 ctype_unparse (ctype_getReturnType (ue->utype))));
903 static /*@notnull@*/ uentry
904 uentry_makeFunctionAux (cstring n, ctype t,
906 /*@only@*/ globSet globs,
907 /*@only@*/ sRefSet mods,
908 /*@only@*/ warnClause warn,
909 /*@keep@*/ fileloc f, bool priv,
910 /*@unused@*/ bool isForward)
912 uentry e = uentry_alloc ();
915 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
917 if (ctype_isFunction (t))
919 ret = ctype_getReturnType (t);
923 if (ctype_isKnown (t))
925 llbug (message ("not function: %s", ctype_unparse (t)));
932 if (fileloc_isSpec (f) || fileloc_isImport (f))
934 e->whereSpecified = f;
935 e->whereDeclared = fileloc_undefined;
939 e->whereSpecified = fileloc_undefined;
940 e->whereDeclared = f;
943 /* e->shallowCopy = FALSE; */
944 e->uname = cstring_copy (n);
946 e->storageclass = SCNONE;
948 e->sref = sRef_makeType (ret);
950 if (ctype_isUA (ret))
952 sRef_setStateFromType (e->sref, ret);
957 e->uses = filelocList_new ();
959 e->hasNameError = FALSE;
963 e->info = (uinfo) dmalloc (sizeof (*e->info));
964 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
966 e->info->fcn->hasMods = sRefSet_isDefined (mods);
967 e->info->fcn->hasGlobs = globSet_isDefined (globs);
969 e->info->fcn->exitCode = XK_UNKNOWN;
970 e->info->fcn->nullPred = qual_createUnknown ();
971 e->info->fcn->specialCode = SPC_NONE;
973 e->info->fcn->access = access;
974 e->info->fcn->globs = globs;
975 e->info->fcn->defparams = uentryList_undefined;
977 sRef_setDefined (e->sref, f);
978 e->whereDefined = fileloc_undefined;
980 e->info->fcn->mods = sRefSet_undefined;
981 e->info->fcn->specclauses = NULL;
984 e->info->fcn->preconditions = NULL;
988 e->info->fcn->postconditions = NULL;
991 checkGlobalsModifies (e, mods);
992 e->info->fcn->mods = mods;
997 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
999 functionClauseList_elements (clauses, el)
1001 DPRINTF (("Reflect clause: %s on %s",
1002 functionClause_unparse (el), uentry_getName (ue)));
1004 if (functionClause_isNoMods (el))
1006 modifiesClause mel = functionClause_getModifies (el);
1008 if (uentry_hasGlobs (ue))
1013 ("No globals and modifies inconsistent to globals clause for %q: %q",
1014 uentry_getName (ue),
1015 globSet_unparse (uentry_getGlobs (ue))),
1016 modifiesClause_getLoc (mel));
1020 if (uentry_hasMods (ue))
1025 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1026 uentry_getName (ue),
1027 sRefSet_unparse (uentry_getMods (ue))),
1028 modifiesClause_getLoc (mel));
1031 uentry_setGlobals (ue, globSet_undefined);
1032 uentry_setModifies (ue, sRefSet_undefined);
1034 else if (functionClause_isGlobals (el))
1036 globalsClause glc = functionClause_getGlobals (el);
1038 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1039 globalsClause_unparse (glc)));
1041 if (uentry_hasGlobs (ue))
1046 ("Multiple globals clauses for %q: %q",
1047 uentry_getName (ue),
1048 globalsClause_unparse (glc)),
1049 globalsClause_getLoc (glc));
1050 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1054 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1057 else if (functionClause_isModifies (el))
1059 modifiesClause mlc = functionClause_getModifies (el);
1061 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1063 if (uentry_hasMods (ue))
1071 ("Multiple modifies clauses for %s: %s",
1072 uentry_getName (ue),
1073 modifiesClause_unparse (mlc)),
1074 modifiesClause_getLoc (mlc)))
1076 llhint (message ("Previous modifies clause: ",
1077 sRefSet_unparse (uentry_getMods (ue))));
1083 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1087 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1090 else if (functionClause_isState (el))
1092 stateClause sc = functionClause_takeState (el);
1093 uentry_addStateClause (ue, sc);
1095 else if (functionClause_isWarn (el))
1097 warnClause wc = functionClause_takeWarn (el);
1098 uentry_addWarning (ue, wc);
1102 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1104 } end_functionClauseList_elements ;
1106 stateClauseList_checkAll (ue);
1109 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1111 bool leaveFunc = FALSE;
1113 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1114 typeId_invalid, globSet_undefined,
1115 sRefSet_undefined, warnClause_undefined,
1119 ** This makes parameters names print out correctly.
1120 ** (But we might be a local variable declaration for a function type...)
1123 if (context_inFunctionLike ())
1125 DPRINTF (("Header: %s / %s",
1126 uentry_unparse (context_getHeader ()),
1127 idDecl_unparse (id)));
1131 context_enterFunctionDeclaration (ue);
1135 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1136 reflectImplicitFunctionQualifiers (ue, FALSE);
1138 uentry_reflectClauses (ue, idDecl_getClauses (id));
1140 if (!uentry_isStatic (ue)
1141 && cstring_equalLit (ue->uname, "main"))
1143 ctype typ = ue->utype;
1147 llassert (ctype_isFunction (typ));
1149 retval = ctype_getReturnType (typ);
1151 if (!ctype_isInt (retval))
1155 message ("Function main declared to return %s, should return int",
1156 ctype_unparse (retval)),
1157 uentry_whereDeclared (ue));
1160 args = ctype_argsFunction (typ);
1162 if (uentryList_isMissingParams (args)
1163 || uentryList_size (args) == 0)
1169 if (uentryList_size (args) != 2)
1173 message ("Function main declared with %d arg%&, "
1174 "should have 2 (int argc, char *argv[])",
1175 uentryList_size (args)),
1176 uentry_whereLast (ue));
1180 uentry arg = uentryList_getN (args, 0);
1181 ctype ct = uentry_getType (arg);
1183 if (!ctype_isInt (ct))
1187 message ("Parameter 1, %q, of function main declared "
1188 "with type %t, should have type int",
1189 uentry_getName (arg), ct),
1190 uentry_whereDeclared (arg));
1193 arg = uentryList_getN (args, 1);
1194 ct = uentry_getType (arg);
1196 if (ctype_isArrayPtr (ct)
1197 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1198 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1206 message ("Parameter 2, %q, of function main declared "
1207 "with type %t, should have type char **",
1208 uentry_getName (arg), ct),
1209 uentry_whereDeclared (arg));
1217 context_exitFunctionDeclaration ();
1223 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1225 alkind ak = sRef_getAliasKind (e->sref);
1227 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1228 && context_getFlag (FLG_PARAMIMPTEMP))
1230 exkind ek = sRef_getExKind (e->sref);
1232 if (exkind_isKnown (ek))
1234 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1235 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1236 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1240 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1241 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1246 static /*@only@*/ /*@notnull@*/ uentry
1247 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s, sstate defstate) /*@i32 exposed*/
1249 cstring pname = makeParam (n);
1252 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1253 e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
1255 cstring_free (pname);
1256 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1257 uentry_implicitParamAnnots (e);
1258 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1260 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1262 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1263 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1264 e->info->var->defstate = defstate;
1267 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1273 uentry_setRefCounted (uentry e)
1275 if (uentry_isValid (e))
1277 uentry_setAliasKind (e, AK_REFCOUNTED);
1278 sRef_storeState (e->sref);
1284 uentry_setStatic (uentry c)
1286 if (uentry_isValid (c))
1288 alkind ak = sRef_getAliasKind (c->sref);
1289 c->storageclass = SCSTATIC;
1291 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1293 if (!alkind_isUnknown (ak)
1294 && !alkind_isStatic (ak))
1296 if (!(ctype_isRealPointer (uentry_getType (c)))
1297 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1298 && !alkind_isRefCounted (ak))
1300 if (alkind_isImplicit (ak)
1301 && alkind_isDependent (ak)
1302 && ctype_isArray (uentry_getType (c)))
1304 ; /* no error for observer arrays */
1310 message ("Static storage %q declared as %s",
1312 alkind_unparse (ak)),
1313 uentry_whereDeclared (c));
1319 if (alkind_isUnknown (ak)
1320 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1321 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1323 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1324 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1332 uentry_setExtern (uentry c)
1334 if (uentry_isValid (c))
1335 c->storageclass = SCEXTERN;
1339 uentry_setParamNo (uentry ue, int pno)
1341 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1342 sRef_setParamNo (ue->sref, pno);
1346 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1348 sRefSet_allElements (sr, el)
1350 sRef base = sRef_getRootBase (el);
1352 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1353 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1355 if (!globSet_member (ue->info->fcn->globs, base))
1357 if (uentry_hasGlobs (ue)
1358 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1361 (FLG_WARNMISSINGGLOBALS,
1363 ("Modifies list for %q uses global %q, "
1364 "not included in globals list.",
1365 uentry_getName (ue),
1366 sRef_unparse (base)),
1367 uentry_whereLast (ue)))
1369 uentry_showWhereSpecified (ue);
1373 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1375 if (sRef_isFileStatic (base))
1377 context_recordFileGlobals (ue->info->fcn->globs);
1381 } end_sRefSet_allElements;
1385 uentry_makeVariableSrefParam (cstring n, ctype t, /*@exposed@*/ sRef s)
1387 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1391 uentry_fixupSref (uentry ue)
1395 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1400 sr = uentry_getSref (ue);
1402 sRef_resetState (sr);
1403 sRef_clearDerived (sr);
1405 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1406 llassert (sRef_isValid (sr));
1408 if (uentry_isVariable (ue))
1410 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1411 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1415 static void uentry_addStateClause (uentry ue, stateClause sc)
1418 ** Okay to allow multiple clauses of the same kind.
1419 */ /*@i834 is this true?@*/
1421 ue->info->fcn->specclauses =
1422 stateClauseList_add (ue->info->fcn->specclauses, sc);
1424 /* Will call checkAll to check later... */
1427 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1429 llassert (uentry_isFunction (ue));
1430 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1432 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1433 ue->info->fcn->specclauses = clauses;
1434 stateClauseList_checkAll (ue);
1435 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1439 ** Used for @modifies@ @endmodifies@ syntax.
1441 ** If ue is specified, sr must contain *only*:
1443 ** o file static globals
1444 ** o sRef's derived from modifies spec (i.e., more specific than
1445 ** what was specified)
1447 ** Otherwise, if sr has modifies it must match sr.
1449 ** If it doesn't have modifies, set them to sr.
1453 uentry_checkModifiesContext (void)
1455 if (sRef_modInFunction ())
1459 ("Modifies list not in function context. "
1460 "A modifies list can only appear following the parameter list "
1461 "in a function declaration or header."));
1470 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1472 if (!uentry_checkModifiesContext ())
1478 if (uentry_isValid (ue))
1480 if (uentry_isIter (ue))
1482 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1483 ue->info->iter->mods = sr;
1487 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1489 uentry_makeVarFunction (ue);
1492 llassertfatal (uentry_isFunction (ue));
1493 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1495 ue->info->fcn->mods = sr;
1496 ue->info->fcn->hasMods = TRUE;
1498 checkGlobalsModifies (ue, sr);
1501 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1503 ue->info->fcn->hasGlobs = TRUE;
1506 if (sRefSet_hasStatic (ue->info->fcn->mods))
1508 context_recordFileModifies (ue->info->fcn->mods);
1518 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1521 ** Function already has one modifies clause (possibly from
1522 ** a specification).
1525 if (!uentry_checkModifiesContext ())
1530 llassert (uentry_isValid (ue));
1532 if (uentry_isIter (ue))
1534 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1538 llassertfatal (uentry_isFunction (ue));
1539 llassert (ue->info->fcn->hasMods);
1541 checkGlobalsModifies (ue, sr);
1542 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1544 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1546 ue->info->fcn->hasGlobs = TRUE;
1550 if (sRefSet_hasStatic (ue->info->fcn->mods))
1552 context_recordFileModifies (ue->info->fcn->mods);
1556 bool uentry_hasWarning (uentry ue)
1558 return (uentry_isValid (ue)
1559 && warnClause_isDefined (ue->warn));
1562 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1564 llassert (warnClause_isUndefined (ue->warn));
1569 uentry_setPreconditions (uentry ue, /*@only@*/ constraintList preconditions)
1571 if (sRef_modInFunction ())
1574 (message ("Precondition list not in function context. "
1575 "A precondition list can only appear following the parameter list "
1576 "in a function declaration or header."));
1578 /*@-mustfree@*/ return; /*@=mustfree@*/
1581 if (uentry_isValid (ue))
1584 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1586 uentry_makeVarFunction (ue);
1589 llassertfatal (uentry_isFunction (ue));
1590 // llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1592 if (constraintList_isDefined(ue->info->fcn->preconditions) )
1594 constraintList_free(ue->info->fcn->preconditions);
1595 ue->info->fcn->preconditions = preconditions;
1598 ue->info->fcn->preconditions = preconditions;
1604 llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
1613 uentry_setPostconditions (uentry ue, /*@only@*/ constraintList postconditions)
1615 if (sRef_modInFunction ())
1618 (message ("Postcondition list not in function context. "
1619 "A postcondition list can only appear following the parameter list "
1620 "in a function declaration or header."));
1622 /*@-mustfree@*/ return; /*@=mustfree@*/
1625 if (uentry_isValid (ue))
1628 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1630 uentry_makeVarFunction (ue);
1633 llassertfatal (uentry_isFunction (ue));
1634 // llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1636 if (constraintList_isUndefined(ue->info->fcn->postconditions) )
1637 ue->info->fcn->postconditions = postconditions;
1640 constraintList_free(ue->info->fcn->postconditions);
1641 ue->info->fcn->postconditions = postconditions;
1649 llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
1654 ** requires: new and old are functions
1658 checkGlobalsConformance (/*@notnull@*/ uentry old,
1659 /*@notnull@*/ uentry unew,
1660 bool mustConform, bool completeConform)
1662 bool hasInternalState = FALSE;
1664 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1666 if (globSet_isDefined (unew->info->fcn->globs))
1668 globSet_allElements (unew->info->fcn->globs, el)
1670 if (sRef_isFileStatic (el))
1672 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1674 if (sRef_isInvalid (sr))
1676 bool hasError = FALSE;
1678 if (!hasInternalState
1679 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1680 sRef_makeInternalState ()))
1681 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1682 sRef_makeSpecState ())))
1685 && !uentry_isStatic (old)
1688 message ("Globals list for %q includes internal state, %q, "
1689 "but %s without globals internalState.",
1690 uentry_getName (old),
1692 uentry_specOrDefName (old)),
1693 uentry_whereLast (unew)))
1695 uentry_showWhereSpecified (old);
1699 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1700 sRef_makeInternalState ());
1701 hasInternalState = TRUE;
1705 && fileloc_sameFile (uentry_whereDeclared (unew),
1706 uentry_whereDeclared (old)))
1711 message ("Function %q inconsistently %rdeclared (in "
1712 "same file) with file static global %q in "
1714 uentry_getName (unew),
1715 uentry_isDeclared (old),
1717 uentry_whereDeclared (unew)))
1719 uentry_showWhereSpecified (old);
1724 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1725 context_recordFileGlobals (old->info->fcn->globs);
1729 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1731 if (sRef_isInvalid (sr))
1736 message ("Function %q inconsistently %rdeclared with "
1737 "%q in globals list",
1738 uentry_getName (unew),
1739 uentry_isDeclared (old),
1741 uentry_whereDeclared (unew)))
1743 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1744 uentry_showWhereSpecified (old);
1749 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1755 ("Function %q global %q inconsistently "
1756 "%rdeclared as %qout global",
1757 uentry_getName (unew),
1759 uentry_isDeclared (old),
1760 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1761 uentry_whereDeclared (unew)))
1763 uentry_showWhereSpecified (old);
1768 } end_globSet_allElements ;
1770 if (completeConform)
1772 globSet_allElements (old->info->fcn->globs, el)
1774 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1776 if (sRef_isInvalid (sr))
1779 && uentry_isReallySpecified (old)
1782 message ("Function %q specified with %q in globals list, "
1783 "but declared without %q",
1784 uentry_getName (unew),
1787 uentry_whereDeclared (unew)))
1789 uentry_showWhereSpecified (old);
1792 } end_globSet_allElements;
1797 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1799 if (uentry_isReallySpecified (old)
1802 message ("%s %q specified with globals list, but "
1803 "declared with no globals",
1804 ekind_capName (unew->ukind),
1805 uentry_getName (unew)),
1806 uentry_whereDeclared (unew)))
1809 (message ("Specification globals: %q",
1810 globSet_unparse (old->info->fcn->globs)),
1811 uentry_whereSpecified (old));
1815 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1816 old->info->fcn->globs);
1821 ** new modifies list must be included by old modifies list.
1823 ** file static state may be added to new, if old has internal.
1827 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1828 bool mustConform, bool completeConform)
1831 bool changedMods = FALSE;
1832 bool modInternal = FALSE;
1834 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1836 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1837 newMods = unew->info->fcn->mods;
1839 if (sRefSet_isEmpty (newMods))
1841 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1842 && uentry_isReallySpecified (old))
1846 message ("%s %q specified with modifies clause, "
1847 "but declared with no modifies clause",
1848 ekind_capName (unew->ukind),
1849 uentry_getName (unew)),
1850 uentry_whereDeclared (unew)))
1852 llgenindentmsg (message ("Specification has modifies %q",
1853 sRefSet_unparse (old->info->fcn->mods)),
1854 uentry_whereSpecified (old));
1861 sRefSet_allElements (newMods, current)
1863 if (sRef_isValid (current))
1865 sRef rb = sRef_getRootBase (current);
1867 if (sRef_isFileStatic (rb))
1871 if (!sRefSet_isSameMember (old->info->fcn->mods,
1872 sRef_makeInternalState ())
1873 && !sRefSet_isSameMember (old->info->fcn->mods,
1874 sRef_makeSpecState ()))
1877 && !uentry_isStatic (old)
1881 ("Modifies list for %q includes internal state, "
1882 "but %s without modifies internal.",
1883 uentry_getName (old),
1884 uentry_specOrDefName (old)),
1885 uentry_whereLast (unew)))
1887 uentry_showWhereSpecified (old);
1890 old->info->fcn->mods =
1891 sRefSet_insert (old->info->fcn->mods,
1892 sRef_makeInternalState ());
1897 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1903 if (sRef_canModifyVal (current, old->info->fcn->mods))
1905 int size = sRefSet_size (old->info->fcn->mods);
1907 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1910 if (sRefSet_size (old->info->fcn->mods) != size)
1921 ("Modifies list for %q contains %q, not modifiable "
1923 uentry_getName (old),
1924 sRef_unparse (current),
1925 uentry_specDeclName (old)),
1926 uentry_whereLast (unew)))
1928 uentry_showWhereSpecified (old);
1933 } end_sRefSet_allElements;
1935 if (completeConform && uentry_isReallySpecified (old))
1937 sRefSet_allElements (old->info->fcn->mods, el)
1939 if (sRef_canModify (el, newMods))
1948 ("Specification modifies clause for %q contains %q, "
1949 "not included in declaration modifies clause",
1950 uentry_getName (old),
1952 uentry_whereLast (unew)))
1954 uentry_showWhereSpecified (old);
1957 } end_sRefSet_allElements ;
1961 ** Make sure file static elements will be removed.
1966 context_recordFileModifies (old->info->fcn->mods);
1971 uentry_checkMutableType (uentry ue)
1973 ctype ct = uentry_getType (ue);
1975 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1977 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
1979 voptgenerror (FLG_MUTREP,
1980 message ("Mutable abstract type %q declared without pointer "
1981 "indirection: %t (violates assignment semantics)",
1982 uentry_getName (ue), ct),
1983 uentry_whereDeclared (ue));
1988 uentry_setMutable (uentry e)
1990 llassert (uentry_isDatatype (e));
1991 e->info->datatype->mut = YES;
1995 uentry_checkIterArgs (uentry ue)
1997 bool hasYield = FALSE;
2000 llassert (uentry_isIter (ue));
2002 args = uentry_getParams (ue);
2004 uentryList_elements (args, el)
2006 sstate ds = uentry_getDefState (el);
2008 if (uentry_isYield (el))
2013 if (sstate_isUnknown (ds))
2015 uentry_setDefState (el, SS_DEFINED);
2021 } end_uentryList_elements;
2025 voptgenerror (FLG_HASYIELD,
2026 message ("Iterator %q declared with no yield parameters",
2027 uentry_getName (ue)),
2028 uentry_whereDeclared (ue));
2033 chkind_fromQual (qual qel)
2035 if (qual_isChecked (qel))
2039 else if (qual_isCheckMod (qel))
2043 else if (qual_isCheckedStrict (qel))
2045 return CH_CHECKEDSTRICT;
2047 else if (qual_isUnchecked (qel))
2049 return CH_UNCHECKED;
2054 /*@notreached@*/ return CH_UNKNOWN;
2059 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2061 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2063 if (!uentry_isRefCounted (ue))
2066 (FLG_ANNOTATIONERROR,
2067 message ("Reference counting qualifier %s used on non-reference "
2068 "counted storage: %q",
2070 uentry_unparse (ue)),
2071 uentry_whereLast (ue));
2075 alkind ak = alkind_fromQual (qel);
2077 uentry_setAliasKind (ue, ak);
2080 else if (qual_isRefCounted (qel))
2082 ctype ct = ctype_realType (uentry_getType (ue));
2085 if (ctype_isPointer (ct)
2086 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2088 /* check there is a refs field */
2089 uentryList fields = ctype_getFields (rt);
2090 uentry refs = uentry_undefined;
2092 uentryList_elements (fields, field)
2094 if (uentry_isRefsField (field))
2096 if (uentry_isValid (refs))
2099 (FLG_ANNOTATIONERROR,
2100 message ("Reference counted structure type %s has "
2101 "multiple refs fields: %q and %q",
2103 uentry_getName (refs),
2104 uentry_getName (field)),
2105 uentry_whereLast (field));
2110 } end_uentryList_elements;
2112 if (uentry_isInvalid (refs))
2116 message ("Reference counted structure type %s has "
2118 ctype_unparse (ct)),
2120 ("To count reference, the structure must have a field named "
2121 "refs of type int."),
2124 else if (!ctype_isInt (uentry_getType (refs)))
2127 (FLG_ANNOTATIONERROR,
2128 message ("Reference counted structure type %s refs field has "
2129 "type %s (should be int)", ctype_unparse (ct),
2130 ctype_unparse (uentry_getType (refs))),
2131 uentry_whereLast (refs));
2135 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2136 uentry_whereDeclared (ue));
2141 if ((ctype_isPointer (ct)
2142 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2143 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2145 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2146 uentry_whereDeclared (ue));
2151 (FLG_ANNOTATIONERROR,
2152 message ("Non-pointer to structure type %s declared with "
2153 "refcounted qualifier",
2154 ctype_unparse (ct)),
2155 uentry_whereLast (ue));
2159 else if (qual_isRefs (qel))
2161 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2163 uentry_setAliasKind (ue, AK_REFS);
2168 (FLG_ANNOTATIONERROR,
2169 message ("Refs qualifier used on non-structure field: %q",
2170 uentry_unparse (ue)),
2171 uentry_whereLast (ue));
2174 else if (qual_isAliasQual (qel))
2176 alkind ak = alkind_fromQual (qel);
2178 alkind oldak = uentry_getAliasKind (ue);
2179 ctype ut = uentry_getType (ue);
2181 if (alkind_isImplicit (ak)
2182 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2184 /* ignore the implied qualifier */
2188 if (uentry_isEitherConstant (ue))
2191 (FLG_ANNOTATIONERROR,
2192 message ("Alias qualifier %s used on constant: %q",
2193 alkind_unparse (ak), uentry_unparse (ue)),
2194 uentry_whereLast (ue));
2199 if (ctype_isFunction (ut))
2201 ut = ctype_getReturnType (ut);
2204 if (!(ctype_isVisiblySharable (ut)
2205 || ctype_isRealArray (ut)
2206 || ctype_isRealSU (ut)))
2208 if (!qual_isImplied (qel))
2211 (FLG_ANNOTATIONERROR,
2212 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2213 alkind_unparse (ak), ut, uentry_getName (ue)),
2214 uentry_whereLast (ue));
2221 if (uentry_isRefCounted (ue))
2223 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2224 || qual_isExposed (qel)
2225 || qual_isObserver (qel)))
2227 if (!qual_isImplied (qel))
2230 (FLG_ANNOTATIONERROR,
2232 ("Alias qualifier %s used on reference counted storage: %q",
2233 alkind_unparse (ak),
2234 uentry_unparse (ue)),
2235 uentry_whereLast (ue));
2243 if (qual_isRefQual (qel))
2246 (FLG_ANNOTATIONERROR,
2247 message ("Qualifier %s used on non-reference counted storage: %q",
2248 alkind_unparse (ak), uentry_unparse (ue)),
2249 uentry_whereLast (ue));
2258 uentry_setAliasKind (ue, ak);
2261 else if (qual_isNull (qel))
2263 if (uentry_isConstant (ue))
2267 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2268 uentry_whereDeclared (ue));
2272 uentry_setNullState (ue, NS_POSNULL);
2275 else if (qual_isRelNull (qel))
2277 uentry_setNullState (ue, NS_RELNULL);
2279 else if (qual_isNotNull (qel))
2281 uentry_setNullState (ue, NS_MNOTNULL);
2283 else if (qual_isAbstract (qel)
2284 || qual_isConcrete (qel))
2286 if (!uentry_isDatatype (ue))
2289 (FLG_ANNOTATIONERROR,
2290 message ("Qualifier %s used with non-datatype",
2291 qual_unparse (qel)),
2292 uentry_whereLast (ue));
2296 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2299 else if (qual_isMutable (qel))
2301 if (!uentry_isDatatype (ue))
2304 (FLG_ANNOTATIONERROR,
2305 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2306 uentry_whereLast (ue));
2310 if (!ynm_isOn (ue->info->datatype->mut))
2312 uentry_checkMutableType (ue);
2315 ue->info->datatype->mut = YES;
2318 else if (qual_isImmutable (qel))
2320 if (!uentry_isDatatype (ue))
2322 voptgenerror (FLG_ANNOTATIONERROR,
2323 message ("Qualifier %s used with non-datatype",
2324 qual_unparse (qel)),
2325 uentry_whereLast (ue));
2329 ue->info->datatype->mut = NO;
2332 else if (qual_isNullPred (qel))
2334 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2336 uentry_makeVarFunction (ue);
2339 if (uentry_isFunction (ue))
2341 ctype typ = uentry_getType (ue);
2342 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2344 if (ctype_isRealBool (rtype))
2346 uentryList pl = ctype_argsFunction (typ);
2348 if (uentryList_size (pl) == 1)
2350 ue->info->fcn->nullPred = qel;
2354 voptgenerror (FLG_ANNOTATIONERROR,
2355 message ("Qualifier %s used with function having %d "
2356 "arguments (should have 1)",
2358 uentryList_size (pl)),
2359 uentry_whereLast (ue));
2364 voptgenerror (FLG_ANNOTATIONERROR,
2365 message ("Qualifier %s used with function returning %s "
2366 "(should return bool)",
2368 ctype_unparse (rtype)),
2369 uentry_whereLast (ue));
2374 voptgenerror (FLG_ANNOTATIONERROR,
2375 message ("Qualifier %s used with non-function",
2376 qual_unparse (qel)),
2377 uentry_whereLast (ue));
2380 else if (qual_isExitQual (qel))
2382 exitkind exk = exitkind_fromQual (qel);
2384 if (uentry_isFunction (ue))
2386 if (exitkind_isKnown (ue->info->fcn->exitCode))
2388 voptgenerror (FLG_ANNOTATIONERROR,
2389 message ("Multiple exit qualifiers used on function %q: %s, %s",
2390 uentry_getName (ue),
2391 exitkind_unparse (ue->info->fcn->exitCode),
2392 exitkind_unparse (exk)),
2393 uentry_whereLast (ue));
2396 ue->info->fcn->exitCode = exk;
2400 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2402 uentry_makeVarFunction (ue);
2403 ue->info->fcn->exitCode = exk;
2407 voptgenerror (FLG_ANNOTATIONERROR,
2408 message ("Exit qualifier %s used with non-function (type %s)",
2410 ctype_unparse (uentry_getType (ue))),
2411 uentry_whereLast (ue));
2415 else if (qual_isMetaState (qel))
2417 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2419 if (annotationInfo_matchesContext (ainfo, ue))
2421 DPRINTF (("Reflecting %s on %s",
2422 annotationInfo_unparse (ainfo),
2423 uentry_unparseFull (ue)));
2425 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2426 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2427 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2432 (FLG_ANNOTATIONERROR,
2433 message ("Meta state anntation %s used in inconsistent context: %q",
2435 uentry_unparse (ue)),
2436 uentry_whereLast (ue)))
2438 /*@i! annotationInfo_showContextError (ainfo, ue); */
2444 if (qual_isCQual (qel))
2450 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2456 uentry_reflectQualifiers (uentry ue, qualList q)
2458 llassert (uentry_isValid (ue));
2460 qualList_elements (q, qel)
2462 if (qual_isStatic (qel))
2464 uentry_setStatic (ue);
2466 else if (qual_isUnused (qel))
2468 uentry_setUsed (ue, fileloc_undefined);
2470 else if (qual_isExternal (qel))
2472 fileloc_free (ue->whereDefined);
2473 ue->whereDefined = fileloc_createExternal ();
2475 else if (qual_isSef (qel))
2477 if (uentry_isVariable (ue))
2479 vkind vk = ue->info->var->kind;
2481 llassert (vk != VKREFPARAM);
2483 if (vk == VKYIELDPARAM)
2486 (FLG_ANNOTATIONERROR,
2487 message ("Qualifier sef cannot be used with %s: %q",
2488 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2489 uentry_unparse (ue)),
2490 uentry_whereLast (ue));
2492 else if (vk == VKRETPARAM)
2494 ue->info->var->kind = VKSEFRETPARAM;
2498 ue->info->var->kind = VKSEFPARAM;
2504 (FLG_ANNOTATIONERROR,
2505 message ("Qualifier sef is meaningful only on parameters: %q",
2506 uentry_unparse (ue)),
2507 uentry_whereLast (ue));
2510 else if (qual_isExtern (qel))
2512 ue->storageclass = SCEXTERN;
2514 else if (qual_isGlobalQual (qel)) /* undef, killed */
2516 DPRINTF (("Reflecting qual: %s / %s",
2517 qual_unparse (qel), uentry_unparse (ue)));
2519 if (uentry_isVariable (ue))
2521 sstate oldstate = ue->info->var->defstate;
2522 sstate defstate = sstate_fromQual (qel);
2525 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2526 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2528 defstate = SS_UNDEFKILLED;
2535 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2536 ue->info->var->defstate = defstate;
2541 (FLG_ANNOTATIONERROR,
2542 message ("Qualifier %s used on non-variable: %q",
2543 qual_unparse (qel), uentry_unparse (ue)),
2544 uentry_whereLast (ue));
2547 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2549 /* start modifications */
2550 else if( qual_isBufQualifier(qel) ) {
2551 ctype ct = ctype_realType(uentry_getType(ue));
2552 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2554 if( uentry_hasBufStateInfo(ue) ) {
2555 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2557 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2558 /* If formal func param */
2559 uentry_setNullTerminatedState(ue);
2560 uentry_setLen (ue, 1);
2561 uentry_setSize (ue, 1);
2563 sRef_setNullTerminatedState(uentry_getSref(ue));
2564 sRef_setLen (uentry_getSref(ue), 1);
2565 sRef_setSize (uentry_getSref(ue), 1);
2567 uentry_setPossiblyNullTerminatedState(ue);
2569 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2573 /* put other BufState Qualifiers here */
2575 cstring s = uentry_getName(ue);
2576 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2577 struct for identifier %s\n", s) );
2579 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2581 sRef retSref = uentry_getSref (ue);
2582 ctype retType = sRef_getType (retSref);
2584 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2585 sRef_setNullTerminatedState (retSref);
2591 message ("Qualifier %s used on non-pointer on \
2592 function return: %q", qual_unparse (qel),
2593 uentry_unparse (ue)));
2600 message ("Qualifier %s used on non-pointer: %q",
2601 qual_unparse (qel), uentry_unparse (ue)));
2603 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2605 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2607 ctype realType = ctype_realType (ue->utype);
2608 sstate defstate = sstate_fromQual (qel);
2610 if (ctype_isFunction (realType))
2612 realType = ctype_realType (ctype_getReturnType (realType));
2615 if (qual_isRelDef (qel))
2617 ; /* okay anywhere */
2621 if (!ctype_isAP (realType)
2622 && !ctype_isSU (realType)
2623 && !ctype_isUnknown (realType)
2624 && !ctype_isAbstract (ue->utype))
2627 (FLG_ANNOTATIONERROR,
2628 message ("Qualifier %s used on non-pointer or struct: %q",
2629 qual_unparse (qel), uentry_unparse (ue)),
2630 uentry_whereLast (ue));
2634 uentry_setDefState (ue, defstate);
2636 if (sRef_isStateSpecial (ue->sref)
2637 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2639 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2642 else if (qual_isYield (qel))
2644 if (uentry_isVariable (ue))
2646 ue->info->var->kind = VKYIELDPARAM;
2651 (FLG_ANNOTATIONERROR,
2652 message ("Qualifier %s used on non-iterator parameter: %q",
2653 qual_unparse (qel), uentry_unparse (ue)),
2654 uentry_whereLast (ue));
2657 else if (qual_isExQual (qel))
2659 exkind ek = exkind_fromQual (qel);
2660 ctype ut = uentry_getType (ue);
2662 DPRINTF (("Reflect ex qual: %s / %s",
2663 uentry_unparse (ue), exkind_unparse (ek)));
2665 if (ctype_isFunction (ut))
2667 ut = ctype_getReturnType (ut);
2670 if (!(ctype_isVisiblySharable (ut))
2671 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2672 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2674 if (!qual_isImplied (qel))
2676 if (ctype_isImmutableAbstract (ut)) {
2678 (FLG_REDUNDANTSHAREQUAL,
2679 message ("Qualifier %s used on unsharable storage type %t: %q",
2680 exkind_unparse (ek), ut, uentry_getName (ue)),
2681 uentry_whereLast (ue));
2684 (FLG_MISPLACEDSHAREQUAL,
2685 message ("Qualifier %s used on unsharable storage type %t: %q",
2686 exkind_unparse (ek), ut, uentry_getName (ue)),
2687 uentry_whereLast (ue));
2693 alkind ak = sRef_getAliasKind (ue->sref);
2695 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2696 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2698 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2700 if (!alkind_isTemp (ak))
2702 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2703 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2706 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2707 || alkind_isOwned (ak))
2715 message ("Exposure qualifier %s used on %s storage (should "
2716 "be dependent): %q",
2718 alkind_unparse (ak),
2719 uentry_unparse (ue)));
2723 else if (qual_isGlobCheck (qel))
2725 if (uentry_isVariable (ue))
2727 chkind ch = chkind_fromQual (qel);
2729 if (ue->info->var->checked != CH_UNKNOWN)
2731 if (ch == ue->info->var->checked)
2733 llerror (FLG_SYNTAX,
2734 message ("Redundant %s qualifier on %q",
2736 uentry_getName (ue)));
2740 llerror (FLG_SYNTAX,
2742 ("Contradictory %s and %s qualifiers on %q",
2744 checkedName (ue->info->var->checked),
2745 uentry_getName (ue)));
2749 ue->info->var->checked = ch;
2755 message ("Qualifier %s used with non-variable",
2756 qual_unparse (qel)));
2759 else if (qual_isReturned (qel))
2761 if (uentry_isVariable (ue))
2763 ue->info->var->kind = VKRETPARAM;
2767 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2768 qual_unparse (qel)));
2773 uentry_reflectOtherQualifier (ue, qel);
2776 sRef_storeState (ue->sref);
2777 } end_qualList_elements;
2783 uentry_isOnly (uentry ue)
2785 return (!uentry_isUndefined (ue)
2786 && uentry_isVariable (ue)
2787 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2791 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2793 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2794 sRef_setOrigAliasKind (ue->sref, ak);
2798 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2800 if (uentry_isVariable (ue))
2802 ue->info->var->nullstate = ns;
2805 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2809 uentry_isUnique (uentry ue)
2811 return (!uentry_isUndefined (ue)
2812 && uentry_isVariable (ue)
2813 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2817 uentry_isFileStatic (uentry ue)
2819 return (uentry_isStatic (ue)
2820 && (!uentry_isVariable (ue)
2821 || sRef_isFileStatic (uentry_getSref (ue))));
2825 uentry_isExported (uentry ue)
2827 if (uentry_isValid (ue))
2829 if (uentry_isVariable (ue))
2831 return (sRef_isRealGlobal (uentry_getSref (ue)));
2835 return !uentry_isStatic (ue);
2843 uentry_isNonLocal (uentry ue)
2845 return (uentry_isValid (ue) && uentry_isVariable (ue)
2846 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2850 uentry_isGlobalVariable (uentry ue)
2852 return (uentry_isValid (ue) && uentry_isVariable (ue)
2853 && sRef_isFileOrGlobalScope (ue->sref));
2857 uentry_isVisibleExternally (uentry ue)
2859 return (uentry_isValid (ue)
2860 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2861 || (!uentry_isStatic (ue)
2862 && (uentry_isFunction (ue)
2863 || uentry_isIter (ue)
2864 || uentry_isEndIter (ue)
2865 || uentry_isConstant (ue)
2866 || uentry_isDatatype (ue)
2867 || uentry_isAnyTag (ue)))));
2871 uentry_isPrintfLike (uentry ue)
2873 return (uentry_isFunction (ue)
2874 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2878 uentry_isScanfLike (uentry ue)
2880 return (uentry_isFunction (ue)
2881 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2885 uentry_isMessageLike (uentry ue)
2887 return (uentry_isFunction (ue)
2888 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2891 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2893 uentryList args = uentry_getParams (ue);
2895 if (!uentryList_isMissingParams (args))
2897 uentry last = uentry_undefined;
2899 uentryList_elements (args, current)
2901 if (uentry_isElipsisMarker (current))
2903 if (uentry_isUndefined (last))
2907 message ("Function %q is marked %s, but has no format "
2908 "string argument before elipsis",
2909 uentry_getName (ue),
2910 specCode_unparse (ue->info->fcn->specialCode)),
2911 uentry_whereLast (ue));
2912 ue->info->fcn->specialCode = SPC_NONE;
2916 ctype rt = ctype_realType (uentry_getType (last));
2918 if (!ctype_match (rt, ctype_string))
2922 /* wchar_t * is okay too */
2923 if (ctype_isAP (rt))
2925 ctype base = ctype_baseArrayPtr (rt);
2927 if (ctype_isArbitraryIntegral (base))
2937 message ("Function %q is marked %s, but the argument "
2938 "before the elipsis has type %s (should be char *)",
2939 uentry_getName (ue),
2940 specCode_unparse (ue->info->fcn->specialCode),
2941 ctype_unparse (uentry_getType (last))),
2942 uentry_whereLast (ue));
2944 ue->info->fcn->specialCode = SPC_NONE;
2951 } end_uentryList_elements ;
2955 message ("Function %q is marked %s, but has no elipsis parameter",
2956 uentry_getName (ue),
2957 specCode_unparse (ue->info->fcn->specialCode)),
2958 uentry_whereLast (ue));
2960 ue->info->fcn->specialCode = SPC_NONE;
2965 uentry_setPrintfLike (uentry ue)
2967 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2969 uentry_makeVarFunction (ue);
2972 llassertfatal (uentry_isFunction (ue));
2973 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2974 checkSpecialFunction (ue);
2978 uentry_setScanfLike (uentry ue)
2980 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2982 uentry_makeVarFunction (ue);
2985 llassertfatal (uentry_isFunction (ue));
2986 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2987 checkSpecialFunction (ue);
2991 uentry_setMessageLike (uentry ue)
2993 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2995 uentry_makeVarFunction (ue);
2998 llassertfatal (uentry_isFunction (ue));
2999 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3000 checkSpecialFunction (ue);
3004 uentry_isSpecialFunction (uentry ue)
3006 return (uentry_isFunction (ue)
3007 && (ue->info->fcn->specialCode != SPC_NONE));
3010 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3012 ctype ct = idDecl_getCtype (t);
3014 sRef pref = sRef_makeParam (i, ct);
3015 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
3017 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3018 uentry_implicitParamAnnots (ue);
3020 /* Parameter type [][] or [x][] is invalid */
3022 while (ctype_isFixedArray (base)) {
3023 base = ctype_baseArrayPtr (base);
3026 if (ctype_isIncompleteArray (base)) {
3027 base = ctype_baseArrayPtr (base);
3029 if (ctype_isArray (base)) {
3030 if (!uentry_hasName (ue)) {
3031 (void) optgenerror (FLG_INCOMPLETETYPE,
3032 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3034 ctype_unparse (ct)),
3035 uentry_whereLast (ue));
3037 (void) optgenerror (FLG_INCOMPLETETYPE,
3038 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3039 uentry_getName (ue),
3040 ctype_unparse (ct)),
3041 uentry_whereLast (ue));
3046 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3050 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3052 ctype ct = idDecl_getCtype (t);
3054 if (ctype_isFunction (ct))
3056 return (uentry_makeIdFunction (t));
3060 fileloc loc = setLocation ();
3061 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3063 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3065 if (!uentry_isExtern (ue))
3067 uentry_setDefined (ue, loc);
3075 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
3077 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
3085 /*@only@*/ /*@notnull@*/
3086 uentry uentry_makeConstantAux (cstring n, ctype t,
3087 /*@keep@*/ fileloc f, bool priv,
3088 /*@only@*/ multiVal m)
3090 uentry e = uentry_alloc ();
3093 e->uname = cstring_copy (n);
3095 e->storageclass = SCNONE;
3097 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3099 e->sref = sRef_makeConst (t);
3104 e->uses = filelocList_new ();
3105 e->isPrivate = priv;
3106 e->hasNameError = FALSE;
3108 e->info = (uinfo) dmalloc (sizeof (*e->info));
3109 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3110 e->info->uconst->val = m;
3111 e->info->uconst->access = typeIdSet_undefined;
3113 uentry_setSpecDef (e, f);
3115 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3117 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3123 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3125 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
3128 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3130 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3131 idDecl_getCtype (t),
3134 llassert (fileloc_isUndefined (ue->whereDeclared));
3135 ue->whereDeclared = setLocation ();
3137 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3146 void uentry_setDefState (uentry ue, sstate defstate)
3148 if (uentry_isValid (ue))
3150 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3152 if (uentry_isVariable (ue))
3154 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3159 bool uentry_isCheckedUnknown (uentry ue)
3161 return (uentry_isVar (ue)
3162 && (ue->info->var->checked == CH_UNKNOWN));
3165 bool uentry_isCheckMod (uentry ue)
3167 return (uentry_isVar (ue)
3168 && (ue->info->var->checked == CH_CHECKMOD));
3171 bool uentry_isUnchecked (uentry ue)
3173 return (uentry_isVar (ue)
3174 && (ue->info->var->checked == CH_UNCHECKED));
3177 bool uentry_isChecked (uentry ue)
3179 return (uentry_isVar (ue)
3180 && (ue->info->var->checked == CH_CHECKED));
3183 bool uentry_isCheckedModify (uentry ue)
3185 return (uentry_isVar (ue)
3186 && (ue->info->var->checked == CH_CHECKED
3187 || ue->info->var->checked == CH_CHECKMOD
3188 || ue->info->var->checked == CH_CHECKEDSTRICT));
3191 bool uentry_isCheckedStrict (uentry ue)
3193 return (uentry_isVar (ue)
3194 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3197 void uentry_setUnchecked (uentry ue)
3199 llassert (uentry_isVar (ue));
3201 ue->info->var->checked = CH_UNCHECKED;
3204 void uentry_setChecked (uentry ue)
3206 llassert (uentry_isVar (ue));
3208 ue->info->var->checked = CH_CHECKED;
3211 void uentry_setCheckMod (uentry ue)
3213 llassert (uentry_isVar (ue));
3215 ue->info->var->checked = CH_CHECKMOD;
3218 void uentry_setCheckedStrict (uentry ue)
3220 llassert (uentry_isVar (ue));
3222 ue->info->var->checked = CH_CHECKEDSTRICT;
3225 static /*@only@*/ /*@notnull@*/
3226 uentry uentry_makeVariableAux (cstring n, ctype t,
3228 /*@exposed@*/ sRef s,
3229 bool priv, vkind kind)
3231 uentry e = uentry_alloc ();
3234 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3237 e->uname = cstring_copy (n);
3240 e->storageclass = SCNONE;
3242 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3249 e->uses = filelocList_new ();
3250 e->isPrivate = priv;
3251 e->hasNameError = FALSE;
3253 e->info = (uinfo) dmalloc (sizeof (*e->info));
3254 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3255 e->info->var->kind = kind;
3257 e->info->var->checked = CH_UNKNOWN;
3259 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3260 uentry_setSpecDef (e, f);
3261 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3263 if (ctype_isFunction (rt))
3265 rt = ctype_getReturnType (rt);
3268 if (ctype_isUA (rt))
3270 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3271 sRef_setStateFromType (e->sref, rt);
3274 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3275 e->info->var->defstate = sRef_getDefState (e->sref);
3276 e->info->var->nullstate = sRef_getNullState (e->sref);
3278 /* start modifications */
3279 /* This function sets the uentry for a pointer or array variable declaration,
3280 it allocates memory and sets the fields. We check if the type of the variable
3281 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3283 if( ctype_isArray (t) || ctype_isPointer(t)) {
3284 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3285 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3286 /*@access sRef@*/ /*i@222*/
3287 /* It probably isn't necessary to violate the abstraction here
3290 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3293 e->info->var->bufinfo = NULL;
3295 /* end modification */
3301 uentry_isYield (uentry ue)
3303 return (uentry_isVariable (ue)
3304 && (ue->info->var->kind == VKYIELDPARAM
3305 || ue->info->var->kind == VKREFYIELDPARAM));
3309 uentry_isRefsField (uentry ue)
3311 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3314 /*@only@*/ /*@notnull@*/
3315 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3317 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3318 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3325 void uentry_makeVarFunction (uentry ue)
3332 llassert (uentry_isValid (ue));
3333 llassert (!sRef_modInFunction ());
3335 ak = sRef_getOrigAliasKind (ue->sref);
3336 ek = sRef_getOrigExKind (ue->sref);
3338 oldInfo = ue->info->var;
3340 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3343 ** expanded macro is marked used (until I write a pre-processor)
3346 ue->used |= (oldInfo->kind == VKEXPMACRO);
3349 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3350 ue->info->fcn->exitCode = XK_UNKNOWN;
3351 ue->info->fcn->nullPred = qual_createUnknown ();
3352 ue->info->fcn->specialCode = SPC_NONE;
3353 ue->info->fcn->access = typeIdSet_undefined;
3354 ue->info->fcn->hasGlobs = FALSE;
3355 ue->info->fcn->globs = globSet_undefined;
3356 ue->info->fcn->hasMods = FALSE;
3357 ue->info->fcn->mods = sRefSet_undefined;
3358 ue->info->fcn->specclauses = NULL;
3359 ue->info->fcn->defparams = uentryList_undefined;
3362 ue->info->fcn->preconditions = constraintList_undefined;
3366 ue->info->fcn->postconditions = constraintList_undefined;
3370 if (ctype_isFunction (ue->utype))
3372 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3376 ue->sref = sRef_makeType (ctype_unknown);
3379 if (sRef_isRefCounted (ue->sref))
3385 if (alkind_isUnknown (ak))
3387 if (exkind_isKnown (ek))
3389 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3390 ak = AK_IMPDEPENDENT;
3394 if (context_getFlag (FLG_RETIMPONLY))
3396 if (ctype_isFunction (ue->utype)
3397 && ctype_isVisiblySharable
3398 (ctype_realType (ctype_getReturnType (ue->utype))))
3400 if (uentryList_hasReturned (uentry_getParams (ue)))
3406 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3421 loc = ue->whereDeclared;
3423 sRef_setAliasKind (ue->sref, ak, loc);
3424 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3425 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3426 sRef_setExKind (ue->sref, ek, loc);
3428 if (oldInfo->kind == VKEXPMACRO)
3431 ue->whereDeclared = fileloc_undefined;
3435 fileloc_free (ue->whereDefined);
3436 ue->whereDefined = fileloc_undefined;
3439 uvinfo_free (oldInfo);
3443 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3445 llassert (uentry_isValid (ue));
3447 if (uentry_isIter (ue))
3449 llassert (globSet_isUndefined (ue->info->iter->globs));
3450 ue->info->iter->globs = globs;
3454 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
3456 uentry_makeVarFunction (ue);
3459 llassert (uentry_isFunction (ue));
3460 llassert (!ue->info->fcn->hasGlobs
3461 && globSet_isUndefined (ue->info->fcn->globs));
3463 ue->info->fcn->hasGlobs = TRUE;
3464 globSet_markImmutable (globs);
3465 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3470 if (globSet_hasStatic (globs))
3472 context_recordFileGlobals (globs);
3476 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3478 ue->info->fcn->hasMods = TRUE;
3482 void uentry_addAccessType (uentry ue, typeId tid)
3484 if (uentry_isFunction (ue))
3486 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3488 else if (uentry_isEitherConstant (ue))
3490 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3492 else if (uentry_isIter (ue))
3494 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3496 else if (uentry_isEndIter (ue))
3498 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3502 llbug (message ("no access for: %q", uentry_unparse (ue)));
3506 /*@only@*/ /*@notnull@*/ uentry
3507 uentry_makeFunction (cstring n, ctype t,
3509 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3510 /*@only@*/ warnClause warn,
3513 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3514 return (uentry_makeFunctionAux (n, t,
3515 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3516 : typeIdSet_single (access)),
3523 /*@notnull@*/ uentry
3524 uentry_makePrivFunction2 (cstring n, ctype t,
3526 globSet globs, sRefSet mods,
3529 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3534 /*@notnull@*/ uentry
3535 uentry_makeSpecFunction (cstring n, ctype t,
3537 /*@only@*/ globSet globs,
3538 /*@only@*/ sRefSet mods,
3541 uentry ue = uentry_makeFunctionAux (n, t, access,
3542 globs, mods, warnClause_undefined,
3545 uentry_setHasGlobs (ue);
3546 uentry_setHasMods (ue);
3548 reflectImplicitFunctionQualifiers (ue, TRUE);
3553 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3555 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3556 sRef_undefined, FALSE, VKEXPMACRO);
3558 uentry_setDefined (ue, f);
3562 /*@notnull@*/ /*@notnull@*/ uentry
3563 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3565 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3566 typeIdSet_singleOpt (access),
3567 globSet_undefined, sRefSet_undefined,
3568 warnClause_undefined,
3572 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3576 bool uentry_isForward (uentry e)
3578 if (uentry_isValid (e))
3580 ctype ct = uentry_getType (e);
3582 return (ctype_isUnknown (ct)
3583 || (ctype_isFunction (ct)
3584 && ctype_isUnknown (ctype_getReturnType (ct))));
3591 /*@notnull@*/ uentry
3592 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3594 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3595 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3599 /*@notnull@*/ uentry
3600 uentry_makeUnspecFunction (cstring n, ctype t,
3604 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3605 sRefSet_undefined, warnClause_undefined,
3608 reflectImplicitFunctionQualifiers (ue, TRUE);
3617 /* is exported for use by usymtab_interface */
3619 /*@notnull@*/ uentry
3620 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3621 fileloc f, bool priv)
3623 uentry e = uentry_alloc ();
3625 DPRINTF (("Make datatype: %s / %s",
3626 n, ctype_unparse (t)));
3628 /* e->shallowCopy = FALSE; */
3629 e->ukind = KDATATYPE;
3630 e->uname = cstring_copy (n);
3632 e->storageclass = SCNONE;
3633 e->sref = sRef_makeUnknown ();
3637 sRef_setStateFromType (e->sref, t);
3640 uentry_setSpecDef (e, f);
3642 e->warn = warnClause_undefined; /*@i634@*/
3643 e->uses = filelocList_new ();
3644 e->isPrivate = priv;
3645 e->hasNameError = FALSE;
3650 e->info = (uinfo) dmalloc (sizeof (*e->info));
3651 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3652 e->info->datatype->abs = abstract;
3653 e->info->datatype->mut = mut;
3654 e->info->datatype->type = ctype_undefined;
3656 if (uentry_isDeclared (e))
3658 uentry_setDefined (e, f);
3661 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3663 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3669 /*@notnull@*/ uentry
3670 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3672 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3675 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3677 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3678 ctype_bool, NO, abstract,
3679 fileloc_getBuiltin (),
3682 ret->info->datatype->type = ctype_bool;
3690 static /*@only@*/ /*@notnull@*/ uentry
3691 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3692 /*@only@*/ fileloc f)
3694 uentry e = uentry_alloc ();
3697 e->uname = cstring_copy (n);
3699 e->sref = sRef_makeUnknown ();
3700 e->storageclass = SCNONE;
3704 uentry_setSpecDef (e, f);
3706 e->warn = warnClause_undefined; /*@i452@*/
3707 e->uses = filelocList_new ();
3708 e->isPrivate = FALSE;
3709 e->hasNameError = FALSE;
3711 e->info = (uinfo) dmalloc (sizeof (*e->info));
3712 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3713 e->info->iter->access = access;
3714 e->info->iter->mods = sRefSet_undefined;
3715 e->info->iter->globs = globSet_undefined;
3717 uentry_checkIterArgs (e);
3721 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3723 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3726 static /*@notnull@*/ uentry
3727 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3729 uentry e = uentry_alloc ();
3731 /* e->shallowCopy = FALSE; */
3732 e->ukind = KENDITER;
3733 e->storageclass = SCNONE;
3734 e->uname = message ("end_%s", n);
3735 e->utype = ctype_unknown;
3736 e->sref = sRef_makeUnknown ();
3738 uentry_setSpecDef (e, f);
3743 e->uses = filelocList_new ();
3744 e->isPrivate = FALSE;
3745 e->hasNameError = FALSE;
3747 e->info = (uinfo) dmalloc (sizeof (*e->info));
3748 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3750 e->info->enditer->access = access;
3752 e->warn = warnClause_undefined; /*@i452@*/
3756 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3758 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3765 static /*@only@*/ /*@notnull@*/ uentry
3766 uentry_makeTagAux (cstring n, ctype t,
3767 /*@only@*/ fileloc fl,
3768 bool priv, ekind kind)
3770 uentry e = uentry_alloc ();
3772 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3774 llbuglit ("uentry_makeTagAux: not a tag type");
3778 /* e->shallowCopy = FALSE; */
3779 e->uname = cstring_copy (n);
3782 e->sref = sRef_makeUnknown ();
3783 e->storageclass = SCNONE;
3785 uentry_setSpecDef (e, fl);
3790 e->uses = filelocList_new ();
3791 e->isPrivate = priv;
3792 e->hasNameError = FALSE;
3794 e->info = (uinfo) dmalloc (sizeof (*e->info));
3795 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3796 e->info->datatype->abs = NO;
3797 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3798 e->info->datatype->type = t;
3799 e->warn = warnClause_undefined; /*@i452@*/
3801 if (uentry_isDeclared (e))
3803 uentry_setDefined (e, fl);
3809 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3811 cstring sname = makeStruct (n);
3812 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3814 cstring_free (sname);
3819 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3821 cstring sname = makeStruct (n);
3822 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3824 cstring_free (sname);
3829 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3831 cstring uname = makeUnion (n);
3832 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3834 cstring_free (uname);
3840 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3842 cstring ename = makeEnum (n);
3843 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3845 cstring_free (ename);
3851 uentry_makeUnionTagLoc (cstring n, ctype t)
3853 cstring uname = makeUnion (n);
3854 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3856 cstring_free (uname);
3861 uentry_makeEnumTagLoc (cstring n, ctype t)
3863 cstring ename = makeEnum (n);
3864 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3866 cstring_free (ename);
3871 uentry_isStructTag (uentry ue)
3873 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3877 uentry_isUnionTag (uentry ue)
3879 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3883 uentry_isEnumTag (uentry ue)
3885 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3889 uentry_isAnyTag (uentry ue)
3891 return (uentry_isStructTag (ue)
3892 || uentry_isUnionTag (ue)
3893 || uentry_isEnumTag (ue));
3896 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3898 extern void uentry_destroyMod (void)
3899 /*@globals killed emarker@*/ /*@modifies emarker@*/
3901 static bool wasDestroyed = FALSE;
3903 llassert (!wasDestroyed);
3905 if (emarker != NULL)
3907 uentry_reallyFree (emarker);
3910 wasDestroyed = TRUE;
3914 uentry_makeElipsisMarker (void)
3916 if (emarker == NULL)
3918 emarker = uentry_alloc ();
3920 emarker->ukind = KELIPSMARKER;
3921 emarker->uname = cstring_makeLiteral ("...");
3922 emarker->utype = ctype_elipsMarker;
3923 emarker->sref = sRef_undefined;
3924 emarker->storageclass = SCNONE;
3925 emarker->used = FALSE;
3926 emarker->lset = FALSE;
3927 emarker->info = NULL;
3929 uentry_setSpecDef (emarker, fileloc_undefined);
3930 emarker->uses = filelocList_new ();
3931 emarker->isPrivate = FALSE;
3932 emarker->hasNameError = FALSE;
3935 /*@ignore@*/ return (emarker); /*@end@*/
3943 uentry_equiv (uentry p1, uentry p2)
3945 if (uentry_compare (p1, p2) != 0)
3956 uentry_xcomparealpha (uentry *p1, uentry *p2)
3960 if ((res = uentry_compare (*p1, *p2)) == 0) {
3961 if ((*p1 != NULL) && (*p2 != NULL)) {
3962 res = cstring_compare ((*p1)->uname,
3971 uentry_xcompareuses (uentry *p1, uentry *p2)
3976 if (uentry_isValid (u1))
3978 if (uentry_isValid (u2))
3980 return (-1 * int_compare (filelocList_size (u1->uses),
3981 filelocList_size (u2->uses)));
3990 if (uentry_isValid (u2))
4002 uentry_compareStrict (uentry v1, uentry v2)
4004 COMPARERETURN (uentry_compare (v1, v2));
4006 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4008 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4009 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4010 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4017 uentry_compare (uentry u1, uentry u2)
4019 if (u1 == u2) return 0;
4021 if (uentry_isInvalid (u1)) return -1;
4022 if (uentry_isInvalid (u2)) return 1;
4024 INTCOMPARERETURN (u1->ukind, u2->ukind);
4025 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4026 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4027 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4033 /* bug detected by lclint:
4034 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4039 return (multiVal_compare (u1->info->uconst->val,
4040 u2->info->uconst->val));
4044 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4046 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4047 uentry_accessType (u2)));
4048 return (uentryList_compareParams (uentry_getParams (u1),
4049 uentry_getParams (u2)));
4051 return (typeIdSet_compare (uentry_accessType (u1),
4052 uentry_accessType (u2)));
4055 ** Functions are never equivalent
4058 if ((int) u1 < (int) u2)
4068 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4069 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4070 sRef_getOrigAliasKind (u2->sref)));
4071 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4072 sRef_getOrigExKind (u2->sref)));
4073 COMPARERETURN (generic_compare (u1->info->var->checked,
4074 u2->info->var->checked));
4075 COMPARERETURN (generic_compare (u1->info->var->defstate,
4076 u2->info->var->defstate));
4077 return (generic_compare (u1->info->var->nullstate,
4078 u2->info->var->nullstate));
4080 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4081 u2->info->datatype->type));
4082 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4083 u2->info->datatype->mut));
4084 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4093 ** all entries are: <type>[@<info>]*#<name>
4095 ** info depends on kind:
4099 advanceField (char **s)
4101 reader_checkChar (s, '@');
4105 advanceName (char **s)
4107 reader_checkChar (s, '#');
4111 vkind_fromInt (int i)
4113 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4115 llbuglit ("vkind_fromInt: out of range");
4122 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4123 typeIdSet access, nstate nullstate,
4124 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4126 uentry e = uentry_alloc ();
4131 e->sref = sRef_makeConst (ct);
4133 sRef_setNullState (e->sref, nullstate, loc);
4134 e->storageclass = SCNONE;
4136 if (fileloc_isSpec (loc))
4138 e->whereSpecified = loc;
4139 e->whereDeclared = fileloc_undefined;
4143 e->whereSpecified = fileloc_undefined;
4144 e->whereDeclared = loc;
4147 e->whereDefined = fileloc_undefined;
4148 e->uses = filelocList_new ();
4149 e->isPrivate = FALSE;
4150 e->hasNameError = FALSE;
4155 e->warn = warnClause_undefined; /*@i452@*/
4157 e->info = (uinfo) dmalloc (sizeof (*e->info));
4158 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4159 e->info->uconst->val = m;
4160 e->info->uconst->access = access;
4162 sRef_storeState (e->sref);
4167 static /*@only@*/ uentry
4168 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4169 sstate defstate, nstate isnull, alkind aliased,
4170 exkind exp, chkind checked,
4171 /*@only@*/ fileloc loc)
4173 uentry e = uentry_alloc ();
4178 e->storageclass = SCNONE;
4180 e->sref = sRef_makeType (ct);
4181 sRef_setNullState (e->sref, isnull, loc);
4183 e->whereDefined = fileloc_undefined;
4185 if (fileloc_isSpec (loc))
4187 e->whereSpecified = loc;
4188 e->whereDeclared = fileloc_undefined;
4192 e->whereSpecified = fileloc_undefined;
4193 e->whereDeclared = loc;
4196 e->isPrivate = FALSE;
4197 e->hasNameError = FALSE;
4202 e->uses = filelocList_new ();
4203 e->warn = warnClause_undefined; /*@i452@*/
4205 e->info = (uinfo) dmalloc (sizeof (*e->info));
4206 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4207 e->info->var->kind = kind;
4208 e->info->var->checked = checked;
4209 e->info->var->defstate = defstate;
4211 sRef_setDefState (e->sref, defstate, loc);
4213 e->info->var->nullstate = sRef_getNullState (e->sref);
4215 sRef_setExKind (e->sref, exp, loc);
4216 sRef_setAliasKind (e->sref, aliased, loc);
4218 sRef_storeState (e->sref);
4220 /*DRL ADDED 9-1-2000 */
4221 e->info->var->bufinfo = NULL;
4226 static /*@only@*/ uentry
4227 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4228 ynm mut, ctype rtype, alkind ak, exkind exp,
4229 sstate defstate, nstate isnull,
4230 /*@only@*/ fileloc loc)
4232 uentry e = uentry_alloc ();
4234 e->ukind = KDATATYPE;
4235 /* e->shallowCopy = FALSE; */
4238 e->storageclass = SCNONE;
4239 e->sref = sRef_makeUnknown ();
4240 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4243 ** This is only setting null state. (I think?)
4246 if (ctype_isUA (ct))
4248 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4250 if (uentry_isValid (te))
4252 sRef_setStateFromUentry (e->sref, te);
4256 /* problem for recursive type definitions */
4260 sRef_setAliasKind (e->sref, ak, loc);
4261 sRef_setExKind (e->sref, exp, loc);
4263 sRef_setDefState (e->sref, defstate, loc);
4265 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4267 isnull = NS_ABSNULL;
4270 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4271 sRef_mergeNullState (e->sref, isnull);
4273 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4275 if (fileloc_isSpec (loc))
4277 e->whereSpecified = loc;
4278 e->whereDeclared = fileloc_undefined;
4282 e->whereSpecified = fileloc_undefined;
4283 e->whereDeclared = loc;
4286 e->isPrivate = FALSE;
4287 e->hasNameError = FALSE;
4289 e->warn = warnClause_undefined; /*@i452@*/
4293 e->uses = filelocList_new ();
4295 e->info = (uinfo) dmalloc (sizeof (*e->info));
4296 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4297 e->info->datatype->abs = abstract;
4298 e->info->datatype->mut = mut;
4299 e->info->datatype->type = rtype;
4301 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4302 sRef_storeState (e->sref);
4303 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4309 static void uentry_setHasGlobs (uentry ue)
4311 llassert (uentry_isFunction (ue));
4313 ue->info->fcn->hasGlobs = TRUE;
4316 static void uentry_setHasMods (uentry ue)
4318 llassert (uentry_isFunction (ue));
4320 ue->info->fcn->hasMods = TRUE;
4324 bool uentry_hasGlobs (uentry ue)
4326 if (uentry_isFunction (ue))
4328 return (ue->info->fcn->hasGlobs);
4334 bool uentry_hasStateClauseList (uentry ue)
4336 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4339 stateClauseList uentry_getStateClauseList (uentry ue)
4341 if (!uentry_isFunction (ue))
4343 llassert (uentry_isFunction (ue));
4344 return stateClauseList_undefined;
4347 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4348 return ue->info->fcn->specclauses;
4351 bool uentry_hasMods (uentry ue)
4353 if (uentry_isFunction (ue))
4355 return (ue->info->fcn->hasMods);
4362 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4364 bool hasGlobs, /*@only@*/ globSet globs,
4365 bool hasMods, /*@only@*/ sRefSet mods,
4366 alkind ak, exkind exp,
4367 sstate defstate, nstate isnull,
4371 /*@only@*/ stateClauseList specclauses,
4372 /*@only@*/ warnClause warnclause,
4373 /*@only@*/ fileloc loc)
4375 uentry e = uentry_alloc ();
4378 /* e->shallowCopy = FALSE; */
4382 e->storageclass = SCNONE;
4384 if (ctype_isFunction (ct))
4386 ret = ctype_getReturnType (ct);
4390 if (ctype_isKnown (ct))
4392 llbug (message ("not function: %s", ctype_unparse (ct)));
4395 ret = ctype_unknown;
4398 e->sref = sRef_makeType (ret);
4400 if (ctype_isUA (ret))
4402 sRef_setStateFromType (e->sref, ret);
4405 sRef_setDefined (e->sref, loc);
4406 sRef_setNullState (e->sref, isnull, loc);
4408 sRef_setAliasKind (e->sref, ak, loc);
4409 sRef_setExKind (e->sref, exp, loc);
4410 sRef_setDefState (e->sref, defstate, loc);
4412 e->whereSpecified = loc;
4413 e->whereDefined = fileloc_undefined;
4415 e->isPrivate = FALSE;
4416 e->hasNameError = FALSE;
4420 e->uses = filelocList_new ();
4421 e->warn = warnclause;
4423 e->info = (uinfo) dmalloc (sizeof (*e->info));
4424 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4426 e->info->fcn->exitCode = exitCode;
4427 e->info->fcn->specialCode = sCode;
4428 e->info->fcn->nullPred = nullPred;
4429 e->info->fcn->access = access;
4431 e->info->fcn->specclauses = specclauses;
4432 e->info->fcn->hasGlobs = hasGlobs;
4433 e->info->fcn->globs = globs;
4435 e->info->fcn->hasMods = hasMods;
4436 e->info->fcn->mods = mods;
4438 e->info->fcn->defparams = uentryList_undefined;
4439 e->whereDeclared = fileloc_undefined;
4441 sRef_storeState (e->sref);
4444 e->info->fcn->preconditions = NULL;
4448 e->info->fcn->postconditions = NULL;
4454 static /*@only@*/ uentry
4455 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4456 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4458 uentry e = uentry_alloc ();
4460 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4462 llbuglit ("uentry_makeTagBase: not a tag type");
4465 /* e->shallowCopy = FALSE; */
4469 e->sref = sRef_makeUnknown ();
4470 e->storageclass = SCNONE;
4472 if (fileloc_isSpec (loc))
4474 e->whereSpecified = loc;
4475 e->whereDeclared = fileloc_undefined;
4479 e->whereDeclared = loc;
4480 e->whereSpecified = fileloc_undefined;
4483 e->whereDefined = fileloc_undefined;
4485 e->isPrivate = FALSE;
4486 e->hasNameError = FALSE;
4490 e->uses = filelocList_new ();
4491 e->warn = warnClause_undefined; /*@i452@*/
4493 e->info = (uinfo) dmalloc (sizeof (*e->info));
4494 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4495 e->info->datatype->abs = NO;
4496 e->info->datatype->mut = MAYBE;
4497 e->info->datatype->type = rtype;
4499 sRef_storeState (e->sref);
4505 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4506 ctype ct, /*@only@*/ fileloc loc)
4508 uentry e = uentry_alloc ();
4510 /* e->shallowCopy = FALSE; */
4514 e->sref = sRef_makeUnknown ();
4515 e->storageclass = SCNONE;
4517 if (fileloc_isSpec (loc))
4519 e->whereSpecified = loc;
4520 e->whereDeclared = fileloc_undefined;
4524 e->whereDeclared = loc;
4525 e->whereSpecified = fileloc_undefined;
4528 e->whereDefined = fileloc_undefined;
4530 e->isPrivate = FALSE;
4531 e->hasNameError = FALSE;
4535 e->uses = filelocList_new ();
4536 e->warn = warnClause_undefined; /*@i452@*/
4538 e->info = (uinfo) dmalloc (sizeof (*e->info));
4539 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4540 e->info->iter->access = access;
4541 e->info->iter->mods = sRefSet_undefined;
4542 e->info->iter->globs = globSet_undefined;
4544 sRef_storeState (e->sref);
4549 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4550 /*@only@*/ fileloc loc)
4552 uentry e = uentry_alloc ();
4554 /* e->shallowCopy = FALSE; */
4555 e->ukind = KENDITER;
4556 e->storageclass = SCNONE;
4558 e->utype = ctype_unknown;
4559 e->sref = sRef_makeUnknown ();
4561 if (fileloc_isSpec (loc))
4563 e->whereSpecified = loc;
4564 e->whereDeclared = fileloc_undefined;
4568 e->whereDeclared = loc;
4569 e->whereSpecified = fileloc_undefined;
4572 e->whereDefined = fileloc_undefined;
4574 e->isPrivate = FALSE;
4575 e->hasNameError = FALSE;
4579 e->uses = filelocList_new ();
4580 e->warn = warnClause_undefined; /*@i452@*/
4582 e->info = (uinfo) dmalloc (sizeof (*e->info));
4583 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4584 e->info->enditer->access = access;
4585 sRef_storeState (e->sref);
4590 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4598 uentry_undump (ekind kind, fileloc loc, char **s)
4602 DPRINTF (("Uentry undump: %s", *s));
4606 reader_checkChar (s, '!');
4607 reader_checkChar (s, '.');
4608 ue = uentry_makeElipsisMarker ();
4612 ctype ct = ctype_undump (s);
4626 reader_checkChar (s, '|');
4628 if (reader_optCheckChar (s, '@'))
4630 tkind = vkind_fromInt (reader_getInt (s));
4631 reader_checkChar (s, '|');
4638 if (reader_optCheckChar (s, '$'))
4640 defstate = SS_UNKNOWN;
4641 isnull = NS_UNKNOWN;
4642 aliased = AK_IMPTEMP;
4644 checked = CH_UNKNOWN;
4646 else if (reader_optCheckChar (s, '&'))
4648 defstate = SS_DEFINED;
4649 isnull = NS_UNKNOWN;
4650 aliased = AK_IMPTEMP;
4652 checked = CH_UNKNOWN;
4654 else if (reader_optCheckChar (s, '^'))
4656 defstate = SS_UNKNOWN;
4657 isnull = NS_UNKNOWN;
4658 aliased = AK_IMPTEMP;
4660 checked = CH_UNKNOWN;
4664 defstate = sstate_fromInt (reader_getInt (s));
4665 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4666 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4668 if (reader_optCheckChar (s, '&'))
4671 checked = CH_UNKNOWN;
4675 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4676 advanceField (s); checked = (chkind) (reader_getInt (s));
4681 name = reader_getStringWord (s);
4683 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4685 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4686 isnull, aliased, exp,
4687 checked, fileloc_copy (loc));
4700 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4701 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4702 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4703 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4704 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4705 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4706 advanceField (s); rtype = ctype_undump (s);
4708 name = reader_getStringWord (s);
4709 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4710 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4711 aliased, exp, defstate, isnull,
4712 fileloc_copy (loc));
4729 stateClauseList specclauses = stateClauseList_undefined;
4730 warnClause warnclause = warnClause_undefined;
4732 if (reader_optCheckChar (s, '$'))
4734 defstate = SS_DEFINED;
4735 isnull = NS_UNKNOWN;
4736 exitCode = XK_UNKNOWN;
4738 nullPred = qual_createUnknown ();
4742 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4743 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4744 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4745 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4746 advanceField (s); nullPred = qual_undump (s);
4749 if (reader_optCheckChar (s, '$'))
4752 globs = globSet_undefined;
4754 mods = sRefSet_undefined;
4756 else if (reader_optCheckChar (s, '^'))
4759 globs = globSet_undefined;
4761 mods = sRefSet_undefined;
4765 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4766 advanceField (s); globs = globSet_undump (s);
4767 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4768 advanceField (s); mods = sRefSet_undump (s);
4771 if (reader_optCheckChar (s, '$'))
4778 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4779 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4782 advanceField (s); access = typeIdSet_undump (s);
4785 ** Optional clauses: Start with @<code>:
4788 while (reader_optCheckChar (s, '@'))
4790 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4792 reader_checkChar (s, ':');
4793 warnclause = warnClause_undump (s);
4795 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4797 reader_checkChar (s, ':');
4798 specclauses = stateClauseList_undump (s);
4806 advanceName (s); name = reader_getStringWord (s);
4808 ue = uentry_makeFunctionBase (name, ct, access,
4811 ak, exp, defstate, isnull,
4812 exitCode, specc, nullPred,
4815 fileloc_copy (loc));
4816 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4823 advanceField (s); access = typeIdSet_undump (s);
4824 advanceName (s); name = reader_getStringWord (s);
4826 ue = uentry_makeIterBase (name, access, ct,
4827 fileloc_copy (loc));
4834 advanceField (s); access = typeIdSet_undump (s);
4835 advanceName (s); name = reader_getStringWord (s);
4837 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4847 if (reader_optCheckChar (s, '$'))
4849 val = multiVal_undefined;
4850 access = typeIdSet_undefined;
4851 nullstate = NS_UNKNOWN;
4855 advanceField (s); val = multiVal_undump (s);
4856 advanceField (s); access = typeIdSet_undump (s);
4857 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4860 advanceName (s); name = reader_getStringWord (s);
4862 ue = uentry_makeConstantBase (name, ct, access,
4863 nullstate, fileloc_copy (loc), val);
4872 advanceField (s); rtype = ctype_undump (s);
4873 advanceName (s); name = reader_getStringWord (s);
4874 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4878 llcontbuglit ("uentry_undump: invalid");
4879 ue = uentry_undefined;
4882 llcontbuglit ("uentry_undump: elips marker");
4883 ue = uentry_undefined;
4892 uentry_dump (uentry v)
4894 return (uentry_dumpAux (v, FALSE));
4898 uentry_dumpParam (uentry v)
4900 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4901 ("dump: %s", uentry_unparseFull (v)));
4903 return (uentry_dumpAux (v, TRUE));
4907 uentry_dumpAux (uentry v, bool isParam)
4909 llassert (uentry_isValid (v));
4910 llassert (!uentry_isGlobalMarker (v));
4912 DPRINTF (("Dump uentry: [%p]", v));
4913 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
4918 llcontbuglit ("uentry_dump: invalid entry");
4919 return cstring_undefined;
4921 return (message ("!."));
4925 vkind vk = v->info->var->kind;
4926 sstate dss = sRef_getDefState (v->sref);
4927 nstate nst = sRef_getNullState (v->sref);
4928 alkind alk = sRef_getAliasKind (v->sref);
4929 exkind exk = sRef_getExKind (v->sref);
4930 chkind chk = v->info->var->checked;
4932 DPRINTF (("Dumping var"));
4934 if (dss == SS_UNKNOWN
4935 && nst == NS_UNKNOWN
4936 && alk == AK_IMPTEMP
4937 && exk == XO_UNKNOWN
4938 && chk == CH_UNKNOWN)
4940 sdump = cstring_makeLiteral ("$");
4942 else if (dss == SS_DEFINED
4943 && nst == NS_UNKNOWN
4944 && alk == AK_IMPTEMP
4945 && exk == XO_UNKNOWN
4946 && chk == CH_UNKNOWN)
4948 sdump = cstring_makeLiteral ("&");
4950 else if (dss == SS_UNKNOWN
4951 && nst == NS_UNKNOWN
4952 && alk == AK_UNKNOWN
4953 && exk == XO_UNKNOWN
4954 && chk == CH_UNKNOWN)
4956 sdump = cstring_makeLiteral ("^");
4958 else if (exk == XO_UNKNOWN
4959 && chk == CH_UNKNOWN)
4961 sdump = message ("%d@%d@%d&",
4968 sdump = message ("%d@%d@%d@%d@%d",
4979 return (message ("%q|@%d|%q#%s",
4980 ctype_dump (v->utype),
4983 isParam ? cstring_undefined : v->uname));
4987 return (message ("%q|%q#%s",
4988 ctype_dump (v->utype),
4990 isParam ? cstring_undefined : v->uname));
4996 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
4998 exkind_unparse (sRef_getExKind (v->sref)),
4999 ctype_unparse (v->utype), (int) v->utype));
5002 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5003 ctype_dump (v->utype),
5004 ynm_unparseCode (v->info->datatype->abs),
5005 ynm_unparseCode (v->info->datatype->mut),
5006 (int) sRef_getDefState (v->sref),
5007 (int) sRef_getNullState (v->sref),
5008 (int) sRef_getAliasKind (v->sref),
5009 (int) sRef_getExKind (v->sref),
5010 ctype_dump (v->info->datatype->type),
5014 cstring sdump, gdump, adump, xdump;
5015 alkind alk = sRef_getAliasKind (v->sref);
5016 exkind exk = sRef_getExKind (v->sref);
5018 if (sRef_getDefState (v->sref) == SS_DEFINED
5019 && !nstate_isKnown (sRef_getNullState (v->sref))
5020 && !exitkind_isKnown (v->info->fcn->exitCode)
5021 && v->info->fcn->specialCode == SPC_NONE
5022 && qual_isUnknown (v->info->fcn->nullPred))
5024 sdump = cstring_makeLiteral ("$");
5028 sdump = message ("@%d@%d@%d@%d@%x",
5029 (int) sRef_getDefState (v->sref),
5030 (int) sRef_getNullState (v->sref),
5031 (int) v->info->fcn->exitCode,
5032 (int) v->info->fcn->specialCode,
5033 qual_dump (v->info->fcn->nullPred));
5036 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5038 gdump = cstring_makeLiteral ("$");
5040 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5041 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5043 gdump = cstring_makeLiteral ("^");
5047 gdump = message ("@%s@%q@%s@%q",
5048 bool_dump (uentry_hasGlobs (v)),
5049 globSet_dump (uentry_getGlobs (v)),
5050 bool_dump (uentry_hasMods (v)),
5051 sRefSet_dump (uentry_getMods (v)));
5054 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5056 adump = cstring_makeLiteral ("$");
5060 adump = message ("@%d@%d", (int) alk, (int) exk);
5063 xdump = cstring_undefined;
5065 if (uentry_hasWarning (v))
5067 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5070 if (uentry_hasStateClauseList (v))
5072 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5075 return (message ("%q%q%q%q@%q%q#%s",
5076 ctype_dump (v->utype),
5080 typeIdSet_dump (uentry_accessType (v)),
5085 return (message ("%q@%q#%s",
5086 ctype_dump (v->utype),
5087 typeIdSet_dump (v->info->iter->access),
5090 return (message ("%q@%q#%s",
5091 ctype_dump (v->utype),
5092 typeIdSet_dump (uentry_accessType (v)),
5099 if (multiVal_isUnknown (v->info->uconst->val)
5100 && typeIdSet_isEmpty (uentry_accessType (v))
5101 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5103 sdump = cstring_makeLiteral ("$");
5107 sdump = message ("@%q@%q@%d",
5108 multiVal_dump (v->info->uconst->val),
5109 typeIdSet_dump (uentry_accessType (v)),
5110 (int) sRef_getNullState (v->sref));
5113 return (message ("%q%q#%s",
5114 ctype_dump (v->utype),
5121 return (message ("%q@%q#%s",
5122 ctype_dump (v->utype),
5123 ctype_dump (v->info->datatype->type), v->uname));
5130 uentry_unparseAbbrev (uentry v)
5132 if (!uentry_isVariable (v))
5134 llcontbuglit ("uentry_unparseAbbrev: not variable");
5135 return uentry_unparse (v);
5138 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5142 uentry_unparse (uentry v)
5146 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5147 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5149 st = uentry_getName (v);
5151 if (cstring_isDefined (st))
5153 return (ctype_unparseDeclaration (v->utype, st));
5158 return (cstring_copy (ctype_unparse (v->utype)));
5163 uentry_unparseFull (uentry v)
5165 if (uentry_isUndefined (v))
5167 return (cstring_makeLiteral ("<undefined>"));
5173 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5174 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5175 ctype_unparse (v->utype),
5176 fileloc_unparse (uentry_whereSpecified (v)),
5177 fileloc_unparse (uentry_whereDeclared (v)),
5178 fileloc_unparse (uentry_whereDefined (v)));
5180 DPRINTF (("uentry: %s", res));
5182 if (uentry_isDatatype (v))
5184 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5187 (ctype_isDefined (v->info->datatype->type)
5188 ? v->info->datatype->type : ctype_unknown),
5189 ynm_unparse (v->info->datatype->mut),
5190 ynm_unparse (v->info->datatype->abs),
5191 sRef_unparseState (v->sref));
5193 else if (uentry_isFunction (v))
5195 res = message ("%q / sref: %q / mods: %q / "
5196 "globs: %q / clauses: %q",
5198 sRef_unparseFull (v->sref),
5199 sRefSet_unparse (v->info->fcn->mods),
5200 globSet_unparse (v->info->fcn->globs),
5201 stateClauseList_unparse (v->info->fcn->specclauses));
5203 else if (uentry_isIter (v))
5205 res = message ("%q / sref: %q",
5207 sRef_unparseFull (v->sref));
5209 else if (uentry_isVariable (v))
5211 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5213 sRef_unparseFull (v->sref),
5214 (int) v->info->var->kind,
5215 (int) v->info->var->defstate,
5216 (int) v->info->var->nullstate,
5218 DPRINTF (("sref: [%p]", v->sref));
5219 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5220 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5224 res = message ("%q :: %q", res, uentry_unparse (v));
5231 bool uentry_hasAccessType (uentry e)
5233 if (uentry_isValid (e))
5238 return (!typeIdSet_isEmpty (e->info->iter->access));
5240 return (!typeIdSet_isEmpty (e->info->enditer->access));
5242 return (!typeIdSet_isEmpty (e->info->fcn->access));
5245 return (!typeIdSet_isEmpty (e->info->uconst->access));
5254 typeIdSet uentry_accessType (uentry e)
5256 if (uentry_isValid (e))
5261 return (e->info->iter->access);
5263 return (e->info->enditer->access);
5265 return (e->info->fcn->access);
5268 return (e->info->uconst->access);
5274 return typeIdSet_undefined;
5278 uentry_isVariable (uentry e)
5280 return (uentry_isVar (e));
5284 uentry_isSpecified (uentry e)
5286 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5290 uentry_isReallySpecified (uentry e)
5292 return (uentry_isValid (e)
5293 && fileloc_isRealSpec (e->whereSpecified));
5297 uentry_isVar (uentry e)
5299 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5303 uentry_isFakeTag (uentry e)
5305 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5309 uentry_isDatatype (uentry e)
5311 return (!uentry_isUndefined (e) &&
5312 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5313 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5317 uentry_setAbstract (uentry e)
5321 llassert (uentry_isDatatype (e)
5322 && (ynm_isMaybe (e->info->datatype->abs)));
5324 oldid = ctype_typeId (e->info->datatype->type);
5325 e->info->datatype->abs = YES;
5326 e->info->datatype->type = ctype_createAbstract (oldid);
5330 uentry_setConcrete (uentry e)
5332 llassert (uentry_isDatatype (e)
5333 && (ynm_isMaybe (e->info->datatype->abs)));
5335 e->info->datatype->abs = NO;
5339 uentry_isAbstractDatatype (uentry e)
5341 return (uentry_isDatatype (e)
5342 && (ynm_isOn (e->info->datatype->abs)));
5346 uentry_isMaybeAbstract (uentry e)
5348 return (uentry_isDatatype (e)
5349 && (ynm_isMaybe (e->info->datatype->abs)));
5353 uentry_isMutableDatatype (uentry e)
5355 bool res = uentry_isDatatype (e)
5356 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5362 uentry_isRefCountedDatatype (uentry e)
5364 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5368 uentry_isParam (uentry u)
5370 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5371 || u->info->var->kind == VKYIELDPARAM));
5375 uentry_isExpandedMacro (uentry u)
5377 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5381 uentry_isSefParam (uentry u)
5383 return (uentry_isVariable (u)
5384 && (u->info->var->kind == VKSEFPARAM
5385 || u->info->var->kind == VKREFSEFPARAM
5386 || u->info->var->kind == VKSEFRETPARAM
5387 || u->info->var->kind == VKREFSEFRETPARAM));
5391 uentry_isRefParam (uentry u)
5393 return (uentry_isVariable (u)
5394 && (u->info->var->kind == VKREFPARAM
5395 || u->info->var->kind == VKREFYIELDPARAM
5396 || u->info->var->kind == VKREFSEFPARAM
5397 || u->info->var->kind == VKREFSEFRETPARAM));
5401 uentry_isAnyParam (uentry u)
5403 return (uentry_isVariable (u)
5404 && ((u->info->var->kind == VKPARAM)
5405 || (u->info->var->kind == VKSEFPARAM)
5406 || (u->info->var->kind == VKYIELDPARAM)
5407 || (u->info->var->kind == VKRETPARAM)
5408 || (u->info->var->kind == VKSEFRETPARAM)));
5412 uentry_getDefState (uentry u)
5414 if (uentry_isValid (u))
5416 return (sRef_getDefState (u->sref));
5420 return (SS_UNKNOWN);
5425 uentry_isOut (uentry u)
5427 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5428 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5432 uentry_isPartial (uentry u)
5434 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5435 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5439 uentry_isStateSpecial (uentry u)
5441 return ((uentry_isVariable (u)
5442 && (u->info->var->defstate == SS_SPECIAL))
5443 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5446 exitkind uentry_getExitCode (uentry ue)
5448 if (uentry_isFunction (ue))
5450 return ue->info->fcn->exitCode;
5458 qual uentry_nullPred (uentry u)
5460 llassert (uentry_isRealFunction (u));
5462 if (uentry_isFunction (u))
5464 return (u->info->fcn->nullPred);
5468 return qual_createUnknown ();
5473 ** Note for variables, this is checking the declared state, not the current state.
5477 uentry_possiblyNull (uentry u)
5479 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5480 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5484 uentry_getAliasKind (uentry u)
5486 if (uentry_isValid (u))
5488 return (sRef_getAliasKind (uentry_getSref (u)));
5497 uentry_getExpKind (uentry u)
5499 if (uentry_isValid (u))
5501 return (sRef_getExKind (uentry_getSref (u)));
5510 uentry_isIter (uentry e)
5512 return (!uentry_isUndefined (e) && e->ukind == KITER);
5516 uentry_isEndIter (uentry e)
5518 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5522 uentry_isRealFunction (uentry e)
5524 return (uentry_isFunction (e) ||
5525 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5529 uentry_hasName (uentry e)
5531 if (uentry_isValid (e))
5533 cstring s = e->uname;
5535 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5536 || uentry_isFakeTag (e)));
5545 ** Returns true for fake tags.
5546 ** This is used for dumping the library
5549 bool uentry_hasRealName (uentry e)
5551 return (uentry_isValid (e)
5552 && cstring_isNonEmpty (e->uname)
5553 && !uentry_isGlobalMarker (e));
5557 /*@observer@*/ globSet
5558 uentry_getGlobs (uentry l)
5560 if (uentry_isInvalid (l))
5562 return globSet_undefined;
5565 if (l->ukind != KFCN)
5567 if (l->ukind != KITER && l->ukind != KENDITER)
5569 if (l->ukind == KVAR)
5571 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5573 ekind_unparse (l->ukind)));
5577 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5579 ekind_unparse (l->ukind)));
5582 return globSet_undefined;
5585 return l->info->fcn->globs;
5588 /*@observer@*/ sRefSet
5589 uentry_getMods (uentry l)
5591 llassert (uentry_isValid (l));
5593 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5595 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5596 return sRefSet_undefined;
5599 return l->info->fcn->mods;
5603 uentry_getKind (uentry e)
5605 llassert (uentry_isValid (e));
5610 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5612 llassert (uentry_isEitherConstant (e));
5614 return (e->info->uconst->val);
5617 /*@observer@*/ uentryList
5618 uentry_getParams (uentry l)
5620 if (uentry_isInvalid (l)) return uentryList_undefined;
5627 ctype ct = l->utype;
5629 if (ctype_isFunction (ct))
5631 return (ctype_argsFunction (ct));
5635 return uentryList_undefined;
5640 ctype ct = l->utype;
5642 llassert (ctype_isFunction (ct));
5643 return (ctype_argsFunction (ct));
5650 /*@observer@*/ cstring
5651 uentry_rawName (uentry e)
5653 if (uentry_isValid (e))
5659 return cstring_undefined;
5664 uentry_getOptName (uentry e)
5666 cstring s = uentry_getName (e);
5668 if (cstring_isDefined (s))
5670 s = cstring_appendChar (s, ' ');
5677 uentry_getName (uentry e)
5679 cstring ret = cstring_undefined;
5681 if (uentry_isValid (e))
5683 if (uentry_isAnyTag (e))
5685 ret = fixTagName (e->uname);
5687 else if (uentry_isAnyParam (e))
5689 ret = cstring_copy (fixParamName (e->uname));
5693 ret = cstring_copy (e->uname);
5700 cstring uentry_observeRealName (uentry e)
5702 cstring ret = cstring_undefined;
5704 if (uentry_isValid (e))
5706 if (uentry_isAnyTag (e))
5708 if (isFakeTag (e->uname))
5710 ret = cstring_undefined;
5714 ret = plainTagName (e->uname);
5717 else if (uentry_isAnyParam (e))
5719 ret = fixParamName (e->uname);
5730 cstring uentry_getRealName (uentry e)
5732 if (uentry_isValid (e))
5734 if (uentry_isAnyTag (e))
5736 return (cstring_undefined);
5743 return cstring_undefined;
5746 ctype uentry_getType (uentry e)
5748 if (uentry_isValid (e))
5754 return ctype_unknown;
5758 fileloc uentry_whereLast (uentry e)
5762 if (uentry_isInvalid (e))
5764 return fileloc_undefined;
5767 loc = e->whereDefined;
5769 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5774 loc = uentry_whereDeclared (e);
5776 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5781 loc = uentry_whereSpecified (e);
5785 fileloc uentry_whereEither (uentry e)
5787 if (uentry_isInvalid (e)) return fileloc_undefined;
5789 if (fileloc_isDefined (e->whereDefined)
5790 && !fileloc_isExternal (e->whereDefined))
5792 return e->whereDefined;
5794 else if (fileloc_isDefined (e->whereDeclared))
5796 return e->whereDeclared;
5800 return e->whereSpecified;
5804 fileloc uentry_whereSpecified (uentry e)
5806 if (uentry_isInvalid (e)) return fileloc_undefined;
5808 return (e->whereSpecified);
5811 fileloc uentry_whereDefined (uentry e)
5813 if (uentry_isInvalid (e)) return fileloc_undefined;
5815 return (e->whereDefined);
5818 fileloc uentry_whereDeclared (uentry e)
5820 if (uentry_isInvalid (e)) return fileloc_undefined;
5822 return (e->whereDeclared);
5825 /*@observer@*/ fileloc
5826 uentry_whereEarliest (uentry e)
5828 if (uentry_isInvalid (e)) return fileloc_undefined;
5830 if (fileloc_isDefined (e->whereSpecified))
5832 return (e->whereSpecified);
5834 else if (fileloc_isDefined (e->whereDeclared))
5836 return (e->whereDeclared);
5840 return e->whereDefined;
5845 uentry_setFunctionDefined (uentry e, fileloc loc)
5847 if (uentry_isValid (e))
5849 llassert (uentry_isFunction (e));
5851 if (fileloc_isUndefined (e->whereDeclared))
5853 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5856 if (!fileloc_isDefined (e->whereDefined))
5858 e->whereDefined = fileloc_update (e->whereDefined, loc);
5864 uentry_setDeclDef (uentry e, fileloc f)
5866 uentry_setDeclared (e, f);
5868 if (!uentry_isFunction (e)
5869 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5871 uentry_setDefined (e, f);
5876 uentry_setDeclaredForce (uentry e, fileloc f)
5878 llassert (uentry_isValid (e));
5879 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5883 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5885 llassert (uentry_isValid (e));
5886 fileloc_free (e->whereDeclared);
5887 e->whereDeclared = f;
5891 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5895 llassert (uentry_isValid (e));
5896 oldloc = e->whereDeclared;
5898 if (fileloc_isDefined (oldloc))
5900 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5902 e->whereDeclared = f;
5903 fileloc_free (oldloc);
5912 e->whereDeclared = f;
5913 fileloc_free (oldloc);
5918 uentry_setDeclared (uentry e, fileloc f)
5922 llassert (uentry_isValid (e));
5923 oldloc = e->whereDeclared;
5925 if (fileloc_isDefined (oldloc))
5927 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5929 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5938 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5943 uentry_clearDefined (uentry e)
5945 if (uentry_isValid (e))
5947 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5952 uentry_setDefined (uentry e, fileloc f)
5956 llassert (uentry_isValid (e));
5957 oldloc = e->whereDefined;
5959 if (fileloc_isDefined (oldloc))
5961 if (fileloc_isLib (oldloc)
5962 || fileloc_isImport (oldloc)
5963 || fileloc_isBuiltin (oldloc)
5964 || fileloc_isPreproc (oldloc))
5966 e->whereDefined = fileloc_update (e->whereDefined, f);
5970 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5976 if (optgenerror (FLG_REDEF,
5977 message ("%s %q redefined",
5978 ekind_capName (e->ukind),
5979 uentry_getName (e)),
5982 llgenindentmsg (message ("Previous definition of %q",
5983 uentry_getName (e)),
5991 e->whereDefined = fileloc_update (e->whereDefined, f);
5996 uentry_isCodeDefined (uentry e)
5998 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
6002 uentry_isDeclared (uentry e)
6004 if (uentry_isValid (e))
6006 return (fileloc_isDefined (e->whereDeclared));
6012 sRef uentry_getSref (uentry e)
6014 /* not true, used for functions too (but shouldn't be? */
6015 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6017 if (uentry_isInvalid (e)) return sRef_undefined;
6022 sRef uentry_getOrigSref (uentry e)
6024 if (uentry_isValid (e))
6026 sRef sr = sRef_copy (uentry_getSref (e));
6028 sRef_resetState (sr);
6029 sRef_clearDerived (sr);
6031 if (uentry_isVariable (e))
6033 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6034 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6041 return sRef_undefined;
6046 ** requires: uentry e is not in a hashed symbol table
6050 uentry_setName (uentry e, /*@only@*/ cstring n)
6052 llassert (uentry_isValid (e));
6054 cstring_free (e->uname);
6059 uentry_setType (uentry e, ctype t)
6061 if (uentry_isValid (e))
6064 sRef_setType (e->sref, t);
6069 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6072 ctype rettype = ctype_unknown;
6074 llassert (uentry_isValid (ue));
6076 rct = ctype_realType (ue->utype);
6078 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
6080 uentry_makeVarFunction (ue);
6083 llassert (uentry_isFunction (ue));
6085 if (ctype_isFunction (rct))
6087 rettype = ctype_getReturnType (rct);
6090 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6094 uentry_setRefParam (uentry e)
6097 if (!uentry_isVar (e))
6099 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6103 if (e->info->var->kind == VKSEFPARAM)
6105 e->info->var->kind = VKREFSEFPARAM;
6107 else if (e->info->var->kind == VKSEFRETPARAM)
6109 e->info->var->kind = VKREFSEFRETPARAM;
6111 else if (e->info->var->kind == VKYIELDPARAM)
6113 e->info->var->kind = VKREFYIELDPARAM;
6117 e->info->var->kind = VKREFPARAM;
6123 uentry_setParam (uentry e)
6125 if (!uentry_isVar (e))
6127 if (uentry_isElipsisMarker (e))
6133 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6140 if (e->info->var->kind == VKYIELDPARAM
6141 || e->info->var->kind == VKSEFPARAM
6142 || e->info->var->kind == VKSEFRETPARAM)
6148 e->info->var->kind = VKPARAM;
6152 e->uname = makeParam (e->uname);
6153 cstring_free (oldname);
6158 uentry_setSref (uentry e, sRef s)
6160 if (uentry_isValid (e))
6162 if (sRef_isValid (e->sref))
6164 sRef_mergeStateQuietReverse (e->sref, s);
6168 e->sref = sRef_saveCopy (s);
6174 uentry_getAbstractType (uentry e)
6176 llassert (uentry_isDatatype (e));
6179 ** This assertion removed.
6180 ** Okay to have undefined type, for system types
6182 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6183 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6188 if (ctype_isUndefined (e->info->datatype->type))
6190 return ctype_unknown;
6194 ** Sadly, a kludge...
6197 if (ctype_isUserBool (e->info->datatype->type)) {
6201 return e->info->datatype->type;
6204 ctype uentry_getRealType (uentry e)
6207 typeId uid = USYMIDINVALID;
6209 if (uentry_isInvalid (e))
6211 return ctype_unknown;
6214 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6216 if (uentry_isAnyTag (e))
6221 if (uentry_isAbstractType (e))
6223 ct = uentry_getAbstractType (e);
6225 if (ctype_isManifestBool (ct)) {
6229 llassert (ctype_isUA (ct));
6231 uid = ctype_typeId (ct);
6233 if (!context_hasAccess (uid))
6239 ct = uentry_getType (e);
6241 /* if (ctype_isUserBool (ct)) return ct; */
6243 if (ctype_isManifestBool (ct)) {
6247 if (ctype_isUA (ct))
6249 usymId iid = ctype_typeId (ct);
6251 if (usymId_equal (iid, uid))
6253 llcontbug (message ("uentry_getRealType: recursive type! %s",
6254 ctype_unparse (ct)));
6259 /* evs 2000-07-25: possible infinite recursion ? */
6260 uentry ue2 = usymtab_getTypeEntry (iid);
6264 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6265 return ctype_unknown;
6268 return uentry_getRealType (ue2);
6277 ctype uentry_getForceRealType (uentry e)
6280 typeId uid = USYMIDINVALID;
6282 if (uentry_isInvalid (e))
6284 return ctype_unknown;
6287 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6289 if (uentry_isAnyTag (e))
6294 if (uentry_isAbstractType (e))
6296 ct = uentry_getAbstractType (e);
6297 llassert (ctype_isUA (ct));
6299 uid = ctype_typeId (ct);
6300 /* no check for access! */
6303 ct = uentry_getType (e);
6305 /* evs 2000-07-25 */
6306 /* if (ctype_isUserBool (ct)) return ct; */
6308 if (ctype_isManifestBool (ct)) {
6312 if (ctype_isUA (ct))
6314 usymId iid = ctype_typeId (ct);
6316 if (usymId_equal (iid, uid))
6318 llcontbug (message ("uentry_getRealType: recursive type! %s",
6319 ctype_unparse (ct)));
6324 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6333 uentry uentry_nameCopy (cstring name, uentry e)
6335 uentry enew = uentry_alloc ();
6337 llassert (uentry_isValid (e));
6339 /* enew->shallowCopy = FALSE; */
6340 enew->ukind = e->ukind;
6342 enew->utype = e->utype;
6343 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6344 enew->whereDefined = fileloc_copy (e->whereDefined);
6345 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6346 enew->sref = sRef_copy (e->sref);
6347 enew->used = e->used;
6349 enew->isPrivate = e->isPrivate;
6350 enew->hasNameError = FALSE;
6352 enew->uses = filelocList_new ();
6353 enew->warn = warnClause_undefined;
6355 enew->storageclass = e->storageclass;
6356 enew->info = uinfo_copy (e->info, e->ukind);
6362 uentry_setDatatype (uentry e, usymId uid)
6364 llassert (uentry_isDatatype (e));
6366 if (uentry_isAbstractType (e))
6368 e->info->datatype->type = ctype_createAbstract (uid);
6372 e->info->datatype->type = ctype_createUser (uid);
6377 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6378 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6381 llassert (uentry_isValid (e));
6383 if (fileloc_isSpec (f) || fileloc_isImport (f))
6385 e->whereSpecified = f;
6386 e->whereDeclared = fileloc_undefined;
6387 e->whereDefined = fileloc_undefined;
6391 e->whereSpecified = fileloc_undefined;
6392 e->whereDeclared = f;
6393 e->whereDefined = fileloc_undefined;
6398 ucinfo_free (/*@only@*/ ucinfo u)
6400 multiVal_free (u->val);
6405 uvinfo_free (/*@only@*/ uvinfo u)
6407 /*drl7x added 6/29/01 */
6408 /*free null terminated stuff */
6410 // free(u->bufinfo);
6415 udinfo_free (/*@only@*/ udinfo u)
6421 ufinfo_free (/*@only@*/ ufinfo u)
6423 globSet_free (u->globs);
6424 sRefSet_free (u->mods);
6425 stateClauseList_free (u->specclauses);
6430 uiinfo_free (/*@only@*/ uiinfo u)
6436 ueinfo_free (/*@only@*/ ueinfo u)
6441 static /*@only@*/ ucinfo
6442 ucinfo_copy (ucinfo u)
6444 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6446 ret->val = multiVal_copy (u->val);
6447 ret->access = u->access;
6452 static /*@only@*/ uvinfo
6453 uvinfo_copy (uvinfo u)
6455 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6457 ret->kind = u->kind;
6458 ret->nullstate = u->nullstate;
6459 ret->defstate = u->defstate;
6460 ret->checked = u->checked;
6462 /* drl added 07-02-001 */
6463 /* copy null terminated information */
6465 if (u->bufinfo != NULL)
6467 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6468 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6469 ret->bufinfo->size = u->bufinfo->size;
6470 ret->bufinfo->len = u->bufinfo->len;
6475 ret->bufinfo = NULL;
6481 static /*@only@*/ udinfo
6482 udinfo_copy (udinfo u)
6484 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6488 ret->type = u->type;
6493 static /*@only@*/ ufinfo
6494 ufinfo_copy (ufinfo u)
6496 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6498 ret->hasGlobs = u->hasGlobs;
6499 ret->hasMods = u->hasMods;
6500 ret->exitCode = u->exitCode;
6501 ret->specialCode = u->specialCode;
6502 ret->nullPred = u->nullPred;
6503 ret->access = u->access;
6504 ret->globs = globSet_newCopy (u->globs);
6505 ret->mods = sRefSet_newCopy (u->mods);
6506 ret->defparams = u->defparams;
6507 ret->specclauses = stateClauseList_copy (u->specclauses);
6512 if (constraintList_isDefined(u->preconditions))
6513 ret->preconditions = constraintList_copy(u->preconditions);
6515 ret->preconditions = NULL;
6518 if (constraintList_isDefined(u->postconditions))
6519 ret->postconditions = constraintList_copy(u->postconditions);
6521 ret->postconditions = NULL;
6527 static /*@only@*/ uiinfo
6528 uiinfo_copy (uiinfo u)
6530 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6532 ret->access = u->access;
6533 ret->globs = globSet_newCopy (u->globs);
6534 ret->mods = sRefSet_newCopy (u->mods);
6539 static /*@only@*/ ueinfo
6540 ueinfo_copy (ueinfo u)
6542 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6544 ret->access = u->access;
6549 uinfo_free (uinfo u, ekind kind)
6554 case KCONST: ucinfo_free (u->uconst); break;
6555 case KVAR: uvinfo_free (u->var); break;
6559 case KDATATYPE: udinfo_free (u->datatype); break;
6560 case KFCN: ufinfo_free (u->fcn); break;
6561 case KITER: uiinfo_free (u->iter); break;
6562 case KENDITER: ueinfo_free (u->enditer); break;
6563 case KELIPSMARKER: break;
6564 case KINVALID: break;
6570 static /*@only@*/ /*@null@*/ uinfo
6571 uinfo_copy (uinfo u, ekind kind)
6573 if (kind == KELIPSMARKER || kind == KINVALID)
6579 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6584 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6585 case KVAR: ret->var = uvinfo_copy (u->var); break;
6589 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6590 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6591 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6592 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6600 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6602 filelocList_free (e->uses);
6603 cstring_free (e->uname);
6605 uinfo_free (e->info, e->ukind);
6607 fileloc_free (e->whereSpecified);
6608 fileloc_free (e->whereDefined);
6609 fileloc_free (e->whereDeclared);
6611 warnClause_free (e->warn);
6617 extern void uentry_markOwned (/*@owned@*/ uentry u)
6619 sfreeEventually (u);
6623 uentry_free (/*@only@*/ uentry e)
6625 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6627 uentry_reallyFree (e);
6632 ** For uentry's in the global or file scope
6636 uentry_freeComplete (/*@only@*/ uentry e)
6638 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6640 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6641 /*@i@*/ sRef_free (e->sref);
6642 e->sref = sRef_undefined;
6643 uentry_reallyFree (e);
6648 ** requires old->kind != new->kind, old->uname = new->uname
6652 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6654 llassert (uentry_isValid (old));
6655 llassert (uentry_isValid (unew));
6657 if (uentry_isEitherConstant (unew)
6658 && (fileloc_isPreproc (uentry_whereDeclared (old))
6659 || ctype_isUnknown (old->utype))
6660 && !uentry_isSpecified (old))
6668 if (!uentry_isDeclared (old))
6670 if (uentry_isSpecified (old))
6672 if (uentry_isSpecified (unew))
6674 llbuglit ("Respecification!");
6676 else if (uentry_isDeclared (unew))
6680 message ("%s %q inconsistently declared as %s: %t",
6681 ekind_capName (old->ukind),
6682 uentry_getName (unew),
6683 ekind_unparseLong (unew->ukind),
6685 uentry_whereDeclared (unew)))
6687 uentry_showWhereLast (old);
6699 message ("%s %q inconsistently declared as %s: %t",
6700 ekind_capName (old->ukind),
6701 uentry_getName (unew),
6702 ekind_unparseLong (unew->ukind),
6704 uentry_whereDeclared (unew)))
6706 uentry_showWhereLast (old);
6712 llassert (uentry_isDeclared (unew));
6716 message ("%s %q inconsistently redeclared as %s",
6717 ekind_capName (old->ukind),
6718 uentry_getName (unew),
6719 ekind_unparseLong (unew->ukind)),
6720 uentry_whereDeclared (unew)))
6722 uentry_showWhereLast (old);
6728 uentry_copyInto (old, unew);
6732 ** def is the definition of spec, modifies spec
6734 ** reports any inconsistencies
6735 ** returns the summary of all available information
6736 ** if spec and def are inconsistent, def is returned
6740 uentry_showWhereLast (uentry spec)
6742 if (uentry_isValid (spec))
6744 if (fileloc_isDefined (spec->whereDefined)
6745 && !fileloc_isLib (spec->whereDefined)
6746 && !fileloc_isPreproc (spec->whereDefined))
6748 llgenindentmsg (message ("Previous definition of %q: %t",
6749 uentry_getName (spec),
6750 uentry_getType (spec)),
6751 uentry_whereDefined (spec));
6753 else if (uentry_isDeclared (spec))
6755 llgenindentmsg (message ("Previous declaration of %q: %t",
6756 uentry_getName (spec),
6757 uentry_getType (spec)),
6758 uentry_whereDeclared (spec));
6760 else if (uentry_isSpecified (spec))
6762 if (uentry_hasName (spec))
6764 llgenindentmsg (message ("Specification of %q: %t",
6765 uentry_getName (spec),
6766 uentry_getType (spec)),
6767 uentry_whereSpecified (spec));
6771 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6772 uentry_whereSpecified (spec));
6777 /* nothing to show */
6783 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6785 fileloc loc = uentry_whereDefined (ce);
6787 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6789 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6793 loc = uentry_whereSpecified (ce);
6795 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6797 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6802 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6804 if (uentry_isDeclared (spec))
6806 llgenindentmsg (message ("Previous declaration of %q: %q",
6807 uentry_getName (spec), extra),
6808 uentry_whereDeclared (spec));
6810 else if (uentry_isSpecified (spec))
6812 llgenindentmsg (message ("Specification of %q: %q",
6813 uentry_getName (spec), extra),
6814 uentry_whereSpecified (spec));
6818 cstring_free (extra);
6823 uentry_showWhereDeclared (uentry spec)
6825 if (uentry_isDeclared (spec))
6827 if (uentry_hasName (spec))
6829 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6830 uentry_whereDeclared (spec));
6834 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6837 else if (uentry_isSpecified (spec))
6839 if (uentry_hasName (spec))
6841 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6842 uentry_whereSpecified (spec));
6846 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6851 /* nothing to show */
6857 uentry_showWhereAny (uentry spec)
6859 if (uentry_isDeclared (spec))
6861 if (uentry_hasName (spec))
6863 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6864 uentry_whereDeclared (spec));
6868 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6871 else if (uentry_isSpecified (spec))
6873 if (uentry_hasName (spec))
6875 llgenindentmsg (message ("Specification of %q",
6876 uentry_getName (spec)),
6877 uentry_whereSpecified (spec));
6881 llgenindentmsg (cstring_makeLiteral ("Specification"),
6882 uentry_whereSpecified (spec));
6885 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6887 if (uentry_hasName (spec))
6889 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6890 uentry_whereDefined (spec));
6894 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6899 /* nothing to show */
6904 uentry_showWhereDefined (uentry spec)
6906 if (uentry_isCodeDefined (spec))
6908 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6909 uentry_whereDefined (spec));
6914 uentry_showWhereLastPlain (uentry spec)
6916 if (uentry_isDeclared (spec))
6918 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6919 uentry_whereDeclared (spec));
6921 else if (uentry_isSpecified (spec))
6923 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6924 uentry_whereSpecified (spec));
6932 uentry_showWhereLastVal (uentry spec, cstring val)
6934 if (uentry_isDeclared (spec))
6936 llgenindentmsg (message ("Previous declaration of %q: %s",
6937 uentry_getName (spec), val),
6938 uentry_whereDeclared (spec));
6940 else if (uentry_isSpecified (spec))
6942 llgenindentmsg (message ("Specification of %q: %s",
6943 uentry_getName (spec), val),
6944 uentry_whereSpecified (spec));
6952 uentry_showWhereSpecified (uentry spec)
6954 if (uentry_isSpecified (spec))
6956 if (uentry_hasName (spec))
6958 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6959 uentry_whereSpecified (spec));
6963 llgenindentmsg (cstring_makeLiteral ("Specification"),
6964 uentry_whereSpecified (spec));
6967 else if (uentry_isDeclared (spec))
6969 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6970 uentry_whereDeclared (spec));
6974 /* nothing to show */
6979 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6981 if (uentry_isSpecified (spec))
6983 if (uentry_hasName (spec))
6985 llgenindentmsg (message ("Specification of %q: %q",
6986 uentry_getName (spec), s),
6987 uentry_whereSpecified (spec));
6991 llgenindentmsg (message ("Specification: %q", s),
6992 uentry_whereSpecified (spec));
6995 else if (uentry_isDeclared (spec))
6997 llgenindentmsg (message ("Declaration of %q: %q",
6998 uentry_getName (spec), s),
6999 uentry_whereDeclared (spec));
7003 llgenindentmsg (message ("Previous: %q", s),
7004 uentry_whereLast (spec));
7013 checkStructConformance (uentry old, uentry unew)
7016 uentryList fold, fnew;
7019 ** requires: types of old and new are structs or unions
7022 llassert (uentry_isValid (old));
7023 llassert (uentry_isValid (unew));
7025 oldr = ctype_realType (old->utype);
7026 fold = ctype_getFields (oldr);
7028 newr = ctype_realType (unew->utype);
7029 fnew = ctype_getFields (newr);
7031 if (!uentryList_matchFields (fold, fnew))
7033 if (fileloc_equal (uentry_whereLast (old),
7034 uentry_whereLast (unew)))
7042 message ("%q %q %rdeclared with fields { %q }, %s "
7043 "with fields { %q }",
7044 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7045 uentry_getName (old),
7046 uentry_isDeclared (old),
7047 uentryList_unparseAbbrev (fnew),
7048 uentry_specOrDefName (old),
7049 uentryList_unparseAbbrev (fold)),
7050 uentry_whereDeclared (unew)))
7052 uentry_showWhereLastPlain (old);
7053 uentryList_showFieldDifference (fold, fnew);
7057 old->utype = unew->utype;
7062 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7065 ** requires old and new are enums
7068 ctype rold = ctype_realType (old->utype);
7069 ctype rnew = ctype_realType (unew->utype);
7070 enumNameList eold = ctype_elist (rold);
7071 enumNameList enew = ctype_elist (rnew);
7073 if (!enumNameList_match (eold, enew))
7077 message ("Enum %q declared with members { %q } but "
7078 "specified with members { %q }",
7079 uentry_getName (old),
7080 enumNameList_unparse (enew),
7081 enumNameList_unparse (eold)),
7082 uentry_whereDeclared (unew)))
7084 uentry_showWhereSpecified (old);
7085 old->utype = unew->utype;
7091 ** either oldCurrent or newCurrent may be undefined!
7095 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7096 uentry unew, uentry newCurrent, ctype newType,
7099 bool hasError = FALSE;
7101 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7103 if (uentry_hasName (newCurrent))
7105 hasError = optgenerror
7107 message ("Parameter %d, %q, of function %q has inconsistent type: "
7108 "declared %t, %s %t",
7109 paramno + 1, uentry_getName (newCurrent),
7110 uentry_getName (unew),
7111 newType, uentry_specOrDefName (old), oldType),
7112 uentry_whereDeclared (newCurrent));
7116 hasError = optgenerror
7118 message ("Parameter %d of function %q has inconsistent type: "
7119 "declared %t, %s %t",
7120 paramno + 1, uentry_getName (unew),
7121 newType, uentry_specOrDefName (old), oldType),
7122 uentry_whereDeclared (newCurrent));
7124 DPRINTF (("type: %s / %s",
7125 ctype_unparse (newType),
7126 ctype_unparse (ctype_realType (newType))));
7131 if (uentry_isDeclared (unew))
7133 hasError = optgenerror
7135 message ("Parameter %d of function %s has inconsistent type: "
7136 "declared %t, %s %t",
7137 paramno + 1, unew->uname,
7138 newType, uentry_specOrDefName (old), oldType),
7139 uentry_whereDeclared (unew));
7143 hasError = optgenerror
7145 message ("Parameter %d of function %s has inconsistent type: "
7146 "declared %t, %s %t",
7147 paramno + 1, unew->uname,
7148 newType, uentry_specOrDefName (old), oldType),
7149 uentry_whereDeclared (unew));
7155 if (!uentry_isUndefined (oldCurrent))
7157 if (!uentry_isUndefined (newCurrent)
7158 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7160 uentry_showWhereLast (oldCurrent);
7164 uentry_showWhereLastPlain (old);
7167 uentry_setType (oldCurrent, newType);
7171 uentry_showWhereLastPlain (old);
7177 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7181 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7183 uentry_isDeclared (old),
7184 uentryList_size (uentry_getParams (unew)),
7185 uentry_specOrDefName (old),
7186 uentryList_size (uentry_getParams (old))),
7187 uentry_whereDeclared (unew)))
7189 uentry_showWhereLastPlain (old);
7194 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7198 message ("Function %s inconsistently %rdeclared to return %t",
7200 uentry_isDeclared (old),
7201 ctype_getReturnType (unew->utype)),
7202 uentry_whereDeclared (unew)))
7204 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7208 static cstring paramStorageName (uentry ue)
7210 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7213 static cstring fcnErrName (uentry ue)
7215 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7218 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7220 if (uentry_isVar (ue))
7222 return (checkedName (ue->info->var->checked));
7226 return (cstring_makeLiteralTemp ("<checked invalid>"));
7230 static cstring checkedName (chkind checked)
7234 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7235 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7236 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7237 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7238 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7244 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7249 if (uentry_isVar (unew))
7251 llassert (uentry_isVar (old));
7253 oldState = old->info->var->nullstate;
7254 newState = unew->info->var->nullstate;
7258 oldState = sRef_getNullState (old->sref);
7259 newState = sRef_getNullState (unew->sref);
7262 if (oldState == NS_ABSNULL)
7264 if (uentry_isVar (old))
7266 old->info->var->nullstate = newState;
7269 sRef_mergeNullState (old->sref, newState);
7271 else if (newState == NS_UNKNOWN)
7273 if (completeConform && newState != oldState
7274 && uentry_isReallySpecified (old))
7278 message ("%s %q specified as %s, but declared without %s qualifier",
7279 ekind_capName (unew->ukind),
7280 uentry_getName (unew),
7281 nstate_unparse (oldState),
7282 nstate_unparse (oldState)),
7283 uentry_whereDeclared (unew)))
7285 uentry_showWhereSpecified (old);
7289 if (uentry_isVar (unew))
7291 unew->info->var->nullstate = oldState;
7294 sRef_mergeNullState (unew->sref, oldState);
7296 else if (newState == NS_POSNULL)
7298 if (oldState == NS_MNOTNULL
7299 && (ctype_isUA (unew->utype)
7300 || (uentry_isFunction (unew)
7301 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7303 if (uentry_isVar (unew))
7305 unew->info->var->nullstate = oldState;
7308 sRef_mergeNullState (unew->sref, oldState);
7312 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7313 || oldState == NS_UNKNOWN)
7320 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7322 uentry_ekindName (unew),
7323 uentry_getName (unew),
7324 uentry_isDeclared (old),
7326 uentry_specOrDefName (old),
7327 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7328 uentry_whereDeclared (unew)))
7330 uentry_showWhereSpecified (old);
7335 if (uentry_isVar (old))
7337 old->info->var->nullstate = newState;
7340 sRef_mergeNullState (old->sref, newState);
7343 else if (newState == NS_MNOTNULL)
7345 if (oldState != NS_MNOTNULL)
7351 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7352 "%s without notnull qualifier",
7353 uentry_ekindName (unew),
7354 uentry_getName (unew),
7355 uentry_isDeclared (old),
7357 uentry_specOrDefName (old)),
7358 uentry_whereDeclared (unew)))
7360 uentry_showWhereSpecified (old);
7364 if (uentry_isVar (old))
7366 old->info->var->nullstate = newState;
7369 sRef_mergeNullState (old->sref, newState);
7374 if (uentry_isVar (unew))
7376 unew->info->var->nullstate = oldState;
7379 sRef_mergeNullState (unew->sref, oldState);
7384 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7385 bool mustConform, bool completeConform)
7391 if (uentry_isVar (old) && uentry_isVar (unew))
7393 oldState = old->info->var->defstate;
7394 newState = unew->info->var->defstate;
7399 oldState = sRef_getDefState (old->sref);
7400 newState = sRef_getDefState (unew->sref);
7403 if (newState != oldState
7404 && newState != SS_UNKNOWN
7405 && newState != SS_DEFINED)
7407 DPRINTF (("Where declared: %s / %s",
7408 fileloc_unparse (uentry_whereDeclared (unew)),
7409 bool_unparse (fileloc_isXHFile (uentry_whereDeclared (unew)))));
7415 message ("%s %q inconsistently %rdeclared %s %s %s, "
7417 uentry_ekindName (unew),
7418 uentry_getName (unew),
7419 uentry_isDeclared (old),
7421 sstate_unparse (newState),
7422 paramStorageName (unew),
7423 uentry_specOrDefName (old),
7425 sstate_unparse (oldState),
7426 paramStorageName (unew)),
7427 uentry_whereDeclared (unew)))
7429 uentry_showWhereSpecified (old);
7433 if (vars) old->info->var->defstate = newState;
7434 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7439 && (newState != oldState) && (oldState != SS_DEFINED)
7440 && uentry_isReallySpecified (old))
7444 message ("%s %q specified as %s, but declared without %s qualifier",
7445 ekind_capName (unew->ukind),
7446 uentry_getName (unew),
7447 sstate_unparse (oldState),
7448 sstate_unparse (oldState)),
7449 uentry_whereDeclared (unew)))
7451 uentry_showWhereSpecified (old);
7455 if (vars) unew->info->var->defstate = oldState;
7456 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7461 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7462 bool mustConform, bool completeConform)
7467 oldKind = sRef_getAliasKind (old->sref);
7468 newKind = sRef_getAliasKind (unew->sref);
7470 if (alkind_isImplicit (newKind)
7471 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7473 if (completeConform && !alkind_equal (newKind, oldKind)
7474 && uentry_isReallySpecified (old))
7478 message ("%s %q specified as %s, but declared without "
7479 "explicit alias qualifier",
7480 ekind_capName (unew->ukind),
7481 uentry_getName (unew),
7482 alkind_unparse (oldKind)),
7483 uentry_whereDeclared (unew)))
7485 uentry_showWhereSpecified (old);
7490 ** This really shouldn't be necessary, but it is!
7491 ** Function params (?) use new here.
7494 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7498 if (alkind_isKnown (newKind))
7500 if (!alkind_equal (oldKind, newKind))
7502 if (alkind_isKnown (oldKind))
7507 message ("%s %q inconsistently %rdeclared %s %s storage, "
7509 uentry_ekindName (unew),
7510 uentry_getName (unew),
7511 uentry_isDeclared (old),
7513 alkind_unparse (newKind),
7514 uentry_specOrDefName (old),
7515 alkind_unparse (oldKind)),
7516 uentry_whereDeclared (unew)))
7518 uentry_showWhereSpecified (old);
7520 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7521 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7522 sRef_setAliasKind (old->sref, AK_ERROR,
7523 uentry_whereDeclared (unew));
7527 sRef_setAliasKind (old->sref, newKind,
7528 uentry_whereDeclared (unew));
7533 if (!(alkind_isImplicit (newKind)))
7536 !uentry_isFunction (unew) &&
7539 message ("%s %q inconsistently %rdeclared %s %s storage, "
7540 "implicitly %s as temp storage",
7541 uentry_ekindName (unew),
7542 uentry_getName (unew),
7543 uentry_isDeclared (old),
7545 alkind_unparse (newKind),
7546 uentry_specOrDefName (old)),
7547 uentry_whereDeclared (unew)))
7549 uentry_showWhereSpecified (old);
7553 sRef_setAliasKind (old->sref, newKind,
7554 uentry_whereDeclared (unew));
7556 else /* newKind is temp or refcounted */
7563 else /* newKind unknown */
7570 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7571 bool mustConform, bool completeConform)
7576 oldKind = sRef_getExKind (old->sref);
7577 newKind = sRef_getExKind (unew->sref);
7579 if (exkind_isKnown (newKind))
7581 if (oldKind != newKind)
7583 if (exkind_isKnown (oldKind))
7588 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7589 uentry_ekindName (unew),
7590 uentry_getName (unew),
7591 uentry_isDeclared (old),
7593 exkind_unparse (newKind),
7594 uentry_specOrDefName (old),
7595 exkind_unparse (oldKind)),
7596 uentry_whereDeclared (unew)))
7598 uentry_showWhereSpecified (old);
7601 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7608 message ("%s %q inconsistently %rdeclared %s %s, "
7609 "implicitly %s without exposure qualifier",
7610 uentry_ekindName (unew),
7611 uentry_getName (unew),
7612 uentry_isDeclared (old),
7614 exkind_unparse (newKind),
7615 uentry_specOrDefName (old)),
7616 uentry_whereDeclared (unew)))
7618 uentry_showWhereSpecified (old);
7621 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7627 if (completeConform && exkind_isKnown (oldKind)
7628 && uentry_isReallySpecified (old))
7632 message ("%s %q specified as %s, but declared without "
7633 "exposure qualifier",
7634 ekind_capName (unew->ukind),
7635 uentry_getName (unew),
7636 exkind_unparse (oldKind)),
7637 uentry_whereDeclared (unew)))
7639 uentry_showWhereSpecified (old);
7643 /* yes, this is necessary! (if its a param) */
7644 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7649 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7650 bool mustConform, /*@unused@*/ bool completeConform)
7652 valueTable newvals = sRef_getValueTable (unew->sref);
7654 if (valueTable_isDefined (newvals))
7656 DPRINTF (("Check meta state: %s -> %s",
7657 uentry_unparseFull (old),
7658 uentry_unparseFull (unew)));
7660 DPRINTF (("Check meta state refs: %s -> %s",
7661 sRef_unparseFull (old->sref),
7662 sRef_unparseFull (unew->sref)));
7664 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7667 ** Copy the new values into the old ref
7670 valueTable_elements (newvals, key, newval)
7672 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7673 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7675 llassert (metaStateInfo_isDefined (msinfo));
7677 if (stateValue_isUndefined (oldval))
7679 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7683 if (stateValue_isError (oldval))
7685 if (!stateValue_isError (newval))
7687 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7691 ; /* No change necessary. */
7696 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7698 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7707 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7708 uentry_ekindName (unew),
7709 uentry_getName (unew),
7710 uentry_isDeclared (old),
7712 metaStateInfo_unparseValue (msinfo,
7713 stateValue_getValue (newval)),
7714 uentry_specOrDefName (old),
7715 metaStateInfo_unparseValue (msinfo,
7716 stateValue_getValue (oldval))),
7717 uentry_whereDeclared (unew)))
7719 uentry_showWhereSpecified (old);
7723 DPRINTF (("Updating!"));
7724 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7728 DPRINTF (("Values match"));
7732 } end_valueTable_elements ;
7737 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7738 /*@notnull@*/ uentry unew,
7739 bool mustConform, bool completeConform)
7741 checkDefState (old, unew, mustConform, completeConform);
7742 checkNullState (old, unew, mustConform, completeConform);
7743 checkAliasState (old, unew, mustConform, completeConform);
7744 checkExpState (old, unew, mustConform, completeConform);
7745 checkMetaState (old, unew, mustConform, completeConform);
7747 sRef_storeState (old->sref);
7748 sRef_storeState (unew->sref);
7752 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7754 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7759 llassert (uentry_isVar (old));
7760 llassert (uentry_isVar (unew));
7762 if (cstring_isEmpty (old->uname))
7764 cstring_free (old->uname);
7765 old->uname = cstring_copy (unew->uname);
7768 if (unew->info->var->kind == VKRETPARAM
7769 || unew->info->var->kind == VKSEFRETPARAM)
7771 if (old->info->var->kind != VKRETPARAM
7772 && old->info->var->kind != VKSEFRETPARAM)
7776 message ("Parameter %q inconsistently %rdeclared as "
7777 "returned parameter",
7778 uentry_getName (unew),
7779 uentry_isDeclared (old)),
7780 uentry_whereDeclared (unew)))
7782 uentry_showWhereSpecified (old);
7783 old->info->var->kind = unew->info->var->kind;
7789 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7791 if (old->info->var->kind != VKSEFPARAM
7792 && old->info->var->kind != VKSEFRETPARAM)
7796 message ("Parameter %qinconsistently %rdeclared as "
7798 uentry_getOptName (unew),
7799 uentry_isDeclared (old)),
7800 uentry_whereDeclared (unew)))
7802 uentry_showWhereSpecified (old);
7803 old->info->var->kind = unew->info->var->kind;
7808 if (old->info->var->kind == VKSPEC)
7810 old->info->var->kind = unew->info->var->kind;
7814 unew->info->var->kind = old->info->var->kind;
7817 if (unew->info->var->checked != CH_UNKNOWN
7818 && unew->info->var->checked != old->info->var->checked)
7820 if (old->info->var->checked == CH_UNKNOWN
7821 && !fileloc_isUser (uentry_whereLast (old)))
7829 message ("Variable %q inconsistently %rdeclared as "
7830 "%s parameter (was %s)",
7831 uentry_getName (unew),
7832 uentry_isDeclared (old),
7833 checkedName (unew->info->var->checked),
7834 checkedName (old->info->var->checked)),
7835 uentry_whereDeclared (unew)))
7837 uentry_showWhereSpecified (old);
7841 old->info->var->checked = unew->info->var->checked;
7846 && (old->info->var->checked != CH_UNKNOWN)
7847 && uentry_isReallySpecified (old))
7851 message ("%s %q specified as %s, but declared without %s qualifier",
7852 ekind_capName (unew->ukind),
7853 uentry_getName (unew),
7854 checkedName (old->info->var->checked),
7855 checkedName (old->info->var->checked)),
7856 uentry_whereDeclared (unew)))
7858 uentry_showWhereSpecified (old);
7862 unew->info->var->checked = old->info->var->checked;
7865 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7868 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7870 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7875 llassert (uentry_isVar (u1));
7876 llassert (uentry_isVar (u2));
7878 if (u1->info->var->kind != u2->info->var->kind) {
7879 if (u1->info->var->kind == VKSEFRETPARAM) {
7880 if (u2->info->var->kind == VKRETPARAM) {
7883 message ("Function types are inconsistent. Parameter %d is "
7884 "sef parameter, but non-sef parameter in "
7885 "assigned function: %s",
7886 paramno, exprNode_unparse (e)),
7888 } else if (u2->info->var->kind == VKSEFPARAM) {
7891 message ("Function types are inconsistent. Parameter %d is "
7892 "returns parameter, but non-returns parameter in "
7893 "assigned function: %s",
7894 paramno, exprNode_unparse (e)),
7899 message ("Function types are inconsistent. Parameter %d is "
7900 "sef returns parameter, but non-sef returns parameter in "
7901 "assigned function: %s",
7902 paramno, exprNode_unparse (e)),
7905 } else if (u1->info->var->kind == VKRETPARAM) {
7908 message ("Function types are inconsistent. Parameter %d is "
7909 "returns parameter, but non-returns parameter in "
7910 "assigned function: %s",
7911 paramno, exprNode_unparse (e)),
7913 } else if (u1->info->var->kind == VKSEFPARAM) {
7916 message ("Function types are inconsistent. Parameter %d is "
7917 "sef parameter, but non-sef parameter in "
7918 "assigned function: %s",
7919 paramno, exprNode_unparse (e)),
7922 if (u2->info->var->kind == VKSEFRETPARAM) {
7925 message ("Function types are inconsistent. Parameter %d is "
7926 "normal parameter, but sef returns parameter in "
7927 "assigned function: %s",
7928 paramno, exprNode_unparse (e)),
7930 } else if (u2->info->var->kind == VKSEFPARAM) {
7933 message ("Function types are inconsistent. Parameter %d is "
7934 "normal parameter, but sef parameter in "
7935 "assigned function: %s",
7936 paramno, exprNode_unparse (e)),
7938 } else if (u2->info->var->kind == VKRETPARAM) {
7941 message ("Function types are inconsistent. Parameter %d is "
7942 "normal parameter, but returns parameter in "
7943 "assigned function: %s",
7944 paramno, exprNode_unparse (e)),
7952 if (u1->info->var->defstate != u2->info->var->defstate)
7956 message ("Function types are inconsistent. Parameter %d is "
7957 "%s, but %s in assigned function: %s",
7959 sstate_unparse (u1->info->var->defstate),
7960 sstate_unparse (u2->info->var->defstate),
7961 exprNode_unparse (e)),
7965 if (u1->info->var->nullstate != u2->info->var->nullstate)
7969 message ("Function types are inconsistent. Parameter %d is "
7970 "%s, but %s in assigned function: %s",
7972 nstate_unparse (u1->info->var->nullstate),
7973 nstate_unparse (u2->info->var->nullstate),
7974 exprNode_unparse (e)),
7978 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7982 message ("Function types are inconsistent. Parameter %d is "
7983 "%s, but %s in assigned function: %s",
7985 alkind_unparse (sRef_getAliasKind (u1->sref)),
7986 alkind_unparse (sRef_getAliasKind (u2->sref)),
7987 exprNode_unparse (e)),
7991 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7995 message ("Function types are inconsistent. Parameter %d is "
7996 "%s, but %s in assigned function: %s",
7998 exkind_unparse (sRef_getExKind (u1->sref)),
7999 exkind_unparse (sRef_getExKind (u2->sref)),
8000 exprNode_unparse (e)),
8006 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8007 /*@notnull@*/ uentry unew,
8008 bool mustConform, /*@unused@*/ bool completeConform)
8010 uentryList oldParams = uentry_getParams (old);
8011 uentryList newParams = uentry_getParams (unew);
8012 ctype newType = unew->utype;
8013 ctype oldType = old->utype;
8014 ctype oldRetType = ctype_unknown;
8015 ctype newRetType = ctype_unknown;
8017 DPRINTF (("Function conform: %s ==> %s",
8018 uentry_unparseFull (old),
8019 uentry_unparseFull (unew)));
8021 if (uentry_isForward (old))
8023 mustConform = FALSE;
8024 uentry_copyInto (old, unew);
8029 ** check return values
8032 if (ctype_isKnown (oldType))
8034 llassert (ctype_isFunction (oldType));
8036 oldRetType = ctype_getReturnType (oldType);
8039 if (ctype_isKnown (newType))
8041 llassert (ctype_isFunction (newType));
8043 newRetType = ctype_getReturnType (newType);
8046 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8047 && !ctype_matchDef (newRetType, oldRetType))
8049 if (mustConform) returnValueError (old, unew);
8053 if (ctype_isConj (newRetType))
8055 if (ctype_isConj (oldRetType))
8057 if (!ctype_sameAltTypes (newRetType, oldRetType))
8061 message ("Function %q inconsistently %rdeclared to "
8062 "return alternate types %s "
8063 "(types match, but alternates are not identical, "
8064 "so checking may not be correct)",
8065 uentry_getName (unew),
8066 uentry_isDeclared (old),
8067 ctype_unparse (newRetType)),
8068 uentry_whereDeclared (unew)))
8070 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8076 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8081 DPRINTF (("Before state: %s",
8082 uentry_unparseFull (old)));
8083 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8084 DPRINTF (("After state: %s",
8085 uentry_unparseFull (old)));
8087 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8089 if (exitkind_isKnown (unew->info->fcn->exitCode))
8093 message ("Function %q inconsistently %rdeclared using %s",
8094 uentry_getName (unew),
8095 uentry_isDeclared (old),
8096 exitkind_unparse (unew->info->fcn->exitCode)),
8097 uentry_whereDeclared (unew)))
8099 uentry_showWhereSpecified (old);
8104 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8108 if (!qual_isUnknown (unew->info->fcn->nullPred))
8110 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8114 message ("Function %q inconsistently %rdeclared using %s",
8115 uentry_getName (unew),
8116 uentry_isDeclared (old),
8117 qual_unparse (unew->info->fcn->nullPred)),
8118 uentry_whereDeclared (unew)))
8120 uentry_showWhereSpecified (old);
8126 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8129 if (unew->info->fcn->specialCode != SPC_NONE)
8131 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8135 message ("Function %q inconsistently %rdeclared using %s",
8136 uentry_getName (unew),
8137 uentry_isDeclared (old),
8138 specCode_unparse (unew->info->fcn->specialCode)),
8139 uentry_whereDeclared (unew)))
8141 uentry_showWhereSpecified (old);
8147 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8154 if (!uentryList_sameObject (oldParams, newParams)
8155 && (!uentryList_isMissingParams (oldParams)))
8157 if (!uentryList_isMissingParams (newParams))
8160 int nparams = uentryList_size (oldParams);
8161 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8163 if (nparams != uentryList_size (newParams))
8165 nargsError (old, unew);
8168 if (uentryList_size (newParams) < nparams)
8170 nparams = uentryList_size (newParams);
8173 while (paramno < nparams)
8175 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8176 uentry newCurrent = uentryList_getN (newParams, paramno);
8177 ctype oldCurrentType = uentry_getType (oldCurrent);
8178 ctype newCurrentType = uentry_getType (newCurrent);
8180 llassert (uentry_isValid (oldCurrent)
8181 && uentry_isValid (newCurrent));
8183 if (!uentry_isElipsisMarker (oldCurrent)
8184 && !uentry_isElipsisMarker (newCurrent))
8186 checkVarConformance (oldCurrent, newCurrent,
8187 mustConform, completeConform);
8192 if (uentry_hasName (oldCurrent)
8193 && uentry_hasName (newCurrent))
8195 cstring oldname = uentry_getName (oldCurrent);
8196 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8198 cstring nname = uentry_getName (newCurrent);
8201 if (cstring_isDefined (pfx)
8202 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
8204 oname = cstring_suffix (oldname, cstring_length (pfx));
8209 /*@-branchstate@*/ } /*@=branchstate@*/
8211 if (cstring_isDefined (pfx)
8212 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
8214 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8219 /*@-branchstate@*/ } /*@=branchstate@*/
8221 if (!cstring_equal (oname, nnamefix))
8224 (FLG_DECLPARAMMATCH,
8225 message ("Definition parameter name %s does not match "
8226 "name of corresponding parameter in "
8229 uentry_whereLast (newCurrent)))
8231 uentry_showWhereLastPlain (oldCurrent);
8235 cstring_free (oldname);
8236 cstring_free (nname);
8240 if (!ctype_match (oldCurrentType, newCurrentType))
8242 paramTypeError (old, oldCurrent, oldCurrentType,
8243 unew, newCurrent, newCurrentType, paramno);
8247 if (ctype_isMissingParamsMarker (newCurrentType)
8248 || ctype_isElips (newCurrentType)
8249 || ctype_isMissingParamsMarker (oldCurrentType)
8250 || ctype_isElips (oldCurrentType))
8256 if (ctype_isConj (newCurrentType))
8258 if (ctype_isConj (oldCurrentType))
8260 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8264 message ("Parameter %q inconsistently %rdeclared with "
8265 "alternate types %s "
8266 "(types match, but alternates are not identical, "
8267 "so checking may not be correct)",
8268 uentry_getName (newCurrent),
8269 uentry_isDeclared (oldCurrent),
8270 ctype_unparse (newCurrentType)),
8271 uentry_whereDeclared (unew)))
8273 uentry_showWhereLastVal (oldCurrent,
8274 ctype_unparse (oldCurrentType));
8282 message ("Parameter %q inconsistently %rdeclared with "
8283 "alternate types %s",
8284 uentry_getName (newCurrent),
8285 uentry_isDeclared (oldCurrent),
8286 ctype_unparse (newCurrentType)),
8287 uentry_whereDeclared (unew)))
8289 uentry_showWhereLastVal (oldCurrent,
8290 ctype_unparse (oldCurrentType));
8297 if (ctype_isConj (oldCurrentType))
8299 uentry_setType (newCurrent, oldCurrentType);
8307 ** Forgot this! detected by lclint:
8308 ** uentry.c:1257,15: Suspected infinite loop
8314 if (!uentryList_isMissingParams (newParams))
8316 if (ctype_isConj (oldRetType))
8318 old->utype = ctype_makeFunction (oldRetType,
8319 uentryList_copy (newParams));
8323 old->utype = unew->utype;
8327 checkGlobalsConformance (old, unew, mustConform, completeConform);
8328 checkModifiesConformance (old, unew, mustConform, completeConform);
8330 DPRINTF (("Before list: %s",
8331 uentry_unparseFull (old)));
8333 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8335 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8340 message ("Function %q redeclared using special clauses (can only "
8341 "be used in first declaration)",
8342 uentry_getName (unew)),
8343 uentry_whereDeclared (unew)))
8345 uentry_showWhereLast (old);
8349 /*@i23 need checking @*/
8351 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8355 /*@i43 should be able to append? @*/
8357 stateClauseList_checkEqual (old, unew);
8358 stateClauseList_free (unew->info->fcn->specclauses);
8359 unew->info->fcn->specclauses = stateClauseList_undefined;
8362 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8365 DPRINTF (("After state: %s",
8366 uentry_unparseFull (old)));
8368 if (fileloc_isUndefined (old->whereDeclared))
8370 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8372 else if (fileloc_isUndefined (unew->whereDeclared))
8374 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8383 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8387 llassert (uentry_isValid (ue));
8388 llassert (uentry_isEitherConstant (ue));
8390 uval = ue->info->uconst->val;
8392 if (multiVal_isDefined (uval))
8394 if (multiVal_isDefined (m))
8396 if (!multiVal_equiv (uval, m))
8400 message ("%s %q defined with inconsistent value: %q",
8401 ekind_capName (ue->ukind),
8402 uentry_getName (ue),
8403 multiVal_unparse (m)),
8406 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8414 ue->info->uconst->val = m;
8415 multiVal_free (uval);
8420 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8423 bool typeError = FALSE;
8425 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8427 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8431 DPRINTF (("Check struct conformance: %s / %s",
8432 uentry_unparseFull (old),
8433 uentry_unparseFull (unew)));
8434 checkStructConformance (old, unew);
8439 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8441 llbug (message ("struct tags: bad types: %t / %t",
8442 old->utype, unew->utype));
8446 else if (uentry_isEnumTag (old))
8448 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8450 if (mustConform) checkEnumConformance (old, unew);
8454 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8456 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8457 ctype_unparse (unew->utype)));
8461 else if (!ctype_match (old->utype, unew->utype))
8463 DPRINTF (("Type mismatch: %s / %s",
8464 ctype_unparse (old->utype),
8465 ctype_unparse (unew->utype)));
8467 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8469 ctype realt = ctype_realType (unew->utype);
8471 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8473 unew->utype = ctype_bool;
8479 typeError = optgenerror
8481 message ("%q defined as %s", uentry_getName (old),
8482 ctype_unparse (realt)),
8483 uentry_whereDeclared (unew));
8491 ctype oldr = ctype_realType (old->utype);
8492 ctype newr = ctype_realType (unew->utype);
8494 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8496 checkStructConformance (old, unew);
8498 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8500 checkStructConformance (old, unew);
8502 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8504 checkEnumConformance (old, unew);
8506 else if (uentry_isConstant (old)
8507 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8509 /* okay...for now! (should check the type is reset later... */
8513 DPRINTF (("YABA!"));
8516 message ("%s %q %rdeclared with inconsistent type: %t",
8517 ekind_capName (unew->ukind),
8518 uentry_getName (unew),
8519 uentry_isDeclared (old),
8521 uentry_whereDeclared (unew)))
8523 uentry_showWhereLast (old);
8539 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8540 /*@notnull@*/ uentry unew,
8541 bool mustConform, bool completeConform)
8543 if (ctype_isDefined (unew->info->datatype->type))
8546 ** bool is hard coded here, since it is built into LCL.
8547 ** For now, we're stuck with LCL's types.
8550 if (ctype_isDirectBool (old->utype) &&
8551 cstring_equalLit (unew->uname, "bool"))
8553 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8554 evs 2000-07-25: removed
8556 unew->utype = ctype_bool;
8559 if (ctype_isUnknown (old->info->datatype->type))
8561 old->info->datatype->type = unew->info->datatype->type;
8565 DPRINTF (("Old: %s / New: %s",
8566 uentry_unparseFull (old),
8567 uentry_unparseFull (unew)));
8568 DPRINTF (("Types: %s / %s",
8569 ctype_unparse (old->info->datatype->type),
8570 ctype_unparse (unew->info->datatype->type)));
8572 if (ctype_matchDef (old->info->datatype->type,
8573 unew->info->datatype->type))
8582 ("Type %q %s with inconsistent type: %t",
8583 uentry_getName (unew),
8584 uentry_reDefDecl (old, unew),
8585 unew->info->datatype->type),
8586 uentry_whereDeclared (unew)))
8588 uentry_showWhereLastExtra
8589 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8592 old->info->datatype->type = unew->info->datatype->type;
8597 if (unew->info->datatype->abs != MAYBE)
8599 if (ynm_isOff (old->info->datatype->abs)
8600 && ynm_isOn (unew->info->datatype->abs))
8602 if (!ctype_isDirectBool (old->utype))
8607 ("Datatype %q inconsistently %rdeclared as abstract type",
8608 uentry_getName (unew),
8609 uentry_isDeclared (old)),
8610 uentry_whereDeclared (unew)))
8612 uentry_showWhereLastPlain (old);
8616 else if (ynm_isOn (old->info->datatype->abs)
8617 && ynm_isOff (unew->info->datatype->abs))
8619 if (!ctype_isDirectBool (old->utype))
8624 ("Datatype %q inconsistently %rdeclared as concrete type",
8625 uentry_getName (unew),
8626 uentry_isDeclared (old)),
8627 uentry_whereDeclared (unew)))
8629 uentry_showWhereLastPlain (old);
8640 if (ynm_isOn (old->info->datatype->abs))
8642 old->sref = unew->sref;
8643 unew->info->datatype->mut = old->info->datatype->mut;
8646 && uentry_isReallySpecified (old))
8651 ("Datatype %q specified as abstract, "
8652 "but abstract annotation not used in declaration",
8653 uentry_getName (unew)),
8654 uentry_whereDeclared (unew)))
8656 uentry_showWhereLastPlain (old);
8662 unew->info->datatype->abs = old->info->datatype->abs;
8664 if (ynm_isMaybe (unew->info->datatype->mut))
8666 if (completeConform && ynm_isOff (old->info->datatype->mut)
8667 && uentry_isReallySpecified (old))
8672 ("Datatype %q specified as immutable, "
8673 "but immutable annotation not used in declaration",
8674 uentry_getName (unew)),
8675 uentry_whereDeclared (unew)))
8677 uentry_showWhereLastPlain (old);
8681 unew->info->datatype->mut = old->info->datatype->mut;
8683 else if (ynm_isMaybe (old->info->datatype->mut))
8685 old->info->datatype->mut = unew->info->datatype->mut;
8689 if (ynm_isOn (old->info->datatype->abs))
8691 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8695 message ("Datatype %q inconsistently %rdeclared as immutable",
8696 uentry_getName (unew),
8697 uentry_isDeclared (old)),
8698 uentry_whereDeclared (unew)))
8700 uentry_showWhereLastPlain (old);
8705 if (ynm_isOff (old->info->datatype->mut)
8706 && ynm_isOn (unew->info->datatype->mut))
8710 message ("Datatype %q inconsistently %rdeclared as mutable",
8711 uentry_getName (unew),
8712 uentry_isDeclared (old)),
8713 uentry_whereDeclared (unew)))
8715 uentry_showWhereLastPlain (old);
8720 old->info->datatype->mut = unew->info->datatype->mut;
8723 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8727 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8728 /*@notnull@*/ uentry unew,
8730 /*@unused@*/ bool completeConform)
8732 multiVal oldVal = old->info->uconst->val;
8733 multiVal newVal = unew->info->uconst->val;
8735 if (multiVal_isDefined (oldVal))
8737 if (multiVal_isDefined (newVal))
8739 if (!multiVal_equiv (oldVal, newVal))
8744 message ("%s %q %rdeclared with inconsistent value: %q",
8745 ekind_capName (unew->ukind),
8746 uentry_getName (unew),
8747 uentry_isDeclared (old),
8748 multiVal_unparse (newVal)),
8749 uentry_whereDeclared (unew)))
8751 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
8755 unew->info->uconst->val = multiVal_copy (oldVal);
8756 multiVal_free (newVal);
8765 old->info->uconst->val = multiVal_copy (newVal);
8770 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8771 /*@notnull@*/ uentry unew, bool mustConform,
8772 bool completeConform)
8774 bool typeError = FALSE;
8775 bool fcnConformance = FALSE;
8777 if (!ekind_equal (unew->ukind, old->ukind))
8780 ** okay, only if one is a function and the other is
8781 ** a variable of type function.
8784 if (unew->ukind == KENUMCONST
8785 && old->ukind == KCONST)
8787 old->ukind = KENUMCONST;
8791 if (unew->ukind == KFCN
8792 && old->ukind == KCONST
8793 && ctype_isUnknown (old->utype))
8796 ** When a function is defined with an unparam macro
8799 uentry_copyInto (old, unew);
8803 if (uentry_isExpandedMacro (old)
8804 && uentry_isEitherConstant (unew))
8806 uentry_copyInto (old, unew);
8810 if (uentry_isEndIter (unew))
8812 if (ctype_isUnknown (old->utype))
8814 if (!uentry_isSpecified (old)
8815 && uentry_isCodeDefined (unew))
8817 if (!fileloc_withinLines (uentry_whereDefined (old),
8818 uentry_whereDeclared (unew), 2))
8819 { /* bogus! will give errors if there is too much whitespace */
8823 ("Iterator finalized name %q does not match name in "
8824 "previous iter declaration (should be end_%q). This iter "
8825 "is declared at %q",
8826 uentry_getName (unew),
8827 uentry_getName (old),
8828 fileloc_unparse (uentry_whereDefined (old))),
8829 uentry_whereDeclared (old));
8833 uentry_copyInto (old, unew);
8838 KindConformanceError (old, unew, mustConform);
8842 if (uentry_isFunction (unew))
8844 if (uentry_isVariable (old))
8846 if (!ctype_isUnknown (old->utype))
8848 if (ctype_isFunction (old->utype))
8850 uentry_makeVarFunction (old);
8851 checkFunctionConformance (old, unew, mustConform,
8853 fcnConformance = TRUE;
8857 KindConformanceError (old, unew, mustConform);
8862 if (uentry_isExpandedMacro (old))
8864 if (fileloc_isUndefined (unew->whereDefined))
8866 unew->whereDefined = fileloc_update (unew->whereDefined,
8870 uentry_copyInto (old, unew);
8871 old->used = unew->used = TRUE;
8876 /* undeclared identifier */
8877 old->utype = unew->utype;
8878 uentry_makeVarFunction (old);
8879 checkFunctionConformance (old, unew, FALSE, FALSE);
8880 fcnConformance = TRUE;
8886 KindConformanceError (old, unew, mustConform);
8889 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8891 if (!ctype_isUnknown (unew->utype))
8893 if (ctype_isFunction (unew->utype))
8895 uentry_makeVarFunction (unew);
8896 checkFunctionConformance (old, unew, mustConform, completeConform);
8897 fcnConformance = TRUE;
8901 KindConformanceError (old, unew, mustConform);
8906 KindConformanceError (old, unew, mustConform);
8911 KindConformanceError (old, unew, mustConform);
8917 ** check parameter lists for functions
8918 ** (before type errors, to get better messages
8921 if (uentry_isFunction (old))
8923 checkFunctionConformance (old, unew, mustConform, completeConform);
8924 fcnConformance = TRUE;
8928 if (!ctype_isUndefined (old->utype))
8930 typeError = checkTypeConformance (old, unew, mustConform);
8937 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8939 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8942 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8944 DPRINTF (("Check datatype: %s / %s",
8945 uentry_unparseFull (old),
8946 uentry_unparseFull (unew)));
8948 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8951 if (uentry_isVariable (old) && uentry_isVariable (unew))
8954 !ctype_matchDef (old->utype, unew->utype))
8959 ("Variable %q %s with inconsistent type (arrays and pointers are "
8960 "not identical in variable declarations): %t",
8961 uentry_getName (unew),
8962 uentry_reDefDecl (old, unew),
8964 uentry_whereDeclared (unew)))
8966 uentry_showWhereLast (old);
8969 ** Avoid repeated errors.
8972 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8974 old->whereDefined = fileloc_update (old->whereDefined,
8982 checkVarConformance (old, unew, mustConform, completeConform);
8987 /* old->utype = unew->utype; */
8991 if (ctype_isConj (old->utype))
8993 if (ctype_isConj (unew->utype))
8995 if (!ctype_sameAltTypes (old->utype, unew->utype))
8999 message ("%s %q inconsistently %rdeclared with "
9000 "alternate types %s "
9001 "(types match, but alternates are not identical, "
9002 "so checking may not be correct)",
9003 ekind_capName (uentry_getKind (old)),
9004 uentry_getName (unew),
9005 uentry_isDeclared (old),
9006 ctype_unparse (unew->utype)),
9007 uentry_whereDeclared (unew)))
9009 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9013 old->utype = unew->utype;
9020 if (ctype_isUnknown (old->utype))
9022 old->utype = unew->utype;
9027 if (unew->ukind == old->ukind)
9030 unew->info = uinfo_copy (old->info, old->ukind);
9033 sRef_storeState (old->sref);
9034 sRef_storeState (unew->sref);
9038 ** modifies spec to reflect def, reports any inconsistencies
9042 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9044 llassert (uentry_isValid (spec));
9045 llassert (uentry_isValid (def));
9046 llassert (cstring_equal (spec->uname, def->uname));
9048 DPRINTF (("Merge entries: %s / %s",
9049 uentry_unparseFull (spec),
9050 uentry_unparseFull (def)));
9052 uentry_checkConformance (spec, def, TRUE,
9053 context_getFlag (FLG_NEEDSPEC));
9055 DPRINTF (("Merge entries after conform: %s / %s",
9056 uentry_unparseFull (spec),
9057 uentry_unparseFull (def)));
9059 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9062 ** okay, declarations conform. Propagate extra information.
9065 uentry_setDefined (spec, uentry_whereDefined (def));
9066 uentry_setDeclared (spec, uentry_whereDeclared (def));
9068 if (uentry_isStatic (def))
9072 message ("%s %q specified, but declared as static",
9073 ekind_capName (def->ukind),
9074 uentry_getName (def)),
9075 uentry_whereDeclared (def)))
9077 uentry_showWhereSpecified (spec);
9082 spec->storageclass = def->storageclass;
9085 sRef_storeState (spec->sref);
9087 spec->used = def->used || spec->used;
9088 spec->hasNameError |= def->hasNameError;
9092 if (!spec->hasNameError)
9094 uentry_checkName (spec);
9103 ** Can't generate function redeclaration errors when the
9104 ** entries are merged, since we don't yet know if its the
9105 ** definition of the function.
9109 uentry_clearDecl (void)
9111 posRedeclared = uentry_undefined;
9112 fileloc_free (posLoc);
9113 posLoc = fileloc_undefined;
9117 uentry_checkDecl (void)
9119 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9121 llassert (fileloc_isDefined (posLoc));
9123 if (uentry_isCodeDefined (posRedeclared))
9125 if (optgenerror (FLG_REDECL,
9126 message ("%s %q declared after definition",
9127 ekind_capName (posRedeclared->ukind),
9128 uentry_getName (posRedeclared)),
9131 llgenindentmsg (message ("Definition of %q",
9132 uentry_getName (posRedeclared)),
9133 posRedeclared->whereDeclared);
9138 if (optgenerror (FLG_REDECL,
9139 message ("%s %q declared more than once",
9140 ekind_capName (posRedeclared->ukind),
9141 uentry_getName (posRedeclared)),
9144 llgenindentmsg (message ("Previous declaration of %q",
9145 uentry_getName (posRedeclared)),
9146 posRedeclared->whereDeclared);
9151 fileloc_free (posLoc);
9152 posLoc = fileloc_undefined;
9153 posRedeclared = uentry_undefined;
9157 ** Redefinition of old as unew.
9158 ** modifies old to reflect unew, reports any inconsistencies
9162 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9164 fileloc olddef = uentry_whereDeclared (old);
9165 fileloc unewdef = uentry_whereDeclared (unew);
9169 DPRINTF (("uentry merge: %s / %s",
9170 uentry_unparseFull (old),
9171 uentry_unparseFull (unew)));
9173 if (uentry_isExtern (unew))
9175 uentry_setUsed (old, unewdef);
9179 fileloc_isUndefined (olddef)
9180 && fileloc_isDefined (uentry_whereDefined (old))
9181 && !uentry_isExpandedMacro (old);
9183 if (!context_getFlag (FLG_INCONDEFSLIB)
9184 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9186 mustConform = FALSE;
9193 llassert (uentry_isValid (old));
9194 llassert (uentry_isValid (unew));
9195 llassert (cstring_equal (old->uname, unew->uname));
9198 ** should check old one was extern!
9201 if (uentry_isStatic (old))
9203 if (!(uentry_isStatic (unew)))
9207 message ("%s %q shadows static declaration",
9208 ekind_capName (unew->ukind),
9209 uentry_getName (unew)),
9212 uentry_showWhereLast (old);
9217 uentry_setDeclDef (old, unewdef);
9220 else if (uentry_isStatic (unew))
9222 uentry_setDeclDef (old, unewdef);
9224 else if (uentry_isExtern (old))
9226 uentry_setDeclared (old, unewdef);
9230 if (!uentry_isExtern (unew) && !uentry_isForward (old)
9231 && !fileloc_equal (olddef, unewdef)
9232 && !fileloc_isUndefined (olddef)
9233 && !fileloc_isUndefined (unewdef)
9234 && !fileloc_isBuiltin (olddef)
9235 && !fileloc_isBuiltin (unewdef)
9236 && !uentry_isYield (old)
9237 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9239 if (uentry_isVariable (old) || uentry_isVariable (unew))
9241 ; /* will report redeclaration error later */
9245 if (fileloc_isDefined (uentry_whereDefined (old)))
9249 message ("%s %q defined more than once",
9250 ekind_capName (unew->ukind),
9251 uentry_getName (unew)),
9252 uentry_whereLast (unew)))
9255 (message ("Previous definition of %q",
9256 uentry_getName (old)),
9257 uentry_whereLast (old));
9260 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9262 uentry_copyInto (old, unew);
9263 old->sref = sRef_saveCopy (old->sref);
9271 if (fileloc_isLib (olddef)
9272 || fileloc_isUndefined (olddef)
9273 || fileloc_isImport (olddef))
9275 if (uentry_isExtern (unew))
9277 if (uentry_isExtern (old)
9278 || (fileloc_isDefined (uentry_whereDeclared (old))
9279 && (!fileloc_equal (uentry_whereDeclared (old),
9280 uentry_whereDefined (old)))))
9284 message ("%s %q declared more than once",
9285 ekind_capName (unew->ukind),
9286 uentry_getName (unew)),
9287 unew->whereDeclared))
9290 (message ("Previous declaration of %q",
9291 uentry_getName (old)),
9292 old->whereDeclared);
9296 uentry_setExtern (old);
9300 uentry_setDefined (old, unewdef);
9306 uentry_checkConformance (old, unew, mustConform, FALSE);
9308 old->used = old->used || unew->used;
9309 old->uses = filelocList_append (old->uses, unew->uses);
9310 unew->uses = filelocList_undefined;
9312 sRef_storeState (old->sref);
9313 sRef_storeState (unew->sref);
9317 old->whereDefined = fileloc_update (old->whereDefined,
9322 ** No redeclaration errors for functions here, since we
9323 ** don't know if this is the definition of the function.
9326 if (fileloc_isUser (old->whereDeclared)
9327 && fileloc_isUser (unew->whereDeclared)
9328 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9329 && !fileloc_isDefined (unew->whereDefined))
9331 if (uentry_isFunction (old))
9333 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9334 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9338 if (optgenerror (FLG_REDECL,
9339 message ("%s %q declared more than once",
9340 ekind_capName (unew->ukind),
9341 uentry_getName (unew)),
9342 unew->whereDeclared))
9344 llgenindentmsg (message ("Previous declaration of %q",
9345 uentry_getName (old)),
9346 old->whereDeclared);
9351 if (fileloc_isUndefined (old->whereDefined))
9353 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9357 if (!context_processingMacros ()
9358 && fileloc_isUser (old->whereDefined)
9359 && fileloc_isUser (unew->whereDefined)
9360 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9362 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9364 if (uentry_isVariable (unew)
9365 && uentry_isExtern (unew))
9367 if (optgenerror (FLG_REDECL,
9368 message ("%s %q declared after definition",
9369 ekind_capName (unew->ukind),
9370 uentry_getName (unew)),
9371 unew->whereDeclared))
9373 llgenindentmsg (message ("Definition of %q",
9374 uentry_getName (old)),
9380 if (optgenerror (FLG_REDEF,
9381 message ("%s %q redefined",
9382 ekind_capName (unew->ukind),
9383 uentry_getName (unew)),
9384 unew->whereDefined))
9386 llgenindentmsg (message ("Previous definition of %q",
9387 uentry_getName (old)),
9395 if (uentry_isExternal (unew))
9397 old->whereDefined = fileloc_createExternal ();
9400 if (unew->hasNameError)
9402 old->hasNameError = TRUE;
9407 if (!old->hasNameError)
9409 uentry_checkName (old);
9412 llassert (!ctype_isUndefined (old->utype));
9416 uentry_copyState (uentry res, uentry other)
9418 llassert (uentry_isValid (res));
9419 llassert (uentry_isValid (other));
9421 res->used = other->used;
9423 res->info->var->kind = other->info->var->kind;
9424 res->info->var->defstate = other->info->var->defstate;
9425 res->info->var->nullstate = other->info->var->nullstate;
9426 res->info->var->checked = other->info->var->checked;
9428 sRef_copyState (res->sref, other->sref);
9432 uentry_sameKind (uentry u1, uentry u2)
9434 if (uentry_isValid (u1) && uentry_isValid (u2))
9436 if (uentry_isVar (u1) && uentry_isVar (u2))
9438 ctype c1 = u1->utype;
9439 ctype c2 = u2->utype;
9441 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9444 ** both functions, or both not functions
9447 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9451 return ((u1->ukind == u2->ukind));
9458 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
9460 llassert (uentry_isValid (unew));
9461 llassert (uentry_isValid (old));
9463 unew->ukind = old->ukind;
9464 unew->uname = cstring_copy (old->uname);
9465 unew->utype = old->utype;
9467 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9468 unew->whereDefined = fileloc_copy (old->whereDefined);
9469 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9471 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9472 unew->used = old->used;
9474 unew->isPrivate = old->isPrivate;
9475 unew->hasNameError = old->hasNameError;
9476 unew->uses = filelocList_undefined;
9478 unew->storageclass = old->storageclass;
9479 unew->info = uinfo_copy (old->info, old->ukind);
9484 uentry_copy (uentry e)
9486 if (uentry_isValid (e))
9488 uentry enew = uentry_alloc ();
9489 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9490 uentry_copyInto (enew, e);
9491 DPRINTF (("Here we are..."));
9492 DPRINTF (("original: %s", uentry_unparseFull (e)));
9493 DPRINTF (("copy: %s", uentry_unparse (enew)));
9494 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9499 return uentry_undefined;
9504 uentry_setState (uentry res, uentry other)
9506 llassert (uentry_isValid (res));
9507 llassert (uentry_isValid (other));
9509 llassert (res->ukind == other->ukind);
9510 llassert (res->ukind == KVAR);
9512 res->sref = sRef_saveCopy (other->sref);
9513 res->used = other->used;
9514 filelocList_free (res->uses);
9515 res->uses = other->uses;
9516 other->uses = filelocList_undefined;
9517 res->lset = other->lset;
9521 uentry_mergeUses (uentry res, uentry other)
9523 llassert (uentry_isValid (res));
9524 llassert (uentry_isValid (other));
9526 res->used = other->used || res->used;
9527 res->lset = other->lset || res->lset;
9528 res->uses = filelocList_append (res->uses, other->uses);
9529 other->uses = filelocList_undefined;
9534 ** This is a really ugly routine.
9536 ** gack...fix this one day.
9541 ** >> res is the false branch, other is the true branch (or continuation)
9543 ** >> res is the true branch, other is the false branch (or continutation)
9550 ** References not effected by res are propagated from other.
9554 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9555 bool flip, clause cl, fileloc loc)
9559 message ("%s %q is %s %s, but %s %s.",
9560 ekind_capName (res->ukind), uentry_getName (res),
9561 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9562 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9565 if (sRef_isDead (res->sref))
9567 sRef_showStateInfo (res->sref);
9569 else if (sRef_isKept (res->sref))
9571 sRef_showAliasInfo (res->sref);
9573 else /* dependent */
9575 sRef_showAliasInfo (res->sref);
9576 sRef_showAliasInfo (other->sref);
9579 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9583 static bool incompatibleStates (sRef rs, sRef os)
9585 alkind rk = sRef_getAliasKind (rs);
9586 alkind ok = sRef_getAliasKind (os);
9588 if (alkind_isError (rk) || alkind_isError (ok))
9594 return ((sRef_isDead (rs)
9595 || (alkind_isKept (rk) && !alkind_isKept (ok))
9596 || (alkind_isDependent (rk)
9597 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9598 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9603 branchStateAltError (/*@notnull@*/ uentry res,
9604 /*@notnull@*/ uentry other, bool flip,
9605 clause cl, fileloc loc)
9609 message ("%s %q is %s %s, but %s %s.",
9610 ekind_capName (res->ukind), uentry_getName (res),
9611 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
9612 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
9615 if (sRef_isDead (other->sref))
9617 sRef_showStateInfo (other->sref);
9621 sRef_showAliasInfo (other->sref);
9624 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9625 sRef_setDefinedComplete (res->sref, fileloc_undefined);
9627 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
9628 sRef_setDefinedComplete (other->sref, fileloc_undefined);
9633 ** A reference is relevant for certain checks, only if it
9634 ** is not definitely null on this path (but not declared
9635 ** to always be null.)
9638 static bool uentry_relevantReference (sRef sr, bool flip)
9640 if (sRef_isKept (sr) || sRef_isDependent (sr))
9648 return !sRef_definitelyNullContext (sr);
9652 return !sRef_definitelyNullAltContext (sr);
9658 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
9659 bool mustReturn, bool flip, bool opt,
9662 DPRINTF (("Merge alias states: %s / %s",
9663 uentry_unparseFull (res),
9664 uentry_unparseFull (other)));
9666 if (sRef_isValid (res->sref))
9671 if (incompatibleStates (res->sref, other->sref))
9675 if (sRef_isThroughArrayFetch (res->sref)
9676 && !context_getFlag (FLG_STRICTBRANCHSTATE))
9678 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
9680 sRef_maybeKill (res->sref, loc);
9682 else if (sRef_isPossiblyDead (other->sref))
9684 sRef_maybeKill (res->sref, loc);
9693 if (uentry_relevantReference (other->sref, flip))
9696 if (sRef_isLocalParamVar (res->sref)
9697 && (sRef_isLocalState (other->sref)
9698 || sRef_isDependent (other->sref)))
9700 if (sRef_isDependent (res->sref))
9702 sRef_setDependent (other->sref, loc);
9706 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
9711 branchStateError (res, other, flip, cl, loc);
9716 if (sRef_isKept (res->sref))
9718 sRef_setKept (other->sref, loc);
9723 if (incompatibleStates (other->sref, res->sref))
9725 if (uentry_relevantReference (res->sref, !flip))
9727 if (sRef_isLocalParamVar (res->sref)
9728 && (sRef_isDependent (res->sref)
9729 || sRef_isLocalState (res->sref)))
9731 if (sRef_isDependent (other->sref))
9733 sRef_setDependent (res->sref, loc);
9737 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
9742 if (sRef_isParam (other->sref))
9745 ** If the local variable associated
9746 ** with the param has the correct state,
9748 ** (e.g., free (s); s = new(); ...
9751 uentry uvar = usymtab_lookupSafe (other->uname);
9753 if (uentry_isValid (uvar)
9754 && ((sRef_isDead (other->sref)
9755 && sRef_isOnly (uvar->sref))
9756 || (sRef_isDependent (other->sref)
9757 && sRef_isOwned (uvar->sref))))
9763 branchStateAltError (res, other,
9769 DPRINTF (("Here: %s / %s",
9770 uentry_unparseFull (res),
9771 uentry_unparseFull (other)));
9773 branchStateAltError (res, other,
9780 if (sRef_isKept (other->sref))
9782 sRef_setKept (res->sref, loc);
9788 DPRINTF (("Merge opt..."));
9789 sRef_mergeOptState (res->sref, other->sref, cl, loc);
9790 DPRINTF (("Done!"));
9794 sRef_mergeState (res->sref, other->sref, cl, loc);
9799 if (sRef_isModified (other->sref))
9801 sRef_setModified (res->sref);
9808 uentry_mergeValueStates (uentry res, uentry other, fileloc loc)
9813 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
9815 rvalues = sRef_getValueTable (res->sref);
9816 ovalues = sRef_getValueTable (other->sref);
9818 if (valueTable_isUndefined (ovalues))
9820 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
9823 else if (valueTable_isUndefined (rvalues))
9826 ** Copy values from other
9830 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
9831 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
9836 valueTable_elements (ovalues, fkey, fval) {
9838 metaStateInfo minfo;
9839 stateCombinationTable sctable;
9843 tval = valueTable_lookup (rvalues, fkey);
9845 DPRINTF (("Merge value: %s / %s X %s", fkey,
9846 stateValue_unparse (fval), stateValue_unparse (tval)));
9848 minfo = context_lookupMetaStateInfo (fkey);
9849 llassert (stateValue_isDefined (tval));
9851 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
9853 DPRINTF (("Cannot find meta state for: %s", fkey));
9858 llassert (metaStateInfo_isDefined (minfo));
9860 if (stateValue_isError (fval)
9861 || sRef_definitelyNullContext (res->sref))
9863 sRef_setMetaStateValueComplete (res->sref,
9864 fkey, stateValue_getValue (fval),
9866 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
9868 else if (stateValue_isError (tval)
9869 || sRef_definitelyNullAltContext (other->sref))
9871 DPRINTF (("Other branch is definitely null!"));
9875 DPRINTF (("Check: %s / %s / %s / %s", fkey,
9876 metaStateInfo_unparse (minfo),
9877 stateValue_unparse (fval),
9878 stateValue_unparse (tval)));
9880 DPRINTF (("state values: %d / %d",
9881 stateValue_getValue (fval), stateValue_getValue (tval)));
9883 sctable = metaStateInfo_getMergeTable (minfo);
9885 DPRINTF (("Merge table: %s",
9886 stateCombinationTable_unparse (sctable)));
9888 msg = cstring_undefined;
9890 nval = stateCombinationTable_lookup (sctable,
9891 stateValue_getValue (fval),
9892 stateValue_getValue (tval),
9895 DPRINTF (("nval: %d / %d / %d", nval,
9896 stateValue_getValue (fval), stateValue_getValue (tval)));
9898 if (cstring_isDefined (msg))
9900 /*@i32 print extra info for assignments@*/
9902 if (uentry_isGlobalMarker (res))
9907 ("Control branches merge with incompatible global states (%s and %s): %s",
9908 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
9909 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
9913 sRef_showMetaStateInfo (res->sref, fkey);
9914 sRef_showMetaStateInfo (other->sref, fkey);
9922 ("Control branches merge with incompatible states for %q (%s and %s): %s",
9923 uentry_getName (res),
9924 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
9925 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
9929 sRef_showMetaStateInfo (res->sref, fkey);
9930 sRef_showMetaStateInfo (other->sref, fkey);
9931 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
9932 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
9933 DPRINTF (("Null: %s / %s",
9934 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
9935 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
9941 if (nval == stateValue_getValue (fval)
9942 && nval != stateValue_getValue (tval))
9944 loc = stateValue_getLoc (fval);
9946 else if (nval == stateValue_getValue (tval)
9947 && nval != stateValue_getValue (fval))
9949 loc = stateValue_getLoc (tval);
9956 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
9957 && nval == stateValue_getValue (fval)
9958 && nval == stateValue_getValue (tval))
9964 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
9968 } end_valueTable_elements ;
9974 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
9975 bool flip, clause cl)
9977 if (cl == DOWHILECLAUSE)
9979 res->used = other->used || res->used;
9980 res->lset = other->lset || res->lset;
9981 res->uses = filelocList_append (res->uses, other->uses);
9982 other->uses = filelocList_undefined;
9986 if (sRef_isMacroParamRef (res->sref)
9987 && !uentry_isSefParam (other)
9988 && !uentry_isSefParam (res))
9990 bool hasError = FALSE;
9992 if (bool_equal (res->used, other->used))
9994 res->used = other->used;
9998 if (other->used && !flip)
10003 message ("Macro parameter %q used in true clause, "
10004 "but not in false clause",
10005 uentry_getName (res)),
10006 uentry_whereDeclared (res));
10013 message ("Macro parameter %q used in false clause, "
10014 "but not in true clause",
10015 uentry_getName (res)),
10016 uentry_whereDeclared (res));
10022 /* make it sef now, prevent more errors */
10023 res->info->var->kind = VKREFSEFPARAM;
10029 res->used = other->used || res->used;
10030 res->lset = other->lset || res->lset;
10031 res->uses = filelocList_append (res->uses, other->uses);
10032 other->uses = filelocList_undefined;
10038 uentry_mergeState (uentry res, uentry other, fileloc loc,
10039 bool mustReturn, bool flip, bool opt,
10042 llassert (uentry_isValid (res));
10043 llassert (uentry_isValid (other));
10045 llassert (res->ukind == other->ukind);
10046 llassert (res->ukind == KVAR);
10048 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10049 uentry_unparseFull (other)));
10051 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10052 uentry_mergeValueStates (res, other, loc);
10053 uentry_mergeSetStates (res, other, loc, flip, cl);
10056 void uentry_setUsed (uentry e, fileloc loc)
10058 static bool firstTime = TRUE;
10059 static bool showUses = FALSE;
10060 static bool exportLocal = FALSE;
10062 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10066 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10068 showUses = context_getFlag (FLG_SHOWUSES);
10069 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10074 if (uentry_isValid (e))
10078 if (warnClause_isDefined (e->warn))
10080 flagSpec flg = warnClause_getFlag (e->warn);
10083 if (warnClause_hasMessage (e->warn))
10085 msg = cstring_copy (warnClause_getMessage (e->warn));
10089 msg = message ("Use of possibly dangerous %s",
10090 uentry_ekindNameLC (e));
10094 message ("%q: %q", msg, uentry_getName (e)),
10098 if (sRef_isMacroParamRef (e->sref))
10100 if (uentry_isYield (e) || uentry_isSefParam (e))
10106 if (context_inConditional ())
10110 message ("Macro parameter %q used in conditionally "
10111 "executed code (may or may not be "
10112 "evaluated exactly once)",
10113 uentry_getName (e)),
10116 e->info->var->kind = VKREFSEFPARAM;
10125 message ("Macro parameter %q used more than once",
10126 uentry_getName (e)),
10127 uentry_whereDeclared (e)))
10129 e->info->var->kind = VKREFSEFPARAM;
10136 if ((dp = uentry_directParamNo (e)) >= 0)
10138 uentry_setUsed (usymtab_getParam (dp), loc);
10143 if (!sRef_isLocalVar (e->sref))
10147 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10153 if (context_inMacro ())
10155 e->uses = filelocList_addUndefined (e->uses);
10159 e->uses = filelocList_addDifferentFile
10161 uentry_whereDeclared (e),
10170 bool uentry_isReturned (uentry u)
10172 return (uentry_isValid (u) && uentry_isVar (u)
10173 && (u->info->var->kind == VKRETPARAM
10174 || u->info->var->kind == VKSEFRETPARAM));
10177 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10179 llassert (uentry_isRealFunction (u));
10181 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10183 stateClauseList clauses = uentry_getStateClauseList (u);
10184 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10186 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10187 sRef_setAllocated (res, g_currentloc);
10189 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10190 stateClauseList_unparse (clauses)));
10192 stateClauseList_postElements (clauses, cl)
10194 if (!stateClause_isGlobal (cl))
10196 sRefSet refs = stateClause_getRefs (cl);
10197 sRefMod modf = stateClause_getEffectFunction (cl);
10199 sRefSet_elements (refs, el)
10201 sRef base = sRef_getRootBase (el);
10203 if (sRef_isResult (base))
10207 sRef sr = sRef_fixBase (el, res);
10208 modf (sr, g_currentloc);
10215 } end_sRefSet_elements ;
10217 } end_stateClauseList_postElements ;
10225 sRefSet prefs = sRefSet_new ();
10226 sRef res = sRef_undefined;
10229 params = uentry_getParams (u);
10231 uentryList_elements (params, current)
10233 if (uentry_isReturned (current))
10235 if (exprNodeList_size (args) >= paramno)
10237 exprNode ecur = exprNodeList_nth (args, paramno);
10238 sRef tref = exprNode_getSref (ecur);
10240 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10242 if (sRef_isValid (tref))
10244 sRef tcref = sRef_copy (tref);
10246 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10248 if (sRef_isDead (tcref))
10250 sRef_setDefined (tcref, g_currentloc);
10251 sRef_setOnly (tcref, g_currentloc);
10254 if (sRef_isRefCounted (tcref))
10256 /* could be a new ref now (but only if its returned) */
10257 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10260 sRef_makeSafe (tcref);
10261 prefs = sRefSet_insert (prefs, tcref);
10267 } end_uentryList_elements ;
10269 if (sRefSet_size (prefs) > 0)
10271 nstate n = sRef_getNullState (u->sref);
10273 if (sRefSet_size (prefs) == 1)
10275 res = sRefSet_choose (prefs);
10279 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10280 res = sRefSet_mergeIntoOne (prefs);
10283 if (nstate_isKnown (n))
10285 sRef_setNullState (res, n, g_currentloc);
10290 if (ctype_isFunction (u->utype))
10292 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10293 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10297 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10300 if (sRef_isRefCounted (res))
10302 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10307 if (sRef_getNullState (res) == NS_ABSNULL)
10309 ctype ct = ctype_realType (u->utype);
10311 if (ctype_isAbstract (ct))
10313 sRef_setNotNull (res, g_currentloc);
10317 if (ctype_isUser (ct))
10319 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10323 sRef_setNotNull (res, g_currentloc);
10328 if (sRef_isRefCounted (res))
10330 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10332 else if (sRef_isKillRef (res))
10334 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10341 ak = sRef_getAliasKind (res);
10343 if (alkind_isImplicit (ak))
10345 sRef_setAliasKind (res,
10346 alkind_fixImplicit (ak),
10350 sRefSet_free (prefs);
10352 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10357 static bool uentry_isRefCounted (uentry ue)
10359 ctype ct = uentry_getType (ue);
10361 if (ctype_isFunction (ct))
10363 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10367 return (ctype_isRefCounted (ct));
10372 ** old was declared yield in the specification.
10373 ** new is declared in the iter implementation.
10376 void uentry_checkYieldParam (uentry old, uentry unew)
10380 llassert (uentry_isVariable (old));
10381 llassert (uentry_isVariable (unew));
10383 unew->info->var->kind = VKYIELDPARAM;
10384 (void) checkTypeConformance (old, unew, TRUE);
10385 checkVarConformance (old, unew, TRUE, FALSE);
10387 /* get rid of param marker */
10389 name = uentry_getName (unew);
10390 cstring_free (unew->uname);
10391 unew->uname = name;
10392 unew->info->var->kind = VKREFYIELDPARAM;
10394 uentry_setUsed (old, fileloc_undefined);
10395 uentry_setUsed (unew, fileloc_undefined);
10398 /*@observer@*/ cstring
10399 uentry_ekindName (uentry ue)
10401 if (uentry_isValid (ue))
10406 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10408 return cstring_makeLiteralTemp ("Datatype");
10410 return cstring_makeLiteralTemp ("Enum member");
10412 return cstring_makeLiteralTemp ("Constant");
10414 if (uentry_isParam (ue))
10416 return cstring_makeLiteralTemp ("Parameter");
10418 else if (uentry_isExpandedMacro (ue))
10420 return cstring_makeLiteralTemp ("Expanded macro");
10424 return cstring_makeLiteralTemp ("Variable");
10427 return cstring_makeLiteralTemp ("Function");
10429 return cstring_makeLiteralTemp ("Iterator");
10431 return cstring_makeLiteralTemp ("Iterator finalizer");
10433 return cstring_makeLiteralTemp ("Struct tag");
10435 return cstring_makeLiteralTemp ("Union tag");
10437 return cstring_makeLiteralTemp ("Enum tag");
10439 return cstring_makeLiteralTemp ("Optional parameters");
10444 return cstring_makeLiteralTemp ("<Undefined>");
10450 /*@observer@*/ cstring
10451 uentry_ekindNameLC (uentry ue)
10453 if (uentry_isValid (ue))
10458 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10460 return cstring_makeLiteralTemp ("datatype");
10462 return cstring_makeLiteralTemp ("enum member");
10464 return cstring_makeLiteralTemp ("constant");
10466 if (uentry_isParam (ue))
10468 return cstring_makeLiteralTemp ("parameter");
10470 else if (uentry_isExpandedMacro (ue))
10472 return cstring_makeLiteralTemp ("expanded macro");
10476 return cstring_makeLiteralTemp ("variable");
10479 return cstring_makeLiteralTemp ("function");
10481 return cstring_makeLiteralTemp ("iterator");
10483 return cstring_makeLiteralTemp ("iterator finalizer");
10485 return cstring_makeLiteralTemp ("struct tag");
10487 return cstring_makeLiteralTemp ("union tag");
10489 return cstring_makeLiteralTemp ("enum tag");
10491 return cstring_makeLiteralTemp ("optional parameters");
10496 return cstring_makeLiteralTemp ("<Undefined>");
10502 void uentry_setHasNameError (uentry ue)
10504 llassert (uentry_isValid (ue));
10506 ue->hasNameError = TRUE;
10509 void uentry_checkName (uentry ue)
10511 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10512 uentry_observeRealName (ue),
10513 bool_unparse (uentry_isVisibleExternally (ue))));
10515 if (uentry_isValid (ue)
10516 && !context_inXHFile ()
10517 && uentry_hasName (ue)
10518 && !uentry_isElipsisMarker (ue)
10519 && context_getFlag (FLG_NAMECHECKS)
10520 && !ue->hasNameError
10521 && !uentry_isEndIter (ue)
10522 && !fileloc_isBuiltin (uentry_whereLast (ue))
10523 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10525 DPRINTF (("Here..."));
10527 if (uentry_isPriv (ue))
10529 ; /* any checks here? */
10531 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10533 ; /* no errors for externals */
10539 if (uentry_isExpandedMacro (ue))
10545 if (uentry_isExpandedMacro (ue))
10549 else if (uentry_isVariable (ue))
10551 sRef sr = uentry_getSref (ue);
10553 if (sRef_isValid (sr))
10555 scope = sRef_getScope (sr);
10562 else if (uentry_isFunction (ue)
10563 || uentry_isIter (ue)
10564 || uentry_isEndIter (ue)
10565 || uentry_isConstant (ue))
10567 scope = uentry_isStatic (ue) ? fileScope : globScope;
10569 else /* datatypes, etc. must be global */
10574 usymtab_checkDistinctName (ue, scope);
10577 if (context_getFlag (FLG_CPPNAMES))
10582 if (scope == globScope)
10584 checkExternalName (ue);
10586 else if (scope == fileScope)
10588 checkFileScopeName (ue);
10592 checkLocalName (ue);
10596 checkAnsiName (ue);
10601 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
10607 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
10608 if (!context_inMacro ())
10610 sRef_setGlobalScopeSafe ();
10613 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
10614 uentry_setUsed (ue, loc);
10616 tloc = fileloc_createExternal ();
10617 uentry_setDefined (ue, tloc);
10618 fileloc_free (tloc);
10619 uentry_setHasNameError (ue);
10621 if (context_getFlag (FLG_REPEATUNRECOG))
10623 uentry_markOwned (ue);
10627 ue = usymtab_supReturnFileEntry (ue);
10630 if (!context_inMacro ())
10632 sRef_clearGlobalScopeSafe ();
10638 uentry uentry_makeGlobalMarker ()
10643 llassert (sRef_inGlobalScope ());
10645 ue = uentry_makeVariableAux
10646 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
10647 sRef_makeGlobalMarker (),
10650 tloc = fileloc_createExternal ();
10651 uentry_setUsed (ue, tloc);
10652 uentry_setDefined (ue, tloc);
10653 fileloc_free (tloc);
10654 uentry_setHasNameError (ue);
10660 bool uentry_isGlobalMarker (uentry ue)
10662 return (uentry_isValid (ue)
10663 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
10668 /* new start modifications */
10675 static void uentry_testInRange (uentry p_e, uentry cconstant) {
10676 if( uentry_isValid(p_e) ) {
10677 if( sRef_isValid (p_e->sref) ) {
10678 char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
10679 int index = atoi( t );
10681 // usymtab_testInRange (p_e->sref, index);
10687 /* void uentry_setStringLength (uentry p_e, uentry cconstant) { */
10688 /* if( uentry_isValid(p_e) ) { */
10689 /* if( p_e->info != NULL) { */
10690 /* if( p_e->info->var != NULL) { */
10691 /* char *t = cstring_toCharsSafe (uentry_unparse(cconstant)); */
10692 /* int length = atoi( t ); */
10694 /* p_e->info->var->bufinfo->len = length; */
10695 /* p_e->sref->bufinfo.len = length; */
10696 /* printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size); */
10703 static void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
10704 if( uentry_isValid(p_e) ) {
10705 if( p_e->info != NULL) {
10706 if( p_e->info->var != NULL) {
10707 int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
10708 p_e->info->var->bufinfo->size = size;
10709 p_e->sref->bufinfo.size = size;
10710 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
10711 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
10712 // fprintf(stderr, "and %d\n", size );
10720 /* start modifications */
10722 requires: p_e is defined, is a ptr/array variable
10724 effects: sets the state of the variable
10728 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
10729 if( uentry_isValid(p_e) ) {
10730 if( p_e->info != NULL) {
10731 if( p_e->info->var != NULL) {
10732 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
10733 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
10739 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
10743 requires: p_e is defined, is a ptr/array variable
10745 effects: sets the size of the buffer
10748 void uentry_setNullTerminatedState (uentry p_e) {
10749 if( uentry_isValid(p_e) ) {
10750 if( p_e->info != NULL) {
10751 if( p_e->info->var != NULL) {
10752 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
10753 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
10759 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
10764 requires: p_e is defined, is a ptr/array variable
10766 effects: sets the state of the variable
10769 /* void uentry_setNotNullTerminatedState (uentry p_e) { */
10770 /* if( uentry_isValid(p_e) ) { */
10771 /* if( p_e->info != NULL) { */
10772 /* if( p_e->info->var != NULL) { */
10773 /* p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED; */
10774 /* p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED; */
10780 /* fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n"); */
10785 requires: p_e is defined, is a ptr/array variable
10787 effects: sets the size of the buffer
10790 void uentry_setSize (uentry p_e, int size) {
10791 if( uentry_isValid(p_e) ) {
10792 if( p_e->info != NULL) {
10793 if( p_e->info->var != NULL) {
10794 p_e->info->var->bufinfo->size = size;
10795 p_e->sref->bufinfo.size = size;
10801 fprintf(stderr, "uentry:Error in setSize\n");
10806 requires: p_e is defined, is a ptr/array variable
10808 effects: sets the length of the buffer
10811 void uentry_setLen (uentry p_e, int len) {
10812 if( uentry_isValid(p_e) ) {
10813 if( p_e->info != NULL) {
10814 if( p_e->info->var != NULL) {
10815 p_e->info->var->bufinfo->len = len;
10816 p_e->sref->bufinfo.len = len;
10822 fprintf(stderr, "uentry:Error in setLen\n");