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"
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
38 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43 static void uentry_checkIterArgs (uentry p_ue);
44 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
47 static void checkAliasState (/*@notnull@*/ uentry p_old,
48 /*@notnull@*/ uentry p_unew,
49 bool p_mustConform, bool p_completeConform)
50 /*@modifies p_old, p_unew@*/ ;
51 static void checkNullState (/*@notnull@*/ uentry p_old,
52 /*@notnull@*/ uentry p_unew,
53 bool p_mustConform, bool p_completeConform)
54 /*@modifies p_old, p_unew@*/ ;
56 static void checkVarConformance (/*@notnull@*/ uentry p_old,
57 /*@notnull@*/ uentry p_unew,
58 bool p_mustConform, bool p_completeConform)
59 /*@modifies p_old, p_unew@*/;
62 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
63 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
66 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
68 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
69 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
72 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
73 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
74 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
75 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
76 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
78 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
79 ctype p_oldType, /*@notnull@*/ uentry p_unew,
80 /*@notnull@*/ uentry p_newCurrent,
81 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
83 static /*@only@*/ /*@notnull@*/ uentry
84 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
85 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
87 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
89 uentry ue = (uentry) dmalloc (sizeof (*ue));
96 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
97 static void uentry_copyInto (/*@out@*/ /*@unique@*/ uentry p_unew, uentry p_old);
98 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
99 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
100 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
101 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
102 static void uvinfo_free (/*@only@*/ uvinfo p_u);
106 static /*@only@*/ cstring ancontext_unparse (ancontext an)
110 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
111 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
112 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
113 case AN_SUFIELD: return cstring_makeLiteral ("su field");
114 case AN_TDEFN: return cstring_makeLiteral ("type definition");
115 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
116 case AN_CONST: return cstring_makeLiteral ("constant");
122 static int annots[AN_LAST][QU_LAST];
123 static int decls[AN_LAST];
124 static int shdecls[AN_LAST];
125 static int idecls[AN_LAST];
131 for (i = AN_UNKNOWN; i < AN_LAST; i++)
137 for (j = QU_UNKNOWN; j < QU_LAST; j++)
144 static void tallyAnnot (ancontext ac, qual q)
158 for (j = QU_UNKNOWN; j < QU_LAST; j++)
163 for (i = AN_UNKNOWN; i < AN_LAST; i++)
169 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
170 ancontext_unparse (i),
171 decls[i], shdecls[i], idecls[i]);
173 totdecls += decls[i];
174 totshdecls += shdecls[i];
175 totidecls += idecls[i];
177 for (j = QU_UNKNOWN; j < QU_LAST; j++)
179 total[j] += annots[i][j];
180 alltotals += annots[i][j];
183 printf (" Allocation:\n");
187 for (j = QU_UNKNOWN; j < QU_LAST; j++)
189 if (qual_isAliasQual (j) && !qual_isUnique (j))
191 if (annots[i][j] > 0)
193 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
194 100.0 * (double)annots[i][j] / (double)decls[i]);
195 tmptot += annots[i][j];
200 printf (" Exposure:\n");
204 for (j = QU_UNKNOWN; j < QU_LAST; j++)
206 if (qual_isExQual (j))
208 if (annots[i][j] > 0)
210 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
211 100.0 * (double)annots[i][j] / (double)decls[i]);
212 tmptot += annots[i][j];
217 printf (" Definition:\n");
219 for (j = QU_UNKNOWN; j < QU_LAST; j++)
221 if (qual_isAllocQual (j))
223 if (annots[i][j] > 0)
225 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
226 100.0 * (double)annots[i][j] / (double)decls[i]);
233 for (j = QU_UNKNOWN; j < QU_LAST; j++)
235 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
237 if (annots[i][j] > 0)
239 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
240 100.0 * (double)annots[i][j] / (double)decls[i]);
249 for (j = QU_UNKNOWN; j < QU_LAST; j++)
253 for (i = AN_UNKNOWN; i < AN_LAST; i++)
255 if (annots[i][j] > 0)
264 printf ("Annotation: %s\n", qual_unparse (j));
266 for (i = AN_UNKNOWN; i < AN_LAST; i++)
268 if (annots[i][j] > 0)
270 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
277 printf ("All Contexts\n");
279 for (j = QU_UNKNOWN; j < QU_LAST; j++)
283 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
284 100.0 * (double)total[j] / (double)(totdecls));
289 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
291 extern void uentry_tallyAnnots (uentry u, ancontext kind)
293 alkind ak = sRef_getAliasKind (u->sref);
294 exkind ek = sRef_getExKind (u->sref);
295 nstate ns = sRef_getNullState (u->sref);
296 sstate ss = sRef_getDefState (u->sref);
297 bool recordUnknown = FALSE;
300 if (kind == AN_UNKNOWN)
308 else if (e == KCONST || e == KENUMCONST)
312 else if (e == KFCN || e == KITER)
314 uentryList params = uentry_getParams (u);
317 uentryList_elements (params, current)
319 if (uentry_isReturned (current))
323 if (!uentry_isElipsisMarker (current))
325 uentry_tallyAnnots (current, AN_FCNPARAM);
327 } end_uentryList_elements;
331 if (ctype_isFunction (u->utype)
333 && ctype_isVisiblySharable (ctype_realType (ctype_returnValue (u->utype))))
335 recordUnknown = TRUE;
338 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
340 ctype t = ctype_realType (u->utype);
344 uentryList fields = ctype_getFields (t);
346 uentryList_elements (fields, current)
348 uentry_tallyAnnots (current, AN_SUFIELD);
350 } end_uentryList_elements;
354 if (ctype_isVisiblySharable (u->utype))
356 recordUnknown = TRUE;
364 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
366 recordUnknown = TRUE;
373 if (kind == AN_FCNRETURN)
387 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
392 if (ctype_isRealPointer (ctype_realType (u->utype)))
409 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
410 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
411 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
412 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
416 if (uentry_isReturned (u))
418 tallyAnnot (kind, QU_RETURNED);
424 if (ctype_isRefCounted (ctype_realType (u->utype))
425 || (ctype_isFunction (u->utype) &&
426 ctype_isRefCounted (ctype_realType (ctype_returnValue (u->utype)))))
432 if (kind == AN_FCNPARAM)
434 tallyAnnot (kind, QU_TEMP);
436 else if (recordUnknown)
438 if (kind == AN_FCNRETURN)
441 tallyAnnot (kind, QU_UNKNOWN);
445 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
446 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
447 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
448 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
450 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
451 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
452 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
453 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
454 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
455 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
456 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
457 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
458 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
459 case AK_IMPDEPENDENT:
460 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
470 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
471 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
477 case NS_ERROR: break;
478 case NS_UNKNOWN: break;
479 case NS_NOTNULL: break;
480 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
481 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
482 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
483 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
485 case NS_ABSNULL: break;
491 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
495 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
496 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
497 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
498 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
499 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
505 static specCode specCode_fromInt (int i)
508 llassert (i >= SPC_NONE && i < SPC_LAST);
510 return ((specCode) i);
514 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
516 if (uentry_isDeclared (u))
518 return cstring_makeLiteralTemp ("previously declared");
522 return cstring_makeLiteralTemp ("specified");
526 /*@observer@*/ cstring uentry_specDeclName (uentry u)
528 if (uentry_isDeclared (u))
530 return cstring_makeLiteralTemp ("previous declaration");
534 return cstring_makeLiteralTemp ("specification");
538 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
540 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
542 return cstring_makeLiteralTemp ("redefined");
544 else if (uentry_isCodeDefined (unew))
546 return cstring_makeLiteralTemp ("defined");
548 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
550 return cstring_makeLiteralTemp ("redeclared");
554 return cstring_makeLiteralTemp ("declared");
558 static /*@only@*/ fileloc setLocation (void)
560 fileloc fl = context_getSaveLocation ();
562 if (fileloc_isDefined (fl))
568 return fileloc_copy (g_currentloc);
572 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
574 fileloc loc = setLocation ();
575 uentry ue = uentry_makeConstant (n, t, loc);
577 ue->ukind = KENUMCONST;
578 uentry_setDefined (ue, loc);
582 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
584 fileloc loc = setLocation ();
585 uentry ue = uentry_makeConstant (n, t, loc);
586 ctype etype = exprNode_getType (expr);
588 if (!ctype_isRealInt (etype)) {
592 ("Value of enum member is not an integeral type (type %s): %s",
593 ctype_unparse (etype), exprNode_unparse (expr)),
594 exprNode_loc (expr));
597 ue->ukind = KENUMCONST;
598 uentry_setDefined (ue, loc);
603 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
605 uentry ue = uentry_makeConstant (n, t, loc);
607 ue->ukind = KENUMCONST;
612 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
614 return uentry_makeVariable (n, t, setLocation (), FALSE);
618 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
620 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
624 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
626 ctype ct = idDecl_getCtype (id);
627 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
628 MAYBE, MAYBE, setLocation ());
630 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
632 if (!ynm_isOn (ue->info->datatype->abs))
634 if (ctype_isUnknown (ct))
636 ue->info->datatype->mut = MAYBE;
640 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
647 void uentry_checkParams (uentry ue)
649 if (uentry_isValid (ue))
651 bool isExt = uentry_isExtern (ue);
653 if (uentry_isRealFunction (ue))
655 uentryList params = uentry_getParams (ue);
657 uentryList_elements (params, current)
659 if (uentry_isValid (current))
661 ctype ct = current->utype;
663 if (ctype_isFixedArray (ct))
665 if (ctype_isArray (ctype_baseArrayPtr (ct))
666 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
673 (FLG_FIXEDFORMALARRAY,
674 message ("Function parameter %q declared as "
675 "manifest array (size constant is meaningless)",
676 uentry_getName (current)),
677 uentry_whereDeclared (current));
682 if (ctype_isArray (ct))
686 message ("Function parameter %q declared as "
687 "array (treated as pointer)",
688 uentry_getName (current)),
689 uentry_whereDeclared (current));
693 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
695 if (ctype_isAbstract (ct) &&
696 (isExt || (ctype_isAbstract (ctype_realType (ct))
697 && !context_hasFileAccess (ctype_typeId (ct)))))
702 ("Function %q declared with notnull parameter %q of abstract "
705 uentry_getName (current),
708 ("Since %s is an abstract type, notnull can only be "
709 "used for parameters if the function is static to a "
710 "module where %s is accessible.",
713 uentry_whereDeclared (current));
717 } end_uentryList_elements;
719 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
721 ctype ct = ue->utype;
723 if (ctype_isAbstract (ct)
724 && (isExt || (ctype_isAbstract (ctype_realType (ct))
725 && !context_hasFileAccess (ctype_typeId (ct)))))
730 ("%s %q declared %s notnull storage of abstract type %s",
731 ekind_capName (uentry_getKind (ue)),
736 ("Since %s is an abstract type, notnull can only be used "
737 "if it is static to a module where %s is accessible.",
740 uentry_whereDeclared (ue));
747 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
749 alkind ak = sRef_getAliasKind (ue->sref);
751 if (alkind_isRefCounted (ak))
753 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
757 if (alkind_isUnknown (ak))
759 exkind ek = sRef_getExKind (ue->sref);
761 if (exkind_isKnown (ek))
763 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
767 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
769 if (ctype_isVisiblySharable
770 (ctype_realType (ctype_returnValue (ue->utype))))
772 if (uentryList_hasReturned (uentry_getParams (ue)))
778 sRef_setAliasKind (ue->sref, AK_IMPONLY,
788 static /*@notnull@*/ uentry
789 uentry_makeFunctionAux (cstring n, ctype t,
791 /*@only@*/ globSet globs,
792 /*@only@*/ sRefSet mods,
793 /*@keep@*/ fileloc f, bool priv,
794 /*@unused@*/ bool isForward)
796 uentry e = uentry_alloc ();
799 if (ctype_isFunction (t))
801 ret = ctype_returnValue (t);
805 if (ctype_isKnown (t))
807 llbug (message ("not function: %s", ctype_unparse (t)));
814 if (fileloc_isSpec (f) || fileloc_isImport (f))
816 e->whereSpecified = f;
817 e->whereDeclared = fileloc_undefined;
821 e->whereSpecified = fileloc_undefined;
822 e->whereDeclared = f;
825 /* e->shallowCopy = FALSE; */
826 e->uname = cstring_copy (n);
828 e->storageclass = SCNONE;
830 e->sref = sRef_makeType (ret);
832 if (ctype_isUA (ret))
834 sRef_setStateFromType (e->sref, ret);
839 e->uses = filelocList_new ();
841 e->hasNameError = FALSE;
843 e->info = (uinfo) dmalloc (sizeof (*e->info));
844 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
846 e->info->fcn->hasMods = sRefSet_isDefined (mods);
847 e->info->fcn->hasGlobs = globSet_isDefined (globs);
849 e->info->fcn->exitCode = XK_UNKNOWN;
850 e->info->fcn->nullPred = QU_UNKNOWN;
851 e->info->fcn->specialCode = SPC_NONE;
853 e->info->fcn->access = access;
854 e->info->fcn->globs = globs;
855 e->info->fcn->defparams = uentryList_undefined;
857 sRef_setDefined (e->sref, f);
858 e->whereDefined = fileloc_undefined;
860 e->info->fcn->mods = sRefSet_undefined;
861 e->info->fcn->specclauses = NULL;
862 checkGlobalsModifies (e, mods);
863 e->info->fcn->mods = mods;
868 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
871 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
872 typeId_invalid, globSet_undefined,
876 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
877 reflectImplicitFunctionQualifiers (ue, FALSE);
879 if (!uentry_isStatic (ue)
880 && cstring_equalLit (ue->uname, "main"))
882 ctype typ = ue->utype;
886 llassert (ctype_isFunction (typ));
888 retval = ctype_returnValue (typ);
890 if (!ctype_isInt (retval))
894 message ("Function main declared to return %s, should return int",
895 ctype_unparse (retval)),
896 uentry_whereDeclared (ue));
899 args = ctype_argsFunction (typ);
901 if (uentryList_isMissingParams (args)
902 || uentryList_size (args) == 0)
908 if (uentryList_size (args) != 2)
912 message ("Function main declared with %d arg%p, "
913 "should have 2 (int argc, char *argv[])",
914 uentryList_size (args)),
915 uentry_whereLast (ue));
919 uentry arg = uentryList_getN (args, 0);
920 ctype ct = uentry_getType (arg);
922 if (!ctype_isInt (ct))
926 message ("Parameter 1, %q, of function main declared "
927 "with type %t, should have type int",
928 uentry_getName (arg), ct),
929 uentry_whereDeclared (arg));
932 arg = uentryList_getN (args, 1);
933 ct = uentry_getType (arg);
935 if (ctype_isArrayPtr (ct)
936 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
937 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
945 message ("Parameter 2, %q, of function main declared "
946 "with type %t, should have type char **",
947 uentry_getName (arg), ct),
948 uentry_whereDeclared (arg));
957 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
959 alkind ak = sRef_getAliasKind (e->sref);
961 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
962 && context_getFlag (FLG_PARAMIMPTEMP))
964 exkind ek = sRef_getExKind (e->sref);
966 if (exkind_isKnown (ek))
968 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
969 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
973 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
974 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
979 static /*@only@*/ /*@notnull@*/ uentry
980 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
982 cstring pname = makeParam (n);
983 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
985 cstring_free (pname);
986 uentry_implicitParamAnnots (e);
988 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
990 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
991 e->info->var->defstate = defstate;
999 uentry_setRefCounted (uentry e)
1001 if (uentry_isValid (e))
1003 uentry_setAliasKind (e, AK_REFCOUNTED);
1004 sRef_storeState (e->sref);
1010 uentry_setStatic (uentry c)
1012 if (uentry_isValid (c))
1014 alkind ak = sRef_getAliasKind (c->sref);
1015 c->storageclass = SCSTATIC;
1017 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1019 if (!alkind_isUnknown (ak)
1020 && !alkind_isStatic (ak))
1022 if (!(ctype_isRealPointer (uentry_getType (c)))
1023 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1024 && !alkind_isRefCounted (ak))
1026 if (alkind_isImplicit (ak)
1027 && alkind_isDependent (ak)
1028 && ctype_isArray (uentry_getType (c)))
1030 ; /* no error for observer arrays */
1036 message ("Static storage %q declared as %s",
1038 alkind_unparse (ak)),
1039 uentry_whereDeclared (c));
1045 if (alkind_isUnknown (ak)
1046 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1047 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1049 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1050 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1058 uentry_setExtern (uentry c)
1060 if (uentry_isValid (c))
1061 c->storageclass = SCEXTERN;
1065 uentry_setParamNo (uentry ue, int pno)
1067 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1068 sRef_setParamNo (ue->sref, pno);
1072 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1074 sRefSet_allElements (sr, el)
1076 sRef base = sRef_getRootBase (el);
1078 if (sRef_isGlobal (base) || sRef_isInternalState (base)
1079 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1081 if (!globSet_member (ue->info->fcn->globs, base))
1083 if (uentry_hasGlobs (ue)
1084 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1087 (FLG_WARNMISSINGGLOBALS,
1089 ("Modifies list for %q uses global %q, "
1090 "not included in globals list.",
1091 uentry_getName (ue),
1092 sRef_unparse (base)),
1093 uentry_whereLast (ue)))
1095 uentry_showWhereSpecified (ue);
1099 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1101 if (sRef_isFileStatic (base))
1103 context_recordFileGlobals (ue->info->fcn->globs);
1107 } end_sRefSet_allElements;
1111 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
1113 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1117 uentry_fixupSref (uentry ue)
1121 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1126 sr = uentry_getSref (ue);
1128 sRef_resetState (sr);
1129 sRef_clearDerived (sr);
1131 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1132 llassert (sRef_isValid (sr));
1134 if (uentry_isVariable (ue))
1136 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1137 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1141 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
1143 llassert (uentry_isFunction (ue));
1144 llassert (!specialClauses_isDefined (ue->info->fcn->specclauses));
1146 ue->info->fcn->specclauses = clauses;
1147 specialClauses_checkAll (ue);
1151 ** Used for @modifies@ @endmodifies@ syntax.
1153 ** If ue is specified, sr must contain *only*:
1155 ** o file static globals
1156 ** o sRef's derived from modifies spec (i.e., more specific than
1157 ** what was specified)
1159 ** Otherwise, if sr has modifies it must match sr.
1161 ** If it doesn't have modifies, set them to sr.
1165 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1167 if (sRef_modInFunction ())
1170 (message ("Modifies list not in function context. "
1171 "A modifies list can only appear following the parameter list "
1172 "in a function declaration or header."));
1174 /*@-mustfree@*/ return; /*@=mustfree@*/
1177 if (sRefSet_hasStatic (sr))
1179 context_recordFileModifies (sr);
1182 if (uentry_isValid (ue))
1184 if (uentry_isIter (ue))
1186 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1187 ue->info->iter->mods = sr;
1191 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1193 uentry_makeVarFunction (ue);
1196 llassertfatal (uentry_isFunction (ue));
1197 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1199 ue->info->fcn->mods = sr;
1200 ue->info->fcn->hasMods = TRUE;
1202 checkGlobalsModifies (ue, sr);
1205 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1207 ue->info->fcn->hasGlobs = TRUE;
1217 ** requires: new and old are functions
1221 checkGlobalsConformance (/*@notnull@*/ uentry old,
1222 /*@notnull@*/ uentry unew,
1223 bool mustConform, bool completeConform)
1225 bool hasInternalState = FALSE;
1227 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1229 if (globSet_isDefined (unew->info->fcn->globs))
1231 globSet_allElements (unew->info->fcn->globs, el)
1233 if (sRef_isFileStatic (el))
1235 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1237 if (sRef_isInvalid (sr))
1239 bool hasError = FALSE;
1241 if (!hasInternalState
1242 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1243 sRef_makeInternalState ()))
1244 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1245 sRef_makeSpecState ())))
1248 && !uentry_isStatic (old)
1251 message ("Globals list for %q includes internal state, %q, "
1252 "but %s without globals internalState.",
1253 uentry_getName (old),
1255 uentry_specOrDefName (old)),
1256 uentry_whereLast (unew)))
1258 uentry_showWhereSpecified (old);
1262 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1263 sRef_makeInternalState ());
1264 hasInternalState = TRUE;
1268 && fileloc_sameFile (uentry_whereDeclared (unew),
1269 uentry_whereDeclared (old)))
1274 message ("Function %q inconsistently %rdeclared (in "
1275 "same file) with file static global %q in "
1277 uentry_getName (unew),
1278 uentry_isDeclared (old),
1280 uentry_whereDeclared (unew)))
1282 uentry_showWhereSpecified (old);
1287 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1288 context_recordFileGlobals (old->info->fcn->globs);
1292 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1294 if (sRef_isInvalid (sr))
1299 message ("Function %q inconsistently %rdeclared with "
1300 "%q in globals list",
1301 uentry_getName (unew),
1302 uentry_isDeclared (old),
1304 uentry_whereDeclared (unew)))
1306 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1307 uentry_showWhereSpecified (old);
1312 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1318 ("Function %q global %q inconsistently "
1319 "%rdeclared as %qout global",
1320 uentry_getName (unew),
1322 uentry_isDeclared (old),
1323 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1324 uentry_whereDeclared (unew)))
1326 uentry_showWhereSpecified (old);
1331 } end_globSet_allElements ;
1333 if (completeConform)
1335 globSet_allElements (old->info->fcn->globs, el)
1337 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1339 if (sRef_isInvalid (sr))
1342 && uentry_isReallySpecified (old)
1345 message ("Function %q specified with %q in globals list, "
1346 "but declared without %q",
1347 uentry_getName (unew),
1350 uentry_whereDeclared (unew)))
1352 uentry_showWhereSpecified (old);
1355 } end_globSet_allElements;
1360 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1362 if (uentry_isReallySpecified (old)
1365 message ("%s %q specified with globals list, but "
1366 "declared with no globals",
1367 ekind_capName (unew->ukind),
1368 uentry_getName (unew)),
1369 uentry_whereDeclared (unew)))
1372 (message ("Specification globals: %q",
1373 globSet_unparse (old->info->fcn->globs)),
1374 uentry_whereSpecified (old));
1378 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
1379 old->info->fcn->globs);
1384 ** new modifies list must be included by old modifies list.
1386 ** file static state may be added to new, if old has internal.
1390 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1391 bool mustConform, bool completeConform)
1394 bool changedMods = FALSE;
1395 bool modInternal = FALSE;
1397 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1399 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1400 newMods = unew->info->fcn->mods;
1402 if (sRefSet_isEmpty (newMods))
1404 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1405 && uentry_isReallySpecified (old))
1409 message ("%s %q specified with modifies clause, "
1410 "but declared with no modifies clause",
1411 ekind_capName (unew->ukind),
1412 uentry_getName (unew)),
1413 uentry_whereDeclared (unew)))
1415 llgenindentmsg (message ("Specification has modifies %q",
1416 sRefSet_unparse (old->info->fcn->mods)),
1417 uentry_whereSpecified (old));
1424 sRefSet_allElements (newMods, current)
1426 if (sRef_isValid (current))
1428 sRef rb = sRef_getRootBase (current);
1430 if (sRef_isFileStatic (rb))
1434 if (!sRefSet_isSameMember (old->info->fcn->mods,
1435 sRef_makeInternalState ())
1436 && !sRefSet_isSameMember (old->info->fcn->mods,
1437 sRef_makeSpecState ()))
1440 && !uentry_isStatic (old)
1444 ("Modifies list for %q includes internal state, "
1445 "but %s without modifies internal.",
1446 uentry_getName (old),
1447 uentry_specOrDefName (old)),
1448 uentry_whereLast (unew)))
1450 uentry_showWhereSpecified (old);
1453 old->info->fcn->mods =
1454 sRefSet_insert (old->info->fcn->mods,
1455 sRef_makeInternalState ());
1460 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1466 if (sRef_canModifyVal (current, old->info->fcn->mods))
1468 int size = sRefSet_size (old->info->fcn->mods);
1470 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1473 if (sRefSet_size (old->info->fcn->mods) != size)
1484 ("Modifies list for %q contains %q, not modifiable "
1486 uentry_getName (old),
1487 sRef_unparse (current),
1488 uentry_specDeclName (old)),
1489 uentry_whereLast (unew)))
1491 uentry_showWhereSpecified (old);
1496 } end_sRefSet_allElements;
1498 if (completeConform && uentry_isReallySpecified (old))
1500 sRefSet_allElements (old->info->fcn->mods, el)
1502 if (sRef_canModify (el, newMods))
1511 ("Specification modifies clause for %q contains %q, "
1512 "not included in declaration modifies clause",
1513 uentry_getName (old),
1515 uentry_whereLast (unew)))
1517 uentry_showWhereSpecified (old);
1520 } end_sRefSet_allElements ;
1524 ** Make sure file static elements will be removed.
1529 context_recordFileModifies (old->info->fcn->mods);
1534 uentry_checkMutableType (uentry ue)
1536 ctype ct = uentry_getType (ue);
1538 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1540 voptgenerror (FLG_MUTREP,
1541 message ("Mutable abstract type %q declared without pointer "
1542 "indirection: %t (violates assignment semantics)",
1543 uentry_getName (ue), ct),
1544 uentry_whereDeclared (ue));
1549 uentry_setMutable (uentry e)
1551 llassert (uentry_isDatatype (e));
1552 e->info->datatype->mut = YES;
1556 uentry_checkIterArgs (uentry ue)
1558 bool hasYield = FALSE;
1561 llassert (uentry_isIter (ue));
1563 args = uentry_getParams (ue);
1565 uentryList_elements (args, el)
1567 sstate ds = uentry_getDefState (el);
1569 if (uentry_isYield (el))
1574 if (sstate_isUnknown (ds))
1576 uentry_setDefState (el, SS_DEFINED);
1582 } end_uentryList_elements;
1586 voptgenerror (FLG_HASYIELD,
1587 message ("Iterator %q declared with no yield parameters",
1588 uentry_getName (ue)),
1589 uentry_whereDeclared (ue));
1594 chkind_fromQual (qual qel)
1596 if (qual_isChecked (qel))
1600 else if (qual_isCheckMod (qel))
1604 else if (qual_isCheckedStrict (qel))
1606 return CH_CHECKEDSTRICT;
1608 else if (qual_isUnchecked (qel))
1610 return CH_UNCHECKED;
1615 /*@notreached@*/ return CH_UNKNOWN;
1620 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
1622 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
1624 if (!uentry_isRefCounted (ue))
1628 message ("Reference counting qualifier %s used on non-reference "
1629 "counted storage: %q",
1631 uentry_unparse (ue)));
1635 alkind ak = alkind_fromQual (qel);
1637 uentry_setAliasKind (ue, ak);
1640 else if (qual_isRefCounted (qel))
1642 ctype ct = ctype_realType (uentry_getType (ue));
1645 if (ctype_isPointer (ct)
1646 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
1648 /* check there is a refs field */
1649 uentryList fields = ctype_getFields (rt);
1650 uentry refs = uentry_undefined;
1652 uentryList_elements (fields, field)
1654 if (uentry_isRefsField (field))
1656 if (uentry_isValid (refs))
1660 message ("Reference counted structure type %s has "
1661 "multiple refs fields: %q and %q",
1663 uentry_getName (refs),
1664 uentry_getName (field)));
1669 } end_uentryList_elements;
1671 if (uentry_isInvalid (refs))
1675 message ("Reference counted structure type %s has "
1677 ctype_unparse (ct)),
1679 ("To count reference, the structure must have a field named "
1680 "refs of type int."),
1683 else if (!ctype_isInt (uentry_getType (refs)))
1687 message ("Reference counted structure type %s refs field has "
1688 "type %s (should be int)", ctype_unparse (ct),
1689 ctype_unparse (uentry_getType (refs))));
1693 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1694 uentry_whereDeclared (ue));
1699 if ((ctype_isPointer (ct)
1700 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
1701 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
1703 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1704 uentry_whereDeclared (ue));
1710 message ("Non-pointer to structure type %s declared with "
1711 "refcounted qualifier",
1712 ctype_unparse (ct)));
1716 else if (qual_isRefs (qel))
1718 if (uentry_isVariable (ue) && !uentry_isParam (ue))
1720 uentry_setAliasKind (ue, AK_REFS);
1726 message ("Refs qualifier used on non-structure field: %q",
1727 uentry_unparse (ue)));
1730 else if (qual_isAliasQual (qel))
1732 alkind ak = alkind_fromQual (qel);
1734 alkind oldak = uentry_getAliasKind (ue);
1735 ctype ut = uentry_getType (ue);
1737 if (alkind_isImplicit (ak)
1738 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
1740 /* ignore the implied qualifier */
1744 if (uentry_isEitherConstant (ue))
1748 message ("Alias qualifier %s used on constant: %q",
1749 alkind_unparse (ak), uentry_unparse (ue)));
1753 if (ctype_isFunction (ut))
1755 ut = ctype_returnValue (ut);
1758 if (!(ctype_isVisiblySharable (ut)
1759 || ctype_isRealArray (ut)
1760 || ctype_isRealSU (ut)))
1762 if (!qual_isImplied (qel))
1766 message ("Alias qualifier %s used on unsharable storage type %t: %q",
1767 alkind_unparse (ak), ut, uentry_getName (ue)));
1774 if (uentry_isRefCounted (ue))
1776 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
1777 || qual_isExposed (qel)
1778 || qual_isObserver (qel)))
1780 if (!qual_isImplied (qel))
1785 ("Alias qualifier %s used on reference counted storage: %q",
1786 alkind_unparse (ak),
1787 uentry_unparse (ue)));
1795 if (qual_isRefQual (qel))
1799 message ("Qualifier %s used on non-reference counted storage: %q",
1800 alkind_unparse (ak), uentry_unparse (ue)));
1809 uentry_setAliasKind (ue, ak);
1812 else if (qual_isNull (qel))
1814 if (uentry_isConstant (ue))
1818 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
1819 uentry_whereDeclared (ue));
1823 uentry_setNullState (ue, NS_POSNULL);
1826 else if (qual_isRelNull (qel))
1828 uentry_setNullState (ue, NS_RELNULL);
1830 else if (qual_isNotNull (qel))
1832 uentry_setNullState (ue, NS_MNOTNULL);
1834 else if (qual_isAbstract (qel)
1835 || qual_isConcrete (qel))
1837 if (!uentry_isDatatype (ue))
1841 message ("Qualifier %s used with non-datatype",
1842 qual_unparse (qel)));
1846 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
1849 else if (qual_isMutable (qel))
1851 if (!uentry_isDatatype (ue))
1853 llerror (FLG_SYNTAX,
1854 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
1858 if (!ynm_isOn (ue->info->datatype->mut))
1860 uentry_checkMutableType (ue);
1863 ue->info->datatype->mut = YES;
1866 else if (qual_isImmutable (qel))
1868 if (!uentry_isDatatype (ue))
1870 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
1871 qual_unparse (qel)));
1875 ue->info->datatype->mut = NO;
1878 else if (qual_isNullPred (qel))
1880 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1882 uentry_makeVarFunction (ue);
1885 if (uentry_isFunction (ue))
1887 ctype typ = uentry_getType (ue);
1888 ctype rtype = ctype_returnValue (uentry_getType (ue));
1890 if (ctype_isRealBool (rtype))
1892 uentryList pl = ctype_argsFunction (typ);
1894 if (uentryList_size (pl) == 1)
1896 ue->info->fcn->nullPred = qel;
1900 llerror (FLG_SYNTAX,
1901 message ("Qualifier %s used with function having %d "
1902 "arguments (should have 1)",
1904 uentryList_size (pl)));
1909 llerror (FLG_SYNTAX,
1910 message ("Qualifier %s used with function returning %s "
1911 "(should return bool)",
1913 ctype_unparse (rtype)));
1918 llerror (FLG_SYNTAX,
1919 message ("Qualifier %s used with non-function",
1920 qual_unparse (qel)));
1923 else if (qual_isExitQual (qel))
1925 exitkind exk = exitkind_fromQual (qel);
1927 if (uentry_isFunction (ue))
1929 if (exitkind_isKnown (ue->info->fcn->exitCode))
1931 llerror (FLG_SYNTAX,
1932 message ("Multiple exit qualifiers used on function %q: %s, %s",
1933 uentry_getName (ue),
1934 exitkind_unparse (ue->info->fcn->exitCode),
1935 exitkind_unparse (exk)));
1938 ue->info->fcn->exitCode = exk;
1942 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1944 uentry_makeVarFunction (ue);
1945 ue->info->fcn->exitCode = exk;
1949 llerror (FLG_SYNTAX,
1950 message ("Exit qualifier %s used with non-function (type %s)",
1952 ctype_unparse (uentry_getType (ue))));
1958 if (qual_isCQual (qel))
1964 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
1970 uentry_reflectQualifiers (uentry ue, qualList q)
1972 llassert (uentry_isValid (ue));
1974 qualList_elements (q, qel)
1976 if (qual_isStatic (qel))
1978 uentry_setStatic (ue);
1980 else if (qual_isUnused (qel))
1982 uentry_setUsed (ue, fileloc_undefined);
1984 else if (qual_isExternal (qel))
1986 fileloc_free (ue->whereDefined);
1987 ue->whereDefined = fileloc_createExternal ();
1989 else if (qual_isSef (qel))
1991 if (uentry_isVariable (ue))
1993 vkind vk = ue->info->var->kind;
1995 llassert (vk != VKREFPARAM);
1997 if (vk == VKYIELDPARAM)
2001 message ("Qualifier sef cannot be used with %s: %q",
2002 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2003 uentry_unparse (ue)));
2005 else if (vk == VKRETPARAM)
2007 ue->info->var->kind = VKSEFRETPARAM;
2011 ue->info->var->kind = VKSEFPARAM;
2018 message ("Qualifier sef is meaningful only on parameters: %q",
2019 uentry_unparse (ue)));
2022 else if (qual_isExtern (qel))
2024 ue->storageclass = SCEXTERN;
2026 else if (qual_isGlobalQual (qel)) /* undef, killed */
2028 if (uentry_isVariable (ue))
2030 sstate oldstate = ue->info->var->defstate;
2031 sstate defstate = sstate_fromQual (qel);
2034 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2035 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2037 defstate = SS_UNDEFKILLED;
2044 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2045 ue->info->var->defstate = defstate;
2051 message ("Qualifier %s used on non-variable: %q",
2052 qual_unparse (qel), uentry_unparse (ue)));
2055 /* start modifications */
2057 else if( qual_isBufQualifier(qel) ) {
2058 ctype ct = ctype_realType(uentry_getType(ue));
2060 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2062 if( uentry_hasBufStateInfo(ue) ) {
2064 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2066 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2067 /* If formal func param */
2068 uentry_setNullTerminatedState(ue);
2069 uentry_setLen (ue, 1);
2070 uentry_setSize (ue, 1);
2072 sRef_setNullTerminatedState(uentry_getSref(ue));
2073 sRef_setLen (uentry_getSref(ue), 1);
2074 sRef_setSize (uentry_getSref(ue), 1);
2076 uentry_setPossiblyNullTerminatedState(ue);
2078 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2082 /* put other BufState Qualifiers here */
2084 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2085 struct for identifier %s\n", uentry_getName(ue) ) );
2087 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2089 sRef retSref = uentry_getSref (ue);
2090 ctype retType = sRef_getType (retSref);
2092 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2093 sRef_setNullTerminatedState (retSref);
2099 message ("Qualifier %s used on non-pointer on \
2100 function return: %q", qual_unparse (qel),
2101 uentry_unparse (ue)));
2108 message ("Qualifier %s used on non-pointer: %q",
2109 qual_unparse (qel), uentry_unparse (ue)));
2112 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2114 ctype realType = ctype_realType (ue->utype);
2115 sstate defstate = sstate_fromQual (qel);
2117 if (ctype_isFunction (realType))
2119 realType = ctype_realType (ctype_returnValue (realType));
2122 if (qual_isRelDef (qel))
2124 ; /* okay anywhere */
2128 if (!ctype_isAP (realType)
2129 && !ctype_isSU (realType)
2130 && !ctype_isUnknown (realType)
2131 && !ctype_isAbstract (ue->utype))
2135 message ("Qualifier %s used on non-pointer or struct: %q",
2136 qual_unparse (qel), uentry_unparse (ue)));
2140 uentry_setDefState (ue, defstate);
2142 if (sRef_isStateSpecial (ue->sref)
2143 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2145 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2148 else if (qual_isYield (qel))
2150 if (uentry_isVariable (ue))
2152 ue->info->var->kind = VKYIELDPARAM;
2158 message ("Qualifier %s used on non-iterator parameter: %q",
2159 qual_unparse (qel), uentry_unparse (ue)));
2162 else if (qual_isExQual (qel))
2164 exkind ek = exkind_fromQual (qel);
2165 ctype ut = uentry_getType (ue);
2167 if (ctype_isFunction (ut))
2169 ut = ctype_returnValue (ut);
2172 if (!(ctype_isVisiblySharable (ut))
2173 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2174 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2176 if (!qual_isImplied (qel))
2180 message ("Qualifier %s used on unsharable storage type %t: %q",
2181 exkind_unparse (ek), ut, uentry_getName (ue)));
2186 alkind ak = sRef_getAliasKind (ue->sref);
2188 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2190 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2192 if (!alkind_isTemp (ak))
2194 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2197 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2198 || alkind_isOwned (ak))
2206 message ("Exposure qualifier %s used on %s storage (should "
2207 "be dependent): %q",
2209 alkind_unparse (ak),
2210 uentry_unparse (ue)));
2214 else if (qual_isGlobCheck (qel))
2216 if (uentry_isVariable (ue))
2218 chkind ch = chkind_fromQual (qel);
2220 if (ue->info->var->checked != CH_UNKNOWN)
2222 if (ch == ue->info->var->checked)
2224 llerror (FLG_SYNTAX,
2225 message ("Redundant %s qualifier on %q",
2227 uentry_getName (ue)));
2231 llerror (FLG_SYNTAX,
2233 ("Contradictory %s and %s qualifiers on %q",
2235 checkedName (ue->info->var->checked),
2236 uentry_getName (ue)));
2240 ue->info->var->checked = ch;
2246 message ("Qualifier %s used with non-variable",
2247 qual_unparse (qel)));
2250 else if (qual_isReturned (qel))
2252 if (uentry_isVariable (ue))
2254 ue->info->var->kind = VKRETPARAM;
2258 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2259 qual_unparse (qel)));
2264 uentry_reflectOtherQualifier (ue, qel);
2267 sRef_storeState (ue->sref);
2268 } end_qualList_elements;
2274 uentry_isOnly (uentry ue)
2276 return (!uentry_isUndefined (ue)
2277 && uentry_isVariable (ue)
2278 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2282 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2284 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2285 sRef_setOrigAliasKind (ue->sref, ak);
2289 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2291 if (uentry_isVariable (ue))
2293 ue->info->var->nullstate = ns;
2296 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2300 uentry_isUnique (uentry ue)
2302 return (!uentry_isUndefined (ue)
2303 && uentry_isVariable (ue)
2304 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2308 uentry_isFileStatic (uentry ue)
2310 return (uentry_isStatic (ue)
2311 && (!uentry_isVariable (ue)
2312 || sRef_isFileStatic (uentry_getSref (ue))));
2316 uentry_isExported (uentry ue)
2318 if (uentry_isValid (ue))
2320 if (uentry_isVariable (ue))
2322 return (sRef_isRealGlobal (uentry_getSref (ue)));
2326 return !uentry_isStatic (ue);
2334 uentry_isNonLocal (uentry ue)
2336 return (uentry_isValid (ue) && uentry_isVariable (ue)
2337 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
2341 uentry_isGlobal (uentry ue)
2343 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
2344 sRef_isGlobal (ue->sref));
2348 uentry_isPrintfLike (uentry ue)
2350 return (uentry_isFunction (ue)
2351 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2355 uentry_isScanfLike (uentry ue)
2357 return (uentry_isFunction (ue)
2358 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2362 uentry_isMessageLike (uentry ue)
2364 return (uentry_isFunction (ue)
2365 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2368 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2370 uentryList args = uentry_getParams (ue);
2372 if (!uentryList_isMissingParams (args))
2374 uentry last = uentry_undefined;
2376 uentryList_elements (args, current)
2378 if (uentry_isElipsisMarker (current))
2380 if (uentry_isUndefined (last))
2384 message ("Function %q is marked %s, but has no format "
2385 "string argument before elipsis",
2386 uentry_getName (ue),
2387 specCode_unparse (ue->info->fcn->specialCode)),
2388 uentry_whereLast (ue));
2389 ue->info->fcn->specialCode = SPC_NONE;
2393 ctype rt = ctype_realType (uentry_getType (last));
2395 if (!ctype_match (rt, ctype_string))
2399 /* wchar_t * is okay too */
2400 if (ctype_isAP (rt))
2402 ctype base = ctype_baseArrayPtr (rt);
2404 if (ctype_isArbitraryIntegral (base))
2414 message ("Function %q is marked %s, but the argument "
2415 "before the elipsis has type %s (should be char *)",
2416 uentry_getName (ue),
2417 specCode_unparse (ue->info->fcn->specialCode),
2418 ctype_unparse (uentry_getType (last))),
2419 uentry_whereLast (ue));
2421 ue->info->fcn->specialCode = SPC_NONE;
2428 } end_uentryList_elements ;
2432 message ("Function %q is marked %s, but has no elipsis parameter",
2433 uentry_getName (ue),
2434 specCode_unparse (ue->info->fcn->specialCode)),
2435 uentry_whereLast (ue));
2437 ue->info->fcn->specialCode = SPC_NONE;
2442 uentry_setPrintfLike (uentry ue)
2444 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2446 uentry_makeVarFunction (ue);
2449 llassertfatal (uentry_isFunction (ue));
2450 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2451 checkSpecialFunction (ue);
2455 uentry_setScanfLike (uentry ue)
2457 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2459 uentry_makeVarFunction (ue);
2462 llassertfatal (uentry_isFunction (ue));
2463 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2464 checkSpecialFunction (ue);
2468 uentry_setMessageLike (uentry ue)
2470 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2472 uentry_makeVarFunction (ue);
2475 llassertfatal (uentry_isFunction (ue));
2476 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
2477 checkSpecialFunction (ue);
2481 uentry_isSpecialFunction (uentry ue)
2483 return (uentry_isFunction (ue)
2484 && (ue->info->fcn->specialCode != SPC_NONE));
2487 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
2489 ctype ct = idDecl_getCtype (t);
2491 sRef pref = sRef_makeParam (i, ct);
2492 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
2494 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2495 uentry_implicitParamAnnots (ue);
2497 /* Parameter type [][] or [x][] is invalid */
2499 while (ctype_isFixedArray (base)) {
2500 base = ctype_baseArrayPtr (base);
2503 if (ctype_isIncompleteArray (base)) {
2504 base = ctype_baseArrayPtr (base);
2506 if (ctype_isArray (base)) {
2507 if (!uentry_hasName (ue)) {
2508 (void) optgenerror (FLG_INCOMPLETETYPE,
2509 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
2511 ctype_unparse (ct)),
2512 uentry_whereLast (ue));
2514 (void) optgenerror (FLG_INCOMPLETETYPE,
2515 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
2516 uentry_getName (ue),
2517 ctype_unparse (ct)),
2518 uentry_whereLast (ue));
2526 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
2528 ctype ct = idDecl_getCtype (t);
2530 if (ctype_isFunction (ct))
2532 return (uentry_makeIdFunction (t));
2536 fileloc loc = setLocation ();
2537 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
2539 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2541 if (!uentry_isExtern (ue))
2543 uentry_setDefined (ue, loc);
2551 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
2553 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
2561 /*@only@*/ /*@notnull@*/
2562 uentry uentry_makeConstantAux (cstring n, ctype t,
2563 /*@keep@*/ fileloc f, bool priv,
2564 /*@only@*/ multiVal m)
2566 uentry e = uentry_alloc ();
2569 e->uname = cstring_copy (n);
2571 e->storageclass = SCNONE;
2573 e->sref = sRef_makeConst (t);
2578 e->uses = filelocList_new ();
2579 e->isPrivate = priv;
2580 e->hasNameError = FALSE;
2582 e->info = (uinfo) dmalloc (sizeof (*e->info));
2583 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
2584 e->info->uconst->val = m;
2585 e->info->uconst->access = typeIdSet_undefined;
2587 uentry_setSpecDef (e, f);
2589 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
2591 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
2597 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
2599 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
2602 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
2604 uentry ue = uentry_makeConstant (idDecl_observeId (t),
2605 idDecl_getCtype (t),
2608 llassert (fileloc_isUndefined (ue->whereDeclared));
2609 ue->whereDeclared = setLocation ();
2611 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2620 void uentry_setDefState (uentry ue, sstate defstate)
2622 if (uentry_isValid (ue))
2624 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2626 if (uentry_isVariable (ue))
2628 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
2633 bool uentry_isCheckedUnknown (uentry ue)
2635 return (uentry_isVar (ue)
2636 && (ue->info->var->checked == CH_UNKNOWN));
2639 bool uentry_isCheckMod (uentry ue)
2641 return (uentry_isVar (ue)
2642 && (ue->info->var->checked == CH_CHECKMOD));
2645 bool uentry_isUnchecked (uentry ue)
2647 return (uentry_isVar (ue)
2648 && (ue->info->var->checked == CH_UNCHECKED));
2651 bool uentry_isChecked (uentry ue)
2653 return (uentry_isVar (ue)
2654 && (ue->info->var->checked == CH_CHECKED));
2657 bool uentry_isCheckedModify (uentry ue)
2659 return (uentry_isVar (ue)
2660 && (ue->info->var->checked == CH_CHECKED
2661 || ue->info->var->checked == CH_CHECKMOD
2662 || ue->info->var->checked == CH_CHECKEDSTRICT));
2665 bool uentry_isCheckedStrict (uentry ue)
2667 return (uentry_isVar (ue)
2668 && (ue->info->var->checked == CH_CHECKEDSTRICT));
2671 void uentry_setUnchecked (uentry ue)
2673 llassert (uentry_isVar (ue));
2675 ue->info->var->checked = CH_UNCHECKED;
2678 void uentry_setChecked (uentry ue)
2680 llassert (uentry_isVar (ue));
2682 ue->info->var->checked = CH_CHECKED;
2685 void uentry_setCheckMod (uentry ue)
2687 llassert (uentry_isVar (ue));
2689 ue->info->var->checked = CH_CHECKMOD;
2692 void uentry_setCheckedStrict (uentry ue)
2694 llassert (uentry_isVar (ue));
2696 ue->info->var->checked = CH_CHECKEDSTRICT;
2699 static /*@only@*/ /*@notnull@*/
2700 uentry uentry_makeVariableAux (cstring n, ctype t,
2702 /*@exposed@*/ sRef s,
2703 bool priv, vkind kind)
2705 uentry e = uentry_alloc ();
2708 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
2711 e->uname = cstring_copy (n);
2714 e->storageclass = SCNONE;
2721 e->uses = filelocList_new ();
2722 e->isPrivate = priv;
2723 e->hasNameError = FALSE;
2725 e->info = (uinfo) dmalloc (sizeof (*e->info));
2726 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
2727 e->info->var->kind = kind;
2729 e->info->var->checked = CH_UNKNOWN;
2731 uentry_setSpecDef (e, f);
2733 if (ctype_isFunction (rt))
2735 rt = ctype_returnValue (rt);
2738 if (ctype_isUA (rt))
2740 sRef_setStateFromType (e->sref, rt);
2743 e->info->var->defstate = sRef_getDefState (e->sref);
2744 e->info->var->nullstate = sRef_getNullState (e->sref);
2746 /* start modifications */
2747 /* This function sets the uentry for a pointer or array variable declaration,
2748 it allocates memory and sets the fields. We check if the type of the variable
2749 is a pointer or array and allocate a `bbufinfo' struct accordingly */
2751 if( ctype_isArray (t) || ctype_isPointer(t)) {
2752 e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
2753 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
2754 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
2756 e->info->var->bufinfo = NULL;
2758 /* end modification */
2764 uentry_isYield (uentry ue)
2766 return (uentry_isVariable (ue)
2767 && (ue->info->var->kind == VKYIELDPARAM
2768 || ue->info->var->kind == VKREFYIELDPARAM));
2772 uentry_isRefsField (uentry ue)
2774 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
2777 /*@only@*/ /*@notnull@*/
2778 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
2780 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
2781 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
2788 void uentry_makeVarFunction (uentry ue)
2795 llassert (uentry_isValid (ue));
2796 llassert (!sRef_modInFunction ());
2798 ak = sRef_getOrigAliasKind (ue->sref);
2799 ek = sRef_getOrigExKind (ue->sref);
2801 oldInfo = ue->info->var;
2803 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
2806 ** expanded macro is marked used (until I write a pre-processor)
2809 ue->used |= (oldInfo->kind == VKEXPMACRO);
2812 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
2813 ue->info->fcn->exitCode = XK_UNKNOWN;
2814 ue->info->fcn->nullPred = QU_UNKNOWN;
2815 ue->info->fcn->specialCode = SPC_NONE;
2816 ue->info->fcn->access = typeIdSet_undefined;
2817 ue->info->fcn->hasGlobs = FALSE;
2818 ue->info->fcn->globs = globSet_undefined;
2819 ue->info->fcn->hasMods = FALSE;
2820 ue->info->fcn->mods = sRefSet_undefined;
2821 ue->info->fcn->specclauses = NULL;
2822 ue->info->fcn->defparams = uentryList_undefined;
2824 if (ctype_isFunction (ue->utype))
2826 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
2830 ue->sref = sRef_makeType (ctype_unknown);
2833 if (sRef_isRefCounted (ue->sref))
2839 if (alkind_isUnknown (ak))
2841 if (exkind_isKnown (ek))
2843 ak = AK_IMPDEPENDENT;
2847 if (context_getFlag (FLG_RETIMPONLY))
2849 if (ctype_isFunction (ue->utype)
2850 && ctype_isVisiblySharable
2851 (ctype_realType (ctype_returnValue (ue->utype))))
2853 if (uentryList_hasReturned (uentry_getParams (ue)))
2867 loc = ue->whereDeclared;
2869 sRef_setAliasKind (ue->sref, ak, loc);
2870 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
2871 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
2872 sRef_setExKind (ue->sref, ek, loc);
2874 if (oldInfo->kind == VKEXPMACRO)
2877 ue->whereDeclared = fileloc_undefined;
2881 fileloc_free (ue->whereDefined);
2882 ue->whereDefined = fileloc_undefined;
2885 uvinfo_free (oldInfo);
2889 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
2891 llassert (uentry_isValid (ue));
2893 if (uentry_isIter (ue))
2895 llassert (globSet_isUndefined (ue->info->iter->globs));
2896 ue->info->iter->globs = globs;
2900 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2902 uentry_makeVarFunction (ue);
2905 llassert (uentry_isFunction (ue));
2906 llassert (!ue->info->fcn->hasGlobs
2907 && globSet_isUndefined (ue->info->fcn->globs));
2909 ue->info->fcn->hasGlobs = TRUE;
2910 /*@-mustfree@*/ ue->info->fcn->globs = globs;
2914 if (globSet_hasStatic (globs))
2916 context_recordFileGlobals (globs);
2919 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
2921 ue->info->fcn->hasMods = TRUE;
2925 void uentry_addAccessType (uentry ue, typeId tid)
2927 if (uentry_isFunction (ue))
2929 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
2931 else if (uentry_isEitherConstant (ue))
2933 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
2935 else if (uentry_isIter (ue))
2937 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
2939 else if (uentry_isEndIter (ue))
2941 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
2945 llbug (message ("no access for: %q", uentry_unparse (ue)));
2949 /*@only@*/ /*@notnull@*/ uentry
2950 uentry_makeFunction (cstring n, ctype t,
2952 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
2955 return (uentry_makeFunctionAux (n, t,
2956 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
2957 : typeIdSet_single (access)),
2963 /*@notnull@*/ uentry
2964 uentry_makePrivFunction2 (cstring n, ctype t,
2966 globSet globs, sRefSet mods,
2969 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
2973 /*@notnull@*/ uentry
2974 uentry_makeSpecFunction (cstring n, ctype t,
2976 /*@only@*/ globSet globs,
2977 /*@only@*/ sRefSet mods,
2980 uentry ue = uentry_makeFunctionAux (n, t, access,
2984 uentry_setHasGlobs (ue);
2985 uentry_setHasMods (ue);
2987 reflectImplicitFunctionQualifiers (ue, TRUE);
2992 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
2994 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
2995 sRef_undefined, FALSE, VKEXPMACRO);
2997 uentry_setDefined (ue, f);
3001 /*@notnull@*/ /*@notnull@*/ uentry
3002 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3004 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3005 typeIdSet_singleOpt (access),
3006 globSet_undefined, sRefSet_undefined,
3010 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3014 bool uentry_isForward (uentry e)
3016 if (uentry_isValid (e))
3018 ctype ct = uentry_getType (e);
3020 return (ctype_isUnknown (ct)
3021 || (ctype_isFunction (ct)
3022 && ctype_isUnknown (ctype_returnValue (ct))));
3029 /*@notnull@*/ uentry
3030 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3032 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3038 /*@notnull@*/ uentry
3039 uentry_makeUnspecFunction (cstring n, ctype t,
3043 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
3044 sRefSet_new (), f, FALSE, TRUE);
3046 reflectImplicitFunctionQualifiers (ue, TRUE);
3055 /* is exported for use by usymtab_interface */
3057 /*@notnull@*/ uentry
3058 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
3059 fileloc f, bool priv)
3061 uentry e = uentry_alloc ();
3063 DPRINTF (("Make datatype: %s / %s",
3064 n, ctype_unparse (t)));
3066 /* e->shallowCopy = FALSE; */
3067 e->ukind = KDATATYPE;
3068 e->uname = cstring_copy (n);
3070 e->storageclass = SCNONE;
3071 e->sref = sRef_makeUnknown ();
3075 sRef_setStateFromType (e->sref, t);
3078 uentry_setSpecDef (e, f);
3080 e->uses = filelocList_new ();
3081 e->isPrivate = priv;
3082 e->hasNameError = FALSE;
3087 e->info = (uinfo) dmalloc (sizeof (*e->info));
3088 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3089 e->info->datatype->abs = abs;
3090 e->info->datatype->mut = mut;
3091 e->info->datatype->type = ctype_undefined;
3093 if (uentry_isDeclared (e))
3095 uentry_setDefined (e, f);
3098 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
3100 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3106 /*@notnull@*/ uentry
3107 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
3110 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
3113 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abs)
3115 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3116 ctype_bool, NO, abs,
3117 fileloc_getBuiltin (),
3120 ret->info->datatype->type = ctype_bool;
3128 static /*@only@*/ /*@notnull@*/ uentry
3129 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3130 /*@only@*/ fileloc f)
3132 uentry e = uentry_alloc ();
3135 e->uname = cstring_copy (n);
3137 e->sref = sRef_makeUnknown ();
3138 e->storageclass = SCNONE;
3142 uentry_setSpecDef (e, f);
3144 e->uses = filelocList_new ();
3145 e->isPrivate = FALSE;
3146 e->hasNameError = FALSE;
3148 e->info = (uinfo) dmalloc (sizeof (*e->info));
3149 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3150 e->info->iter->access = access;
3151 e->info->iter->mods = sRefSet_undefined;
3152 e->info->iter->globs = globSet_undefined;
3154 uentry_checkIterArgs (e);
3158 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3160 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3163 static /*@notnull@*/ uentry
3164 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3166 uentry e = uentry_alloc ();
3168 /* e->shallowCopy = FALSE; */
3169 e->ukind = KENDITER;
3170 e->storageclass = SCNONE;
3171 e->uname = message ("end_%s", n);
3172 e->utype = ctype_unknown;
3173 e->sref = sRef_makeUnknown ();
3175 uentry_setSpecDef (e, f);
3180 e->uses = filelocList_new ();
3181 e->isPrivate = FALSE;
3182 e->hasNameError = FALSE;
3184 e->info = (uinfo) dmalloc (sizeof (*e->info));
3185 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3187 e->info->enditer->access = access;
3192 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3194 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3201 static /*@only@*/ /*@notnull@*/ uentry
3202 uentry_makeTagAux (cstring n, ctype t,
3203 /*@only@*/ fileloc fl,
3204 bool priv, ekind kind)
3206 uentry e = uentry_alloc ();
3208 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3210 llbuglit ("uentry_makeTagAux: not a tag type");
3214 /* e->shallowCopy = FALSE; */
3215 e->uname = cstring_copy (n);
3218 e->sref = sRef_makeUnknown ();
3219 e->storageclass = SCNONE;
3221 uentry_setSpecDef (e, fl);
3226 e->uses = filelocList_new ();
3227 e->isPrivate = priv;
3228 e->hasNameError = FALSE;
3230 e->info = (uinfo) dmalloc (sizeof (*e->info));
3231 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3232 e->info->datatype->abs = NO;
3233 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3234 e->info->datatype->type = t;
3236 if (uentry_isDeclared (e))
3238 uentry_setDefined (e, fl);
3241 DPRINTF (("Make tag: %s / %s [%d]", uentry_unparseFull (e),
3242 ctype_unparse (t), t));
3246 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3248 cstring sname = makeStruct (n);
3249 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3251 cstring_free (sname);
3256 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3258 cstring sname = makeStruct (n);
3259 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3261 cstring_free (sname);
3266 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3268 cstring uname = makeUnion (n);
3269 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3271 cstring_free (uname);
3277 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3279 cstring ename = makeEnum (n);
3280 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3282 cstring_free (ename);
3288 uentry_makeUnionTagLoc (cstring n, ctype t)
3290 cstring uname = makeUnion (n);
3291 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3293 cstring_free (uname);
3298 uentry_makeEnumTagLoc (cstring n, ctype t)
3300 cstring ename = makeEnum (n);
3301 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3303 cstring_free (ename);
3308 uentry_isStructTag (uentry ue)
3310 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3314 uentry_isUnionTag (uentry ue)
3316 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3320 uentry_isEnumTag (uentry ue)
3322 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3326 uentry_isAnyTag (uentry ue)
3328 return (uentry_isStructTag (ue)
3329 || uentry_isUnionTag (ue)
3330 || uentry_isEnumTag (ue));
3333 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3335 extern void uentry_destroyMod (void)
3336 /*@globals killed emarker@*/ /*@modifies emarker@*/
3338 static bool wasDestroyed = FALSE;
3340 llassert (!wasDestroyed);
3342 if (emarker != NULL)
3344 uentry_reallyFree (emarker);
3347 wasDestroyed = TRUE;
3351 uentry_makeElipsisMarker (void)
3353 if (emarker == NULL)
3355 emarker = uentry_alloc ();
3357 emarker->ukind = KELIPSMARKER;
3358 emarker->uname = cstring_makeLiteral ("...");
3359 emarker->utype = ctype_elipsMarker;
3360 emarker->sref = sRef_undefined;
3361 emarker->storageclass = SCNONE;
3362 emarker->used = FALSE;
3363 emarker->lset = FALSE;
3364 emarker->info = NULL;
3366 uentry_setSpecDef (emarker, fileloc_undefined);
3367 emarker->uses = filelocList_new ();
3368 emarker->isPrivate = FALSE;
3369 emarker->hasNameError = FALSE;
3372 /*@ignore@*/ return (emarker); /*@end@*/
3380 uentry_equiv (uentry p1, uentry p2)
3382 if (uentry_compare (p1, p2) != 0)
3393 uentry_xcomparealpha (uentry *p1, uentry *p2)
3397 if ((res = uentry_compare (*p1, *p2)) == 0) {
3398 if ((*p1 != NULL) && (*p2 != NULL)) {
3399 res = cstring_compare ((*p1)->uname,
3408 uentry_xcompareuses (uentry *p1, uentry *p2)
3413 if (uentry_isValid (u1))
3415 if (uentry_isValid (u2))
3417 return (-1 * int_compare (filelocList_size (u1->uses),
3418 filelocList_size (u2->uses)));
3427 if (uentry_isValid (u2))
3439 uentry_compareStrict (uentry v1, uentry v2)
3441 COMPARERETURN (uentry_compare (v1, v2));
3443 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
3445 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
3446 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
3447 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
3454 uentry_compare (uentry u1, uentry u2)
3456 if (u1 == u2) return 0;
3458 if (uentry_isInvalid (u1)) return -1;
3459 if (uentry_isInvalid (u2)) return 1;
3461 INTCOMPARERETURN (u1->ukind, u2->ukind);
3462 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
3463 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
3465 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
3471 /* bug detected by lclint:
3472 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
3477 return (multiVal_compare (u1->info->uconst->val,
3478 u2->info->uconst->val));
3482 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
3484 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3485 uentry_accessType (u2)));
3486 return (uentryList_compareParams (uentry_getParams (u1),
3487 uentry_getParams (u2)));
3489 return (typeIdSet_compare (uentry_accessType (u1),
3490 uentry_accessType (u2)));
3492 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3493 uentry_accessType (u2)));
3494 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
3495 uentry_getGlobs (u2)));
3496 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
3497 uentry_getParams (u2)));
3498 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
3499 u2->info->fcn->specialCode));
3500 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
3501 u2->info->fcn->nullPred));
3503 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
3505 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
3506 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
3507 sRef_getOrigAliasKind (u2->sref)));
3508 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
3509 sRef_getOrigExKind (u2->sref)));
3510 COMPARERETURN (generic_compare (u1->info->var->checked,
3511 u2->info->var->checked));
3512 COMPARERETURN (generic_compare (u1->info->var->defstate,
3513 u2->info->var->defstate));
3514 return (generic_compare (u1->info->var->nullstate,
3515 u2->info->var->nullstate));
3517 COMPARERETURN (ctype_compare (u1->info->datatype->type,
3518 u2->info->datatype->type));
3519 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
3520 u2->info->datatype->mut));
3521 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
3530 ** all entries are: <type>[@<info>]*#<name>
3532 ** info depends on kind:
3536 advanceField (char **s)
3542 advanceName (char **s)
3548 vkind_fromInt (int i)
3550 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
3552 llbuglit ("vkind_fromInt: out of range");
3559 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
3560 typeIdSet access, nstate nullstate,
3561 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
3563 uentry e = uentry_alloc ();
3568 e->sref = sRef_makeConst (ct);
3570 sRef_setNullState (e->sref, nullstate, loc);
3571 e->storageclass = SCNONE;
3573 if (fileloc_isSpec (loc))
3575 e->whereSpecified = loc;
3576 e->whereDeclared = fileloc_undefined;
3580 e->whereSpecified = fileloc_undefined;
3581 e->whereDeclared = loc;
3584 e->whereDefined = fileloc_undefined;
3585 e->uses = filelocList_new ();
3586 e->isPrivate = FALSE;
3587 e->hasNameError = FALSE;
3592 e->info = (uinfo) dmalloc (sizeof (*e->info));
3593 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3594 e->info->uconst->val = m;
3595 e->info->uconst->access = access;
3597 sRef_storeState (e->sref);
3602 static /*@only@*/ uentry
3603 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
3604 sstate defstate, nstate isnull, alkind aliased,
3605 exkind exp, chkind checked,
3606 /*@only@*/ fileloc loc)
3608 uentry e = uentry_alloc ();
3613 e->storageclass = SCNONE;
3615 e->sref = sRef_makeType (ct);
3616 sRef_setNullState (e->sref, isnull, loc);
3618 e->whereDefined = fileloc_undefined;
3620 if (fileloc_isSpec (loc))
3622 e->whereSpecified = loc;
3623 e->whereDeclared = fileloc_undefined;
3627 e->whereSpecified = fileloc_undefined;
3628 e->whereDeclared = loc;
3631 e->isPrivate = FALSE;
3632 e->hasNameError = FALSE;
3637 e->uses = filelocList_new ();
3639 e->info = (uinfo) dmalloc (sizeof (*e->info));
3640 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3641 e->info->var->kind = kind;
3642 e->info->var->checked = checked;
3643 e->info->var->defstate = defstate;
3645 sRef_setDefState (e->sref, defstate, loc);
3647 e->info->var->nullstate = sRef_getNullState (e->sref);
3649 sRef_setExKind (e->sref, exp, loc);
3650 sRef_setAliasKind (e->sref, aliased, loc);
3652 sRef_storeState (e->sref);
3656 static /*@only@*/ uentry
3657 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abs,
3658 ynm mut, ctype rtype, alkind ak, exkind exp,
3659 sstate defstate, nstate isnull,
3660 /*@only@*/ fileloc loc)
3662 uentry e = uentry_alloc ();
3664 e->ukind = KDATATYPE;
3665 /* e->shallowCopy = FALSE; */
3668 e->storageclass = SCNONE;
3669 e->sref = sRef_makeUnknown ();
3672 ** This is only setting null state. (I think?)
3675 if (ctype_isUA (ct))
3677 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
3679 if (uentry_isValid (te))
3681 sRef_setStateFromUentry (e->sref, te);
3685 /* problem for recursive type definitions */
3689 sRef_setAliasKind (e->sref, ak, loc);
3690 sRef_setExKind (e->sref, exp, loc);
3692 sRef_setDefState (e->sref, defstate, loc);
3694 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
3696 isnull = NS_ABSNULL;
3699 sRef_mergeNullState (e->sref, isnull);
3701 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
3703 if (fileloc_isSpec (loc))
3705 e->whereSpecified = loc;
3706 e->whereDeclared = fileloc_undefined;
3710 e->whereSpecified = fileloc_undefined;
3711 e->whereDeclared = loc;
3714 e->isPrivate = FALSE;
3715 e->hasNameError = FALSE;
3719 e->uses = filelocList_new ();
3721 e->info = (uinfo) dmalloc (sizeof (*e->info));
3722 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3723 e->info->datatype->abs = abs;
3724 e->info->datatype->mut = mut;
3725 e->info->datatype->type = rtype;
3727 sRef_storeState (e->sref);
3733 static void uentry_setHasGlobs (uentry ue)
3735 llassert (uentry_isFunction (ue));
3737 ue->info->fcn->hasGlobs = TRUE;
3740 static void uentry_setHasMods (uentry ue)
3742 llassert (uentry_isFunction (ue));
3744 ue->info->fcn->hasMods = TRUE;
3748 bool uentry_hasGlobs (uentry ue)
3750 if (uentry_isFunction (ue))
3752 return (ue->info->fcn->hasGlobs);
3758 bool uentry_hasSpecialClauses (uentry ue)
3760 return (uentry_isFunction (ue) && specialClauses_isDefined (ue->info->fcn->specclauses));
3763 specialClauses uentry_getSpecialClauses (uentry ue)
3765 llassert (uentry_isFunction (ue));
3766 return ue->info->fcn->specclauses;
3769 bool uentry_hasMods (uentry ue)
3771 if (uentry_isFunction (ue))
3773 return (ue->info->fcn->hasMods);
3780 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
3782 bool hasGlobs, /*@only@*/ globSet globs,
3783 bool hasMods, /*@only@*/ sRefSet mods,
3784 alkind ak, exkind exp,
3785 sstate defstate, nstate isnull,
3789 /*@only@*/ specialClauses specclauses,
3790 /*@only@*/ fileloc loc)
3792 uentry e = uentry_alloc ();
3795 /* e->shallowCopy = FALSE; */
3799 e->storageclass = SCNONE;
3801 if (ctype_isFunction (ct))
3803 ret = ctype_returnValue (ct);
3807 if (ctype_isKnown (ct))
3809 llbug (message ("not function: %s", ctype_unparse (ct)));
3812 ret = ctype_unknown;
3815 e->sref = sRef_makeType (ret);
3817 if (ctype_isUA (ret))
3819 sRef_setStateFromType (e->sref, ret);
3822 sRef_setDefined (e->sref, loc);
3823 sRef_setNullState (e->sref, isnull, loc);
3825 sRef_setAliasKind (e->sref, ak, loc);
3826 sRef_setExKind (e->sref, exp, loc);
3827 sRef_setDefState (e->sref, defstate, loc);
3829 e->whereSpecified = loc;
3830 e->whereDefined = fileloc_undefined;
3832 e->isPrivate = FALSE;
3833 e->hasNameError = FALSE;
3837 e->uses = filelocList_new ();
3839 e->info = (uinfo) dmalloc (sizeof (*e->info));
3840 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
3842 e->info->fcn->exitCode = exitCode;
3843 e->info->fcn->specialCode = sCode;
3844 e->info->fcn->nullPred = nullPred;
3845 e->info->fcn->access = access;
3847 e->info->fcn->specclauses = specclauses;
3848 e->info->fcn->hasGlobs = hasGlobs;
3849 e->info->fcn->globs = globs;
3851 e->info->fcn->hasMods = hasMods;
3852 e->info->fcn->mods = mods;
3854 e->info->fcn->defparams = uentryList_undefined;
3855 e->whereDeclared = fileloc_undefined;
3857 sRef_storeState (e->sref);
3862 static /*@only@*/ uentry
3863 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
3864 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
3866 uentry e = uentry_alloc ();
3868 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
3870 llbuglit ("uentry_makeTagBase: not a tag type");
3873 /* e->shallowCopy = FALSE; */
3877 e->sref = sRef_makeUnknown ();
3878 e->storageclass = SCNONE;
3880 if (fileloc_isSpec (loc))
3882 e->whereSpecified = loc;
3883 e->whereDeclared = fileloc_undefined;
3887 e->whereDeclared = loc;
3888 e->whereSpecified = fileloc_undefined;
3891 e->whereDefined = fileloc_undefined;
3893 e->isPrivate = FALSE;
3894 e->hasNameError = FALSE;
3898 e->uses = filelocList_new ();
3900 e->info = (uinfo) dmalloc (sizeof (*e->info));
3901 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3902 e->info->datatype->abs = NO;
3903 e->info->datatype->mut = MAYBE;
3904 e->info->datatype->type = rtype;
3906 sRef_storeState (e->sref);
3912 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
3913 ctype ct, /*@only@*/ fileloc loc)
3915 uentry e = uentry_alloc ();
3917 /* e->shallowCopy = FALSE; */
3921 e->sref = sRef_makeUnknown ();
3922 e->storageclass = SCNONE;
3924 if (fileloc_isSpec (loc))
3926 e->whereSpecified = loc;
3927 e->whereDeclared = fileloc_undefined;
3931 e->whereDeclared = loc;
3932 e->whereSpecified = fileloc_undefined;
3935 e->whereDefined = fileloc_undefined;
3937 e->isPrivate = FALSE;
3938 e->hasNameError = FALSE;
3942 e->uses = filelocList_new ();
3944 e->info = (uinfo) dmalloc (sizeof (*e->info));
3945 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3946 e->info->iter->access = access;
3947 e->info->iter->mods = sRefSet_undefined;
3948 e->info->iter->globs = globSet_undefined;
3950 sRef_storeState (e->sref);
3955 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
3956 /*@only@*/ fileloc loc)
3958 uentry e = uentry_alloc ();
3960 /* e->shallowCopy = FALSE; */
3961 e->ukind = KENDITER;
3962 e->storageclass = SCNONE;
3964 e->utype = ctype_unknown;
3965 e->sref = sRef_makeUnknown ();
3967 if (fileloc_isSpec (loc))
3969 e->whereSpecified = loc;
3970 e->whereDeclared = fileloc_undefined;
3974 e->whereDeclared = loc;
3975 e->whereSpecified = fileloc_undefined;
3978 e->whereDefined = fileloc_undefined;
3980 e->isPrivate = FALSE;
3981 e->hasNameError = FALSE;
3985 e->uses = filelocList_new ();
3987 e->info = (uinfo) dmalloc (sizeof (*e->info));
3988 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3989 e->info->enditer->access = access;
3990 sRef_storeState (e->sref);
3995 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4003 uentry_undump (ekind kind, fileloc loc, char **s)
4011 ue = uentry_makeElipsisMarker ();
4015 ctype ct = ctype_undump (s);
4031 if (optCheckChar (s, '@'))
4033 tkind = vkind_fromInt (getInt (s));
4041 if (optCheckChar (s, '$'))
4043 defstate = SS_UNKNOWN;
4044 isnull = NS_UNKNOWN;
4045 aliased = AK_IMPTEMP;
4047 checked = CH_UNKNOWN;
4049 else if (optCheckChar (s, '&'))
4051 defstate = SS_DEFINED;
4052 isnull = NS_UNKNOWN;
4053 aliased = AK_IMPTEMP;
4055 checked = CH_UNKNOWN;
4057 else if (optCheckChar (s, '^'))
4059 defstate = SS_UNKNOWN;
4060 isnull = NS_UNKNOWN;
4061 aliased = AK_IMPTEMP;
4063 checked = CH_UNKNOWN;
4067 defstate = sstate_fromInt (getInt (s));
4068 advanceField (s); isnull = nstate_fromInt (getInt (s));
4069 advanceField (s); aliased = alkind_fromInt (getInt (s));
4071 if (optCheckChar (s, '&'))
4074 checked = CH_UNKNOWN;
4078 advanceField (s); exp = exkind_fromInt (getInt (s));
4079 advanceField (s); checked = (chkind) (getInt (s));
4084 name = getStringWord (s);
4086 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4087 isnull, aliased, exp,
4088 checked, fileloc_copy (loc));
4101 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
4102 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
4103 advanceField (s); defstate = sstate_fromInt (getInt (s));
4104 advanceField (s); isnull = nstate_fromInt (getInt (s));
4105 advanceField (s); aliased = alkind_fromInt (getInt (s));
4106 advanceField (s); exp = exkind_fromInt (getInt (s));
4107 advanceField (s); rtype = ctype_undump (s);
4109 name = getStringWord (s);
4111 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
4112 aliased, exp, defstate, isnull,
4113 fileloc_copy (loc));
4130 specialClauses specclauses;
4132 if (optCheckChar (s, '$'))
4134 defstate = SS_DEFINED;
4135 isnull = NS_UNKNOWN;
4136 exitCode = XK_UNKNOWN;
4138 nullPred = QU_UNKNOWN;
4142 advanceField (s); defstate = sstate_fromInt (getInt (s));
4143 advanceField (s); isnull = nstate_fromInt (getInt (s));
4144 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
4145 advanceField (s); specc = specCode_fromInt (getInt (s));
4146 advanceField (s); nullPred = qual_fromInt (getInt (s));
4149 if (optCheckChar (s, '$'))
4152 globs = globSet_undefined;
4154 mods = sRefSet_undefined;
4156 else if (optCheckChar (s, '^'))
4159 globs = globSet_undefined;
4161 mods = sRefSet_undefined;
4165 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
4166 advanceField (s); globs = globSet_undump (s);
4167 advanceField (s); hasMods = bool_fromInt (getInt (s));
4168 advanceField (s); mods = sRefSet_undump (s);
4171 if (optCheckChar (s, '$'))
4178 advanceField (s); ak = alkind_fromInt (getInt (s));
4179 advanceField (s); exp = exkind_fromInt (getInt (s));
4182 advanceField (s); access = typeIdSet_undump (s);
4184 if (optCheckChar (s, '@'))
4186 specclauses = specialClauses_undump (s);
4190 specclauses = specialClauses_undefined;
4193 advanceName (s); name = getStringWord (s);
4195 ue = uentry_makeFunctionBase (name, ct, access,
4198 ak, exp, defstate, isnull,
4199 exitCode, specc, nullPred,
4201 fileloc_copy (loc));
4202 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4209 advanceField (s); access = typeIdSet_undump (s);
4210 advanceName (s); name = getStringWord (s);
4212 ue = uentry_makeIterBase (name, access, ct,
4213 fileloc_copy (loc));
4220 advanceField (s); access = typeIdSet_undump (s);
4221 advanceName (s); name = getStringWord (s);
4223 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4233 if (optCheckChar (s, '$'))
4235 val = multiVal_undefined;
4236 access = typeIdSet_undefined;
4237 nullstate = NS_UNKNOWN;
4241 advanceField (s); val = multiVal_undump (s);
4242 advanceField (s); access = typeIdSet_undump (s);
4243 advanceField (s); nullstate = nstate_fromInt (getInt (s));
4246 advanceName (s); name = getStringWord (s);
4248 ue = uentry_makeConstantBase (name, ct, access,
4249 nullstate, fileloc_copy (loc), val);
4258 advanceField (s); rtype = ctype_undump (s);
4259 advanceName (s); name = getStringWord (s);
4260 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4264 llcontbuglit ("uentry_undump: invalid");
4265 ue = uentry_undefined;
4268 llcontbuglit ("uentry_undump: elips marker");
4269 ue = uentry_undefined;
4278 uentry_dump (uentry v)
4280 return (uentry_dumpAux (v, FALSE));
4284 uentry_dumpParam (uentry v)
4286 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4287 ("dump: %s", uentry_unparseFull (v)));
4289 return (uentry_dumpAux (v, TRUE));
4293 uentry_dumpAux (uentry v, bool isParam)
4295 llassert (uentry_isValid (v));
4297 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
4302 llcontbuglit ("uentry_dump: invalid entry");
4303 return cstring_undefined;
4305 return (message ("!."));
4309 vkind vk = v->info->var->kind;
4310 sstate dss = sRef_getDefState (v->sref);
4311 nstate nst = sRef_getNullState (v->sref);
4312 alkind alk = sRef_getAliasKind (v->sref);
4313 exkind exk = sRef_getExKind (v->sref);
4314 chkind chk = v->info->var->checked;
4316 DPRINTF (("Dumping var"));
4318 if (dss == SS_UNKNOWN
4319 && nst == NS_UNKNOWN
4320 && alk == AK_IMPTEMP
4321 && exk == XO_UNKNOWN
4322 && chk == CH_UNKNOWN)
4324 sdump = cstring_makeLiteral ("$");
4326 else if (dss == SS_DEFINED
4327 && nst == NS_UNKNOWN
4328 && alk == AK_IMPTEMP
4329 && exk == XO_UNKNOWN
4330 && chk == CH_UNKNOWN)
4332 sdump = cstring_makeLiteral ("&");
4334 else if (dss == SS_UNKNOWN
4335 && nst == NS_UNKNOWN
4336 && alk == AK_UNKNOWN
4337 && exk == XO_UNKNOWN
4338 && chk == CH_UNKNOWN)
4340 sdump = cstring_makeLiteral ("^");
4342 else if (exk == XO_UNKNOWN
4343 && chk == CH_UNKNOWN)
4345 sdump = message ("%d@%d@%d&",
4352 sdump = message ("%d@%d@%d@%d@%d",
4363 return (message ("%q|@%d|%q#%s",
4364 ctype_dump (v->utype),
4367 isParam ? cstring_undefined : v->uname));
4371 return (message ("%q|%q#%s",
4372 ctype_dump (v->utype),
4374 isParam ? cstring_undefined : v->uname));
4379 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
4380 ctype_dump (v->utype),
4381 ynm_unparseCode (v->info->datatype->abs),
4382 ynm_unparseCode (v->info->datatype->mut),
4383 (int) sRef_getDefState (v->sref),
4384 (int) sRef_getNullState (v->sref),
4385 (int) sRef_getAliasKind (v->sref),
4386 (int) sRef_getExKind (v->sref),
4387 ctype_dump (v->info->datatype->type),
4391 cstring sdump, gdump, adump;
4392 alkind alk = sRef_getAliasKind (v->sref);
4393 exkind exk = sRef_getExKind (v->sref);
4395 if (sRef_getDefState (v->sref) == SS_DEFINED
4396 && !nstate_isKnown (sRef_getNullState (v->sref))
4397 && !exitkind_isKnown (v->info->fcn->exitCode)
4398 && v->info->fcn->specialCode == SPC_NONE
4399 && v->info->fcn->nullPred == QU_UNKNOWN)
4401 sdump = cstring_makeLiteral ("$");
4405 sdump = message ("@%d@%d@%d@%d@%d",
4406 (int) sRef_getDefState (v->sref),
4407 (int) sRef_getNullState (v->sref),
4408 (int) v->info->fcn->exitCode,
4409 (int) v->info->fcn->specialCode,
4410 (int) v->info->fcn->nullPred);
4413 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
4415 gdump = cstring_makeLiteral ("$");
4417 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
4418 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
4420 gdump = cstring_makeLiteral ("^");
4424 gdump = message ("@%s@%q@%s@%q",
4425 bool_dump (uentry_hasGlobs (v)),
4426 globSet_dump (uentry_getGlobs (v)),
4427 bool_dump (uentry_hasMods (v)),
4428 sRefSet_dump (uentry_getMods (v)));
4431 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
4433 adump = cstring_makeLiteral ("$");
4437 adump = message ("@%d@%d", (int) alk, (int) exk);
4440 if (uentry_hasSpecialClauses (v))
4442 return (message ("%q%q%q%q@%q@%q#%s",
4443 ctype_dump (v->utype),
4447 typeIdSet_dump (uentry_accessType (v)),
4448 specialClauses_dump (v->info->fcn->specclauses),
4453 return (message ("%q%q%q%q@%q#%s",
4454 ctype_dump (v->utype),
4458 typeIdSet_dump (uentry_accessType (v)),
4463 return (message ("%q@%q#%s",
4464 ctype_dump (v->utype),
4465 typeIdSet_dump (v->info->iter->access),
4468 return (message ("%q@%q#%s",
4469 ctype_dump (v->utype),
4470 typeIdSet_dump (uentry_accessType (v)),
4477 if (multiVal_isUnknown (v->info->uconst->val)
4478 && typeIdSet_isEmpty (uentry_accessType (v))
4479 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
4481 sdump = cstring_makeLiteral ("$");
4485 sdump = message ("@%q@%q@%d",
4486 multiVal_dump (v->info->uconst->val),
4487 typeIdSet_dump (uentry_accessType (v)),
4488 (int) sRef_getNullState (v->sref));
4491 return (message ("%q%q#%s",
4492 ctype_dump (v->utype),
4499 return (message ("%q@%q#%s",
4500 ctype_dump (v->utype),
4501 ctype_dump (v->info->datatype->type), v->uname));
4508 uentry_unparseAbbrev (uentry v)
4510 if (!uentry_isVariable (v))
4512 llcontbuglit ("uentry_unparseAbbrev: not variable");
4513 return uentry_unparse (v);
4516 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
4520 uentry_unparse (uentry v)
4524 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
4525 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
4527 st = uentry_getName (v);
4529 if (cstring_isDefined (st))
4531 return (ctype_unparseDeclaration (v->utype, st));
4536 return (cstring_copy (ctype_unparse (v->utype)));
4541 uentry_unparseFull (uentry v)
4543 if (uentry_isUndefined (v))
4545 return (cstring_makeLiteral ("<undefined>"));
4547 else if (uentry_isDatatype (v))
4549 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
4551 ekind_unparse (v->ukind),
4555 ctype_isDefined (v->info->datatype->type)
4556 ? v->info->datatype->type : ctype_unknown,
4557 ynm_unparse (v->info->datatype->mut),
4558 ynm_unparse (v->info->datatype->abs),
4559 sRef_unparseState (v->sref),
4560 fileloc_unparse (v->whereSpecified),
4561 fileloc_unparse (v->whereDefined)));
4563 else if (uentry_isFunction (v))
4565 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
4566 "globs: %q / [s: %q; decl: %q; def: %q]",
4568 ekind_unparse (v->ukind),
4571 sRef_unparseFull (v->sref),
4572 sRefSet_unparse (v->info->fcn->mods),
4573 globSet_unparse (v->info->fcn->globs),
4574 fileloc_unparse (v->whereSpecified),
4575 fileloc_unparse (v->whereDeclared),
4576 fileloc_unparse (v->whereDefined)));
4578 else if (uentry_isIter (v))
4580 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
4581 ekind_unparse (v->ukind),
4584 sRef_unparseFull (v->sref),
4585 fileloc_unparse (v->whereSpecified),
4586 fileloc_unparse (v->whereDefined)));
4588 else if (uentry_isVariable (v))
4591 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
4592 "kind <%d> isout <%d> used <%d>",
4593 checkedName (v->info->var->checked),
4595 ekind_unparse (v->ukind),
4598 sRef_unparseDeep (v->sref),
4599 fileloc_unparse (v->whereSpecified),
4600 fileloc_unparse (v->whereDefined),
4601 fileloc_unparse (v->whereDeclared),
4602 (int) v->info->var->kind,
4603 (int) v->info->var->defstate,
4608 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
4609 ekind_unparse (v->ukind),
4612 sRef_unparseFull (v->sref),
4613 fileloc_unparse (v->whereSpecified),
4614 fileloc_unparse (v->whereDefined)));
4619 bool uentry_hasAccessType (uentry e)
4621 if (uentry_isValid (e))
4626 return (!typeIdSet_isEmpty (e->info->iter->access));
4628 return (!typeIdSet_isEmpty (e->info->enditer->access));
4630 return (!typeIdSet_isEmpty (e->info->fcn->access));
4633 return (!typeIdSet_isEmpty (e->info->uconst->access));
4642 typeIdSet uentry_accessType (uentry e)
4644 if (uentry_isValid (e))
4649 return (e->info->iter->access);
4651 return (e->info->enditer->access);
4653 return (e->info->fcn->access);
4656 return (e->info->uconst->access);
4662 return typeIdSet_undefined;
4666 uentry_isVariable (uentry e)
4668 return (uentry_isVar (e));
4672 uentry_isSpecified (uentry e)
4674 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
4678 uentry_isReallySpecified (uentry e)
4680 return (uentry_isValid (e)
4681 && fileloc_isRealSpec (e->whereSpecified));
4685 uentry_isVar (uentry e)
4687 return (!uentry_isUndefined (e) && e->ukind == KVAR);
4691 uentry_isFakeTag (uentry e)
4693 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
4697 uentry_isDatatype (uentry e)
4699 return (!uentry_isUndefined (e) &&
4700 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
4701 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
4705 uentry_setAbstract (uentry e)
4709 llassert (uentry_isDatatype (e)
4710 && (ynm_isMaybe (e->info->datatype->abs)));
4712 oldid = ctype_typeId (e->info->datatype->type);
4713 e->info->datatype->abs = YES;
4714 e->info->datatype->type = ctype_createAbstract (oldid);
4718 uentry_setConcrete (uentry e)
4720 llassert (uentry_isDatatype (e)
4721 && (ynm_isMaybe (e->info->datatype->abs)));
4723 e->info->datatype->abs = NO;
4727 uentry_isAbstractDatatype (uentry e)
4729 return (uentry_isDatatype (e)
4730 && (ynm_isOn (e->info->datatype->abs)));
4734 uentry_isMaybeAbstract (uentry e)
4736 return (uentry_isDatatype (e)
4737 && (ynm_isMaybe (e->info->datatype->abs)));
4741 uentry_isMutableDatatype (uentry e)
4743 bool res = uentry_isDatatype (e)
4744 && (ynm_toBoolRelaxed (e->info->datatype->mut));
4750 uentry_isRefCountedDatatype (uentry e)
4752 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
4756 uentry_isParam (uentry u)
4758 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
4759 || u->info->var->kind == VKYIELDPARAM));
4763 uentry_isExpandedMacro (uentry u)
4765 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
4769 uentry_isSefParam (uentry u)
4771 return (uentry_isVariable (u)
4772 && (u->info->var->kind == VKSEFPARAM
4773 || u->info->var->kind == VKREFSEFPARAM
4774 || u->info->var->kind == VKSEFRETPARAM
4775 || u->info->var->kind == VKREFSEFRETPARAM));
4779 uentry_isRefParam (uentry u)
4781 return (uentry_isVariable (u)
4782 && (u->info->var->kind == VKREFPARAM
4783 || u->info->var->kind == VKREFYIELDPARAM
4784 || u->info->var->kind == VKREFSEFPARAM
4785 || u->info->var->kind == VKREFSEFRETPARAM));
4789 uentry_isAnyParam (uentry u)
4791 return (uentry_isVariable (u)
4792 && ((u->info->var->kind == VKPARAM)
4793 || (u->info->var->kind == VKSEFPARAM)
4794 || (u->info->var->kind == VKYIELDPARAM)
4795 || (u->info->var->kind == VKRETPARAM)
4796 || (u->info->var->kind == VKSEFRETPARAM)));
4800 uentry_getDefState (uentry u)
4802 if (uentry_isValid (u))
4804 return (sRef_getDefState (u->sref));
4808 return (SS_UNKNOWN);
4813 uentry_isOut (uentry u)
4815 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
4816 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4820 uentry_isPartial (uentry u)
4822 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
4823 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4827 uentry_isStateSpecial (uentry u)
4829 return ((uentry_isVariable (u)
4830 && (u->info->var->defstate == SS_SPECIAL))
4831 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
4834 exitkind uentry_getExitCode (uentry ue)
4836 if (uentry_isFunction (ue))
4838 return ue->info->fcn->exitCode;
4847 uentry_nullPred (uentry u)
4849 llassert (uentry_isRealFunction (u));
4851 if (uentry_isFunction (u))
4853 return (u->info->fcn->nullPred);
4862 uentry_possiblyNull (uentry u)
4864 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
4865 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
4869 uentry_getAliasKind (uentry u)
4871 if (uentry_isValid (u))
4873 return (sRef_getAliasKind (uentry_getSref (u)));
4882 uentry_getExpKind (uentry u)
4884 if (uentry_isValid (u))
4886 return (sRef_getExKind (uentry_getSref (u)));
4895 uentry_isIter (uentry e)
4897 return (!uentry_isUndefined (e) && e->ukind == KITER);
4901 uentry_isEndIter (uentry e)
4903 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
4907 uentry_isRealFunction (uentry e)
4909 return (uentry_isFunction (e) ||
4910 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
4914 uentry_hasName (uentry e)
4916 if (uentry_isValid (e))
4918 cstring s = e->uname;
4920 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
4928 bool uentry_hasRealName (uentry e)
4930 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
4934 /*@observer@*/ globSet
4935 uentry_getGlobs (uentry l)
4937 if (uentry_isInvalid (l))
4939 return globSet_undefined;
4942 if (l->ukind != KFCN)
4944 if (l->ukind != KITER && l->ukind != KENDITER)
4946 if (l->ukind == KVAR)
4948 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
4950 ekind_unparse (l->ukind)));
4954 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
4956 ekind_unparse (l->ukind)));
4959 return globSet_undefined;
4962 return l->info->fcn->globs;
4965 /*@observer@*/ sRefSet
4966 uentry_getMods (uentry l)
4968 llassert (uentry_isValid (l));
4970 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
4972 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
4973 return sRefSet_undefined;
4976 return l->info->fcn->mods;
4980 uentry_getKind (uentry e)
4982 llassert (uentry_isValid (e));
4987 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
4989 llassert (uentry_isEitherConstant (e));
4991 return (e->info->uconst->val);
4994 /*@observer@*/ uentryList
4995 uentry_getParams (uentry l)
4997 if (uentry_isInvalid (l)) return uentryList_undefined;
5004 ctype ct = l->utype;
5006 if (ctype_isFunction (ct))
5008 return (ctype_argsFunction (ct));
5012 return uentryList_undefined;
5017 ctype ct = l->utype;
5019 llassert (ctype_isFunction (ct));
5020 return (ctype_argsFunction (ct));
5027 /*@observer@*/ cstring
5028 uentry_rawName (uentry e)
5030 if (uentry_isValid (e))
5036 return cstring_undefined;
5041 uentry_getOptName (uentry e)
5043 cstring s = uentry_getName (e);
5045 if (cstring_isDefined (s))
5047 s = cstring_appendChar (s, ' ');
5054 uentry_getName (uentry e)
5056 cstring ret = cstring_undefined;
5058 if (uentry_isValid (e))
5061 if (uentry_isAnyTag (e))
5063 ret = fixTagName (e->uname);
5065 else if (uentry_isAnyParam (e))
5067 ret = cstring_copy (fixParamName (e->uname));
5071 ret = cstring_copy (e->uname);
5078 cstring uentry_getRealName (uentry e)
5080 if (uentry_isValid (e))
5082 if (uentry_isAnyTag (e))
5084 return (cstring_undefined);
5091 return cstring_undefined;
5094 ctype uentry_getType (uentry e)
5096 if (uentry_isValid (e))
5102 return ctype_unknown;
5106 fileloc uentry_whereLast (uentry e)
5110 if (uentry_isInvalid (e))
5112 return fileloc_undefined;
5115 loc = e->whereDefined;
5117 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5122 loc = uentry_whereDeclared (e);
5124 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5129 loc = uentry_whereSpecified (e);
5133 fileloc uentry_whereEither (uentry e)
5135 if (uentry_isInvalid (e)) return fileloc_undefined;
5137 if (fileloc_isDefined (e->whereDefined)
5138 && !fileloc_isExternal (e->whereDefined))
5140 return e->whereDefined;
5142 else if (fileloc_isDefined (e->whereDeclared))
5144 return e->whereDeclared;
5148 return e->whereSpecified;
5152 fileloc uentry_whereSpecified (uentry e)
5154 if (uentry_isInvalid (e)) return fileloc_undefined;
5156 return (e->whereSpecified);
5159 fileloc uentry_whereDefined (uentry e)
5161 if (uentry_isInvalid (e)) return fileloc_undefined;
5163 return (e->whereDefined);
5166 fileloc uentry_whereDeclared (uentry e)
5168 if (uentry_isInvalid (e)) return fileloc_undefined;
5170 return (e->whereDeclared);
5173 /*@observer@*/ fileloc
5174 uentry_whereEarliest (uentry e)
5176 if (uentry_isInvalid (e)) return fileloc_undefined;
5178 if (fileloc_isDefined (e->whereSpecified))
5180 return (e->whereSpecified);
5182 else if (fileloc_isDefined (e->whereDeclared))
5184 return (e->whereDeclared);
5188 return e->whereDefined;
5193 uentry_setFunctionDefined (uentry e, fileloc loc)
5195 if (uentry_isValid (e))
5197 llassert (uentry_isFunction (e));
5199 if (fileloc_isUndefined (e->whereDeclared))
5201 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5204 if (!fileloc_isDefined (e->whereDefined))
5206 e->whereDefined = fileloc_update (e->whereDefined, loc);
5212 uentry_setDeclDef (uentry e, fileloc f)
5214 uentry_setDeclared (e, f);
5216 if (!uentry_isFunction (e)
5217 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5219 uentry_setDefined (e, f);
5224 uentry_setDeclaredForce (uentry e, fileloc f)
5226 llassert (uentry_isValid (e));
5227 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5231 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5233 llassert (uentry_isValid (e));
5234 fileloc_free (e->whereDeclared);
5235 e->whereDeclared = f;
5239 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5243 llassert (uentry_isValid (e));
5244 oldloc = e->whereDeclared;
5246 if (fileloc_isDefined (oldloc))
5248 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5250 e->whereDeclared = f;
5251 fileloc_free (oldloc);
5260 e->whereDeclared = f;
5261 fileloc_free (oldloc);
5266 uentry_setDeclared (uentry e, fileloc f)
5270 llassert (uentry_isValid (e));
5271 oldloc = e->whereDeclared;
5273 if (fileloc_isDefined (oldloc))
5275 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5277 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5286 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5291 uentry_clearDefined (uentry e)
5293 if (uentry_isValid (e))
5295 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5300 uentry_setDefined (uentry e, fileloc f)
5304 llassert (uentry_isValid (e));
5305 oldloc = e->whereDefined;
5307 if (fileloc_isDefined (oldloc))
5309 if (fileloc_isLib (oldloc)
5310 || fileloc_isImport (oldloc)
5311 || fileloc_isBuiltin (oldloc)
5312 || fileloc_isPreproc (oldloc))
5314 e->whereDefined = fileloc_update (e->whereDefined, f);
5318 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5324 if (optgenerror (FLG_REDEF,
5325 message ("%s %q redefined",
5326 ekind_capName (e->ukind),
5327 uentry_getName (e)),
5330 llgenindentmsg (message ("Previous definition of %q",
5331 uentry_getName (e)),
5339 e->whereDefined = fileloc_update (e->whereDefined, f);
5344 uentry_isCodeDefined (uentry e)
5346 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
5350 uentry_isDeclared (uentry e)
5352 if (uentry_isValid (e))
5354 return (fileloc_isDefined (e->whereDeclared));
5360 sRef uentry_getSref (uentry e)
5362 /* not true, used for functions too (but shouldn't be? */
5363 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
5365 if (uentry_isInvalid (e)) return sRef_undefined;
5370 sRef uentry_getOrigSref (uentry e)
5372 if (uentry_isValid (e))
5374 sRef sr = sRef_copy (uentry_getSref (e));
5376 sRef_resetState (sr);
5377 sRef_clearDerived (sr);
5379 if (uentry_isVariable (e))
5381 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
5382 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
5389 return sRef_undefined;
5394 ** requires: uentry e is not in a hashed symbol table
5398 uentry_setName (uentry e, /*@only@*/ cstring n)
5400 llassert (uentry_isValid (e));
5402 cstring_free (e->uname);
5407 uentry_setType (uentry e, ctype t)
5409 if (uentry_isValid (e))
5412 sRef_setType (e->sref, t);
5417 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
5420 ctype rettype = ctype_unknown;
5422 llassert (uentry_isValid (ue));
5424 rct = ctype_realType (ue->utype);
5426 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
5428 uentry_makeVarFunction (ue);
5431 llassert (uentry_isFunction (ue));
5433 if (ctype_isFunction (rct))
5435 rettype = ctype_returnValue (rct);
5438 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
5442 uentry_setRefParam (uentry e)
5445 if (!uentry_isVar (e))
5447 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5451 if (e->info->var->kind == VKSEFPARAM)
5453 e->info->var->kind = VKREFSEFPARAM;
5455 else if (e->info->var->kind == VKSEFRETPARAM)
5457 e->info->var->kind = VKREFSEFRETPARAM;
5459 else if (e->info->var->kind == VKYIELDPARAM)
5461 e->info->var->kind = VKREFYIELDPARAM;
5465 e->info->var->kind = VKREFPARAM;
5471 uentry_setParam (uentry e)
5473 if (!uentry_isVar (e))
5475 if (uentry_isElipsisMarker (e))
5481 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5488 if (e->info->var->kind == VKYIELDPARAM
5489 || e->info->var->kind == VKSEFPARAM
5490 || e->info->var->kind == VKSEFRETPARAM)
5496 e->info->var->kind = VKPARAM;
5500 e->uname = makeParam (e->uname);
5501 cstring_free (oldname);
5506 uentry_setSref (uentry e, sRef s)
5508 if (uentry_isValid (e))
5510 if (sRef_isValid (e->sref))
5512 sRef_mergeStateQuietReverse (e->sref, s);
5516 e->sref = sRef_saveCopy (s);
5522 uentry_getAbstractType (uentry e)
5524 llassert (uentry_isDatatype (e));
5527 ** This assertion removed.
5528 ** Okay to have undefined type, for system types
5530 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
5531 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
5536 if (ctype_isUndefined (e->info->datatype->type))
5538 return ctype_unknown;
5542 ** Sadly, a kludge...
5545 if (ctype_isUserBool (e->info->datatype->type)) {
5549 return e->info->datatype->type;
5552 ctype uentry_getRealType (uentry e)
5555 typeId uid = USYMIDINVALID;
5557 if (uentry_isInvalid (e))
5559 return ctype_unknown;
5562 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5564 if (uentry_isAnyTag (e))
5569 if (uentry_isAbstractType (e))
5571 ct = uentry_getAbstractType (e);
5573 if (ctype_isManifestBool (ct)) {
5577 llassert (ctype_isUA (ct));
5579 uid = ctype_typeId (ct);
5581 if (!context_hasAccess (uid))
5587 ct = uentry_getType (e);
5589 /* if (ctype_isUserBool (ct)) return ct; */
5591 if (ctype_isManifestBool (ct)) {
5595 if (ctype_isUA (ct))
5597 usymId iid = ctype_typeId (ct);
5599 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5601 llcontbug (message ("uentry_getRealType: recursive type! %s",
5602 ctype_unparse (ct)));
5607 /* evs 2000-07-25: possible infinite recursion ? */
5608 uentry ue2 = usymtab_getTypeEntry (iid);
5609 llassertprint (ue2 != e, ("Bad recursion: %s", uentry_unparseFull (e)));
5611 return uentry_getRealType (ue2);
5620 ctype uentry_getForceRealType (uentry e)
5623 typeId uid = USYMIDINVALID;
5625 if (uentry_isInvalid (e))
5627 return ctype_unknown;
5630 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5632 if (uentry_isAnyTag (e))
5637 if (uentry_isAbstractType (e))
5639 ct = uentry_getAbstractType (e);
5640 llassert (ctype_isUA (ct));
5642 uid = ctype_typeId (ct);
5643 /* no check for access! */
5646 ct = uentry_getType (e);
5648 /* evs 2000-07-25 */
5649 /* if (ctype_isUserBool (ct)) return ct; */
5651 if (ctype_isManifestBool (ct)) {
5655 if (ctype_isUA (ct))
5657 usymId iid = ctype_typeId (ct);
5659 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5661 llcontbug (message ("uentry_getRealType: recursive type! %s",
5662 ctype_unparse (ct)));
5667 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
5676 uentry uentry_nameCopy (cstring name, uentry e)
5678 uentry enew = uentry_alloc ();
5680 llassert (uentry_isValid (e));
5682 /* enew->shallowCopy = FALSE; */
5683 enew->ukind = e->ukind;
5685 enew->utype = e->utype;
5686 enew->whereSpecified = fileloc_copy (e->whereSpecified);
5687 enew->whereDefined = fileloc_copy (e->whereDefined);
5688 enew->whereDeclared = fileloc_copy (e->whereDeclared);
5689 enew->sref = sRef_copy (e->sref);
5690 enew->used = e->used;
5692 enew->isPrivate = e->isPrivate;
5693 enew->hasNameError = FALSE;
5695 enew->uses = filelocList_new ();
5697 enew->storageclass = e->storageclass;
5698 enew->info = uinfo_copy (e->info, e->ukind);
5704 uentry_setDatatype (uentry e, usymId uid)
5706 llassert (uentry_isDatatype (e));
5708 if (uentry_isAbstractType (e))
5710 e->info->datatype->type = ctype_createAbstract (uid);
5714 e->info->datatype->type = ctype_createUser (uid);
5719 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
5720 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
5723 llassert (uentry_isValid (e));
5725 if (fileloc_isSpec (f) || fileloc_isImport (f))
5727 e->whereSpecified = f;
5728 e->whereDeclared = fileloc_undefined;
5729 e->whereDefined = fileloc_undefined;
5733 e->whereSpecified = fileloc_undefined;
5734 e->whereDeclared = f;
5735 e->whereDefined = fileloc_undefined;
5740 ucinfo_free (/*@only@*/ ucinfo u)
5742 multiVal_free (u->val);
5747 uvinfo_free (/*@only@*/ uvinfo u)
5753 udinfo_free (/*@only@*/ udinfo u)
5759 ufinfo_free (/*@only@*/ ufinfo u)
5761 globSet_free (u->globs);
5762 sRefSet_free (u->mods);
5763 specialClauses_free (u->specclauses);
5769 uiinfo_free (/*@only@*/ uiinfo u)
5775 ueinfo_free (/*@only@*/ ueinfo u)
5780 static /*@only@*/ ucinfo
5781 ucinfo_copy (ucinfo u)
5783 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
5785 ret->val = multiVal_copy (u->val);
5786 ret->access = u->access;
5791 static /*@only@*/ uvinfo
5792 uvinfo_copy (uvinfo u)
5794 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
5796 ret->kind = u->kind;
5797 ret->nullstate = u->nullstate;
5798 ret->defstate = u->defstate;
5799 ret->checked = u->checked;
5804 static /*@only@*/ udinfo
5805 udinfo_copy (udinfo u)
5807 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
5811 ret->type = u->type;
5816 static /*@only@*/ ufinfo
5817 ufinfo_copy (ufinfo u)
5819 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
5821 ret->hasGlobs = u->hasGlobs;
5822 ret->hasMods = u->hasMods;
5823 ret->exitCode = u->exitCode;
5824 ret->specialCode = u->specialCode;
5825 ret->nullPred = u->nullPred;
5826 ret->access = u->access;
5827 ret->globs = globSet_newCopy (u->globs);
5828 ret->mods = sRefSet_newCopy (u->mods);
5829 ret->defparams = u->defparams;
5830 ret->specclauses = specialClauses_copy (u->specclauses);
5835 static /*@only@*/ uiinfo
5836 uiinfo_copy (uiinfo u)
5838 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
5840 ret->access = u->access;
5841 ret->globs = globSet_newCopy (u->globs);
5842 ret->mods = sRefSet_newCopy (u->mods);
5847 static /*@only@*/ ueinfo
5848 ueinfo_copy (ueinfo u)
5850 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
5852 ret->access = u->access;
5857 uinfo_free (uinfo u, ekind kind)
5862 case KCONST: ucinfo_free (u->uconst); break;
5863 case KVAR: uvinfo_free (u->var); break;
5867 case KDATATYPE: udinfo_free (u->datatype); break;
5868 case KFCN: ufinfo_free (u->fcn); break;
5869 case KITER: uiinfo_free (u->iter); break;
5870 case KENDITER: ueinfo_free (u->enditer); break;
5871 case KELIPSMARKER: break;
5872 case KINVALID: break;
5878 static /*@only@*/ /*@null@*/ uinfo
5879 uinfo_copy (uinfo u, ekind kind)
5881 if (kind == KELIPSMARKER || kind == KINVALID)
5887 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
5892 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
5893 case KVAR: ret->var = uvinfo_copy (u->var); break;
5897 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
5898 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
5899 case KITER: ret->iter = uiinfo_copy (u->iter); break;
5900 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
5908 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
5910 filelocList_free (e->uses);
5911 cstring_free (e->uname);
5913 uinfo_free (e->info, e->ukind);
5915 fileloc_free (e->whereSpecified);
5916 fileloc_free (e->whereDefined);
5917 fileloc_free (e->whereDeclared);
5923 extern void uentry_markOwned (/*@owned@*/ uentry u)
5925 sfreeEventually (u);
5929 uentry_free (/*@only@*/ uentry e)
5931 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
5933 uentry_reallyFree (e);
5938 ** For uentry's in the global or file scope
5942 uentry_freeComplete (/*@only@*/ uentry e)
5944 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
5946 /*@i@*/ sRef_free (e->sref);
5947 e->sref = sRef_undefined;
5948 uentry_reallyFree (e);
5953 ** requires old->kind != new->kind, old->uname = new->uname
5957 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
5959 llassert (uentry_isValid (old));
5960 llassert (uentry_isValid (unew));
5962 if (uentry_isEitherConstant (unew)
5963 && (fileloc_isPreproc (uentry_whereDeclared (old))
5964 || ctype_isUnknown (old->utype))
5965 && !uentry_isSpecified (old))
5973 if (!uentry_isDeclared (old))
5975 if (uentry_isSpecified (old))
5977 if (uentry_isSpecified (unew))
5979 llbuglit ("Respecification!");
5981 else if (uentry_isDeclared (unew))
5985 message ("%s %q inconsistently declared as %s: %t",
5986 ekind_capName (old->ukind),
5987 uentry_getName (unew),
5988 ekind_unparseLong (unew->ukind),
5990 uentry_whereDeclared (unew)))
5992 uentry_showWhereLast (old);
6004 message ("%s %q inconsistently declared as %s: %t",
6005 ekind_capName (old->ukind),
6006 uentry_getName (unew),
6007 ekind_unparseLong (unew->ukind),
6009 uentry_whereDeclared (unew)))
6011 uentry_showWhereLast (old);
6017 llassert (uentry_isDeclared (unew));
6021 message ("%s %q inconsistently redeclared as %s",
6022 ekind_capName (old->ukind),
6023 uentry_getName (unew),
6024 ekind_unparseLong (unew->ukind)),
6025 uentry_whereDeclared (unew)))
6027 uentry_showWhereLast (old);
6033 uentry_copyInto (old, unew);
6037 ** def is the definition of spec, modifies spec
6039 ** reports any inconsistencies
6040 ** returns the summary of all available information
6041 ** if spec and def are inconsistent, def is returned
6045 uentry_showWhereLast (uentry spec)
6047 if (uentry_isValid (spec))
6049 if (fileloc_isDefined (spec->whereDefined)
6050 && !fileloc_isLib (spec->whereDefined)
6051 && !fileloc_isPreproc (spec->whereDefined))
6053 llgenindentmsg (message ("Previous definition of %q: %t",
6054 uentry_getName (spec),
6055 uentry_getType (spec)),
6056 uentry_whereDefined (spec));
6058 else if (uentry_isDeclared (spec))
6060 llgenindentmsg (message ("Previous declaration of %q: %t",
6061 uentry_getName (spec),
6062 uentry_getType (spec)),
6063 uentry_whereDeclared (spec));
6065 else if (uentry_isSpecified (spec))
6067 if (uentry_hasName (spec))
6069 llgenindentmsg (message ("Specification of %q: %t",
6070 uentry_getName (spec),
6071 uentry_getType (spec)),
6072 uentry_whereSpecified (spec));
6076 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6077 uentry_whereSpecified (spec));
6082 /* nothing to show */
6088 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6090 fileloc loc = uentry_whereDefined (ce);
6092 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6094 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6098 loc = uentry_whereSpecified (ce);
6100 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6102 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6107 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6109 if (uentry_isDeclared (spec))
6111 llgenindentmsg (message ("Previous declaration of %q: %q",
6112 uentry_getName (spec), extra),
6113 uentry_whereDeclared (spec));
6115 else if (uentry_isSpecified (spec))
6117 llgenindentmsg (message ("Specification of %q: %q",
6118 uentry_getName (spec), extra),
6119 uentry_whereSpecified (spec));
6123 cstring_free (extra);
6128 uentry_showWhereDeclared (uentry spec)
6130 if (uentry_isDeclared (spec))
6132 if (uentry_hasName (spec))
6134 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6135 uentry_whereDeclared (spec));
6139 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6142 else if (uentry_isSpecified (spec))
6144 if (uentry_hasName (spec))
6146 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6147 uentry_whereSpecified (spec));
6151 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6156 /* nothing to show */
6162 uentry_showWhereAny (uentry spec)
6164 if (uentry_isDeclared (spec))
6166 if (uentry_hasName (spec))
6168 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6169 uentry_whereDeclared (spec));
6173 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6176 else if (uentry_isSpecified (spec))
6178 if (uentry_hasName (spec))
6180 llgenindentmsg (message ("Specification of %q",
6181 uentry_getName (spec)),
6182 uentry_whereSpecified (spec));
6186 llgenindentmsg (cstring_makeLiteral ("Specification"),
6187 uentry_whereSpecified (spec));
6190 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6192 if (uentry_hasName (spec))
6194 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6195 uentry_whereDefined (spec));
6199 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6204 /* nothing to show */
6209 uentry_showWhereDefined (uentry spec)
6211 if (uentry_isCodeDefined (spec))
6213 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6214 uentry_whereDefined (spec));
6219 uentry_showWhereLastPlain (uentry spec)
6221 if (uentry_isDeclared (spec))
6223 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6224 uentry_whereDeclared (spec));
6226 else if (uentry_isSpecified (spec))
6228 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6229 uentry_whereSpecified (spec));
6237 uentry_showWhereLastVal (uentry spec, cstring val)
6239 if (uentry_isDeclared (spec))
6241 llgenindentmsg (message ("Previous declaration of %q: %s",
6242 uentry_getName (spec), val),
6243 uentry_whereDeclared (spec));
6245 else if (uentry_isSpecified (spec))
6247 llgenindentmsg (message ("Specification of %q: %s",
6248 uentry_getName (spec), val),
6249 uentry_whereSpecified (spec));
6257 uentry_showWhereSpecified (uentry spec)
6259 if (uentry_isSpecified (spec))
6261 if (uentry_hasName (spec))
6263 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6264 uentry_whereSpecified (spec));
6268 llgenindentmsg (cstring_makeLiteral ("Specification"),
6269 uentry_whereSpecified (spec));
6272 else if (uentry_isDeclared (spec))
6274 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6275 uentry_whereDeclared (spec));
6279 /* nothing to show */
6284 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6286 if (uentry_isSpecified (spec))
6288 if (uentry_hasName (spec))
6290 llgenindentmsg (message ("Specification of %q: %q",
6291 uentry_getName (spec), s),
6292 uentry_whereSpecified (spec));
6296 llgenindentmsg (message ("Specification: %q", s),
6297 uentry_whereSpecified (spec));
6300 else if (uentry_isDeclared (spec))
6302 llgenindentmsg (message ("Declaration of %q: %q",
6303 uentry_getName (spec), s),
6304 uentry_whereDeclared (spec));
6308 llgenindentmsg (message ("Previous: %q", s),
6309 uentry_whereLast (spec));
6318 checkStructConformance (uentry old, uentry unew)
6321 uentryList fold, fnew;
6324 ** requires: types of old and new are structs or unions
6327 llassert (uentry_isValid (old));
6328 llassert (uentry_isValid (unew));
6330 oldr = ctype_realType (old->utype);
6331 fold = ctype_getFields (oldr);
6333 newr = ctype_realType (unew->utype);
6334 fnew = ctype_getFields (newr);
6336 if (!uentryList_matchFields (fold, fnew))
6338 if (fileloc_equal (uentry_whereLast (old),
6339 uentry_whereLast (unew)))
6347 message ("%q %q %rdeclared with fields { %q }, %s "
6348 "with fields { %q }",
6349 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
6350 uentry_getName (old),
6351 uentry_isDeclared (old),
6352 uentryList_unparseAbbrev (fnew),
6353 uentry_specOrDefName (old),
6354 uentryList_unparseAbbrev (fold)),
6355 uentry_whereDeclared (unew)))
6357 uentry_showWhereLastPlain (old);
6358 uentryList_showFieldDifference (fold, fnew);
6362 old->utype = unew->utype;
6367 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6370 ** requires old and new are enums
6373 ctype rold = ctype_realType (old->utype);
6374 ctype rnew = ctype_realType (unew->utype);
6375 enumNameList eold = ctype_elist (rold);
6376 enumNameList enew = ctype_elist (rnew);
6378 if (!enumNameList_match (eold, enew))
6382 message ("Enum %q declared with members { %q } but "
6383 "specified with members { %q }",
6384 uentry_getName (old),
6385 enumNameList_unparse (enew),
6386 enumNameList_unparse (eold)),
6387 uentry_whereDeclared (unew)))
6389 uentry_showWhereSpecified (old);
6390 old->utype = unew->utype;
6396 ** either oldCurrent or newCurrent may be undefined!
6400 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
6401 uentry unew, uentry newCurrent, ctype newType,
6404 bool hasError = FALSE;
6406 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
6408 if (uentry_hasName (newCurrent))
6410 hasError = optgenerror
6412 message ("Parameter %d, %q, of function %q has inconsistent type: "
6413 "declared %t, %s %t",
6414 paramno + 1, uentry_getName (newCurrent),
6415 uentry_getName (unew),
6416 newType, uentry_specOrDefName (old), oldType),
6417 uentry_whereDeclared (newCurrent));
6421 hasError = optgenerror
6423 message ("Parameter %d of function %q has inconsistent type: "
6424 "declared %t, %s %t",
6425 paramno + 1, uentry_getName (unew),
6426 newType, uentry_specOrDefName (old), oldType),
6427 uentry_whereDeclared (newCurrent));
6429 DPRINTF (("type: %s / %s",
6430 ctype_unparse (newType),
6431 ctype_unparse (ctype_realType (newType))));
6436 if (uentry_isDeclared (unew))
6438 hasError = optgenerror
6440 message ("Parameter %d of function %s has inconsistent type: "
6441 "declared %t, %s %t",
6442 paramno + 1, unew->uname,
6443 newType, uentry_specOrDefName (old), oldType),
6444 uentry_whereDeclared (unew));
6448 hasError = optgenerror
6450 message ("Parameter %d of function %s has inconsistent type: "
6451 "declared %t, %s %t",
6452 paramno + 1, unew->uname,
6453 newType, uentry_specOrDefName (old), oldType),
6454 uentry_whereDeclared (unew));
6460 if (!uentry_isUndefined (oldCurrent))
6462 if (!uentry_isUndefined (newCurrent)
6463 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
6465 uentry_showWhereLast (oldCurrent);
6469 uentry_showWhereLastPlain (old);
6472 uentry_setType (oldCurrent, newType);
6476 uentry_showWhereLastPlain (old);
6482 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6486 message ("Function %s %rdeclared with %d arg%p, %s with %d",
6488 uentry_isDeclared (old),
6489 uentryList_size (uentry_getParams (unew)),
6490 uentry_specOrDefName (old),
6491 uentryList_size (uentry_getParams (old))),
6492 uentry_whereDeclared (unew)))
6494 uentry_showWhereLastPlain (old);
6499 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6503 message ("Function %s inconsistently %rdeclared to return %t",
6505 uentry_isDeclared (old),
6506 ctype_returnValue (unew->utype)),
6507 uentry_whereDeclared (unew)))
6509 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
6513 static cstring paramStorageName (uentry ue)
6515 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
6518 static cstring fcnErrName (uentry ue)
6520 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
6523 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
6525 if (uentry_isVar (ue))
6527 return (checkedName (ue->info->var->checked));
6531 return (cstring_makeLiteralTemp ("<checked invalid>"));
6535 static cstring checkedName (chkind checked)
6539 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
6540 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
6541 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
6542 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
6543 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
6549 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
6554 if (uentry_isVar (unew))
6556 llassert (uentry_isVar (old));
6558 oldState = old->info->var->nullstate;
6559 newState = unew->info->var->nullstate;
6563 oldState = sRef_getNullState (old->sref);
6564 newState = sRef_getNullState (unew->sref);
6567 if (oldState == NS_ABSNULL)
6569 if (uentry_isVar (old))
6571 old->info->var->nullstate = newState;
6574 sRef_mergeNullState (old->sref, newState);
6576 else if (newState == NS_UNKNOWN)
6578 if (completeConform && newState != oldState
6579 && uentry_isReallySpecified (old))
6583 message ("%s %q specified as %s, but declared without %s qualifier",
6584 ekind_capName (unew->ukind),
6585 uentry_getName (unew),
6586 nstate_unparse (oldState),
6587 nstate_unparse (oldState)),
6588 uentry_whereDeclared (unew)))
6590 uentry_showWhereSpecified (old);
6594 if (uentry_isVar (unew))
6596 unew->info->var->nullstate = oldState;
6599 sRef_mergeNullState (unew->sref, oldState);
6601 else if (newState == NS_POSNULL)
6603 if (oldState == NS_MNOTNULL
6604 && (ctype_isUA (unew->utype)
6605 || (uentry_isFunction (unew)
6606 && ctype_isUA (ctype_returnValue (unew->utype)))))
6608 if (uentry_isVar (unew))
6610 unew->info->var->nullstate = oldState;
6613 sRef_mergeNullState (unew->sref, oldState);
6617 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
6618 || oldState == NS_UNKNOWN)
6625 ("%s %q inconsistently %rdeclared %s possibly null storage, "
6627 uentry_ekindName (unew),
6628 uentry_getName (unew),
6629 uentry_isDeclared (old),
6631 uentry_specOrDefName (old),
6632 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
6633 uentry_whereDeclared (unew)))
6635 uentry_showWhereSpecified (old);
6640 if (uentry_isVar (old))
6642 old->info->var->nullstate = newState;
6645 sRef_mergeNullState (old->sref, newState);
6648 else if (newState == NS_MNOTNULL)
6650 if (oldState != NS_MNOTNULL)
6656 message ("%s %q inconsistently %rdeclared %s notnull storage, "
6657 "%s without notnull qualifier",
6658 uentry_ekindName (unew),
6659 uentry_getName (unew),
6660 uentry_isDeclared (old),
6662 uentry_specOrDefName (old)),
6663 uentry_whereDeclared (unew)))
6665 uentry_showWhereSpecified (old);
6669 if (uentry_isVar (old))
6671 old->info->var->nullstate = newState;
6674 sRef_mergeNullState (old->sref, newState);
6679 if (uentry_isVar (unew))
6681 unew->info->var->nullstate = oldState;
6684 sRef_mergeNullState (unew->sref, oldState);
6689 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6690 bool mustConform, bool completeConform)
6696 if (uentry_isVar (old) && uentry_isVar (unew))
6698 oldState = old->info->var->defstate;
6699 newState = unew->info->var->defstate;
6704 oldState = sRef_getDefState (old->sref);
6705 newState = sRef_getDefState (unew->sref);
6708 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
6714 message ("%s %q inconsistently %rdeclared %s %s %s, "
6716 uentry_ekindName (unew),
6717 uentry_getName (unew),
6718 uentry_isDeclared (old),
6720 sstate_unparse (newState),
6721 paramStorageName (unew),
6722 uentry_specOrDefName (old),
6724 sstate_unparse (oldState),
6725 paramStorageName (unew)),
6726 uentry_whereDeclared (unew)))
6728 uentry_showWhereSpecified (old);
6732 if (vars) old->info->var->defstate = newState;
6733 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
6738 && (newState != oldState) && (oldState != SS_DEFINED)
6739 && uentry_isReallySpecified (old))
6743 message ("%s %q specified as %s, but declared without %s qualifier",
6744 ekind_capName (unew->ukind),
6745 uentry_getName (unew),
6746 sstate_unparse (oldState),
6747 sstate_unparse (oldState)),
6748 uentry_whereDeclared (unew)))
6750 uentry_showWhereSpecified (old);
6754 if (vars) unew->info->var->defstate = oldState;
6755 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
6760 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6761 bool mustConform, bool completeConform)
6766 oldKind = sRef_getAliasKind (old->sref);
6767 newKind = sRef_getAliasKind (unew->sref);
6769 if (alkind_isImplicit (newKind)
6770 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
6772 if (completeConform && !alkind_equal (newKind, oldKind)
6773 && uentry_isReallySpecified (old))
6777 message ("%s %q specified as %s, but declared without "
6778 "explicit alias qualifier",
6779 ekind_capName (unew->ukind),
6780 uentry_getName (unew),
6781 alkind_unparse (oldKind)),
6782 uentry_whereDeclared (unew)))
6784 uentry_showWhereSpecified (old);
6789 ** This really shouldn't be necessary, but it is!
6790 ** Function params (?) use new here.
6793 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
6797 if (alkind_isKnown (newKind))
6799 if (!alkind_equal (oldKind, newKind))
6801 if (alkind_isKnown (oldKind))
6806 message ("%s %q inconsistently %rdeclared %s %s storage, "
6808 uentry_ekindName (unew),
6809 uentry_getName (unew),
6810 uentry_isDeclared (old),
6812 alkind_unparse (newKind),
6813 uentry_specOrDefName (old),
6814 alkind_unparse (oldKind)),
6815 uentry_whereDeclared (unew)))
6817 uentry_showWhereSpecified (old);
6819 sRef_setAliasKind (old->sref, AK_ERROR,
6820 uentry_whereDeclared (unew));
6824 sRef_setAliasKind (old->sref, newKind,
6825 uentry_whereDeclared (unew));
6830 if (!(alkind_isImplicit (newKind)))
6833 !uentry_isFunction (unew) &&
6836 message ("%s %q inconsistently %rdeclared %s %s storage, "
6837 "implicitly %s as temp storage",
6838 uentry_ekindName (unew),
6839 uentry_getName (unew),
6840 uentry_isDeclared (old),
6842 alkind_unparse (newKind),
6843 uentry_specOrDefName (old)),
6844 uentry_whereDeclared (unew)))
6846 uentry_showWhereSpecified (old);
6850 sRef_setAliasKind (old->sref, newKind,
6851 uentry_whereDeclared (unew));
6853 else /* newKind is temp or refcounted */
6860 else /* newKind unknown */
6867 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6868 bool mustConform, bool completeConform)
6873 oldKind = sRef_getExKind (old->sref);
6874 newKind = sRef_getExKind (unew->sref);
6876 if (exkind_isKnown (newKind))
6878 if (oldKind != newKind)
6880 if (exkind_isKnown (oldKind))
6885 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
6886 uentry_ekindName (unew),
6887 uentry_getName (unew),
6888 uentry_isDeclared (old),
6890 exkind_unparse (newKind),
6891 uentry_specOrDefName (old),
6892 exkind_unparse (oldKind)),
6893 uentry_whereDeclared (unew)))
6895 uentry_showWhereSpecified (old);
6898 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6905 message ("%s %q inconsistently %rdeclared %s %s, "
6906 "implicitly %s without exposure qualifier",
6907 uentry_ekindName (unew),
6908 uentry_getName (unew),
6909 uentry_isDeclared (old),
6911 exkind_unparse (newKind),
6912 uentry_specOrDefName (old)),
6913 uentry_whereDeclared (unew)))
6915 uentry_showWhereSpecified (old);
6918 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6924 if (completeConform && exkind_isKnown (oldKind)
6925 && uentry_isReallySpecified (old))
6929 message ("%s %q specified as %s, but declared without "
6930 "exposure qualifier",
6931 ekind_capName (unew->ukind),
6932 uentry_getName (unew),
6933 exkind_unparse (oldKind)),
6934 uentry_whereDeclared (unew)))
6936 uentry_showWhereSpecified (old);
6940 /* yes, this is necessary! (if its a param) */
6941 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
6946 uentry_checkStateConformance (/*@notnull@*/ uentry old,
6947 /*@notnull@*/ uentry unew,
6948 bool mustConform, bool completeConform)
6950 checkDefState (old, unew, mustConform, completeConform);
6951 checkNullState (old, unew, mustConform, completeConform);
6952 checkAliasState (old, unew, mustConform, completeConform);
6953 checkExpState (old, unew, mustConform, completeConform);
6955 sRef_storeState (old->sref);
6956 sRef_storeState (unew->sref);
6960 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
6962 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
6967 llassert (uentry_isVar (old));
6968 llassert (uentry_isVar (unew));
6970 if (cstring_isEmpty (old->uname))
6972 cstring_free (old->uname);
6973 old->uname = cstring_copy (unew->uname);
6976 if (unew->info->var->kind == VKRETPARAM
6977 || unew->info->var->kind == VKSEFRETPARAM)
6979 if (old->info->var->kind != VKRETPARAM
6980 && old->info->var->kind != VKSEFRETPARAM)
6984 message ("Parameter %q inconsistently %rdeclared as "
6985 "returned parameter",
6986 uentry_getName (unew),
6987 uentry_isDeclared (old)),
6988 uentry_whereDeclared (unew)))
6990 uentry_showWhereSpecified (old);
6991 old->info->var->kind = unew->info->var->kind;
6997 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
6999 if (old->info->var->kind != VKSEFPARAM
7000 && old->info->var->kind != VKSEFRETPARAM)
7004 message ("Parameter %qinconsistently %rdeclared as "
7006 uentry_getOptName (unew),
7007 uentry_isDeclared (old)),
7008 uentry_whereDeclared (unew)))
7010 uentry_showWhereSpecified (old);
7011 old->info->var->kind = unew->info->var->kind;
7016 if (old->info->var->kind == VKSPEC)
7018 old->info->var->kind = unew->info->var->kind;
7022 unew->info->var->kind = old->info->var->kind;
7025 if (unew->info->var->checked != CH_UNKNOWN
7026 && unew->info->var->checked != old->info->var->checked)
7028 if (old->info->var->checked == CH_UNKNOWN
7029 && !fileloc_isUser (uentry_whereLast (old)))
7037 message ("Variable %q inconsistently %rdeclared as "
7038 "%s parameter (was %s)",
7039 uentry_getName (unew),
7040 uentry_isDeclared (old),
7041 checkedName (unew->info->var->checked),
7042 checkedName (old->info->var->checked)),
7043 uentry_whereDeclared (unew)))
7045 uentry_showWhereSpecified (old);
7049 old->info->var->checked = unew->info->var->checked;
7054 && (old->info->var->checked != CH_UNKNOWN)
7055 && uentry_isReallySpecified (old))
7059 message ("%s %q specified as %s, but declared without %s qualifier",
7060 ekind_capName (unew->ukind),
7061 uentry_getName (unew),
7062 checkedName (old->info->var->checked),
7063 checkedName (old->info->var->checked)),
7064 uentry_whereDeclared (unew)))
7066 uentry_showWhereSpecified (old);
7070 unew->info->var->checked = old->info->var->checked;
7073 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7076 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7078 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7083 llassert (uentry_isVar (u1));
7084 llassert (uentry_isVar (u2));
7086 if (u1->info->var->kind != u2->info->var->kind) {
7087 if (u1->info->var->kind == VKSEFRETPARAM) {
7088 if (u2->info->var->kind == VKRETPARAM) {
7091 message ("Function types are inconsistent. Parameter %d is "
7092 "sef parameter, but non-sef parameter in "
7093 "assigned function: %s",
7094 paramno, exprNode_unparse (e)),
7096 } else if (u2->info->var->kind == VKSEFPARAM) {
7099 message ("Function types are inconsistent. Parameter %d is "
7100 "returns parameter, but non-returns parameter in "
7101 "assigned function: %s",
7102 paramno, exprNode_unparse (e)),
7107 message ("Function types are inconsistent. Parameter %d is "
7108 "sef returns parameter, but non-sef returns parameter in "
7109 "assigned function: %s",
7110 paramno, exprNode_unparse (e)),
7113 } else if (u1->info->var->kind == VKRETPARAM) {
7116 message ("Function types are inconsistent. Parameter %d is "
7117 "returns parameter, but non-returns parameter in "
7118 "assigned function: %s",
7119 paramno, exprNode_unparse (e)),
7121 } else if (u1->info->var->kind == VKSEFPARAM) {
7124 message ("Function types are inconsistent. Parameter %d is "
7125 "sef parameter, but non-sef parameter in "
7126 "assigned function: %s",
7127 paramno, exprNode_unparse (e)),
7130 if (u2->info->var->kind == VKSEFRETPARAM) {
7133 message ("Function types are inconsistent. Parameter %d is "
7134 "normal parameter, but sef returns parameter in "
7135 "assigned function: %s",
7136 paramno, exprNode_unparse (e)),
7138 } else if (u2->info->var->kind == VKSEFPARAM) {
7141 message ("Function types are inconsistent. Parameter %d is "
7142 "normal parameter, but sef parameter in "
7143 "assigned function: %s",
7144 paramno, exprNode_unparse (e)),
7146 } else if (u2->info->var->kind == VKRETPARAM) {
7149 message ("Function types are inconsistent. Parameter %d is "
7150 "normal parameter, but returns parameter in "
7151 "assigned function: %s",
7152 paramno, exprNode_unparse (e)),
7160 if (u1->info->var->defstate != u2->info->var->defstate)
7164 message ("Function types are inconsistent. Parameter %d is "
7165 "%s, but %s in assigned function: %s",
7167 sstate_unparse (u1->info->var->defstate),
7168 sstate_unparse (u2->info->var->defstate),
7169 exprNode_unparse (e)),
7173 if (u1->info->var->nullstate != u2->info->var->nullstate)
7177 message ("Function types are inconsistent. Parameter %d is "
7178 "%s, but %s in assigned function: %s",
7180 nstate_unparse (u1->info->var->nullstate),
7181 nstate_unparse (u2->info->var->nullstate),
7182 exprNode_unparse (e)),
7186 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7190 message ("Function types are inconsistent. Parameter %d is "
7191 "%s, but %s in assigned function: %s",
7193 alkind_unparse (sRef_getAliasKind (u1->sref)),
7194 alkind_unparse (sRef_getAliasKind (u2->sref)),
7195 exprNode_unparse (e)),
7199 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7203 message ("Function types are inconsistent. Parameter %d is "
7204 "%s, but %s in assigned function: %s",
7206 exkind_unparse (sRef_getExKind (u1->sref)),
7207 exkind_unparse (sRef_getExKind (u2->sref)),
7208 exprNode_unparse (e)),
7214 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7215 /*@notnull@*/ uentry unew,
7216 bool mustConform, /*@unused@*/ bool completeConform)
7218 uentryList oldParams = uentry_getParams (old);
7219 uentryList newParams = uentry_getParams (unew);
7220 ctype newType = unew->utype;
7221 ctype oldType = old->utype;
7222 ctype oldRetType = ctype_unknown;
7223 ctype newRetType = ctype_unknown;
7225 if (uentry_isForward (old))
7227 mustConform = FALSE;
7228 uentry_copyInto (old, unew);
7233 ** check return values
7236 if (ctype_isKnown (oldType))
7238 llassert (ctype_isFunction (oldType));
7240 oldRetType = ctype_returnValue (oldType);
7243 if (ctype_isKnown (newType))
7245 llassert (ctype_isFunction (newType));
7247 newRetType = ctype_returnValue (newType);
7250 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
7251 && !ctype_matchDef (newRetType, oldRetType))
7253 if (mustConform) returnValueError (old, unew);
7257 if (ctype_isConj (newRetType))
7259 if (ctype_isConj (oldRetType))
7261 if (!ctype_sameAltTypes (newRetType, oldRetType))
7265 message ("Function %q inconsistently %rdeclared to "
7266 "return alternate types %s "
7267 "(types match, but alternates are not identical, "
7268 "so checking may not be correct)",
7269 uentry_getName (unew),
7270 uentry_isDeclared (old),
7271 ctype_unparse (newRetType)),
7272 uentry_whereDeclared (unew)))
7274 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
7280 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
7285 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7287 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
7289 if (exitkind_isKnown (unew->info->fcn->exitCode))
7293 message ("Function %q inconsistently %rdeclared using %s",
7294 uentry_getName (unew),
7295 uentry_isDeclared (old),
7296 exitkind_unparse (unew->info->fcn->exitCode)),
7297 uentry_whereDeclared (unew)))
7299 uentry_showWhereSpecified (old);
7304 unew->info->fcn->exitCode = old->info->fcn->exitCode;
7308 if (!qual_isUnknown (unew->info->fcn->nullPred))
7310 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
7314 message ("Function %q inconsistently %rdeclared using %s",
7315 uentry_getName (unew),
7316 uentry_isDeclared (old),
7317 qual_unparse (unew->info->fcn->nullPred)),
7318 uentry_whereDeclared (unew)))
7320 uentry_showWhereSpecified (old);
7326 unew->info->fcn->nullPred = old->info->fcn->nullPred;
7329 if (unew->info->fcn->specialCode != SPC_NONE)
7331 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
7335 message ("Function %q inconsistently %rdeclared using %s",
7336 uentry_getName (unew),
7337 uentry_isDeclared (old),
7338 specCode_unparse (unew->info->fcn->specialCode)),
7339 uentry_whereDeclared (unew)))
7341 uentry_showWhereSpecified (old);
7347 unew->info->fcn->specialCode = old->info->fcn->specialCode;
7354 if (!uentryList_sameObject (oldParams, newParams)
7355 && (!uentryList_isMissingParams (oldParams)))
7357 if (!uentryList_isMissingParams (newParams))
7360 int nparams = uentryList_size (oldParams);
7361 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
7363 if (nparams != uentryList_size (newParams))
7365 nargsError (old, unew);
7368 if (uentryList_size (newParams) < nparams)
7370 nparams = uentryList_size (newParams);
7373 while (paramno < nparams)
7375 uentry oldCurrent = uentryList_getN (oldParams, paramno);
7376 uentry newCurrent = uentryList_getN (newParams, paramno);
7377 ctype oldCurrentType = uentry_getType (oldCurrent);
7378 ctype newCurrentType = uentry_getType (newCurrent);
7380 llassert (uentry_isValid (oldCurrent)
7381 && uentry_isValid (newCurrent));
7383 if (!uentry_isElipsisMarker (oldCurrent)
7384 && !uentry_isElipsisMarker (newCurrent))
7386 checkVarConformance (oldCurrent, newCurrent,
7387 mustConform, completeConform);
7392 if (uentry_hasName (oldCurrent)
7393 && uentry_hasName (newCurrent))
7395 cstring oldname = uentry_getName (oldCurrent);
7396 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
7398 cstring nname = uentry_getName (newCurrent);
7401 if (cstring_isDefined (pfx)
7402 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
7404 oname = cstring_suffix (oldname, cstring_length (pfx));
7409 /*@-branchstate@*/ } /*@=branchstate@*/
7411 if (cstring_isDefined (pfx)
7412 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
7414 nnamefix = cstring_suffix (nname, cstring_length (pfx));
7419 /*@-branchstate@*/ } /*@=branchstate@*/
7421 if (!cstring_equal (oname, nnamefix))
7424 (FLG_DECLPARAMMATCH,
7425 message ("Definition parameter name %s does not match "
7426 "name of corresponding parameter in "
7429 uentry_whereLast (newCurrent)))
7431 uentry_showWhereLastPlain (oldCurrent);
7435 cstring_free (oldname);
7436 cstring_free (nname);
7440 if (!ctype_match (oldCurrentType, newCurrentType))
7442 paramTypeError (old, oldCurrent, oldCurrentType,
7443 unew, newCurrent, newCurrentType, paramno);
7447 if (ctype_isMissingParamsMarker (newCurrentType)
7448 || ctype_isElips (newCurrentType)
7449 || ctype_isMissingParamsMarker (oldCurrentType)
7450 || ctype_isElips (oldCurrentType))
7456 if (ctype_isConj (newCurrentType))
7458 if (ctype_isConj (oldCurrentType))
7460 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
7464 message ("Parameter %q inconsistently %rdeclared with "
7465 "alternate types %s "
7466 "(types match, but alternates are not identical, "
7467 "so checking may not be correct)",
7468 uentry_getName (newCurrent),
7469 uentry_isDeclared (oldCurrent),
7470 ctype_unparse (newCurrentType)),
7471 uentry_whereDeclared (unew)))
7473 uentry_showWhereLastVal (oldCurrent,
7474 ctype_unparse (oldCurrentType));
7482 message ("Parameter %q inconsistently %rdeclared with "
7483 "alternate types %s",
7484 uentry_getName (newCurrent),
7485 uentry_isDeclared (oldCurrent),
7486 ctype_unparse (newCurrentType)),
7487 uentry_whereDeclared (unew)))
7489 uentry_showWhereLastVal (oldCurrent,
7490 ctype_unparse (oldCurrentType));
7497 if (ctype_isConj (oldCurrentType))
7499 uentry_setType (newCurrent, oldCurrentType);
7507 ** Forgot this! detected by lclint:
7508 ** uentry.c:1257,15: Suspected infinite loop
7514 if (!uentryList_isMissingParams (newParams))
7516 if (ctype_isConj (oldRetType))
7518 old->utype = ctype_makeFunction (oldRetType,
7519 uentryList_copy (newParams));
7523 old->utype = unew->utype;
7527 checkGlobalsConformance (old, unew, mustConform, completeConform);
7528 checkModifiesConformance (old, unew, mustConform, completeConform);
7530 if (specialClauses_isDefined (unew->info->fcn->specclauses))
7532 if (!specialClauses_isDefined (old->info->fcn->specclauses))
7536 message ("Function %q redeclared using special clauses (can only "
7537 "be used in first declaration)",
7538 uentry_getName (unew)),
7539 uentry_whereDeclared (unew)))
7541 uentry_showWhereLast (old);
7546 specialClauses_checkEqual (old, unew);
7550 if (fileloc_isUndefined (old->whereDeclared))
7552 old->whereDeclared = fileloc_copy (unew->whereDeclared);
7554 else if (fileloc_isUndefined (unew->whereDeclared))
7556 unew->whereDeclared = fileloc_copy (old->whereDeclared);
7565 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
7569 llassert (uentry_isValid (ue));
7570 llassert (uentry_isEitherConstant (ue));
7572 uval = ue->info->uconst->val;
7574 if (multiVal_isDefined (uval))
7576 if (multiVal_isDefined (m))
7578 if (!multiVal_equiv (uval, m))
7582 message ("%s %q defined with inconsistent value: %q",
7583 ekind_capName (ue->ukind),
7584 uentry_getName (ue),
7585 multiVal_unparse (m)),
7588 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
7596 ue->info->uconst->val = m;
7597 multiVal_free (uval);
7602 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7605 bool typeError = FALSE;
7607 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
7609 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
7613 checkStructConformance (old, unew);
7618 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7620 llbug (message ("struct tags: bad types: %t / %t",
7621 old->utype, unew->utype));
7625 else if (uentry_isEnumTag (old))
7627 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
7629 if (mustConform) checkEnumConformance (old, unew);
7633 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7635 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
7636 ctype_unparse (unew->utype)));
7640 else if (!ctype_match (old->utype, unew->utype))
7642 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
7644 ctype realt = ctype_realType (unew->utype);
7646 if (ctype_isRealInt (realt) || ctype_isChar (realt))
7648 unew->utype = ctype_bool;
7654 typeError = optgenerror
7656 message ("%q defined as %s", uentry_getName (old),
7657 ctype_unparse (realt)),
7658 uentry_whereDeclared (unew));
7666 ctype oldr = ctype_realType (old->utype);
7667 ctype newr = ctype_realType (unew->utype);
7669 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
7671 checkStructConformance (old, unew);
7673 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
7675 checkStructConformance (old, unew);
7677 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
7679 checkEnumConformance (old, unew);
7681 else if (uentry_isConstant (old)
7682 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
7684 /* okay...for now! (should check the type is reset later... */
7688 DPRINTF (("YABA!"));
7691 message ("%s %q %rdeclared with inconsistent type: %t",
7692 ekind_capName (unew->ukind),
7693 uentry_getName (unew),
7694 uentry_isDeclared (old),
7696 uentry_whereDeclared (unew)))
7698 uentry_showWhereLast (old);
7714 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
7715 /*@notnull@*/ uentry unew,
7716 bool mustConform, bool completeConform)
7718 if (ctype_isDefined (unew->info->datatype->type))
7721 ** bool is hard coded here, since it is built into LCL.
7722 ** For now, we're stuck with LCL's types.
7725 if (ctype_isDirectBool (old->utype) &&
7726 cstring_equalLit (unew->uname, "bool"))
7728 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
7729 evs 2000-07-25: removed
7731 unew->utype = ctype_bool;
7734 if (ctype_isUnknown (old->info->datatype->type))
7736 old->info->datatype->type = unew->info->datatype->type;
7740 DPRINTF (("Old: %s / New: %s",
7741 uentry_unparseFull (old),
7742 uentry_unparseFull (unew)));
7743 DPRINTF (("Types: %s / %s",
7744 ctype_unparse (old->info->datatype->type),
7745 ctype_unparse (unew->info->datatype->type)));
7747 if (ctype_matchDef (old->info->datatype->type,
7748 unew->info->datatype->type))
7757 ("Type %q %s with inconsistent type: %t",
7758 uentry_getName (unew),
7759 uentry_reDefDecl (old, unew),
7760 unew->info->datatype->type),
7761 uentry_whereDeclared (unew)))
7763 uentry_showWhereLastExtra
7764 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
7767 old->info->datatype->type = unew->info->datatype->type;
7772 if (unew->info->datatype->abs != MAYBE)
7774 if (ynm_isOff (old->info->datatype->abs)
7775 && ynm_isOn (unew->info->datatype->abs))
7777 if (!ctype_isDirectBool (old->utype))
7782 ("Datatype %q inconsistently %rdeclared as abstract type",
7783 uentry_getName (unew),
7784 uentry_isDeclared (old)),
7785 uentry_whereDeclared (unew)))
7787 uentry_showWhereLastPlain (old);
7791 else if (ynm_isOn (old->info->datatype->abs)
7792 && ynm_isOff (unew->info->datatype->abs))
7794 if (!ctype_isDirectBool (old->utype))
7799 ("Datatype %q inconsistently %rdeclared as concrete type",
7800 uentry_getName (unew),
7801 uentry_isDeclared (old)),
7802 uentry_whereDeclared (unew)))
7804 uentry_showWhereLastPlain (old);
7815 if (ynm_isOn (old->info->datatype->abs))
7817 old->sref = unew->sref;
7818 unew->info->datatype->mut = old->info->datatype->mut;
7821 && uentry_isReallySpecified (old))
7826 ("Datatype %q specified as abstract, "
7827 "but abstract annotation not used in declaration",
7828 uentry_getName (unew)),
7829 uentry_whereDeclared (unew)))
7831 uentry_showWhereLastPlain (old);
7837 unew->info->datatype->abs = old->info->datatype->abs;
7839 if (ynm_isMaybe (unew->info->datatype->mut))
7841 if (completeConform && ynm_isOff (old->info->datatype->mut)
7842 && uentry_isReallySpecified (old))
7847 ("Datatype %q specified as immutable, "
7848 "but immutable annotation not used in declaration",
7849 uentry_getName (unew)),
7850 uentry_whereDeclared (unew)))
7852 uentry_showWhereLastPlain (old);
7856 unew->info->datatype->mut = old->info->datatype->mut;
7858 else if (ynm_isMaybe (old->info->datatype->mut))
7860 old->info->datatype->mut = unew->info->datatype->mut;
7864 if (ynm_isOn (old->info->datatype->abs))
7866 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
7870 message ("Datatype %q inconsistently %rdeclared as immutable",
7871 uentry_getName (unew),
7872 uentry_isDeclared (old)),
7873 uentry_whereDeclared (unew)))
7875 uentry_showWhereLastPlain (old);
7880 if (ynm_isOff (old->info->datatype->mut)
7881 && ynm_isOn (unew->info->datatype->mut))
7885 message ("Datatype %q inconsistently %rdeclared as mutable",
7886 uentry_getName (unew),
7887 uentry_isDeclared (old)),
7888 uentry_whereDeclared (unew)))
7890 uentry_showWhereLastPlain (old);
7895 old->info->datatype->mut = unew->info->datatype->mut;
7898 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7902 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
7903 /*@notnull@*/ uentry unew,
7905 /*@unused@*/ bool completeConform)
7907 multiVal oldVal = old->info->uconst->val;
7908 multiVal newVal = unew->info->uconst->val;
7910 if (multiVal_isDefined (oldVal))
7912 if (multiVal_isDefined (newVal))
7914 if (!multiVal_equiv (oldVal, newVal))
7919 message ("%s %q %rdeclared with inconsistent value: %q",
7920 ekind_capName (unew->ukind),
7921 uentry_getName (unew),
7922 uentry_isDeclared (old),
7923 multiVal_unparse (newVal)),
7924 uentry_whereDeclared (unew)))
7926 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
7930 unew->info->uconst->val = multiVal_copy (oldVal);
7931 multiVal_free (newVal);
7940 old->info->uconst->val = multiVal_copy (newVal);
7945 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7946 /*@notnull@*/ uentry unew, bool mustConform,
7947 bool completeConform)
7949 bool typeError = FALSE;
7950 bool fcnConformance = FALSE;
7952 if (!ekind_equal (unew->ukind, old->ukind))
7955 ** okay, only if one is a function and the other is
7956 ** a variable of type function.
7959 if (unew->ukind == KENUMCONST
7960 && old->ukind == KCONST)
7962 old->ukind = KENUMCONST;
7966 if (unew->ukind == KFCN
7967 && old->ukind == KCONST
7968 && ctype_isUnknown (old->utype))
7971 ** When a function is defined with an unparam macro
7974 uentry_copyInto (old, unew);
7978 if (uentry_isExpandedMacro (old)
7979 && uentry_isEitherConstant (unew))
7981 uentry_copyInto (old, unew);
7985 if (uentry_isEndIter (unew))
7987 if (ctype_isUnknown (old->utype))
7989 if (!uentry_isSpecified (old)
7990 && uentry_isCodeDefined (unew))
7992 if (!fileloc_withinLines (uentry_whereDefined (old),
7993 uentry_whereDeclared (unew), 2))
7994 { /* bogus! will give errors if there is too much whitespace */
7998 ("Iterator finalized name %q does not match name in "
7999 "previous iter declaration (should be end_%q). This iter "
8000 "is declared at %q",
8001 uentry_getName (unew),
8002 uentry_getName (old),
8003 fileloc_unparse (uentry_whereDefined (old))),
8004 uentry_whereDeclared (old));
8008 uentry_copyInto (old, unew);
8013 KindConformanceError (old, unew, mustConform);
8017 if (uentry_isFunction (unew))
8019 if (uentry_isVariable (old))
8021 if (!ctype_isUnknown (old->utype))
8023 if (ctype_isFunction (old->utype))
8025 uentry_makeVarFunction (old);
8026 checkFunctionConformance (old, unew, mustConform,
8028 fcnConformance = TRUE;
8032 KindConformanceError (old, unew, mustConform);
8037 if (uentry_isExpandedMacro (old))
8039 if (fileloc_isUndefined (unew->whereDefined))
8041 unew->whereDefined = fileloc_update (unew->whereDefined,
8045 uentry_copyInto (old, unew);
8046 old->used = unew->used = TRUE;
8051 /* undeclared identifier */
8052 old->utype = unew->utype;
8053 uentry_makeVarFunction (old);
8054 checkFunctionConformance (old, unew, FALSE, FALSE);
8055 fcnConformance = TRUE;
8061 KindConformanceError (old, unew, mustConform);
8064 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8066 if (!ctype_isUnknown (unew->utype))
8068 if (ctype_isFunction (unew->utype))
8070 uentry_makeVarFunction (unew);
8071 checkFunctionConformance (old, unew, mustConform, completeConform);
8072 fcnConformance = TRUE;
8076 KindConformanceError (old, unew, mustConform);
8081 KindConformanceError (old, unew, mustConform);
8086 KindConformanceError (old, unew, mustConform);
8092 ** check parameter lists for functions
8093 ** (before type errors, to get better messages
8096 if (uentry_isFunction (old))
8098 checkFunctionConformance (old, unew, mustConform, completeConform);
8099 fcnConformance = TRUE;
8103 if (!ctype_isUndefined (old->utype))
8105 typeError = checkTypeConformance (old, unew, mustConform);
8112 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8114 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8117 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8119 DPRINTF (("Check datatype: %s / %s",
8120 uentry_unparseFull (old),
8121 uentry_unparseFull (unew)));
8123 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8126 if (uentry_isVariable (old) && uentry_isVariable (unew))
8129 !ctype_matchDef (old->utype, unew->utype))
8134 ("Variable %q %s with inconsistent type (arrays and pointers are "
8135 "not identical in variable declarations): %t",
8136 uentry_getName (unew),
8137 uentry_reDefDecl (old, unew),
8139 uentry_whereDeclared (unew)))
8141 uentry_showWhereLast (old);
8144 ** Avoid repeated errors.
8147 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8149 old->whereDefined = fileloc_update (old->whereDefined,
8157 checkVarConformance (old, unew, mustConform, completeConform);
8162 /* old->utype = unew->utype; */
8166 if (ctype_isConj (old->utype))
8168 if (ctype_isConj (unew->utype))
8170 if (!ctype_sameAltTypes (old->utype, unew->utype))
8174 message ("%s %q inconsistently %rdeclared with "
8175 "alternate types %s "
8176 "(types match, but alternates are not identical, "
8177 "so checking may not be correct)",
8178 ekind_capName (uentry_getKind (old)),
8179 uentry_getName (unew),
8180 uentry_isDeclared (old),
8181 ctype_unparse (unew->utype)),
8182 uentry_whereDeclared (unew)))
8184 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
8188 old->utype = unew->utype;
8195 if (ctype_isUnknown (old->utype))
8197 old->utype = unew->utype;
8202 if (unew->ukind == old->ukind)
8205 unew->info = uinfo_copy (old->info, old->ukind);
8208 sRef_storeState (old->sref);
8209 sRef_storeState (unew->sref);
8213 ** modifies spec to reflect def, reports any inconsistencies
8217 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
8219 llassert (uentry_isValid (spec));
8220 llassert (uentry_isValid (def));
8221 llassert (cstring_equal (spec->uname, def->uname));
8223 uentry_checkConformance (spec, def, TRUE,
8224 context_getFlag (FLG_NEEDSPEC));
8226 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
8229 ** okay, declarations conform. Propagate extra information.
8232 uentry_setDefined (spec, uentry_whereDefined (def));
8233 uentry_setDeclared (spec, uentry_whereDeclared (def));
8235 if (uentry_isStatic (def))
8239 message ("%s %q specified, but declared as static",
8240 ekind_capName (def->ukind),
8241 uentry_getName (def)),
8242 uentry_whereDeclared (def)))
8244 uentry_showWhereSpecified (spec);
8249 spec->storageclass = def->storageclass;
8252 sRef_storeState (spec->sref);
8254 spec->used = def->used || spec->used;
8255 spec->hasNameError |= def->hasNameError;
8259 if (!spec->hasNameError)
8261 uentry_checkName (spec);
8270 ** Can't generate function redeclaration errors when the
8271 ** entries are merged, since we don't yet know if its the
8272 ** definition of the function.
8276 uentry_clearDecl (void)
8278 posRedeclared = uentry_undefined;
8279 fileloc_free (posLoc);
8280 posLoc = fileloc_undefined;
8284 uentry_checkDecl (void)
8286 if (uentry_isValid (posRedeclared))
8288 llassert (fileloc_isDefined (posLoc));
8290 if (uentry_isCodeDefined (posRedeclared))
8292 if (optgenerror (FLG_REDECL,
8293 message ("%s %q declared after definition",
8294 ekind_capName (posRedeclared->ukind),
8295 uentry_getName (posRedeclared)),
8298 llgenindentmsg (message ("Definition of %q",
8299 uentry_getName (posRedeclared)),
8300 posRedeclared->whereDeclared);
8305 if (optgenerror (FLG_REDECL,
8306 message ("%s %q declared more than once",
8307 ekind_capName (posRedeclared->ukind),
8308 uentry_getName (posRedeclared)),
8311 llgenindentmsg (message ("Previous declaration of %q",
8312 uentry_getName (posRedeclared)),
8313 posRedeclared->whereDeclared);
8318 fileloc_free (posLoc);
8319 posLoc = fileloc_undefined;
8320 posRedeclared = uentry_undefined;
8324 ** Redefinition of old as unew.
8325 ** modifies old to reflect unew, reports any inconsistencies
8329 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
8331 fileloc olddef = uentry_whereDeclared (old);
8332 fileloc unewdef = uentry_whereDeclared (unew);
8336 if (uentry_isExtern (unew))
8338 uentry_setUsed (old, unewdef);
8342 fileloc_isUndefined (olddef)
8343 && fileloc_isDefined (uentry_whereDefined (old))
8344 && !uentry_isExpandedMacro (old);
8346 if (!context_getFlag (FLG_INCONDEFSLIB)
8347 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8349 mustConform = FALSE;
8356 llassert (uentry_isValid (old));
8357 llassert (uentry_isValid (unew));
8358 llassert (cstring_equal (old->uname, unew->uname));
8361 ** should check old one was extern!
8364 if (uentry_isStatic (old))
8366 if (!(uentry_isStatic (unew)))
8370 message ("%s %q shadows static declaration",
8371 ekind_capName (unew->ukind),
8372 uentry_getName (unew)),
8375 uentry_showWhereLast (old);
8380 uentry_setDeclDef (old, unewdef);
8383 else if (uentry_isStatic (unew))
8385 uentry_setDeclDef (old, unewdef);
8387 else if (uentry_isExtern (old))
8389 uentry_setDeclared (old, unewdef);
8393 if (!uentry_isExtern (unew) && !uentry_isForward (old)
8394 && !fileloc_equal (olddef, unewdef)
8395 && !fileloc_isUndefined (olddef)
8396 && !fileloc_isUndefined (unewdef)
8397 && !fileloc_isBuiltin (olddef)
8398 && !fileloc_isBuiltin (unewdef)
8399 && !uentry_isYield (old)
8400 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8402 if (uentry_isVariable (old) || uentry_isVariable (unew))
8404 ; /* will report redeclaration error later */
8408 if (fileloc_isDefined (uentry_whereDefined (old)))
8412 message ("%s %q defined more than once",
8413 ekind_capName (unew->ukind),
8414 uentry_getName (unew)),
8415 uentry_whereLast (unew)))
8418 (message ("Previous definition of %q",
8419 uentry_getName (old)),
8420 uentry_whereLast (old));
8423 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
8425 uentry_copyInto (old, unew);
8426 old->sref = sRef_saveCopy (old->sref);
8434 if (fileloc_isLib (olddef)
8435 || fileloc_isUndefined (olddef)
8436 || fileloc_isImport (olddef))
8438 if (uentry_isExtern (unew))
8440 if (uentry_isExtern (old)
8441 || (fileloc_isDefined (uentry_whereDeclared (old))
8442 && (!fileloc_equal (uentry_whereDeclared (old),
8443 uentry_whereDefined (old)))))
8447 message ("%s %q declared more than once",
8448 ekind_capName (unew->ukind),
8449 uentry_getName (unew)),
8450 unew->whereDeclared))
8453 (message ("Previous declaration of %q",
8454 uentry_getName (old)),
8455 old->whereDeclared);
8459 uentry_setExtern (old);
8463 uentry_setDefined (old, unewdef);
8469 uentry_checkConformance (old, unew, mustConform, FALSE);
8471 old->used = old->used || unew->used;
8472 old->uses = filelocList_append (old->uses, unew->uses);
8473 unew->uses = filelocList_undefined;
8475 sRef_storeState (old->sref);
8476 sRef_storeState (unew->sref);
8480 old->whereDefined = fileloc_update (old->whereDefined,
8485 ** No redeclaration errors for functions here, since we
8486 ** don't know if this is the definition of the function.
8489 if (fileloc_isUser (old->whereDeclared)
8490 && fileloc_isUser (unew->whereDeclared)
8491 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
8492 && !fileloc_isDefined (unew->whereDefined))
8494 if (uentry_isFunction (old))
8496 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
8497 posLoc = fileloc_update (posLoc, unew->whereDeclared);
8501 if (optgenerror (FLG_REDECL,
8502 message ("%s %q declared more than once",
8503 ekind_capName (unew->ukind),
8504 uentry_getName (unew)),
8505 unew->whereDeclared))
8507 llgenindentmsg (message ("Previous declaration of %q",
8508 uentry_getName (old)),
8509 old->whereDeclared);
8514 if (fileloc_isUndefined (old->whereDefined))
8516 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
8520 if (!context_processingMacros ()
8521 && fileloc_isUser (old->whereDefined)
8522 && fileloc_isUser (unew->whereDefined)
8523 && !fileloc_equal (old->whereDefined, unew->whereDefined))
8525 if (uentry_isVariable (unew) || uentry_isFunction (unew))
8527 if (uentry_isVariable (unew)
8528 && uentry_isExtern (unew))
8530 if (optgenerror (FLG_REDECL,
8531 message ("%s %q declared after definition",
8532 ekind_capName (unew->ukind),
8533 uentry_getName (unew)),
8534 unew->whereDeclared))
8536 llgenindentmsg (message ("Definition of %q",
8537 uentry_getName (old)),
8543 if (optgenerror (FLG_REDEF,
8544 message ("%s %q redefined",
8545 ekind_capName (unew->ukind),
8546 uentry_getName (unew)),
8547 unew->whereDefined))
8549 llgenindentmsg (message ("Previous definition of %q",
8550 uentry_getName (old)),
8558 if (uentry_isExternal (unew))
8560 old->whereDefined = fileloc_createExternal ();
8563 if (unew->hasNameError)
8565 old->hasNameError = TRUE;
8570 if (!old->hasNameError)
8572 uentry_checkName (old);
8575 llassert (!ctype_isUndefined (old->utype));
8579 uentry_copyState (uentry res, uentry other)
8581 llassert (uentry_isValid (res));
8582 llassert (uentry_isValid (other));
8584 res->used = other->used;
8586 res->info->var->kind = other->info->var->kind;
8587 res->info->var->defstate = other->info->var->defstate;
8588 res->info->var->nullstate = other->info->var->nullstate;
8589 res->info->var->checked = other->info->var->checked;
8591 sRef_copyState (res->sref, other->sref);
8595 uentry_sameKind (uentry u1, uentry u2)
8597 if (uentry_isValid (u1) && uentry_isValid (u2))
8599 if (uentry_isVar (u1) && uentry_isVar (u2))
8601 ctype c1 = u1->utype;
8602 ctype c2 = u2->utype;
8604 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
8607 ** both functions, or both not functions
8610 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
8614 return ((u1->ukind == u2->ukind));
8621 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
8623 llassert (uentry_isValid (unew));
8624 llassert (uentry_isValid (old));
8626 unew->ukind = old->ukind;
8627 unew->uname = cstring_copy (old->uname);
8628 unew->utype = old->utype;
8630 unew->whereSpecified = fileloc_copy (old->whereSpecified);
8631 unew->whereDefined = fileloc_copy (old->whereDefined);
8632 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8634 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
8635 unew->used = old->used;
8637 unew->isPrivate = old->isPrivate;
8638 unew->hasNameError = old->hasNameError;
8639 unew->uses = filelocList_undefined;
8641 unew->storageclass = old->storageclass;
8642 unew->info = uinfo_copy (old->info, old->ukind);
8647 uentry_copy (uentry e)
8649 if (uentry_isValid (e))
8651 uentry enew = uentry_alloc ();
8652 DPRINTF (("copy: %s", uentry_unparseFull (e)));
8653 uentry_copyInto (enew, e);
8654 DPRINTF (("Here we are..."));
8655 DPRINTF (("original: %s", uentry_unparseFull (e)));
8656 DPRINTF (("copy: %s", uentry_unparse (enew)));
8657 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
8662 return uentry_undefined;
8667 uentry_setState (uentry res, uentry other)
8669 llassert (uentry_isValid (res));
8670 llassert (uentry_isValid (other));
8672 llassert (res->ukind == other->ukind);
8673 llassert (res->ukind == KVAR);
8675 res->sref = sRef_saveCopy (other->sref);
8676 res->used = other->used;
8677 filelocList_free (res->uses);
8678 res->uses = other->uses;
8679 other->uses = filelocList_undefined;
8680 res->lset = other->lset;
8684 uentry_mergeUses (uentry res, uentry other)
8686 llassert (uentry_isValid (res));
8687 llassert (uentry_isValid (other));
8689 res->used = other->used || res->used;
8690 res->lset = other->lset || res->lset;
8691 res->uses = filelocList_append (res->uses, other->uses);
8692 other->uses = filelocList_undefined;
8697 ** This is a really ugly routine.
8699 ** gack...fix this one day.
8704 ** >> res is the false branch, other is the true branch (or continuation)
8706 ** >> res is the true branch, other is the false branch (or continutation)
8713 ** References not effected by res are propagated from other.
8717 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
8718 bool flip, clause cl, fileloc loc)
8722 message ("%s %q is %s %s, but %s %s.",
8723 ekind_capName (res->ukind), uentry_getName (res),
8724 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
8725 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
8728 if (sRef_isDead (res->sref))
8730 sRef_showStateInfo (res->sref);
8732 else if (sRef_isKept (res->sref))
8734 sRef_showAliasInfo (res->sref);
8736 else /* dependent */
8738 sRef_showAliasInfo (res->sref);
8739 sRef_showAliasInfo (other->sref);
8742 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8746 static bool incompatibleStates (sRef rs, sRef os)
8748 alkind rk = sRef_getAliasKind (rs);
8749 alkind ok = sRef_getAliasKind (os);
8751 if (alkind_isError (rk) || alkind_isError (ok))
8757 return ((sRef_isDead (rs)
8758 || (alkind_isKept (rk) && !alkind_isKept (ok))
8759 || (alkind_isDependent (rk)
8760 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
8761 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
8766 branchStateAltError (/*@notnull@*/ uentry res,
8767 /*@notnull@*/ uentry other, bool flip,
8768 clause cl, fileloc loc)
8772 message ("%s %q is %s %s, but %s %s.",
8773 ekind_capName (res->ukind), uentry_getName (res),
8774 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
8775 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
8778 if (sRef_isDead (other->sref))
8780 sRef_showStateInfo (other->sref);
8784 sRef_showAliasInfo (other->sref);
8787 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8788 sRef_setDefinedComplete (res->sref, fileloc_undefined);
8790 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
8791 sRef_setDefinedComplete (other->sref, fileloc_undefined);
8795 static bool notNull (sRef sr, bool flip)
8797 return (!sRef_definitelyNull (sr)
8798 && !(sRef_isKept (sr))
8799 && !(sRef_isDependent (sr))
8800 && !(flip ? usymtab_isProbableDeepNull (sr)
8801 : usymtab_isAltProbablyDeepNull (sr)));
8805 uentry_mergeState (uentry res, uentry other, fileloc loc,
8806 bool mustReturn, bool flip, bool opt,
8809 llassert (uentry_isValid (res));
8810 llassert (uentry_isValid (other));
8812 llassert (res->ukind == other->ukind);
8813 llassert (res->ukind == KVAR);
8815 DPRINTF (("Merge state: %s / %s",
8816 uentry_unparse (res),
8817 uentry_unparse (other)));
8819 if (sRef_isValid (res->sref))
8823 if (incompatibleStates (res->sref, other->sref))
8825 if (sRef_isThroughArrayFetch (res->sref)
8826 && !context_getFlag (FLG_STRICTBRANCHSTATE))
8828 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
8830 sRef_maybeKill (res->sref, loc);
8832 else if (sRef_isPossiblyDead (other->sref))
8834 sRef_maybeKill (res->sref, loc);
8843 if (notNull (other->sref, flip))
8845 if (sRef_isLocalParamVar (res->sref)
8846 && (sRef_isLocalState (other->sref)
8847 || sRef_isDependent (other->sref)))
8849 if (sRef_isDependent (res->sref))
8851 sRef_setDependent (other->sref, loc);
8855 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8860 branchStateError (res, other, flip, cl, loc);
8865 if (sRef_isKept (res->sref))
8867 sRef_setKept (other->sref, loc);
8872 if (incompatibleStates (other->sref, res->sref))
8874 if (notNull (res->sref, !flip))
8876 if (sRef_isLocalParamVar (res->sref)
8877 && (sRef_isDependent (res->sref)
8878 || sRef_isLocalState (res->sref)))
8880 if (sRef_isDependent (other->sref))
8882 sRef_setDependent (res->sref, loc);
8886 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8891 if (sRef_isParam (other->sref))
8894 ** If the local variable associated
8895 ** with the param has the correct state,
8897 ** (e.g., free (s); s = new(); ...
8900 uentry uvar = usymtab_lookupSafe (other->uname);
8902 if (uentry_isValid (uvar)
8903 && ((sRef_isDead (other->sref)
8904 && sRef_isOnly (uvar->sref))
8905 || (sRef_isDependent (other->sref)
8906 && sRef_isOwned (uvar->sref))))
8912 branchStateAltError (res, other,
8918 branchStateAltError (res, other,
8925 if (sRef_isKept (other->sref))
8927 sRef_setKept (res->sref, loc);
8933 DPRINTF (("Merge opt..."));
8934 sRef_mergeOptState (res->sref, other->sref, cl, loc);
8935 DPRINTF (("Done!"));
8939 sRef_mergeState (res->sref, other->sref, cl, loc);
8944 if (sRef_isModified (other->sref))
8946 sRef_setModified (res->sref);
8950 if (cl == DOWHILECLAUSE)
8952 res->used = other->used || res->used;
8953 res->lset = other->lset || res->lset;
8954 res->uses = filelocList_append (res->uses, other->uses);
8955 other->uses = filelocList_undefined;
8959 if (sRef_isMacroParamRef (res->sref)
8960 && !uentry_isSefParam (other)
8961 && !uentry_isSefParam (res))
8963 bool hasError = FALSE;
8965 if (bool_equal (res->used, other->used))
8967 res->used = other->used;
8971 if (other->used && !flip)
8976 message ("Macro parameter %q used in true clause, "
8977 "but not in false clause",
8978 uentry_getName (res)),
8979 uentry_whereDeclared (res));
8986 message ("Macro parameter %q used in false clause, "
8987 "but not in true clause",
8988 uentry_getName (res)),
8989 uentry_whereDeclared (res));
8995 /* make it sef now, prevent more errors */
8996 res->info->var->kind = VKREFSEFPARAM;
9002 res->used = other->used || res->used;
9003 res->lset = other->lset || res->lset;
9004 res->uses = filelocList_append (res->uses, other->uses);
9005 other->uses = filelocList_undefined;
9011 void uentry_setUsed (uentry e, fileloc loc)
9013 static bool firstTime = TRUE;
9014 static bool showUses = FALSE;
9015 static bool exportLocal = FALSE;
9019 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
9021 showUses = context_getFlag (FLG_SHOWUSES);
9022 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
9027 if (uentry_isValid (e))
9031 if (sRef_isMacroParamRef (e->sref))
9033 if (uentry_isYield (e) || uentry_isSefParam (e))
9039 if (context_inConditional ())
9043 message ("Macro parameter %q used in conditionally "
9044 "executed code (may or may not be "
9045 "evaluated exactly once)",
9046 uentry_getName (e)),
9049 e->info->var->kind = VKREFSEFPARAM;
9058 message ("Macro parameter %q used more than once",
9059 uentry_getName (e)),
9060 uentry_whereDeclared (e)))
9062 e->info->var->kind = VKREFSEFPARAM;
9069 if ((dp = uentry_directParamNo (e)) >= 0)
9071 uentry_setUsed (usymtab_getParam (dp), loc);
9076 if (!sRef_isLocalVar (e->sref))
9080 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
9086 if (context_inMacro ())
9088 e->uses = filelocList_addUndefined (e->uses);
9092 e->uses = filelocList_addDifferentFile
9094 uentry_whereDeclared (e),
9103 bool uentry_isReturned (uentry u)
9105 return (uentry_isValid (u) && uentry_isVar (u)
9106 && (u->info->var->kind == VKRETPARAM
9107 || u->info->var->kind == VKSEFRETPARAM));
9110 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
9112 llassert (uentry_isRealFunction (u));
9114 if (ctype_isFunction (u->utype)
9115 && sRef_isStateSpecial (uentry_getSref (u)))
9117 specialClauses clauses = uentry_getSpecialClauses (u);
9118 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9120 sRef_setAllocated (res, g_currentloc);
9122 specialClauses_postElements (clauses, cl)
9124 sRefSet refs = specialClause_getRefs (cl);
9125 sRefMod modf = specialClause_getEffectFunction (cl);
9127 sRefSet_elements (refs, el)
9129 sRef base = sRef_getRootBase (el);
9131 if (sRef_isResult (base))
9135 sRef sr = sRef_fixBase (el, res);
9136 modf (sr, g_currentloc);
9143 } end_sRefSet_elements ;
9145 } end_specialClauses_postElements ;
9153 sRefSet prefs = sRefSet_new ();
9154 sRef res = sRef_undefined;
9157 params = uentry_getParams (u);
9159 uentryList_elements (params, current)
9161 if (uentry_isReturned (current))
9163 if (exprNodeList_size (args) >= paramno)
9165 exprNode ecur = exprNodeList_nth (args, paramno);
9166 sRef tref = exprNode_getSref (ecur);
9168 if (sRef_isValid (tref))
9170 sRef tcref = sRef_copy (tref);
9172 if (sRef_isDead (tcref))
9174 sRef_setDefined (tcref, g_currentloc);
9175 sRef_setOnly (tcref, g_currentloc);
9178 if (sRef_isRefCounted (tcref))
9180 /* could be a new ref now (but only if its returned) */
9181 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
9184 sRef_makeSafe (tcref);
9186 prefs = sRefSet_insert (prefs, tcref);
9192 } end_uentryList_elements ;
9194 if (sRefSet_size (prefs) > 0)
9196 nstate n = sRef_getNullState (u->sref);
9198 if (sRefSet_size (prefs) == 1)
9200 res = sRefSet_choose (prefs);
9204 res = sRefSet_mergeIntoOne (prefs);
9207 if (nstate_isKnown (n))
9209 sRef_setNullState (res, n, g_currentloc);
9214 if (ctype_isFunction (u->utype))
9216 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9220 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
9223 if (sRef_isRefCounted (res))
9225 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9229 if (sRef_getNullState (res) == NS_ABSNULL)
9231 ctype ct = ctype_realType (u->utype);
9233 if (ctype_isAbstract (ct))
9235 sRef_setNotNull (res, g_currentloc);
9239 if (ctype_isUser (ct))
9241 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
9245 sRef_setNotNull (res, g_currentloc);
9250 if (sRef_isRefCounted (res))
9252 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9254 else if (sRef_isKillRef (res))
9256 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
9263 ak = sRef_getAliasKind (res);
9265 if (alkind_isImplicit (ak))
9267 sRef_setAliasKind (res,
9268 alkind_fixImplicit (ak),
9272 sRefSet_free (prefs);
9278 static bool uentry_isRefCounted (uentry ue)
9280 ctype ct = uentry_getType (ue);
9282 if (ctype_isFunction (ct))
9284 return (ctype_isRefCounted (ctype_returnValue (ct)));
9288 return (ctype_isRefCounted (ct));
9293 ** old was declared yield in the specification.
9294 ** new is declared in the iter implementation.
9297 void uentry_checkYieldParam (uentry old, uentry unew)
9301 llassert (uentry_isVariable (old));
9302 llassert (uentry_isVariable (unew));
9304 unew->info->var->kind = VKYIELDPARAM;
9305 (void) checkTypeConformance (old, unew, TRUE);
9306 checkVarConformance (old, unew, TRUE, FALSE);
9308 /* get rid of param marker */
9310 name = uentry_getName (unew);
9311 cstring_free (unew->uname);
9313 unew->info->var->kind = VKREFYIELDPARAM;
9315 uentry_setUsed (old, fileloc_undefined);
9316 uentry_setUsed (unew, fileloc_undefined);
9319 /*@observer@*/ cstring
9320 uentry_ekindName (uentry ue)
9322 if (uentry_isValid (ue))
9327 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
9329 return cstring_makeLiteralTemp ("Datatype");
9331 return cstring_makeLiteralTemp ("Enum member");
9333 return cstring_makeLiteralTemp ("Constant");
9335 if (uentry_isParam (ue))
9337 return cstring_makeLiteralTemp ("Parameter");
9339 else if (uentry_isExpandedMacro (ue))
9341 return cstring_makeLiteralTemp ("Expanded macro");
9345 return cstring_makeLiteralTemp ("Variable");
9348 return cstring_makeLiteralTemp ("Function");
9350 return cstring_makeLiteralTemp ("Iterator");
9352 return cstring_makeLiteralTemp ("Iterator finalizer");
9354 return cstring_makeLiteralTemp ("Struct tag");
9356 return cstring_makeLiteralTemp ("Union tag");
9358 return cstring_makeLiteralTemp ("Enum tag");
9360 return cstring_makeLiteralTemp ("Optional parameters");
9365 return cstring_makeLiteralTemp ("<Undefined>");
9371 void uentry_setHasNameError (uentry ue)
9373 llassert (uentry_isValid (ue));
9375 ue->hasNameError = TRUE;
9378 void uentry_checkName (uentry ue)
9380 if (uentry_isValid (ue)
9381 && !uentry_isElipsisMarker (ue)
9382 && context_getFlag (FLG_NAMECHECKS)
9383 && !ue->hasNameError
9384 && !uentry_isEndIter (ue)
9385 && !fileloc_isBuiltin (uentry_whereLast (ue))
9386 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
9389 if (uentry_isPriv (ue))
9391 ; /* any checks here? */
9393 else if (fileloc_isExternal (uentry_whereDefined (ue)))
9395 ; /* no errors for externals */
9401 if (uentry_isExpandedMacro (ue))
9407 if (uentry_isExpandedMacro (ue))
9411 else if (uentry_isVariable (ue))
9413 sRef sr = uentry_getSref (ue);
9415 if (sRef_isValid (sr))
9417 scope = sRef_getScope (sr);
9424 else if (uentry_isFunction (ue)
9425 || uentry_isIter (ue)
9426 || uentry_isEndIter (ue)
9427 || uentry_isConstant (ue))
9429 scope = uentry_isStatic (ue) ? fileScope : globScope;
9431 else /* datatypes, etc. must be global */
9436 usymtab_checkDistinctName (ue, scope);
9439 if (context_getFlag (FLG_CPPNAMES))
9441 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
9443 uentry_setHasNameError (ue);
9447 if (scope == globScope)
9449 checkGlobalName (ue);
9451 if (context_getFlag (FLG_ANSIRESERVED))
9453 if (uentry_hasName (ue)
9454 && !uentry_isAnyTag (ue))
9456 if (checkAnsiName (uentry_rawName (ue),
9457 uentry_whereLast (ue)))
9459 uentry_setHasNameError (ue);
9466 checkLocalName (ue);
9468 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
9470 if (uentry_hasName (ue)
9471 && !uentry_isAnyTag (ue))
9473 if (checkAnsiName (uentry_rawName (ue),
9474 uentry_whereLast (ue)))
9476 uentry_setHasNameError (ue);
9482 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
9488 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
9494 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
9495 if (!context_inMacro ())
9497 sRef_setGlobalScopeSafe ();
9500 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
9501 uentry_setUsed (ue, loc);
9503 tloc = fileloc_createExternal ();
9504 uentry_setDefined (ue, tloc);
9505 fileloc_free (tloc);
9506 uentry_setHasNameError (ue);
9508 if (context_getFlag (FLG_REPEATUNRECOG))
9510 uentry_markOwned (ue);
9514 ue = usymtab_supReturnFileEntry (ue);
9517 if (!context_inMacro ())
9519 sRef_clearGlobalScopeSafe ();
9525 /* new start modifications */
9527 void uentry_testInRange (uentry p_e, uentry cconstant) {
9528 if( uentry_isValid(p_e) ) {
9529 if( p_e->sref != NULL) {
9530 int index = atoi(exprNode_unparse(cconstant) );
9531 usymtab_testInRange (p_e->sref, index);
9536 void uentry_setStringLength (uentry p_e, uentry cconstant) {
9537 if( uentry_isValid(p_e) ) {
9538 if( p_e->info != NULL) {
9539 if( p_e->info->var != NULL) {
9540 int length = atoi(exprNode_unparse(cconstant) );
9541 p_e->info->var->bufinfo->len = length;
9542 p_e->sref->bufinfo.len = length;
9543 printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size);
9550 void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
9551 if( uentry_isValid(p_e) ) {
9552 if( p_e->info != NULL) {
9553 if( p_e->info->var != NULL) {
9554 int size = atoi(exprNode_unparse(cconstant) );
9555 p_e->info->var->bufinfo->size = size;
9556 p_e->sref->bufinfo.size = size;
9557 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
9558 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
9559 // fprintf(stderr, "and %d\n", size );
9567 /* start modifications */
9569 requires: p_e is defined, is a ptr/array variable
9571 effects: sets the state of the variable
9574 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
9575 if( uentry_isValid(p_e) ) {
9576 if( p_e->info != NULL) {
9577 if( p_e->info->var != NULL) {
9578 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
9579 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9585 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
9589 requires: p_e is defined, is a ptr/array variable
9591 effects: sets the size of the buffer
9594 void uentry_setNullTerminatedState (uentry p_e) {
9595 if( uentry_isValid(p_e) ) {
9596 if( p_e->info != NULL) {
9597 if( p_e->info->var != NULL) {
9598 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
9599 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
9605 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
9610 requires: p_e is defined, is a ptr/array variable
9612 effects: sets the state of the variable
9615 void uentry_setNotNullTerminatedState (uentry p_e) {
9616 if( uentry_isValid(p_e) ) {
9617 if( p_e->info != NULL) {
9618 if( p_e->info->var != NULL) {
9619 p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
9620 p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED;
9626 fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n");
9631 requires: p_e is defined, is a ptr/array variable
9633 effects: sets the size of the buffer
9636 void uentry_setSize (uentry p_e, int size) {
9637 if( uentry_isValid(p_e) ) {
9638 if( p_e->info != NULL) {
9639 if( p_e->info->var != NULL) {
9640 p_e->info->var->bufinfo->size = size;
9641 p_e->sref->bufinfo.size = size;
9647 fprintf(stderr, "uentry:Error in setSize\n");
9652 requires: p_e is defined, is a ptr/array variable
9654 effects: sets the length of the buffer
9657 void uentry_setLen (uentry p_e, int len) {
9658 if( uentry_isValid(p_e) ) {
9659 if( p_e->info != NULL) {
9660 if( p_e->info->var != NULL) {
9661 p_e->info->var->bufinfo->len = len;
9662 p_e->sref->bufinfo.len = len;
9668 fprintf(stderr, "uentry:Error in setLen\n");