2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 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"
35 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
36 static /*@only@*/ fileloc posLoc = fileloc_undefined;
37 static int nuentries = 0;
38 static int totuentries = 0;
40 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
41 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
42 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
43 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
44 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
45 static void uentry_checkIterArgs (uentry p_ue);
46 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
49 static void checkAliasState (/*@notnull@*/ uentry p_old,
50 /*@notnull@*/ uentry p_unew,
51 bool p_mustConform, bool p_completeConform)
52 /*@modifies p_old, p_unew@*/ ;
53 static void checkNullState (/*@notnull@*/ uentry p_old,
54 /*@notnull@*/ uentry p_unew,
55 bool p_mustConform, bool p_completeConform)
56 /*@modifies p_old, p_unew@*/ ;
58 static void checkVarConformance (/*@notnull@*/ uentry p_old,
59 /*@notnull@*/ uentry p_unew,
60 bool p_mustConform, bool p_completeConform)
61 /*@modifies p_old, p_unew@*/;
64 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
65 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
68 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
70 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
71 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
74 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
75 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
76 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
77 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
78 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
80 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
81 ctype p_oldType, /*@notnull@*/ uentry p_unew,
82 /*@notnull@*/ uentry p_newCurrent,
83 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
85 static /*@only@*/ /*@notnull@*/ uentry
86 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
87 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
89 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
91 uentry ue = (uentry) dmalloc (sizeof (*ue));
98 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
99 static void uentry_copyInto (/*@out@*/ /*@unique@*/ uentry p_unew, uentry p_old);
100 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
101 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
102 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
103 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
104 static void uvinfo_free (/*@only@*/ uvinfo p_u);
108 static /*@only@*/ cstring ancontext_unparse (ancontext an)
112 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
113 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
114 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
115 case AN_SUFIELD: return cstring_makeLiteral ("su field");
116 case AN_TDEFN: return cstring_makeLiteral ("type definition");
117 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
118 case AN_CONST: return cstring_makeLiteral ("constant");
124 static int annots[AN_LAST][QU_LAST];
125 static int decls[AN_LAST];
126 static int shdecls[AN_LAST];
127 static int idecls[AN_LAST];
133 for (i = AN_UNKNOWN; i < AN_LAST; i++)
139 for (j = QU_UNKNOWN; j < QU_LAST; j++)
146 static void tallyAnnot (ancontext ac, qual q)
160 for (j = QU_UNKNOWN; j < QU_LAST; j++)
165 for (i = AN_UNKNOWN; i < AN_LAST; i++)
171 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
172 ancontext_unparse (i),
173 decls[i], shdecls[i], idecls[i]);
175 totdecls += decls[i];
176 totshdecls += shdecls[i];
177 totidecls += idecls[i];
179 for (j = QU_UNKNOWN; j < QU_LAST; j++)
181 total[j] += annots[i][j];
182 alltotals += annots[i][j];
185 printf (" Allocation:\n");
189 for (j = QU_UNKNOWN; j < QU_LAST; j++)
191 if (qual_isAliasQual (j) && !qual_isUnique (j))
193 if (annots[i][j] > 0)
195 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
196 100.0 * (double)annots[i][j] / (double)decls[i]);
197 tmptot += annots[i][j];
202 printf (" Exposure:\n");
206 for (j = QU_UNKNOWN; j < QU_LAST; j++)
208 if (qual_isExQual (j))
210 if (annots[i][j] > 0)
212 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
213 100.0 * (double)annots[i][j] / (double)decls[i]);
214 tmptot += annots[i][j];
219 printf (" Definition:\n");
221 for (j = QU_UNKNOWN; j < QU_LAST; j++)
223 if (qual_isAllocQual (j))
225 if (annots[i][j] > 0)
227 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
228 100.0 * (double)annots[i][j] / (double)decls[i]);
235 for (j = QU_UNKNOWN; j < QU_LAST; j++)
237 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
239 if (annots[i][j] > 0)
241 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
242 100.0 * (double)annots[i][j] / (double)decls[i]);
251 for (j = QU_UNKNOWN; j < QU_LAST; j++)
255 for (i = AN_UNKNOWN; i < AN_LAST; i++)
257 if (annots[i][j] > 0)
266 printf ("Annotation: %s\n", qual_unparse (j));
268 for (i = AN_UNKNOWN; i < AN_LAST; i++)
270 if (annots[i][j] > 0)
272 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
279 printf ("All Contexts\n");
281 for (j = QU_UNKNOWN; j < QU_LAST; j++)
285 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
286 100.0 * (double)total[j] / (double)(totdecls));
291 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
293 extern void uentry_tallyAnnots (uentry u, ancontext kind)
295 alkind ak = sRef_getAliasKind (u->sref);
296 exkind ek = sRef_getExKind (u->sref);
297 nstate ns = sRef_getNullState (u->sref);
298 sstate ss = sRef_getDefState (u->sref);
299 bool recordUnknown = FALSE;
302 if (kind == AN_UNKNOWN)
310 else if (e == KCONST || e == KENUMCONST)
314 else if (e == KFCN || e == KITER)
316 uentryList params = uentry_getParams (u);
319 uentryList_elements (params, current)
321 if (uentry_isReturned (current))
325 if (!uentry_isElipsisMarker (current))
327 uentry_tallyAnnots (current, AN_FCNPARAM);
329 } end_uentryList_elements;
333 if (ctype_isFunction (u->utype)
335 && ctype_isVisiblySharable (ctype_realType (ctype_returnValue (u->utype))))
337 recordUnknown = TRUE;
340 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
342 ctype t = ctype_realType (u->utype);
346 uentryList fields = ctype_getFields (t);
348 uentryList_elements (fields, current)
350 uentry_tallyAnnots (current, AN_SUFIELD);
352 } end_uentryList_elements;
356 if (ctype_isVisiblySharable (u->utype))
358 recordUnknown = TRUE;
366 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
368 recordUnknown = TRUE;
375 if (kind == AN_FCNRETURN)
389 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
394 if (ctype_isRealPointer (ctype_realType (u->utype)))
411 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
412 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
413 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
414 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
418 if (uentry_isReturned (u))
420 tallyAnnot (kind, QU_RETURNED);
426 if (ctype_isRefCounted (ctype_realType (u->utype))
427 || (ctype_isFunction (u->utype) &&
428 ctype_isRefCounted (ctype_realType (ctype_returnValue (u->utype)))))
434 if (kind == AN_FCNPARAM)
436 tallyAnnot (kind, QU_TEMP);
438 else if (recordUnknown)
440 if (kind == AN_FCNRETURN)
443 tallyAnnot (kind, QU_UNKNOWN);
447 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
448 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
449 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
450 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
452 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
453 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
454 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
455 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
456 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
457 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
458 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
459 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
460 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
461 case AK_IMPDEPENDENT:
462 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
472 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
473 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
479 case NS_ERROR: break;
480 case NS_UNKNOWN: break;
481 case NS_NOTNULL: break;
482 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
483 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
484 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
485 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
487 case NS_ABSNULL: break;
493 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
497 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
498 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
499 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
500 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
501 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
507 static specCode specCode_fromInt (int i)
510 llassert (i >= SPC_NONE && i < SPC_LAST);
512 return ((specCode) i);
516 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
518 if (uentry_isDeclared (u))
520 return cstring_makeLiteralTemp ("previously declared");
524 return cstring_makeLiteralTemp ("specified");
528 /*@observer@*/ cstring uentry_specDeclName (uentry u)
530 if (uentry_isDeclared (u))
532 return cstring_makeLiteralTemp ("previous declaration");
536 return cstring_makeLiteralTemp ("specification");
540 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
542 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
544 return cstring_makeLiteralTemp ("redefined");
546 else if (uentry_isCodeDefined (unew))
548 return cstring_makeLiteralTemp ("defined");
550 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
552 return cstring_makeLiteralTemp ("redeclared");
556 return cstring_makeLiteralTemp ("declared");
560 static /*@only@*/ fileloc setLocation (void)
562 fileloc fl = context_getSaveLocation ();
564 if (fileloc_isDefined (fl))
570 return fileloc_copy (g_currentloc);
574 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
576 fileloc loc = setLocation ();
577 uentry ue = uentry_makeConstant (n, t, loc);
579 ue->ukind = KENUMCONST;
580 uentry_setDefined (ue, loc);
584 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
586 fileloc loc = setLocation ();
587 uentry ue = uentry_makeConstant (n, t, loc);
588 ctype etype = exprNode_getType (expr);
590 if (!ctype_isRealInt (etype)) {
594 ("Value of enum member is not an integeral type (type %s): %s",
595 ctype_unparse (etype), exprNode_unparse (expr)),
596 exprNode_loc (expr));
599 ue->ukind = KENUMCONST;
600 uentry_setDefined (ue, loc);
605 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
607 uentry ue = uentry_makeConstant (n, t, loc);
609 ue->ukind = KENUMCONST;
614 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
616 return uentry_makeVariable (n, t, setLocation (), FALSE);
620 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
622 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
626 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
628 ctype ct = idDecl_getCtype (id);
629 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
630 MAYBE, MAYBE, setLocation ());
632 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
634 if (!ynm_isOn (ue->info->datatype->abs))
636 if (ctype_isUnknown (ct))
638 ue->info->datatype->mut = MAYBE;
642 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
649 void uentry_checkParams (uentry ue)
651 if (uentry_isValid (ue))
653 bool isExt = uentry_isExtern (ue);
655 if (uentry_isRealFunction (ue))
657 uentryList params = uentry_getParams (ue);
659 uentryList_elements (params, current)
661 if (uentry_isValid (current))
663 ctype ct = current->utype;
665 if (ctype_isFixedArray (ct))
667 if (ctype_isArray (ctype_baseArrayPtr (ct))
668 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
675 (FLG_FIXEDFORMALARRAY,
676 message ("Function parameter %q declared as "
677 "manifest array (size constant is meaningless)",
678 uentry_getName (current)),
679 uentry_whereDeclared (current));
684 if (ctype_isArray (ct))
688 message ("Function parameter %q declared as "
689 "array (treated as pointer)",
690 uentry_getName (current)),
691 uentry_whereDeclared (current));
695 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
697 if (ctype_isAbstract (ct) &&
698 (isExt || (ctype_isAbstract (ctype_realType (ct))
699 && !context_hasFileAccess (ctype_typeId (ct)))))
704 ("Function %q declared with notnull parameter %q of abstract "
707 uentry_getName (current),
710 ("Since %s is an abstract type, notnull can only be "
711 "used for parameters if the function is static to a "
712 "module where %s is accessible.",
715 uentry_whereDeclared (current));
719 } end_uentryList_elements;
721 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
723 ctype ct = ue->utype;
725 if (ctype_isAbstract (ct)
726 && (isExt || (ctype_isAbstract (ctype_realType (ct))
727 && !context_hasFileAccess (ctype_typeId (ct)))))
732 ("%s %q declared %s notnull storage of abstract type %s",
733 ekind_capName (uentry_getKind (ue)),
738 ("Since %s is an abstract type, notnull can only be used "
739 "if it is static to a module where %s is accessible.",
742 uentry_whereDeclared (ue));
749 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
751 alkind ak = sRef_getAliasKind (ue->sref);
753 if (alkind_isRefCounted (ak))
755 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
759 if (alkind_isUnknown (ak))
761 exkind ek = sRef_getExKind (ue->sref);
763 if (exkind_isKnown (ek))
765 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
769 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
771 if (ctype_isVisiblySharable
772 (ctype_realType (ctype_returnValue (ue->utype))))
774 if (uentryList_hasReturned (uentry_getParams (ue)))
780 sRef_setAliasKind (ue->sref, AK_IMPONLY,
790 static /*@notnull@*/ uentry
791 uentry_makeFunctionAux (cstring n, ctype t,
793 /*@only@*/ globSet globs,
794 /*@only@*/ sRefSet mods,
795 /*@keep@*/ fileloc f, bool priv,
796 /*@unused@*/ bool isForward)
798 uentry e = uentry_alloc ();
801 if (ctype_isFunction (t))
803 ret = ctype_returnValue (t);
807 if (ctype_isKnown (t))
809 llbug (message ("not function: %s", ctype_unparse (t)));
816 if (fileloc_isSpec (f) || fileloc_isImport (f))
818 e->whereSpecified = f;
819 e->whereDeclared = fileloc_undefined;
823 e->whereSpecified = fileloc_undefined;
824 e->whereDeclared = f;
827 /* e->shallowCopy = FALSE; */
828 e->uname = cstring_copy (n);
830 e->storageclass = SCNONE;
832 e->sref = sRef_makeType (ret);
834 if (ctype_isUA (ret))
836 sRef_setStateFromType (e->sref, ret);
841 e->uses = filelocList_new ();
843 e->hasNameError = FALSE;
845 e->info = (uinfo) dmalloc (sizeof (*e->info));
846 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
848 e->info->fcn->hasMods = sRefSet_isDefined (mods);
849 e->info->fcn->hasGlobs = globSet_isDefined (globs);
851 e->info->fcn->exitCode = XK_UNKNOWN;
852 e->info->fcn->nullPred = QU_UNKNOWN;
853 e->info->fcn->specialCode = SPC_NONE;
855 e->info->fcn->access = access;
856 e->info->fcn->globs = globs;
857 e->info->fcn->defparams = uentryList_undefined;
859 sRef_setDefined (e->sref, f);
860 e->whereDefined = fileloc_undefined;
862 e->info->fcn->mods = sRefSet_undefined;
863 e->info->fcn->specclauses = NULL;
864 checkGlobalsModifies (e, mods);
865 e->info->fcn->mods = mods;
870 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
873 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
874 typeId_invalid, globSet_undefined,
878 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
879 reflectImplicitFunctionQualifiers (ue, FALSE);
881 if (!uentry_isStatic (ue)
882 && cstring_equalLit (ue->uname, "main"))
884 ctype typ = ue->utype;
888 llassert (ctype_isFunction (typ));
890 retval = ctype_returnValue (typ);
892 if (!ctype_isInt (retval))
896 message ("Function main declared to return %s, should return int",
897 ctype_unparse (retval)),
898 uentry_whereDeclared (ue));
901 args = ctype_argsFunction (typ);
903 if (uentryList_isMissingParams (args)
904 || uentryList_size (args) == 0)
910 if (uentryList_size (args) != 2)
914 message ("Function main declared with %d arg%p, "
915 "should have 2 (int argc, char *argv[])",
916 uentryList_size (args)),
917 uentry_whereLast (ue));
921 uentry arg = uentryList_getN (args, 0);
922 ctype ct = uentry_getType (arg);
924 if (!ctype_isInt (ct))
928 message ("Parameter 1, %q, of function main declared "
929 "with type %t, should have type int",
930 uentry_getName (arg), ct),
931 uentry_whereDeclared (arg));
934 arg = uentryList_getN (args, 1);
935 ct = uentry_getType (arg);
937 if (ctype_isArrayPtr (ct)
938 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
939 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
947 message ("Parameter 2, %q, of function main declared "
948 "with type %t, should have type char **",
949 uentry_getName (arg), ct),
950 uentry_whereDeclared (arg));
959 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
961 alkind ak = sRef_getAliasKind (e->sref);
963 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
964 && context_getFlag (FLG_PARAMIMPTEMP))
966 exkind ek = sRef_getExKind (e->sref);
968 if (exkind_isKnown (ek))
970 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
971 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
975 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
976 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
981 static /*@only@*/ /*@notnull@*/ uentry
982 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
984 cstring pname = makeParam (n);
985 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
987 cstring_free (pname);
988 uentry_implicitParamAnnots (e);
990 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
992 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
993 e->info->var->defstate = defstate;
1001 uentry_setRefCounted (uentry e)
1003 if (uentry_isValid (e))
1005 uentry_setAliasKind (e, AK_REFCOUNTED);
1006 sRef_storeState (e->sref);
1012 uentry_setStatic (uentry c)
1014 if (uentry_isValid (c))
1016 alkind ak = sRef_getAliasKind (c->sref);
1017 c->storageclass = SCSTATIC;
1019 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1021 if (!alkind_isUnknown (ak)
1022 && !alkind_isStatic (ak))
1024 if (!(ctype_isRealPointer (uentry_getType (c)))
1025 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1026 && !alkind_isRefCounted (ak))
1028 if (alkind_isImplicit (ak)
1029 && alkind_isDependent (ak)
1030 && ctype_isArray (uentry_getType (c)))
1032 ; /* no error for observer arrays */
1038 message ("Static storage %q declared as %s",
1040 alkind_unparse (ak)),
1041 uentry_whereDeclared (c));
1047 if (alkind_isUnknown (ak)
1048 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1049 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1051 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1052 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1060 uentry_setExtern (uentry c)
1062 if (uentry_isValid (c))
1063 c->storageclass = SCEXTERN;
1067 uentry_setParamNo (uentry ue, int pno)
1069 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1070 sRef_setParamNo (ue->sref, pno);
1074 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1076 sRefSet_allElements (sr, el)
1078 sRef base = sRef_getRootBase (el);
1080 if (sRef_isGlobal (base) || sRef_isInternalState (base)
1081 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1083 if (!globSet_member (ue->info->fcn->globs, base))
1085 if (uentry_hasGlobs (ue)
1086 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1089 (FLG_WARNMISSINGGLOBALS,
1091 ("Modifies list for %q uses global %q, "
1092 "not included in globals list.",
1093 uentry_getName (ue),
1094 sRef_unparse (base)),
1095 uentry_whereLast (ue)))
1097 uentry_showWhereSpecified (ue);
1101 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1103 if (sRef_isFileStatic (base))
1105 context_recordFileGlobals (ue->info->fcn->globs);
1109 } end_sRefSet_allElements;
1113 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
1115 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1119 uentry_fixupSref (uentry ue)
1123 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1128 sr = uentry_getSref (ue);
1130 sRef_resetState (sr);
1131 sRef_clearDerived (sr);
1133 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1134 llassert (sRef_isValid (sr));
1136 if (uentry_isVariable (ue))
1138 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1139 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1143 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
1145 llassert (uentry_isFunction (ue));
1146 llassert (!specialClauses_isDefined (ue->info->fcn->specclauses));
1148 ue->info->fcn->specclauses = clauses;
1149 specialClauses_checkAll (ue);
1153 ** Used for @modifies@ @endmodifies@ syntax.
1155 ** If ue is specified, sr must contain *only*:
1157 ** o file static globals
1158 ** o sRef's derived from modifies spec (i.e., more specific than
1159 ** what was specified)
1161 ** Otherwise, if sr has modifies it must match sr.
1163 ** If it doesn't have modifies, set them to sr.
1167 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1169 if (sRef_modInFunction ())
1172 (message ("Modifies list not in function context. "
1173 "A modifies list can only appear following the parameter list "
1174 "in a function declaration or header."));
1176 /*@-mustfree@*/ return; /*@=mustfree@*/
1179 if (sRefSet_hasStatic (sr))
1181 context_recordFileModifies (sr);
1184 if (uentry_isValid (ue))
1186 if (uentry_isIter (ue))
1188 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1189 ue->info->iter->mods = sr;
1193 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1195 uentry_makeVarFunction (ue);
1198 llassertfatal (uentry_isFunction (ue));
1199 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1201 ue->info->fcn->mods = sr;
1202 ue->info->fcn->hasMods = TRUE;
1204 checkGlobalsModifies (ue, sr);
1207 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1209 ue->info->fcn->hasGlobs = TRUE;
1219 ** requires: new and old are functions
1223 checkGlobalsConformance (/*@notnull@*/ uentry old,
1224 /*@notnull@*/ uentry unew,
1225 bool mustConform, bool completeConform)
1227 bool hasInternalState = FALSE;
1229 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1231 if (globSet_isDefined (unew->info->fcn->globs))
1233 globSet_allElements (unew->info->fcn->globs, el)
1235 if (sRef_isFileStatic (el))
1237 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1239 if (sRef_isInvalid (sr))
1241 bool hasError = FALSE;
1243 if (!hasInternalState
1244 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1245 sRef_makeInternalState ()))
1246 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1247 sRef_makeSpecState ())))
1250 && !uentry_isStatic (old)
1253 message ("Globals list for %q includes internal state, %q, "
1254 "but %s without globals internalState.",
1255 uentry_getName (old),
1257 uentry_specOrDefName (old)),
1258 uentry_whereLast (unew)))
1260 uentry_showWhereSpecified (old);
1264 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1265 sRef_makeInternalState ());
1266 hasInternalState = TRUE;
1270 && fileloc_sameFile (uentry_whereDeclared (unew),
1271 uentry_whereDeclared (old)))
1276 message ("Function %q inconsistently %rdeclared (in "
1277 "same file) with file static global %q in "
1279 uentry_getName (unew),
1280 uentry_isDeclared (old),
1282 uentry_whereDeclared (unew)))
1284 uentry_showWhereSpecified (old);
1289 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1290 context_recordFileGlobals (old->info->fcn->globs);
1294 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1296 if (sRef_isInvalid (sr))
1301 message ("Function %q inconsistently %rdeclared with "
1302 "%q in globals list",
1303 uentry_getName (unew),
1304 uentry_isDeclared (old),
1306 uentry_whereDeclared (unew)))
1308 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1309 uentry_showWhereSpecified (old);
1314 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1320 ("Function %q global %q inconsistently "
1321 "%rdeclared as %qout global",
1322 uentry_getName (unew),
1324 uentry_isDeclared (old),
1325 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1326 uentry_whereDeclared (unew)))
1328 uentry_showWhereSpecified (old);
1333 } end_globSet_allElements ;
1335 if (completeConform)
1337 globSet_allElements (old->info->fcn->globs, el)
1339 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1341 if (sRef_isInvalid (sr))
1344 && uentry_isReallySpecified (old)
1347 message ("Function %q specified with %q in globals list, "
1348 "but declared without %q",
1349 uentry_getName (unew),
1352 uentry_whereDeclared (unew)))
1354 uentry_showWhereSpecified (old);
1357 } end_globSet_allElements;
1362 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1364 if (uentry_isReallySpecified (old)
1367 message ("%s %q specified with globals list, but "
1368 "declared with no globals",
1369 ekind_capName (unew->ukind),
1370 uentry_getName (unew)),
1371 uentry_whereDeclared (unew)))
1374 (message ("Specification globals: %q",
1375 globSet_unparse (old->info->fcn->globs)),
1376 uentry_whereSpecified (old));
1380 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
1381 old->info->fcn->globs);
1386 ** new modifies list must be included by old modifies list.
1388 ** file static state may be added to new, if old has internal.
1392 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1393 bool mustConform, bool completeConform)
1396 bool changedMods = FALSE;
1397 bool modInternal = FALSE;
1399 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1401 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1402 newMods = unew->info->fcn->mods;
1404 if (sRefSet_isEmpty (newMods))
1406 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1407 && uentry_isReallySpecified (old))
1411 message ("%s %q specified with modifies clause, "
1412 "but declared with no modifies clause",
1413 ekind_capName (unew->ukind),
1414 uentry_getName (unew)),
1415 uentry_whereDeclared (unew)))
1417 llgenindentmsg (message ("Specification has modifies %q",
1418 sRefSet_unparse (old->info->fcn->mods)),
1419 uentry_whereSpecified (old));
1426 sRefSet_allElements (newMods, current)
1428 if (sRef_isValid (current))
1430 sRef rb = sRef_getRootBase (current);
1432 if (sRef_isFileStatic (rb))
1436 if (!sRefSet_isSameMember (old->info->fcn->mods,
1437 sRef_makeInternalState ())
1438 && !sRefSet_isSameMember (old->info->fcn->mods,
1439 sRef_makeSpecState ()))
1442 && !uentry_isStatic (old)
1446 ("Modifies list for %q includes internal state, "
1447 "but %s without modifies internal.",
1448 uentry_getName (old),
1449 uentry_specOrDefName (old)),
1450 uentry_whereLast (unew)))
1452 uentry_showWhereSpecified (old);
1455 old->info->fcn->mods =
1456 sRefSet_insert (old->info->fcn->mods,
1457 sRef_makeInternalState ());
1462 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1468 if (sRef_canModifyVal (current, old->info->fcn->mods))
1470 int size = sRefSet_size (old->info->fcn->mods);
1472 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1475 if (sRefSet_size (old->info->fcn->mods) != size)
1486 ("Modifies list for %q contains %q, not modifiable "
1488 uentry_getName (old),
1489 sRef_unparse (current),
1490 uentry_specDeclName (old)),
1491 uentry_whereLast (unew)))
1493 uentry_showWhereSpecified (old);
1498 } end_sRefSet_allElements;
1500 if (completeConform && uentry_isReallySpecified (old))
1502 sRefSet_allElements (old->info->fcn->mods, el)
1504 if (sRef_canModify (el, newMods))
1513 ("Specification modifies clause for %q contains %q, "
1514 "not included in declaration modifies clause",
1515 uentry_getName (old),
1517 uentry_whereLast (unew)))
1519 uentry_showWhereSpecified (old);
1522 } end_sRefSet_allElements ;
1526 ** Make sure file static elements will be removed.
1531 context_recordFileModifies (old->info->fcn->mods);
1536 uentry_checkMutableType (uentry ue)
1538 ctype ct = uentry_getType (ue);
1540 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1542 voptgenerror (FLG_MUTREP,
1543 message ("Mutable abstract type %q declared without pointer "
1544 "indirection: %t (violates assignment semantics)",
1545 uentry_getName (ue), ct),
1546 uentry_whereDeclared (ue));
1551 uentry_setMutable (uentry e)
1553 llassert (uentry_isDatatype (e));
1554 e->info->datatype->mut = YES;
1558 uentry_checkIterArgs (uentry ue)
1560 bool hasYield = FALSE;
1563 llassert (uentry_isIter (ue));
1565 args = uentry_getParams (ue);
1567 uentryList_elements (args, el)
1569 sstate ds = uentry_getDefState (el);
1571 if (uentry_isYield (el))
1576 if (sstate_isUnknown (ds))
1578 uentry_setDefState (el, SS_DEFINED);
1584 } end_uentryList_elements;
1588 voptgenerror (FLG_HASYIELD,
1589 message ("Iterator %q declared with no yield parameters",
1590 uentry_getName (ue)),
1591 uentry_whereDeclared (ue));
1596 chkind_fromQual (qual qel)
1598 if (qual_isChecked (qel))
1602 else if (qual_isCheckMod (qel))
1606 else if (qual_isCheckedStrict (qel))
1608 return CH_CHECKEDSTRICT;
1610 else if (qual_isUnchecked (qel))
1612 return CH_UNCHECKED;
1617 /*@notreached@*/ return CH_UNKNOWN;
1622 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
1624 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
1626 if (!uentry_isRefCounted (ue))
1630 message ("Reference counting qualifier %s used on non-reference "
1631 "counted storage: %q",
1633 uentry_unparse (ue)));
1637 alkind ak = alkind_fromQual (qel);
1639 uentry_setAliasKind (ue, ak);
1642 else if (qual_isRefCounted (qel))
1644 ctype ct = ctype_realType (uentry_getType (ue));
1647 if (ctype_isPointer (ct)
1648 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
1650 /* check there is a refs field */
1651 uentryList fields = ctype_getFields (rt);
1652 uentry refs = uentry_undefined;
1654 uentryList_elements (fields, field)
1656 if (uentry_isRefsField (field))
1658 if (uentry_isValid (refs))
1662 message ("Reference counted structure type %s has "
1663 "multiple refs fields: %q and %q",
1665 uentry_getName (refs),
1666 uentry_getName (field)));
1671 } end_uentryList_elements;
1673 if (uentry_isInvalid (refs))
1677 message ("Reference counted structure type %s has "
1679 ctype_unparse (ct)),
1681 ("To count reference, the structure must have a field named "
1682 "refs of type int."),
1685 else if (!ctype_isInt (uentry_getType (refs)))
1689 message ("Reference counted structure type %s refs field has "
1690 "type %s (should be int)", ctype_unparse (ct),
1691 ctype_unparse (uentry_getType (refs))));
1695 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1696 uentry_whereDeclared (ue));
1701 if ((ctype_isPointer (ct)
1702 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
1703 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
1705 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1706 uentry_whereDeclared (ue));
1712 message ("Non-pointer to structure type %s declared with "
1713 "refcounted qualifier",
1714 ctype_unparse (ct)));
1718 else if (qual_isRefs (qel))
1720 if (uentry_isVariable (ue) && !uentry_isParam (ue))
1722 uentry_setAliasKind (ue, AK_REFS);
1728 message ("Refs qualifier used on non-structure field: %q",
1729 uentry_unparse (ue)));
1732 else if (qual_isAliasQual (qel))
1734 alkind ak = alkind_fromQual (qel);
1736 alkind oldak = uentry_getAliasKind (ue);
1737 ctype ut = uentry_getType (ue);
1739 if (alkind_isImplicit (ak)
1740 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
1742 /* ignore the implied qualifier */
1746 if (uentry_isEitherConstant (ue))
1750 message ("Alias qualifier %s used on constant: %q",
1751 alkind_unparse (ak), uentry_unparse (ue)));
1755 if (ctype_isFunction (ut))
1757 ut = ctype_returnValue (ut);
1760 if (!(ctype_isVisiblySharable (ut)
1761 || ctype_isRealArray (ut)
1762 || ctype_isRealSU (ut)))
1764 if (!qual_isImplied (qel))
1768 message ("Alias qualifier %s used on unsharable storage type %t: %q",
1769 alkind_unparse (ak), ut, uentry_getName (ue)));
1776 if (uentry_isRefCounted (ue))
1778 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
1779 || qual_isExposed (qel)
1780 || qual_isObserver (qel)))
1782 if (!qual_isImplied (qel))
1787 ("Alias qualifier %s used on reference counted storage: %q",
1788 alkind_unparse (ak),
1789 uentry_unparse (ue)));
1797 if (qual_isRefQual (qel))
1801 message ("Qualifier %s used on non-reference counted storage: %q",
1802 alkind_unparse (ak), uentry_unparse (ue)));
1811 uentry_setAliasKind (ue, ak);
1814 else if (qual_isNull (qel))
1816 if (uentry_isConstant (ue))
1820 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
1821 uentry_whereDeclared (ue));
1825 uentry_setNullState (ue, NS_POSNULL);
1828 else if (qual_isRelNull (qel))
1830 uentry_setNullState (ue, NS_RELNULL);
1832 else if (qual_isNotNull (qel))
1834 uentry_setNullState (ue, NS_MNOTNULL);
1836 else if (qual_isAbstract (qel)
1837 || qual_isConcrete (qel))
1839 if (!uentry_isDatatype (ue))
1843 message ("Qualifier %s used with non-datatype",
1844 qual_unparse (qel)));
1848 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
1851 else if (qual_isMutable (qel))
1853 if (!uentry_isDatatype (ue))
1855 llerror (FLG_SYNTAX,
1856 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
1860 if (!ynm_isOn (ue->info->datatype->mut))
1862 uentry_checkMutableType (ue);
1865 ue->info->datatype->mut = YES;
1868 else if (qual_isImmutable (qel))
1870 if (!uentry_isDatatype (ue))
1872 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
1873 qual_unparse (qel)));
1877 ue->info->datatype->mut = NO;
1880 else if (qual_isNullPred (qel))
1882 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1884 uentry_makeVarFunction (ue);
1887 if (uentry_isFunction (ue))
1889 ctype typ = uentry_getType (ue);
1890 ctype rtype = ctype_returnValue (uentry_getType (ue));
1892 if (ctype_isRealBool (rtype))
1894 uentryList pl = ctype_argsFunction (typ);
1896 if (uentryList_size (pl) == 1)
1898 ue->info->fcn->nullPred = qel;
1902 llerror (FLG_SYNTAX,
1903 message ("Qualifier %s used with function having %d "
1904 "arguments (should have 1)",
1906 uentryList_size (pl)));
1911 llerror (FLG_SYNTAX,
1912 message ("Qualifier %s used with function returning %s "
1913 "(should return bool)",
1915 ctype_unparse (rtype)));
1920 llerror (FLG_SYNTAX,
1921 message ("Qualifier %s used with non-function",
1922 qual_unparse (qel)));
1925 else if (qual_isExitQual (qel))
1927 exitkind exk = exitkind_fromQual (qel);
1929 if (uentry_isFunction (ue))
1931 if (exitkind_isKnown (ue->info->fcn->exitCode))
1933 llerror (FLG_SYNTAX,
1934 message ("Multiple exit qualifiers used on function %q: %s, %s",
1935 uentry_getName (ue),
1936 exitkind_unparse (ue->info->fcn->exitCode),
1937 exitkind_unparse (exk)));
1940 ue->info->fcn->exitCode = exk;
1944 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1946 uentry_makeVarFunction (ue);
1947 ue->info->fcn->exitCode = exk;
1951 llerror (FLG_SYNTAX,
1952 message ("Exit qualifier %s used with non-function (type %s)",
1954 ctype_unparse (uentry_getType (ue))));
1960 if (qual_isCQual (qel))
1966 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
1972 uentry_reflectQualifiers (uentry ue, qualList q)
1974 llassert (uentry_isValid (ue));
1976 qualList_elements (q, qel)
1978 if (qual_isStatic (qel))
1980 uentry_setStatic (ue);
1982 else if (qual_isUnused (qel))
1984 uentry_setUsed (ue, fileloc_undefined);
1986 else if (qual_isExternal (qel))
1988 fileloc_free (ue->whereDefined);
1989 ue->whereDefined = fileloc_createExternal ();
1991 else if (qual_isSef (qel))
1993 if (uentry_isVariable (ue))
1995 vkind vk = ue->info->var->kind;
1997 llassert (vk != VKREFPARAM);
1999 if (vk == VKYIELDPARAM)
2003 message ("Qualifier sef cannot be used with %s: %q",
2004 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2005 uentry_unparse (ue)));
2007 else if (vk == VKRETPARAM)
2009 ue->info->var->kind = VKSEFRETPARAM;
2013 ue->info->var->kind = VKSEFPARAM;
2020 message ("Qualifier sef is meaningful only on parameters: %q",
2021 uentry_unparse (ue)));
2024 else if (qual_isExtern (qel))
2026 ue->storageclass = SCEXTERN;
2028 else if (qual_isGlobalQual (qel)) /* undef, killed */
2030 if (uentry_isVariable (ue))
2032 sstate oldstate = ue->info->var->defstate;
2033 sstate defstate = sstate_fromQual (qel);
2036 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2037 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2039 defstate = SS_UNDEFKILLED;
2046 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2047 ue->info->var->defstate = defstate;
2053 message ("Qualifier %s used on non-variable: %q",
2054 qual_unparse (qel), uentry_unparse (ue)));
2057 /* start modifications */
2059 else if( qual_isBufQualifier(qel) ) {
2060 ctype ct = ctype_realType(uentry_getType(ue));
2062 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2064 if( uentry_hasBufStateInfo(ue) ) {
2066 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2068 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2069 /* If formal func param */
2070 uentry_setNullTerminatedState(ue);
2071 uentry_setLen (ue, 1);
2072 uentry_setSize (ue, 1);
2074 sRef_setNullTerminatedState(uentry_getSref(ue));
2075 sRef_setLen (uentry_getSref(ue), 1);
2076 sRef_setSize (uentry_getSref(ue), 1);
2078 uentry_setPossiblyNullTerminatedState(ue);
2080 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2084 /* put other BufState Qualifiers here */
2086 cstring s = uentry_getName(ue);
2087 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2088 struct for identifier %s\n", s) );
2090 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2092 sRef retSref = uentry_getSref (ue);
2093 ctype retType = sRef_getType (retSref);
2095 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2096 sRef_setNullTerminatedState (retSref);
2102 message ("Qualifier %s used on non-pointer on \
2103 function return: %q", qual_unparse (qel),
2104 uentry_unparse (ue)));
2111 message ("Qualifier %s used on non-pointer: %q",
2112 qual_unparse (qel), uentry_unparse (ue)));
2115 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2117 ctype realType = ctype_realType (ue->utype);
2118 sstate defstate = sstate_fromQual (qel);
2120 if (ctype_isFunction (realType))
2122 realType = ctype_realType (ctype_returnValue (realType));
2125 if (qual_isRelDef (qel))
2127 ; /* okay anywhere */
2131 if (!ctype_isAP (realType)
2132 && !ctype_isSU (realType)
2133 && !ctype_isUnknown (realType)
2134 && !ctype_isAbstract (ue->utype))
2138 message ("Qualifier %s used on non-pointer or struct: %q",
2139 qual_unparse (qel), uentry_unparse (ue)));
2143 uentry_setDefState (ue, defstate);
2145 if (sRef_isStateSpecial (ue->sref)
2146 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2148 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2151 else if (qual_isYield (qel))
2153 if (uentry_isVariable (ue))
2155 ue->info->var->kind = VKYIELDPARAM;
2161 message ("Qualifier %s used on non-iterator parameter: %q",
2162 qual_unparse (qel), uentry_unparse (ue)));
2165 else if (qual_isExQual (qel))
2167 exkind ek = exkind_fromQual (qel);
2168 ctype ut = uentry_getType (ue);
2170 if (ctype_isFunction (ut))
2172 ut = ctype_returnValue (ut);
2175 if (!(ctype_isVisiblySharable (ut))
2176 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2177 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2179 if (!qual_isImplied (qel))
2183 message ("Qualifier %s used on unsharable storage type %t: %q",
2184 exkind_unparse (ek), ut, uentry_getName (ue)));
2189 alkind ak = sRef_getAliasKind (ue->sref);
2191 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2193 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2195 if (!alkind_isTemp (ak))
2197 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2200 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2201 || alkind_isOwned (ak))
2209 message ("Exposure qualifier %s used on %s storage (should "
2210 "be dependent): %q",
2212 alkind_unparse (ak),
2213 uentry_unparse (ue)));
2217 else if (qual_isGlobCheck (qel))
2219 if (uentry_isVariable (ue))
2221 chkind ch = chkind_fromQual (qel);
2223 if (ue->info->var->checked != CH_UNKNOWN)
2225 if (ch == ue->info->var->checked)
2227 llerror (FLG_SYNTAX,
2228 message ("Redundant %s qualifier on %q",
2230 uentry_getName (ue)));
2234 llerror (FLG_SYNTAX,
2236 ("Contradictory %s and %s qualifiers on %q",
2238 checkedName (ue->info->var->checked),
2239 uentry_getName (ue)));
2243 ue->info->var->checked = ch;
2249 message ("Qualifier %s used with non-variable",
2250 qual_unparse (qel)));
2253 else if (qual_isReturned (qel))
2255 if (uentry_isVariable (ue))
2257 ue->info->var->kind = VKRETPARAM;
2261 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2262 qual_unparse (qel)));
2267 uentry_reflectOtherQualifier (ue, qel);
2270 sRef_storeState (ue->sref);
2271 } end_qualList_elements;
2277 uentry_isOnly (uentry ue)
2279 return (!uentry_isUndefined (ue)
2280 && uentry_isVariable (ue)
2281 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2285 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2287 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2288 sRef_setOrigAliasKind (ue->sref, ak);
2292 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2294 if (uentry_isVariable (ue))
2296 ue->info->var->nullstate = ns;
2299 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2303 uentry_isUnique (uentry ue)
2305 return (!uentry_isUndefined (ue)
2306 && uentry_isVariable (ue)
2307 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2311 uentry_isFileStatic (uentry ue)
2313 return (uentry_isStatic (ue)
2314 && (!uentry_isVariable (ue)
2315 || sRef_isFileStatic (uentry_getSref (ue))));
2319 uentry_isExported (uentry ue)
2321 if (uentry_isValid (ue))
2323 if (uentry_isVariable (ue))
2325 return (sRef_isRealGlobal (uentry_getSref (ue)));
2329 return !uentry_isStatic (ue);
2337 uentry_isNonLocal (uentry ue)
2339 return (uentry_isValid (ue) && uentry_isVariable (ue)
2340 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
2344 uentry_isGlobal (uentry ue)
2346 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
2347 sRef_isGlobal (ue->sref));
2351 uentry_isPrintfLike (uentry ue)
2353 return (uentry_isFunction (ue)
2354 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2358 uentry_isScanfLike (uentry ue)
2360 return (uentry_isFunction (ue)
2361 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2365 uentry_isMessageLike (uentry ue)
2367 return (uentry_isFunction (ue)
2368 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2371 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2373 uentryList args = uentry_getParams (ue);
2375 if (!uentryList_isMissingParams (args))
2377 uentry last = uentry_undefined;
2379 uentryList_elements (args, current)
2381 if (uentry_isElipsisMarker (current))
2383 if (uentry_isUndefined (last))
2387 message ("Function %q is marked %s, but has no format "
2388 "string argument before elipsis",
2389 uentry_getName (ue),
2390 specCode_unparse (ue->info->fcn->specialCode)),
2391 uentry_whereLast (ue));
2392 ue->info->fcn->specialCode = SPC_NONE;
2396 ctype rt = ctype_realType (uentry_getType (last));
2398 if (!ctype_match (rt, ctype_string))
2402 /* wchar_t * is okay too */
2403 if (ctype_isAP (rt))
2405 ctype base = ctype_baseArrayPtr (rt);
2407 if (ctype_isArbitraryIntegral (base))
2417 message ("Function %q is marked %s, but the argument "
2418 "before the elipsis has type %s (should be char *)",
2419 uentry_getName (ue),
2420 specCode_unparse (ue->info->fcn->specialCode),
2421 ctype_unparse (uentry_getType (last))),
2422 uentry_whereLast (ue));
2424 ue->info->fcn->specialCode = SPC_NONE;
2431 } end_uentryList_elements ;
2435 message ("Function %q is marked %s, but has no elipsis parameter",
2436 uentry_getName (ue),
2437 specCode_unparse (ue->info->fcn->specialCode)),
2438 uentry_whereLast (ue));
2440 ue->info->fcn->specialCode = SPC_NONE;
2445 uentry_setPrintfLike (uentry ue)
2447 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2449 uentry_makeVarFunction (ue);
2452 llassertfatal (uentry_isFunction (ue));
2453 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2454 checkSpecialFunction (ue);
2458 uentry_setScanfLike (uentry ue)
2460 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2462 uentry_makeVarFunction (ue);
2465 llassertfatal (uentry_isFunction (ue));
2466 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2467 checkSpecialFunction (ue);
2471 uentry_setMessageLike (uentry ue)
2473 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2475 uentry_makeVarFunction (ue);
2478 llassertfatal (uentry_isFunction (ue));
2479 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
2480 checkSpecialFunction (ue);
2484 uentry_isSpecialFunction (uentry ue)
2486 return (uentry_isFunction (ue)
2487 && (ue->info->fcn->specialCode != SPC_NONE));
2490 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
2492 ctype ct = idDecl_getCtype (t);
2494 sRef pref = sRef_makeParam (i, ct);
2495 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
2497 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2498 uentry_implicitParamAnnots (ue);
2500 /* Parameter type [][] or [x][] is invalid */
2502 while (ctype_isFixedArray (base)) {
2503 base = ctype_baseArrayPtr (base);
2506 if (ctype_isIncompleteArray (base)) {
2507 base = ctype_baseArrayPtr (base);
2509 if (ctype_isArray (base)) {
2510 if (!uentry_hasName (ue)) {
2511 (void) optgenerror (FLG_INCOMPLETETYPE,
2512 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
2514 ctype_unparse (ct)),
2515 uentry_whereLast (ue));
2517 (void) optgenerror (FLG_INCOMPLETETYPE,
2518 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
2519 uentry_getName (ue),
2520 ctype_unparse (ct)),
2521 uentry_whereLast (ue));
2529 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
2531 ctype ct = idDecl_getCtype (t);
2533 if (ctype_isFunction (ct))
2535 return (uentry_makeIdFunction (t));
2539 fileloc loc = setLocation ();
2540 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
2542 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2544 if (!uentry_isExtern (ue))
2546 uentry_setDefined (ue, loc);
2554 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
2556 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
2564 /*@only@*/ /*@notnull@*/
2565 uentry uentry_makeConstantAux (cstring n, ctype t,
2566 /*@keep@*/ fileloc f, bool priv,
2567 /*@only@*/ multiVal m)
2569 uentry e = uentry_alloc ();
2572 e->uname = cstring_copy (n);
2574 e->storageclass = SCNONE;
2576 e->sref = sRef_makeConst (t);
2581 e->uses = filelocList_new ();
2582 e->isPrivate = priv;
2583 e->hasNameError = FALSE;
2585 e->info = (uinfo) dmalloc (sizeof (*e->info));
2586 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
2587 e->info->uconst->val = m;
2588 e->info->uconst->access = typeIdSet_undefined;
2590 uentry_setSpecDef (e, f);
2592 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
2594 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
2600 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
2602 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
2605 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
2607 uentry ue = uentry_makeConstant (idDecl_observeId (t),
2608 idDecl_getCtype (t),
2611 llassert (fileloc_isUndefined (ue->whereDeclared));
2612 ue->whereDeclared = setLocation ();
2614 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2623 void uentry_setDefState (uentry ue, sstate defstate)
2625 if (uentry_isValid (ue))
2627 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2629 if (uentry_isVariable (ue))
2631 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
2636 bool uentry_isCheckedUnknown (uentry ue)
2638 return (uentry_isVar (ue)
2639 && (ue->info->var->checked == CH_UNKNOWN));
2642 bool uentry_isCheckMod (uentry ue)
2644 return (uentry_isVar (ue)
2645 && (ue->info->var->checked == CH_CHECKMOD));
2648 bool uentry_isUnchecked (uentry ue)
2650 return (uentry_isVar (ue)
2651 && (ue->info->var->checked == CH_UNCHECKED));
2654 bool uentry_isChecked (uentry ue)
2656 return (uentry_isVar (ue)
2657 && (ue->info->var->checked == CH_CHECKED));
2660 bool uentry_isCheckedModify (uentry ue)
2662 return (uentry_isVar (ue)
2663 && (ue->info->var->checked == CH_CHECKED
2664 || ue->info->var->checked == CH_CHECKMOD
2665 || ue->info->var->checked == CH_CHECKEDSTRICT));
2668 bool uentry_isCheckedStrict (uentry ue)
2670 return (uentry_isVar (ue)
2671 && (ue->info->var->checked == CH_CHECKEDSTRICT));
2674 void uentry_setUnchecked (uentry ue)
2676 llassert (uentry_isVar (ue));
2678 ue->info->var->checked = CH_UNCHECKED;
2681 void uentry_setChecked (uentry ue)
2683 llassert (uentry_isVar (ue));
2685 ue->info->var->checked = CH_CHECKED;
2688 void uentry_setCheckMod (uentry ue)
2690 llassert (uentry_isVar (ue));
2692 ue->info->var->checked = CH_CHECKMOD;
2695 void uentry_setCheckedStrict (uentry ue)
2697 llassert (uentry_isVar (ue));
2699 ue->info->var->checked = CH_CHECKEDSTRICT;
2702 static /*@only@*/ /*@notnull@*/
2703 uentry uentry_makeVariableAux (cstring n, ctype t,
2705 /*@exposed@*/ sRef s,
2706 bool priv, vkind kind)
2708 uentry e = uentry_alloc ();
2711 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
2714 e->uname = cstring_copy (n);
2717 e->storageclass = SCNONE;
2724 e->uses = filelocList_new ();
2725 e->isPrivate = priv;
2726 e->hasNameError = FALSE;
2728 e->info = (uinfo) dmalloc (sizeof (*e->info));
2729 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
2730 e->info->var->kind = kind;
2732 e->info->var->checked = CH_UNKNOWN;
2734 uentry_setSpecDef (e, f);
2736 if (ctype_isFunction (rt))
2738 rt = ctype_returnValue (rt);
2741 if (ctype_isUA (rt))
2743 sRef_setStateFromType (e->sref, rt);
2746 e->info->var->defstate = sRef_getDefState (e->sref);
2747 e->info->var->nullstate = sRef_getNullState (e->sref);
2749 /* start modifications */
2750 /* This function sets the uentry for a pointer or array variable declaration,
2751 it allocates memory and sets the fields. We check if the type of the variable
2752 is a pointer or array and allocate a `bbufinfo' struct accordingly */
2754 if( ctype_isArray (t) || ctype_isPointer(t)) {
2755 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
2756 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
2757 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
2759 e->info->var->bufinfo = NULL;
2761 /* end modification */
2767 uentry_isYield (uentry ue)
2769 return (uentry_isVariable (ue)
2770 && (ue->info->var->kind == VKYIELDPARAM
2771 || ue->info->var->kind == VKREFYIELDPARAM));
2775 uentry_isRefsField (uentry ue)
2777 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
2780 /*@only@*/ /*@notnull@*/
2781 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
2783 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
2784 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
2791 void uentry_makeVarFunction (uentry ue)
2798 llassert (uentry_isValid (ue));
2799 llassert (!sRef_modInFunction ());
2801 ak = sRef_getOrigAliasKind (ue->sref);
2802 ek = sRef_getOrigExKind (ue->sref);
2804 oldInfo = ue->info->var;
2806 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
2809 ** expanded macro is marked used (until I write a pre-processor)
2812 ue->used |= (oldInfo->kind == VKEXPMACRO);
2815 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
2816 ue->info->fcn->exitCode = XK_UNKNOWN;
2817 ue->info->fcn->nullPred = QU_UNKNOWN;
2818 ue->info->fcn->specialCode = SPC_NONE;
2819 ue->info->fcn->access = typeIdSet_undefined;
2820 ue->info->fcn->hasGlobs = FALSE;
2821 ue->info->fcn->globs = globSet_undefined;
2822 ue->info->fcn->hasMods = FALSE;
2823 ue->info->fcn->mods = sRefSet_undefined;
2824 ue->info->fcn->specclauses = NULL;
2825 ue->info->fcn->defparams = uentryList_undefined;
2827 if (ctype_isFunction (ue->utype))
2829 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
2833 ue->sref = sRef_makeType (ctype_unknown);
2836 if (sRef_isRefCounted (ue->sref))
2842 if (alkind_isUnknown (ak))
2844 if (exkind_isKnown (ek))
2846 ak = AK_IMPDEPENDENT;
2850 if (context_getFlag (FLG_RETIMPONLY))
2852 if (ctype_isFunction (ue->utype)
2853 && ctype_isVisiblySharable
2854 (ctype_realType (ctype_returnValue (ue->utype))))
2856 if (uentryList_hasReturned (uentry_getParams (ue)))
2870 loc = ue->whereDeclared;
2872 sRef_setAliasKind (ue->sref, ak, loc);
2873 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
2874 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
2875 sRef_setExKind (ue->sref, ek, loc);
2877 if (oldInfo->kind == VKEXPMACRO)
2880 ue->whereDeclared = fileloc_undefined;
2884 fileloc_free (ue->whereDefined);
2885 ue->whereDefined = fileloc_undefined;
2888 uvinfo_free (oldInfo);
2892 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
2894 llassert (uentry_isValid (ue));
2896 if (uentry_isIter (ue))
2898 llassert (globSet_isUndefined (ue->info->iter->globs));
2899 ue->info->iter->globs = globs;
2903 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2905 uentry_makeVarFunction (ue);
2908 llassert (uentry_isFunction (ue));
2909 llassert (!ue->info->fcn->hasGlobs
2910 && globSet_isUndefined (ue->info->fcn->globs));
2912 ue->info->fcn->hasGlobs = TRUE;
2913 /*@-mustfree@*/ ue->info->fcn->globs = globs;
2917 if (globSet_hasStatic (globs))
2919 context_recordFileGlobals (globs);
2922 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
2924 ue->info->fcn->hasMods = TRUE;
2928 void uentry_addAccessType (uentry ue, typeId tid)
2930 if (uentry_isFunction (ue))
2932 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
2934 else if (uentry_isEitherConstant (ue))
2936 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
2938 else if (uentry_isIter (ue))
2940 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
2942 else if (uentry_isEndIter (ue))
2944 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
2948 llbug (message ("no access for: %q", uentry_unparse (ue)));
2952 /*@only@*/ /*@notnull@*/ uentry
2953 uentry_makeFunction (cstring n, ctype t,
2955 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
2958 return (uentry_makeFunctionAux (n, t,
2959 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
2960 : typeIdSet_single (access)),
2966 /*@notnull@*/ uentry
2967 uentry_makePrivFunction2 (cstring n, ctype t,
2969 globSet globs, sRefSet mods,
2972 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
2976 /*@notnull@*/ uentry
2977 uentry_makeSpecFunction (cstring n, ctype t,
2979 /*@only@*/ globSet globs,
2980 /*@only@*/ sRefSet mods,
2983 uentry ue = uentry_makeFunctionAux (n, t, access,
2987 uentry_setHasGlobs (ue);
2988 uentry_setHasMods (ue);
2990 reflectImplicitFunctionQualifiers (ue, TRUE);
2995 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
2997 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
2998 sRef_undefined, FALSE, VKEXPMACRO);
3000 uentry_setDefined (ue, f);
3004 /*@notnull@*/ /*@notnull@*/ uentry
3005 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3007 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3008 typeIdSet_singleOpt (access),
3009 globSet_undefined, sRefSet_undefined,
3013 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3017 bool uentry_isForward (uentry e)
3019 if (uentry_isValid (e))
3021 ctype ct = uentry_getType (e);
3023 return (ctype_isUnknown (ct)
3024 || (ctype_isFunction (ct)
3025 && ctype_isUnknown (ctype_returnValue (ct))));
3032 /*@notnull@*/ uentry
3033 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3035 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3041 /*@notnull@*/ uentry
3042 uentry_makeUnspecFunction (cstring n, ctype t,
3046 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
3047 sRefSet_new (), f, FALSE, TRUE);
3049 reflectImplicitFunctionQualifiers (ue, TRUE);
3058 /* is exported for use by usymtab_interface */
3060 /*@notnull@*/ uentry
3061 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
3062 fileloc f, bool priv)
3064 uentry e = uentry_alloc ();
3066 DPRINTF (("Make datatype: %s / %s",
3067 n, ctype_unparse (t)));
3069 /* e->shallowCopy = FALSE; */
3070 e->ukind = KDATATYPE;
3071 e->uname = cstring_copy (n);
3073 e->storageclass = SCNONE;
3074 e->sref = sRef_makeUnknown ();
3078 sRef_setStateFromType (e->sref, t);
3081 uentry_setSpecDef (e, f);
3083 e->uses = filelocList_new ();
3084 e->isPrivate = priv;
3085 e->hasNameError = FALSE;
3090 e->info = (uinfo) dmalloc (sizeof (*e->info));
3091 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3092 e->info->datatype->abs = abs;
3093 e->info->datatype->mut = mut;
3094 e->info->datatype->type = ctype_undefined;
3096 if (uentry_isDeclared (e))
3098 uentry_setDefined (e, f);
3101 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
3103 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3109 /*@notnull@*/ uentry
3110 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
3113 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
3116 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abs)
3118 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3119 ctype_bool, NO, abs,
3120 fileloc_getBuiltin (),
3123 ret->info->datatype->type = ctype_bool;
3131 static /*@only@*/ /*@notnull@*/ uentry
3132 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3133 /*@only@*/ fileloc f)
3135 uentry e = uentry_alloc ();
3138 e->uname = cstring_copy (n);
3140 e->sref = sRef_makeUnknown ();
3141 e->storageclass = SCNONE;
3145 uentry_setSpecDef (e, f);
3147 e->uses = filelocList_new ();
3148 e->isPrivate = FALSE;
3149 e->hasNameError = FALSE;
3151 e->info = (uinfo) dmalloc (sizeof (*e->info));
3152 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3153 e->info->iter->access = access;
3154 e->info->iter->mods = sRefSet_undefined;
3155 e->info->iter->globs = globSet_undefined;
3157 uentry_checkIterArgs (e);
3161 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3163 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3166 static /*@notnull@*/ uentry
3167 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3169 uentry e = uentry_alloc ();
3171 /* e->shallowCopy = FALSE; */
3172 e->ukind = KENDITER;
3173 e->storageclass = SCNONE;
3174 e->uname = message ("end_%s", n);
3175 e->utype = ctype_unknown;
3176 e->sref = sRef_makeUnknown ();
3178 uentry_setSpecDef (e, f);
3183 e->uses = filelocList_new ();
3184 e->isPrivate = FALSE;
3185 e->hasNameError = FALSE;
3187 e->info = (uinfo) dmalloc (sizeof (*e->info));
3188 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3190 e->info->enditer->access = access;
3195 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3197 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3204 static /*@only@*/ /*@notnull@*/ uentry
3205 uentry_makeTagAux (cstring n, ctype t,
3206 /*@only@*/ fileloc fl,
3207 bool priv, ekind kind)
3209 uentry e = uentry_alloc ();
3211 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3213 llbuglit ("uentry_makeTagAux: not a tag type");
3217 /* e->shallowCopy = FALSE; */
3218 e->uname = cstring_copy (n);
3221 e->sref = sRef_makeUnknown ();
3222 e->storageclass = SCNONE;
3224 uentry_setSpecDef (e, fl);
3229 e->uses = filelocList_new ();
3230 e->isPrivate = priv;
3231 e->hasNameError = FALSE;
3233 e->info = (uinfo) dmalloc (sizeof (*e->info));
3234 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3235 e->info->datatype->abs = NO;
3236 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3237 e->info->datatype->type = t;
3239 if (uentry_isDeclared (e))
3241 uentry_setDefined (e, fl);
3247 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3249 cstring sname = makeStruct (n);
3250 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3252 cstring_free (sname);
3257 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3259 cstring sname = makeStruct (n);
3260 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3262 cstring_free (sname);
3267 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3269 cstring uname = makeUnion (n);
3270 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3272 cstring_free (uname);
3278 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3280 cstring ename = makeEnum (n);
3281 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3283 cstring_free (ename);
3289 uentry_makeUnionTagLoc (cstring n, ctype t)
3291 cstring uname = makeUnion (n);
3292 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3294 cstring_free (uname);
3299 uentry_makeEnumTagLoc (cstring n, ctype t)
3301 cstring ename = makeEnum (n);
3302 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3304 cstring_free (ename);
3309 uentry_isStructTag (uentry ue)
3311 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3315 uentry_isUnionTag (uentry ue)
3317 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3321 uentry_isEnumTag (uentry ue)
3323 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3327 uentry_isAnyTag (uentry ue)
3329 return (uentry_isStructTag (ue)
3330 || uentry_isUnionTag (ue)
3331 || uentry_isEnumTag (ue));
3334 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3336 extern void uentry_destroyMod (void)
3337 /*@globals killed emarker@*/ /*@modifies emarker@*/
3339 static bool wasDestroyed = FALSE;
3341 llassert (!wasDestroyed);
3343 if (emarker != NULL)
3345 uentry_reallyFree (emarker);
3348 wasDestroyed = TRUE;
3352 uentry_makeElipsisMarker (void)
3354 if (emarker == NULL)
3356 emarker = uentry_alloc ();
3358 emarker->ukind = KELIPSMARKER;
3359 emarker->uname = cstring_makeLiteral ("...");
3360 emarker->utype = ctype_elipsMarker;
3361 emarker->sref = sRef_undefined;
3362 emarker->storageclass = SCNONE;
3363 emarker->used = FALSE;
3364 emarker->lset = FALSE;
3365 emarker->info = NULL;
3367 uentry_setSpecDef (emarker, fileloc_undefined);
3368 emarker->uses = filelocList_new ();
3369 emarker->isPrivate = FALSE;
3370 emarker->hasNameError = FALSE;
3373 /*@ignore@*/ return (emarker); /*@end@*/
3381 uentry_equiv (uentry p1, uentry p2)
3383 if (uentry_compare (p1, p2) != 0)
3394 uentry_xcomparealpha (uentry *p1, uentry *p2)
3398 if ((res = uentry_compare (*p1, *p2)) == 0) {
3399 if ((*p1 != NULL) && (*p2 != NULL)) {
3400 res = cstring_compare ((*p1)->uname,
3409 uentry_xcompareuses (uentry *p1, uentry *p2)
3414 if (uentry_isValid (u1))
3416 if (uentry_isValid (u2))
3418 return (-1 * int_compare (filelocList_size (u1->uses),
3419 filelocList_size (u2->uses)));
3428 if (uentry_isValid (u2))
3440 uentry_compareStrict (uentry v1, uentry v2)
3442 COMPARERETURN (uentry_compare (v1, v2));
3444 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
3446 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
3447 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
3448 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
3455 uentry_compare (uentry u1, uentry u2)
3457 if (u1 == u2) return 0;
3459 if (uentry_isInvalid (u1)) return -1;
3460 if (uentry_isInvalid (u2)) return 1;
3462 INTCOMPARERETURN (u1->ukind, u2->ukind);
3463 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
3464 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
3466 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
3472 /* bug detected by lclint:
3473 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
3478 return (multiVal_compare (u1->info->uconst->val,
3479 u2->info->uconst->val));
3483 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
3485 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3486 uentry_accessType (u2)));
3487 return (uentryList_compareParams (uentry_getParams (u1),
3488 uentry_getParams (u2)));
3490 return (typeIdSet_compare (uentry_accessType (u1),
3491 uentry_accessType (u2)));
3493 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3494 uentry_accessType (u2)));
3495 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
3496 uentry_getGlobs (u2)));
3497 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
3498 uentry_getParams (u2)));
3499 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
3500 u2->info->fcn->specialCode));
3501 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
3502 u2->info->fcn->nullPred));
3504 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
3506 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
3507 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
3508 sRef_getOrigAliasKind (u2->sref)));
3509 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
3510 sRef_getOrigExKind (u2->sref)));
3511 COMPARERETURN (generic_compare (u1->info->var->checked,
3512 u2->info->var->checked));
3513 COMPARERETURN (generic_compare (u1->info->var->defstate,
3514 u2->info->var->defstate));
3515 return (generic_compare (u1->info->var->nullstate,
3516 u2->info->var->nullstate));
3518 COMPARERETURN (ctype_compare (u1->info->datatype->type,
3519 u2->info->datatype->type));
3520 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
3521 u2->info->datatype->mut));
3522 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
3531 ** all entries are: <type>[@<info>]*#<name>
3533 ** info depends on kind:
3537 advanceField (char **s)
3543 advanceName (char **s)
3549 vkind_fromInt (int i)
3551 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
3553 llbuglit ("vkind_fromInt: out of range");
3560 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
3561 typeIdSet access, nstate nullstate,
3562 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
3564 uentry e = uentry_alloc ();
3569 e->sref = sRef_makeConst (ct);
3571 sRef_setNullState (e->sref, nullstate, loc);
3572 e->storageclass = SCNONE;
3574 if (fileloc_isSpec (loc))
3576 e->whereSpecified = loc;
3577 e->whereDeclared = fileloc_undefined;
3581 e->whereSpecified = fileloc_undefined;
3582 e->whereDeclared = loc;
3585 e->whereDefined = fileloc_undefined;
3586 e->uses = filelocList_new ();
3587 e->isPrivate = FALSE;
3588 e->hasNameError = FALSE;
3593 e->info = (uinfo) dmalloc (sizeof (*e->info));
3594 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3595 e->info->uconst->val = m;
3596 e->info->uconst->access = access;
3598 sRef_storeState (e->sref);
3603 static /*@only@*/ uentry
3604 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
3605 sstate defstate, nstate isnull, alkind aliased,
3606 exkind exp, chkind checked,
3607 /*@only@*/ fileloc loc)
3609 uentry e = uentry_alloc ();
3614 e->storageclass = SCNONE;
3616 e->sref = sRef_makeType (ct);
3617 sRef_setNullState (e->sref, isnull, loc);
3619 e->whereDefined = fileloc_undefined;
3621 if (fileloc_isSpec (loc))
3623 e->whereSpecified = loc;
3624 e->whereDeclared = fileloc_undefined;
3628 e->whereSpecified = fileloc_undefined;
3629 e->whereDeclared = loc;
3632 e->isPrivate = FALSE;
3633 e->hasNameError = FALSE;
3638 e->uses = filelocList_new ();
3640 e->info = (uinfo) dmalloc (sizeof (*e->info));
3641 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3642 e->info->var->kind = kind;
3643 e->info->var->checked = checked;
3644 e->info->var->defstate = defstate;
3646 sRef_setDefState (e->sref, defstate, loc);
3648 e->info->var->nullstate = sRef_getNullState (e->sref);
3650 sRef_setExKind (e->sref, exp, loc);
3651 sRef_setAliasKind (e->sref, aliased, loc);
3653 sRef_storeState (e->sref);
3655 /*DRL ADDED 9-1-2000 */
3656 e->info->var->bufinfo = NULL;
3661 static /*@only@*/ uentry
3662 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abs,
3663 ynm mut, ctype rtype, alkind ak, exkind exp,
3664 sstate defstate, nstate isnull,
3665 /*@only@*/ fileloc loc)
3667 uentry e = uentry_alloc ();
3669 e->ukind = KDATATYPE;
3670 /* e->shallowCopy = FALSE; */
3673 e->storageclass = SCNONE;
3674 e->sref = sRef_makeUnknown ();
3677 ** This is only setting null state. (I think?)
3680 if (ctype_isUA (ct))
3682 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
3684 if (uentry_isValid (te))
3686 sRef_setStateFromUentry (e->sref, te);
3690 /* problem for recursive type definitions */
3694 sRef_setAliasKind (e->sref, ak, loc);
3695 sRef_setExKind (e->sref, exp, loc);
3697 sRef_setDefState (e->sref, defstate, loc);
3699 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
3701 isnull = NS_ABSNULL;
3704 sRef_mergeNullState (e->sref, isnull);
3706 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
3708 if (fileloc_isSpec (loc))
3710 e->whereSpecified = loc;
3711 e->whereDeclared = fileloc_undefined;
3715 e->whereSpecified = fileloc_undefined;
3716 e->whereDeclared = loc;
3719 e->isPrivate = FALSE;
3720 e->hasNameError = FALSE;
3724 e->uses = filelocList_new ();
3726 e->info = (uinfo) dmalloc (sizeof (*e->info));
3727 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3728 e->info->datatype->abs = abs;
3729 e->info->datatype->mut = mut;
3730 e->info->datatype->type = rtype;
3732 sRef_storeState (e->sref);
3738 static void uentry_setHasGlobs (uentry ue)
3740 llassert (uentry_isFunction (ue));
3742 ue->info->fcn->hasGlobs = TRUE;
3745 static void uentry_setHasMods (uentry ue)
3747 llassert (uentry_isFunction (ue));
3749 ue->info->fcn->hasMods = TRUE;
3753 bool uentry_hasGlobs (uentry ue)
3755 if (uentry_isFunction (ue))
3757 return (ue->info->fcn->hasGlobs);
3763 bool uentry_hasSpecialClauses (uentry ue)
3765 return (uentry_isFunction (ue) && specialClauses_isDefined (ue->info->fcn->specclauses));
3768 specialClauses uentry_getSpecialClauses (uentry ue)
3770 llassert (uentry_isFunction (ue));
3771 return ue->info->fcn->specclauses;
3774 bool uentry_hasMods (uentry ue)
3776 if (uentry_isFunction (ue))
3778 return (ue->info->fcn->hasMods);
3785 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
3787 bool hasGlobs, /*@only@*/ globSet globs,
3788 bool hasMods, /*@only@*/ sRefSet mods,
3789 alkind ak, exkind exp,
3790 sstate defstate, nstate isnull,
3794 /*@only@*/ specialClauses specclauses,
3795 /*@only@*/ fileloc loc)
3797 uentry e = uentry_alloc ();
3800 /* e->shallowCopy = FALSE; */
3804 e->storageclass = SCNONE;
3806 if (ctype_isFunction (ct))
3808 ret = ctype_returnValue (ct);
3812 if (ctype_isKnown (ct))
3814 llbug (message ("not function: %s", ctype_unparse (ct)));
3817 ret = ctype_unknown;
3820 e->sref = sRef_makeType (ret);
3822 if (ctype_isUA (ret))
3824 sRef_setStateFromType (e->sref, ret);
3827 sRef_setDefined (e->sref, loc);
3828 sRef_setNullState (e->sref, isnull, loc);
3830 sRef_setAliasKind (e->sref, ak, loc);
3831 sRef_setExKind (e->sref, exp, loc);
3832 sRef_setDefState (e->sref, defstate, loc);
3834 e->whereSpecified = loc;
3835 e->whereDefined = fileloc_undefined;
3837 e->isPrivate = FALSE;
3838 e->hasNameError = FALSE;
3842 e->uses = filelocList_new ();
3844 e->info = (uinfo) dmalloc (sizeof (*e->info));
3845 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
3847 e->info->fcn->exitCode = exitCode;
3848 e->info->fcn->specialCode = sCode;
3849 e->info->fcn->nullPred = nullPred;
3850 e->info->fcn->access = access;
3852 e->info->fcn->specclauses = specclauses;
3853 e->info->fcn->hasGlobs = hasGlobs;
3854 e->info->fcn->globs = globs;
3856 e->info->fcn->hasMods = hasMods;
3857 e->info->fcn->mods = mods;
3859 e->info->fcn->defparams = uentryList_undefined;
3860 e->whereDeclared = fileloc_undefined;
3862 sRef_storeState (e->sref);
3867 static /*@only@*/ uentry
3868 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
3869 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
3871 uentry e = uentry_alloc ();
3873 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
3875 llbuglit ("uentry_makeTagBase: not a tag type");
3878 /* e->shallowCopy = FALSE; */
3882 e->sref = sRef_makeUnknown ();
3883 e->storageclass = SCNONE;
3885 if (fileloc_isSpec (loc))
3887 e->whereSpecified = loc;
3888 e->whereDeclared = fileloc_undefined;
3892 e->whereDeclared = loc;
3893 e->whereSpecified = fileloc_undefined;
3896 e->whereDefined = fileloc_undefined;
3898 e->isPrivate = FALSE;
3899 e->hasNameError = FALSE;
3903 e->uses = filelocList_new ();
3905 e->info = (uinfo) dmalloc (sizeof (*e->info));
3906 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3907 e->info->datatype->abs = NO;
3908 e->info->datatype->mut = MAYBE;
3909 e->info->datatype->type = rtype;
3911 sRef_storeState (e->sref);
3917 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
3918 ctype ct, /*@only@*/ fileloc loc)
3920 uentry e = uentry_alloc ();
3922 /* e->shallowCopy = FALSE; */
3926 e->sref = sRef_makeUnknown ();
3927 e->storageclass = SCNONE;
3929 if (fileloc_isSpec (loc))
3931 e->whereSpecified = loc;
3932 e->whereDeclared = fileloc_undefined;
3936 e->whereDeclared = loc;
3937 e->whereSpecified = fileloc_undefined;
3940 e->whereDefined = fileloc_undefined;
3942 e->isPrivate = FALSE;
3943 e->hasNameError = FALSE;
3947 e->uses = filelocList_new ();
3949 e->info = (uinfo) dmalloc (sizeof (*e->info));
3950 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3951 e->info->iter->access = access;
3952 e->info->iter->mods = sRefSet_undefined;
3953 e->info->iter->globs = globSet_undefined;
3955 sRef_storeState (e->sref);
3960 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
3961 /*@only@*/ fileloc loc)
3963 uentry e = uentry_alloc ();
3965 /* e->shallowCopy = FALSE; */
3966 e->ukind = KENDITER;
3967 e->storageclass = SCNONE;
3969 e->utype = ctype_unknown;
3970 e->sref = sRef_makeUnknown ();
3972 if (fileloc_isSpec (loc))
3974 e->whereSpecified = loc;
3975 e->whereDeclared = fileloc_undefined;
3979 e->whereDeclared = loc;
3980 e->whereSpecified = fileloc_undefined;
3983 e->whereDefined = fileloc_undefined;
3985 e->isPrivate = FALSE;
3986 e->hasNameError = FALSE;
3990 e->uses = filelocList_new ();
3992 e->info = (uinfo) dmalloc (sizeof (*e->info));
3993 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3994 e->info->enditer->access = access;
3995 sRef_storeState (e->sref);
4000 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4008 uentry_undump (ekind kind, fileloc loc, char **s)
4016 ue = uentry_makeElipsisMarker ();
4020 ctype ct = ctype_undump (s);
4036 if (optCheckChar (s, '@'))
4038 tkind = vkind_fromInt (getInt (s));
4046 if (optCheckChar (s, '$'))
4048 defstate = SS_UNKNOWN;
4049 isnull = NS_UNKNOWN;
4050 aliased = AK_IMPTEMP;
4052 checked = CH_UNKNOWN;
4054 else if (optCheckChar (s, '&'))
4056 defstate = SS_DEFINED;
4057 isnull = NS_UNKNOWN;
4058 aliased = AK_IMPTEMP;
4060 checked = CH_UNKNOWN;
4062 else if (optCheckChar (s, '^'))
4064 defstate = SS_UNKNOWN;
4065 isnull = NS_UNKNOWN;
4066 aliased = AK_IMPTEMP;
4068 checked = CH_UNKNOWN;
4072 defstate = sstate_fromInt (getInt (s));
4073 advanceField (s); isnull = nstate_fromInt (getInt (s));
4074 advanceField (s); aliased = alkind_fromInt (getInt (s));
4076 if (optCheckChar (s, '&'))
4079 checked = CH_UNKNOWN;
4083 advanceField (s); exp = exkind_fromInt (getInt (s));
4084 advanceField (s); checked = (chkind) (getInt (s));
4089 name = getStringWord (s);
4091 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4092 isnull, aliased, exp,
4093 checked, fileloc_copy (loc));
4106 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
4107 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
4108 advanceField (s); defstate = sstate_fromInt (getInt (s));
4109 advanceField (s); isnull = nstate_fromInt (getInt (s));
4110 advanceField (s); aliased = alkind_fromInt (getInt (s));
4111 advanceField (s); exp = exkind_fromInt (getInt (s));
4112 advanceField (s); rtype = ctype_undump (s);
4114 name = getStringWord (s);
4116 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
4117 aliased, exp, defstate, isnull,
4118 fileloc_copy (loc));
4135 specialClauses specclauses;
4137 if (optCheckChar (s, '$'))
4139 defstate = SS_DEFINED;
4140 isnull = NS_UNKNOWN;
4141 exitCode = XK_UNKNOWN;
4143 nullPred = QU_UNKNOWN;
4147 advanceField (s); defstate = sstate_fromInt (getInt (s));
4148 advanceField (s); isnull = nstate_fromInt (getInt (s));
4149 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
4150 advanceField (s); specc = specCode_fromInt (getInt (s));
4151 advanceField (s); nullPred = qual_fromInt (getInt (s));
4154 if (optCheckChar (s, '$'))
4157 globs = globSet_undefined;
4159 mods = sRefSet_undefined;
4161 else if (optCheckChar (s, '^'))
4164 globs = globSet_undefined;
4166 mods = sRefSet_undefined;
4170 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
4171 advanceField (s); globs = globSet_undump (s);
4172 advanceField (s); hasMods = bool_fromInt (getInt (s));
4173 advanceField (s); mods = sRefSet_undump (s);
4176 if (optCheckChar (s, '$'))
4183 advanceField (s); ak = alkind_fromInt (getInt (s));
4184 advanceField (s); exp = exkind_fromInt (getInt (s));
4187 advanceField (s); access = typeIdSet_undump (s);
4189 if (optCheckChar (s, '@'))
4191 specclauses = specialClauses_undump (s);
4195 specclauses = specialClauses_undefined;
4198 advanceName (s); name = getStringWord (s);
4200 ue = uentry_makeFunctionBase (name, ct, access,
4203 ak, exp, defstate, isnull,
4204 exitCode, specc, nullPred,
4206 fileloc_copy (loc));
4207 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4214 advanceField (s); access = typeIdSet_undump (s);
4215 advanceName (s); name = getStringWord (s);
4217 ue = uentry_makeIterBase (name, access, ct,
4218 fileloc_copy (loc));
4225 advanceField (s); access = typeIdSet_undump (s);
4226 advanceName (s); name = getStringWord (s);
4228 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4238 if (optCheckChar (s, '$'))
4240 val = multiVal_undefined;
4241 access = typeIdSet_undefined;
4242 nullstate = NS_UNKNOWN;
4246 advanceField (s); val = multiVal_undump (s);
4247 advanceField (s); access = typeIdSet_undump (s);
4248 advanceField (s); nullstate = nstate_fromInt (getInt (s));
4251 advanceName (s); name = getStringWord (s);
4253 ue = uentry_makeConstantBase (name, ct, access,
4254 nullstate, fileloc_copy (loc), val);
4263 advanceField (s); rtype = ctype_undump (s);
4264 advanceName (s); name = getStringWord (s);
4265 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4269 llcontbuglit ("uentry_undump: invalid");
4270 ue = uentry_undefined;
4273 llcontbuglit ("uentry_undump: elips marker");
4274 ue = uentry_undefined;
4283 uentry_dump (uentry v)
4285 return (uentry_dumpAux (v, FALSE));
4289 uentry_dumpParam (uentry v)
4291 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4292 ("dump: %s", uentry_unparseFull (v)));
4294 return (uentry_dumpAux (v, TRUE));
4298 uentry_dumpAux (uentry v, bool isParam)
4300 llassert (uentry_isValid (v));
4302 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
4307 llcontbuglit ("uentry_dump: invalid entry");
4308 return cstring_undefined;
4310 return (message ("!."));
4314 vkind vk = v->info->var->kind;
4315 sstate dss = sRef_getDefState (v->sref);
4316 nstate nst = sRef_getNullState (v->sref);
4317 alkind alk = sRef_getAliasKind (v->sref);
4318 exkind exk = sRef_getExKind (v->sref);
4319 chkind chk = v->info->var->checked;
4321 DPRINTF (("Dumping var"));
4323 if (dss == SS_UNKNOWN
4324 && nst == NS_UNKNOWN
4325 && alk == AK_IMPTEMP
4326 && exk == XO_UNKNOWN
4327 && chk == CH_UNKNOWN)
4329 sdump = cstring_makeLiteral ("$");
4331 else if (dss == SS_DEFINED
4332 && nst == NS_UNKNOWN
4333 && alk == AK_IMPTEMP
4334 && exk == XO_UNKNOWN
4335 && chk == CH_UNKNOWN)
4337 sdump = cstring_makeLiteral ("&");
4339 else if (dss == SS_UNKNOWN
4340 && nst == NS_UNKNOWN
4341 && alk == AK_UNKNOWN
4342 && exk == XO_UNKNOWN
4343 && chk == CH_UNKNOWN)
4345 sdump = cstring_makeLiteral ("^");
4347 else if (exk == XO_UNKNOWN
4348 && chk == CH_UNKNOWN)
4350 sdump = message ("%d@%d@%d&",
4357 sdump = message ("%d@%d@%d@%d@%d",
4368 return (message ("%q|@%d|%q#%s",
4369 ctype_dump (v->utype),
4372 isParam ? cstring_undefined : v->uname));
4376 return (message ("%q|%q#%s",
4377 ctype_dump (v->utype),
4379 isParam ? cstring_undefined : v->uname));
4384 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
4385 ctype_dump (v->utype),
4386 ynm_unparseCode (v->info->datatype->abs),
4387 ynm_unparseCode (v->info->datatype->mut),
4388 (int) sRef_getDefState (v->sref),
4389 (int) sRef_getNullState (v->sref),
4390 (int) sRef_getAliasKind (v->sref),
4391 (int) sRef_getExKind (v->sref),
4392 ctype_dump (v->info->datatype->type),
4396 cstring sdump, gdump, adump;
4397 alkind alk = sRef_getAliasKind (v->sref);
4398 exkind exk = sRef_getExKind (v->sref);
4400 if (sRef_getDefState (v->sref) == SS_DEFINED
4401 && !nstate_isKnown (sRef_getNullState (v->sref))
4402 && !exitkind_isKnown (v->info->fcn->exitCode)
4403 && v->info->fcn->specialCode == SPC_NONE
4404 && v->info->fcn->nullPred == QU_UNKNOWN)
4406 sdump = cstring_makeLiteral ("$");
4410 sdump = message ("@%d@%d@%d@%d@%d",
4411 (int) sRef_getDefState (v->sref),
4412 (int) sRef_getNullState (v->sref),
4413 (int) v->info->fcn->exitCode,
4414 (int) v->info->fcn->specialCode,
4415 (int) v->info->fcn->nullPred);
4418 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
4420 gdump = cstring_makeLiteral ("$");
4422 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
4423 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
4425 gdump = cstring_makeLiteral ("^");
4429 gdump = message ("@%s@%q@%s@%q",
4430 bool_dump (uentry_hasGlobs (v)),
4431 globSet_dump (uentry_getGlobs (v)),
4432 bool_dump (uentry_hasMods (v)),
4433 sRefSet_dump (uentry_getMods (v)));
4436 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
4438 adump = cstring_makeLiteral ("$");
4442 adump = message ("@%d@%d", (int) alk, (int) exk);
4445 if (uentry_hasSpecialClauses (v))
4447 return (message ("%q%q%q%q@%q@%q#%s",
4448 ctype_dump (v->utype),
4452 typeIdSet_dump (uentry_accessType (v)),
4453 specialClauses_dump (v->info->fcn->specclauses),
4458 return (message ("%q%q%q%q@%q#%s",
4459 ctype_dump (v->utype),
4463 typeIdSet_dump (uentry_accessType (v)),
4468 return (message ("%q@%q#%s",
4469 ctype_dump (v->utype),
4470 typeIdSet_dump (v->info->iter->access),
4473 return (message ("%q@%q#%s",
4474 ctype_dump (v->utype),
4475 typeIdSet_dump (uentry_accessType (v)),
4482 if (multiVal_isUnknown (v->info->uconst->val)
4483 && typeIdSet_isEmpty (uentry_accessType (v))
4484 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
4486 sdump = cstring_makeLiteral ("$");
4490 sdump = message ("@%q@%q@%d",
4491 multiVal_dump (v->info->uconst->val),
4492 typeIdSet_dump (uentry_accessType (v)),
4493 (int) sRef_getNullState (v->sref));
4496 return (message ("%q%q#%s",
4497 ctype_dump (v->utype),
4504 return (message ("%q@%q#%s",
4505 ctype_dump (v->utype),
4506 ctype_dump (v->info->datatype->type), v->uname));
4513 uentry_unparseAbbrev (uentry v)
4515 if (!uentry_isVariable (v))
4517 llcontbuglit ("uentry_unparseAbbrev: not variable");
4518 return uentry_unparse (v);
4521 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
4525 uentry_unparse (uentry v)
4529 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
4530 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
4532 st = uentry_getName (v);
4534 if (cstring_isDefined (st))
4536 return (ctype_unparseDeclaration (v->utype, st));
4541 return (cstring_copy (ctype_unparse (v->utype)));
4546 uentry_unparseFull (uentry v)
4548 if (uentry_isUndefined (v))
4550 return (cstring_makeLiteral ("<undefined>"));
4552 else if (uentry_isDatatype (v))
4554 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
4556 ekind_unparse (v->ukind),
4560 ctype_isDefined (v->info->datatype->type)
4561 ? v->info->datatype->type : ctype_unknown,
4562 ynm_unparse (v->info->datatype->mut),
4563 ynm_unparse (v->info->datatype->abs),
4564 sRef_unparseState (v->sref),
4565 fileloc_unparse (v->whereSpecified),
4566 fileloc_unparse (v->whereDefined)));
4568 else if (uentry_isFunction (v))
4570 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
4571 "globs: %q / [s: %q; decl: %q; def: %q]",
4573 ekind_unparse (v->ukind),
4576 sRef_unparseFull (v->sref),
4577 sRefSet_unparse (v->info->fcn->mods),
4578 globSet_unparse (v->info->fcn->globs),
4579 fileloc_unparse (v->whereSpecified),
4580 fileloc_unparse (v->whereDeclared),
4581 fileloc_unparse (v->whereDefined)));
4583 else if (uentry_isIter (v))
4585 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
4586 ekind_unparse (v->ukind),
4589 sRef_unparseFull (v->sref),
4590 fileloc_unparse (v->whereSpecified),
4591 fileloc_unparse (v->whereDefined)));
4593 else if (uentry_isVariable (v))
4596 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
4597 "kind <%d> isout <%d> used <%d>",
4598 checkedName (v->info->var->checked),
4600 ekind_unparse (v->ukind),
4603 sRef_unparseDeep (v->sref),
4604 fileloc_unparse (v->whereSpecified),
4605 fileloc_unparse (v->whereDefined),
4606 fileloc_unparse (v->whereDeclared),
4607 (int) v->info->var->kind,
4608 (int) v->info->var->defstate,
4613 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
4614 ekind_unparse (v->ukind),
4617 sRef_unparseFull (v->sref),
4618 fileloc_unparse (v->whereSpecified),
4619 fileloc_unparse (v->whereDefined)));
4624 bool uentry_hasAccessType (uentry e)
4626 if (uentry_isValid (e))
4631 return (!typeIdSet_isEmpty (e->info->iter->access));
4633 return (!typeIdSet_isEmpty (e->info->enditer->access));
4635 return (!typeIdSet_isEmpty (e->info->fcn->access));
4638 return (!typeIdSet_isEmpty (e->info->uconst->access));
4647 typeIdSet uentry_accessType (uentry e)
4649 if (uentry_isValid (e))
4654 return (e->info->iter->access);
4656 return (e->info->enditer->access);
4658 return (e->info->fcn->access);
4661 return (e->info->uconst->access);
4667 return typeIdSet_undefined;
4671 uentry_isVariable (uentry e)
4673 return (uentry_isVar (e));
4677 uentry_isSpecified (uentry e)
4679 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
4683 uentry_isReallySpecified (uentry e)
4685 return (uentry_isValid (e)
4686 && fileloc_isRealSpec (e->whereSpecified));
4690 uentry_isVar (uentry e)
4692 return (!uentry_isUndefined (e) && e->ukind == KVAR);
4696 uentry_isFakeTag (uentry e)
4698 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
4702 uentry_isDatatype (uentry e)
4704 return (!uentry_isUndefined (e) &&
4705 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
4706 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
4710 uentry_setAbstract (uentry e)
4714 llassert (uentry_isDatatype (e)
4715 && (ynm_isMaybe (e->info->datatype->abs)));
4717 oldid = ctype_typeId (e->info->datatype->type);
4718 e->info->datatype->abs = YES;
4719 e->info->datatype->type = ctype_createAbstract (oldid);
4723 uentry_setConcrete (uentry e)
4725 llassert (uentry_isDatatype (e)
4726 && (ynm_isMaybe (e->info->datatype->abs)));
4728 e->info->datatype->abs = NO;
4732 uentry_isAbstractDatatype (uentry e)
4734 return (uentry_isDatatype (e)
4735 && (ynm_isOn (e->info->datatype->abs)));
4739 uentry_isMaybeAbstract (uentry e)
4741 return (uentry_isDatatype (e)
4742 && (ynm_isMaybe (e->info->datatype->abs)));
4746 uentry_isMutableDatatype (uentry e)
4748 bool res = uentry_isDatatype (e)
4749 && (ynm_toBoolRelaxed (e->info->datatype->mut));
4755 uentry_isRefCountedDatatype (uentry e)
4757 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
4761 uentry_isParam (uentry u)
4763 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
4764 || u->info->var->kind == VKYIELDPARAM));
4768 uentry_isExpandedMacro (uentry u)
4770 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
4774 uentry_isSefParam (uentry u)
4776 return (uentry_isVariable (u)
4777 && (u->info->var->kind == VKSEFPARAM
4778 || u->info->var->kind == VKREFSEFPARAM
4779 || u->info->var->kind == VKSEFRETPARAM
4780 || u->info->var->kind == VKREFSEFRETPARAM));
4784 uentry_isRefParam (uentry u)
4786 return (uentry_isVariable (u)
4787 && (u->info->var->kind == VKREFPARAM
4788 || u->info->var->kind == VKREFYIELDPARAM
4789 || u->info->var->kind == VKREFSEFPARAM
4790 || u->info->var->kind == VKREFSEFRETPARAM));
4794 uentry_isAnyParam (uentry u)
4796 return (uentry_isVariable (u)
4797 && ((u->info->var->kind == VKPARAM)
4798 || (u->info->var->kind == VKSEFPARAM)
4799 || (u->info->var->kind == VKYIELDPARAM)
4800 || (u->info->var->kind == VKRETPARAM)
4801 || (u->info->var->kind == VKSEFRETPARAM)));
4805 uentry_getDefState (uentry u)
4807 if (uentry_isValid (u))
4809 return (sRef_getDefState (u->sref));
4813 return (SS_UNKNOWN);
4818 uentry_isOut (uentry u)
4820 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
4821 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4825 uentry_isPartial (uentry u)
4827 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
4828 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4832 uentry_isStateSpecial (uentry u)
4834 return ((uentry_isVariable (u)
4835 && (u->info->var->defstate == SS_SPECIAL))
4836 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
4839 exitkind uentry_getExitCode (uentry ue)
4841 if (uentry_isFunction (ue))
4843 return ue->info->fcn->exitCode;
4852 uentry_nullPred (uentry u)
4854 llassert (uentry_isRealFunction (u));
4856 if (uentry_isFunction (u))
4858 return (u->info->fcn->nullPred);
4867 uentry_possiblyNull (uentry u)
4869 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
4870 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
4874 uentry_getAliasKind (uentry u)
4876 if (uentry_isValid (u))
4878 return (sRef_getAliasKind (uentry_getSref (u)));
4887 uentry_getExpKind (uentry u)
4889 if (uentry_isValid (u))
4891 return (sRef_getExKind (uentry_getSref (u)));
4900 uentry_isIter (uentry e)
4902 return (!uentry_isUndefined (e) && e->ukind == KITER);
4906 uentry_isEndIter (uentry e)
4908 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
4912 uentry_isRealFunction (uentry e)
4914 return (uentry_isFunction (e) ||
4915 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
4919 uentry_hasName (uentry e)
4921 if (uentry_isValid (e))
4923 cstring s = e->uname;
4925 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
4933 bool uentry_hasRealName (uentry e)
4935 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
4939 /*@observer@*/ globSet
4940 uentry_getGlobs (uentry l)
4942 if (uentry_isInvalid (l))
4944 return globSet_undefined;
4947 if (l->ukind != KFCN)
4949 if (l->ukind != KITER && l->ukind != KENDITER)
4951 if (l->ukind == KVAR)
4953 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
4955 ekind_unparse (l->ukind)));
4959 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
4961 ekind_unparse (l->ukind)));
4964 return globSet_undefined;
4967 return l->info->fcn->globs;
4970 /*@observer@*/ sRefSet
4971 uentry_getMods (uentry l)
4973 llassert (uentry_isValid (l));
4975 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
4977 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
4978 return sRefSet_undefined;
4981 return l->info->fcn->mods;
4985 uentry_getKind (uentry e)
4987 llassert (uentry_isValid (e));
4992 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
4994 llassert (uentry_isEitherConstant (e));
4996 return (e->info->uconst->val);
4999 /*@observer@*/ uentryList
5000 uentry_getParams (uentry l)
5002 if (uentry_isInvalid (l)) return uentryList_undefined;
5009 ctype ct = l->utype;
5011 if (ctype_isFunction (ct))
5013 return (ctype_argsFunction (ct));
5017 return uentryList_undefined;
5022 ctype ct = l->utype;
5024 llassert (ctype_isFunction (ct));
5025 return (ctype_argsFunction (ct));
5032 /*@observer@*/ cstring
5033 uentry_rawName (uentry e)
5035 if (uentry_isValid (e))
5041 return cstring_undefined;
5046 uentry_getOptName (uentry e)
5048 cstring s = uentry_getName (e);
5050 if (cstring_isDefined (s))
5052 s = cstring_appendChar (s, ' ');
5059 uentry_getName (uentry e)
5061 cstring ret = cstring_undefined;
5063 if (uentry_isValid (e))
5066 if (uentry_isAnyTag (e))
5068 ret = fixTagName (e->uname);
5070 else if (uentry_isAnyParam (e))
5072 ret = cstring_copy (fixParamName (e->uname));
5076 ret = cstring_copy (e->uname);
5083 cstring uentry_getRealName (uentry e)
5085 if (uentry_isValid (e))
5087 if (uentry_isAnyTag (e))
5089 return (cstring_undefined);
5096 return cstring_undefined;
5099 ctype uentry_getType (uentry e)
5101 if (uentry_isValid (e))
5107 return ctype_unknown;
5111 fileloc uentry_whereLast (uentry e)
5115 if (uentry_isInvalid (e))
5117 return fileloc_undefined;
5120 loc = e->whereDefined;
5122 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5127 loc = uentry_whereDeclared (e);
5129 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5134 loc = uentry_whereSpecified (e);
5138 fileloc uentry_whereEither (uentry e)
5140 if (uentry_isInvalid (e)) return fileloc_undefined;
5142 if (fileloc_isDefined (e->whereDefined)
5143 && !fileloc_isExternal (e->whereDefined))
5145 return e->whereDefined;
5147 else if (fileloc_isDefined (e->whereDeclared))
5149 return e->whereDeclared;
5153 return e->whereSpecified;
5157 fileloc uentry_whereSpecified (uentry e)
5159 if (uentry_isInvalid (e)) return fileloc_undefined;
5161 return (e->whereSpecified);
5164 fileloc uentry_whereDefined (uentry e)
5166 if (uentry_isInvalid (e)) return fileloc_undefined;
5168 return (e->whereDefined);
5171 fileloc uentry_whereDeclared (uentry e)
5173 if (uentry_isInvalid (e)) return fileloc_undefined;
5175 return (e->whereDeclared);
5178 /*@observer@*/ fileloc
5179 uentry_whereEarliest (uentry e)
5181 if (uentry_isInvalid (e)) return fileloc_undefined;
5183 if (fileloc_isDefined (e->whereSpecified))
5185 return (e->whereSpecified);
5187 else if (fileloc_isDefined (e->whereDeclared))
5189 return (e->whereDeclared);
5193 return e->whereDefined;
5198 uentry_setFunctionDefined (uentry e, fileloc loc)
5200 if (uentry_isValid (e))
5202 llassert (uentry_isFunction (e));
5204 if (fileloc_isUndefined (e->whereDeclared))
5206 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5209 if (!fileloc_isDefined (e->whereDefined))
5211 e->whereDefined = fileloc_update (e->whereDefined, loc);
5217 uentry_setDeclDef (uentry e, fileloc f)
5219 uentry_setDeclared (e, f);
5221 if (!uentry_isFunction (e)
5222 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5224 uentry_setDefined (e, f);
5229 uentry_setDeclaredForce (uentry e, fileloc f)
5231 llassert (uentry_isValid (e));
5232 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5236 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5238 llassert (uentry_isValid (e));
5239 fileloc_free (e->whereDeclared);
5240 e->whereDeclared = f;
5244 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5248 llassert (uentry_isValid (e));
5249 oldloc = e->whereDeclared;
5251 if (fileloc_isDefined (oldloc))
5253 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5255 e->whereDeclared = f;
5256 fileloc_free (oldloc);
5265 e->whereDeclared = f;
5266 fileloc_free (oldloc);
5271 uentry_setDeclared (uentry e, fileloc f)
5275 llassert (uentry_isValid (e));
5276 oldloc = e->whereDeclared;
5278 if (fileloc_isDefined (oldloc))
5280 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5282 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5291 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5296 uentry_clearDefined (uentry e)
5298 if (uentry_isValid (e))
5300 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5305 uentry_setDefined (uentry e, fileloc f)
5309 llassert (uentry_isValid (e));
5310 oldloc = e->whereDefined;
5312 if (fileloc_isDefined (oldloc))
5314 if (fileloc_isLib (oldloc)
5315 || fileloc_isImport (oldloc)
5316 || fileloc_isBuiltin (oldloc)
5317 || fileloc_isPreproc (oldloc))
5319 e->whereDefined = fileloc_update (e->whereDefined, f);
5323 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5329 if (optgenerror (FLG_REDEF,
5330 message ("%s %q redefined",
5331 ekind_capName (e->ukind),
5332 uentry_getName (e)),
5335 llgenindentmsg (message ("Previous definition of %q",
5336 uentry_getName (e)),
5344 e->whereDefined = fileloc_update (e->whereDefined, f);
5349 uentry_isCodeDefined (uentry e)
5351 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
5355 uentry_isDeclared (uentry e)
5357 if (uentry_isValid (e))
5359 return (fileloc_isDefined (e->whereDeclared));
5365 sRef uentry_getSref (uentry e)
5367 /* not true, used for functions too (but shouldn't be? */
5368 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
5370 if (uentry_isInvalid (e)) return sRef_undefined;
5375 sRef uentry_getOrigSref (uentry e)
5377 if (uentry_isValid (e))
5379 sRef sr = sRef_copy (uentry_getSref (e));
5381 sRef_resetState (sr);
5382 sRef_clearDerived (sr);
5384 if (uentry_isVariable (e))
5386 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
5387 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
5394 return sRef_undefined;
5399 ** requires: uentry e is not in a hashed symbol table
5403 uentry_setName (uentry e, /*@only@*/ cstring n)
5405 llassert (uentry_isValid (e));
5407 cstring_free (e->uname);
5412 uentry_setType (uentry e, ctype t)
5414 if (uentry_isValid (e))
5417 sRef_setType (e->sref, t);
5422 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
5425 ctype rettype = ctype_unknown;
5427 llassert (uentry_isValid (ue));
5429 rct = ctype_realType (ue->utype);
5431 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
5433 uentry_makeVarFunction (ue);
5436 llassert (uentry_isFunction (ue));
5438 if (ctype_isFunction (rct))
5440 rettype = ctype_returnValue (rct);
5443 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
5447 uentry_setRefParam (uentry e)
5450 if (!uentry_isVar (e))
5452 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5456 if (e->info->var->kind == VKSEFPARAM)
5458 e->info->var->kind = VKREFSEFPARAM;
5460 else if (e->info->var->kind == VKSEFRETPARAM)
5462 e->info->var->kind = VKREFSEFRETPARAM;
5464 else if (e->info->var->kind == VKYIELDPARAM)
5466 e->info->var->kind = VKREFYIELDPARAM;
5470 e->info->var->kind = VKREFPARAM;
5476 uentry_setParam (uentry e)
5478 if (!uentry_isVar (e))
5480 if (uentry_isElipsisMarker (e))
5486 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5493 if (e->info->var->kind == VKYIELDPARAM
5494 || e->info->var->kind == VKSEFPARAM
5495 || e->info->var->kind == VKSEFRETPARAM)
5501 e->info->var->kind = VKPARAM;
5505 e->uname = makeParam (e->uname);
5506 cstring_free (oldname);
5511 uentry_setSref (uentry e, sRef s)
5513 if (uentry_isValid (e))
5515 if (sRef_isValid (e->sref))
5517 sRef_mergeStateQuietReverse (e->sref, s);
5521 e->sref = sRef_saveCopy (s);
5527 uentry_getAbstractType (uentry e)
5529 llassert (uentry_isDatatype (e));
5532 ** This assertion removed.
5533 ** Okay to have undefined type, for system types
5535 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
5536 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
5541 if (ctype_isUndefined (e->info->datatype->type))
5543 return ctype_unknown;
5547 ** Sadly, a kludge...
5550 if (ctype_isUserBool (e->info->datatype->type)) {
5554 return e->info->datatype->type;
5557 ctype uentry_getRealType (uentry e)
5560 typeId uid = USYMIDINVALID;
5562 if (uentry_isInvalid (e))
5564 return ctype_unknown;
5567 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5569 if (uentry_isAnyTag (e))
5574 if (uentry_isAbstractType (e))
5576 ct = uentry_getAbstractType (e);
5578 if (ctype_isManifestBool (ct)) {
5582 llassert (ctype_isUA (ct));
5584 uid = ctype_typeId (ct);
5586 if (!context_hasAccess (uid))
5592 ct = uentry_getType (e);
5594 /* if (ctype_isUserBool (ct)) return ct; */
5596 if (ctype_isManifestBool (ct)) {
5600 if (ctype_isUA (ct))
5602 usymId iid = ctype_typeId (ct);
5604 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5606 llcontbug (message ("uentry_getRealType: recursive type! %s",
5607 ctype_unparse (ct)));
5612 /* evs 2000-07-25: possible infinite recursion ? */
5613 uentry ue2 = usymtab_getTypeEntry (iid);
5614 llassertprint (ue2 != e, ("Bad recursion: %s", uentry_unparseFull (e)));
5616 return uentry_getRealType (ue2);
5625 ctype uentry_getForceRealType (uentry e)
5628 typeId uid = USYMIDINVALID;
5630 if (uentry_isInvalid (e))
5632 return ctype_unknown;
5635 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5637 if (uentry_isAnyTag (e))
5642 if (uentry_isAbstractType (e))
5644 ct = uentry_getAbstractType (e);
5645 llassert (ctype_isUA (ct));
5647 uid = ctype_typeId (ct);
5648 /* no check for access! */
5651 ct = uentry_getType (e);
5653 /* evs 2000-07-25 */
5654 /* if (ctype_isUserBool (ct)) return ct; */
5656 if (ctype_isManifestBool (ct)) {
5660 if (ctype_isUA (ct))
5662 usymId iid = ctype_typeId (ct);
5664 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5666 llcontbug (message ("uentry_getRealType: recursive type! %s",
5667 ctype_unparse (ct)));
5672 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
5681 uentry uentry_nameCopy (cstring name, uentry e)
5683 uentry enew = uentry_alloc ();
5685 llassert (uentry_isValid (e));
5687 /* enew->shallowCopy = FALSE; */
5688 enew->ukind = e->ukind;
5690 enew->utype = e->utype;
5691 enew->whereSpecified = fileloc_copy (e->whereSpecified);
5692 enew->whereDefined = fileloc_copy (e->whereDefined);
5693 enew->whereDeclared = fileloc_copy (e->whereDeclared);
5694 enew->sref = sRef_copy (e->sref);
5695 enew->used = e->used;
5697 enew->isPrivate = e->isPrivate;
5698 enew->hasNameError = FALSE;
5700 enew->uses = filelocList_new ();
5702 enew->storageclass = e->storageclass;
5703 enew->info = uinfo_copy (e->info, e->ukind);
5709 uentry_setDatatype (uentry e, usymId uid)
5711 llassert (uentry_isDatatype (e));
5713 if (uentry_isAbstractType (e))
5715 e->info->datatype->type = ctype_createAbstract (uid);
5719 e->info->datatype->type = ctype_createUser (uid);
5724 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
5725 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
5728 llassert (uentry_isValid (e));
5730 if (fileloc_isSpec (f) || fileloc_isImport (f))
5732 e->whereSpecified = f;
5733 e->whereDeclared = fileloc_undefined;
5734 e->whereDefined = fileloc_undefined;
5738 e->whereSpecified = fileloc_undefined;
5739 e->whereDeclared = f;
5740 e->whereDefined = fileloc_undefined;
5745 ucinfo_free (/*@only@*/ ucinfo u)
5747 multiVal_free (u->val);
5752 uvinfo_free (/*@only@*/ uvinfo u)
5758 udinfo_free (/*@only@*/ udinfo u)
5764 ufinfo_free (/*@only@*/ ufinfo u)
5766 globSet_free (u->globs);
5767 sRefSet_free (u->mods);
5768 specialClauses_free (u->specclauses);
5774 uiinfo_free (/*@only@*/ uiinfo u)
5780 ueinfo_free (/*@only@*/ ueinfo u)
5785 static /*@only@*/ ucinfo
5786 ucinfo_copy (ucinfo u)
5788 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
5790 ret->val = multiVal_copy (u->val);
5791 ret->access = u->access;
5796 static /*@only@*/ uvinfo
5797 uvinfo_copy (uvinfo u)
5799 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
5801 ret->kind = u->kind;
5802 ret->nullstate = u->nullstate;
5803 ret->defstate = u->defstate;
5804 ret->checked = u->checked;
5806 //ret->bufinfo = u->bufinfo;
5807 /*@i334@*/ return ret;
5810 static /*@only@*/ udinfo
5811 udinfo_copy (udinfo u)
5813 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
5817 ret->type = u->type;
5822 static /*@only@*/ ufinfo
5823 ufinfo_copy (ufinfo u)
5825 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
5827 ret->hasGlobs = u->hasGlobs;
5828 ret->hasMods = u->hasMods;
5829 ret->exitCode = u->exitCode;
5830 ret->specialCode = u->specialCode;
5831 ret->nullPred = u->nullPred;
5832 ret->access = u->access;
5833 ret->globs = globSet_newCopy (u->globs);
5834 ret->mods = sRefSet_newCopy (u->mods);
5835 ret->defparams = u->defparams;
5836 ret->specclauses = specialClauses_copy (u->specclauses);
5841 static /*@only@*/ uiinfo
5842 uiinfo_copy (uiinfo u)
5844 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
5846 ret->access = u->access;
5847 ret->globs = globSet_newCopy (u->globs);
5848 ret->mods = sRefSet_newCopy (u->mods);
5853 static /*@only@*/ ueinfo
5854 ueinfo_copy (ueinfo u)
5856 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
5858 ret->access = u->access;
5863 uinfo_free (uinfo u, ekind kind)
5868 case KCONST: ucinfo_free (u->uconst); break;
5869 case KVAR: uvinfo_free (u->var); break;
5873 case KDATATYPE: udinfo_free (u->datatype); break;
5874 case KFCN: ufinfo_free (u->fcn); break;
5875 case KITER: uiinfo_free (u->iter); break;
5876 case KENDITER: ueinfo_free (u->enditer); break;
5877 case KELIPSMARKER: break;
5878 case KINVALID: break;
5884 static /*@only@*/ /*@null@*/ uinfo
5885 uinfo_copy (uinfo u, ekind kind)
5887 if (kind == KELIPSMARKER || kind == KINVALID)
5893 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
5898 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
5899 case KVAR: ret->var = uvinfo_copy (u->var); break;
5903 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
5904 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
5905 case KITER: ret->iter = uiinfo_copy (u->iter); break;
5906 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
5914 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
5916 filelocList_free (e->uses);
5917 cstring_free (e->uname);
5919 uinfo_free (e->info, e->ukind);
5921 fileloc_free (e->whereSpecified);
5922 fileloc_free (e->whereDefined);
5923 fileloc_free (e->whereDeclared);
5929 extern void uentry_markOwned (/*@owned@*/ uentry u)
5931 sfreeEventually (u);
5935 uentry_free (/*@only@*/ uentry e)
5937 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
5939 uentry_reallyFree (e);
5944 ** For uentry's in the global or file scope
5948 uentry_freeComplete (/*@only@*/ uentry e)
5950 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
5952 /*@i@*/ sRef_free (e->sref);
5953 e->sref = sRef_undefined;
5954 uentry_reallyFree (e);
5959 ** requires old->kind != new->kind, old->uname = new->uname
5963 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
5965 llassert (uentry_isValid (old));
5966 llassert (uentry_isValid (unew));
5968 if (uentry_isEitherConstant (unew)
5969 && (fileloc_isPreproc (uentry_whereDeclared (old))
5970 || ctype_isUnknown (old->utype))
5971 && !uentry_isSpecified (old))
5979 if (!uentry_isDeclared (old))
5981 if (uentry_isSpecified (old))
5983 if (uentry_isSpecified (unew))
5985 llbuglit ("Respecification!");
5987 else if (uentry_isDeclared (unew))
5991 message ("%s %q inconsistently declared as %s: %t",
5992 ekind_capName (old->ukind),
5993 uentry_getName (unew),
5994 ekind_unparseLong (unew->ukind),
5996 uentry_whereDeclared (unew)))
5998 uentry_showWhereLast (old);
6010 message ("%s %q inconsistently declared as %s: %t",
6011 ekind_capName (old->ukind),
6012 uentry_getName (unew),
6013 ekind_unparseLong (unew->ukind),
6015 uentry_whereDeclared (unew)))
6017 uentry_showWhereLast (old);
6023 llassert (uentry_isDeclared (unew));
6027 message ("%s %q inconsistently redeclared as %s",
6028 ekind_capName (old->ukind),
6029 uentry_getName (unew),
6030 ekind_unparseLong (unew->ukind)),
6031 uentry_whereDeclared (unew)))
6033 uentry_showWhereLast (old);
6039 uentry_copyInto (old, unew);
6043 ** def is the definition of spec, modifies spec
6045 ** reports any inconsistencies
6046 ** returns the summary of all available information
6047 ** if spec and def are inconsistent, def is returned
6051 uentry_showWhereLast (uentry spec)
6053 if (uentry_isValid (spec))
6055 if (fileloc_isDefined (spec->whereDefined)
6056 && !fileloc_isLib (spec->whereDefined)
6057 && !fileloc_isPreproc (spec->whereDefined))
6059 llgenindentmsg (message ("Previous definition of %q: %t",
6060 uentry_getName (spec),
6061 uentry_getType (spec)),
6062 uentry_whereDefined (spec));
6064 else if (uentry_isDeclared (spec))
6066 llgenindentmsg (message ("Previous declaration of %q: %t",
6067 uentry_getName (spec),
6068 uentry_getType (spec)),
6069 uentry_whereDeclared (spec));
6071 else if (uentry_isSpecified (spec))
6073 if (uentry_hasName (spec))
6075 llgenindentmsg (message ("Specification of %q: %t",
6076 uentry_getName (spec),
6077 uentry_getType (spec)),
6078 uentry_whereSpecified (spec));
6082 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6083 uentry_whereSpecified (spec));
6088 /* nothing to show */
6094 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6096 fileloc loc = uentry_whereDefined (ce);
6098 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6100 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6104 loc = uentry_whereSpecified (ce);
6106 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6108 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6113 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6115 if (uentry_isDeclared (spec))
6117 llgenindentmsg (message ("Previous declaration of %q: %q",
6118 uentry_getName (spec), extra),
6119 uentry_whereDeclared (spec));
6121 else if (uentry_isSpecified (spec))
6123 llgenindentmsg (message ("Specification of %q: %q",
6124 uentry_getName (spec), extra),
6125 uentry_whereSpecified (spec));
6129 cstring_free (extra);
6134 uentry_showWhereDeclared (uentry spec)
6136 if (uentry_isDeclared (spec))
6138 if (uentry_hasName (spec))
6140 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6141 uentry_whereDeclared (spec));
6145 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6148 else if (uentry_isSpecified (spec))
6150 if (uentry_hasName (spec))
6152 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6153 uentry_whereSpecified (spec));
6157 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6162 /* nothing to show */
6168 uentry_showWhereAny (uentry spec)
6170 if (uentry_isDeclared (spec))
6172 if (uentry_hasName (spec))
6174 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6175 uentry_whereDeclared (spec));
6179 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6182 else if (uentry_isSpecified (spec))
6184 if (uentry_hasName (spec))
6186 llgenindentmsg (message ("Specification of %q",
6187 uentry_getName (spec)),
6188 uentry_whereSpecified (spec));
6192 llgenindentmsg (cstring_makeLiteral ("Specification"),
6193 uentry_whereSpecified (spec));
6196 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6198 if (uentry_hasName (spec))
6200 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6201 uentry_whereDefined (spec));
6205 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6210 /* nothing to show */
6215 uentry_showWhereDefined (uentry spec)
6217 if (uentry_isCodeDefined (spec))
6219 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6220 uentry_whereDefined (spec));
6225 uentry_showWhereLastPlain (uentry spec)
6227 if (uentry_isDeclared (spec))
6229 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6230 uentry_whereDeclared (spec));
6232 else if (uentry_isSpecified (spec))
6234 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6235 uentry_whereSpecified (spec));
6243 uentry_showWhereLastVal (uentry spec, cstring val)
6245 if (uentry_isDeclared (spec))
6247 llgenindentmsg (message ("Previous declaration of %q: %s",
6248 uentry_getName (spec), val),
6249 uentry_whereDeclared (spec));
6251 else if (uentry_isSpecified (spec))
6253 llgenindentmsg (message ("Specification of %q: %s",
6254 uentry_getName (spec), val),
6255 uentry_whereSpecified (spec));
6263 uentry_showWhereSpecified (uentry spec)
6265 if (uentry_isSpecified (spec))
6267 if (uentry_hasName (spec))
6269 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6270 uentry_whereSpecified (spec));
6274 llgenindentmsg (cstring_makeLiteral ("Specification"),
6275 uentry_whereSpecified (spec));
6278 else if (uentry_isDeclared (spec))
6280 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6281 uentry_whereDeclared (spec));
6285 /* nothing to show */
6290 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6292 if (uentry_isSpecified (spec))
6294 if (uentry_hasName (spec))
6296 llgenindentmsg (message ("Specification of %q: %q",
6297 uentry_getName (spec), s),
6298 uentry_whereSpecified (spec));
6302 llgenindentmsg (message ("Specification: %q", s),
6303 uentry_whereSpecified (spec));
6306 else if (uentry_isDeclared (spec))
6308 llgenindentmsg (message ("Declaration of %q: %q",
6309 uentry_getName (spec), s),
6310 uentry_whereDeclared (spec));
6314 llgenindentmsg (message ("Previous: %q", s),
6315 uentry_whereLast (spec));
6324 checkStructConformance (uentry old, uentry unew)
6327 uentryList fold, fnew;
6330 ** requires: types of old and new are structs or unions
6333 llassert (uentry_isValid (old));
6334 llassert (uentry_isValid (unew));
6336 oldr = ctype_realType (old->utype);
6337 fold = ctype_getFields (oldr);
6339 newr = ctype_realType (unew->utype);
6340 fnew = ctype_getFields (newr);
6342 if (!uentryList_matchFields (fold, fnew))
6344 if (fileloc_equal (uentry_whereLast (old),
6345 uentry_whereLast (unew)))
6353 message ("%q %q %rdeclared with fields { %q }, %s "
6354 "with fields { %q }",
6355 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
6356 uentry_getName (old),
6357 uentry_isDeclared (old),
6358 uentryList_unparseAbbrev (fnew),
6359 uentry_specOrDefName (old),
6360 uentryList_unparseAbbrev (fold)),
6361 uentry_whereDeclared (unew)))
6363 uentry_showWhereLastPlain (old);
6364 uentryList_showFieldDifference (fold, fnew);
6368 old->utype = unew->utype;
6373 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6376 ** requires old and new are enums
6379 ctype rold = ctype_realType (old->utype);
6380 ctype rnew = ctype_realType (unew->utype);
6381 enumNameList eold = ctype_elist (rold);
6382 enumNameList enew = ctype_elist (rnew);
6384 if (!enumNameList_match (eold, enew))
6388 message ("Enum %q declared with members { %q } but "
6389 "specified with members { %q }",
6390 uentry_getName (old),
6391 enumNameList_unparse (enew),
6392 enumNameList_unparse (eold)),
6393 uentry_whereDeclared (unew)))
6395 uentry_showWhereSpecified (old);
6396 old->utype = unew->utype;
6402 ** either oldCurrent or newCurrent may be undefined!
6406 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
6407 uentry unew, uentry newCurrent, ctype newType,
6410 bool hasError = FALSE;
6412 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
6414 if (uentry_hasName (newCurrent))
6416 hasError = optgenerror
6418 message ("Parameter %d, %q, of function %q has inconsistent type: "
6419 "declared %t, %s %t",
6420 paramno + 1, uentry_getName (newCurrent),
6421 uentry_getName (unew),
6422 newType, uentry_specOrDefName (old), oldType),
6423 uentry_whereDeclared (newCurrent));
6427 hasError = optgenerror
6429 message ("Parameter %d of function %q has inconsistent type: "
6430 "declared %t, %s %t",
6431 paramno + 1, uentry_getName (unew),
6432 newType, uentry_specOrDefName (old), oldType),
6433 uentry_whereDeclared (newCurrent));
6435 DPRINTF (("type: %s / %s",
6436 ctype_unparse (newType),
6437 ctype_unparse (ctype_realType (newType))));
6442 if (uentry_isDeclared (unew))
6444 hasError = optgenerror
6446 message ("Parameter %d of function %s has inconsistent type: "
6447 "declared %t, %s %t",
6448 paramno + 1, unew->uname,
6449 newType, uentry_specOrDefName (old), oldType),
6450 uentry_whereDeclared (unew));
6454 hasError = optgenerror
6456 message ("Parameter %d of function %s has inconsistent type: "
6457 "declared %t, %s %t",
6458 paramno + 1, unew->uname,
6459 newType, uentry_specOrDefName (old), oldType),
6460 uentry_whereDeclared (unew));
6466 if (!uentry_isUndefined (oldCurrent))
6468 if (!uentry_isUndefined (newCurrent)
6469 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
6471 uentry_showWhereLast (oldCurrent);
6475 uentry_showWhereLastPlain (old);
6478 uentry_setType (oldCurrent, newType);
6482 uentry_showWhereLastPlain (old);
6488 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6492 message ("Function %s %rdeclared with %d arg%p, %s with %d",
6494 uentry_isDeclared (old),
6495 uentryList_size (uentry_getParams (unew)),
6496 uentry_specOrDefName (old),
6497 uentryList_size (uentry_getParams (old))),
6498 uentry_whereDeclared (unew)))
6500 uentry_showWhereLastPlain (old);
6505 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6509 message ("Function %s inconsistently %rdeclared to return %t",
6511 uentry_isDeclared (old),
6512 ctype_returnValue (unew->utype)),
6513 uentry_whereDeclared (unew)))
6515 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
6519 static cstring paramStorageName (uentry ue)
6521 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
6524 static cstring fcnErrName (uentry ue)
6526 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
6529 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
6531 if (uentry_isVar (ue))
6533 return (checkedName (ue->info->var->checked));
6537 return (cstring_makeLiteralTemp ("<checked invalid>"));
6541 static cstring checkedName (chkind checked)
6545 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
6546 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
6547 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
6548 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
6549 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
6555 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
6560 if (uentry_isVar (unew))
6562 llassert (uentry_isVar (old));
6564 oldState = old->info->var->nullstate;
6565 newState = unew->info->var->nullstate;
6569 oldState = sRef_getNullState (old->sref);
6570 newState = sRef_getNullState (unew->sref);
6573 if (oldState == NS_ABSNULL)
6575 if (uentry_isVar (old))
6577 old->info->var->nullstate = newState;
6580 sRef_mergeNullState (old->sref, newState);
6582 else if (newState == NS_UNKNOWN)
6584 if (completeConform && newState != oldState
6585 && uentry_isReallySpecified (old))
6589 message ("%s %q specified as %s, but declared without %s qualifier",
6590 ekind_capName (unew->ukind),
6591 uentry_getName (unew),
6592 nstate_unparse (oldState),
6593 nstate_unparse (oldState)),
6594 uentry_whereDeclared (unew)))
6596 uentry_showWhereSpecified (old);
6600 if (uentry_isVar (unew))
6602 unew->info->var->nullstate = oldState;
6605 sRef_mergeNullState (unew->sref, oldState);
6607 else if (newState == NS_POSNULL)
6609 if (oldState == NS_MNOTNULL
6610 && (ctype_isUA (unew->utype)
6611 || (uentry_isFunction (unew)
6612 && ctype_isUA (ctype_returnValue (unew->utype)))))
6614 if (uentry_isVar (unew))
6616 unew->info->var->nullstate = oldState;
6619 sRef_mergeNullState (unew->sref, oldState);
6623 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
6624 || oldState == NS_UNKNOWN)
6631 ("%s %q inconsistently %rdeclared %s possibly null storage, "
6633 uentry_ekindName (unew),
6634 uentry_getName (unew),
6635 uentry_isDeclared (old),
6637 uentry_specOrDefName (old),
6638 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
6639 uentry_whereDeclared (unew)))
6641 uentry_showWhereSpecified (old);
6646 if (uentry_isVar (old))
6648 old->info->var->nullstate = newState;
6651 sRef_mergeNullState (old->sref, newState);
6654 else if (newState == NS_MNOTNULL)
6656 if (oldState != NS_MNOTNULL)
6662 message ("%s %q inconsistently %rdeclared %s notnull storage, "
6663 "%s without notnull qualifier",
6664 uentry_ekindName (unew),
6665 uentry_getName (unew),
6666 uentry_isDeclared (old),
6668 uentry_specOrDefName (old)),
6669 uentry_whereDeclared (unew)))
6671 uentry_showWhereSpecified (old);
6675 if (uentry_isVar (old))
6677 old->info->var->nullstate = newState;
6680 sRef_mergeNullState (old->sref, newState);
6685 if (uentry_isVar (unew))
6687 unew->info->var->nullstate = oldState;
6690 sRef_mergeNullState (unew->sref, oldState);
6695 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6696 bool mustConform, bool completeConform)
6702 if (uentry_isVar (old) && uentry_isVar (unew))
6704 oldState = old->info->var->defstate;
6705 newState = unew->info->var->defstate;
6710 oldState = sRef_getDefState (old->sref);
6711 newState = sRef_getDefState (unew->sref);
6714 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
6720 message ("%s %q inconsistently %rdeclared %s %s %s, "
6722 uentry_ekindName (unew),
6723 uentry_getName (unew),
6724 uentry_isDeclared (old),
6726 sstate_unparse (newState),
6727 paramStorageName (unew),
6728 uentry_specOrDefName (old),
6730 sstate_unparse (oldState),
6731 paramStorageName (unew)),
6732 uentry_whereDeclared (unew)))
6734 uentry_showWhereSpecified (old);
6738 if (vars) old->info->var->defstate = newState;
6739 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
6744 && (newState != oldState) && (oldState != SS_DEFINED)
6745 && uentry_isReallySpecified (old))
6749 message ("%s %q specified as %s, but declared without %s qualifier",
6750 ekind_capName (unew->ukind),
6751 uentry_getName (unew),
6752 sstate_unparse (oldState),
6753 sstate_unparse (oldState)),
6754 uentry_whereDeclared (unew)))
6756 uentry_showWhereSpecified (old);
6760 if (vars) unew->info->var->defstate = oldState;
6761 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
6766 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6767 bool mustConform, bool completeConform)
6772 oldKind = sRef_getAliasKind (old->sref);
6773 newKind = sRef_getAliasKind (unew->sref);
6775 if (alkind_isImplicit (newKind)
6776 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
6778 if (completeConform && !alkind_equal (newKind, oldKind)
6779 && uentry_isReallySpecified (old))
6783 message ("%s %q specified as %s, but declared without "
6784 "explicit alias qualifier",
6785 ekind_capName (unew->ukind),
6786 uentry_getName (unew),
6787 alkind_unparse (oldKind)),
6788 uentry_whereDeclared (unew)))
6790 uentry_showWhereSpecified (old);
6795 ** This really shouldn't be necessary, but it is!
6796 ** Function params (?) use new here.
6799 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
6803 if (alkind_isKnown (newKind))
6805 if (!alkind_equal (oldKind, newKind))
6807 if (alkind_isKnown (oldKind))
6812 message ("%s %q inconsistently %rdeclared %s %s storage, "
6814 uentry_ekindName (unew),
6815 uentry_getName (unew),
6816 uentry_isDeclared (old),
6818 alkind_unparse (newKind),
6819 uentry_specOrDefName (old),
6820 alkind_unparse (oldKind)),
6821 uentry_whereDeclared (unew)))
6823 uentry_showWhereSpecified (old);
6825 sRef_setAliasKind (old->sref, AK_ERROR,
6826 uentry_whereDeclared (unew));
6830 sRef_setAliasKind (old->sref, newKind,
6831 uentry_whereDeclared (unew));
6836 if (!(alkind_isImplicit (newKind)))
6839 !uentry_isFunction (unew) &&
6842 message ("%s %q inconsistently %rdeclared %s %s storage, "
6843 "implicitly %s as temp storage",
6844 uentry_ekindName (unew),
6845 uentry_getName (unew),
6846 uentry_isDeclared (old),
6848 alkind_unparse (newKind),
6849 uentry_specOrDefName (old)),
6850 uentry_whereDeclared (unew)))
6852 uentry_showWhereSpecified (old);
6856 sRef_setAliasKind (old->sref, newKind,
6857 uentry_whereDeclared (unew));
6859 else /* newKind is temp or refcounted */
6866 else /* newKind unknown */
6873 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6874 bool mustConform, bool completeConform)
6879 oldKind = sRef_getExKind (old->sref);
6880 newKind = sRef_getExKind (unew->sref);
6882 if (exkind_isKnown (newKind))
6884 if (oldKind != newKind)
6886 if (exkind_isKnown (oldKind))
6891 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
6892 uentry_ekindName (unew),
6893 uentry_getName (unew),
6894 uentry_isDeclared (old),
6896 exkind_unparse (newKind),
6897 uentry_specOrDefName (old),
6898 exkind_unparse (oldKind)),
6899 uentry_whereDeclared (unew)))
6901 uentry_showWhereSpecified (old);
6904 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6911 message ("%s %q inconsistently %rdeclared %s %s, "
6912 "implicitly %s without exposure qualifier",
6913 uentry_ekindName (unew),
6914 uentry_getName (unew),
6915 uentry_isDeclared (old),
6917 exkind_unparse (newKind),
6918 uentry_specOrDefName (old)),
6919 uentry_whereDeclared (unew)))
6921 uentry_showWhereSpecified (old);
6924 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6930 if (completeConform && exkind_isKnown (oldKind)
6931 && uentry_isReallySpecified (old))
6935 message ("%s %q specified as %s, but declared without "
6936 "exposure qualifier",
6937 ekind_capName (unew->ukind),
6938 uentry_getName (unew),
6939 exkind_unparse (oldKind)),
6940 uentry_whereDeclared (unew)))
6942 uentry_showWhereSpecified (old);
6946 /* yes, this is necessary! (if its a param) */
6947 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
6952 uentry_checkStateConformance (/*@notnull@*/ uentry old,
6953 /*@notnull@*/ uentry unew,
6954 bool mustConform, bool completeConform)
6956 checkDefState (old, unew, mustConform, completeConform);
6957 checkNullState (old, unew, mustConform, completeConform);
6958 checkAliasState (old, unew, mustConform, completeConform);
6959 checkExpState (old, unew, mustConform, completeConform);
6961 sRef_storeState (old->sref);
6962 sRef_storeState (unew->sref);
6966 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
6968 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
6973 llassert (uentry_isVar (old));
6974 llassert (uentry_isVar (unew));
6976 if (cstring_isEmpty (old->uname))
6978 cstring_free (old->uname);
6979 old->uname = cstring_copy (unew->uname);
6982 if (unew->info->var->kind == VKRETPARAM
6983 || unew->info->var->kind == VKSEFRETPARAM)
6985 if (old->info->var->kind != VKRETPARAM
6986 && old->info->var->kind != VKSEFRETPARAM)
6990 message ("Parameter %q inconsistently %rdeclared as "
6991 "returned parameter",
6992 uentry_getName (unew),
6993 uentry_isDeclared (old)),
6994 uentry_whereDeclared (unew)))
6996 uentry_showWhereSpecified (old);
6997 old->info->var->kind = unew->info->var->kind;
7003 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7005 if (old->info->var->kind != VKSEFPARAM
7006 && old->info->var->kind != VKSEFRETPARAM)
7010 message ("Parameter %qinconsistently %rdeclared as "
7012 uentry_getOptName (unew),
7013 uentry_isDeclared (old)),
7014 uentry_whereDeclared (unew)))
7016 uentry_showWhereSpecified (old);
7017 old->info->var->kind = unew->info->var->kind;
7022 if (old->info->var->kind == VKSPEC)
7024 old->info->var->kind = unew->info->var->kind;
7028 unew->info->var->kind = old->info->var->kind;
7031 if (unew->info->var->checked != CH_UNKNOWN
7032 && unew->info->var->checked != old->info->var->checked)
7034 if (old->info->var->checked == CH_UNKNOWN
7035 && !fileloc_isUser (uentry_whereLast (old)))
7043 message ("Variable %q inconsistently %rdeclared as "
7044 "%s parameter (was %s)",
7045 uentry_getName (unew),
7046 uentry_isDeclared (old),
7047 checkedName (unew->info->var->checked),
7048 checkedName (old->info->var->checked)),
7049 uentry_whereDeclared (unew)))
7051 uentry_showWhereSpecified (old);
7055 old->info->var->checked = unew->info->var->checked;
7060 && (old->info->var->checked != CH_UNKNOWN)
7061 && uentry_isReallySpecified (old))
7065 message ("%s %q specified as %s, but declared without %s qualifier",
7066 ekind_capName (unew->ukind),
7067 uentry_getName (unew),
7068 checkedName (old->info->var->checked),
7069 checkedName (old->info->var->checked)),
7070 uentry_whereDeclared (unew)))
7072 uentry_showWhereSpecified (old);
7076 unew->info->var->checked = old->info->var->checked;
7079 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7082 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7084 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7089 llassert (uentry_isVar (u1));
7090 llassert (uentry_isVar (u2));
7092 if (u1->info->var->kind != u2->info->var->kind) {
7093 if (u1->info->var->kind == VKSEFRETPARAM) {
7094 if (u2->info->var->kind == VKRETPARAM) {
7097 message ("Function types are inconsistent. Parameter %d is "
7098 "sef parameter, but non-sef parameter in "
7099 "assigned function: %s",
7100 paramno, exprNode_unparse (e)),
7102 } else if (u2->info->var->kind == VKSEFPARAM) {
7105 message ("Function types are inconsistent. Parameter %d is "
7106 "returns parameter, but non-returns parameter in "
7107 "assigned function: %s",
7108 paramno, exprNode_unparse (e)),
7113 message ("Function types are inconsistent. Parameter %d is "
7114 "sef returns parameter, but non-sef returns parameter in "
7115 "assigned function: %s",
7116 paramno, exprNode_unparse (e)),
7119 } else if (u1->info->var->kind == VKRETPARAM) {
7122 message ("Function types are inconsistent. Parameter %d is "
7123 "returns parameter, but non-returns parameter in "
7124 "assigned function: %s",
7125 paramno, exprNode_unparse (e)),
7127 } else if (u1->info->var->kind == VKSEFPARAM) {
7130 message ("Function types are inconsistent. Parameter %d is "
7131 "sef parameter, but non-sef parameter in "
7132 "assigned function: %s",
7133 paramno, exprNode_unparse (e)),
7136 if (u2->info->var->kind == VKSEFRETPARAM) {
7139 message ("Function types are inconsistent. Parameter %d is "
7140 "normal parameter, but sef returns parameter in "
7141 "assigned function: %s",
7142 paramno, exprNode_unparse (e)),
7144 } else if (u2->info->var->kind == VKSEFPARAM) {
7147 message ("Function types are inconsistent. Parameter %d is "
7148 "normal parameter, but sef parameter in "
7149 "assigned function: %s",
7150 paramno, exprNode_unparse (e)),
7152 } else if (u2->info->var->kind == VKRETPARAM) {
7155 message ("Function types are inconsistent. Parameter %d is "
7156 "normal parameter, but returns parameter in "
7157 "assigned function: %s",
7158 paramno, exprNode_unparse (e)),
7166 if (u1->info->var->defstate != u2->info->var->defstate)
7170 message ("Function types are inconsistent. Parameter %d is "
7171 "%s, but %s in assigned function: %s",
7173 sstate_unparse (u1->info->var->defstate),
7174 sstate_unparse (u2->info->var->defstate),
7175 exprNode_unparse (e)),
7179 if (u1->info->var->nullstate != u2->info->var->nullstate)
7183 message ("Function types are inconsistent. Parameter %d is "
7184 "%s, but %s in assigned function: %s",
7186 nstate_unparse (u1->info->var->nullstate),
7187 nstate_unparse (u2->info->var->nullstate),
7188 exprNode_unparse (e)),
7192 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7196 message ("Function types are inconsistent. Parameter %d is "
7197 "%s, but %s in assigned function: %s",
7199 alkind_unparse (sRef_getAliasKind (u1->sref)),
7200 alkind_unparse (sRef_getAliasKind (u2->sref)),
7201 exprNode_unparse (e)),
7205 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7209 message ("Function types are inconsistent. Parameter %d is "
7210 "%s, but %s in assigned function: %s",
7212 exkind_unparse (sRef_getExKind (u1->sref)),
7213 exkind_unparse (sRef_getExKind (u2->sref)),
7214 exprNode_unparse (e)),
7220 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7221 /*@notnull@*/ uentry unew,
7222 bool mustConform, /*@unused@*/ bool completeConform)
7224 uentryList oldParams = uentry_getParams (old);
7225 uentryList newParams = uentry_getParams (unew);
7226 ctype newType = unew->utype;
7227 ctype oldType = old->utype;
7228 ctype oldRetType = ctype_unknown;
7229 ctype newRetType = ctype_unknown;
7231 if (uentry_isForward (old))
7233 mustConform = FALSE;
7234 uentry_copyInto (old, unew);
7239 ** check return values
7242 if (ctype_isKnown (oldType))
7244 llassert (ctype_isFunction (oldType));
7246 oldRetType = ctype_returnValue (oldType);
7249 if (ctype_isKnown (newType))
7251 llassert (ctype_isFunction (newType));
7253 newRetType = ctype_returnValue (newType);
7256 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
7257 && !ctype_matchDef (newRetType, oldRetType))
7259 if (mustConform) returnValueError (old, unew);
7263 if (ctype_isConj (newRetType))
7265 if (ctype_isConj (oldRetType))
7267 if (!ctype_sameAltTypes (newRetType, oldRetType))
7271 message ("Function %q inconsistently %rdeclared to "
7272 "return alternate types %s "
7273 "(types match, but alternates are not identical, "
7274 "so checking may not be correct)",
7275 uentry_getName (unew),
7276 uentry_isDeclared (old),
7277 ctype_unparse (newRetType)),
7278 uentry_whereDeclared (unew)))
7280 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
7286 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
7291 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7293 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
7295 if (exitkind_isKnown (unew->info->fcn->exitCode))
7299 message ("Function %q inconsistently %rdeclared using %s",
7300 uentry_getName (unew),
7301 uentry_isDeclared (old),
7302 exitkind_unparse (unew->info->fcn->exitCode)),
7303 uentry_whereDeclared (unew)))
7305 uentry_showWhereSpecified (old);
7310 unew->info->fcn->exitCode = old->info->fcn->exitCode;
7314 if (!qual_isUnknown (unew->info->fcn->nullPred))
7316 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
7320 message ("Function %q inconsistently %rdeclared using %s",
7321 uentry_getName (unew),
7322 uentry_isDeclared (old),
7323 qual_unparse (unew->info->fcn->nullPred)),
7324 uentry_whereDeclared (unew)))
7326 uentry_showWhereSpecified (old);
7332 unew->info->fcn->nullPred = old->info->fcn->nullPred;
7335 if (unew->info->fcn->specialCode != SPC_NONE)
7337 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
7341 message ("Function %q inconsistently %rdeclared using %s",
7342 uentry_getName (unew),
7343 uentry_isDeclared (old),
7344 specCode_unparse (unew->info->fcn->specialCode)),
7345 uentry_whereDeclared (unew)))
7347 uentry_showWhereSpecified (old);
7353 unew->info->fcn->specialCode = old->info->fcn->specialCode;
7360 if (!uentryList_sameObject (oldParams, newParams)
7361 && (!uentryList_isMissingParams (oldParams)))
7363 if (!uentryList_isMissingParams (newParams))
7366 int nparams = uentryList_size (oldParams);
7367 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
7369 if (nparams != uentryList_size (newParams))
7371 nargsError (old, unew);
7374 if (uentryList_size (newParams) < nparams)
7376 nparams = uentryList_size (newParams);
7379 while (paramno < nparams)
7381 uentry oldCurrent = uentryList_getN (oldParams, paramno);
7382 uentry newCurrent = uentryList_getN (newParams, paramno);
7383 ctype oldCurrentType = uentry_getType (oldCurrent);
7384 ctype newCurrentType = uentry_getType (newCurrent);
7386 llassert (uentry_isValid (oldCurrent)
7387 && uentry_isValid (newCurrent));
7389 if (!uentry_isElipsisMarker (oldCurrent)
7390 && !uentry_isElipsisMarker (newCurrent))
7392 checkVarConformance (oldCurrent, newCurrent,
7393 mustConform, completeConform);
7398 if (uentry_hasName (oldCurrent)
7399 && uentry_hasName (newCurrent))
7401 cstring oldname = uentry_getName (oldCurrent);
7402 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
7404 cstring nname = uentry_getName (newCurrent);
7407 if (cstring_isDefined (pfx)
7408 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
7410 oname = cstring_suffix (oldname, cstring_length (pfx));
7415 /*@-branchstate@*/ } /*@=branchstate@*/
7417 if (cstring_isDefined (pfx)
7418 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
7420 nnamefix = cstring_suffix (nname, cstring_length (pfx));
7425 /*@-branchstate@*/ } /*@=branchstate@*/
7427 if (!cstring_equal (oname, nnamefix))
7430 (FLG_DECLPARAMMATCH,
7431 message ("Definition parameter name %s does not match "
7432 "name of corresponding parameter in "
7435 uentry_whereLast (newCurrent)))
7437 uentry_showWhereLastPlain (oldCurrent);
7441 cstring_free (oldname);
7442 cstring_free (nname);
7446 if (!ctype_match (oldCurrentType, newCurrentType))
7448 paramTypeError (old, oldCurrent, oldCurrentType,
7449 unew, newCurrent, newCurrentType, paramno);
7453 if (ctype_isMissingParamsMarker (newCurrentType)
7454 || ctype_isElips (newCurrentType)
7455 || ctype_isMissingParamsMarker (oldCurrentType)
7456 || ctype_isElips (oldCurrentType))
7462 if (ctype_isConj (newCurrentType))
7464 if (ctype_isConj (oldCurrentType))
7466 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
7470 message ("Parameter %q inconsistently %rdeclared with "
7471 "alternate types %s "
7472 "(types match, but alternates are not identical, "
7473 "so checking may not be correct)",
7474 uentry_getName (newCurrent),
7475 uentry_isDeclared (oldCurrent),
7476 ctype_unparse (newCurrentType)),
7477 uentry_whereDeclared (unew)))
7479 uentry_showWhereLastVal (oldCurrent,
7480 ctype_unparse (oldCurrentType));
7488 message ("Parameter %q inconsistently %rdeclared with "
7489 "alternate types %s",
7490 uentry_getName (newCurrent),
7491 uentry_isDeclared (oldCurrent),
7492 ctype_unparse (newCurrentType)),
7493 uentry_whereDeclared (unew)))
7495 uentry_showWhereLastVal (oldCurrent,
7496 ctype_unparse (oldCurrentType));
7503 if (ctype_isConj (oldCurrentType))
7505 uentry_setType (newCurrent, oldCurrentType);
7513 ** Forgot this! detected by lclint:
7514 ** uentry.c:1257,15: Suspected infinite loop
7520 if (!uentryList_isMissingParams (newParams))
7522 if (ctype_isConj (oldRetType))
7524 old->utype = ctype_makeFunction (oldRetType,
7525 uentryList_copy (newParams));
7529 old->utype = unew->utype;
7533 checkGlobalsConformance (old, unew, mustConform, completeConform);
7534 checkModifiesConformance (old, unew, mustConform, completeConform);
7536 if (specialClauses_isDefined (unew->info->fcn->specclauses))
7538 if (!specialClauses_isDefined (old->info->fcn->specclauses))
7542 message ("Function %q redeclared using special clauses (can only "
7543 "be used in first declaration)",
7544 uentry_getName (unew)),
7545 uentry_whereDeclared (unew)))
7547 uentry_showWhereLast (old);
7552 specialClauses_checkEqual (old, unew);
7556 if (fileloc_isUndefined (old->whereDeclared))
7558 old->whereDeclared = fileloc_copy (unew->whereDeclared);
7560 else if (fileloc_isUndefined (unew->whereDeclared))
7562 unew->whereDeclared = fileloc_copy (old->whereDeclared);
7571 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
7575 llassert (uentry_isValid (ue));
7576 llassert (uentry_isEitherConstant (ue));
7578 uval = ue->info->uconst->val;
7580 if (multiVal_isDefined (uval))
7582 if (multiVal_isDefined (m))
7584 if (!multiVal_equiv (uval, m))
7588 message ("%s %q defined with inconsistent value: %q",
7589 ekind_capName (ue->ukind),
7590 uentry_getName (ue),
7591 multiVal_unparse (m)),
7594 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
7602 ue->info->uconst->val = m;
7603 multiVal_free (uval);
7608 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7611 bool typeError = FALSE;
7613 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
7615 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
7619 checkStructConformance (old, unew);
7624 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7626 llbug (message ("struct tags: bad types: %t / %t",
7627 old->utype, unew->utype));
7631 else if (uentry_isEnumTag (old))
7633 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
7635 if (mustConform) checkEnumConformance (old, unew);
7639 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7641 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
7642 ctype_unparse (unew->utype)));
7646 else if (!ctype_match (old->utype, unew->utype))
7648 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
7650 ctype realt = ctype_realType (unew->utype);
7652 if (ctype_isRealInt (realt) || ctype_isChar (realt))
7654 unew->utype = ctype_bool;
7660 typeError = optgenerror
7662 message ("%q defined as %s", uentry_getName (old),
7663 ctype_unparse (realt)),
7664 uentry_whereDeclared (unew));
7672 ctype oldr = ctype_realType (old->utype);
7673 ctype newr = ctype_realType (unew->utype);
7675 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
7677 checkStructConformance (old, unew);
7679 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
7681 checkStructConformance (old, unew);
7683 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
7685 checkEnumConformance (old, unew);
7687 else if (uentry_isConstant (old)
7688 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
7690 /* okay...for now! (should check the type is reset later... */
7694 DPRINTF (("YABA!"));
7697 message ("%s %q %rdeclared with inconsistent type: %t",
7698 ekind_capName (unew->ukind),
7699 uentry_getName (unew),
7700 uentry_isDeclared (old),
7702 uentry_whereDeclared (unew)))
7704 uentry_showWhereLast (old);
7720 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
7721 /*@notnull@*/ uentry unew,
7722 bool mustConform, bool completeConform)
7724 if (ctype_isDefined (unew->info->datatype->type))
7727 ** bool is hard coded here, since it is built into LCL.
7728 ** For now, we're stuck with LCL's types.
7731 if (ctype_isDirectBool (old->utype) &&
7732 cstring_equalLit (unew->uname, "bool"))
7734 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
7735 evs 2000-07-25: removed
7737 unew->utype = ctype_bool;
7740 if (ctype_isUnknown (old->info->datatype->type))
7742 old->info->datatype->type = unew->info->datatype->type;
7746 DPRINTF (("Old: %s / New: %s",
7747 uentry_unparseFull (old),
7748 uentry_unparseFull (unew)));
7749 DPRINTF (("Types: %s / %s",
7750 ctype_unparse (old->info->datatype->type),
7751 ctype_unparse (unew->info->datatype->type)));
7753 if (ctype_matchDef (old->info->datatype->type,
7754 unew->info->datatype->type))
7763 ("Type %q %s with inconsistent type: %t",
7764 uentry_getName (unew),
7765 uentry_reDefDecl (old, unew),
7766 unew->info->datatype->type),
7767 uentry_whereDeclared (unew)))
7769 uentry_showWhereLastExtra
7770 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
7773 old->info->datatype->type = unew->info->datatype->type;
7778 if (unew->info->datatype->abs != MAYBE)
7780 if (ynm_isOff (old->info->datatype->abs)
7781 && ynm_isOn (unew->info->datatype->abs))
7783 if (!ctype_isDirectBool (old->utype))
7788 ("Datatype %q inconsistently %rdeclared as abstract type",
7789 uentry_getName (unew),
7790 uentry_isDeclared (old)),
7791 uentry_whereDeclared (unew)))
7793 uentry_showWhereLastPlain (old);
7797 else if (ynm_isOn (old->info->datatype->abs)
7798 && ynm_isOff (unew->info->datatype->abs))
7800 if (!ctype_isDirectBool (old->utype))
7805 ("Datatype %q inconsistently %rdeclared as concrete type",
7806 uentry_getName (unew),
7807 uentry_isDeclared (old)),
7808 uentry_whereDeclared (unew)))
7810 uentry_showWhereLastPlain (old);
7821 if (ynm_isOn (old->info->datatype->abs))
7823 old->sref = unew->sref;
7824 unew->info->datatype->mut = old->info->datatype->mut;
7827 && uentry_isReallySpecified (old))
7832 ("Datatype %q specified as abstract, "
7833 "but abstract annotation not used in declaration",
7834 uentry_getName (unew)),
7835 uentry_whereDeclared (unew)))
7837 uentry_showWhereLastPlain (old);
7843 unew->info->datatype->abs = old->info->datatype->abs;
7845 if (ynm_isMaybe (unew->info->datatype->mut))
7847 if (completeConform && ynm_isOff (old->info->datatype->mut)
7848 && uentry_isReallySpecified (old))
7853 ("Datatype %q specified as immutable, "
7854 "but immutable annotation not used in declaration",
7855 uentry_getName (unew)),
7856 uentry_whereDeclared (unew)))
7858 uentry_showWhereLastPlain (old);
7862 unew->info->datatype->mut = old->info->datatype->mut;
7864 else if (ynm_isMaybe (old->info->datatype->mut))
7866 old->info->datatype->mut = unew->info->datatype->mut;
7870 if (ynm_isOn (old->info->datatype->abs))
7872 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
7876 message ("Datatype %q inconsistently %rdeclared as immutable",
7877 uentry_getName (unew),
7878 uentry_isDeclared (old)),
7879 uentry_whereDeclared (unew)))
7881 uentry_showWhereLastPlain (old);
7886 if (ynm_isOff (old->info->datatype->mut)
7887 && ynm_isOn (unew->info->datatype->mut))
7891 message ("Datatype %q inconsistently %rdeclared as mutable",
7892 uentry_getName (unew),
7893 uentry_isDeclared (old)),
7894 uentry_whereDeclared (unew)))
7896 uentry_showWhereLastPlain (old);
7901 old->info->datatype->mut = unew->info->datatype->mut;
7904 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7908 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
7909 /*@notnull@*/ uentry unew,
7911 /*@unused@*/ bool completeConform)
7913 multiVal oldVal = old->info->uconst->val;
7914 multiVal newVal = unew->info->uconst->val;
7916 if (multiVal_isDefined (oldVal))
7918 if (multiVal_isDefined (newVal))
7920 if (!multiVal_equiv (oldVal, newVal))
7925 message ("%s %q %rdeclared with inconsistent value: %q",
7926 ekind_capName (unew->ukind),
7927 uentry_getName (unew),
7928 uentry_isDeclared (old),
7929 multiVal_unparse (newVal)),
7930 uentry_whereDeclared (unew)))
7932 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
7936 unew->info->uconst->val = multiVal_copy (oldVal);
7937 multiVal_free (newVal);
7946 old->info->uconst->val = multiVal_copy (newVal);
7951 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7952 /*@notnull@*/ uentry unew, bool mustConform,
7953 bool completeConform)
7955 bool typeError = FALSE;
7956 bool fcnConformance = FALSE;
7958 if (!ekind_equal (unew->ukind, old->ukind))
7961 ** okay, only if one is a function and the other is
7962 ** a variable of type function.
7965 if (unew->ukind == KENUMCONST
7966 && old->ukind == KCONST)
7968 old->ukind = KENUMCONST;
7972 if (unew->ukind == KFCN
7973 && old->ukind == KCONST
7974 && ctype_isUnknown (old->utype))
7977 ** When a function is defined with an unparam macro
7980 uentry_copyInto (old, unew);
7984 if (uentry_isExpandedMacro (old)
7985 && uentry_isEitherConstant (unew))
7987 uentry_copyInto (old, unew);
7991 if (uentry_isEndIter (unew))
7993 if (ctype_isUnknown (old->utype))
7995 if (!uentry_isSpecified (old)
7996 && uentry_isCodeDefined (unew))
7998 if (!fileloc_withinLines (uentry_whereDefined (old),
7999 uentry_whereDeclared (unew), 2))
8000 { /* bogus! will give errors if there is too much whitespace */
8004 ("Iterator finalized name %q does not match name in "
8005 "previous iter declaration (should be end_%q). This iter "
8006 "is declared at %q",
8007 uentry_getName (unew),
8008 uentry_getName (old),
8009 fileloc_unparse (uentry_whereDefined (old))),
8010 uentry_whereDeclared (old));
8014 uentry_copyInto (old, unew);
8019 KindConformanceError (old, unew, mustConform);
8023 if (uentry_isFunction (unew))
8025 if (uentry_isVariable (old))
8027 if (!ctype_isUnknown (old->utype))
8029 if (ctype_isFunction (old->utype))
8031 uentry_makeVarFunction (old);
8032 checkFunctionConformance (old, unew, mustConform,
8034 fcnConformance = TRUE;
8038 KindConformanceError (old, unew, mustConform);
8043 if (uentry_isExpandedMacro (old))
8045 if (fileloc_isUndefined (unew->whereDefined))
8047 unew->whereDefined = fileloc_update (unew->whereDefined,
8051 uentry_copyInto (old, unew);
8052 old->used = unew->used = TRUE;
8057 /* undeclared identifier */
8058 old->utype = unew->utype;
8059 uentry_makeVarFunction (old);
8060 checkFunctionConformance (old, unew, FALSE, FALSE);
8061 fcnConformance = TRUE;
8067 KindConformanceError (old, unew, mustConform);
8070 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8072 if (!ctype_isUnknown (unew->utype))
8074 if (ctype_isFunction (unew->utype))
8076 uentry_makeVarFunction (unew);
8077 checkFunctionConformance (old, unew, mustConform, completeConform);
8078 fcnConformance = TRUE;
8082 KindConformanceError (old, unew, mustConform);
8087 KindConformanceError (old, unew, mustConform);
8092 KindConformanceError (old, unew, mustConform);
8098 ** check parameter lists for functions
8099 ** (before type errors, to get better messages
8102 if (uentry_isFunction (old))
8104 checkFunctionConformance (old, unew, mustConform, completeConform);
8105 fcnConformance = TRUE;
8109 if (!ctype_isUndefined (old->utype))
8111 typeError = checkTypeConformance (old, unew, mustConform);
8118 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8120 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8123 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8125 DPRINTF (("Check datatype: %s / %s",
8126 uentry_unparseFull (old),
8127 uentry_unparseFull (unew)));
8129 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8132 if (uentry_isVariable (old) && uentry_isVariable (unew))
8135 !ctype_matchDef (old->utype, unew->utype))
8140 ("Variable %q %s with inconsistent type (arrays and pointers are "
8141 "not identical in variable declarations): %t",
8142 uentry_getName (unew),
8143 uentry_reDefDecl (old, unew),
8145 uentry_whereDeclared (unew)))
8147 uentry_showWhereLast (old);
8150 ** Avoid repeated errors.
8153 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8155 old->whereDefined = fileloc_update (old->whereDefined,
8163 checkVarConformance (old, unew, mustConform, completeConform);
8168 /* old->utype = unew->utype; */
8172 if (ctype_isConj (old->utype))
8174 if (ctype_isConj (unew->utype))
8176 if (!ctype_sameAltTypes (old->utype, unew->utype))
8180 message ("%s %q inconsistently %rdeclared with "
8181 "alternate types %s "
8182 "(types match, but alternates are not identical, "
8183 "so checking may not be correct)",
8184 ekind_capName (uentry_getKind (old)),
8185 uentry_getName (unew),
8186 uentry_isDeclared (old),
8187 ctype_unparse (unew->utype)),
8188 uentry_whereDeclared (unew)))
8190 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
8194 old->utype = unew->utype;
8201 if (ctype_isUnknown (old->utype))
8203 old->utype = unew->utype;
8208 if (unew->ukind == old->ukind)
8211 unew->info = uinfo_copy (old->info, old->ukind);
8214 sRef_storeState (old->sref);
8215 sRef_storeState (unew->sref);
8219 ** modifies spec to reflect def, reports any inconsistencies
8223 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
8225 llassert (uentry_isValid (spec));
8226 llassert (uentry_isValid (def));
8227 llassert (cstring_equal (spec->uname, def->uname));
8229 uentry_checkConformance (spec, def, TRUE,
8230 context_getFlag (FLG_NEEDSPEC));
8232 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
8235 ** okay, declarations conform. Propagate extra information.
8238 uentry_setDefined (spec, uentry_whereDefined (def));
8239 uentry_setDeclared (spec, uentry_whereDeclared (def));
8241 if (uentry_isStatic (def))
8245 message ("%s %q specified, but declared as static",
8246 ekind_capName (def->ukind),
8247 uentry_getName (def)),
8248 uentry_whereDeclared (def)))
8250 uentry_showWhereSpecified (spec);
8255 spec->storageclass = def->storageclass;
8258 sRef_storeState (spec->sref);
8260 spec->used = def->used || spec->used;
8261 spec->hasNameError |= def->hasNameError;
8265 if (!spec->hasNameError)
8267 uentry_checkName (spec);
8276 ** Can't generate function redeclaration errors when the
8277 ** entries are merged, since we don't yet know if its the
8278 ** definition of the function.
8282 uentry_clearDecl (void)
8284 posRedeclared = uentry_undefined;
8285 fileloc_free (posLoc);
8286 posLoc = fileloc_undefined;
8290 uentry_checkDecl (void)
8292 if (uentry_isValid (posRedeclared))
8294 llassert (fileloc_isDefined (posLoc));
8296 if (uentry_isCodeDefined (posRedeclared))
8298 if (optgenerror (FLG_REDECL,
8299 message ("%s %q declared after definition",
8300 ekind_capName (posRedeclared->ukind),
8301 uentry_getName (posRedeclared)),
8304 llgenindentmsg (message ("Definition of %q",
8305 uentry_getName (posRedeclared)),
8306 posRedeclared->whereDeclared);
8311 if (optgenerror (FLG_REDECL,
8312 message ("%s %q declared more than once",
8313 ekind_capName (posRedeclared->ukind),
8314 uentry_getName (posRedeclared)),
8317 llgenindentmsg (message ("Previous declaration of %q",
8318 uentry_getName (posRedeclared)),
8319 posRedeclared->whereDeclared);
8324 fileloc_free (posLoc);
8325 posLoc = fileloc_undefined;
8326 posRedeclared = uentry_undefined;
8330 ** Redefinition of old as unew.
8331 ** modifies old to reflect unew, reports any inconsistencies
8335 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
8337 fileloc olddef = uentry_whereDeclared (old);
8338 fileloc unewdef = uentry_whereDeclared (unew);
8342 if (uentry_isExtern (unew))
8344 uentry_setUsed (old, unewdef);
8348 fileloc_isUndefined (olddef)
8349 && fileloc_isDefined (uentry_whereDefined (old))
8350 && !uentry_isExpandedMacro (old);
8352 if (!context_getFlag (FLG_INCONDEFSLIB)
8353 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8355 mustConform = FALSE;
8362 llassert (uentry_isValid (old));
8363 llassert (uentry_isValid (unew));
8364 llassert (cstring_equal (old->uname, unew->uname));
8367 ** should check old one was extern!
8370 if (uentry_isStatic (old))
8372 if (!(uentry_isStatic (unew)))
8376 message ("%s %q shadows static declaration",
8377 ekind_capName (unew->ukind),
8378 uentry_getName (unew)),
8381 uentry_showWhereLast (old);
8386 uentry_setDeclDef (old, unewdef);
8389 else if (uentry_isStatic (unew))
8391 uentry_setDeclDef (old, unewdef);
8393 else if (uentry_isExtern (old))
8395 uentry_setDeclared (old, unewdef);
8399 if (!uentry_isExtern (unew) && !uentry_isForward (old)
8400 && !fileloc_equal (olddef, unewdef)
8401 && !fileloc_isUndefined (olddef)
8402 && !fileloc_isUndefined (unewdef)
8403 && !fileloc_isBuiltin (olddef)
8404 && !fileloc_isBuiltin (unewdef)
8405 && !uentry_isYield (old)
8406 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8408 if (uentry_isVariable (old) || uentry_isVariable (unew))
8410 ; /* will report redeclaration error later */
8414 if (fileloc_isDefined (uentry_whereDefined (old)))
8418 message ("%s %q defined more than once",
8419 ekind_capName (unew->ukind),
8420 uentry_getName (unew)),
8421 uentry_whereLast (unew)))
8424 (message ("Previous definition of %q",
8425 uentry_getName (old)),
8426 uentry_whereLast (old));
8429 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
8431 uentry_copyInto (old, unew);
8432 old->sref = sRef_saveCopy (old->sref);
8440 if (fileloc_isLib (olddef)
8441 || fileloc_isUndefined (olddef)
8442 || fileloc_isImport (olddef))
8444 if (uentry_isExtern (unew))
8446 if (uentry_isExtern (old)
8447 || (fileloc_isDefined (uentry_whereDeclared (old))
8448 && (!fileloc_equal (uentry_whereDeclared (old),
8449 uentry_whereDefined (old)))))
8453 message ("%s %q declared more than once",
8454 ekind_capName (unew->ukind),
8455 uentry_getName (unew)),
8456 unew->whereDeclared))
8459 (message ("Previous declaration of %q",
8460 uentry_getName (old)),
8461 old->whereDeclared);
8465 uentry_setExtern (old);
8469 uentry_setDefined (old, unewdef);
8475 uentry_checkConformance (old, unew, mustConform, FALSE);
8477 old->used = old->used || unew->used;
8478 old->uses = filelocList_append (old->uses, unew->uses);
8479 unew->uses = filelocList_undefined;
8481 sRef_storeState (old->sref);
8482 sRef_storeState (unew->sref);
8486 old->whereDefined = fileloc_update (old->whereDefined,
8491 ** No redeclaration errors for functions here, since we
8492 ** don't know if this is the definition of the function.
8495 if (fileloc_isUser (old->whereDeclared)
8496 && fileloc_isUser (unew->whereDeclared)
8497 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
8498 && !fileloc_isDefined (unew->whereDefined))
8500 if (uentry_isFunction (old))
8502 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
8503 posLoc = fileloc_update (posLoc, unew->whereDeclared);
8507 if (optgenerror (FLG_REDECL,
8508 message ("%s %q declared more than once",
8509 ekind_capName (unew->ukind),
8510 uentry_getName (unew)),
8511 unew->whereDeclared))
8513 llgenindentmsg (message ("Previous declaration of %q",
8514 uentry_getName (old)),
8515 old->whereDeclared);
8520 if (fileloc_isUndefined (old->whereDefined))
8522 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
8526 if (!context_processingMacros ()
8527 && fileloc_isUser (old->whereDefined)
8528 && fileloc_isUser (unew->whereDefined)
8529 && !fileloc_equal (old->whereDefined, unew->whereDefined))
8531 if (uentry_isVariable (unew) || uentry_isFunction (unew))
8533 if (uentry_isVariable (unew)
8534 && uentry_isExtern (unew))
8536 if (optgenerror (FLG_REDECL,
8537 message ("%s %q declared after definition",
8538 ekind_capName (unew->ukind),
8539 uentry_getName (unew)),
8540 unew->whereDeclared))
8542 llgenindentmsg (message ("Definition of %q",
8543 uentry_getName (old)),
8549 if (optgenerror (FLG_REDEF,
8550 message ("%s %q redefined",
8551 ekind_capName (unew->ukind),
8552 uentry_getName (unew)),
8553 unew->whereDefined))
8555 llgenindentmsg (message ("Previous definition of %q",
8556 uentry_getName (old)),
8564 if (uentry_isExternal (unew))
8566 old->whereDefined = fileloc_createExternal ();
8569 if (unew->hasNameError)
8571 old->hasNameError = TRUE;
8576 if (!old->hasNameError)
8578 uentry_checkName (old);
8581 llassert (!ctype_isUndefined (old->utype));
8585 uentry_copyState (uentry res, uentry other)
8587 llassert (uentry_isValid (res));
8588 llassert (uentry_isValid (other));
8590 res->used = other->used;
8592 res->info->var->kind = other->info->var->kind;
8593 res->info->var->defstate = other->info->var->defstate;
8594 res->info->var->nullstate = other->info->var->nullstate;
8595 res->info->var->checked = other->info->var->checked;
8597 sRef_copyState (res->sref, other->sref);
8601 uentry_sameKind (uentry u1, uentry u2)
8603 if (uentry_isValid (u1) && uentry_isValid (u2))
8605 if (uentry_isVar (u1) && uentry_isVar (u2))
8607 ctype c1 = u1->utype;
8608 ctype c2 = u2->utype;
8610 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
8613 ** both functions, or both not functions
8616 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
8620 return ((u1->ukind == u2->ukind));
8627 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
8629 llassert (uentry_isValid (unew));
8630 llassert (uentry_isValid (old));
8632 unew->ukind = old->ukind;
8633 unew->uname = cstring_copy (old->uname);
8634 unew->utype = old->utype;
8636 unew->whereSpecified = fileloc_copy (old->whereSpecified);
8637 unew->whereDefined = fileloc_copy (old->whereDefined);
8638 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8640 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
8641 unew->used = old->used;
8643 unew->isPrivate = old->isPrivate;
8644 unew->hasNameError = old->hasNameError;
8645 unew->uses = filelocList_undefined;
8647 unew->storageclass = old->storageclass;
8648 unew->info = uinfo_copy (old->info, old->ukind);
8653 uentry_copy (uentry e)
8655 if (uentry_isValid (e))
8657 uentry enew = uentry_alloc ();
8658 DPRINTF (("copy: %s", uentry_unparseFull (e)));
8659 uentry_copyInto (enew, e);
8660 DPRINTF (("Here we are..."));
8661 DPRINTF (("original: %s", uentry_unparseFull (e)));
8662 DPRINTF (("copy: %s", uentry_unparse (enew)));
8663 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
8668 return uentry_undefined;
8673 uentry_setState (uentry res, uentry other)
8675 llassert (uentry_isValid (res));
8676 llassert (uentry_isValid (other));
8678 llassert (res->ukind == other->ukind);
8679 llassert (res->ukind == KVAR);
8681 res->sref = sRef_saveCopy (other->sref);
8682 res->used = other->used;
8683 filelocList_free (res->uses);
8684 res->uses = other->uses;
8685 other->uses = filelocList_undefined;
8686 res->lset = other->lset;
8690 uentry_mergeUses (uentry res, uentry other)
8692 llassert (uentry_isValid (res));
8693 llassert (uentry_isValid (other));
8695 res->used = other->used || res->used;
8696 res->lset = other->lset || res->lset;
8697 res->uses = filelocList_append (res->uses, other->uses);
8698 other->uses = filelocList_undefined;
8703 ** This is a really ugly routine.
8705 ** gack...fix this one day.
8710 ** >> res is the false branch, other is the true branch (or continuation)
8712 ** >> res is the true branch, other is the false branch (or continutation)
8719 ** References not effected by res are propagated from other.
8723 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
8724 bool flip, clause cl, fileloc loc)
8728 message ("%s %q is %s %s, but %s %s.",
8729 ekind_capName (res->ukind), uentry_getName (res),
8730 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
8731 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
8734 if (sRef_isDead (res->sref))
8736 sRef_showStateInfo (res->sref);
8738 else if (sRef_isKept (res->sref))
8740 sRef_showAliasInfo (res->sref);
8742 else /* dependent */
8744 sRef_showAliasInfo (res->sref);
8745 sRef_showAliasInfo (other->sref);
8748 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8752 static bool incompatibleStates (sRef rs, sRef os)
8754 alkind rk = sRef_getAliasKind (rs);
8755 alkind ok = sRef_getAliasKind (os);
8757 if (alkind_isError (rk) || alkind_isError (ok))
8763 return ((sRef_isDead (rs)
8764 || (alkind_isKept (rk) && !alkind_isKept (ok))
8765 || (alkind_isDependent (rk)
8766 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
8767 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
8772 branchStateAltError (/*@notnull@*/ uentry res,
8773 /*@notnull@*/ uentry other, bool flip,
8774 clause cl, fileloc loc)
8778 message ("%s %q is %s %s, but %s %s.",
8779 ekind_capName (res->ukind), uentry_getName (res),
8780 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
8781 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
8784 if (sRef_isDead (other->sref))
8786 sRef_showStateInfo (other->sref);
8790 sRef_showAliasInfo (other->sref);
8793 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8794 sRef_setDefinedComplete (res->sref, fileloc_undefined);
8796 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
8797 sRef_setDefinedComplete (other->sref, fileloc_undefined);
8801 static bool notNull (sRef sr, bool flip)
8803 return (!sRef_definitelyNull (sr)
8804 && !(sRef_isKept (sr))
8805 && !(sRef_isDependent (sr))
8806 && !(flip ? usymtab_isProbableDeepNull (sr)
8807 : usymtab_isAltProbablyDeepNull (sr)));
8811 uentry_mergeState (uentry res, uentry other, fileloc loc,
8812 bool mustReturn, bool flip, bool opt,
8815 llassert (uentry_isValid (res));
8816 llassert (uentry_isValid (other));
8818 llassert (res->ukind == other->ukind);
8819 llassert (res->ukind == KVAR);
8821 DPRINTF (("Merge state: %s / %s",
8822 uentry_unparse (res),
8823 uentry_unparse (other)));
8825 if (sRef_isValid (res->sref))
8829 if (incompatibleStates (res->sref, other->sref))
8831 if (sRef_isThroughArrayFetch (res->sref)
8832 && !context_getFlag (FLG_STRICTBRANCHSTATE))
8834 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
8836 sRef_maybeKill (res->sref, loc);
8838 else if (sRef_isPossiblyDead (other->sref))
8840 sRef_maybeKill (res->sref, loc);
8849 if (notNull (other->sref, flip))
8851 if (sRef_isLocalParamVar (res->sref)
8852 && (sRef_isLocalState (other->sref)
8853 || sRef_isDependent (other->sref)))
8855 if (sRef_isDependent (res->sref))
8857 sRef_setDependent (other->sref, loc);
8861 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8866 branchStateError (res, other, flip, cl, loc);
8871 if (sRef_isKept (res->sref))
8873 sRef_setKept (other->sref, loc);
8878 if (incompatibleStates (other->sref, res->sref))
8880 if (notNull (res->sref, !flip))
8882 if (sRef_isLocalParamVar (res->sref)
8883 && (sRef_isDependent (res->sref)
8884 || sRef_isLocalState (res->sref)))
8886 if (sRef_isDependent (other->sref))
8888 sRef_setDependent (res->sref, loc);
8892 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8897 if (sRef_isParam (other->sref))
8900 ** If the local variable associated
8901 ** with the param has the correct state,
8903 ** (e.g., free (s); s = new(); ...
8906 uentry uvar = usymtab_lookupSafe (other->uname);
8908 if (uentry_isValid (uvar)
8909 && ((sRef_isDead (other->sref)
8910 && sRef_isOnly (uvar->sref))
8911 || (sRef_isDependent (other->sref)
8912 && sRef_isOwned (uvar->sref))))
8918 branchStateAltError (res, other,
8924 branchStateAltError (res, other,
8931 if (sRef_isKept (other->sref))
8933 sRef_setKept (res->sref, loc);
8939 DPRINTF (("Merge opt..."));
8940 sRef_mergeOptState (res->sref, other->sref, cl, loc);
8941 DPRINTF (("Done!"));
8945 sRef_mergeState (res->sref, other->sref, cl, loc);
8950 if (sRef_isModified (other->sref))
8952 sRef_setModified (res->sref);
8956 if (cl == DOWHILECLAUSE)
8958 res->used = other->used || res->used;
8959 res->lset = other->lset || res->lset;
8960 res->uses = filelocList_append (res->uses, other->uses);
8961 other->uses = filelocList_undefined;
8965 if (sRef_isMacroParamRef (res->sref)
8966 && !uentry_isSefParam (other)
8967 && !uentry_isSefParam (res))
8969 bool hasError = FALSE;
8971 if (bool_equal (res->used, other->used))
8973 res->used = other->used;
8977 if (other->used && !flip)
8982 message ("Macro parameter %q used in true clause, "
8983 "but not in false clause",
8984 uentry_getName (res)),
8985 uentry_whereDeclared (res));
8992 message ("Macro parameter %q used in false clause, "
8993 "but not in true clause",
8994 uentry_getName (res)),
8995 uentry_whereDeclared (res));
9001 /* make it sef now, prevent more errors */
9002 res->info->var->kind = VKREFSEFPARAM;
9008 res->used = other->used || res->used;
9009 res->lset = other->lset || res->lset;
9010 res->uses = filelocList_append (res->uses, other->uses);
9011 other->uses = filelocList_undefined;
9017 void uentry_setUsed (uentry e, fileloc loc)
9019 static bool firstTime = TRUE;
9020 static bool showUses = FALSE;
9021 static bool exportLocal = FALSE;
9025 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
9027 showUses = context_getFlag (FLG_SHOWUSES);
9028 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
9033 if (uentry_isValid (e))
9037 if (sRef_isMacroParamRef (e->sref))
9039 if (uentry_isYield (e) || uentry_isSefParam (e))
9045 if (context_inConditional ())
9049 message ("Macro parameter %q used in conditionally "
9050 "executed code (may or may not be "
9051 "evaluated exactly once)",
9052 uentry_getName (e)),
9055 e->info->var->kind = VKREFSEFPARAM;
9064 message ("Macro parameter %q used more than once",
9065 uentry_getName (e)),
9066 uentry_whereDeclared (e)))
9068 e->info->var->kind = VKREFSEFPARAM;
9075 if ((dp = uentry_directParamNo (e)) >= 0)
9077 uentry_setUsed (usymtab_getParam (dp), loc);
9082 if (!sRef_isLocalVar (e->sref))
9086 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
9092 if (context_inMacro ())
9094 e->uses = filelocList_addUndefined (e->uses);
9098 e->uses = filelocList_addDifferentFile
9100 uentry_whereDeclared (e),
9109 bool uentry_isReturned (uentry u)
9111 return (uentry_isValid (u) && uentry_isVar (u)
9112 && (u->info->var->kind == VKRETPARAM
9113 || u->info->var->kind == VKSEFRETPARAM));
9116 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
9118 llassert (uentry_isRealFunction (u));
9120 if (ctype_isFunction (u->utype)
9121 && sRef_isStateSpecial (uentry_getSref (u)))
9123 specialClauses clauses = uentry_getSpecialClauses (u);
9124 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9126 sRef_setAllocated (res, g_currentloc);
9128 specialClauses_postElements (clauses, cl)
9130 sRefSet refs = specialClause_getRefs (cl);
9131 sRefMod modf = specialClause_getEffectFunction (cl);
9133 sRefSet_elements (refs, el)
9135 sRef base = sRef_getRootBase (el);
9137 if (sRef_isResult (base))
9141 sRef sr = sRef_fixBase (el, res);
9142 modf (sr, g_currentloc);
9149 } end_sRefSet_elements ;
9151 } end_specialClauses_postElements ;
9159 sRefSet prefs = sRefSet_new ();
9160 sRef res = sRef_undefined;
9163 params = uentry_getParams (u);
9165 uentryList_elements (params, current)
9167 if (uentry_isReturned (current))
9169 if (exprNodeList_size (args) >= paramno)
9171 exprNode ecur = exprNodeList_nth (args, paramno);
9172 sRef tref = exprNode_getSref (ecur);
9174 if (sRef_isValid (tref))
9176 sRef tcref = sRef_copy (tref);
9178 if (sRef_isDead (tcref))
9180 sRef_setDefined (tcref, g_currentloc);
9181 sRef_setOnly (tcref, g_currentloc);
9184 if (sRef_isRefCounted (tcref))
9186 /* could be a new ref now (but only if its returned) */
9187 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
9190 sRef_makeSafe (tcref);
9192 prefs = sRefSet_insert (prefs, tcref);
9198 } end_uentryList_elements ;
9200 if (sRefSet_size (prefs) > 0)
9202 nstate n = sRef_getNullState (u->sref);
9204 if (sRefSet_size (prefs) == 1)
9206 res = sRefSet_choose (prefs);
9210 res = sRefSet_mergeIntoOne (prefs);
9213 if (nstate_isKnown (n))
9215 sRef_setNullState (res, n, g_currentloc);
9220 if (ctype_isFunction (u->utype))
9222 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9226 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
9229 if (sRef_isRefCounted (res))
9231 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9235 if (sRef_getNullState (res) == NS_ABSNULL)
9237 ctype ct = ctype_realType (u->utype);
9239 if (ctype_isAbstract (ct))
9241 sRef_setNotNull (res, g_currentloc);
9245 if (ctype_isUser (ct))
9247 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
9251 sRef_setNotNull (res, g_currentloc);
9256 if (sRef_isRefCounted (res))
9258 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9260 else if (sRef_isKillRef (res))
9262 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
9269 ak = sRef_getAliasKind (res);
9271 if (alkind_isImplicit (ak))
9273 sRef_setAliasKind (res,
9274 alkind_fixImplicit (ak),
9278 sRefSet_free (prefs);
9284 static bool uentry_isRefCounted (uentry ue)
9286 ctype ct = uentry_getType (ue);
9288 if (ctype_isFunction (ct))
9290 return (ctype_isRefCounted (ctype_returnValue (ct)));
9294 return (ctype_isRefCounted (ct));
9299 ** old was declared yield in the specification.
9300 ** new is declared in the iter implementation.
9303 void uentry_checkYieldParam (uentry old, uentry unew)
9307 llassert (uentry_isVariable (old));
9308 llassert (uentry_isVariable (unew));
9310 unew->info->var->kind = VKYIELDPARAM;
9311 (void) checkTypeConformance (old, unew, TRUE);
9312 checkVarConformance (old, unew, TRUE, FALSE);
9314 /* get rid of param marker */
9316 name = uentry_getName (unew);
9317 cstring_free (unew->uname);
9319 unew->info->var->kind = VKREFYIELDPARAM;
9321 uentry_setUsed (old, fileloc_undefined);
9322 uentry_setUsed (unew, fileloc_undefined);
9325 /*@observer@*/ cstring
9326 uentry_ekindName (uentry ue)
9328 if (uentry_isValid (ue))
9333 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
9335 return cstring_makeLiteralTemp ("Datatype");
9337 return cstring_makeLiteralTemp ("Enum member");
9339 return cstring_makeLiteralTemp ("Constant");
9341 if (uentry_isParam (ue))
9343 return cstring_makeLiteralTemp ("Parameter");
9345 else if (uentry_isExpandedMacro (ue))
9347 return cstring_makeLiteralTemp ("Expanded macro");
9351 return cstring_makeLiteralTemp ("Variable");
9354 return cstring_makeLiteralTemp ("Function");
9356 return cstring_makeLiteralTemp ("Iterator");
9358 return cstring_makeLiteralTemp ("Iterator finalizer");
9360 return cstring_makeLiteralTemp ("Struct tag");
9362 return cstring_makeLiteralTemp ("Union tag");
9364 return cstring_makeLiteralTemp ("Enum tag");
9366 return cstring_makeLiteralTemp ("Optional parameters");
9371 return cstring_makeLiteralTemp ("<Undefined>");
9377 void uentry_setHasNameError (uentry ue)
9379 llassert (uentry_isValid (ue));
9381 ue->hasNameError = TRUE;
9384 void uentry_checkName (uentry ue)
9386 if (uentry_isValid (ue)
9387 && !uentry_isElipsisMarker (ue)
9388 && context_getFlag (FLG_NAMECHECKS)
9389 && !ue->hasNameError
9390 && !uentry_isEndIter (ue)
9391 && !fileloc_isBuiltin (uentry_whereLast (ue))
9392 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
9395 if (uentry_isPriv (ue))
9397 ; /* any checks here? */
9399 else if (fileloc_isExternal (uentry_whereDefined (ue)))
9401 ; /* no errors for externals */
9407 if (uentry_isExpandedMacro (ue))
9413 if (uentry_isExpandedMacro (ue))
9417 else if (uentry_isVariable (ue))
9419 sRef sr = uentry_getSref (ue);
9421 if (sRef_isValid (sr))
9423 scope = sRef_getScope (sr);
9430 else if (uentry_isFunction (ue)
9431 || uentry_isIter (ue)
9432 || uentry_isEndIter (ue)
9433 || uentry_isConstant (ue))
9435 scope = uentry_isStatic (ue) ? fileScope : globScope;
9437 else /* datatypes, etc. must be global */
9442 usymtab_checkDistinctName (ue, scope);
9445 if (context_getFlag (FLG_CPPNAMES))
9447 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
9449 uentry_setHasNameError (ue);
9453 if (scope == globScope)
9455 checkGlobalName (ue);
9457 if (context_getFlag (FLG_ANSIRESERVED))
9459 if (uentry_hasName (ue)
9460 && !uentry_isAnyTag (ue))
9462 if (checkAnsiName (uentry_rawName (ue),
9463 uentry_whereLast (ue)))
9465 uentry_setHasNameError (ue);
9472 checkLocalName (ue);
9474 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
9476 if (uentry_hasName (ue)
9477 && !uentry_isAnyTag (ue))
9479 if (checkAnsiName (uentry_rawName (ue),
9480 uentry_whereLast (ue)))
9482 uentry_setHasNameError (ue);
9488 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
9494 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
9500 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
9501 if (!context_inMacro ())
9503 sRef_setGlobalScopeSafe ();
9506 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
9507 uentry_setUsed (ue, loc);
9509 tloc = fileloc_createExternal ();
9510 uentry_setDefined (ue, tloc);
9511 fileloc_free (tloc);
9512 uentry_setHasNameError (ue);
9514 if (context_getFlag (FLG_REPEATUNRECOG))
9516 uentry_markOwned (ue);
9520 ue = usymtab_supReturnFileEntry (ue);
9523 if (!context_inMacro ())
9525 sRef_clearGlobalScopeSafe ();
9531 /* new start modifications */
9533 void uentry_testInRange (uentry p_e, uentry cconstant) {
9534 if( uentry_isValid(p_e) ) {
9535 if( p_e->sref != NULL) {
9536 char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
9537 int index = atoi( t );
9539 usymtab_testInRange (p_e->sref, index);
9544 void uentry_setStringLength (uentry p_e, uentry cconstant) {
9545 if( uentry_isValid(p_e) ) {
9546 if( p_e->info != NULL) {
9547 if( p_e->info->var != NULL) {
9548 char *t = cstring_toCharsSafe (uentry_unparse(cconstant));
9549 int length = atoi( t );
9551 p_e->info->var->bufinfo->len = length;
9552 p_e->sref->bufinfo.len = length;
9553 printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size);
9560 void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
9561 if( uentry_isValid(p_e) ) {
9562 if( p_e->info != NULL) {
9563 if( p_e->info->var != NULL) {
9564 int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
9565 p_e->info->var->bufinfo->size = size;
9566 p_e->sref->bufinfo.size = size;
9567 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
9568 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
9569 // fprintf(stderr, "and %d\n", size );
9577 /* start modifications */
9579 requires: p_e is defined, is a ptr/array variable
9581 effects: sets the state of the variable
9584 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
9585 if( uentry_isValid(p_e) ) {
9586 if( p_e->info != NULL) {
9587 if( p_e->info->var != NULL) {
9588 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
9589 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9595 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
9599 requires: p_e is defined, is a ptr/array variable
9601 effects: sets the size of the buffer
9604 void uentry_setNullTerminatedState (uentry p_e) {
9605 if( uentry_isValid(p_e) ) {
9606 if( p_e->info != NULL) {
9607 if( p_e->info->var != NULL) {
9608 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
9609 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
9615 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
9620 requires: p_e is defined, is a ptr/array variable
9622 effects: sets the state of the variable
9625 void uentry_setNotNullTerminatedState (uentry p_e) {
9626 if( uentry_isValid(p_e) ) {
9627 if( p_e->info != NULL) {
9628 if( p_e->info->var != NULL) {
9629 p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
9630 p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED;
9636 fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n");
9641 requires: p_e is defined, is a ptr/array variable
9643 effects: sets the size of the buffer
9646 void uentry_setSize (uentry p_e, int size) {
9647 if( uentry_isValid(p_e) ) {
9648 if( p_e->info != NULL) {
9649 if( p_e->info->var != NULL) {
9650 p_e->info->var->bufinfo->size = size;
9651 p_e->sref->bufinfo.size = size;
9657 fprintf(stderr, "uentry:Error in setSize\n");
9662 requires: p_e is defined, is a ptr/array variable
9664 effects: sets the length of the buffer
9667 void uentry_setLen (uentry p_e, int len) {
9668 if( uentry_isValid(p_e) ) {
9669 if( p_e->info != NULL) {
9670 if( p_e->info->var != NULL) {
9671 p_e->info->var->bufinfo->len = len;
9672 p_e->sref->bufinfo.len = len;
9678 fprintf(stderr, "uentry:Error in setLen\n");