2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
28 # include "lclintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
35 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
36 static /*@only@*/ fileloc posLoc = fileloc_undefined;
37 static int nuentries = 0;
38 static int totuentries = 0;
40 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
41 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
42 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
43 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
44 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
45 static void uentry_checkIterArgs (uentry p_ue);
46 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
49 static void checkAliasState (/*@notnull@*/ uentry p_old,
50 /*@notnull@*/ uentry p_unew,
51 bool p_mustConform, bool p_completeConform)
52 /*@modifies p_old, p_unew@*/ ;
53 static void checkNullState (/*@notnull@*/ uentry p_old,
54 /*@notnull@*/ uentry p_unew,
55 bool p_mustConform, bool p_completeConform)
56 /*@modifies p_old, p_unew@*/ ;
58 static void checkVarConformance (/*@notnull@*/ uentry p_old,
59 /*@notnull@*/ uentry p_unew,
60 bool p_mustConform, bool p_completeConform)
61 /*@modifies p_old, p_unew@*/;
64 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
65 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
68 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
70 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
71 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
74 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
75 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
76 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
77 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
78 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
80 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
81 ctype p_oldType, /*@notnull@*/ uentry p_unew,
82 /*@notnull@*/ uentry p_newCurrent,
83 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
85 static /*@only@*/ /*@notnull@*/ uentry
86 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
87 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
89 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
91 uentry ue = (uentry) dmalloc (sizeof (*ue));
98 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
99 static void uentry_copyInto (/*@out@*/ /*@unique@*/ uentry p_unew, uentry p_old);
100 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
101 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
102 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
103 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
104 static void uvinfo_free (/*@only@*/ uvinfo p_u);
108 static /*@only@*/ cstring ancontext_unparse (ancontext an)
112 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
113 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
114 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
115 case AN_SUFIELD: return cstring_makeLiteral ("su field");
116 case AN_TDEFN: return cstring_makeLiteral ("type definition");
117 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
118 case AN_CONST: return cstring_makeLiteral ("constant");
124 static int annots[AN_LAST][QU_LAST];
125 static int decls[AN_LAST];
126 static int shdecls[AN_LAST];
127 static int idecls[AN_LAST];
133 for (i = AN_UNKNOWN; i < AN_LAST; i++)
139 for (j = QU_UNKNOWN; j < QU_LAST; j++)
146 static void tallyAnnot (ancontext ac, qual q)
160 for (j = QU_UNKNOWN; j < QU_LAST; j++)
165 for (i = AN_UNKNOWN; i < AN_LAST; i++)
171 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
172 ancontext_unparse (i),
173 decls[i], shdecls[i], idecls[i]);
175 totdecls += decls[i];
176 totshdecls += shdecls[i];
177 totidecls += idecls[i];
179 for (j = QU_UNKNOWN; j < QU_LAST; j++)
181 total[j] += annots[i][j];
182 alltotals += annots[i][j];
185 printf (" Allocation:\n");
189 for (j = QU_UNKNOWN; j < QU_LAST; j++)
191 if (qual_isAliasQual (j) && !qual_isUnique (j))
193 if (annots[i][j] > 0)
195 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
196 100.0 * (double)annots[i][j] / (double)decls[i]);
197 tmptot += annots[i][j];
202 printf (" Exposure:\n");
206 for (j = QU_UNKNOWN; j < QU_LAST; j++)
208 if (qual_isExQual (j))
210 if (annots[i][j] > 0)
212 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
213 100.0 * (double)annots[i][j] / (double)decls[i]);
214 tmptot += annots[i][j];
219 printf (" Definition:\n");
221 for (j = QU_UNKNOWN; j < QU_LAST; j++)
223 if (qual_isAllocQual (j))
225 if (annots[i][j] > 0)
227 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
228 100.0 * (double)annots[i][j] / (double)decls[i]);
235 for (j = QU_UNKNOWN; j < QU_LAST; j++)
237 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
239 if (annots[i][j] > 0)
241 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
242 100.0 * (double)annots[i][j] / (double)decls[i]);
251 for (j = QU_UNKNOWN; j < QU_LAST; j++)
255 for (i = AN_UNKNOWN; i < AN_LAST; i++)
257 if (annots[i][j] > 0)
266 printf ("Annotation: %s\n", qual_unparse (j));
268 for (i = AN_UNKNOWN; i < AN_LAST; i++)
270 if (annots[i][j] > 0)
272 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
279 printf ("All Contexts\n");
281 for (j = QU_UNKNOWN; j < QU_LAST; j++)
285 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
286 100.0 * (double)total[j] / (double)(totdecls));
291 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls);
294 extern void uentry_tallyAnnots (uentry u, ancontext kind)
296 alkind ak = sRef_getAliasKind (u->sref);
297 exkind ek = sRef_getExKind (u->sref);
298 nstate ns = sRef_getNullState (u->sref);
299 sstate ss = sRef_getDefState (u->sref);
300 bool recordUnknown = FALSE;
303 if (kind == AN_UNKNOWN)
311 else if (e == KCONST || e == KENUMCONST)
315 else if (e == KFCN || e == KITER)
317 uentryList params = uentry_getParams (u);
320 uentryList_elements (params, current)
322 if (uentry_isReturned (current))
326 if (!uentry_isElipsisMarker (current))
328 uentry_tallyAnnots (current, AN_FCNPARAM);
330 } end_uentryList_elements;
334 if (ctype_isFunction (u->utype)
336 && ctype_isVisiblySharable (ctype_realType (ctype_returnValue (u->utype))))
338 recordUnknown = TRUE;
341 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
343 ctype t = ctype_realType (u->utype);
347 uentryList fields = ctype_getFields (t);
349 uentryList_elements (fields, current)
351 uentry_tallyAnnots (current, AN_SUFIELD);
353 } end_uentryList_elements;
357 if (ctype_isVisiblySharable (u->utype))
359 recordUnknown = TRUE;
367 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
369 recordUnknown = TRUE;
376 if (kind == AN_FCNRETURN)
390 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
395 if (ctype_isRealPointer (ctype_realType (u->utype)))
412 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
413 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
414 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
415 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
419 if (uentry_isReturned (u))
421 tallyAnnot (kind, QU_RETURNED);
427 if (ctype_isRefCounted (ctype_realType (u->utype))
428 || (ctype_isFunction (u->utype) &&
429 ctype_isRefCounted (ctype_realType (ctype_returnValue (u->utype)))))
435 if (kind == AN_FCNPARAM)
437 tallyAnnot (kind, QU_TEMP);
439 else if (recordUnknown)
441 if (kind == AN_FCNRETURN)
444 tallyAnnot (kind, QU_UNKNOWN);
448 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
449 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
450 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
451 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
453 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
454 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
455 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
456 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
457 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
458 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
459 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
460 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
461 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
462 case AK_IMPDEPENDENT:
463 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
473 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
474 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
480 case NS_ERROR: break;
481 case NS_UNKNOWN: break;
482 case NS_NOTNULL: break;
483 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
484 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
485 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
486 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
488 case NS_ABSNULL: break;
494 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
498 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
499 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
500 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
501 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
502 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
508 static specCode specCode_fromInt (int i)
511 llassert (i >= SPC_NONE && i < SPC_LAST);
513 return ((specCode) i);
517 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
519 if (uentry_isDeclared (u))
521 return cstring_makeLiteralTemp ("previously declared");
525 return cstring_makeLiteralTemp ("specified");
529 /*@observer@*/ cstring uentry_specDeclName (uentry u)
531 if (uentry_isDeclared (u))
533 return cstring_makeLiteralTemp ("previous declaration");
537 return cstring_makeLiteralTemp ("specification");
541 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
543 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
545 return cstring_makeLiteralTemp ("redefined");
547 else if (uentry_isCodeDefined (unew))
549 return cstring_makeLiteralTemp ("defined");
551 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
553 return cstring_makeLiteralTemp ("redeclared");
557 return cstring_makeLiteralTemp ("declared");
563 constraintList uentry_getFcnPreconditions (uentry ue)
565 if (uentry_isValid (ue))
568 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
570 uentry_makeVarFunction (ue);
573 //llassert (uentry_isFunction (ue));
574 //llassert ((ue->info->fcn->preconditions));
576 if (!uentry_isFunction (ue))
578 BPRINTF ( (message ("called uentry_getFcnPreconditions on nonfunction %s",
579 uentry_unparse (ue) ) ) );
580 return constraintList_undefined;
583 if (ue->info->fcn->preconditions)
585 return constraintList_copy (ue->info->fcn->preconditions);
595 return constraintList_undefined;
601 static /*@only@*/ fileloc setLocation (void)
603 fileloc fl = context_getSaveLocation ();
605 if (fileloc_isDefined (fl))
611 return fileloc_copy (g_currentloc);
615 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
617 fileloc loc = setLocation ();
618 uentry ue = uentry_makeConstant (n, t, loc);
620 ue->ukind = KENUMCONST;
621 uentry_setDefined (ue, loc);
625 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
627 fileloc loc = setLocation ();
628 uentry ue = uentry_makeConstant (n, t, loc);
629 ctype etype = exprNode_getType (expr);
631 if (!ctype_isRealInt (etype)) {
635 ("Value of enum member is not an integeral type (type %s): %s",
636 ctype_unparse (etype), exprNode_unparse (expr)),
637 exprNode_loc (expr));
640 ue->ukind = KENUMCONST;
641 uentry_setDefined (ue, loc);
646 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
648 uentry ue = uentry_makeConstant (n, t, loc);
650 ue->ukind = KENUMCONST;
655 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
657 return uentry_makeVariable (n, t, setLocation (), FALSE);
661 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
663 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
667 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
669 ctype ct = idDecl_getCtype (id);
670 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
671 MAYBE, MAYBE, setLocation ());
673 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
675 if (!ynm_isOn (ue->info->datatype->abs))
677 if (ctype_isUnknown (ct))
679 ue->info->datatype->mut = MAYBE;
683 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
690 void uentry_checkParams (uentry ue)
692 if (uentry_isValid (ue))
694 bool isExt = uentry_isExtern (ue);
696 if (uentry_isRealFunction (ue))
698 uentryList params = uentry_getParams (ue);
700 uentryList_elements (params, current)
702 if (uentry_isValid (current))
704 ctype ct = current->utype;
706 if (ctype_isFixedArray (ct))
708 if (ctype_isArray (ctype_baseArrayPtr (ct))
709 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
716 (FLG_FIXEDFORMALARRAY,
717 message ("Function parameter %q declared as "
718 "manifest array (size constant is meaningless)",
719 uentry_getName (current)),
720 uentry_whereDeclared (current));
725 if (ctype_isArray (ct))
729 message ("Function parameter %q declared as "
730 "array (treated as pointer)",
731 uentry_getName (current)),
732 uentry_whereDeclared (current));
736 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
738 if (ctype_isAbstract (ct) &&
739 (isExt || (ctype_isAbstract (ctype_realType (ct))
740 && !context_hasFileAccess (ctype_typeId (ct)))))
745 ("Function %q declared with notnull parameter %q of abstract "
748 uentry_getName (current),
751 ("Since %s is an abstract type, notnull can only be "
752 "used for parameters if the function is static to a "
753 "module where %s is accessible.",
756 uentry_whereDeclared (current));
760 } end_uentryList_elements;
762 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
764 ctype ct = ue->utype;
766 if (ctype_isAbstract (ct)
767 && (isExt || (ctype_isAbstract (ctype_realType (ct))
768 && !context_hasFileAccess (ctype_typeId (ct)))))
773 ("%s %q declared %s notnull storage of abstract type %s",
774 ekind_capName (uentry_getKind (ue)),
779 ("Since %s is an abstract type, notnull can only be used "
780 "if it is static to a module where %s is accessible.",
783 uentry_whereDeclared (ue));
790 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
792 alkind ak = sRef_getAliasKind (ue->sref);
794 if (alkind_isRefCounted (ak))
796 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
800 if (alkind_isUnknown (ak))
802 exkind ek = sRef_getExKind (ue->sref);
804 if (exkind_isKnown (ek))
806 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
810 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
812 if (ctype_isVisiblySharable
813 (ctype_realType (ctype_returnValue (ue->utype))))
815 if (uentryList_hasReturned (uentry_getParams (ue)))
821 sRef_setAliasKind (ue->sref, AK_IMPONLY,
831 static /*@notnull@*/ uentry
832 uentry_makeFunctionAux (cstring n, ctype t,
834 /*@only@*/ globSet globs,
835 /*@only@*/ sRefSet mods,
836 /*@keep@*/ fileloc f, bool priv,
837 /*@unused@*/ bool isForward)
839 uentry e = uentry_alloc ();
842 if (ctype_isFunction (t))
844 ret = ctype_returnValue (t);
848 if (ctype_isKnown (t))
850 llbug (message ("not function: %s", ctype_unparse (t)));
857 if (fileloc_isSpec (f) || fileloc_isImport (f))
859 e->whereSpecified = f;
860 e->whereDeclared = fileloc_undefined;
864 e->whereSpecified = fileloc_undefined;
865 e->whereDeclared = f;
868 /* e->shallowCopy = FALSE; */
869 e->uname = cstring_copy (n);
871 e->storageclass = SCNONE;
873 e->sref = sRef_makeType (ret);
875 if (ctype_isUA (ret))
877 sRef_setStateFromType (e->sref, ret);
882 e->uses = filelocList_new ();
884 e->hasNameError = FALSE;
886 e->info = (uinfo) dmalloc (sizeof (*e->info));
887 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
889 e->info->fcn->hasMods = sRefSet_isDefined (mods);
890 e->info->fcn->hasGlobs = globSet_isDefined (globs);
892 e->info->fcn->exitCode = XK_UNKNOWN;
893 e->info->fcn->nullPred = QU_UNKNOWN;
894 e->info->fcn->specialCode = SPC_NONE;
896 e->info->fcn->access = access;
897 e->info->fcn->globs = globs;
898 e->info->fcn->defparams = uentryList_undefined;
900 sRef_setDefined (e->sref, f);
901 e->whereDefined = fileloc_undefined;
903 e->info->fcn->mods = sRefSet_undefined;
904 e->info->fcn->specclauses = NULL;
907 e->info->fcn->preconditions = NULL;
910 checkGlobalsModifies (e, mods);
911 e->info->fcn->mods = mods;
916 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
919 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
920 typeId_invalid, globSet_undefined,
924 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
925 reflectImplicitFunctionQualifiers (ue, FALSE);
927 if (!uentry_isStatic (ue)
928 && cstring_equalLit (ue->uname, "main"))
930 ctype typ = ue->utype;
934 llassert (ctype_isFunction (typ));
936 retval = ctype_returnValue (typ);
938 if (!ctype_isInt (retval))
942 message ("Function main declared to return %s, should return int",
943 ctype_unparse (retval)),
944 uentry_whereDeclared (ue));
947 args = ctype_argsFunction (typ);
949 if (uentryList_isMissingParams (args)
950 || uentryList_size (args) == 0)
956 if (uentryList_size (args) != 2)
960 message ("Function main declared with %d arg%p, "
961 "should have 2 (int argc, char *argv[])",
962 uentryList_size (args)),
963 uentry_whereLast (ue));
967 uentry arg = uentryList_getN (args, 0);
968 ctype ct = uentry_getType (arg);
970 if (!ctype_isInt (ct))
974 message ("Parameter 1, %q, of function main declared "
975 "with type %t, should have type int",
976 uentry_getName (arg), ct),
977 uentry_whereDeclared (arg));
980 arg = uentryList_getN (args, 1);
981 ct = uentry_getType (arg);
983 if (ctype_isArrayPtr (ct)
984 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
985 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
993 message ("Parameter 2, %q, of function main declared "
994 "with type %t, should have type char **",
995 uentry_getName (arg), ct),
996 uentry_whereDeclared (arg));
1005 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1007 alkind ak = sRef_getAliasKind (e->sref);
1009 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1010 && context_getFlag (FLG_PARAMIMPTEMP))
1012 exkind ek = sRef_getExKind (e->sref);
1014 if (exkind_isKnown (ek))
1016 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1017 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1021 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1022 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1027 static /*@only@*/ /*@notnull@*/ uentry
1028 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
1030 cstring pname = makeParam (n);
1031 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
1033 cstring_free (pname);
1034 uentry_implicitParamAnnots (e);
1036 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1038 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1039 e->info->var->defstate = defstate;
1047 uentry_setRefCounted (uentry e)
1049 if (uentry_isValid (e))
1051 uentry_setAliasKind (e, AK_REFCOUNTED);
1052 sRef_storeState (e->sref);
1058 uentry_setStatic (uentry c)
1060 if (uentry_isValid (c))
1062 alkind ak = sRef_getAliasKind (c->sref);
1063 c->storageclass = SCSTATIC;
1065 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1067 if (!alkind_isUnknown (ak)
1068 && !alkind_isStatic (ak))
1070 if (!(ctype_isRealPointer (uentry_getType (c)))
1071 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1072 && !alkind_isRefCounted (ak))
1074 if (alkind_isImplicit (ak)
1075 && alkind_isDependent (ak)
1076 && ctype_isArray (uentry_getType (c)))
1078 ; /* no error for observer arrays */
1084 message ("Static storage %q declared as %s",
1086 alkind_unparse (ak)),
1087 uentry_whereDeclared (c));
1093 if (alkind_isUnknown (ak)
1094 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1095 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1097 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1098 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1106 uentry_setExtern (uentry c)
1108 if (uentry_isValid (c))
1109 c->storageclass = SCEXTERN;
1113 uentry_setParamNo (uentry ue, int pno)
1115 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1116 sRef_setParamNo (ue->sref, pno);
1120 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1122 sRefSet_allElements (sr, el)
1124 sRef base = sRef_getRootBase (el);
1126 if (sRef_isGlobal (base) || sRef_isInternalState (base)
1127 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1129 if (!globSet_member (ue->info->fcn->globs, base))
1131 if (uentry_hasGlobs (ue)
1132 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1135 (FLG_WARNMISSINGGLOBALS,
1137 ("Modifies list for %q uses global %q, "
1138 "not included in globals list.",
1139 uentry_getName (ue),
1140 sRef_unparse (base)),
1141 uentry_whereLast (ue)))
1143 uentry_showWhereSpecified (ue);
1147 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1149 if (sRef_isFileStatic (base))
1151 context_recordFileGlobals (ue->info->fcn->globs);
1155 } end_sRefSet_allElements;
1159 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
1161 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1165 uentry_fixupSref (uentry ue)
1169 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1174 sr = uentry_getSref (ue);
1176 sRef_resetState (sr);
1177 sRef_clearDerived (sr);
1179 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1180 llassert (sRef_isValid (sr));
1182 if (uentry_isVariable (ue))
1184 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1185 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1189 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
1191 llassert (uentry_isFunction (ue));
1192 llassert (!specialClauses_isDefined (ue->info->fcn->specclauses));
1194 ue->info->fcn->specclauses = clauses;
1195 specialClauses_checkAll (ue);
1199 ** Used for @modifies@ @endmodifies@ syntax.
1201 ** If ue is specified, sr must contain *only*:
1203 ** o file static globals
1204 ** o sRef's derived from modifies spec (i.e., more specific than
1205 ** what was specified)
1207 ** Otherwise, if sr has modifies it must match sr.
1209 ** If it doesn't have modifies, set them to sr.
1213 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1215 if (sRef_modInFunction ())
1218 (message ("Modifies list not in function context. "
1219 "A modifies list can only appear following the parameter list "
1220 "in a function declaration or header."));
1222 /*@-mustfree@*/ return; /*@=mustfree@*/
1225 if (sRefSet_hasStatic (sr))
1227 context_recordFileModifies (sr);
1230 if (uentry_isValid (ue))
1232 if (uentry_isIter (ue))
1234 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1235 ue->info->iter->mods = sr;
1239 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1241 uentry_makeVarFunction (ue);
1244 llassertfatal (uentry_isFunction (ue));
1245 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1247 ue->info->fcn->mods = sr;
1248 ue->info->fcn->hasMods = TRUE;
1250 checkGlobalsModifies (ue, sr);
1253 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1255 ue->info->fcn->hasGlobs = TRUE;
1265 uentry_setPreconditions (uentry ue, /*@owned@*/ constraintList preconditions)
1267 if (sRef_modInFunction ())
1270 (message ("Precondition list not in function context. "
1271 "A precondition list can only appear following the parameter list "
1272 "in a function declaration or header."));
1274 /*@-mustfree@*/ return; /*@=mustfree@*/
1277 if (uentry_isValid (ue))
1280 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1282 uentry_makeVarFunction (ue);
1285 llassertfatal (uentry_isFunction (ue));
1286 // llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1288 ue->info->fcn->preconditions = preconditions;
1299 ** requires: new and old are functions
1303 checkGlobalsConformance (/*@notnull@*/ uentry old,
1304 /*@notnull@*/ uentry unew,
1305 bool mustConform, bool completeConform)
1307 bool hasInternalState = FALSE;
1309 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1311 if (globSet_isDefined (unew->info->fcn->globs))
1313 globSet_allElements (unew->info->fcn->globs, el)
1315 if (sRef_isFileStatic (el))
1317 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1319 if (sRef_isInvalid (sr))
1321 bool hasError = FALSE;
1323 if (!hasInternalState
1324 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1325 sRef_makeInternalState ()))
1326 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1327 sRef_makeSpecState ())))
1330 && !uentry_isStatic (old)
1333 message ("Globals list for %q includes internal state, %q, "
1334 "but %s without globals internalState.",
1335 uentry_getName (old),
1337 uentry_specOrDefName (old)),
1338 uentry_whereLast (unew)))
1340 uentry_showWhereSpecified (old);
1344 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1345 sRef_makeInternalState ());
1346 hasInternalState = TRUE;
1350 && fileloc_sameFile (uentry_whereDeclared (unew),
1351 uentry_whereDeclared (old)))
1356 message ("Function %q inconsistently %rdeclared (in "
1357 "same file) with file static global %q in "
1359 uentry_getName (unew),
1360 uentry_isDeclared (old),
1362 uentry_whereDeclared (unew)))
1364 uentry_showWhereSpecified (old);
1369 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1370 context_recordFileGlobals (old->info->fcn->globs);
1374 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1376 if (sRef_isInvalid (sr))
1381 message ("Function %q inconsistently %rdeclared with "
1382 "%q in globals list",
1383 uentry_getName (unew),
1384 uentry_isDeclared (old),
1386 uentry_whereDeclared (unew)))
1388 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1389 uentry_showWhereSpecified (old);
1394 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1400 ("Function %q global %q inconsistently "
1401 "%rdeclared as %qout global",
1402 uentry_getName (unew),
1404 uentry_isDeclared (old),
1405 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1406 uentry_whereDeclared (unew)))
1408 uentry_showWhereSpecified (old);
1413 } end_globSet_allElements ;
1415 if (completeConform)
1417 globSet_allElements (old->info->fcn->globs, el)
1419 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1421 if (sRef_isInvalid (sr))
1424 && uentry_isReallySpecified (old)
1427 message ("Function %q specified with %q in globals list, "
1428 "but declared without %q",
1429 uentry_getName (unew),
1432 uentry_whereDeclared (unew)))
1434 uentry_showWhereSpecified (old);
1437 } end_globSet_allElements;
1442 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1444 if (uentry_isReallySpecified (old)
1447 message ("%s %q specified with globals list, but "
1448 "declared with no globals",
1449 ekind_capName (unew->ukind),
1450 uentry_getName (unew)),
1451 uentry_whereDeclared (unew)))
1454 (message ("Specification globals: %q",
1455 globSet_unparse (old->info->fcn->globs)),
1456 uentry_whereSpecified (old));
1460 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
1461 old->info->fcn->globs);
1466 ** new modifies list must be included by old modifies list.
1468 ** file static state may be added to new, if old has internal.
1472 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1473 bool mustConform, bool completeConform)
1476 bool changedMods = FALSE;
1477 bool modInternal = FALSE;
1479 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1481 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1482 newMods = unew->info->fcn->mods;
1484 if (sRefSet_isEmpty (newMods))
1486 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1487 && uentry_isReallySpecified (old))
1491 message ("%s %q specified with modifies clause, "
1492 "but declared with no modifies clause",
1493 ekind_capName (unew->ukind),
1494 uentry_getName (unew)),
1495 uentry_whereDeclared (unew)))
1497 llgenindentmsg (message ("Specification has modifies %q",
1498 sRefSet_unparse (old->info->fcn->mods)),
1499 uentry_whereSpecified (old));
1506 sRefSet_allElements (newMods, current)
1508 if (sRef_isValid (current))
1510 sRef rb = sRef_getRootBase (current);
1512 if (sRef_isFileStatic (rb))
1516 if (!sRefSet_isSameMember (old->info->fcn->mods,
1517 sRef_makeInternalState ())
1518 && !sRefSet_isSameMember (old->info->fcn->mods,
1519 sRef_makeSpecState ()))
1522 && !uentry_isStatic (old)
1526 ("Modifies list for %q includes internal state, "
1527 "but %s without modifies internal.",
1528 uentry_getName (old),
1529 uentry_specOrDefName (old)),
1530 uentry_whereLast (unew)))
1532 uentry_showWhereSpecified (old);
1535 old->info->fcn->mods =
1536 sRefSet_insert (old->info->fcn->mods,
1537 sRef_makeInternalState ());
1542 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1548 if (sRef_canModifyVal (current, old->info->fcn->mods))
1550 int size = sRefSet_size (old->info->fcn->mods);
1552 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1555 if (sRefSet_size (old->info->fcn->mods) != size)
1566 ("Modifies list for %q contains %q, not modifiable "
1568 uentry_getName (old),
1569 sRef_unparse (current),
1570 uentry_specDeclName (old)),
1571 uentry_whereLast (unew)))
1573 uentry_showWhereSpecified (old);
1578 } end_sRefSet_allElements;
1580 if (completeConform && uentry_isReallySpecified (old))
1582 sRefSet_allElements (old->info->fcn->mods, el)
1584 if (sRef_canModify (el, newMods))
1593 ("Specification modifies clause for %q contains %q, "
1594 "not included in declaration modifies clause",
1595 uentry_getName (old),
1597 uentry_whereLast (unew)))
1599 uentry_showWhereSpecified (old);
1602 } end_sRefSet_allElements ;
1606 ** Make sure file static elements will be removed.
1611 context_recordFileModifies (old->info->fcn->mods);
1616 uentry_checkMutableType (uentry ue)
1618 ctype ct = uentry_getType (ue);
1620 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1622 voptgenerror (FLG_MUTREP,
1623 message ("Mutable abstract type %q declared without pointer "
1624 "indirection: %t (violates assignment semantics)",
1625 uentry_getName (ue), ct),
1626 uentry_whereDeclared (ue));
1631 uentry_setMutable (uentry e)
1633 llassert (uentry_isDatatype (e));
1634 e->info->datatype->mut = YES;
1638 uentry_checkIterArgs (uentry ue)
1640 bool hasYield = FALSE;
1643 llassert (uentry_isIter (ue));
1645 args = uentry_getParams (ue);
1647 uentryList_elements (args, el)
1649 sstate ds = uentry_getDefState (el);
1651 if (uentry_isYield (el))
1656 if (sstate_isUnknown (ds))
1658 uentry_setDefState (el, SS_DEFINED);
1664 } end_uentryList_elements;
1668 voptgenerror (FLG_HASYIELD,
1669 message ("Iterator %q declared with no yield parameters",
1670 uentry_getName (ue)),
1671 uentry_whereDeclared (ue));
1676 chkind_fromQual (qual qel)
1678 if (qual_isChecked (qel))
1682 else if (qual_isCheckMod (qel))
1686 else if (qual_isCheckedStrict (qel))
1688 return CH_CHECKEDSTRICT;
1690 else if (qual_isUnchecked (qel))
1692 return CH_UNCHECKED;
1697 /*@notreached@*/ return CH_UNKNOWN;
1702 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
1704 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
1706 if (!uentry_isRefCounted (ue))
1710 message ("Reference counting qualifier %s used on non-reference "
1711 "counted storage: %q",
1713 uentry_unparse (ue)));
1717 alkind ak = alkind_fromQual (qel);
1719 uentry_setAliasKind (ue, ak);
1722 else if (qual_isRefCounted (qel))
1724 ctype ct = ctype_realType (uentry_getType (ue));
1727 if (ctype_isPointer (ct)
1728 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
1730 /* check there is a refs field */
1731 uentryList fields = ctype_getFields (rt);
1732 uentry refs = uentry_undefined;
1734 uentryList_elements (fields, field)
1736 if (uentry_isRefsField (field))
1738 if (uentry_isValid (refs))
1742 message ("Reference counted structure type %s has "
1743 "multiple refs fields: %q and %q",
1745 uentry_getName (refs),
1746 uentry_getName (field)));
1751 } end_uentryList_elements;
1753 if (uentry_isInvalid (refs))
1757 message ("Reference counted structure type %s has "
1759 ctype_unparse (ct)),
1761 ("To count reference, the structure must have a field named "
1762 "refs of type int."),
1765 else if (!ctype_isInt (uentry_getType (refs)))
1769 message ("Reference counted structure type %s refs field has "
1770 "type %s (should be int)", ctype_unparse (ct),
1771 ctype_unparse (uentry_getType (refs))));
1775 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1776 uentry_whereDeclared (ue));
1781 if ((ctype_isPointer (ct)
1782 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
1783 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
1785 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1786 uentry_whereDeclared (ue));
1792 message ("Non-pointer to structure type %s declared with "
1793 "refcounted qualifier",
1794 ctype_unparse (ct)));
1798 else if (qual_isRefs (qel))
1800 if (uentry_isVariable (ue) && !uentry_isParam (ue))
1802 uentry_setAliasKind (ue, AK_REFS);
1808 message ("Refs qualifier used on non-structure field: %q",
1809 uentry_unparse (ue)));
1812 else if (qual_isAliasQual (qel))
1814 alkind ak = alkind_fromQual (qel);
1816 alkind oldak = uentry_getAliasKind (ue);
1817 ctype ut = uentry_getType (ue);
1819 if (alkind_isImplicit (ak)
1820 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
1822 /* ignore the implied qualifier */
1826 if (uentry_isEitherConstant (ue))
1830 message ("Alias qualifier %s used on constant: %q",
1831 alkind_unparse (ak), uentry_unparse (ue)));
1835 if (ctype_isFunction (ut))
1837 ut = ctype_returnValue (ut);
1840 if (!(ctype_isVisiblySharable (ut)
1841 || ctype_isRealArray (ut)
1842 || ctype_isRealSU (ut)))
1844 if (!qual_isImplied (qel))
1848 message ("Alias qualifier %s used on unsharable storage type %t: %q",
1849 alkind_unparse (ak), ut, uentry_getName (ue)));
1856 if (uentry_isRefCounted (ue))
1858 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
1859 || qual_isExposed (qel)
1860 || qual_isObserver (qel)))
1862 if (!qual_isImplied (qel))
1867 ("Alias qualifier %s used on reference counted storage: %q",
1868 alkind_unparse (ak),
1869 uentry_unparse (ue)));
1877 if (qual_isRefQual (qel))
1881 message ("Qualifier %s used on non-reference counted storage: %q",
1882 alkind_unparse (ak), uentry_unparse (ue)));
1891 uentry_setAliasKind (ue, ak);
1894 else if (qual_isNull (qel))
1896 if (uentry_isConstant (ue))
1900 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
1901 uentry_whereDeclared (ue));
1905 uentry_setNullState (ue, NS_POSNULL);
1908 else if (qual_isRelNull (qel))
1910 uentry_setNullState (ue, NS_RELNULL);
1912 else if (qual_isNotNull (qel))
1914 uentry_setNullState (ue, NS_MNOTNULL);
1916 else if (qual_isAbstract (qel)
1917 || qual_isConcrete (qel))
1919 if (!uentry_isDatatype (ue))
1923 message ("Qualifier %s used with non-datatype",
1924 qual_unparse (qel)));
1928 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
1931 else if (qual_isMutable (qel))
1933 if (!uentry_isDatatype (ue))
1935 llerror (FLG_SYNTAX,
1936 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
1940 if (!ynm_isOn (ue->info->datatype->mut))
1942 uentry_checkMutableType (ue);
1945 ue->info->datatype->mut = YES;
1948 else if (qual_isImmutable (qel))
1950 if (!uentry_isDatatype (ue))
1952 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
1953 qual_unparse (qel)));
1957 ue->info->datatype->mut = NO;
1960 else if (qual_isNullPred (qel))
1962 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1964 uentry_makeVarFunction (ue);
1967 if (uentry_isFunction (ue))
1969 ctype typ = uentry_getType (ue);
1970 ctype rtype = ctype_returnValue (uentry_getType (ue));
1972 if (ctype_isRealBool (rtype))
1974 uentryList pl = ctype_argsFunction (typ);
1976 if (uentryList_size (pl) == 1)
1978 ue->info->fcn->nullPred = qel;
1982 llerror (FLG_SYNTAX,
1983 message ("Qualifier %s used with function having %d "
1984 "arguments (should have 1)",
1986 uentryList_size (pl)));
1991 llerror (FLG_SYNTAX,
1992 message ("Qualifier %s used with function returning %s "
1993 "(should return bool)",
1995 ctype_unparse (rtype)));
2000 llerror (FLG_SYNTAX,
2001 message ("Qualifier %s used with non-function",
2002 qual_unparse (qel)));
2005 else if (qual_isExitQual (qel))
2007 exitkind exk = exitkind_fromQual (qel);
2009 if (uentry_isFunction (ue))
2011 if (exitkind_isKnown (ue->info->fcn->exitCode))
2013 llerror (FLG_SYNTAX,
2014 message ("Multiple exit qualifiers used on function %q: %s, %s",
2015 uentry_getName (ue),
2016 exitkind_unparse (ue->info->fcn->exitCode),
2017 exitkind_unparse (exk)));
2020 ue->info->fcn->exitCode = exk;
2024 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2026 uentry_makeVarFunction (ue);
2027 ue->info->fcn->exitCode = exk;
2031 llerror (FLG_SYNTAX,
2032 message ("Exit qualifier %s used with non-function (type %s)",
2034 ctype_unparse (uentry_getType (ue))));
2040 if (qual_isCQual (qel))
2046 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
2052 uentry_reflectQualifiers (uentry ue, qualList q)
2054 llassert (uentry_isValid (ue));
2056 qualList_elements (q, qel)
2058 if (qual_isStatic (qel))
2060 uentry_setStatic (ue);
2062 else if (qual_isUnused (qel))
2064 uentry_setUsed (ue, fileloc_undefined);
2066 else if (qual_isExternal (qel))
2068 fileloc_free (ue->whereDefined);
2069 ue->whereDefined = fileloc_createExternal ();
2071 else if (qual_isSef (qel))
2073 if (uentry_isVariable (ue))
2075 vkind vk = ue->info->var->kind;
2077 llassert (vk != VKREFPARAM);
2079 if (vk == VKYIELDPARAM)
2083 message ("Qualifier sef cannot be used with %s: %q",
2084 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2085 uentry_unparse (ue)));
2087 else if (vk == VKRETPARAM)
2089 ue->info->var->kind = VKSEFRETPARAM;
2093 ue->info->var->kind = VKSEFPARAM;
2100 message ("Qualifier sef is meaningful only on parameters: %q",
2101 uentry_unparse (ue)));
2104 else if (qual_isExtern (qel))
2106 ue->storageclass = SCEXTERN;
2108 else if (qual_isGlobalQual (qel)) /* undef, killed */
2110 if (uentry_isVariable (ue))
2112 sstate oldstate = ue->info->var->defstate;
2113 sstate defstate = sstate_fromQual (qel);
2116 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2117 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2119 defstate = SS_UNDEFKILLED;
2126 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2127 ue->info->var->defstate = defstate;
2133 message ("Qualifier %s used on non-variable: %q",
2134 qual_unparse (qel), uentry_unparse (ue)));
2137 /* start modifications */
2139 else if( qual_isBufQualifier(qel) ) {
2140 ctype ct = ctype_realType(uentry_getType(ue));
2142 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2144 if( uentry_hasBufStateInfo(ue) ) {
2146 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2148 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2149 /* If formal func param */
2150 uentry_setNullTerminatedState(ue);
2151 uentry_setLen (ue, 1);
2152 uentry_setSize (ue, 1);
2154 sRef_setNullTerminatedState(uentry_getSref(ue));
2155 sRef_setLen (uentry_getSref(ue), 1);
2156 sRef_setSize (uentry_getSref(ue), 1);
2158 uentry_setPossiblyNullTerminatedState(ue);
2160 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2164 /* put other BufState Qualifiers here */
2166 cstring s = uentry_getName(ue);
2167 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2168 struct for identifier %s\n", s) );
2170 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2172 sRef retSref = uentry_getSref (ue);
2173 ctype retType = sRef_getType (retSref);
2175 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2176 sRef_setNullTerminatedState (retSref);
2182 message ("Qualifier %s used on non-pointer on \
2183 function return: %q", qual_unparse (qel),
2184 uentry_unparse (ue)));
2191 message ("Qualifier %s used on non-pointer: %q",
2192 qual_unparse (qel), uentry_unparse (ue)));
2195 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2197 ctype realType = ctype_realType (ue->utype);
2198 sstate defstate = sstate_fromQual (qel);
2200 if (ctype_isFunction (realType))
2202 realType = ctype_realType (ctype_returnValue (realType));
2205 if (qual_isRelDef (qel))
2207 ; /* okay anywhere */
2211 if (!ctype_isAP (realType)
2212 && !ctype_isSU (realType)
2213 && !ctype_isUnknown (realType)
2214 && !ctype_isAbstract (ue->utype))
2218 message ("Qualifier %s used on non-pointer or struct: %q",
2219 qual_unparse (qel), uentry_unparse (ue)));
2223 uentry_setDefState (ue, defstate);
2225 if (sRef_isStateSpecial (ue->sref)
2226 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2228 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2231 else if (qual_isYield (qel))
2233 if (uentry_isVariable (ue))
2235 ue->info->var->kind = VKYIELDPARAM;
2241 message ("Qualifier %s used on non-iterator parameter: %q",
2242 qual_unparse (qel), uentry_unparse (ue)));
2245 else if (qual_isExQual (qel))
2247 exkind ek = exkind_fromQual (qel);
2248 ctype ut = uentry_getType (ue);
2250 if (ctype_isFunction (ut))
2252 ut = ctype_returnValue (ut);
2255 if (!(ctype_isVisiblySharable (ut))
2256 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2257 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2259 if (!qual_isImplied (qel))
2263 message ("Qualifier %s used on unsharable storage type %t: %q",
2264 exkind_unparse (ek), ut, uentry_getName (ue)));
2269 alkind ak = sRef_getAliasKind (ue->sref);
2271 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2273 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2275 if (!alkind_isTemp (ak))
2277 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2280 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2281 || alkind_isOwned (ak))
2289 message ("Exposure qualifier %s used on %s storage (should "
2290 "be dependent): %q",
2292 alkind_unparse (ak),
2293 uentry_unparse (ue)));
2297 else if (qual_isGlobCheck (qel))
2299 if (uentry_isVariable (ue))
2301 chkind ch = chkind_fromQual (qel);
2303 if (ue->info->var->checked != CH_UNKNOWN)
2305 if (ch == ue->info->var->checked)
2307 llerror (FLG_SYNTAX,
2308 message ("Redundant %s qualifier on %q",
2310 uentry_getName (ue)));
2314 llerror (FLG_SYNTAX,
2316 ("Contradictory %s and %s qualifiers on %q",
2318 checkedName (ue->info->var->checked),
2319 uentry_getName (ue)));
2323 ue->info->var->checked = ch;
2329 message ("Qualifier %s used with non-variable",
2330 qual_unparse (qel)));
2333 else if (qual_isReturned (qel))
2335 if (uentry_isVariable (ue))
2337 ue->info->var->kind = VKRETPARAM;
2341 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2342 qual_unparse (qel)));
2347 uentry_reflectOtherQualifier (ue, qel);
2350 sRef_storeState (ue->sref);
2351 } end_qualList_elements;
2357 uentry_isOnly (uentry ue)
2359 return (!uentry_isUndefined (ue)
2360 && uentry_isVariable (ue)
2361 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2365 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2367 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2368 sRef_setOrigAliasKind (ue->sref, ak);
2372 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2374 if (uentry_isVariable (ue))
2376 ue->info->var->nullstate = ns;
2379 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2383 uentry_isUnique (uentry ue)
2385 return (!uentry_isUndefined (ue)
2386 && uentry_isVariable (ue)
2387 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2391 uentry_isFileStatic (uentry ue)
2393 return (uentry_isStatic (ue)
2394 && (!uentry_isVariable (ue)
2395 || sRef_isFileStatic (uentry_getSref (ue))));
2399 uentry_isExported (uentry ue)
2401 if (uentry_isValid (ue))
2403 if (uentry_isVariable (ue))
2405 return (sRef_isRealGlobal (uentry_getSref (ue)));
2409 return !uentry_isStatic (ue);
2417 uentry_isNonLocal (uentry ue)
2419 return (uentry_isValid (ue) && uentry_isVariable (ue)
2420 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
2424 uentry_isGlobal (uentry ue)
2426 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
2427 sRef_isGlobal (ue->sref));
2431 uentry_isPrintfLike (uentry ue)
2433 return (uentry_isFunction (ue)
2434 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2438 uentry_isScanfLike (uentry ue)
2440 return (uentry_isFunction (ue)
2441 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2445 uentry_isMessageLike (uentry ue)
2447 return (uentry_isFunction (ue)
2448 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2451 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2453 uentryList args = uentry_getParams (ue);
2455 if (!uentryList_isMissingParams (args))
2457 uentry last = uentry_undefined;
2459 uentryList_elements (args, current)
2461 if (uentry_isElipsisMarker (current))
2463 if (uentry_isUndefined (last))
2467 message ("Function %q is marked %s, but has no format "
2468 "string argument before elipsis",
2469 uentry_getName (ue),
2470 specCode_unparse (ue->info->fcn->specialCode)),
2471 uentry_whereLast (ue));
2472 ue->info->fcn->specialCode = SPC_NONE;
2476 ctype rt = ctype_realType (uentry_getType (last));
2478 if (!ctype_match (rt, ctype_string))
2482 /* wchar_t * is okay too */
2483 if (ctype_isAP (rt))
2485 ctype base = ctype_baseArrayPtr (rt);
2487 if (ctype_isArbitraryIntegral (base))
2497 message ("Function %q is marked %s, but the argument "
2498 "before the elipsis has type %s (should be char *)",
2499 uentry_getName (ue),
2500 specCode_unparse (ue->info->fcn->specialCode),
2501 ctype_unparse (uentry_getType (last))),
2502 uentry_whereLast (ue));
2504 ue->info->fcn->specialCode = SPC_NONE;
2511 } end_uentryList_elements ;
2515 message ("Function %q is marked %s, but has no elipsis parameter",
2516 uentry_getName (ue),
2517 specCode_unparse (ue->info->fcn->specialCode)),
2518 uentry_whereLast (ue));
2520 ue->info->fcn->specialCode = SPC_NONE;
2525 uentry_setPrintfLike (uentry ue)
2527 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2529 uentry_makeVarFunction (ue);
2532 llassertfatal (uentry_isFunction (ue));
2533 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2534 checkSpecialFunction (ue);
2538 uentry_setScanfLike (uentry ue)
2540 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2542 uentry_makeVarFunction (ue);
2545 llassertfatal (uentry_isFunction (ue));
2546 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2547 checkSpecialFunction (ue);
2551 uentry_setMessageLike (uentry ue)
2553 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2555 uentry_makeVarFunction (ue);
2558 llassertfatal (uentry_isFunction (ue));
2559 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
2560 checkSpecialFunction (ue);
2564 uentry_isSpecialFunction (uentry ue)
2566 return (uentry_isFunction (ue)
2567 && (ue->info->fcn->specialCode != SPC_NONE));
2570 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
2572 ctype ct = idDecl_getCtype (t);
2574 sRef pref = sRef_makeParam (i, ct);
2575 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
2577 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2578 uentry_implicitParamAnnots (ue);
2580 /* Parameter type [][] or [x][] is invalid */
2582 while (ctype_isFixedArray (base)) {
2583 base = ctype_baseArrayPtr (base);
2586 if (ctype_isIncompleteArray (base)) {
2587 base = ctype_baseArrayPtr (base);
2589 if (ctype_isArray (base)) {
2590 if (!uentry_hasName (ue)) {
2591 (void) optgenerror (FLG_INCOMPLETETYPE,
2592 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
2594 ctype_unparse (ct)),
2595 uentry_whereLast (ue));
2597 (void) optgenerror (FLG_INCOMPLETETYPE,
2598 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
2599 uentry_getName (ue),
2600 ctype_unparse (ct)),
2601 uentry_whereLast (ue));
2609 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
2611 ctype ct = idDecl_getCtype (t);
2613 if (ctype_isFunction (ct))
2615 return (uentry_makeIdFunction (t));
2619 fileloc loc = setLocation ();
2620 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
2622 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2624 if (!uentry_isExtern (ue))
2626 uentry_setDefined (ue, loc);
2634 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
2636 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
2644 /*@only@*/ /*@notnull@*/
2645 uentry uentry_makeConstantAux (cstring n, ctype t,
2646 /*@keep@*/ fileloc f, bool priv,
2647 /*@only@*/ multiVal m)
2649 uentry e = uentry_alloc ();
2652 e->uname = cstring_copy (n);
2654 e->storageclass = SCNONE;
2656 e->sref = sRef_makeConst (t);
2661 e->uses = filelocList_new ();
2662 e->isPrivate = priv;
2663 e->hasNameError = FALSE;
2665 e->info = (uinfo) dmalloc (sizeof (*e->info));
2666 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
2667 e->info->uconst->val = m;
2668 e->info->uconst->access = typeIdSet_undefined;
2670 uentry_setSpecDef (e, f);
2672 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
2674 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
2680 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
2682 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
2685 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
2687 uentry ue = uentry_makeConstant (idDecl_observeId (t),
2688 idDecl_getCtype (t),
2691 llassert (fileloc_isUndefined (ue->whereDeclared));
2692 ue->whereDeclared = setLocation ();
2694 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2703 void uentry_setDefState (uentry ue, sstate defstate)
2705 if (uentry_isValid (ue))
2707 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2709 if (uentry_isVariable (ue))
2711 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
2716 bool uentry_isCheckedUnknown (uentry ue)
2718 return (uentry_isVar (ue)
2719 && (ue->info->var->checked == CH_UNKNOWN));
2722 bool uentry_isCheckMod (uentry ue)
2724 return (uentry_isVar (ue)
2725 && (ue->info->var->checked == CH_CHECKMOD));
2728 bool uentry_isUnchecked (uentry ue)
2730 return (uentry_isVar (ue)
2731 && (ue->info->var->checked == CH_UNCHECKED));
2734 bool uentry_isChecked (uentry ue)
2736 return (uentry_isVar (ue)
2737 && (ue->info->var->checked == CH_CHECKED));
2740 bool uentry_isCheckedModify (uentry ue)
2742 return (uentry_isVar (ue)
2743 && (ue->info->var->checked == CH_CHECKED
2744 || ue->info->var->checked == CH_CHECKMOD
2745 || ue->info->var->checked == CH_CHECKEDSTRICT));
2748 bool uentry_isCheckedStrict (uentry ue)
2750 return (uentry_isVar (ue)
2751 && (ue->info->var->checked == CH_CHECKEDSTRICT));
2754 void uentry_setUnchecked (uentry ue)
2756 llassert (uentry_isVar (ue));
2758 ue->info->var->checked = CH_UNCHECKED;
2761 void uentry_setChecked (uentry ue)
2763 llassert (uentry_isVar (ue));
2765 ue->info->var->checked = CH_CHECKED;
2768 void uentry_setCheckMod (uentry ue)
2770 llassert (uentry_isVar (ue));
2772 ue->info->var->checked = CH_CHECKMOD;
2775 void uentry_setCheckedStrict (uentry ue)
2777 llassert (uentry_isVar (ue));
2779 ue->info->var->checked = CH_CHECKEDSTRICT;
2782 static /*@only@*/ /*@notnull@*/
2783 uentry uentry_makeVariableAux (cstring n, ctype t,
2785 /*@exposed@*/ sRef s,
2786 bool priv, vkind kind)
2788 uentry e = uentry_alloc ();
2791 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
2794 e->uname = cstring_copy (n);
2797 e->storageclass = SCNONE;
2804 e->uses = filelocList_new ();
2805 e->isPrivate = priv;
2806 e->hasNameError = FALSE;
2808 e->info = (uinfo) dmalloc (sizeof (*e->info));
2809 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
2810 e->info->var->kind = kind;
2812 e->info->var->checked = CH_UNKNOWN;
2814 uentry_setSpecDef (e, f);
2816 if (ctype_isFunction (rt))
2818 rt = ctype_returnValue (rt);
2821 if (ctype_isUA (rt))
2823 sRef_setStateFromType (e->sref, rt);
2826 e->info->var->defstate = sRef_getDefState (e->sref);
2827 e->info->var->nullstate = sRef_getNullState (e->sref);
2829 /* start modifications */
2830 /* This function sets the uentry for a pointer or array variable declaration,
2831 it allocates memory and sets the fields. We check if the type of the variable
2832 is a pointer or array and allocate a `bbufinfo' struct accordingly */
2834 if( ctype_isArray (t) || ctype_isPointer(t)) {
2835 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
2836 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
2837 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
2839 e->info->var->bufinfo = NULL;
2841 /* end modification */
2847 uentry_isYield (uentry ue)
2849 return (uentry_isVariable (ue)
2850 && (ue->info->var->kind == VKYIELDPARAM
2851 || ue->info->var->kind == VKREFYIELDPARAM));
2855 uentry_isRefsField (uentry ue)
2857 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
2860 /*@only@*/ /*@notnull@*/
2861 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
2863 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
2864 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
2871 void uentry_makeVarFunction (uentry ue)
2878 llassert (uentry_isValid (ue));
2879 llassert (!sRef_modInFunction ());
2881 ak = sRef_getOrigAliasKind (ue->sref);
2882 ek = sRef_getOrigExKind (ue->sref);
2884 oldInfo = ue->info->var;
2886 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
2889 ** expanded macro is marked used (until I write a pre-processor)
2892 ue->used |= (oldInfo->kind == VKEXPMACRO);
2895 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
2896 ue->info->fcn->exitCode = XK_UNKNOWN;
2897 ue->info->fcn->nullPred = QU_UNKNOWN;
2898 ue->info->fcn->specialCode = SPC_NONE;
2899 ue->info->fcn->access = typeIdSet_undefined;
2900 ue->info->fcn->hasGlobs = FALSE;
2901 ue->info->fcn->globs = globSet_undefined;
2902 ue->info->fcn->hasMods = FALSE;
2903 ue->info->fcn->mods = sRefSet_undefined;
2904 ue->info->fcn->specclauses = NULL;
2905 ue->info->fcn->defparams = uentryList_undefined;
2908 ue->info->fcn->preconditions = constraintList_undefined;
2911 if (ctype_isFunction (ue->utype))
2913 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
2917 ue->sref = sRef_makeType (ctype_unknown);
2920 if (sRef_isRefCounted (ue->sref))
2926 if (alkind_isUnknown (ak))
2928 if (exkind_isKnown (ek))
2930 ak = AK_IMPDEPENDENT;
2934 if (context_getFlag (FLG_RETIMPONLY))
2936 if (ctype_isFunction (ue->utype)
2937 && ctype_isVisiblySharable
2938 (ctype_realType (ctype_returnValue (ue->utype))))
2940 if (uentryList_hasReturned (uentry_getParams (ue)))
2954 loc = ue->whereDeclared;
2956 sRef_setAliasKind (ue->sref, ak, loc);
2957 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
2958 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
2959 sRef_setExKind (ue->sref, ek, loc);
2961 if (oldInfo->kind == VKEXPMACRO)
2964 ue->whereDeclared = fileloc_undefined;
2968 fileloc_free (ue->whereDefined);
2969 ue->whereDefined = fileloc_undefined;
2972 uvinfo_free (oldInfo);
2976 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
2978 llassert (uentry_isValid (ue));
2980 if (uentry_isIter (ue))
2982 llassert (globSet_isUndefined (ue->info->iter->globs));
2983 ue->info->iter->globs = globs;
2987 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2989 uentry_makeVarFunction (ue);
2992 llassert (uentry_isFunction (ue));
2993 llassert (!ue->info->fcn->hasGlobs
2994 && globSet_isUndefined (ue->info->fcn->globs));
2996 ue->info->fcn->hasGlobs = TRUE;
2997 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3001 if (globSet_hasStatic (globs))
3003 context_recordFileGlobals (globs);
3006 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3008 ue->info->fcn->hasMods = TRUE;
3012 void uentry_addAccessType (uentry ue, typeId tid)
3014 if (uentry_isFunction (ue))
3016 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3018 else if (uentry_isEitherConstant (ue))
3020 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3022 else if (uentry_isIter (ue))
3024 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3026 else if (uentry_isEndIter (ue))
3028 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3032 llbug (message ("no access for: %q", uentry_unparse (ue)));
3036 /*@only@*/ /*@notnull@*/ uentry
3037 uentry_makeFunction (cstring n, ctype t,
3039 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3042 return (uentry_makeFunctionAux (n, t,
3043 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3044 : typeIdSet_single (access)),
3050 /*@notnull@*/ uentry
3051 uentry_makePrivFunction2 (cstring n, ctype t,
3053 globSet globs, sRefSet mods,
3056 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
3060 /*@notnull@*/ uentry
3061 uentry_makeSpecFunction (cstring n, ctype t,
3063 /*@only@*/ globSet globs,
3064 /*@only@*/ sRefSet mods,
3067 uentry ue = uentry_makeFunctionAux (n, t, access,
3071 uentry_setHasGlobs (ue);
3072 uentry_setHasMods (ue);
3074 reflectImplicitFunctionQualifiers (ue, TRUE);
3079 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3081 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3082 sRef_undefined, FALSE, VKEXPMACRO);
3084 uentry_setDefined (ue, f);
3088 /*@notnull@*/ /*@notnull@*/ uentry
3089 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3091 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3092 typeIdSet_singleOpt (access),
3093 globSet_undefined, sRefSet_undefined,
3097 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3101 bool uentry_isForward (uentry e)
3103 if (uentry_isValid (e))
3105 ctype ct = uentry_getType (e);
3107 return (ctype_isUnknown (ct)
3108 || (ctype_isFunction (ct)
3109 && ctype_isUnknown (ctype_returnValue (ct))));
3116 /*@notnull@*/ uentry
3117 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3119 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3125 /*@notnull@*/ uentry
3126 uentry_makeUnspecFunction (cstring n, ctype t,
3130 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
3131 sRefSet_new (), f, FALSE, TRUE);
3133 reflectImplicitFunctionQualifiers (ue, TRUE);
3142 /* is exported for use by usymtab_interface */
3144 /*@notnull@*/ uentry
3145 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
3146 fileloc f, bool priv)
3148 uentry e = uentry_alloc ();
3150 DPRINTF (("Make datatype: %s / %s",
3151 n, ctype_unparse (t)));
3153 /* e->shallowCopy = FALSE; */
3154 e->ukind = KDATATYPE;
3155 e->uname = cstring_copy (n);
3157 e->storageclass = SCNONE;
3158 e->sref = sRef_makeUnknown ();
3162 sRef_setStateFromType (e->sref, t);
3165 uentry_setSpecDef (e, f);
3167 e->uses = filelocList_new ();
3168 e->isPrivate = priv;
3169 e->hasNameError = FALSE;
3174 e->info = (uinfo) dmalloc (sizeof (*e->info));
3175 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3176 e->info->datatype->abs = abs;
3177 e->info->datatype->mut = mut;
3178 e->info->datatype->type = ctype_undefined;
3180 if (uentry_isDeclared (e))
3182 uentry_setDefined (e, f);
3185 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
3187 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3193 /*@notnull@*/ uentry
3194 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
3197 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
3200 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abs)
3202 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3203 ctype_bool, NO, abs,
3204 fileloc_getBuiltin (),
3207 ret->info->datatype->type = ctype_bool;
3215 static /*@only@*/ /*@notnull@*/ uentry
3216 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3217 /*@only@*/ fileloc f)
3219 uentry e = uentry_alloc ();
3222 e->uname = cstring_copy (n);
3224 e->sref = sRef_makeUnknown ();
3225 e->storageclass = SCNONE;
3229 uentry_setSpecDef (e, f);
3231 e->uses = filelocList_new ();
3232 e->isPrivate = FALSE;
3233 e->hasNameError = FALSE;
3235 e->info = (uinfo) dmalloc (sizeof (*e->info));
3236 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3237 e->info->iter->access = access;
3238 e->info->iter->mods = sRefSet_undefined;
3239 e->info->iter->globs = globSet_undefined;
3241 uentry_checkIterArgs (e);
3245 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3247 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3250 static /*@notnull@*/ uentry
3251 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3253 uentry e = uentry_alloc ();
3255 /* e->shallowCopy = FALSE; */
3256 e->ukind = KENDITER;
3257 e->storageclass = SCNONE;
3258 e->uname = message ("end_%s", n);
3259 e->utype = ctype_unknown;
3260 e->sref = sRef_makeUnknown ();
3262 uentry_setSpecDef (e, f);
3267 e->uses = filelocList_new ();
3268 e->isPrivate = FALSE;
3269 e->hasNameError = FALSE;
3271 e->info = (uinfo) dmalloc (sizeof (*e->info));
3272 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3274 e->info->enditer->access = access;
3279 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3281 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3288 static /*@only@*/ /*@notnull@*/ uentry
3289 uentry_makeTagAux (cstring n, ctype t,
3290 /*@only@*/ fileloc fl,
3291 bool priv, ekind kind)
3293 uentry e = uentry_alloc ();
3295 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3297 llbuglit ("uentry_makeTagAux: not a tag type");
3301 /* e->shallowCopy = FALSE; */
3302 e->uname = cstring_copy (n);
3305 e->sref = sRef_makeUnknown ();
3306 e->storageclass = SCNONE;
3308 uentry_setSpecDef (e, fl);
3313 e->uses = filelocList_new ();
3314 e->isPrivate = priv;
3315 e->hasNameError = FALSE;
3317 e->info = (uinfo) dmalloc (sizeof (*e->info));
3318 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3319 e->info->datatype->abs = NO;
3320 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3321 e->info->datatype->type = t;
3323 if (uentry_isDeclared (e))
3325 uentry_setDefined (e, fl);
3331 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3333 cstring sname = makeStruct (n);
3334 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3336 cstring_free (sname);
3341 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3343 cstring sname = makeStruct (n);
3344 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3346 cstring_free (sname);
3351 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3353 cstring uname = makeUnion (n);
3354 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3356 cstring_free (uname);
3362 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3364 cstring ename = makeEnum (n);
3365 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3367 cstring_free (ename);
3373 uentry_makeUnionTagLoc (cstring n, ctype t)
3375 cstring uname = makeUnion (n);
3376 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3378 cstring_free (uname);
3383 uentry_makeEnumTagLoc (cstring n, ctype t)
3385 cstring ename = makeEnum (n);
3386 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3388 cstring_free (ename);
3393 uentry_isStructTag (uentry ue)
3395 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3399 uentry_isUnionTag (uentry ue)
3401 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3405 uentry_isEnumTag (uentry ue)
3407 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3411 uentry_isAnyTag (uentry ue)
3413 return (uentry_isStructTag (ue)
3414 || uentry_isUnionTag (ue)
3415 || uentry_isEnumTag (ue));
3418 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3420 extern void uentry_destroyMod (void)
3421 /*@globals killed emarker@*/ /*@modifies emarker@*/
3423 static bool wasDestroyed = FALSE;
3425 llassert (!wasDestroyed);
3427 if (emarker != NULL)
3429 uentry_reallyFree (emarker);
3432 wasDestroyed = TRUE;
3436 uentry_makeElipsisMarker (void)
3438 if (emarker == NULL)
3440 emarker = uentry_alloc ();
3442 emarker->ukind = KELIPSMARKER;
3443 emarker->uname = cstring_makeLiteral ("...");
3444 emarker->utype = ctype_elipsMarker;
3445 emarker->sref = sRef_undefined;
3446 emarker->storageclass = SCNONE;
3447 emarker->used = FALSE;
3448 emarker->lset = FALSE;
3449 emarker->info = NULL;
3451 uentry_setSpecDef (emarker, fileloc_undefined);
3452 emarker->uses = filelocList_new ();
3453 emarker->isPrivate = FALSE;
3454 emarker->hasNameError = FALSE;
3457 /*@ignore@*/ return (emarker); /*@end@*/
3465 uentry_equiv (uentry p1, uentry p2)
3467 if (uentry_compare (p1, p2) != 0)
3478 uentry_xcomparealpha (uentry *p1, uentry *p2)
3482 if ((res = uentry_compare (*p1, *p2)) == 0) {
3483 if ((*p1 != NULL) && (*p2 != NULL)) {
3484 res = cstring_compare ((*p1)->uname,
3493 uentry_xcompareuses (uentry *p1, uentry *p2)
3498 if (uentry_isValid (u1))
3500 if (uentry_isValid (u2))
3502 return (-1 * int_compare (filelocList_size (u1->uses),
3503 filelocList_size (u2->uses)));
3512 if (uentry_isValid (u2))
3524 uentry_compareStrict (uentry v1, uentry v2)
3526 COMPARERETURN (uentry_compare (v1, v2));
3528 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
3530 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
3531 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
3532 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
3539 uentry_compare (uentry u1, uentry u2)
3541 if (u1 == u2) return 0;
3543 if (uentry_isInvalid (u1)) return -1;
3544 if (uentry_isInvalid (u2)) return 1;
3546 INTCOMPARERETURN (u1->ukind, u2->ukind);
3547 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
3548 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
3550 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
3556 /* bug detected by lclint:
3557 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
3562 return (multiVal_compare (u1->info->uconst->val,
3563 u2->info->uconst->val));
3567 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
3569 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3570 uentry_accessType (u2)));
3571 return (uentryList_compareParams (uentry_getParams (u1),
3572 uentry_getParams (u2)));
3574 return (typeIdSet_compare (uentry_accessType (u1),
3575 uentry_accessType (u2)));
3577 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3578 uentry_accessType (u2)));
3579 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
3580 uentry_getGlobs (u2)));
3581 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
3582 uentry_getParams (u2)));
3583 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
3584 u2->info->fcn->specialCode));
3585 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
3586 u2->info->fcn->nullPred));
3588 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
3590 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
3591 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
3592 sRef_getOrigAliasKind (u2->sref)));
3593 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
3594 sRef_getOrigExKind (u2->sref)));
3595 COMPARERETURN (generic_compare (u1->info->var->checked,
3596 u2->info->var->checked));
3597 COMPARERETURN (generic_compare (u1->info->var->defstate,
3598 u2->info->var->defstate));
3599 return (generic_compare (u1->info->var->nullstate,
3600 u2->info->var->nullstate));
3602 COMPARERETURN (ctype_compare (u1->info->datatype->type,
3603 u2->info->datatype->type));
3604 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
3605 u2->info->datatype->mut));
3606 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
3615 ** all entries are: <type>[@<info>]*#<name>
3617 ** info depends on kind:
3621 advanceField (char **s)
3627 advanceName (char **s)
3633 vkind_fromInt (int i)
3635 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
3637 llbuglit ("vkind_fromInt: out of range");
3644 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
3645 typeIdSet access, nstate nullstate,
3646 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
3648 uentry e = uentry_alloc ();
3653 e->sref = sRef_makeConst (ct);
3655 sRef_setNullState (e->sref, nullstate, loc);
3656 e->storageclass = SCNONE;
3658 if (fileloc_isSpec (loc))
3660 e->whereSpecified = loc;
3661 e->whereDeclared = fileloc_undefined;
3665 e->whereSpecified = fileloc_undefined;
3666 e->whereDeclared = loc;
3669 e->whereDefined = fileloc_undefined;
3670 e->uses = filelocList_new ();
3671 e->isPrivate = FALSE;
3672 e->hasNameError = FALSE;
3677 e->info = (uinfo) dmalloc (sizeof (*e->info));
3678 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3679 e->info->uconst->val = m;
3680 e->info->uconst->access = access;
3682 sRef_storeState (e->sref);
3687 static /*@only@*/ uentry
3688 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
3689 sstate defstate, nstate isnull, alkind aliased,
3690 exkind exp, chkind checked,
3691 /*@only@*/ fileloc loc)
3693 uentry e = uentry_alloc ();
3698 e->storageclass = SCNONE;
3700 e->sref = sRef_makeType (ct);
3701 sRef_setNullState (e->sref, isnull, loc);
3703 e->whereDefined = fileloc_undefined;
3705 if (fileloc_isSpec (loc))
3707 e->whereSpecified = loc;
3708 e->whereDeclared = fileloc_undefined;
3712 e->whereSpecified = fileloc_undefined;
3713 e->whereDeclared = loc;
3716 e->isPrivate = FALSE;
3717 e->hasNameError = FALSE;
3722 e->uses = filelocList_new ();
3724 e->info = (uinfo) dmalloc (sizeof (*e->info));
3725 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3726 e->info->var->kind = kind;
3727 e->info->var->checked = checked;
3728 e->info->var->defstate = defstate;
3730 sRef_setDefState (e->sref, defstate, loc);
3732 e->info->var->nullstate = sRef_getNullState (e->sref);
3734 sRef_setExKind (e->sref, exp, loc);
3735 sRef_setAliasKind (e->sref, aliased, loc);
3737 sRef_storeState (e->sref);
3739 /*DRL ADDED 9-1-2000 */
3740 e->info->var->bufinfo = NULL;
3745 static /*@only@*/ uentry
3746 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abs,
3747 ynm mut, ctype rtype, alkind ak, exkind exp,
3748 sstate defstate, nstate isnull,
3749 /*@only@*/ fileloc loc)
3751 uentry e = uentry_alloc ();
3753 e->ukind = KDATATYPE;
3754 /* e->shallowCopy = FALSE; */
3757 e->storageclass = SCNONE;
3758 e->sref = sRef_makeUnknown ();
3761 ** This is only setting null state. (I think?)
3764 if (ctype_isUA (ct))
3766 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
3768 if (uentry_isValid (te))
3770 sRef_setStateFromUentry (e->sref, te);
3774 /* problem for recursive type definitions */
3778 sRef_setAliasKind (e->sref, ak, loc);
3779 sRef_setExKind (e->sref, exp, loc);
3781 sRef_setDefState (e->sref, defstate, loc);
3783 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
3785 isnull = NS_ABSNULL;
3788 sRef_mergeNullState (e->sref, isnull);
3790 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
3792 if (fileloc_isSpec (loc))
3794 e->whereSpecified = loc;
3795 e->whereDeclared = fileloc_undefined;
3799 e->whereSpecified = fileloc_undefined;
3800 e->whereDeclared = loc;
3803 e->isPrivate = FALSE;
3804 e->hasNameError = FALSE;
3808 e->uses = filelocList_new ();
3810 e->info = (uinfo) dmalloc (sizeof (*e->info));
3811 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3812 e->info->datatype->abs = abs;
3813 e->info->datatype->mut = mut;
3814 e->info->datatype->type = rtype;
3816 sRef_storeState (e->sref);
3822 static void uentry_setHasGlobs (uentry ue)
3824 llassert (uentry_isFunction (ue));
3826 ue->info->fcn->hasGlobs = TRUE;
3829 static void uentry_setHasMods (uentry ue)
3831 llassert (uentry_isFunction (ue));
3833 ue->info->fcn->hasMods = TRUE;
3837 bool uentry_hasGlobs (uentry ue)
3839 if (uentry_isFunction (ue))
3841 return (ue->info->fcn->hasGlobs);
3847 bool uentry_hasSpecialClauses (uentry ue)
3849 return (uentry_isFunction (ue) && specialClauses_isDefined (ue->info->fcn->specclauses));
3852 specialClauses uentry_getSpecialClauses (uentry ue)
3854 llassert (uentry_isFunction (ue));
3855 return ue->info->fcn->specclauses;
3858 bool uentry_hasMods (uentry ue)
3860 if (uentry_isFunction (ue))
3862 return (ue->info->fcn->hasMods);
3869 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
3871 bool hasGlobs, /*@only@*/ globSet globs,
3872 bool hasMods, /*@only@*/ sRefSet mods,
3873 alkind ak, exkind exp,
3874 sstate defstate, nstate isnull,
3878 /*@only@*/ specialClauses specclauses,
3879 /*@only@*/ fileloc loc)
3881 uentry e = uentry_alloc ();
3884 /* e->shallowCopy = FALSE; */
3888 e->storageclass = SCNONE;
3890 if (ctype_isFunction (ct))
3892 ret = ctype_returnValue (ct);
3896 if (ctype_isKnown (ct))
3898 llbug (message ("not function: %s", ctype_unparse (ct)));
3901 ret = ctype_unknown;
3904 e->sref = sRef_makeType (ret);
3906 if (ctype_isUA (ret))
3908 sRef_setStateFromType (e->sref, ret);
3911 sRef_setDefined (e->sref, loc);
3912 sRef_setNullState (e->sref, isnull, loc);
3914 sRef_setAliasKind (e->sref, ak, loc);
3915 sRef_setExKind (e->sref, exp, loc);
3916 sRef_setDefState (e->sref, defstate, loc);
3918 e->whereSpecified = loc;
3919 e->whereDefined = fileloc_undefined;
3921 e->isPrivate = FALSE;
3922 e->hasNameError = FALSE;
3926 e->uses = filelocList_new ();
3928 e->info = (uinfo) dmalloc (sizeof (*e->info));
3929 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
3931 e->info->fcn->exitCode = exitCode;
3932 e->info->fcn->specialCode = sCode;
3933 e->info->fcn->nullPred = nullPred;
3934 e->info->fcn->access = access;
3936 e->info->fcn->specclauses = specclauses;
3937 e->info->fcn->hasGlobs = hasGlobs;
3938 e->info->fcn->globs = globs;
3940 e->info->fcn->hasMods = hasMods;
3941 e->info->fcn->mods = mods;
3943 e->info->fcn->defparams = uentryList_undefined;
3944 e->whereDeclared = fileloc_undefined;
3946 sRef_storeState (e->sref);
3949 e->info->fcn->preconditions = NULL;
3955 static /*@only@*/ uentry
3956 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
3957 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
3959 uentry e = uentry_alloc ();
3961 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
3963 llbuglit ("uentry_makeTagBase: not a tag type");
3966 /* e->shallowCopy = FALSE; */
3970 e->sref = sRef_makeUnknown ();
3971 e->storageclass = SCNONE;
3973 if (fileloc_isSpec (loc))
3975 e->whereSpecified = loc;
3976 e->whereDeclared = fileloc_undefined;
3980 e->whereDeclared = loc;
3981 e->whereSpecified = fileloc_undefined;
3984 e->whereDefined = fileloc_undefined;
3986 e->isPrivate = FALSE;
3987 e->hasNameError = FALSE;
3991 e->uses = filelocList_new ();
3993 e->info = (uinfo) dmalloc (sizeof (*e->info));
3994 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3995 e->info->datatype->abs = NO;
3996 e->info->datatype->mut = MAYBE;
3997 e->info->datatype->type = rtype;
3999 sRef_storeState (e->sref);
4005 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4006 ctype ct, /*@only@*/ fileloc loc)
4008 uentry e = uentry_alloc ();
4010 /* e->shallowCopy = FALSE; */
4014 e->sref = sRef_makeUnknown ();
4015 e->storageclass = SCNONE;
4017 if (fileloc_isSpec (loc))
4019 e->whereSpecified = loc;
4020 e->whereDeclared = fileloc_undefined;
4024 e->whereDeclared = loc;
4025 e->whereSpecified = fileloc_undefined;
4028 e->whereDefined = fileloc_undefined;
4030 e->isPrivate = FALSE;
4031 e->hasNameError = FALSE;
4035 e->uses = filelocList_new ();
4037 e->info = (uinfo) dmalloc (sizeof (*e->info));
4038 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4039 e->info->iter->access = access;
4040 e->info->iter->mods = sRefSet_undefined;
4041 e->info->iter->globs = globSet_undefined;
4043 sRef_storeState (e->sref);
4048 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4049 /*@only@*/ fileloc loc)
4051 uentry e = uentry_alloc ();
4053 /* e->shallowCopy = FALSE; */
4054 e->ukind = KENDITER;
4055 e->storageclass = SCNONE;
4057 e->utype = ctype_unknown;
4058 e->sref = sRef_makeUnknown ();
4060 if (fileloc_isSpec (loc))
4062 e->whereSpecified = loc;
4063 e->whereDeclared = fileloc_undefined;
4067 e->whereDeclared = loc;
4068 e->whereSpecified = fileloc_undefined;
4071 e->whereDefined = fileloc_undefined;
4073 e->isPrivate = FALSE;
4074 e->hasNameError = FALSE;
4078 e->uses = filelocList_new ();
4080 e->info = (uinfo) dmalloc (sizeof (*e->info));
4081 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4082 e->info->enditer->access = access;
4083 sRef_storeState (e->sref);
4088 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4096 uentry_undump (ekind kind, fileloc loc, char **s)
4104 ue = uentry_makeElipsisMarker ();
4108 ctype ct = ctype_undump (s);
4124 if (optCheckChar (s, '@'))
4126 tkind = vkind_fromInt (getInt (s));
4134 if (optCheckChar (s, '$'))
4136 defstate = SS_UNKNOWN;
4137 isnull = NS_UNKNOWN;
4138 aliased = AK_IMPTEMP;
4140 checked = CH_UNKNOWN;
4142 else if (optCheckChar (s, '&'))
4144 defstate = SS_DEFINED;
4145 isnull = NS_UNKNOWN;
4146 aliased = AK_IMPTEMP;
4148 checked = CH_UNKNOWN;
4150 else if (optCheckChar (s, '^'))
4152 defstate = SS_UNKNOWN;
4153 isnull = NS_UNKNOWN;
4154 aliased = AK_IMPTEMP;
4156 checked = CH_UNKNOWN;
4160 defstate = sstate_fromInt (getInt (s));
4161 advanceField (s); isnull = nstate_fromInt (getInt (s));
4162 advanceField (s); aliased = alkind_fromInt (getInt (s));
4164 if (optCheckChar (s, '&'))
4167 checked = CH_UNKNOWN;
4171 advanceField (s); exp = exkind_fromInt (getInt (s));
4172 advanceField (s); checked = (chkind) (getInt (s));
4177 name = getStringWord (s);
4179 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4180 isnull, aliased, exp,
4181 checked, fileloc_copy (loc));
4194 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
4195 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
4196 advanceField (s); defstate = sstate_fromInt (getInt (s));
4197 advanceField (s); isnull = nstate_fromInt (getInt (s));
4198 advanceField (s); aliased = alkind_fromInt (getInt (s));
4199 advanceField (s); exp = exkind_fromInt (getInt (s));
4200 advanceField (s); rtype = ctype_undump (s);
4202 name = getStringWord (s);
4204 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
4205 aliased, exp, defstate, isnull,
4206 fileloc_copy (loc));
4223 specialClauses specclauses;
4225 if (optCheckChar (s, '$'))
4227 defstate = SS_DEFINED;
4228 isnull = NS_UNKNOWN;
4229 exitCode = XK_UNKNOWN;
4231 nullPred = QU_UNKNOWN;
4235 advanceField (s); defstate = sstate_fromInt (getInt (s));
4236 advanceField (s); isnull = nstate_fromInt (getInt (s));
4237 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
4238 advanceField (s); specc = specCode_fromInt (getInt (s));
4239 advanceField (s); nullPred = qual_fromInt (getInt (s));
4242 if (optCheckChar (s, '$'))
4245 globs = globSet_undefined;
4247 mods = sRefSet_undefined;
4249 else if (optCheckChar (s, '^'))
4252 globs = globSet_undefined;
4254 mods = sRefSet_undefined;
4258 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
4259 advanceField (s); globs = globSet_undump (s);
4260 advanceField (s); hasMods = bool_fromInt (getInt (s));
4261 advanceField (s); mods = sRefSet_undump (s);
4264 if (optCheckChar (s, '$'))
4271 advanceField (s); ak = alkind_fromInt (getInt (s));
4272 advanceField (s); exp = exkind_fromInt (getInt (s));
4275 advanceField (s); access = typeIdSet_undump (s);
4277 if (optCheckChar (s, '@'))
4279 specclauses = specialClauses_undump (s);
4283 specclauses = specialClauses_undefined;
4286 advanceName (s); name = getStringWord (s);
4288 ue = uentry_makeFunctionBase (name, ct, access,
4291 ak, exp, defstate, isnull,
4292 exitCode, specc, nullPred,
4294 fileloc_copy (loc));
4295 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4302 advanceField (s); access = typeIdSet_undump (s);
4303 advanceName (s); name = getStringWord (s);
4305 ue = uentry_makeIterBase (name, access, ct,
4306 fileloc_copy (loc));
4313 advanceField (s); access = typeIdSet_undump (s);
4314 advanceName (s); name = getStringWord (s);
4316 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4326 if (optCheckChar (s, '$'))
4328 val = multiVal_undefined;
4329 access = typeIdSet_undefined;
4330 nullstate = NS_UNKNOWN;
4334 advanceField (s); val = multiVal_undump (s);
4335 advanceField (s); access = typeIdSet_undump (s);
4336 advanceField (s); nullstate = nstate_fromInt (getInt (s));
4339 advanceName (s); name = getStringWord (s);
4341 ue = uentry_makeConstantBase (name, ct, access,
4342 nullstate, fileloc_copy (loc), val);
4351 advanceField (s); rtype = ctype_undump (s);
4352 advanceName (s); name = getStringWord (s);
4353 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4357 llcontbuglit ("uentry_undump: invalid");
4358 ue = uentry_undefined;
4361 llcontbuglit ("uentry_undump: elips marker");
4362 ue = uentry_undefined;
4371 uentry_dump (uentry v)
4373 return (uentry_dumpAux (v, FALSE));
4377 uentry_dumpParam (uentry v)
4379 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4380 ("dump: %s", uentry_unparseFull (v)));
4382 return (uentry_dumpAux (v, TRUE));
4386 uentry_dumpAux (uentry v, bool isParam)
4388 llassert (uentry_isValid (v));
4390 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
4395 llcontbuglit ("uentry_dump: invalid entry");
4396 return cstring_undefined;
4398 return (message ("!."));
4402 vkind vk = v->info->var->kind;
4403 sstate dss = sRef_getDefState (v->sref);
4404 nstate nst = sRef_getNullState (v->sref);
4405 alkind alk = sRef_getAliasKind (v->sref);
4406 exkind exk = sRef_getExKind (v->sref);
4407 chkind chk = v->info->var->checked;
4409 DPRINTF (("Dumping var"));
4411 if (dss == SS_UNKNOWN
4412 && nst == NS_UNKNOWN
4413 && alk == AK_IMPTEMP
4414 && exk == XO_UNKNOWN
4415 && chk == CH_UNKNOWN)
4417 sdump = cstring_makeLiteral ("$");
4419 else if (dss == SS_DEFINED
4420 && nst == NS_UNKNOWN
4421 && alk == AK_IMPTEMP
4422 && exk == XO_UNKNOWN
4423 && chk == CH_UNKNOWN)
4425 sdump = cstring_makeLiteral ("&");
4427 else if (dss == SS_UNKNOWN
4428 && nst == NS_UNKNOWN
4429 && alk == AK_UNKNOWN
4430 && exk == XO_UNKNOWN
4431 && chk == CH_UNKNOWN)
4433 sdump = cstring_makeLiteral ("^");
4435 else if (exk == XO_UNKNOWN
4436 && chk == CH_UNKNOWN)
4438 sdump = message ("%d@%d@%d&",
4445 sdump = message ("%d@%d@%d@%d@%d",
4456 return (message ("%q|@%d|%q#%s",
4457 ctype_dump (v->utype),
4460 isParam ? cstring_undefined : v->uname));
4464 return (message ("%q|%q#%s",
4465 ctype_dump (v->utype),
4467 isParam ? cstring_undefined : v->uname));
4472 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
4473 ctype_dump (v->utype),
4474 ynm_unparseCode (v->info->datatype->abs),
4475 ynm_unparseCode (v->info->datatype->mut),
4476 (int) sRef_getDefState (v->sref),
4477 (int) sRef_getNullState (v->sref),
4478 (int) sRef_getAliasKind (v->sref),
4479 (int) sRef_getExKind (v->sref),
4480 ctype_dump (v->info->datatype->type),
4484 cstring sdump, gdump, adump;
4485 alkind alk = sRef_getAliasKind (v->sref);
4486 exkind exk = sRef_getExKind (v->sref);
4488 if (sRef_getDefState (v->sref) == SS_DEFINED
4489 && !nstate_isKnown (sRef_getNullState (v->sref))
4490 && !exitkind_isKnown (v->info->fcn->exitCode)
4491 && v->info->fcn->specialCode == SPC_NONE
4492 && v->info->fcn->nullPred == QU_UNKNOWN)
4494 sdump = cstring_makeLiteral ("$");
4498 sdump = message ("@%d@%d@%d@%d@%d",
4499 (int) sRef_getDefState (v->sref),
4500 (int) sRef_getNullState (v->sref),
4501 (int) v->info->fcn->exitCode,
4502 (int) v->info->fcn->specialCode,
4503 (int) v->info->fcn->nullPred);
4506 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
4508 gdump = cstring_makeLiteral ("$");
4510 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
4511 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
4513 gdump = cstring_makeLiteral ("^");
4517 gdump = message ("@%s@%q@%s@%q",
4518 bool_dump (uentry_hasGlobs (v)),
4519 globSet_dump (uentry_getGlobs (v)),
4520 bool_dump (uentry_hasMods (v)),
4521 sRefSet_dump (uentry_getMods (v)));
4524 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
4526 adump = cstring_makeLiteral ("$");
4530 adump = message ("@%d@%d", (int) alk, (int) exk);
4533 if (uentry_hasSpecialClauses (v))
4535 return (message ("%q%q%q%q@%q@%q#%s",
4536 ctype_dump (v->utype),
4540 typeIdSet_dump (uentry_accessType (v)),
4541 specialClauses_dump (v->info->fcn->specclauses),
4546 return (message ("%q%q%q%q@%q#%s",
4547 ctype_dump (v->utype),
4551 typeIdSet_dump (uentry_accessType (v)),
4556 return (message ("%q@%q#%s",
4557 ctype_dump (v->utype),
4558 typeIdSet_dump (v->info->iter->access),
4561 return (message ("%q@%q#%s",
4562 ctype_dump (v->utype),
4563 typeIdSet_dump (uentry_accessType (v)),
4570 if (multiVal_isUnknown (v->info->uconst->val)
4571 && typeIdSet_isEmpty (uentry_accessType (v))
4572 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
4574 sdump = cstring_makeLiteral ("$");
4578 sdump = message ("@%q@%q@%d",
4579 multiVal_dump (v->info->uconst->val),
4580 typeIdSet_dump (uentry_accessType (v)),
4581 (int) sRef_getNullState (v->sref));
4584 return (message ("%q%q#%s",
4585 ctype_dump (v->utype),
4592 return (message ("%q@%q#%s",
4593 ctype_dump (v->utype),
4594 ctype_dump (v->info->datatype->type), v->uname));
4601 uentry_unparseAbbrev (uentry v)
4603 if (!uentry_isVariable (v))
4605 llcontbuglit ("uentry_unparseAbbrev: not variable");
4606 return uentry_unparse (v);
4609 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
4613 uentry_unparse (uentry v)
4617 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
4618 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
4620 st = uentry_getName (v);
4622 if (cstring_isDefined (st))
4624 return (ctype_unparseDeclaration (v->utype, st));
4629 return (cstring_copy (ctype_unparse (v->utype)));
4634 uentry_unparseFull (uentry v)
4636 if (uentry_isUndefined (v))
4638 return (cstring_makeLiteral ("<undefined>"));
4640 else if (uentry_isDatatype (v))
4642 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
4644 ekind_unparse (v->ukind),
4648 ctype_isDefined (v->info->datatype->type)
4649 ? v->info->datatype->type : ctype_unknown,
4650 ynm_unparse (v->info->datatype->mut),
4651 ynm_unparse (v->info->datatype->abs),
4652 sRef_unparseState (v->sref),
4653 fileloc_unparse (v->whereSpecified),
4654 fileloc_unparse (v->whereDefined)));
4656 else if (uentry_isFunction (v))
4658 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
4659 "globs: %q / [s: %q; decl: %q; def: %q]",
4661 ekind_unparse (v->ukind),
4664 sRef_unparseFull (v->sref),
4665 sRefSet_unparse (v->info->fcn->mods),
4666 globSet_unparse (v->info->fcn->globs),
4667 fileloc_unparse (v->whereSpecified),
4668 fileloc_unparse (v->whereDeclared),
4669 fileloc_unparse (v->whereDefined)));
4671 else if (uentry_isIter (v))
4673 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
4674 ekind_unparse (v->ukind),
4677 sRef_unparseFull (v->sref),
4678 fileloc_unparse (v->whereSpecified),
4679 fileloc_unparse (v->whereDefined)));
4681 else if (uentry_isVariable (v))
4684 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
4685 "kind <%d> isout <%d> used <%d>",
4686 checkedName (v->info->var->checked),
4688 ekind_unparse (v->ukind),
4691 sRef_unparseDeep (v->sref),
4692 fileloc_unparse (v->whereSpecified),
4693 fileloc_unparse (v->whereDefined),
4694 fileloc_unparse (v->whereDeclared),
4695 (int) v->info->var->kind,
4696 (int) v->info->var->defstate,
4701 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
4702 ekind_unparse (v->ukind),
4705 sRef_unparseFull (v->sref),
4706 fileloc_unparse (v->whereSpecified),
4707 fileloc_unparse (v->whereDefined)));
4712 bool uentry_hasAccessType (uentry e)
4714 if (uentry_isValid (e))
4719 return (!typeIdSet_isEmpty (e->info->iter->access));
4721 return (!typeIdSet_isEmpty (e->info->enditer->access));
4723 return (!typeIdSet_isEmpty (e->info->fcn->access));
4726 return (!typeIdSet_isEmpty (e->info->uconst->access));
4735 typeIdSet uentry_accessType (uentry e)
4737 if (uentry_isValid (e))
4742 return (e->info->iter->access);
4744 return (e->info->enditer->access);
4746 return (e->info->fcn->access);
4749 return (e->info->uconst->access);
4755 return typeIdSet_undefined;
4759 uentry_isVariable (uentry e)
4761 return (uentry_isVar (e));
4765 uentry_isSpecified (uentry e)
4767 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
4771 uentry_isReallySpecified (uentry e)
4773 return (uentry_isValid (e)
4774 && fileloc_isRealSpec (e->whereSpecified));
4778 uentry_isVar (uentry e)
4780 return (!uentry_isUndefined (e) && e->ukind == KVAR);
4784 uentry_isFakeTag (uentry e)
4786 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
4790 uentry_isDatatype (uentry e)
4792 return (!uentry_isUndefined (e) &&
4793 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
4794 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
4798 uentry_setAbstract (uentry e)
4802 llassert (uentry_isDatatype (e)
4803 && (ynm_isMaybe (e->info->datatype->abs)));
4805 oldid = ctype_typeId (e->info->datatype->type);
4806 e->info->datatype->abs = YES;
4807 e->info->datatype->type = ctype_createAbstract (oldid);
4811 uentry_setConcrete (uentry e)
4813 llassert (uentry_isDatatype (e)
4814 && (ynm_isMaybe (e->info->datatype->abs)));
4816 e->info->datatype->abs = NO;
4820 uentry_isAbstractDatatype (uentry e)
4822 return (uentry_isDatatype (e)
4823 && (ynm_isOn (e->info->datatype->abs)));
4827 uentry_isMaybeAbstract (uentry e)
4829 return (uentry_isDatatype (e)
4830 && (ynm_isMaybe (e->info->datatype->abs)));
4834 uentry_isMutableDatatype (uentry e)
4836 bool res = uentry_isDatatype (e)
4837 && (ynm_toBoolRelaxed (e->info->datatype->mut));
4843 uentry_isRefCountedDatatype (uentry e)
4845 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
4849 uentry_isParam (uentry u)
4851 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
4852 || u->info->var->kind == VKYIELDPARAM));
4856 uentry_isExpandedMacro (uentry u)
4858 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
4862 uentry_isSefParam (uentry u)
4864 return (uentry_isVariable (u)
4865 && (u->info->var->kind == VKSEFPARAM
4866 || u->info->var->kind == VKREFSEFPARAM
4867 || u->info->var->kind == VKSEFRETPARAM
4868 || u->info->var->kind == VKREFSEFRETPARAM));
4872 uentry_isRefParam (uentry u)
4874 return (uentry_isVariable (u)
4875 && (u->info->var->kind == VKREFPARAM
4876 || u->info->var->kind == VKREFYIELDPARAM
4877 || u->info->var->kind == VKREFSEFPARAM
4878 || u->info->var->kind == VKREFSEFRETPARAM));
4882 uentry_isAnyParam (uentry u)
4884 return (uentry_isVariable (u)
4885 && ((u->info->var->kind == VKPARAM)
4886 || (u->info->var->kind == VKSEFPARAM)
4887 || (u->info->var->kind == VKYIELDPARAM)
4888 || (u->info->var->kind == VKRETPARAM)
4889 || (u->info->var->kind == VKSEFRETPARAM)));
4893 uentry_getDefState (uentry u)
4895 if (uentry_isValid (u))
4897 return (sRef_getDefState (u->sref));
4901 return (SS_UNKNOWN);
4906 uentry_isOut (uentry u)
4908 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
4909 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4913 uentry_isPartial (uentry u)
4915 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
4916 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4920 uentry_isStateSpecial (uentry u)
4922 return ((uentry_isVariable (u)
4923 && (u->info->var->defstate == SS_SPECIAL))
4924 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
4927 exitkind uentry_getExitCode (uentry ue)
4929 if (uentry_isFunction (ue))
4931 return ue->info->fcn->exitCode;
4940 uentry_nullPred (uentry u)
4942 llassert (uentry_isRealFunction (u));
4944 if (uentry_isFunction (u))
4946 return (u->info->fcn->nullPred);
4955 uentry_possiblyNull (uentry u)
4957 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
4958 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
4962 uentry_getAliasKind (uentry u)
4964 if (uentry_isValid (u))
4966 return (sRef_getAliasKind (uentry_getSref (u)));
4975 uentry_getExpKind (uentry u)
4977 if (uentry_isValid (u))
4979 return (sRef_getExKind (uentry_getSref (u)));
4988 uentry_isIter (uentry e)
4990 return (!uentry_isUndefined (e) && e->ukind == KITER);
4994 uentry_isEndIter (uentry e)
4996 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5000 uentry_isRealFunction (uentry e)
5002 return (uentry_isFunction (e) ||
5003 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5007 uentry_hasName (uentry e)
5009 if (uentry_isValid (e))
5011 cstring s = e->uname;
5013 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
5021 bool uentry_hasRealName (uentry e)
5023 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
5027 /*@observer@*/ globSet
5028 uentry_getGlobs (uentry l)
5030 if (uentry_isInvalid (l))
5032 return globSet_undefined;
5035 if (l->ukind != KFCN)
5037 if (l->ukind != KITER && l->ukind != KENDITER)
5039 if (l->ukind == KVAR)
5041 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5043 ekind_unparse (l->ukind)));
5047 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5049 ekind_unparse (l->ukind)));
5052 return globSet_undefined;
5055 return l->info->fcn->globs;
5058 /*@observer@*/ sRefSet
5059 uentry_getMods (uentry l)
5061 llassert (uentry_isValid (l));
5063 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5065 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5066 return sRefSet_undefined;
5069 return l->info->fcn->mods;
5073 uentry_getKind (uentry e)
5075 llassert (uentry_isValid (e));
5080 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5082 llassert (uentry_isEitherConstant (e));
5084 return (e->info->uconst->val);
5087 /*@observer@*/ uentryList
5088 uentry_getParams (uentry l)
5090 if (uentry_isInvalid (l)) return uentryList_undefined;
5097 ctype ct = l->utype;
5099 if (ctype_isFunction (ct))
5101 return (ctype_argsFunction (ct));
5105 return uentryList_undefined;
5110 ctype ct = l->utype;
5112 llassert (ctype_isFunction (ct));
5113 return (ctype_argsFunction (ct));
5120 /*@observer@*/ cstring
5121 uentry_rawName (uentry e)
5123 if (uentry_isValid (e))
5129 return cstring_undefined;
5134 uentry_getOptName (uentry e)
5136 cstring s = uentry_getName (e);
5138 if (cstring_isDefined (s))
5140 s = cstring_appendChar (s, ' ');
5147 uentry_getName (uentry e)
5149 cstring ret = cstring_undefined;
5151 if (uentry_isValid (e))
5154 if (uentry_isAnyTag (e))
5156 ret = fixTagName (e->uname);
5158 else if (uentry_isAnyParam (e))
5160 ret = cstring_copy (fixParamName (e->uname));
5164 ret = cstring_copy (e->uname);
5171 cstring uentry_getRealName (uentry e)
5173 if (uentry_isValid (e))
5175 if (uentry_isAnyTag (e))
5177 return (cstring_undefined);
5184 return cstring_undefined;
5187 ctype uentry_getType (uentry e)
5189 if (uentry_isValid (e))
5195 return ctype_unknown;
5199 fileloc uentry_whereLast (uentry e)
5203 if (uentry_isInvalid (e))
5205 return fileloc_undefined;
5208 loc = e->whereDefined;
5210 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5215 loc = uentry_whereDeclared (e);
5217 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5222 loc = uentry_whereSpecified (e);
5226 fileloc uentry_whereEither (uentry e)
5228 if (uentry_isInvalid (e)) return fileloc_undefined;
5230 if (fileloc_isDefined (e->whereDefined)
5231 && !fileloc_isExternal (e->whereDefined))
5233 return e->whereDefined;
5235 else if (fileloc_isDefined (e->whereDeclared))
5237 return e->whereDeclared;
5241 return e->whereSpecified;
5245 fileloc uentry_whereSpecified (uentry e)
5247 if (uentry_isInvalid (e)) return fileloc_undefined;
5249 return (e->whereSpecified);
5252 fileloc uentry_whereDefined (uentry e)
5254 if (uentry_isInvalid (e)) return fileloc_undefined;
5256 return (e->whereDefined);
5259 fileloc uentry_whereDeclared (uentry e)
5261 if (uentry_isInvalid (e)) return fileloc_undefined;
5263 return (e->whereDeclared);
5266 /*@observer@*/ fileloc
5267 uentry_whereEarliest (uentry e)
5269 if (uentry_isInvalid (e)) return fileloc_undefined;
5271 if (fileloc_isDefined (e->whereSpecified))
5273 return (e->whereSpecified);
5275 else if (fileloc_isDefined (e->whereDeclared))
5277 return (e->whereDeclared);
5281 return e->whereDefined;
5286 uentry_setFunctionDefined (uentry e, fileloc loc)
5288 if (uentry_isValid (e))
5290 llassert (uentry_isFunction (e));
5292 if (fileloc_isUndefined (e->whereDeclared))
5294 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5297 if (!fileloc_isDefined (e->whereDefined))
5299 e->whereDefined = fileloc_update (e->whereDefined, loc);
5305 uentry_setDeclDef (uentry e, fileloc f)
5307 uentry_setDeclared (e, f);
5309 if (!uentry_isFunction (e)
5310 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5312 uentry_setDefined (e, f);
5317 uentry_setDeclaredForce (uentry e, fileloc f)
5319 llassert (uentry_isValid (e));
5320 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5324 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5326 llassert (uentry_isValid (e));
5327 fileloc_free (e->whereDeclared);
5328 e->whereDeclared = f;
5332 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5336 llassert (uentry_isValid (e));
5337 oldloc = e->whereDeclared;
5339 if (fileloc_isDefined (oldloc))
5341 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5343 e->whereDeclared = f;
5344 fileloc_free (oldloc);
5353 e->whereDeclared = f;
5354 fileloc_free (oldloc);
5359 uentry_setDeclared (uentry e, fileloc f)
5363 llassert (uentry_isValid (e));
5364 oldloc = e->whereDeclared;
5366 if (fileloc_isDefined (oldloc))
5368 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5370 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5379 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5384 uentry_clearDefined (uentry e)
5386 if (uentry_isValid (e))
5388 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5393 uentry_setDefined (uentry e, fileloc f)
5397 llassert (uentry_isValid (e));
5398 oldloc = e->whereDefined;
5400 if (fileloc_isDefined (oldloc))
5402 if (fileloc_isLib (oldloc)
5403 || fileloc_isImport (oldloc)
5404 || fileloc_isBuiltin (oldloc)
5405 || fileloc_isPreproc (oldloc))
5407 e->whereDefined = fileloc_update (e->whereDefined, f);
5411 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5417 if (optgenerror (FLG_REDEF,
5418 message ("%s %q redefined",
5419 ekind_capName (e->ukind),
5420 uentry_getName (e)),
5423 llgenindentmsg (message ("Previous definition of %q",
5424 uentry_getName (e)),
5432 e->whereDefined = fileloc_update (e->whereDefined, f);
5437 uentry_isCodeDefined (uentry e)
5439 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
5443 uentry_isDeclared (uentry e)
5445 if (uentry_isValid (e))
5447 return (fileloc_isDefined (e->whereDeclared));
5453 sRef uentry_getSref (uentry e)
5455 /* not true, used for functions too (but shouldn't be? */
5456 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
5458 if (uentry_isInvalid (e)) return sRef_undefined;
5463 sRef uentry_getOrigSref (uentry e)
5465 if (uentry_isValid (e))
5467 sRef sr = sRef_copy (uentry_getSref (e));
5469 sRef_resetState (sr);
5470 sRef_clearDerived (sr);
5472 if (uentry_isVariable (e))
5474 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
5475 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
5482 return sRef_undefined;
5487 ** requires: uentry e is not in a hashed symbol table
5491 uentry_setName (uentry e, /*@only@*/ cstring n)
5493 llassert (uentry_isValid (e));
5495 cstring_free (e->uname);
5500 uentry_setType (uentry e, ctype t)
5502 if (uentry_isValid (e))
5505 sRef_setType (e->sref, t);
5510 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
5513 ctype rettype = ctype_unknown;
5515 llassert (uentry_isValid (ue));
5517 rct = ctype_realType (ue->utype);
5519 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
5521 uentry_makeVarFunction (ue);
5524 llassert (uentry_isFunction (ue));
5526 if (ctype_isFunction (rct))
5528 rettype = ctype_returnValue (rct);
5531 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
5535 uentry_setRefParam (uentry e)
5538 if (!uentry_isVar (e))
5540 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5544 if (e->info->var->kind == VKSEFPARAM)
5546 e->info->var->kind = VKREFSEFPARAM;
5548 else if (e->info->var->kind == VKSEFRETPARAM)
5550 e->info->var->kind = VKREFSEFRETPARAM;
5552 else if (e->info->var->kind == VKYIELDPARAM)
5554 e->info->var->kind = VKREFYIELDPARAM;
5558 e->info->var->kind = VKREFPARAM;
5564 uentry_setParam (uentry e)
5566 if (!uentry_isVar (e))
5568 if (uentry_isElipsisMarker (e))
5574 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5581 if (e->info->var->kind == VKYIELDPARAM
5582 || e->info->var->kind == VKSEFPARAM
5583 || e->info->var->kind == VKSEFRETPARAM)
5589 e->info->var->kind = VKPARAM;
5593 e->uname = makeParam (e->uname);
5594 cstring_free (oldname);
5599 uentry_setSref (uentry e, sRef s)
5601 if (uentry_isValid (e))
5603 if (sRef_isValid (e->sref))
5605 sRef_mergeStateQuietReverse (e->sref, s);
5609 e->sref = sRef_saveCopy (s);
5615 uentry_getAbstractType (uentry e)
5617 llassert (uentry_isDatatype (e));
5620 ** This assertion removed.
5621 ** Okay to have undefined type, for system types
5623 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
5624 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
5629 if (ctype_isUndefined (e->info->datatype->type))
5631 return ctype_unknown;
5635 ** Sadly, a kludge...
5638 if (ctype_isUserBool (e->info->datatype->type)) {
5642 return e->info->datatype->type;
5645 ctype uentry_getRealType (uentry e)
5648 typeId uid = USYMIDINVALID;
5650 if (uentry_isInvalid (e))
5652 return ctype_unknown;
5655 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5657 if (uentry_isAnyTag (e))
5662 if (uentry_isAbstractType (e))
5664 ct = uentry_getAbstractType (e);
5666 if (ctype_isManifestBool (ct)) {
5670 llassert (ctype_isUA (ct));
5672 uid = ctype_typeId (ct);
5674 if (!context_hasAccess (uid))
5680 ct = uentry_getType (e);
5682 /* if (ctype_isUserBool (ct)) return ct; */
5684 if (ctype_isManifestBool (ct)) {
5688 if (ctype_isUA (ct))
5690 usymId iid = ctype_typeId (ct);
5692 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5694 llcontbug (message ("uentry_getRealType: recursive type! %s",
5695 ctype_unparse (ct)));
5700 /* evs 2000-07-25: possible infinite recursion ? */
5701 uentry ue2 = usymtab_getTypeEntry (iid);
5702 llassertprint (ue2 != e, ("Bad recursion: %s", uentry_unparseFull (e)));
5704 return uentry_getRealType (ue2);
5713 ctype uentry_getForceRealType (uentry e)
5716 typeId uid = USYMIDINVALID;
5718 if (uentry_isInvalid (e))
5720 return ctype_unknown;
5723 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5725 if (uentry_isAnyTag (e))
5730 if (uentry_isAbstractType (e))
5732 ct = uentry_getAbstractType (e);
5733 llassert (ctype_isUA (ct));
5735 uid = ctype_typeId (ct);
5736 /* no check for access! */
5739 ct = uentry_getType (e);
5741 /* evs 2000-07-25 */
5742 /* if (ctype_isUserBool (ct)) return ct; */
5744 if (ctype_isManifestBool (ct)) {
5748 if (ctype_isUA (ct))
5750 usymId iid = ctype_typeId (ct);
5752 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5754 llcontbug (message ("uentry_getRealType: recursive type! %s",
5755 ctype_unparse (ct)));
5760 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
5769 uentry uentry_nameCopy (cstring name, uentry e)
5771 uentry enew = uentry_alloc ();
5773 llassert (uentry_isValid (e));
5775 /* enew->shallowCopy = FALSE; */
5776 enew->ukind = e->ukind;
5778 enew->utype = e->utype;
5779 enew->whereSpecified = fileloc_copy (e->whereSpecified);
5780 enew->whereDefined = fileloc_copy (e->whereDefined);
5781 enew->whereDeclared = fileloc_copy (e->whereDeclared);
5782 enew->sref = sRef_copy (e->sref);
5783 enew->used = e->used;
5785 enew->isPrivate = e->isPrivate;
5786 enew->hasNameError = FALSE;
5788 enew->uses = filelocList_new ();
5790 enew->storageclass = e->storageclass;
5791 enew->info = uinfo_copy (e->info, e->ukind);
5797 uentry_setDatatype (uentry e, usymId uid)
5799 llassert (uentry_isDatatype (e));
5801 if (uentry_isAbstractType (e))
5803 e->info->datatype->type = ctype_createAbstract (uid);
5807 e->info->datatype->type = ctype_createUser (uid);
5812 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
5813 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
5816 llassert (uentry_isValid (e));
5818 if (fileloc_isSpec (f) || fileloc_isImport (f))
5820 e->whereSpecified = f;
5821 e->whereDeclared = fileloc_undefined;
5822 e->whereDefined = fileloc_undefined;
5826 e->whereSpecified = fileloc_undefined;
5827 e->whereDeclared = f;
5828 e->whereDefined = fileloc_undefined;
5833 ucinfo_free (/*@only@*/ ucinfo u)
5835 multiVal_free (u->val);
5840 uvinfo_free (/*@only@*/ uvinfo u)
5846 udinfo_free (/*@only@*/ udinfo u)
5852 ufinfo_free (/*@only@*/ ufinfo u)
5854 globSet_free (u->globs);
5855 sRefSet_free (u->mods);
5856 specialClauses_free (u->specclauses);
5862 uiinfo_free (/*@only@*/ uiinfo u)
5868 ueinfo_free (/*@only@*/ ueinfo u)
5873 static /*@only@*/ ucinfo
5874 ucinfo_copy (ucinfo u)
5876 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
5878 ret->val = multiVal_copy (u->val);
5879 ret->access = u->access;
5884 static /*@only@*/ uvinfo
5885 uvinfo_copy (uvinfo u)
5887 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
5889 ret->kind = u->kind;
5890 ret->nullstate = u->nullstate;
5891 ret->defstate = u->defstate;
5892 ret->checked = u->checked;
5894 //ret->bufinfo = u->bufinfo;
5895 /*@i334@*/ return ret;
5898 static /*@only@*/ udinfo
5899 udinfo_copy (udinfo u)
5901 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
5905 ret->type = u->type;
5910 static /*@only@*/ ufinfo
5911 ufinfo_copy (ufinfo u)
5913 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
5915 ret->hasGlobs = u->hasGlobs;
5916 ret->hasMods = u->hasMods;
5917 ret->exitCode = u->exitCode;
5918 ret->specialCode = u->specialCode;
5919 ret->nullPred = u->nullPred;
5920 ret->access = u->access;
5921 ret->globs = globSet_newCopy (u->globs);
5922 ret->mods = sRefSet_newCopy (u->mods);
5923 ret->defparams = u->defparams;
5924 ret->specclauses = specialClauses_copy (u->specclauses);
5927 ret->preconditions = u->preconditions? constraintList_copy(u->preconditions): NULL;
5933 static /*@only@*/ uiinfo
5934 uiinfo_copy (uiinfo u)
5936 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
5938 ret->access = u->access;
5939 ret->globs = globSet_newCopy (u->globs);
5940 ret->mods = sRefSet_newCopy (u->mods);
5945 static /*@only@*/ ueinfo
5946 ueinfo_copy (ueinfo u)
5948 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
5950 ret->access = u->access;
5955 uinfo_free (uinfo u, ekind kind)
5960 case KCONST: ucinfo_free (u->uconst); break;
5961 case KVAR: uvinfo_free (u->var); break;
5965 case KDATATYPE: udinfo_free (u->datatype); break;
5966 case KFCN: ufinfo_free (u->fcn); break;
5967 case KITER: uiinfo_free (u->iter); break;
5968 case KENDITER: ueinfo_free (u->enditer); break;
5969 case KELIPSMARKER: break;
5970 case KINVALID: break;
5976 static /*@only@*/ /*@null@*/ uinfo
5977 uinfo_copy (uinfo u, ekind kind)
5979 if (kind == KELIPSMARKER || kind == KINVALID)
5985 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
5990 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
5991 case KVAR: ret->var = uvinfo_copy (u->var); break;
5995 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
5996 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
5997 case KITER: ret->iter = uiinfo_copy (u->iter); break;
5998 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6006 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6008 filelocList_free (e->uses);
6009 cstring_free (e->uname);
6011 uinfo_free (e->info, e->ukind);
6013 fileloc_free (e->whereSpecified);
6014 fileloc_free (e->whereDefined);
6015 fileloc_free (e->whereDeclared);
6021 extern void uentry_markOwned (/*@owned@*/ uentry u)
6023 sfreeEventually (u);
6027 uentry_free (/*@only@*/ uentry e)
6029 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6031 uentry_reallyFree (e);
6036 ** For uentry's in the global or file scope
6040 uentry_freeComplete (/*@only@*/ uentry e)
6042 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6044 /*@i@*/ sRef_free (e->sref);
6045 e->sref = sRef_undefined;
6046 uentry_reallyFree (e);
6051 ** requires old->kind != new->kind, old->uname = new->uname
6055 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6057 llassert (uentry_isValid (old));
6058 llassert (uentry_isValid (unew));
6060 if (uentry_isEitherConstant (unew)
6061 && (fileloc_isPreproc (uentry_whereDeclared (old))
6062 || ctype_isUnknown (old->utype))
6063 && !uentry_isSpecified (old))
6071 if (!uentry_isDeclared (old))
6073 if (uentry_isSpecified (old))
6075 if (uentry_isSpecified (unew))
6077 llbuglit ("Respecification!");
6079 else if (uentry_isDeclared (unew))
6083 message ("%s %q inconsistently declared as %s: %t",
6084 ekind_capName (old->ukind),
6085 uentry_getName (unew),
6086 ekind_unparseLong (unew->ukind),
6088 uentry_whereDeclared (unew)))
6090 uentry_showWhereLast (old);
6102 message ("%s %q inconsistently declared as %s: %t",
6103 ekind_capName (old->ukind),
6104 uentry_getName (unew),
6105 ekind_unparseLong (unew->ukind),
6107 uentry_whereDeclared (unew)))
6109 uentry_showWhereLast (old);
6115 llassert (uentry_isDeclared (unew));
6119 message ("%s %q inconsistently redeclared as %s",
6120 ekind_capName (old->ukind),
6121 uentry_getName (unew),
6122 ekind_unparseLong (unew->ukind)),
6123 uentry_whereDeclared (unew)))
6125 uentry_showWhereLast (old);
6131 uentry_copyInto (old, unew);
6135 ** def is the definition of spec, modifies spec
6137 ** reports any inconsistencies
6138 ** returns the summary of all available information
6139 ** if spec and def are inconsistent, def is returned
6143 uentry_showWhereLast (uentry spec)
6145 if (uentry_isValid (spec))
6147 if (fileloc_isDefined (spec->whereDefined)
6148 && !fileloc_isLib (spec->whereDefined)
6149 && !fileloc_isPreproc (spec->whereDefined))
6151 llgenindentmsg (message ("Previous definition of %q: %t",
6152 uentry_getName (spec),
6153 uentry_getType (spec)),
6154 uentry_whereDefined (spec));
6156 else if (uentry_isDeclared (spec))
6158 llgenindentmsg (message ("Previous declaration of %q: %t",
6159 uentry_getName (spec),
6160 uentry_getType (spec)),
6161 uentry_whereDeclared (spec));
6163 else if (uentry_isSpecified (spec))
6165 if (uentry_hasName (spec))
6167 llgenindentmsg (message ("Specification of %q: %t",
6168 uentry_getName (spec),
6169 uentry_getType (spec)),
6170 uentry_whereSpecified (spec));
6174 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6175 uentry_whereSpecified (spec));
6180 /* nothing to show */
6186 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6188 fileloc loc = uentry_whereDefined (ce);
6190 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6192 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6196 loc = uentry_whereSpecified (ce);
6198 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6200 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6205 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6207 if (uentry_isDeclared (spec))
6209 llgenindentmsg (message ("Previous declaration of %q: %q",
6210 uentry_getName (spec), extra),
6211 uentry_whereDeclared (spec));
6213 else if (uentry_isSpecified (spec))
6215 llgenindentmsg (message ("Specification of %q: %q",
6216 uentry_getName (spec), extra),
6217 uentry_whereSpecified (spec));
6221 cstring_free (extra);
6226 uentry_showWhereDeclared (uentry spec)
6228 if (uentry_isDeclared (spec))
6230 if (uentry_hasName (spec))
6232 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6233 uentry_whereDeclared (spec));
6237 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6240 else if (uentry_isSpecified (spec))
6242 if (uentry_hasName (spec))
6244 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6245 uentry_whereSpecified (spec));
6249 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6254 /* nothing to show */
6260 uentry_showWhereAny (uentry spec)
6262 if (uentry_isDeclared (spec))
6264 if (uentry_hasName (spec))
6266 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6267 uentry_whereDeclared (spec));
6271 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6274 else if (uentry_isSpecified (spec))
6276 if (uentry_hasName (spec))
6278 llgenindentmsg (message ("Specification of %q",
6279 uentry_getName (spec)),
6280 uentry_whereSpecified (spec));
6284 llgenindentmsg (cstring_makeLiteral ("Specification"),
6285 uentry_whereSpecified (spec));
6288 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6290 if (uentry_hasName (spec))
6292 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6293 uentry_whereDefined (spec));
6297 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6302 /* nothing to show */
6307 uentry_showWhereDefined (uentry spec)
6309 if (uentry_isCodeDefined (spec))
6311 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6312 uentry_whereDefined (spec));
6317 uentry_showWhereLastPlain (uentry spec)
6319 if (uentry_isDeclared (spec))
6321 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6322 uentry_whereDeclared (spec));
6324 else if (uentry_isSpecified (spec))
6326 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6327 uentry_whereSpecified (spec));
6335 uentry_showWhereLastVal (uentry spec, cstring val)
6337 if (uentry_isDeclared (spec))
6339 llgenindentmsg (message ("Previous declaration of %q: %s",
6340 uentry_getName (spec), val),
6341 uentry_whereDeclared (spec));
6343 else if (uentry_isSpecified (spec))
6345 llgenindentmsg (message ("Specification of %q: %s",
6346 uentry_getName (spec), val),
6347 uentry_whereSpecified (spec));
6355 uentry_showWhereSpecified (uentry spec)
6357 if (uentry_isSpecified (spec))
6359 if (uentry_hasName (spec))
6361 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6362 uentry_whereSpecified (spec));
6366 llgenindentmsg (cstring_makeLiteral ("Specification"),
6367 uentry_whereSpecified (spec));
6370 else if (uentry_isDeclared (spec))
6372 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6373 uentry_whereDeclared (spec));
6377 /* nothing to show */
6382 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6384 if (uentry_isSpecified (spec))
6386 if (uentry_hasName (spec))
6388 llgenindentmsg (message ("Specification of %q: %q",
6389 uentry_getName (spec), s),
6390 uentry_whereSpecified (spec));
6394 llgenindentmsg (message ("Specification: %q", s),
6395 uentry_whereSpecified (spec));
6398 else if (uentry_isDeclared (spec))
6400 llgenindentmsg (message ("Declaration of %q: %q",
6401 uentry_getName (spec), s),
6402 uentry_whereDeclared (spec));
6406 llgenindentmsg (message ("Previous: %q", s),
6407 uentry_whereLast (spec));
6416 checkStructConformance (uentry old, uentry unew)
6419 uentryList fold, fnew;
6422 ** requires: types of old and new are structs or unions
6425 llassert (uentry_isValid (old));
6426 llassert (uentry_isValid (unew));
6428 oldr = ctype_realType (old->utype);
6429 fold = ctype_getFields (oldr);
6431 newr = ctype_realType (unew->utype);
6432 fnew = ctype_getFields (newr);
6434 if (!uentryList_matchFields (fold, fnew))
6436 if (fileloc_equal (uentry_whereLast (old),
6437 uentry_whereLast (unew)))
6445 message ("%q %q %rdeclared with fields { %q }, %s "
6446 "with fields { %q }",
6447 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
6448 uentry_getName (old),
6449 uentry_isDeclared (old),
6450 uentryList_unparseAbbrev (fnew),
6451 uentry_specOrDefName (old),
6452 uentryList_unparseAbbrev (fold)),
6453 uentry_whereDeclared (unew)))
6455 uentry_showWhereLastPlain (old);
6456 uentryList_showFieldDifference (fold, fnew);
6460 old->utype = unew->utype;
6465 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6468 ** requires old and new are enums
6471 ctype rold = ctype_realType (old->utype);
6472 ctype rnew = ctype_realType (unew->utype);
6473 enumNameList eold = ctype_elist (rold);
6474 enumNameList enew = ctype_elist (rnew);
6476 if (!enumNameList_match (eold, enew))
6480 message ("Enum %q declared with members { %q } but "
6481 "specified with members { %q }",
6482 uentry_getName (old),
6483 enumNameList_unparse (enew),
6484 enumNameList_unparse (eold)),
6485 uentry_whereDeclared (unew)))
6487 uentry_showWhereSpecified (old);
6488 old->utype = unew->utype;
6494 ** either oldCurrent or newCurrent may be undefined!
6498 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
6499 uentry unew, uentry newCurrent, ctype newType,
6502 bool hasError = FALSE;
6504 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
6506 if (uentry_hasName (newCurrent))
6508 hasError = optgenerror
6510 message ("Parameter %d, %q, of function %q has inconsistent type: "
6511 "declared %t, %s %t",
6512 paramno + 1, uentry_getName (newCurrent),
6513 uentry_getName (unew),
6514 newType, uentry_specOrDefName (old), oldType),
6515 uentry_whereDeclared (newCurrent));
6519 hasError = optgenerror
6521 message ("Parameter %d of function %q has inconsistent type: "
6522 "declared %t, %s %t",
6523 paramno + 1, uentry_getName (unew),
6524 newType, uentry_specOrDefName (old), oldType),
6525 uentry_whereDeclared (newCurrent));
6527 DPRINTF (("type: %s / %s",
6528 ctype_unparse (newType),
6529 ctype_unparse (ctype_realType (newType))));
6534 if (uentry_isDeclared (unew))
6536 hasError = optgenerror
6538 message ("Parameter %d of function %s has inconsistent type: "
6539 "declared %t, %s %t",
6540 paramno + 1, unew->uname,
6541 newType, uentry_specOrDefName (old), oldType),
6542 uentry_whereDeclared (unew));
6546 hasError = optgenerror
6548 message ("Parameter %d of function %s has inconsistent type: "
6549 "declared %t, %s %t",
6550 paramno + 1, unew->uname,
6551 newType, uentry_specOrDefName (old), oldType),
6552 uentry_whereDeclared (unew));
6558 if (!uentry_isUndefined (oldCurrent))
6560 if (!uentry_isUndefined (newCurrent)
6561 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
6563 uentry_showWhereLast (oldCurrent);
6567 uentry_showWhereLastPlain (old);
6570 uentry_setType (oldCurrent, newType);
6574 uentry_showWhereLastPlain (old);
6580 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6584 message ("Function %s %rdeclared with %d arg%p, %s with %d",
6586 uentry_isDeclared (old),
6587 uentryList_size (uentry_getParams (unew)),
6588 uentry_specOrDefName (old),
6589 uentryList_size (uentry_getParams (old))),
6590 uentry_whereDeclared (unew)))
6592 uentry_showWhereLastPlain (old);
6597 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6601 message ("Function %s inconsistently %rdeclared to return %t",
6603 uentry_isDeclared (old),
6604 ctype_returnValue (unew->utype)),
6605 uentry_whereDeclared (unew)))
6607 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
6611 static cstring paramStorageName (uentry ue)
6613 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
6616 static cstring fcnErrName (uentry ue)
6618 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
6621 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
6623 if (uentry_isVar (ue))
6625 return (checkedName (ue->info->var->checked));
6629 return (cstring_makeLiteralTemp ("<checked invalid>"));
6633 static cstring checkedName (chkind checked)
6637 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
6638 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
6639 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
6640 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
6641 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
6647 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
6652 if (uentry_isVar (unew))
6654 llassert (uentry_isVar (old));
6656 oldState = old->info->var->nullstate;
6657 newState = unew->info->var->nullstate;
6661 oldState = sRef_getNullState (old->sref);
6662 newState = sRef_getNullState (unew->sref);
6665 if (oldState == NS_ABSNULL)
6667 if (uentry_isVar (old))
6669 old->info->var->nullstate = newState;
6672 sRef_mergeNullState (old->sref, newState);
6674 else if (newState == NS_UNKNOWN)
6676 if (completeConform && newState != oldState
6677 && uentry_isReallySpecified (old))
6681 message ("%s %q specified as %s, but declared without %s qualifier",
6682 ekind_capName (unew->ukind),
6683 uentry_getName (unew),
6684 nstate_unparse (oldState),
6685 nstate_unparse (oldState)),
6686 uentry_whereDeclared (unew)))
6688 uentry_showWhereSpecified (old);
6692 if (uentry_isVar (unew))
6694 unew->info->var->nullstate = oldState;
6697 sRef_mergeNullState (unew->sref, oldState);
6699 else if (newState == NS_POSNULL)
6701 if (oldState == NS_MNOTNULL
6702 && (ctype_isUA (unew->utype)
6703 || (uentry_isFunction (unew)
6704 && ctype_isUA (ctype_returnValue (unew->utype)))))
6706 if (uentry_isVar (unew))
6708 unew->info->var->nullstate = oldState;
6711 sRef_mergeNullState (unew->sref, oldState);
6715 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
6716 || oldState == NS_UNKNOWN)
6723 ("%s %q inconsistently %rdeclared %s possibly null storage, "
6725 uentry_ekindName (unew),
6726 uentry_getName (unew),
6727 uentry_isDeclared (old),
6729 uentry_specOrDefName (old),
6730 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
6731 uentry_whereDeclared (unew)))
6733 uentry_showWhereSpecified (old);
6738 if (uentry_isVar (old))
6740 old->info->var->nullstate = newState;
6743 sRef_mergeNullState (old->sref, newState);
6746 else if (newState == NS_MNOTNULL)
6748 if (oldState != NS_MNOTNULL)
6754 message ("%s %q inconsistently %rdeclared %s notnull storage, "
6755 "%s without notnull qualifier",
6756 uentry_ekindName (unew),
6757 uentry_getName (unew),
6758 uentry_isDeclared (old),
6760 uentry_specOrDefName (old)),
6761 uentry_whereDeclared (unew)))
6763 uentry_showWhereSpecified (old);
6767 if (uentry_isVar (old))
6769 old->info->var->nullstate = newState;
6772 sRef_mergeNullState (old->sref, newState);
6777 if (uentry_isVar (unew))
6779 unew->info->var->nullstate = oldState;
6782 sRef_mergeNullState (unew->sref, oldState);
6787 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6788 bool mustConform, bool completeConform)
6794 if (uentry_isVar (old) && uentry_isVar (unew))
6796 oldState = old->info->var->defstate;
6797 newState = unew->info->var->defstate;
6802 oldState = sRef_getDefState (old->sref);
6803 newState = sRef_getDefState (unew->sref);
6806 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
6812 message ("%s %q inconsistently %rdeclared %s %s %s, "
6814 uentry_ekindName (unew),
6815 uentry_getName (unew),
6816 uentry_isDeclared (old),
6818 sstate_unparse (newState),
6819 paramStorageName (unew),
6820 uentry_specOrDefName (old),
6822 sstate_unparse (oldState),
6823 paramStorageName (unew)),
6824 uentry_whereDeclared (unew)))
6826 uentry_showWhereSpecified (old);
6830 if (vars) old->info->var->defstate = newState;
6831 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
6836 && (newState != oldState) && (oldState != SS_DEFINED)
6837 && uentry_isReallySpecified (old))
6841 message ("%s %q specified as %s, but declared without %s qualifier",
6842 ekind_capName (unew->ukind),
6843 uentry_getName (unew),
6844 sstate_unparse (oldState),
6845 sstate_unparse (oldState)),
6846 uentry_whereDeclared (unew)))
6848 uentry_showWhereSpecified (old);
6852 if (vars) unew->info->var->defstate = oldState;
6853 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
6858 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6859 bool mustConform, bool completeConform)
6864 oldKind = sRef_getAliasKind (old->sref);
6865 newKind = sRef_getAliasKind (unew->sref);
6867 if (alkind_isImplicit (newKind)
6868 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
6870 if (completeConform && !alkind_equal (newKind, oldKind)
6871 && uentry_isReallySpecified (old))
6875 message ("%s %q specified as %s, but declared without "
6876 "explicit alias qualifier",
6877 ekind_capName (unew->ukind),
6878 uentry_getName (unew),
6879 alkind_unparse (oldKind)),
6880 uentry_whereDeclared (unew)))
6882 uentry_showWhereSpecified (old);
6887 ** This really shouldn't be necessary, but it is!
6888 ** Function params (?) use new here.
6891 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
6895 if (alkind_isKnown (newKind))
6897 if (!alkind_equal (oldKind, newKind))
6899 if (alkind_isKnown (oldKind))
6904 message ("%s %q inconsistently %rdeclared %s %s storage, "
6906 uentry_ekindName (unew),
6907 uentry_getName (unew),
6908 uentry_isDeclared (old),
6910 alkind_unparse (newKind),
6911 uentry_specOrDefName (old),
6912 alkind_unparse (oldKind)),
6913 uentry_whereDeclared (unew)))
6915 uentry_showWhereSpecified (old);
6917 sRef_setAliasKind (old->sref, AK_ERROR,
6918 uentry_whereDeclared (unew));
6922 sRef_setAliasKind (old->sref, newKind,
6923 uentry_whereDeclared (unew));
6928 if (!(alkind_isImplicit (newKind)))
6931 !uentry_isFunction (unew) &&
6934 message ("%s %q inconsistently %rdeclared %s %s storage, "
6935 "implicitly %s as temp storage",
6936 uentry_ekindName (unew),
6937 uentry_getName (unew),
6938 uentry_isDeclared (old),
6940 alkind_unparse (newKind),
6941 uentry_specOrDefName (old)),
6942 uentry_whereDeclared (unew)))
6944 uentry_showWhereSpecified (old);
6948 sRef_setAliasKind (old->sref, newKind,
6949 uentry_whereDeclared (unew));
6951 else /* newKind is temp or refcounted */
6958 else /* newKind unknown */
6965 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6966 bool mustConform, bool completeConform)
6971 oldKind = sRef_getExKind (old->sref);
6972 newKind = sRef_getExKind (unew->sref);
6974 if (exkind_isKnown (newKind))
6976 if (oldKind != newKind)
6978 if (exkind_isKnown (oldKind))
6983 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
6984 uentry_ekindName (unew),
6985 uentry_getName (unew),
6986 uentry_isDeclared (old),
6988 exkind_unparse (newKind),
6989 uentry_specOrDefName (old),
6990 exkind_unparse (oldKind)),
6991 uentry_whereDeclared (unew)))
6993 uentry_showWhereSpecified (old);
6996 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7003 message ("%s %q inconsistently %rdeclared %s %s, "
7004 "implicitly %s without exposure qualifier",
7005 uentry_ekindName (unew),
7006 uentry_getName (unew),
7007 uentry_isDeclared (old),
7009 exkind_unparse (newKind),
7010 uentry_specOrDefName (old)),
7011 uentry_whereDeclared (unew)))
7013 uentry_showWhereSpecified (old);
7016 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7022 if (completeConform && exkind_isKnown (oldKind)
7023 && uentry_isReallySpecified (old))
7027 message ("%s %q specified as %s, but declared without "
7028 "exposure qualifier",
7029 ekind_capName (unew->ukind),
7030 uentry_getName (unew),
7031 exkind_unparse (oldKind)),
7032 uentry_whereDeclared (unew)))
7034 uentry_showWhereSpecified (old);
7038 /* yes, this is necessary! (if its a param) */
7039 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7044 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7045 /*@notnull@*/ uentry unew,
7046 bool mustConform, bool completeConform)
7048 checkDefState (old, unew, mustConform, completeConform);
7049 checkNullState (old, unew, mustConform, completeConform);
7050 checkAliasState (old, unew, mustConform, completeConform);
7051 checkExpState (old, unew, mustConform, completeConform);
7053 sRef_storeState (old->sref);
7054 sRef_storeState (unew->sref);
7058 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7060 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7065 llassert (uentry_isVar (old));
7066 llassert (uentry_isVar (unew));
7068 if (cstring_isEmpty (old->uname))
7070 cstring_free (old->uname);
7071 old->uname = cstring_copy (unew->uname);
7074 if (unew->info->var->kind == VKRETPARAM
7075 || unew->info->var->kind == VKSEFRETPARAM)
7077 if (old->info->var->kind != VKRETPARAM
7078 && old->info->var->kind != VKSEFRETPARAM)
7082 message ("Parameter %q inconsistently %rdeclared as "
7083 "returned parameter",
7084 uentry_getName (unew),
7085 uentry_isDeclared (old)),
7086 uentry_whereDeclared (unew)))
7088 uentry_showWhereSpecified (old);
7089 old->info->var->kind = unew->info->var->kind;
7095 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7097 if (old->info->var->kind != VKSEFPARAM
7098 && old->info->var->kind != VKSEFRETPARAM)
7102 message ("Parameter %qinconsistently %rdeclared as "
7104 uentry_getOptName (unew),
7105 uentry_isDeclared (old)),
7106 uentry_whereDeclared (unew)))
7108 uentry_showWhereSpecified (old);
7109 old->info->var->kind = unew->info->var->kind;
7114 if (old->info->var->kind == VKSPEC)
7116 old->info->var->kind = unew->info->var->kind;
7120 unew->info->var->kind = old->info->var->kind;
7123 if (unew->info->var->checked != CH_UNKNOWN
7124 && unew->info->var->checked != old->info->var->checked)
7126 if (old->info->var->checked == CH_UNKNOWN
7127 && !fileloc_isUser (uentry_whereLast (old)))
7135 message ("Variable %q inconsistently %rdeclared as "
7136 "%s parameter (was %s)",
7137 uentry_getName (unew),
7138 uentry_isDeclared (old),
7139 checkedName (unew->info->var->checked),
7140 checkedName (old->info->var->checked)),
7141 uentry_whereDeclared (unew)))
7143 uentry_showWhereSpecified (old);
7147 old->info->var->checked = unew->info->var->checked;
7152 && (old->info->var->checked != CH_UNKNOWN)
7153 && uentry_isReallySpecified (old))
7157 message ("%s %q specified as %s, but declared without %s qualifier",
7158 ekind_capName (unew->ukind),
7159 uentry_getName (unew),
7160 checkedName (old->info->var->checked),
7161 checkedName (old->info->var->checked)),
7162 uentry_whereDeclared (unew)))
7164 uentry_showWhereSpecified (old);
7168 unew->info->var->checked = old->info->var->checked;
7171 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7174 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7176 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7181 llassert (uentry_isVar (u1));
7182 llassert (uentry_isVar (u2));
7184 if (u1->info->var->kind != u2->info->var->kind) {
7185 if (u1->info->var->kind == VKSEFRETPARAM) {
7186 if (u2->info->var->kind == VKRETPARAM) {
7189 message ("Function types are inconsistent. Parameter %d is "
7190 "sef parameter, but non-sef parameter in "
7191 "assigned function: %s",
7192 paramno, exprNode_unparse (e)),
7194 } else if (u2->info->var->kind == VKSEFPARAM) {
7197 message ("Function types are inconsistent. Parameter %d is "
7198 "returns parameter, but non-returns parameter in "
7199 "assigned function: %s",
7200 paramno, exprNode_unparse (e)),
7205 message ("Function types are inconsistent. Parameter %d is "
7206 "sef returns parameter, but non-sef returns parameter in "
7207 "assigned function: %s",
7208 paramno, exprNode_unparse (e)),
7211 } else if (u1->info->var->kind == VKRETPARAM) {
7214 message ("Function types are inconsistent. Parameter %d is "
7215 "returns parameter, but non-returns parameter in "
7216 "assigned function: %s",
7217 paramno, exprNode_unparse (e)),
7219 } else if (u1->info->var->kind == VKSEFPARAM) {
7222 message ("Function types are inconsistent. Parameter %d is "
7223 "sef parameter, but non-sef parameter in "
7224 "assigned function: %s",
7225 paramno, exprNode_unparse (e)),
7228 if (u2->info->var->kind == VKSEFRETPARAM) {
7231 message ("Function types are inconsistent. Parameter %d is "
7232 "normal parameter, but sef returns parameter in "
7233 "assigned function: %s",
7234 paramno, exprNode_unparse (e)),
7236 } else if (u2->info->var->kind == VKSEFPARAM) {
7239 message ("Function types are inconsistent. Parameter %d is "
7240 "normal parameter, but sef parameter in "
7241 "assigned function: %s",
7242 paramno, exprNode_unparse (e)),
7244 } else if (u2->info->var->kind == VKRETPARAM) {
7247 message ("Function types are inconsistent. Parameter %d is "
7248 "normal parameter, but returns parameter in "
7249 "assigned function: %s",
7250 paramno, exprNode_unparse (e)),
7258 if (u1->info->var->defstate != u2->info->var->defstate)
7262 message ("Function types are inconsistent. Parameter %d is "
7263 "%s, but %s in assigned function: %s",
7265 sstate_unparse (u1->info->var->defstate),
7266 sstate_unparse (u2->info->var->defstate),
7267 exprNode_unparse (e)),
7271 if (u1->info->var->nullstate != u2->info->var->nullstate)
7275 message ("Function types are inconsistent. Parameter %d is "
7276 "%s, but %s in assigned function: %s",
7278 nstate_unparse (u1->info->var->nullstate),
7279 nstate_unparse (u2->info->var->nullstate),
7280 exprNode_unparse (e)),
7284 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7288 message ("Function types are inconsistent. Parameter %d is "
7289 "%s, but %s in assigned function: %s",
7291 alkind_unparse (sRef_getAliasKind (u1->sref)),
7292 alkind_unparse (sRef_getAliasKind (u2->sref)),
7293 exprNode_unparse (e)),
7297 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7301 message ("Function types are inconsistent. Parameter %d is "
7302 "%s, but %s in assigned function: %s",
7304 exkind_unparse (sRef_getExKind (u1->sref)),
7305 exkind_unparse (sRef_getExKind (u2->sref)),
7306 exprNode_unparse (e)),
7312 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7313 /*@notnull@*/ uentry unew,
7314 bool mustConform, /*@unused@*/ bool completeConform)
7316 uentryList oldParams = uentry_getParams (old);
7317 uentryList newParams = uentry_getParams (unew);
7318 ctype newType = unew->utype;
7319 ctype oldType = old->utype;
7320 ctype oldRetType = ctype_unknown;
7321 ctype newRetType = ctype_unknown;
7323 if (uentry_isForward (old))
7325 mustConform = FALSE;
7326 uentry_copyInto (old, unew);
7331 ** check return values
7334 if (ctype_isKnown (oldType))
7336 llassert (ctype_isFunction (oldType));
7338 oldRetType = ctype_returnValue (oldType);
7341 if (ctype_isKnown (newType))
7343 llassert (ctype_isFunction (newType));
7345 newRetType = ctype_returnValue (newType);
7348 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
7349 && !ctype_matchDef (newRetType, oldRetType))
7351 if (mustConform) returnValueError (old, unew);
7355 if (ctype_isConj (newRetType))
7357 if (ctype_isConj (oldRetType))
7359 if (!ctype_sameAltTypes (newRetType, oldRetType))
7363 message ("Function %q inconsistently %rdeclared to "
7364 "return alternate types %s "
7365 "(types match, but alternates are not identical, "
7366 "so checking may not be correct)",
7367 uentry_getName (unew),
7368 uentry_isDeclared (old),
7369 ctype_unparse (newRetType)),
7370 uentry_whereDeclared (unew)))
7372 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
7378 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
7383 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7385 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
7387 if (exitkind_isKnown (unew->info->fcn->exitCode))
7391 message ("Function %q inconsistently %rdeclared using %s",
7392 uentry_getName (unew),
7393 uentry_isDeclared (old),
7394 exitkind_unparse (unew->info->fcn->exitCode)),
7395 uentry_whereDeclared (unew)))
7397 uentry_showWhereSpecified (old);
7402 unew->info->fcn->exitCode = old->info->fcn->exitCode;
7406 if (!qual_isUnknown (unew->info->fcn->nullPred))
7408 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
7412 message ("Function %q inconsistently %rdeclared using %s",
7413 uentry_getName (unew),
7414 uentry_isDeclared (old),
7415 qual_unparse (unew->info->fcn->nullPred)),
7416 uentry_whereDeclared (unew)))
7418 uentry_showWhereSpecified (old);
7424 unew->info->fcn->nullPred = old->info->fcn->nullPred;
7427 if (unew->info->fcn->specialCode != SPC_NONE)
7429 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
7433 message ("Function %q inconsistently %rdeclared using %s",
7434 uentry_getName (unew),
7435 uentry_isDeclared (old),
7436 specCode_unparse (unew->info->fcn->specialCode)),
7437 uentry_whereDeclared (unew)))
7439 uentry_showWhereSpecified (old);
7445 unew->info->fcn->specialCode = old->info->fcn->specialCode;
7452 if (!uentryList_sameObject (oldParams, newParams)
7453 && (!uentryList_isMissingParams (oldParams)))
7455 if (!uentryList_isMissingParams (newParams))
7458 int nparams = uentryList_size (oldParams);
7459 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
7461 if (nparams != uentryList_size (newParams))
7463 nargsError (old, unew);
7466 if (uentryList_size (newParams) < nparams)
7468 nparams = uentryList_size (newParams);
7471 while (paramno < nparams)
7473 uentry oldCurrent = uentryList_getN (oldParams, paramno);
7474 uentry newCurrent = uentryList_getN (newParams, paramno);
7475 ctype oldCurrentType = uentry_getType (oldCurrent);
7476 ctype newCurrentType = uentry_getType (newCurrent);
7478 llassert (uentry_isValid (oldCurrent)
7479 && uentry_isValid (newCurrent));
7481 if (!uentry_isElipsisMarker (oldCurrent)
7482 && !uentry_isElipsisMarker (newCurrent))
7484 checkVarConformance (oldCurrent, newCurrent,
7485 mustConform, completeConform);
7490 if (uentry_hasName (oldCurrent)
7491 && uentry_hasName (newCurrent))
7493 cstring oldname = uentry_getName (oldCurrent);
7494 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
7496 cstring nname = uentry_getName (newCurrent);
7499 if (cstring_isDefined (pfx)
7500 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
7502 oname = cstring_suffix (oldname, cstring_length (pfx));
7507 /*@-branchstate@*/ } /*@=branchstate@*/
7509 if (cstring_isDefined (pfx)
7510 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
7512 nnamefix = cstring_suffix (nname, cstring_length (pfx));
7517 /*@-branchstate@*/ } /*@=branchstate@*/
7519 if (!cstring_equal (oname, nnamefix))
7522 (FLG_DECLPARAMMATCH,
7523 message ("Definition parameter name %s does not match "
7524 "name of corresponding parameter in "
7527 uentry_whereLast (newCurrent)))
7529 uentry_showWhereLastPlain (oldCurrent);
7533 cstring_free (oldname);
7534 cstring_free (nname);
7538 if (!ctype_match (oldCurrentType, newCurrentType))
7540 paramTypeError (old, oldCurrent, oldCurrentType,
7541 unew, newCurrent, newCurrentType, paramno);
7545 if (ctype_isMissingParamsMarker (newCurrentType)
7546 || ctype_isElips (newCurrentType)
7547 || ctype_isMissingParamsMarker (oldCurrentType)
7548 || ctype_isElips (oldCurrentType))
7554 if (ctype_isConj (newCurrentType))
7556 if (ctype_isConj (oldCurrentType))
7558 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
7562 message ("Parameter %q inconsistently %rdeclared with "
7563 "alternate types %s "
7564 "(types match, but alternates are not identical, "
7565 "so checking may not be correct)",
7566 uentry_getName (newCurrent),
7567 uentry_isDeclared (oldCurrent),
7568 ctype_unparse (newCurrentType)),
7569 uentry_whereDeclared (unew)))
7571 uentry_showWhereLastVal (oldCurrent,
7572 ctype_unparse (oldCurrentType));
7580 message ("Parameter %q inconsistently %rdeclared with "
7581 "alternate types %s",
7582 uentry_getName (newCurrent),
7583 uentry_isDeclared (oldCurrent),
7584 ctype_unparse (newCurrentType)),
7585 uentry_whereDeclared (unew)))
7587 uentry_showWhereLastVal (oldCurrent,
7588 ctype_unparse (oldCurrentType));
7595 if (ctype_isConj (oldCurrentType))
7597 uentry_setType (newCurrent, oldCurrentType);
7605 ** Forgot this! detected by lclint:
7606 ** uentry.c:1257,15: Suspected infinite loop
7612 if (!uentryList_isMissingParams (newParams))
7614 if (ctype_isConj (oldRetType))
7616 old->utype = ctype_makeFunction (oldRetType,
7617 uentryList_copy (newParams));
7621 old->utype = unew->utype;
7625 checkGlobalsConformance (old, unew, mustConform, completeConform);
7626 checkModifiesConformance (old, unew, mustConform, completeConform);
7628 if (specialClauses_isDefined (unew->info->fcn->specclauses))
7630 if (!specialClauses_isDefined (old->info->fcn->specclauses))
7634 message ("Function %q redeclared using special clauses (can only "
7635 "be used in first declaration)",
7636 uentry_getName (unew)),
7637 uentry_whereDeclared (unew)))
7639 uentry_showWhereLast (old);
7644 specialClauses_checkEqual (old, unew);
7648 if (fileloc_isUndefined (old->whereDeclared))
7650 old->whereDeclared = fileloc_copy (unew->whereDeclared);
7652 else if (fileloc_isUndefined (unew->whereDeclared))
7654 unew->whereDeclared = fileloc_copy (old->whereDeclared);
7663 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
7667 llassert (uentry_isValid (ue));
7668 llassert (uentry_isEitherConstant (ue));
7670 uval = ue->info->uconst->val;
7672 if (multiVal_isDefined (uval))
7674 if (multiVal_isDefined (m))
7676 if (!multiVal_equiv (uval, m))
7680 message ("%s %q defined with inconsistent value: %q",
7681 ekind_capName (ue->ukind),
7682 uentry_getName (ue),
7683 multiVal_unparse (m)),
7686 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
7694 ue->info->uconst->val = m;
7695 multiVal_free (uval);
7700 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7703 bool typeError = FALSE;
7705 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
7707 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
7711 checkStructConformance (old, unew);
7716 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7718 llbug (message ("struct tags: bad types: %t / %t",
7719 old->utype, unew->utype));
7723 else if (uentry_isEnumTag (old))
7725 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
7727 if (mustConform) checkEnumConformance (old, unew);
7731 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7733 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
7734 ctype_unparse (unew->utype)));
7738 else if (!ctype_match (old->utype, unew->utype))
7740 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
7742 ctype realt = ctype_realType (unew->utype);
7744 if (ctype_isRealInt (realt) || ctype_isChar (realt))
7746 unew->utype = ctype_bool;
7752 typeError = optgenerror
7754 message ("%q defined as %s", uentry_getName (old),
7755 ctype_unparse (realt)),
7756 uentry_whereDeclared (unew));
7764 ctype oldr = ctype_realType (old->utype);
7765 ctype newr = ctype_realType (unew->utype);
7767 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
7769 checkStructConformance (old, unew);
7771 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
7773 checkStructConformance (old, unew);
7775 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
7777 checkEnumConformance (old, unew);
7779 else if (uentry_isConstant (old)
7780 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
7782 /* okay...for now! (should check the type is reset later... */
7786 DPRINTF (("YABA!"));
7789 message ("%s %q %rdeclared with inconsistent type: %t",
7790 ekind_capName (unew->ukind),
7791 uentry_getName (unew),
7792 uentry_isDeclared (old),
7794 uentry_whereDeclared (unew)))
7796 uentry_showWhereLast (old);
7812 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
7813 /*@notnull@*/ uentry unew,
7814 bool mustConform, bool completeConform)
7816 if (ctype_isDefined (unew->info->datatype->type))
7819 ** bool is hard coded here, since it is built into LCL.
7820 ** For now, we're stuck with LCL's types.
7823 if (ctype_isDirectBool (old->utype) &&
7824 cstring_equalLit (unew->uname, "bool"))
7826 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
7827 evs 2000-07-25: removed
7829 unew->utype = ctype_bool;
7832 if (ctype_isUnknown (old->info->datatype->type))
7834 old->info->datatype->type = unew->info->datatype->type;
7838 DPRINTF (("Old: %s / New: %s",
7839 uentry_unparseFull (old),
7840 uentry_unparseFull (unew)));
7841 DPRINTF (("Types: %s / %s",
7842 ctype_unparse (old->info->datatype->type),
7843 ctype_unparse (unew->info->datatype->type)));
7845 if (ctype_matchDef (old->info->datatype->type,
7846 unew->info->datatype->type))
7855 ("Type %q %s with inconsistent type: %t",
7856 uentry_getName (unew),
7857 uentry_reDefDecl (old, unew),
7858 unew->info->datatype->type),
7859 uentry_whereDeclared (unew)))
7861 uentry_showWhereLastExtra
7862 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
7865 old->info->datatype->type = unew->info->datatype->type;
7870 if (unew->info->datatype->abs != MAYBE)
7872 if (ynm_isOff (old->info->datatype->abs)
7873 && ynm_isOn (unew->info->datatype->abs))
7875 if (!ctype_isDirectBool (old->utype))
7880 ("Datatype %q inconsistently %rdeclared as abstract type",
7881 uentry_getName (unew),
7882 uentry_isDeclared (old)),
7883 uentry_whereDeclared (unew)))
7885 uentry_showWhereLastPlain (old);
7889 else if (ynm_isOn (old->info->datatype->abs)
7890 && ynm_isOff (unew->info->datatype->abs))
7892 if (!ctype_isDirectBool (old->utype))
7897 ("Datatype %q inconsistently %rdeclared as concrete type",
7898 uentry_getName (unew),
7899 uentry_isDeclared (old)),
7900 uentry_whereDeclared (unew)))
7902 uentry_showWhereLastPlain (old);
7913 if (ynm_isOn (old->info->datatype->abs))
7915 old->sref = unew->sref;
7916 unew->info->datatype->mut = old->info->datatype->mut;
7919 && uentry_isReallySpecified (old))
7924 ("Datatype %q specified as abstract, "
7925 "but abstract annotation not used in declaration",
7926 uentry_getName (unew)),
7927 uentry_whereDeclared (unew)))
7929 uentry_showWhereLastPlain (old);
7935 unew->info->datatype->abs = old->info->datatype->abs;
7937 if (ynm_isMaybe (unew->info->datatype->mut))
7939 if (completeConform && ynm_isOff (old->info->datatype->mut)
7940 && uentry_isReallySpecified (old))
7945 ("Datatype %q specified as immutable, "
7946 "but immutable annotation not used in declaration",
7947 uentry_getName (unew)),
7948 uentry_whereDeclared (unew)))
7950 uentry_showWhereLastPlain (old);
7954 unew->info->datatype->mut = old->info->datatype->mut;
7956 else if (ynm_isMaybe (old->info->datatype->mut))
7958 old->info->datatype->mut = unew->info->datatype->mut;
7962 if (ynm_isOn (old->info->datatype->abs))
7964 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
7968 message ("Datatype %q inconsistently %rdeclared as immutable",
7969 uentry_getName (unew),
7970 uentry_isDeclared (old)),
7971 uentry_whereDeclared (unew)))
7973 uentry_showWhereLastPlain (old);
7978 if (ynm_isOff (old->info->datatype->mut)
7979 && ynm_isOn (unew->info->datatype->mut))
7983 message ("Datatype %q inconsistently %rdeclared as mutable",
7984 uentry_getName (unew),
7985 uentry_isDeclared (old)),
7986 uentry_whereDeclared (unew)))
7988 uentry_showWhereLastPlain (old);
7993 old->info->datatype->mut = unew->info->datatype->mut;
7996 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8000 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8001 /*@notnull@*/ uentry unew,
8003 /*@unused@*/ bool completeConform)
8005 multiVal oldVal = old->info->uconst->val;
8006 multiVal newVal = unew->info->uconst->val;
8008 if (multiVal_isDefined (oldVal))
8010 if (multiVal_isDefined (newVal))
8012 if (!multiVal_equiv (oldVal, newVal))
8017 message ("%s %q %rdeclared with inconsistent value: %q",
8018 ekind_capName (unew->ukind),
8019 uentry_getName (unew),
8020 uentry_isDeclared (old),
8021 multiVal_unparse (newVal)),
8022 uentry_whereDeclared (unew)))
8024 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
8028 unew->info->uconst->val = multiVal_copy (oldVal);
8029 multiVal_free (newVal);
8038 old->info->uconst->val = multiVal_copy (newVal);
8043 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8044 /*@notnull@*/ uentry unew, bool mustConform,
8045 bool completeConform)
8047 bool typeError = FALSE;
8048 bool fcnConformance = FALSE;
8050 if (!ekind_equal (unew->ukind, old->ukind))
8053 ** okay, only if one is a function and the other is
8054 ** a variable of type function.
8057 if (unew->ukind == KENUMCONST
8058 && old->ukind == KCONST)
8060 old->ukind = KENUMCONST;
8064 if (unew->ukind == KFCN
8065 && old->ukind == KCONST
8066 && ctype_isUnknown (old->utype))
8069 ** When a function is defined with an unparam macro
8072 uentry_copyInto (old, unew);
8076 if (uentry_isExpandedMacro (old)
8077 && uentry_isEitherConstant (unew))
8079 uentry_copyInto (old, unew);
8083 if (uentry_isEndIter (unew))
8085 if (ctype_isUnknown (old->utype))
8087 if (!uentry_isSpecified (old)
8088 && uentry_isCodeDefined (unew))
8090 if (!fileloc_withinLines (uentry_whereDefined (old),
8091 uentry_whereDeclared (unew), 2))
8092 { /* bogus! will give errors if there is too much whitespace */
8096 ("Iterator finalized name %q does not match name in "
8097 "previous iter declaration (should be end_%q). This iter "
8098 "is declared at %q",
8099 uentry_getName (unew),
8100 uentry_getName (old),
8101 fileloc_unparse (uentry_whereDefined (old))),
8102 uentry_whereDeclared (old));
8106 uentry_copyInto (old, unew);
8111 KindConformanceError (old, unew, mustConform);
8115 if (uentry_isFunction (unew))
8117 if (uentry_isVariable (old))
8119 if (!ctype_isUnknown (old->utype))
8121 if (ctype_isFunction (old->utype))
8123 uentry_makeVarFunction (old);
8124 checkFunctionConformance (old, unew, mustConform,
8126 fcnConformance = TRUE;
8130 KindConformanceError (old, unew, mustConform);
8135 if (uentry_isExpandedMacro (old))
8137 if (fileloc_isUndefined (unew->whereDefined))
8139 unew->whereDefined = fileloc_update (unew->whereDefined,
8143 uentry_copyInto (old, unew);
8144 old->used = unew->used = TRUE;
8149 /* undeclared identifier */
8150 old->utype = unew->utype;
8151 uentry_makeVarFunction (old);
8152 checkFunctionConformance (old, unew, FALSE, FALSE);
8153 fcnConformance = TRUE;
8159 KindConformanceError (old, unew, mustConform);
8162 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8164 if (!ctype_isUnknown (unew->utype))
8166 if (ctype_isFunction (unew->utype))
8168 uentry_makeVarFunction (unew);
8169 checkFunctionConformance (old, unew, mustConform, completeConform);
8170 fcnConformance = TRUE;
8174 KindConformanceError (old, unew, mustConform);
8179 KindConformanceError (old, unew, mustConform);
8184 KindConformanceError (old, unew, mustConform);
8190 ** check parameter lists for functions
8191 ** (before type errors, to get better messages
8194 if (uentry_isFunction (old))
8196 checkFunctionConformance (old, unew, mustConform, completeConform);
8197 fcnConformance = TRUE;
8201 if (!ctype_isUndefined (old->utype))
8203 typeError = checkTypeConformance (old, unew, mustConform);
8210 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8212 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8215 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8217 DPRINTF (("Check datatype: %s / %s",
8218 uentry_unparseFull (old),
8219 uentry_unparseFull (unew)));
8221 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8224 if (uentry_isVariable (old) && uentry_isVariable (unew))
8227 !ctype_matchDef (old->utype, unew->utype))
8232 ("Variable %q %s with inconsistent type (arrays and pointers are "
8233 "not identical in variable declarations): %t",
8234 uentry_getName (unew),
8235 uentry_reDefDecl (old, unew),
8237 uentry_whereDeclared (unew)))
8239 uentry_showWhereLast (old);
8242 ** Avoid repeated errors.
8245 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8247 old->whereDefined = fileloc_update (old->whereDefined,
8255 checkVarConformance (old, unew, mustConform, completeConform);
8260 /* old->utype = unew->utype; */
8264 if (ctype_isConj (old->utype))
8266 if (ctype_isConj (unew->utype))
8268 if (!ctype_sameAltTypes (old->utype, unew->utype))
8272 message ("%s %q inconsistently %rdeclared with "
8273 "alternate types %s "
8274 "(types match, but alternates are not identical, "
8275 "so checking may not be correct)",
8276 ekind_capName (uentry_getKind (old)),
8277 uentry_getName (unew),
8278 uentry_isDeclared (old),
8279 ctype_unparse (unew->utype)),
8280 uentry_whereDeclared (unew)))
8282 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
8286 old->utype = unew->utype;
8293 if (ctype_isUnknown (old->utype))
8295 old->utype = unew->utype;
8300 if (unew->ukind == old->ukind)
8303 unew->info = uinfo_copy (old->info, old->ukind);
8306 sRef_storeState (old->sref);
8307 sRef_storeState (unew->sref);
8311 ** modifies spec to reflect def, reports any inconsistencies
8315 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
8317 llassert (uentry_isValid (spec));
8318 llassert (uentry_isValid (def));
8319 llassert (cstring_equal (spec->uname, def->uname));
8321 uentry_checkConformance (spec, def, TRUE,
8322 context_getFlag (FLG_NEEDSPEC));
8324 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
8327 ** okay, declarations conform. Propagate extra information.
8330 uentry_setDefined (spec, uentry_whereDefined (def));
8331 uentry_setDeclared (spec, uentry_whereDeclared (def));
8333 if (uentry_isStatic (def))
8337 message ("%s %q specified, but declared as static",
8338 ekind_capName (def->ukind),
8339 uentry_getName (def)),
8340 uentry_whereDeclared (def)))
8342 uentry_showWhereSpecified (spec);
8347 spec->storageclass = def->storageclass;
8350 sRef_storeState (spec->sref);
8352 spec->used = def->used || spec->used;
8353 spec->hasNameError |= def->hasNameError;
8357 if (!spec->hasNameError)
8359 uentry_checkName (spec);
8368 ** Can't generate function redeclaration errors when the
8369 ** entries are merged, since we don't yet know if its the
8370 ** definition of the function.
8374 uentry_clearDecl (void)
8376 posRedeclared = uentry_undefined;
8377 fileloc_free (posLoc);
8378 posLoc = fileloc_undefined;
8382 uentry_checkDecl (void)
8384 if (uentry_isValid (posRedeclared))
8386 llassert (fileloc_isDefined (posLoc));
8388 if (uentry_isCodeDefined (posRedeclared))
8390 if (optgenerror (FLG_REDECL,
8391 message ("%s %q declared after definition",
8392 ekind_capName (posRedeclared->ukind),
8393 uentry_getName (posRedeclared)),
8396 llgenindentmsg (message ("Definition of %q",
8397 uentry_getName (posRedeclared)),
8398 posRedeclared->whereDeclared);
8403 if (optgenerror (FLG_REDECL,
8404 message ("%s %q declared more than once",
8405 ekind_capName (posRedeclared->ukind),
8406 uentry_getName (posRedeclared)),
8409 llgenindentmsg (message ("Previous declaration of %q",
8410 uentry_getName (posRedeclared)),
8411 posRedeclared->whereDeclared);
8416 fileloc_free (posLoc);
8417 posLoc = fileloc_undefined;
8418 posRedeclared = uentry_undefined;
8422 ** Redefinition of old as unew.
8423 ** modifies old to reflect unew, reports any inconsistencies
8427 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
8429 fileloc olddef = uentry_whereDeclared (old);
8430 fileloc unewdef = uentry_whereDeclared (unew);
8434 if (uentry_isExtern (unew))
8436 uentry_setUsed (old, unewdef);
8440 fileloc_isUndefined (olddef)
8441 && fileloc_isDefined (uentry_whereDefined (old))
8442 && !uentry_isExpandedMacro (old);
8444 if (!context_getFlag (FLG_INCONDEFSLIB)
8445 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8447 mustConform = FALSE;
8454 llassert (uentry_isValid (old));
8455 llassert (uentry_isValid (unew));
8456 llassert (cstring_equal (old->uname, unew->uname));
8459 ** should check old one was extern!
8462 if (uentry_isStatic (old))
8464 if (!(uentry_isStatic (unew)))
8468 message ("%s %q shadows static declaration",
8469 ekind_capName (unew->ukind),
8470 uentry_getName (unew)),
8473 uentry_showWhereLast (old);
8478 uentry_setDeclDef (old, unewdef);
8481 else if (uentry_isStatic (unew))
8483 uentry_setDeclDef (old, unewdef);
8485 else if (uentry_isExtern (old))
8487 uentry_setDeclared (old, unewdef);
8491 if (!uentry_isExtern (unew) && !uentry_isForward (old)
8492 && !fileloc_equal (olddef, unewdef)
8493 && !fileloc_isUndefined (olddef)
8494 && !fileloc_isUndefined (unewdef)
8495 && !fileloc_isBuiltin (olddef)
8496 && !fileloc_isBuiltin (unewdef)
8497 && !uentry_isYield (old)
8498 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8500 if (uentry_isVariable (old) || uentry_isVariable (unew))
8502 ; /* will report redeclaration error later */
8506 if (fileloc_isDefined (uentry_whereDefined (old)))
8510 message ("%s %q defined more than once",
8511 ekind_capName (unew->ukind),
8512 uentry_getName (unew)),
8513 uentry_whereLast (unew)))
8516 (message ("Previous definition of %q",
8517 uentry_getName (old)),
8518 uentry_whereLast (old));
8521 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
8523 uentry_copyInto (old, unew);
8524 old->sref = sRef_saveCopy (old->sref);
8532 if (fileloc_isLib (olddef)
8533 || fileloc_isUndefined (olddef)
8534 || fileloc_isImport (olddef))
8536 if (uentry_isExtern (unew))
8538 if (uentry_isExtern (old)
8539 || (fileloc_isDefined (uentry_whereDeclared (old))
8540 && (!fileloc_equal (uentry_whereDeclared (old),
8541 uentry_whereDefined (old)))))
8545 message ("%s %q declared more than once",
8546 ekind_capName (unew->ukind),
8547 uentry_getName (unew)),
8548 unew->whereDeclared))
8551 (message ("Previous declaration of %q",
8552 uentry_getName (old)),
8553 old->whereDeclared);
8557 uentry_setExtern (old);
8561 uentry_setDefined (old, unewdef);
8567 uentry_checkConformance (old, unew, mustConform, FALSE);
8569 old->used = old->used || unew->used;
8570 old->uses = filelocList_append (old->uses, unew->uses);
8571 unew->uses = filelocList_undefined;
8573 sRef_storeState (old->sref);
8574 sRef_storeState (unew->sref);
8578 old->whereDefined = fileloc_update (old->whereDefined,
8583 ** No redeclaration errors for functions here, since we
8584 ** don't know if this is the definition of the function.
8587 if (fileloc_isUser (old->whereDeclared)
8588 && fileloc_isUser (unew->whereDeclared)
8589 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
8590 && !fileloc_isDefined (unew->whereDefined))
8592 if (uentry_isFunction (old))
8594 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
8595 posLoc = fileloc_update (posLoc, unew->whereDeclared);
8599 if (optgenerror (FLG_REDECL,
8600 message ("%s %q declared more than once",
8601 ekind_capName (unew->ukind),
8602 uentry_getName (unew)),
8603 unew->whereDeclared))
8605 llgenindentmsg (message ("Previous declaration of %q",
8606 uentry_getName (old)),
8607 old->whereDeclared);
8612 if (fileloc_isUndefined (old->whereDefined))
8614 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
8618 if (!context_processingMacros ()
8619 && fileloc_isUser (old->whereDefined)
8620 && fileloc_isUser (unew->whereDefined)
8621 && !fileloc_equal (old->whereDefined, unew->whereDefined))
8623 if (uentry_isVariable (unew) || uentry_isFunction (unew))
8625 if (uentry_isVariable (unew)
8626 && uentry_isExtern (unew))
8628 if (optgenerror (FLG_REDECL,
8629 message ("%s %q declared after definition",
8630 ekind_capName (unew->ukind),
8631 uentry_getName (unew)),
8632 unew->whereDeclared))
8634 llgenindentmsg (message ("Definition of %q",
8635 uentry_getName (old)),
8641 if (optgenerror (FLG_REDEF,
8642 message ("%s %q redefined",
8643 ekind_capName (unew->ukind),
8644 uentry_getName (unew)),
8645 unew->whereDefined))
8647 llgenindentmsg (message ("Previous definition of %q",
8648 uentry_getName (old)),
8656 if (uentry_isExternal (unew))
8658 old->whereDefined = fileloc_createExternal ();
8661 if (unew->hasNameError)
8663 old->hasNameError = TRUE;
8668 if (!old->hasNameError)
8670 uentry_checkName (old);
8673 llassert (!ctype_isUndefined (old->utype));
8677 uentry_copyState (uentry res, uentry other)
8679 llassert (uentry_isValid (res));
8680 llassert (uentry_isValid (other));
8682 res->used = other->used;
8684 res->info->var->kind = other->info->var->kind;
8685 res->info->var->defstate = other->info->var->defstate;
8686 res->info->var->nullstate = other->info->var->nullstate;
8687 res->info->var->checked = other->info->var->checked;
8689 sRef_copyState (res->sref, other->sref);
8693 uentry_sameKind (uentry u1, uentry u2)
8695 if (uentry_isValid (u1) && uentry_isValid (u2))
8697 if (uentry_isVar (u1) && uentry_isVar (u2))
8699 ctype c1 = u1->utype;
8700 ctype c2 = u2->utype;
8702 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
8705 ** both functions, or both not functions
8708 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
8712 return ((u1->ukind == u2->ukind));
8719 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
8721 llassert (uentry_isValid (unew));
8722 llassert (uentry_isValid (old));
8724 unew->ukind = old->ukind;
8725 unew->uname = cstring_copy (old->uname);
8726 unew->utype = old->utype;
8728 unew->whereSpecified = fileloc_copy (old->whereSpecified);
8729 unew->whereDefined = fileloc_copy (old->whereDefined);
8730 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8732 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
8733 unew->used = old->used;
8735 unew->isPrivate = old->isPrivate;
8736 unew->hasNameError = old->hasNameError;
8737 unew->uses = filelocList_undefined;
8739 unew->storageclass = old->storageclass;
8740 unew->info = uinfo_copy (old->info, old->ukind);
8745 uentry_copy (uentry e)
8747 if (uentry_isValid (e))
8749 uentry enew = uentry_alloc ();
8750 DPRINTF (("copy: %s", uentry_unparseFull (e)));
8751 uentry_copyInto (enew, e);
8752 DPRINTF (("Here we are..."));
8753 DPRINTF (("original: %s", uentry_unparseFull (e)));
8754 DPRINTF (("copy: %s", uentry_unparse (enew)));
8755 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
8760 return uentry_undefined;
8765 uentry_setState (uentry res, uentry other)
8767 llassert (uentry_isValid (res));
8768 llassert (uentry_isValid (other));
8770 llassert (res->ukind == other->ukind);
8771 llassert (res->ukind == KVAR);
8773 res->sref = sRef_saveCopy (other->sref);
8774 res->used = other->used;
8775 filelocList_free (res->uses);
8776 res->uses = other->uses;
8777 other->uses = filelocList_undefined;
8778 res->lset = other->lset;
8782 uentry_mergeUses (uentry res, uentry other)
8784 llassert (uentry_isValid (res));
8785 llassert (uentry_isValid (other));
8787 res->used = other->used || res->used;
8788 res->lset = other->lset || res->lset;
8789 res->uses = filelocList_append (res->uses, other->uses);
8790 other->uses = filelocList_undefined;
8795 ** This is a really ugly routine.
8797 ** gack...fix this one day.
8802 ** >> res is the false branch, other is the true branch (or continuation)
8804 ** >> res is the true branch, other is the false branch (or continutation)
8811 ** References not effected by res are propagated from other.
8815 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
8816 bool flip, clause cl, fileloc loc)
8820 message ("%s %q is %s %s, but %s %s.",
8821 ekind_capName (res->ukind), uentry_getName (res),
8822 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
8823 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
8826 if (sRef_isDead (res->sref))
8828 sRef_showStateInfo (res->sref);
8830 else if (sRef_isKept (res->sref))
8832 sRef_showAliasInfo (res->sref);
8834 else /* dependent */
8836 sRef_showAliasInfo (res->sref);
8837 sRef_showAliasInfo (other->sref);
8840 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8844 static bool incompatibleStates (sRef rs, sRef os)
8846 alkind rk = sRef_getAliasKind (rs);
8847 alkind ok = sRef_getAliasKind (os);
8849 if (alkind_isError (rk) || alkind_isError (ok))
8855 return ((sRef_isDead (rs)
8856 || (alkind_isKept (rk) && !alkind_isKept (ok))
8857 || (alkind_isDependent (rk)
8858 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
8859 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
8864 branchStateAltError (/*@notnull@*/ uentry res,
8865 /*@notnull@*/ uentry other, bool flip,
8866 clause cl, fileloc loc)
8870 message ("%s %q is %s %s, but %s %s.",
8871 ekind_capName (res->ukind), uentry_getName (res),
8872 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
8873 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
8876 if (sRef_isDead (other->sref))
8878 sRef_showStateInfo (other->sref);
8882 sRef_showAliasInfo (other->sref);
8885 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8886 sRef_setDefinedComplete (res->sref, fileloc_undefined);
8888 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
8889 sRef_setDefinedComplete (other->sref, fileloc_undefined);
8893 static bool notNull (sRef sr, bool flip)
8895 return (!sRef_definitelyNull (sr)
8896 && !(sRef_isKept (sr))
8897 && !(sRef_isDependent (sr))
8898 && !(flip ? usymtab_isProbableDeepNull (sr)
8899 : usymtab_isAltProbablyDeepNull (sr)));
8903 uentry_mergeState (uentry res, uentry other, fileloc loc,
8904 bool mustReturn, bool flip, bool opt,
8907 llassert (uentry_isValid (res));
8908 llassert (uentry_isValid (other));
8910 llassert (res->ukind == other->ukind);
8911 llassert (res->ukind == KVAR);
8913 DPRINTF (("Merge state: %s / %s",
8914 uentry_unparse (res),
8915 uentry_unparse (other)));
8917 if (sRef_isValid (res->sref))
8921 if (incompatibleStates (res->sref, other->sref))
8923 if (sRef_isThroughArrayFetch (res->sref)
8924 && !context_getFlag (FLG_STRICTBRANCHSTATE))
8926 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
8928 sRef_maybeKill (res->sref, loc);
8930 else if (sRef_isPossiblyDead (other->sref))
8932 sRef_maybeKill (res->sref, loc);
8941 if (notNull (other->sref, flip))
8943 if (sRef_isLocalParamVar (res->sref)
8944 && (sRef_isLocalState (other->sref)
8945 || sRef_isDependent (other->sref)))
8947 if (sRef_isDependent (res->sref))
8949 sRef_setDependent (other->sref, loc);
8953 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8958 branchStateError (res, other, flip, cl, loc);
8963 if (sRef_isKept (res->sref))
8965 sRef_setKept (other->sref, loc);
8970 if (incompatibleStates (other->sref, res->sref))
8972 if (notNull (res->sref, !flip))
8974 if (sRef_isLocalParamVar (res->sref)
8975 && (sRef_isDependent (res->sref)
8976 || sRef_isLocalState (res->sref)))
8978 if (sRef_isDependent (other->sref))
8980 sRef_setDependent (res->sref, loc);
8984 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8989 if (sRef_isParam (other->sref))
8992 ** If the local variable associated
8993 ** with the param has the correct state,
8995 ** (e.g., free (s); s = new(); ...
8998 uentry uvar = usymtab_lookupSafe (other->uname);
9000 if (uentry_isValid (uvar)
9001 && ((sRef_isDead (other->sref)
9002 && sRef_isOnly (uvar->sref))
9003 || (sRef_isDependent (other->sref)
9004 && sRef_isOwned (uvar->sref))))
9010 branchStateAltError (res, other,
9016 branchStateAltError (res, other,
9023 if (sRef_isKept (other->sref))
9025 sRef_setKept (res->sref, loc);
9031 DPRINTF (("Merge opt..."));
9032 sRef_mergeOptState (res->sref, other->sref, cl, loc);
9033 DPRINTF (("Done!"));
9037 sRef_mergeState (res->sref, other->sref, cl, loc);
9042 if (sRef_isModified (other->sref))
9044 sRef_setModified (res->sref);
9048 if (cl == DOWHILECLAUSE)
9050 res->used = other->used || res->used;
9051 res->lset = other->lset || res->lset;
9052 res->uses = filelocList_append (res->uses, other->uses);
9053 other->uses = filelocList_undefined;
9057 if (sRef_isMacroParamRef (res->sref)
9058 && !uentry_isSefParam (other)
9059 && !uentry_isSefParam (res))
9061 bool hasError = FALSE;
9063 if (bool_equal (res->used, other->used))
9065 res->used = other->used;
9069 if (other->used && !flip)
9074 message ("Macro parameter %q used in true clause, "
9075 "but not in false clause",
9076 uentry_getName (res)),
9077 uentry_whereDeclared (res));
9084 message ("Macro parameter %q used in false clause, "
9085 "but not in true clause",
9086 uentry_getName (res)),
9087 uentry_whereDeclared (res));
9093 /* make it sef now, prevent more errors */
9094 res->info->var->kind = VKREFSEFPARAM;
9100 res->used = other->used || res->used;
9101 res->lset = other->lset || res->lset;
9102 res->uses = filelocList_append (res->uses, other->uses);
9103 other->uses = filelocList_undefined;
9109 void uentry_setUsed (uentry e, fileloc loc)
9111 static bool firstTime = TRUE;
9112 static bool showUses = FALSE;
9113 static bool exportLocal = FALSE;
9117 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
9119 showUses = context_getFlag (FLG_SHOWUSES);
9120 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
9125 if (uentry_isValid (e))
9129 if (sRef_isMacroParamRef (e->sref))
9131 if (uentry_isYield (e) || uentry_isSefParam (e))
9137 if (context_inConditional ())
9141 message ("Macro parameter %q used in conditionally "
9142 "executed code (may or may not be "
9143 "evaluated exactly once)",
9144 uentry_getName (e)),
9147 e->info->var->kind = VKREFSEFPARAM;
9156 message ("Macro parameter %q used more than once",
9157 uentry_getName (e)),
9158 uentry_whereDeclared (e)))
9160 e->info->var->kind = VKREFSEFPARAM;
9167 if ((dp = uentry_directParamNo (e)) >= 0)
9169 uentry_setUsed (usymtab_getParam (dp), loc);
9174 if (!sRef_isLocalVar (e->sref))
9178 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
9184 if (context_inMacro ())
9186 e->uses = filelocList_addUndefined (e->uses);
9190 e->uses = filelocList_addDifferentFile
9192 uentry_whereDeclared (e),
9201 bool uentry_isReturned (uentry u)
9203 return (uentry_isValid (u) && uentry_isVar (u)
9204 && (u->info->var->kind == VKRETPARAM
9205 || u->info->var->kind == VKSEFRETPARAM));
9208 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
9210 llassert (uentry_isRealFunction (u));
9212 if (ctype_isFunction (u->utype)
9213 && sRef_isStateSpecial (uentry_getSref (u)))
9215 specialClauses clauses = uentry_getSpecialClauses (u);
9216 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9218 sRef_setAllocated (res, g_currentloc);
9220 specialClauses_postElements (clauses, cl)
9222 sRefSet refs = specialClause_getRefs (cl);
9223 sRefMod modf = specialClause_getEffectFunction (cl);
9225 sRefSet_elements (refs, el)
9227 sRef base = sRef_getRootBase (el);
9229 if (sRef_isResult (base))
9233 sRef sr = sRef_fixBase (el, res);
9234 modf (sr, g_currentloc);
9241 } end_sRefSet_elements ;
9243 } end_specialClauses_postElements ;
9251 sRefSet prefs = sRefSet_new ();
9252 sRef res = sRef_undefined;
9255 params = uentry_getParams (u);
9257 uentryList_elements (params, current)
9259 if (uentry_isReturned (current))
9261 if (exprNodeList_size (args) >= paramno)
9263 exprNode ecur = exprNodeList_nth (args, paramno);
9264 sRef tref = exprNode_getSref (ecur);
9266 if (sRef_isValid (tref))
9268 sRef tcref = sRef_copy (tref);
9270 if (sRef_isDead (tcref))
9272 sRef_setDefined (tcref, g_currentloc);
9273 sRef_setOnly (tcref, g_currentloc);
9276 if (sRef_isRefCounted (tcref))
9278 /* could be a new ref now (but only if its returned) */
9279 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
9282 sRef_makeSafe (tcref);
9284 prefs = sRefSet_insert (prefs, tcref);
9290 } end_uentryList_elements ;
9292 if (sRefSet_size (prefs) > 0)
9294 nstate n = sRef_getNullState (u->sref);
9296 if (sRefSet_size (prefs) == 1)
9298 res = sRefSet_choose (prefs);
9302 res = sRefSet_mergeIntoOne (prefs);
9305 if (nstate_isKnown (n))
9307 sRef_setNullState (res, n, g_currentloc);
9312 if (ctype_isFunction (u->utype))
9314 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9318 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
9321 if (sRef_isRefCounted (res))
9323 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9327 if (sRef_getNullState (res) == NS_ABSNULL)
9329 ctype ct = ctype_realType (u->utype);
9331 if (ctype_isAbstract (ct))
9333 sRef_setNotNull (res, g_currentloc);
9337 if (ctype_isUser (ct))
9339 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
9343 sRef_setNotNull (res, g_currentloc);
9348 if (sRef_isRefCounted (res))
9350 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9352 else if (sRef_isKillRef (res))
9354 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
9361 ak = sRef_getAliasKind (res);
9363 if (alkind_isImplicit (ak))
9365 sRef_setAliasKind (res,
9366 alkind_fixImplicit (ak),
9370 sRefSet_free (prefs);
9376 static bool uentry_isRefCounted (uentry ue)
9378 ctype ct = uentry_getType (ue);
9380 if (ctype_isFunction (ct))
9382 return (ctype_isRefCounted (ctype_returnValue (ct)));
9386 return (ctype_isRefCounted (ct));
9391 ** old was declared yield in the specification.
9392 ** new is declared in the iter implementation.
9395 void uentry_checkYieldParam (uentry old, uentry unew)
9399 llassert (uentry_isVariable (old));
9400 llassert (uentry_isVariable (unew));
9402 unew->info->var->kind = VKYIELDPARAM;
9403 (void) checkTypeConformance (old, unew, TRUE);
9404 checkVarConformance (old, unew, TRUE, FALSE);
9406 /* get rid of param marker */
9408 name = uentry_getName (unew);
9409 cstring_free (unew->uname);
9411 unew->info->var->kind = VKREFYIELDPARAM;
9413 uentry_setUsed (old, fileloc_undefined);
9414 uentry_setUsed (unew, fileloc_undefined);
9417 /*@observer@*/ cstring
9418 uentry_ekindName (uentry ue)
9420 if (uentry_isValid (ue))
9425 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
9427 return cstring_makeLiteralTemp ("Datatype");
9429 return cstring_makeLiteralTemp ("Enum member");
9431 return cstring_makeLiteralTemp ("Constant");
9433 if (uentry_isParam (ue))
9435 return cstring_makeLiteralTemp ("Parameter");
9437 else if (uentry_isExpandedMacro (ue))
9439 return cstring_makeLiteralTemp ("Expanded macro");
9443 return cstring_makeLiteralTemp ("Variable");
9446 return cstring_makeLiteralTemp ("Function");
9448 return cstring_makeLiteralTemp ("Iterator");
9450 return cstring_makeLiteralTemp ("Iterator finalizer");
9452 return cstring_makeLiteralTemp ("Struct tag");
9454 return cstring_makeLiteralTemp ("Union tag");
9456 return cstring_makeLiteralTemp ("Enum tag");
9458 return cstring_makeLiteralTemp ("Optional parameters");
9463 return cstring_makeLiteralTemp ("<Undefined>");
9469 void uentry_setHasNameError (uentry ue)
9471 llassert (uentry_isValid (ue));
9473 ue->hasNameError = TRUE;
9476 void uentry_checkName (uentry ue)
9478 if (uentry_isValid (ue)
9479 && !uentry_isElipsisMarker (ue)
9480 && context_getFlag (FLG_NAMECHECKS)
9481 && !ue->hasNameError
9482 && !uentry_isEndIter (ue)
9483 && !fileloc_isBuiltin (uentry_whereLast (ue))
9484 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
9487 if (uentry_isPriv (ue))
9489 ; /* any checks here? */
9491 else if (fileloc_isExternal (uentry_whereDefined (ue)))
9493 ; /* no errors for externals */
9499 if (uentry_isExpandedMacro (ue))
9505 if (uentry_isExpandedMacro (ue))
9509 else if (uentry_isVariable (ue))
9511 sRef sr = uentry_getSref (ue);
9513 if (sRef_isValid (sr))
9515 scope = sRef_getScope (sr);
9522 else if (uentry_isFunction (ue)
9523 || uentry_isIter (ue)
9524 || uentry_isEndIter (ue)
9525 || uentry_isConstant (ue))
9527 scope = uentry_isStatic (ue) ? fileScope : globScope;
9529 else /* datatypes, etc. must be global */
9534 usymtab_checkDistinctName (ue, scope);
9537 if (context_getFlag (FLG_CPPNAMES))
9539 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
9541 uentry_setHasNameError (ue);
9545 if (scope == globScope)
9547 checkGlobalName (ue);
9549 if (context_getFlag (FLG_ANSIRESERVED))
9551 if (uentry_hasName (ue)
9552 && !uentry_isAnyTag (ue))
9554 if (checkAnsiName (uentry_rawName (ue),
9555 uentry_whereLast (ue)))
9557 uentry_setHasNameError (ue);
9564 checkLocalName (ue);
9566 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
9568 if (uentry_hasName (ue)
9569 && !uentry_isAnyTag (ue))
9571 if (checkAnsiName (uentry_rawName (ue),
9572 uentry_whereLast (ue)))
9574 uentry_setHasNameError (ue);
9580 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
9586 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
9592 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
9593 if (!context_inMacro ())
9595 sRef_setGlobalScopeSafe ();
9598 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
9599 uentry_setUsed (ue, loc);
9601 tloc = fileloc_createExternal ();
9602 uentry_setDefined (ue, tloc);
9603 fileloc_free (tloc);
9604 uentry_setHasNameError (ue);
9606 if (context_getFlag (FLG_REPEATUNRECOG))
9608 uentry_markOwned (ue);
9612 ue = usymtab_supReturnFileEntry (ue);
9615 if (!context_inMacro ())
9617 sRef_clearGlobalScopeSafe ();
9623 /* new start modifications */
9625 void uentry_testInRange (uentry p_e, uentry cconstant) {
9626 if( uentry_isValid(p_e) ) {
9627 if( sRef_isValid (p_e->sref) ) {
9628 char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
9629 int index = atoi( t );
9631 usymtab_testInRange (p_e->sref, index);
9636 void uentry_setStringLength (uentry p_e, uentry cconstant) {
9637 if( uentry_isValid(p_e) ) {
9638 if( p_e->info != NULL) {
9639 if( p_e->info->var != NULL) {
9640 char *t = cstring_toCharsSafe (uentry_unparse(cconstant));
9641 int length = atoi( t );
9643 p_e->info->var->bufinfo->len = length;
9644 p_e->sref->bufinfo.len = length;
9645 printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size);
9652 void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
9653 if( uentry_isValid(p_e) ) {
9654 if( p_e->info != NULL) {
9655 if( p_e->info->var != NULL) {
9656 int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
9657 p_e->info->var->bufinfo->size = size;
9658 p_e->sref->bufinfo.size = size;
9659 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
9660 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
9661 // fprintf(stderr, "and %d\n", size );
9669 /* start modifications */
9671 requires: p_e is defined, is a ptr/array variable
9673 effects: sets the state of the variable
9676 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
9677 if( uentry_isValid(p_e) ) {
9678 if( p_e->info != NULL) {
9679 if( p_e->info->var != NULL) {
9680 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
9681 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9687 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
9691 requires: p_e is defined, is a ptr/array variable
9693 effects: sets the size of the buffer
9696 void uentry_setNullTerminatedState (uentry p_e) {
9697 if( uentry_isValid(p_e) ) {
9698 if( p_e->info != NULL) {
9699 if( p_e->info->var != NULL) {
9700 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
9701 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
9707 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
9712 requires: p_e is defined, is a ptr/array variable
9714 effects: sets the state of the variable
9717 void uentry_setNotNullTerminatedState (uentry p_e) {
9718 if( uentry_isValid(p_e) ) {
9719 if( p_e->info != NULL) {
9720 if( p_e->info->var != NULL) {
9721 p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
9722 p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED;
9728 fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n");
9733 requires: p_e is defined, is a ptr/array variable
9735 effects: sets the size of the buffer
9738 void uentry_setSize (uentry p_e, int size) {
9739 if( uentry_isValid(p_e) ) {
9740 if( p_e->info != NULL) {
9741 if( p_e->info->var != NULL) {
9742 p_e->info->var->bufinfo->size = size;
9743 p_e->sref->bufinfo.size = size;
9749 fprintf(stderr, "uentry:Error in setSize\n");
9754 requires: p_e is defined, is a ptr/array variable
9756 effects: sets the length of the buffer
9759 void uentry_setLen (uentry p_e, int len) {
9760 if( uentry_isValid(p_e) ) {
9761 if( p_e->info != NULL) {
9762 if( p_e->info->var != NULL) {
9763 p_e->info->var->bufinfo->len = len;
9764 p_e->sref->bufinfo.len = len;
9770 fprintf(stderr, "uentry:Error in setLen\n");