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 return constraintList_undefined;
581 return ue->info->fcn->preconditions;
586 return constraintList_undefined;
592 static /*@only@*/ fileloc setLocation (void)
594 fileloc fl = context_getSaveLocation ();
596 if (fileloc_isDefined (fl))
602 return fileloc_copy (g_currentloc);
606 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
608 fileloc loc = setLocation ();
609 uentry ue = uentry_makeConstant (n, t, loc);
611 ue->ukind = KENUMCONST;
612 uentry_setDefined (ue, loc);
616 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
618 fileloc loc = setLocation ();
619 uentry ue = uentry_makeConstant (n, t, loc);
620 ctype etype = exprNode_getType (expr);
622 if (!ctype_isRealInt (etype)) {
626 ("Value of enum member is not an integeral type (type %s): %s",
627 ctype_unparse (etype), exprNode_unparse (expr)),
628 exprNode_loc (expr));
631 ue->ukind = KENUMCONST;
632 uentry_setDefined (ue, loc);
637 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
639 uentry ue = uentry_makeConstant (n, t, loc);
641 ue->ukind = KENUMCONST;
646 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
648 return uentry_makeVariable (n, t, setLocation (), FALSE);
652 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
654 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
658 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
660 ctype ct = idDecl_getCtype (id);
661 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
662 MAYBE, MAYBE, setLocation ());
664 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
666 if (!ynm_isOn (ue->info->datatype->abs))
668 if (ctype_isUnknown (ct))
670 ue->info->datatype->mut = MAYBE;
674 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
681 void uentry_checkParams (uentry ue)
683 if (uentry_isValid (ue))
685 bool isExt = uentry_isExtern (ue);
687 if (uentry_isRealFunction (ue))
689 uentryList params = uentry_getParams (ue);
691 uentryList_elements (params, current)
693 if (uentry_isValid (current))
695 ctype ct = current->utype;
697 if (ctype_isFixedArray (ct))
699 if (ctype_isArray (ctype_baseArrayPtr (ct))
700 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
707 (FLG_FIXEDFORMALARRAY,
708 message ("Function parameter %q declared as "
709 "manifest array (size constant is meaningless)",
710 uentry_getName (current)),
711 uentry_whereDeclared (current));
716 if (ctype_isArray (ct))
720 message ("Function parameter %q declared as "
721 "array (treated as pointer)",
722 uentry_getName (current)),
723 uentry_whereDeclared (current));
727 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
729 if (ctype_isAbstract (ct) &&
730 (isExt || (ctype_isAbstract (ctype_realType (ct))
731 && !context_hasFileAccess (ctype_typeId (ct)))))
736 ("Function %q declared with notnull parameter %q of abstract "
739 uentry_getName (current),
742 ("Since %s is an abstract type, notnull can only be "
743 "used for parameters if the function is static to a "
744 "module where %s is accessible.",
747 uentry_whereDeclared (current));
751 } end_uentryList_elements;
753 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
755 ctype ct = ue->utype;
757 if (ctype_isAbstract (ct)
758 && (isExt || (ctype_isAbstract (ctype_realType (ct))
759 && !context_hasFileAccess (ctype_typeId (ct)))))
764 ("%s %q declared %s notnull storage of abstract type %s",
765 ekind_capName (uentry_getKind (ue)),
770 ("Since %s is an abstract type, notnull can only be used "
771 "if it is static to a module where %s is accessible.",
774 uentry_whereDeclared (ue));
781 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
783 alkind ak = sRef_getAliasKind (ue->sref);
785 if (alkind_isRefCounted (ak))
787 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
791 if (alkind_isUnknown (ak))
793 exkind ek = sRef_getExKind (ue->sref);
795 if (exkind_isKnown (ek))
797 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
801 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
803 if (ctype_isVisiblySharable
804 (ctype_realType (ctype_returnValue (ue->utype))))
806 if (uentryList_hasReturned (uentry_getParams (ue)))
812 sRef_setAliasKind (ue->sref, AK_IMPONLY,
822 static /*@notnull@*/ uentry
823 uentry_makeFunctionAux (cstring n, ctype t,
825 /*@only@*/ globSet globs,
826 /*@only@*/ sRefSet mods,
827 /*@keep@*/ fileloc f, bool priv,
828 /*@unused@*/ bool isForward)
830 uentry e = uentry_alloc ();
833 if (ctype_isFunction (t))
835 ret = ctype_returnValue (t);
839 if (ctype_isKnown (t))
841 llbug (message ("not function: %s", ctype_unparse (t)));
848 if (fileloc_isSpec (f) || fileloc_isImport (f))
850 e->whereSpecified = f;
851 e->whereDeclared = fileloc_undefined;
855 e->whereSpecified = fileloc_undefined;
856 e->whereDeclared = f;
859 /* e->shallowCopy = FALSE; */
860 e->uname = cstring_copy (n);
862 e->storageclass = SCNONE;
864 e->sref = sRef_makeType (ret);
866 if (ctype_isUA (ret))
868 sRef_setStateFromType (e->sref, ret);
873 e->uses = filelocList_new ();
875 e->hasNameError = FALSE;
877 e->info = (uinfo) dmalloc (sizeof (*e->info));
878 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
880 e->info->fcn->hasMods = sRefSet_isDefined (mods);
881 e->info->fcn->hasGlobs = globSet_isDefined (globs);
883 e->info->fcn->exitCode = XK_UNKNOWN;
884 e->info->fcn->nullPred = QU_UNKNOWN;
885 e->info->fcn->specialCode = SPC_NONE;
887 e->info->fcn->access = access;
888 e->info->fcn->globs = globs;
889 e->info->fcn->defparams = uentryList_undefined;
891 sRef_setDefined (e->sref, f);
892 e->whereDefined = fileloc_undefined;
894 e->info->fcn->mods = sRefSet_undefined;
895 e->info->fcn->specclauses = NULL;
896 checkGlobalsModifies (e, mods);
897 e->info->fcn->mods = mods;
902 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
905 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
906 typeId_invalid, globSet_undefined,
910 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
911 reflectImplicitFunctionQualifiers (ue, FALSE);
913 if (!uentry_isStatic (ue)
914 && cstring_equalLit (ue->uname, "main"))
916 ctype typ = ue->utype;
920 llassert (ctype_isFunction (typ));
922 retval = ctype_returnValue (typ);
924 if (!ctype_isInt (retval))
928 message ("Function main declared to return %s, should return int",
929 ctype_unparse (retval)),
930 uentry_whereDeclared (ue));
933 args = ctype_argsFunction (typ);
935 if (uentryList_isMissingParams (args)
936 || uentryList_size (args) == 0)
942 if (uentryList_size (args) != 2)
946 message ("Function main declared with %d arg%p, "
947 "should have 2 (int argc, char *argv[])",
948 uentryList_size (args)),
949 uentry_whereLast (ue));
953 uentry arg = uentryList_getN (args, 0);
954 ctype ct = uentry_getType (arg);
956 if (!ctype_isInt (ct))
960 message ("Parameter 1, %q, of function main declared "
961 "with type %t, should have type int",
962 uentry_getName (arg), ct),
963 uentry_whereDeclared (arg));
966 arg = uentryList_getN (args, 1);
967 ct = uentry_getType (arg);
969 if (ctype_isArrayPtr (ct)
970 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
971 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
979 message ("Parameter 2, %q, of function main declared "
980 "with type %t, should have type char **",
981 uentry_getName (arg), ct),
982 uentry_whereDeclared (arg));
991 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
993 alkind ak = sRef_getAliasKind (e->sref);
995 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
996 && context_getFlag (FLG_PARAMIMPTEMP))
998 exkind ek = sRef_getExKind (e->sref);
1000 if (exkind_isKnown (ek))
1002 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1003 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1007 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1008 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1013 static /*@only@*/ /*@notnull@*/ uentry
1014 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
1016 cstring pname = makeParam (n);
1017 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
1019 cstring_free (pname);
1020 uentry_implicitParamAnnots (e);
1022 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1024 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1025 e->info->var->defstate = defstate;
1033 uentry_setRefCounted (uentry e)
1035 if (uentry_isValid (e))
1037 uentry_setAliasKind (e, AK_REFCOUNTED);
1038 sRef_storeState (e->sref);
1044 uentry_setStatic (uentry c)
1046 if (uentry_isValid (c))
1048 alkind ak = sRef_getAliasKind (c->sref);
1049 c->storageclass = SCSTATIC;
1051 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1053 if (!alkind_isUnknown (ak)
1054 && !alkind_isStatic (ak))
1056 if (!(ctype_isRealPointer (uentry_getType (c)))
1057 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1058 && !alkind_isRefCounted (ak))
1060 if (alkind_isImplicit (ak)
1061 && alkind_isDependent (ak)
1062 && ctype_isArray (uentry_getType (c)))
1064 ; /* no error for observer arrays */
1070 message ("Static storage %q declared as %s",
1072 alkind_unparse (ak)),
1073 uentry_whereDeclared (c));
1079 if (alkind_isUnknown (ak)
1080 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1081 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1083 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1084 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1092 uentry_setExtern (uentry c)
1094 if (uentry_isValid (c))
1095 c->storageclass = SCEXTERN;
1099 uentry_setParamNo (uentry ue, int pno)
1101 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1102 sRef_setParamNo (ue->sref, pno);
1106 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1108 sRefSet_allElements (sr, el)
1110 sRef base = sRef_getRootBase (el);
1112 if (sRef_isGlobal (base) || sRef_isInternalState (base)
1113 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1115 if (!globSet_member (ue->info->fcn->globs, base))
1117 if (uentry_hasGlobs (ue)
1118 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1121 (FLG_WARNMISSINGGLOBALS,
1123 ("Modifies list for %q uses global %q, "
1124 "not included in globals list.",
1125 uentry_getName (ue),
1126 sRef_unparse (base)),
1127 uentry_whereLast (ue)))
1129 uentry_showWhereSpecified (ue);
1133 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1135 if (sRef_isFileStatic (base))
1137 context_recordFileGlobals (ue->info->fcn->globs);
1141 } end_sRefSet_allElements;
1145 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
1147 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1151 uentry_fixupSref (uentry ue)
1155 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1160 sr = uentry_getSref (ue);
1162 sRef_resetState (sr);
1163 sRef_clearDerived (sr);
1165 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1166 llassert (sRef_isValid (sr));
1168 if (uentry_isVariable (ue))
1170 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1171 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1175 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
1177 llassert (uentry_isFunction (ue));
1178 llassert (!specialClauses_isDefined (ue->info->fcn->specclauses));
1180 ue->info->fcn->specclauses = clauses;
1181 specialClauses_checkAll (ue);
1185 ** Used for @modifies@ @endmodifies@ syntax.
1187 ** If ue is specified, sr must contain *only*:
1189 ** o file static globals
1190 ** o sRef's derived from modifies spec (i.e., more specific than
1191 ** what was specified)
1193 ** Otherwise, if sr has modifies it must match sr.
1195 ** If it doesn't have modifies, set them to sr.
1199 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1201 if (sRef_modInFunction ())
1204 (message ("Modifies list not in function context. "
1205 "A modifies list can only appear following the parameter list "
1206 "in a function declaration or header."));
1208 /*@-mustfree@*/ return; /*@=mustfree@*/
1211 if (sRefSet_hasStatic (sr))
1213 context_recordFileModifies (sr);
1216 if (uentry_isValid (ue))
1218 if (uentry_isIter (ue))
1220 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1221 ue->info->iter->mods = sr;
1225 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1227 uentry_makeVarFunction (ue);
1230 llassertfatal (uentry_isFunction (ue));
1231 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1233 ue->info->fcn->mods = sr;
1234 ue->info->fcn->hasMods = TRUE;
1236 checkGlobalsModifies (ue, sr);
1239 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1241 ue->info->fcn->hasGlobs = TRUE;
1251 uentry_setPreconditions (uentry ue, /*@owned@*/ constraintList preconditions)
1253 if (sRef_modInFunction ())
1256 (message ("Precondition list not in function context. "
1257 "A precondition list can only appear following the parameter list "
1258 "in a function declaration or header."));
1260 /*@-mustfree@*/ return; /*@=mustfree@*/
1263 if (uentry_isValid (ue))
1266 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1268 uentry_makeVarFunction (ue);
1271 llassertfatal (uentry_isFunction (ue));
1272 // llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1274 ue->info->fcn->preconditions = preconditions;
1285 ** requires: new and old are functions
1289 checkGlobalsConformance (/*@notnull@*/ uentry old,
1290 /*@notnull@*/ uentry unew,
1291 bool mustConform, bool completeConform)
1293 bool hasInternalState = FALSE;
1295 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1297 if (globSet_isDefined (unew->info->fcn->globs))
1299 globSet_allElements (unew->info->fcn->globs, el)
1301 if (sRef_isFileStatic (el))
1303 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1305 if (sRef_isInvalid (sr))
1307 bool hasError = FALSE;
1309 if (!hasInternalState
1310 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1311 sRef_makeInternalState ()))
1312 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1313 sRef_makeSpecState ())))
1316 && !uentry_isStatic (old)
1319 message ("Globals list for %q includes internal state, %q, "
1320 "but %s without globals internalState.",
1321 uentry_getName (old),
1323 uentry_specOrDefName (old)),
1324 uentry_whereLast (unew)))
1326 uentry_showWhereSpecified (old);
1330 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1331 sRef_makeInternalState ());
1332 hasInternalState = TRUE;
1336 && fileloc_sameFile (uentry_whereDeclared (unew),
1337 uentry_whereDeclared (old)))
1342 message ("Function %q inconsistently %rdeclared (in "
1343 "same file) with file static global %q in "
1345 uentry_getName (unew),
1346 uentry_isDeclared (old),
1348 uentry_whereDeclared (unew)))
1350 uentry_showWhereSpecified (old);
1355 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1356 context_recordFileGlobals (old->info->fcn->globs);
1360 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1362 if (sRef_isInvalid (sr))
1367 message ("Function %q inconsistently %rdeclared with "
1368 "%q in globals list",
1369 uentry_getName (unew),
1370 uentry_isDeclared (old),
1372 uentry_whereDeclared (unew)))
1374 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1375 uentry_showWhereSpecified (old);
1380 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1386 ("Function %q global %q inconsistently "
1387 "%rdeclared as %qout global",
1388 uentry_getName (unew),
1390 uentry_isDeclared (old),
1391 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1392 uentry_whereDeclared (unew)))
1394 uentry_showWhereSpecified (old);
1399 } end_globSet_allElements ;
1401 if (completeConform)
1403 globSet_allElements (old->info->fcn->globs, el)
1405 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1407 if (sRef_isInvalid (sr))
1410 && uentry_isReallySpecified (old)
1413 message ("Function %q specified with %q in globals list, "
1414 "but declared without %q",
1415 uentry_getName (unew),
1418 uentry_whereDeclared (unew)))
1420 uentry_showWhereSpecified (old);
1423 } end_globSet_allElements;
1428 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1430 if (uentry_isReallySpecified (old)
1433 message ("%s %q specified with globals list, but "
1434 "declared with no globals",
1435 ekind_capName (unew->ukind),
1436 uentry_getName (unew)),
1437 uentry_whereDeclared (unew)))
1440 (message ("Specification globals: %q",
1441 globSet_unparse (old->info->fcn->globs)),
1442 uentry_whereSpecified (old));
1446 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
1447 old->info->fcn->globs);
1452 ** new modifies list must be included by old modifies list.
1454 ** file static state may be added to new, if old has internal.
1458 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1459 bool mustConform, bool completeConform)
1462 bool changedMods = FALSE;
1463 bool modInternal = FALSE;
1465 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1467 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1468 newMods = unew->info->fcn->mods;
1470 if (sRefSet_isEmpty (newMods))
1472 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1473 && uentry_isReallySpecified (old))
1477 message ("%s %q specified with modifies clause, "
1478 "but declared with no modifies clause",
1479 ekind_capName (unew->ukind),
1480 uentry_getName (unew)),
1481 uentry_whereDeclared (unew)))
1483 llgenindentmsg (message ("Specification has modifies %q",
1484 sRefSet_unparse (old->info->fcn->mods)),
1485 uentry_whereSpecified (old));
1492 sRefSet_allElements (newMods, current)
1494 if (sRef_isValid (current))
1496 sRef rb = sRef_getRootBase (current);
1498 if (sRef_isFileStatic (rb))
1502 if (!sRefSet_isSameMember (old->info->fcn->mods,
1503 sRef_makeInternalState ())
1504 && !sRefSet_isSameMember (old->info->fcn->mods,
1505 sRef_makeSpecState ()))
1508 && !uentry_isStatic (old)
1512 ("Modifies list for %q includes internal state, "
1513 "but %s without modifies internal.",
1514 uentry_getName (old),
1515 uentry_specOrDefName (old)),
1516 uentry_whereLast (unew)))
1518 uentry_showWhereSpecified (old);
1521 old->info->fcn->mods =
1522 sRefSet_insert (old->info->fcn->mods,
1523 sRef_makeInternalState ());
1528 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1534 if (sRef_canModifyVal (current, old->info->fcn->mods))
1536 int size = sRefSet_size (old->info->fcn->mods);
1538 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1541 if (sRefSet_size (old->info->fcn->mods) != size)
1552 ("Modifies list for %q contains %q, not modifiable "
1554 uentry_getName (old),
1555 sRef_unparse (current),
1556 uentry_specDeclName (old)),
1557 uentry_whereLast (unew)))
1559 uentry_showWhereSpecified (old);
1564 } end_sRefSet_allElements;
1566 if (completeConform && uentry_isReallySpecified (old))
1568 sRefSet_allElements (old->info->fcn->mods, el)
1570 if (sRef_canModify (el, newMods))
1579 ("Specification modifies clause for %q contains %q, "
1580 "not included in declaration modifies clause",
1581 uentry_getName (old),
1583 uentry_whereLast (unew)))
1585 uentry_showWhereSpecified (old);
1588 } end_sRefSet_allElements ;
1592 ** Make sure file static elements will be removed.
1597 context_recordFileModifies (old->info->fcn->mods);
1602 uentry_checkMutableType (uentry ue)
1604 ctype ct = uentry_getType (ue);
1606 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1608 voptgenerror (FLG_MUTREP,
1609 message ("Mutable abstract type %q declared without pointer "
1610 "indirection: %t (violates assignment semantics)",
1611 uentry_getName (ue), ct),
1612 uentry_whereDeclared (ue));
1617 uentry_setMutable (uentry e)
1619 llassert (uentry_isDatatype (e));
1620 e->info->datatype->mut = YES;
1624 uentry_checkIterArgs (uentry ue)
1626 bool hasYield = FALSE;
1629 llassert (uentry_isIter (ue));
1631 args = uentry_getParams (ue);
1633 uentryList_elements (args, el)
1635 sstate ds = uentry_getDefState (el);
1637 if (uentry_isYield (el))
1642 if (sstate_isUnknown (ds))
1644 uentry_setDefState (el, SS_DEFINED);
1650 } end_uentryList_elements;
1654 voptgenerror (FLG_HASYIELD,
1655 message ("Iterator %q declared with no yield parameters",
1656 uentry_getName (ue)),
1657 uentry_whereDeclared (ue));
1662 chkind_fromQual (qual qel)
1664 if (qual_isChecked (qel))
1668 else if (qual_isCheckMod (qel))
1672 else if (qual_isCheckedStrict (qel))
1674 return CH_CHECKEDSTRICT;
1676 else if (qual_isUnchecked (qel))
1678 return CH_UNCHECKED;
1683 /*@notreached@*/ return CH_UNKNOWN;
1688 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
1690 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
1692 if (!uentry_isRefCounted (ue))
1696 message ("Reference counting qualifier %s used on non-reference "
1697 "counted storage: %q",
1699 uentry_unparse (ue)));
1703 alkind ak = alkind_fromQual (qel);
1705 uentry_setAliasKind (ue, ak);
1708 else if (qual_isRefCounted (qel))
1710 ctype ct = ctype_realType (uentry_getType (ue));
1713 if (ctype_isPointer (ct)
1714 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
1716 /* check there is a refs field */
1717 uentryList fields = ctype_getFields (rt);
1718 uentry refs = uentry_undefined;
1720 uentryList_elements (fields, field)
1722 if (uentry_isRefsField (field))
1724 if (uentry_isValid (refs))
1728 message ("Reference counted structure type %s has "
1729 "multiple refs fields: %q and %q",
1731 uentry_getName (refs),
1732 uentry_getName (field)));
1737 } end_uentryList_elements;
1739 if (uentry_isInvalid (refs))
1743 message ("Reference counted structure type %s has "
1745 ctype_unparse (ct)),
1747 ("To count reference, the structure must have a field named "
1748 "refs of type int."),
1751 else if (!ctype_isInt (uentry_getType (refs)))
1755 message ("Reference counted structure type %s refs field has "
1756 "type %s (should be int)", ctype_unparse (ct),
1757 ctype_unparse (uentry_getType (refs))));
1761 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1762 uentry_whereDeclared (ue));
1767 if ((ctype_isPointer (ct)
1768 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
1769 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
1771 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1772 uentry_whereDeclared (ue));
1778 message ("Non-pointer to structure type %s declared with "
1779 "refcounted qualifier",
1780 ctype_unparse (ct)));
1784 else if (qual_isRefs (qel))
1786 if (uentry_isVariable (ue) && !uentry_isParam (ue))
1788 uentry_setAliasKind (ue, AK_REFS);
1794 message ("Refs qualifier used on non-structure field: %q",
1795 uentry_unparse (ue)));
1798 else if (qual_isAliasQual (qel))
1800 alkind ak = alkind_fromQual (qel);
1802 alkind oldak = uentry_getAliasKind (ue);
1803 ctype ut = uentry_getType (ue);
1805 if (alkind_isImplicit (ak)
1806 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
1808 /* ignore the implied qualifier */
1812 if (uentry_isEitherConstant (ue))
1816 message ("Alias qualifier %s used on constant: %q",
1817 alkind_unparse (ak), uentry_unparse (ue)));
1821 if (ctype_isFunction (ut))
1823 ut = ctype_returnValue (ut);
1826 if (!(ctype_isVisiblySharable (ut)
1827 || ctype_isRealArray (ut)
1828 || ctype_isRealSU (ut)))
1830 if (!qual_isImplied (qel))
1834 message ("Alias qualifier %s used on unsharable storage type %t: %q",
1835 alkind_unparse (ak), ut, uentry_getName (ue)));
1842 if (uentry_isRefCounted (ue))
1844 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
1845 || qual_isExposed (qel)
1846 || qual_isObserver (qel)))
1848 if (!qual_isImplied (qel))
1853 ("Alias qualifier %s used on reference counted storage: %q",
1854 alkind_unparse (ak),
1855 uentry_unparse (ue)));
1863 if (qual_isRefQual (qel))
1867 message ("Qualifier %s used on non-reference counted storage: %q",
1868 alkind_unparse (ak), uentry_unparse (ue)));
1877 uentry_setAliasKind (ue, ak);
1880 else if (qual_isNull (qel))
1882 if (uentry_isConstant (ue))
1886 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
1887 uentry_whereDeclared (ue));
1891 uentry_setNullState (ue, NS_POSNULL);
1894 else if (qual_isRelNull (qel))
1896 uentry_setNullState (ue, NS_RELNULL);
1898 else if (qual_isNotNull (qel))
1900 uentry_setNullState (ue, NS_MNOTNULL);
1902 else if (qual_isAbstract (qel)
1903 || qual_isConcrete (qel))
1905 if (!uentry_isDatatype (ue))
1909 message ("Qualifier %s used with non-datatype",
1910 qual_unparse (qel)));
1914 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
1917 else if (qual_isMutable (qel))
1919 if (!uentry_isDatatype (ue))
1921 llerror (FLG_SYNTAX,
1922 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
1926 if (!ynm_isOn (ue->info->datatype->mut))
1928 uentry_checkMutableType (ue);
1931 ue->info->datatype->mut = YES;
1934 else if (qual_isImmutable (qel))
1936 if (!uentry_isDatatype (ue))
1938 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
1939 qual_unparse (qel)));
1943 ue->info->datatype->mut = NO;
1946 else if (qual_isNullPred (qel))
1948 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1950 uentry_makeVarFunction (ue);
1953 if (uentry_isFunction (ue))
1955 ctype typ = uentry_getType (ue);
1956 ctype rtype = ctype_returnValue (uentry_getType (ue));
1958 if (ctype_isRealBool (rtype))
1960 uentryList pl = ctype_argsFunction (typ);
1962 if (uentryList_size (pl) == 1)
1964 ue->info->fcn->nullPred = qel;
1968 llerror (FLG_SYNTAX,
1969 message ("Qualifier %s used with function having %d "
1970 "arguments (should have 1)",
1972 uentryList_size (pl)));
1977 llerror (FLG_SYNTAX,
1978 message ("Qualifier %s used with function returning %s "
1979 "(should return bool)",
1981 ctype_unparse (rtype)));
1986 llerror (FLG_SYNTAX,
1987 message ("Qualifier %s used with non-function",
1988 qual_unparse (qel)));
1991 else if (qual_isExitQual (qel))
1993 exitkind exk = exitkind_fromQual (qel);
1995 if (uentry_isFunction (ue))
1997 if (exitkind_isKnown (ue->info->fcn->exitCode))
1999 llerror (FLG_SYNTAX,
2000 message ("Multiple exit qualifiers used on function %q: %s, %s",
2001 uentry_getName (ue),
2002 exitkind_unparse (ue->info->fcn->exitCode),
2003 exitkind_unparse (exk)));
2006 ue->info->fcn->exitCode = exk;
2010 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2012 uentry_makeVarFunction (ue);
2013 ue->info->fcn->exitCode = exk;
2017 llerror (FLG_SYNTAX,
2018 message ("Exit qualifier %s used with non-function (type %s)",
2020 ctype_unparse (uentry_getType (ue))));
2026 if (qual_isCQual (qel))
2032 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
2038 uentry_reflectQualifiers (uentry ue, qualList q)
2040 llassert (uentry_isValid (ue));
2042 qualList_elements (q, qel)
2044 if (qual_isStatic (qel))
2046 uentry_setStatic (ue);
2048 else if (qual_isUnused (qel))
2050 uentry_setUsed (ue, fileloc_undefined);
2052 else if (qual_isExternal (qel))
2054 fileloc_free (ue->whereDefined);
2055 ue->whereDefined = fileloc_createExternal ();
2057 else if (qual_isSef (qel))
2059 if (uentry_isVariable (ue))
2061 vkind vk = ue->info->var->kind;
2063 llassert (vk != VKREFPARAM);
2065 if (vk == VKYIELDPARAM)
2069 message ("Qualifier sef cannot be used with %s: %q",
2070 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2071 uentry_unparse (ue)));
2073 else if (vk == VKRETPARAM)
2075 ue->info->var->kind = VKSEFRETPARAM;
2079 ue->info->var->kind = VKSEFPARAM;
2086 message ("Qualifier sef is meaningful only on parameters: %q",
2087 uentry_unparse (ue)));
2090 else if (qual_isExtern (qel))
2092 ue->storageclass = SCEXTERN;
2094 else if (qual_isGlobalQual (qel)) /* undef, killed */
2096 if (uentry_isVariable (ue))
2098 sstate oldstate = ue->info->var->defstate;
2099 sstate defstate = sstate_fromQual (qel);
2102 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2103 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2105 defstate = SS_UNDEFKILLED;
2112 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2113 ue->info->var->defstate = defstate;
2119 message ("Qualifier %s used on non-variable: %q",
2120 qual_unparse (qel), uentry_unparse (ue)));
2123 /* start modifications */
2125 else if( qual_isBufQualifier(qel) ) {
2126 ctype ct = ctype_realType(uentry_getType(ue));
2128 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2130 if( uentry_hasBufStateInfo(ue) ) {
2132 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2134 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2135 /* If formal func param */
2136 uentry_setNullTerminatedState(ue);
2137 uentry_setLen (ue, 1);
2138 uentry_setSize (ue, 1);
2140 sRef_setNullTerminatedState(uentry_getSref(ue));
2141 sRef_setLen (uentry_getSref(ue), 1);
2142 sRef_setSize (uentry_getSref(ue), 1);
2144 uentry_setPossiblyNullTerminatedState(ue);
2146 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2150 /* put other BufState Qualifiers here */
2152 cstring s = uentry_getName(ue);
2153 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2154 struct for identifier %s\n", s) );
2156 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2158 sRef retSref = uentry_getSref (ue);
2159 ctype retType = sRef_getType (retSref);
2161 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2162 sRef_setNullTerminatedState (retSref);
2168 message ("Qualifier %s used on non-pointer on \
2169 function return: %q", qual_unparse (qel),
2170 uentry_unparse (ue)));
2177 message ("Qualifier %s used on non-pointer: %q",
2178 qual_unparse (qel), uentry_unparse (ue)));
2181 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2183 ctype realType = ctype_realType (ue->utype);
2184 sstate defstate = sstate_fromQual (qel);
2186 if (ctype_isFunction (realType))
2188 realType = ctype_realType (ctype_returnValue (realType));
2191 if (qual_isRelDef (qel))
2193 ; /* okay anywhere */
2197 if (!ctype_isAP (realType)
2198 && !ctype_isSU (realType)
2199 && !ctype_isUnknown (realType)
2200 && !ctype_isAbstract (ue->utype))
2204 message ("Qualifier %s used on non-pointer or struct: %q",
2205 qual_unparse (qel), uentry_unparse (ue)));
2209 uentry_setDefState (ue, defstate);
2211 if (sRef_isStateSpecial (ue->sref)
2212 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2214 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2217 else if (qual_isYield (qel))
2219 if (uentry_isVariable (ue))
2221 ue->info->var->kind = VKYIELDPARAM;
2227 message ("Qualifier %s used on non-iterator parameter: %q",
2228 qual_unparse (qel), uentry_unparse (ue)));
2231 else if (qual_isExQual (qel))
2233 exkind ek = exkind_fromQual (qel);
2234 ctype ut = uentry_getType (ue);
2236 if (ctype_isFunction (ut))
2238 ut = ctype_returnValue (ut);
2241 if (!(ctype_isVisiblySharable (ut))
2242 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2243 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2245 if (!qual_isImplied (qel))
2249 message ("Qualifier %s used on unsharable storage type %t: %q",
2250 exkind_unparse (ek), ut, uentry_getName (ue)));
2255 alkind ak = sRef_getAliasKind (ue->sref);
2257 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2259 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2261 if (!alkind_isTemp (ak))
2263 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2266 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2267 || alkind_isOwned (ak))
2275 message ("Exposure qualifier %s used on %s storage (should "
2276 "be dependent): %q",
2278 alkind_unparse (ak),
2279 uentry_unparse (ue)));
2283 else if (qual_isGlobCheck (qel))
2285 if (uentry_isVariable (ue))
2287 chkind ch = chkind_fromQual (qel);
2289 if (ue->info->var->checked != CH_UNKNOWN)
2291 if (ch == ue->info->var->checked)
2293 llerror (FLG_SYNTAX,
2294 message ("Redundant %s qualifier on %q",
2296 uentry_getName (ue)));
2300 llerror (FLG_SYNTAX,
2302 ("Contradictory %s and %s qualifiers on %q",
2304 checkedName (ue->info->var->checked),
2305 uentry_getName (ue)));
2309 ue->info->var->checked = ch;
2315 message ("Qualifier %s used with non-variable",
2316 qual_unparse (qel)));
2319 else if (qual_isReturned (qel))
2321 if (uentry_isVariable (ue))
2323 ue->info->var->kind = VKRETPARAM;
2327 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2328 qual_unparse (qel)));
2333 uentry_reflectOtherQualifier (ue, qel);
2336 sRef_storeState (ue->sref);
2337 } end_qualList_elements;
2343 uentry_isOnly (uentry ue)
2345 return (!uentry_isUndefined (ue)
2346 && uentry_isVariable (ue)
2347 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2351 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2353 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2354 sRef_setOrigAliasKind (ue->sref, ak);
2358 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2360 if (uentry_isVariable (ue))
2362 ue->info->var->nullstate = ns;
2365 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2369 uentry_isUnique (uentry ue)
2371 return (!uentry_isUndefined (ue)
2372 && uentry_isVariable (ue)
2373 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2377 uentry_isFileStatic (uentry ue)
2379 return (uentry_isStatic (ue)
2380 && (!uentry_isVariable (ue)
2381 || sRef_isFileStatic (uentry_getSref (ue))));
2385 uentry_isExported (uentry ue)
2387 if (uentry_isValid (ue))
2389 if (uentry_isVariable (ue))
2391 return (sRef_isRealGlobal (uentry_getSref (ue)));
2395 return !uentry_isStatic (ue);
2403 uentry_isNonLocal (uentry ue)
2405 return (uentry_isValid (ue) && uentry_isVariable (ue)
2406 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
2410 uentry_isGlobal (uentry ue)
2412 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
2413 sRef_isGlobal (ue->sref));
2417 uentry_isPrintfLike (uentry ue)
2419 return (uentry_isFunction (ue)
2420 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2424 uentry_isScanfLike (uentry ue)
2426 return (uentry_isFunction (ue)
2427 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2431 uentry_isMessageLike (uentry ue)
2433 return (uentry_isFunction (ue)
2434 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2437 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2439 uentryList args = uentry_getParams (ue);
2441 if (!uentryList_isMissingParams (args))
2443 uentry last = uentry_undefined;
2445 uentryList_elements (args, current)
2447 if (uentry_isElipsisMarker (current))
2449 if (uentry_isUndefined (last))
2453 message ("Function %q is marked %s, but has no format "
2454 "string argument before elipsis",
2455 uentry_getName (ue),
2456 specCode_unparse (ue->info->fcn->specialCode)),
2457 uentry_whereLast (ue));
2458 ue->info->fcn->specialCode = SPC_NONE;
2462 ctype rt = ctype_realType (uentry_getType (last));
2464 if (!ctype_match (rt, ctype_string))
2468 /* wchar_t * is okay too */
2469 if (ctype_isAP (rt))
2471 ctype base = ctype_baseArrayPtr (rt);
2473 if (ctype_isArbitraryIntegral (base))
2483 message ("Function %q is marked %s, but the argument "
2484 "before the elipsis has type %s (should be char *)",
2485 uentry_getName (ue),
2486 specCode_unparse (ue->info->fcn->specialCode),
2487 ctype_unparse (uentry_getType (last))),
2488 uentry_whereLast (ue));
2490 ue->info->fcn->specialCode = SPC_NONE;
2497 } end_uentryList_elements ;
2501 message ("Function %q is marked %s, but has no elipsis parameter",
2502 uentry_getName (ue),
2503 specCode_unparse (ue->info->fcn->specialCode)),
2504 uentry_whereLast (ue));
2506 ue->info->fcn->specialCode = SPC_NONE;
2511 uentry_setPrintfLike (uentry ue)
2513 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2515 uentry_makeVarFunction (ue);
2518 llassertfatal (uentry_isFunction (ue));
2519 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2520 checkSpecialFunction (ue);
2524 uentry_setScanfLike (uentry ue)
2526 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2528 uentry_makeVarFunction (ue);
2531 llassertfatal (uentry_isFunction (ue));
2532 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2533 checkSpecialFunction (ue);
2537 uentry_setMessageLike (uentry ue)
2539 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2541 uentry_makeVarFunction (ue);
2544 llassertfatal (uentry_isFunction (ue));
2545 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
2546 checkSpecialFunction (ue);
2550 uentry_isSpecialFunction (uentry ue)
2552 return (uentry_isFunction (ue)
2553 && (ue->info->fcn->specialCode != SPC_NONE));
2556 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
2558 ctype ct = idDecl_getCtype (t);
2560 sRef pref = sRef_makeParam (i, ct);
2561 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
2563 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2564 uentry_implicitParamAnnots (ue);
2566 /* Parameter type [][] or [x][] is invalid */
2568 while (ctype_isFixedArray (base)) {
2569 base = ctype_baseArrayPtr (base);
2572 if (ctype_isIncompleteArray (base)) {
2573 base = ctype_baseArrayPtr (base);
2575 if (ctype_isArray (base)) {
2576 if (!uentry_hasName (ue)) {
2577 (void) optgenerror (FLG_INCOMPLETETYPE,
2578 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
2580 ctype_unparse (ct)),
2581 uentry_whereLast (ue));
2583 (void) optgenerror (FLG_INCOMPLETETYPE,
2584 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
2585 uentry_getName (ue),
2586 ctype_unparse (ct)),
2587 uentry_whereLast (ue));
2595 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
2597 ctype ct = idDecl_getCtype (t);
2599 if (ctype_isFunction (ct))
2601 return (uentry_makeIdFunction (t));
2605 fileloc loc = setLocation ();
2606 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
2608 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2610 if (!uentry_isExtern (ue))
2612 uentry_setDefined (ue, loc);
2620 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
2622 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
2630 /*@only@*/ /*@notnull@*/
2631 uentry uentry_makeConstantAux (cstring n, ctype t,
2632 /*@keep@*/ fileloc f, bool priv,
2633 /*@only@*/ multiVal m)
2635 uentry e = uentry_alloc ();
2638 e->uname = cstring_copy (n);
2640 e->storageclass = SCNONE;
2642 e->sref = sRef_makeConst (t);
2647 e->uses = filelocList_new ();
2648 e->isPrivate = priv;
2649 e->hasNameError = FALSE;
2651 e->info = (uinfo) dmalloc (sizeof (*e->info));
2652 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
2653 e->info->uconst->val = m;
2654 e->info->uconst->access = typeIdSet_undefined;
2656 uentry_setSpecDef (e, f);
2658 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
2660 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
2666 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
2668 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
2671 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
2673 uentry ue = uentry_makeConstant (idDecl_observeId (t),
2674 idDecl_getCtype (t),
2677 llassert (fileloc_isUndefined (ue->whereDeclared));
2678 ue->whereDeclared = setLocation ();
2680 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2689 void uentry_setDefState (uentry ue, sstate defstate)
2691 if (uentry_isValid (ue))
2693 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2695 if (uentry_isVariable (ue))
2697 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
2702 bool uentry_isCheckedUnknown (uentry ue)
2704 return (uentry_isVar (ue)
2705 && (ue->info->var->checked == CH_UNKNOWN));
2708 bool uentry_isCheckMod (uentry ue)
2710 return (uentry_isVar (ue)
2711 && (ue->info->var->checked == CH_CHECKMOD));
2714 bool uentry_isUnchecked (uentry ue)
2716 return (uentry_isVar (ue)
2717 && (ue->info->var->checked == CH_UNCHECKED));
2720 bool uentry_isChecked (uentry ue)
2722 return (uentry_isVar (ue)
2723 && (ue->info->var->checked == CH_CHECKED));
2726 bool uentry_isCheckedModify (uentry ue)
2728 return (uentry_isVar (ue)
2729 && (ue->info->var->checked == CH_CHECKED
2730 || ue->info->var->checked == CH_CHECKMOD
2731 || ue->info->var->checked == CH_CHECKEDSTRICT));
2734 bool uentry_isCheckedStrict (uentry ue)
2736 return (uentry_isVar (ue)
2737 && (ue->info->var->checked == CH_CHECKEDSTRICT));
2740 void uentry_setUnchecked (uentry ue)
2742 llassert (uentry_isVar (ue));
2744 ue->info->var->checked = CH_UNCHECKED;
2747 void uentry_setChecked (uentry ue)
2749 llassert (uentry_isVar (ue));
2751 ue->info->var->checked = CH_CHECKED;
2754 void uentry_setCheckMod (uentry ue)
2756 llassert (uentry_isVar (ue));
2758 ue->info->var->checked = CH_CHECKMOD;
2761 void uentry_setCheckedStrict (uentry ue)
2763 llassert (uentry_isVar (ue));
2765 ue->info->var->checked = CH_CHECKEDSTRICT;
2768 static /*@only@*/ /*@notnull@*/
2769 uentry uentry_makeVariableAux (cstring n, ctype t,
2771 /*@exposed@*/ sRef s,
2772 bool priv, vkind kind)
2774 uentry e = uentry_alloc ();
2777 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
2780 e->uname = cstring_copy (n);
2783 e->storageclass = SCNONE;
2790 e->uses = filelocList_new ();
2791 e->isPrivate = priv;
2792 e->hasNameError = FALSE;
2794 e->info = (uinfo) dmalloc (sizeof (*e->info));
2795 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
2796 e->info->var->kind = kind;
2798 e->info->var->checked = CH_UNKNOWN;
2800 uentry_setSpecDef (e, f);
2802 if (ctype_isFunction (rt))
2804 rt = ctype_returnValue (rt);
2807 if (ctype_isUA (rt))
2809 sRef_setStateFromType (e->sref, rt);
2812 e->info->var->defstate = sRef_getDefState (e->sref);
2813 e->info->var->nullstate = sRef_getNullState (e->sref);
2815 /* start modifications */
2816 /* This function sets the uentry for a pointer or array variable declaration,
2817 it allocates memory and sets the fields. We check if the type of the variable
2818 is a pointer or array and allocate a `bbufinfo' struct accordingly */
2820 if( ctype_isArray (t) || ctype_isPointer(t)) {
2821 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
2822 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
2823 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
2825 e->info->var->bufinfo = NULL;
2827 /* end modification */
2833 uentry_isYield (uentry ue)
2835 return (uentry_isVariable (ue)
2836 && (ue->info->var->kind == VKYIELDPARAM
2837 || ue->info->var->kind == VKREFYIELDPARAM));
2841 uentry_isRefsField (uentry ue)
2843 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
2846 /*@only@*/ /*@notnull@*/
2847 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
2849 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
2850 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
2857 void uentry_makeVarFunction (uentry ue)
2864 llassert (uentry_isValid (ue));
2865 llassert (!sRef_modInFunction ());
2867 ak = sRef_getOrigAliasKind (ue->sref);
2868 ek = sRef_getOrigExKind (ue->sref);
2870 oldInfo = ue->info->var;
2872 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
2875 ** expanded macro is marked used (until I write a pre-processor)
2878 ue->used |= (oldInfo->kind == VKEXPMACRO);
2881 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
2882 ue->info->fcn->exitCode = XK_UNKNOWN;
2883 ue->info->fcn->nullPred = QU_UNKNOWN;
2884 ue->info->fcn->specialCode = SPC_NONE;
2885 ue->info->fcn->access = typeIdSet_undefined;
2886 ue->info->fcn->hasGlobs = FALSE;
2887 ue->info->fcn->globs = globSet_undefined;
2888 ue->info->fcn->hasMods = FALSE;
2889 ue->info->fcn->mods = sRefSet_undefined;
2890 ue->info->fcn->specclauses = NULL;
2891 ue->info->fcn->defparams = uentryList_undefined;
2894 ue->info->fcn->preconditions = constraintList_undefined;
2897 if (ctype_isFunction (ue->utype))
2899 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
2903 ue->sref = sRef_makeType (ctype_unknown);
2906 if (sRef_isRefCounted (ue->sref))
2912 if (alkind_isUnknown (ak))
2914 if (exkind_isKnown (ek))
2916 ak = AK_IMPDEPENDENT;
2920 if (context_getFlag (FLG_RETIMPONLY))
2922 if (ctype_isFunction (ue->utype)
2923 && ctype_isVisiblySharable
2924 (ctype_realType (ctype_returnValue (ue->utype))))
2926 if (uentryList_hasReturned (uentry_getParams (ue)))
2940 loc = ue->whereDeclared;
2942 sRef_setAliasKind (ue->sref, ak, loc);
2943 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
2944 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
2945 sRef_setExKind (ue->sref, ek, loc);
2947 if (oldInfo->kind == VKEXPMACRO)
2950 ue->whereDeclared = fileloc_undefined;
2954 fileloc_free (ue->whereDefined);
2955 ue->whereDefined = fileloc_undefined;
2958 uvinfo_free (oldInfo);
2962 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
2964 llassert (uentry_isValid (ue));
2966 if (uentry_isIter (ue))
2968 llassert (globSet_isUndefined (ue->info->iter->globs));
2969 ue->info->iter->globs = globs;
2973 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2975 uentry_makeVarFunction (ue);
2978 llassert (uentry_isFunction (ue));
2979 llassert (!ue->info->fcn->hasGlobs
2980 && globSet_isUndefined (ue->info->fcn->globs));
2982 ue->info->fcn->hasGlobs = TRUE;
2983 /*@-mustfree@*/ ue->info->fcn->globs = globs;
2987 if (globSet_hasStatic (globs))
2989 context_recordFileGlobals (globs);
2992 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
2994 ue->info->fcn->hasMods = TRUE;
2998 void uentry_addAccessType (uentry ue, typeId tid)
3000 if (uentry_isFunction (ue))
3002 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3004 else if (uentry_isEitherConstant (ue))
3006 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3008 else if (uentry_isIter (ue))
3010 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3012 else if (uentry_isEndIter (ue))
3014 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3018 llbug (message ("no access for: %q", uentry_unparse (ue)));
3022 /*@only@*/ /*@notnull@*/ uentry
3023 uentry_makeFunction (cstring n, ctype t,
3025 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3028 return (uentry_makeFunctionAux (n, t,
3029 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3030 : typeIdSet_single (access)),
3036 /*@notnull@*/ uentry
3037 uentry_makePrivFunction2 (cstring n, ctype t,
3039 globSet globs, sRefSet mods,
3042 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
3046 /*@notnull@*/ uentry
3047 uentry_makeSpecFunction (cstring n, ctype t,
3049 /*@only@*/ globSet globs,
3050 /*@only@*/ sRefSet mods,
3053 uentry ue = uentry_makeFunctionAux (n, t, access,
3057 uentry_setHasGlobs (ue);
3058 uentry_setHasMods (ue);
3060 reflectImplicitFunctionQualifiers (ue, TRUE);
3065 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3067 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3068 sRef_undefined, FALSE, VKEXPMACRO);
3070 uentry_setDefined (ue, f);
3074 /*@notnull@*/ /*@notnull@*/ uentry
3075 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3077 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3078 typeIdSet_singleOpt (access),
3079 globSet_undefined, sRefSet_undefined,
3083 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3087 bool uentry_isForward (uentry e)
3089 if (uentry_isValid (e))
3091 ctype ct = uentry_getType (e);
3093 return (ctype_isUnknown (ct)
3094 || (ctype_isFunction (ct)
3095 && ctype_isUnknown (ctype_returnValue (ct))));
3102 /*@notnull@*/ uentry
3103 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3105 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3111 /*@notnull@*/ uentry
3112 uentry_makeUnspecFunction (cstring n, ctype t,
3116 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
3117 sRefSet_new (), f, FALSE, TRUE);
3119 reflectImplicitFunctionQualifiers (ue, TRUE);
3128 /* is exported for use by usymtab_interface */
3130 /*@notnull@*/ uentry
3131 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
3132 fileloc f, bool priv)
3134 uentry e = uentry_alloc ();
3136 DPRINTF (("Make datatype: %s / %s",
3137 n, ctype_unparse (t)));
3139 /* e->shallowCopy = FALSE; */
3140 e->ukind = KDATATYPE;
3141 e->uname = cstring_copy (n);
3143 e->storageclass = SCNONE;
3144 e->sref = sRef_makeUnknown ();
3148 sRef_setStateFromType (e->sref, t);
3151 uentry_setSpecDef (e, f);
3153 e->uses = filelocList_new ();
3154 e->isPrivate = priv;
3155 e->hasNameError = FALSE;
3160 e->info = (uinfo) dmalloc (sizeof (*e->info));
3161 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3162 e->info->datatype->abs = abs;
3163 e->info->datatype->mut = mut;
3164 e->info->datatype->type = ctype_undefined;
3166 if (uentry_isDeclared (e))
3168 uentry_setDefined (e, f);
3171 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
3173 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3179 /*@notnull@*/ uentry
3180 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
3183 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
3186 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abs)
3188 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3189 ctype_bool, NO, abs,
3190 fileloc_getBuiltin (),
3193 ret->info->datatype->type = ctype_bool;
3201 static /*@only@*/ /*@notnull@*/ uentry
3202 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3203 /*@only@*/ fileloc f)
3205 uentry e = uentry_alloc ();
3208 e->uname = cstring_copy (n);
3210 e->sref = sRef_makeUnknown ();
3211 e->storageclass = SCNONE;
3215 uentry_setSpecDef (e, f);
3217 e->uses = filelocList_new ();
3218 e->isPrivate = FALSE;
3219 e->hasNameError = FALSE;
3221 e->info = (uinfo) dmalloc (sizeof (*e->info));
3222 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3223 e->info->iter->access = access;
3224 e->info->iter->mods = sRefSet_undefined;
3225 e->info->iter->globs = globSet_undefined;
3227 uentry_checkIterArgs (e);
3231 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3233 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3236 static /*@notnull@*/ uentry
3237 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3239 uentry e = uentry_alloc ();
3241 /* e->shallowCopy = FALSE; */
3242 e->ukind = KENDITER;
3243 e->storageclass = SCNONE;
3244 e->uname = message ("end_%s", n);
3245 e->utype = ctype_unknown;
3246 e->sref = sRef_makeUnknown ();
3248 uentry_setSpecDef (e, f);
3253 e->uses = filelocList_new ();
3254 e->isPrivate = FALSE;
3255 e->hasNameError = FALSE;
3257 e->info = (uinfo) dmalloc (sizeof (*e->info));
3258 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3260 e->info->enditer->access = access;
3265 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3267 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3274 static /*@only@*/ /*@notnull@*/ uentry
3275 uentry_makeTagAux (cstring n, ctype t,
3276 /*@only@*/ fileloc fl,
3277 bool priv, ekind kind)
3279 uentry e = uentry_alloc ();
3281 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3283 llbuglit ("uentry_makeTagAux: not a tag type");
3287 /* e->shallowCopy = FALSE; */
3288 e->uname = cstring_copy (n);
3291 e->sref = sRef_makeUnknown ();
3292 e->storageclass = SCNONE;
3294 uentry_setSpecDef (e, fl);
3299 e->uses = filelocList_new ();
3300 e->isPrivate = priv;
3301 e->hasNameError = FALSE;
3303 e->info = (uinfo) dmalloc (sizeof (*e->info));
3304 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3305 e->info->datatype->abs = NO;
3306 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3307 e->info->datatype->type = t;
3309 if (uentry_isDeclared (e))
3311 uentry_setDefined (e, fl);
3317 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3319 cstring sname = makeStruct (n);
3320 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3322 cstring_free (sname);
3327 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3329 cstring sname = makeStruct (n);
3330 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3332 cstring_free (sname);
3337 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3339 cstring uname = makeUnion (n);
3340 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3342 cstring_free (uname);
3348 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3350 cstring ename = makeEnum (n);
3351 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3353 cstring_free (ename);
3359 uentry_makeUnionTagLoc (cstring n, ctype t)
3361 cstring uname = makeUnion (n);
3362 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3364 cstring_free (uname);
3369 uentry_makeEnumTagLoc (cstring n, ctype t)
3371 cstring ename = makeEnum (n);
3372 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3374 cstring_free (ename);
3379 uentry_isStructTag (uentry ue)
3381 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3385 uentry_isUnionTag (uentry ue)
3387 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3391 uentry_isEnumTag (uentry ue)
3393 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3397 uentry_isAnyTag (uentry ue)
3399 return (uentry_isStructTag (ue)
3400 || uentry_isUnionTag (ue)
3401 || uentry_isEnumTag (ue));
3404 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3406 extern void uentry_destroyMod (void)
3407 /*@globals killed emarker@*/ /*@modifies emarker@*/
3409 static bool wasDestroyed = FALSE;
3411 llassert (!wasDestroyed);
3413 if (emarker != NULL)
3415 uentry_reallyFree (emarker);
3418 wasDestroyed = TRUE;
3422 uentry_makeElipsisMarker (void)
3424 if (emarker == NULL)
3426 emarker = uentry_alloc ();
3428 emarker->ukind = KELIPSMARKER;
3429 emarker->uname = cstring_makeLiteral ("...");
3430 emarker->utype = ctype_elipsMarker;
3431 emarker->sref = sRef_undefined;
3432 emarker->storageclass = SCNONE;
3433 emarker->used = FALSE;
3434 emarker->lset = FALSE;
3435 emarker->info = NULL;
3437 uentry_setSpecDef (emarker, fileloc_undefined);
3438 emarker->uses = filelocList_new ();
3439 emarker->isPrivate = FALSE;
3440 emarker->hasNameError = FALSE;
3443 /*@ignore@*/ return (emarker); /*@end@*/
3451 uentry_equiv (uentry p1, uentry p2)
3453 if (uentry_compare (p1, p2) != 0)
3464 uentry_xcomparealpha (uentry *p1, uentry *p2)
3468 if ((res = uentry_compare (*p1, *p2)) == 0) {
3469 if ((*p1 != NULL) && (*p2 != NULL)) {
3470 res = cstring_compare ((*p1)->uname,
3479 uentry_xcompareuses (uentry *p1, uentry *p2)
3484 if (uentry_isValid (u1))
3486 if (uentry_isValid (u2))
3488 return (-1 * int_compare (filelocList_size (u1->uses),
3489 filelocList_size (u2->uses)));
3498 if (uentry_isValid (u2))
3510 uentry_compareStrict (uentry v1, uentry v2)
3512 COMPARERETURN (uentry_compare (v1, v2));
3514 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
3516 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
3517 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
3518 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
3525 uentry_compare (uentry u1, uentry u2)
3527 if (u1 == u2) return 0;
3529 if (uentry_isInvalid (u1)) return -1;
3530 if (uentry_isInvalid (u2)) return 1;
3532 INTCOMPARERETURN (u1->ukind, u2->ukind);
3533 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
3534 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
3536 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
3542 /* bug detected by lclint:
3543 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
3548 return (multiVal_compare (u1->info->uconst->val,
3549 u2->info->uconst->val));
3553 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
3555 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3556 uentry_accessType (u2)));
3557 return (uentryList_compareParams (uentry_getParams (u1),
3558 uentry_getParams (u2)));
3560 return (typeIdSet_compare (uentry_accessType (u1),
3561 uentry_accessType (u2)));
3563 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3564 uentry_accessType (u2)));
3565 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
3566 uentry_getGlobs (u2)));
3567 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
3568 uentry_getParams (u2)));
3569 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
3570 u2->info->fcn->specialCode));
3571 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
3572 u2->info->fcn->nullPred));
3574 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
3576 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
3577 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
3578 sRef_getOrigAliasKind (u2->sref)));
3579 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
3580 sRef_getOrigExKind (u2->sref)));
3581 COMPARERETURN (generic_compare (u1->info->var->checked,
3582 u2->info->var->checked));
3583 COMPARERETURN (generic_compare (u1->info->var->defstate,
3584 u2->info->var->defstate));
3585 return (generic_compare (u1->info->var->nullstate,
3586 u2->info->var->nullstate));
3588 COMPARERETURN (ctype_compare (u1->info->datatype->type,
3589 u2->info->datatype->type));
3590 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
3591 u2->info->datatype->mut));
3592 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
3601 ** all entries are: <type>[@<info>]*#<name>
3603 ** info depends on kind:
3607 advanceField (char **s)
3613 advanceName (char **s)
3619 vkind_fromInt (int i)
3621 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
3623 llbuglit ("vkind_fromInt: out of range");
3630 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
3631 typeIdSet access, nstate nullstate,
3632 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
3634 uentry e = uentry_alloc ();
3639 e->sref = sRef_makeConst (ct);
3641 sRef_setNullState (e->sref, nullstate, loc);
3642 e->storageclass = SCNONE;
3644 if (fileloc_isSpec (loc))
3646 e->whereSpecified = loc;
3647 e->whereDeclared = fileloc_undefined;
3651 e->whereSpecified = fileloc_undefined;
3652 e->whereDeclared = loc;
3655 e->whereDefined = fileloc_undefined;
3656 e->uses = filelocList_new ();
3657 e->isPrivate = FALSE;
3658 e->hasNameError = FALSE;
3663 e->info = (uinfo) dmalloc (sizeof (*e->info));
3664 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3665 e->info->uconst->val = m;
3666 e->info->uconst->access = access;
3668 sRef_storeState (e->sref);
3673 static /*@only@*/ uentry
3674 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
3675 sstate defstate, nstate isnull, alkind aliased,
3676 exkind exp, chkind checked,
3677 /*@only@*/ fileloc loc)
3679 uentry e = uentry_alloc ();
3684 e->storageclass = SCNONE;
3686 e->sref = sRef_makeType (ct);
3687 sRef_setNullState (e->sref, isnull, loc);
3689 e->whereDefined = fileloc_undefined;
3691 if (fileloc_isSpec (loc))
3693 e->whereSpecified = loc;
3694 e->whereDeclared = fileloc_undefined;
3698 e->whereSpecified = fileloc_undefined;
3699 e->whereDeclared = loc;
3702 e->isPrivate = FALSE;
3703 e->hasNameError = FALSE;
3708 e->uses = filelocList_new ();
3710 e->info = (uinfo) dmalloc (sizeof (*e->info));
3711 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3712 e->info->var->kind = kind;
3713 e->info->var->checked = checked;
3714 e->info->var->defstate = defstate;
3716 sRef_setDefState (e->sref, defstate, loc);
3718 e->info->var->nullstate = sRef_getNullState (e->sref);
3720 sRef_setExKind (e->sref, exp, loc);
3721 sRef_setAliasKind (e->sref, aliased, loc);
3723 sRef_storeState (e->sref);
3725 /*DRL ADDED 9-1-2000 */
3726 e->info->var->bufinfo = NULL;
3731 static /*@only@*/ uentry
3732 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abs,
3733 ynm mut, ctype rtype, alkind ak, exkind exp,
3734 sstate defstate, nstate isnull,
3735 /*@only@*/ fileloc loc)
3737 uentry e = uentry_alloc ();
3739 e->ukind = KDATATYPE;
3740 /* e->shallowCopy = FALSE; */
3743 e->storageclass = SCNONE;
3744 e->sref = sRef_makeUnknown ();
3747 ** This is only setting null state. (I think?)
3750 if (ctype_isUA (ct))
3752 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
3754 if (uentry_isValid (te))
3756 sRef_setStateFromUentry (e->sref, te);
3760 /* problem for recursive type definitions */
3764 sRef_setAliasKind (e->sref, ak, loc);
3765 sRef_setExKind (e->sref, exp, loc);
3767 sRef_setDefState (e->sref, defstate, loc);
3769 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
3771 isnull = NS_ABSNULL;
3774 sRef_mergeNullState (e->sref, isnull);
3776 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
3778 if (fileloc_isSpec (loc))
3780 e->whereSpecified = loc;
3781 e->whereDeclared = fileloc_undefined;
3785 e->whereSpecified = fileloc_undefined;
3786 e->whereDeclared = loc;
3789 e->isPrivate = FALSE;
3790 e->hasNameError = FALSE;
3794 e->uses = filelocList_new ();
3796 e->info = (uinfo) dmalloc (sizeof (*e->info));
3797 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3798 e->info->datatype->abs = abs;
3799 e->info->datatype->mut = mut;
3800 e->info->datatype->type = rtype;
3802 sRef_storeState (e->sref);
3808 static void uentry_setHasGlobs (uentry ue)
3810 llassert (uentry_isFunction (ue));
3812 ue->info->fcn->hasGlobs = TRUE;
3815 static void uentry_setHasMods (uentry ue)
3817 llassert (uentry_isFunction (ue));
3819 ue->info->fcn->hasMods = TRUE;
3823 bool uentry_hasGlobs (uentry ue)
3825 if (uentry_isFunction (ue))
3827 return (ue->info->fcn->hasGlobs);
3833 bool uentry_hasSpecialClauses (uentry ue)
3835 return (uentry_isFunction (ue) && specialClauses_isDefined (ue->info->fcn->specclauses));
3838 specialClauses uentry_getSpecialClauses (uentry ue)
3840 llassert (uentry_isFunction (ue));
3841 return ue->info->fcn->specclauses;
3844 bool uentry_hasMods (uentry ue)
3846 if (uentry_isFunction (ue))
3848 return (ue->info->fcn->hasMods);
3855 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
3857 bool hasGlobs, /*@only@*/ globSet globs,
3858 bool hasMods, /*@only@*/ sRefSet mods,
3859 alkind ak, exkind exp,
3860 sstate defstate, nstate isnull,
3864 /*@only@*/ specialClauses specclauses,
3865 /*@only@*/ fileloc loc)
3867 uentry e = uentry_alloc ();
3870 /* e->shallowCopy = FALSE; */
3874 e->storageclass = SCNONE;
3876 if (ctype_isFunction (ct))
3878 ret = ctype_returnValue (ct);
3882 if (ctype_isKnown (ct))
3884 llbug (message ("not function: %s", ctype_unparse (ct)));
3887 ret = ctype_unknown;
3890 e->sref = sRef_makeType (ret);
3892 if (ctype_isUA (ret))
3894 sRef_setStateFromType (e->sref, ret);
3897 sRef_setDefined (e->sref, loc);
3898 sRef_setNullState (e->sref, isnull, loc);
3900 sRef_setAliasKind (e->sref, ak, loc);
3901 sRef_setExKind (e->sref, exp, loc);
3902 sRef_setDefState (e->sref, defstate, loc);
3904 e->whereSpecified = loc;
3905 e->whereDefined = fileloc_undefined;
3907 e->isPrivate = FALSE;
3908 e->hasNameError = FALSE;
3912 e->uses = filelocList_new ();
3914 e->info = (uinfo) dmalloc (sizeof (*e->info));
3915 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
3917 e->info->fcn->exitCode = exitCode;
3918 e->info->fcn->specialCode = sCode;
3919 e->info->fcn->nullPred = nullPred;
3920 e->info->fcn->access = access;
3922 e->info->fcn->specclauses = specclauses;
3923 e->info->fcn->hasGlobs = hasGlobs;
3924 e->info->fcn->globs = globs;
3926 e->info->fcn->hasMods = hasMods;
3927 e->info->fcn->mods = mods;
3929 e->info->fcn->defparams = uentryList_undefined;
3930 e->whereDeclared = fileloc_undefined;
3932 sRef_storeState (e->sref);
3937 static /*@only@*/ uentry
3938 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
3939 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
3941 uentry e = uentry_alloc ();
3943 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
3945 llbuglit ("uentry_makeTagBase: not a tag type");
3948 /* e->shallowCopy = FALSE; */
3952 e->sref = sRef_makeUnknown ();
3953 e->storageclass = SCNONE;
3955 if (fileloc_isSpec (loc))
3957 e->whereSpecified = loc;
3958 e->whereDeclared = fileloc_undefined;
3962 e->whereDeclared = loc;
3963 e->whereSpecified = fileloc_undefined;
3966 e->whereDefined = fileloc_undefined;
3968 e->isPrivate = FALSE;
3969 e->hasNameError = FALSE;
3973 e->uses = filelocList_new ();
3975 e->info = (uinfo) dmalloc (sizeof (*e->info));
3976 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3977 e->info->datatype->abs = NO;
3978 e->info->datatype->mut = MAYBE;
3979 e->info->datatype->type = rtype;
3981 sRef_storeState (e->sref);
3987 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
3988 ctype ct, /*@only@*/ fileloc loc)
3990 uentry e = uentry_alloc ();
3992 /* e->shallowCopy = FALSE; */
3996 e->sref = sRef_makeUnknown ();
3997 e->storageclass = SCNONE;
3999 if (fileloc_isSpec (loc))
4001 e->whereSpecified = loc;
4002 e->whereDeclared = fileloc_undefined;
4006 e->whereDeclared = loc;
4007 e->whereSpecified = fileloc_undefined;
4010 e->whereDefined = fileloc_undefined;
4012 e->isPrivate = FALSE;
4013 e->hasNameError = FALSE;
4017 e->uses = filelocList_new ();
4019 e->info = (uinfo) dmalloc (sizeof (*e->info));
4020 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4021 e->info->iter->access = access;
4022 e->info->iter->mods = sRefSet_undefined;
4023 e->info->iter->globs = globSet_undefined;
4025 sRef_storeState (e->sref);
4030 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4031 /*@only@*/ fileloc loc)
4033 uentry e = uentry_alloc ();
4035 /* e->shallowCopy = FALSE; */
4036 e->ukind = KENDITER;
4037 e->storageclass = SCNONE;
4039 e->utype = ctype_unknown;
4040 e->sref = sRef_makeUnknown ();
4042 if (fileloc_isSpec (loc))
4044 e->whereSpecified = loc;
4045 e->whereDeclared = fileloc_undefined;
4049 e->whereDeclared = loc;
4050 e->whereSpecified = fileloc_undefined;
4053 e->whereDefined = fileloc_undefined;
4055 e->isPrivate = FALSE;
4056 e->hasNameError = FALSE;
4060 e->uses = filelocList_new ();
4062 e->info = (uinfo) dmalloc (sizeof (*e->info));
4063 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4064 e->info->enditer->access = access;
4065 sRef_storeState (e->sref);
4070 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4078 uentry_undump (ekind kind, fileloc loc, char **s)
4086 ue = uentry_makeElipsisMarker ();
4090 ctype ct = ctype_undump (s);
4106 if (optCheckChar (s, '@'))
4108 tkind = vkind_fromInt (getInt (s));
4116 if (optCheckChar (s, '$'))
4118 defstate = SS_UNKNOWN;
4119 isnull = NS_UNKNOWN;
4120 aliased = AK_IMPTEMP;
4122 checked = CH_UNKNOWN;
4124 else if (optCheckChar (s, '&'))
4126 defstate = SS_DEFINED;
4127 isnull = NS_UNKNOWN;
4128 aliased = AK_IMPTEMP;
4130 checked = CH_UNKNOWN;
4132 else if (optCheckChar (s, '^'))
4134 defstate = SS_UNKNOWN;
4135 isnull = NS_UNKNOWN;
4136 aliased = AK_IMPTEMP;
4138 checked = CH_UNKNOWN;
4142 defstate = sstate_fromInt (getInt (s));
4143 advanceField (s); isnull = nstate_fromInt (getInt (s));
4144 advanceField (s); aliased = alkind_fromInt (getInt (s));
4146 if (optCheckChar (s, '&'))
4149 checked = CH_UNKNOWN;
4153 advanceField (s); exp = exkind_fromInt (getInt (s));
4154 advanceField (s); checked = (chkind) (getInt (s));
4159 name = getStringWord (s);
4161 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4162 isnull, aliased, exp,
4163 checked, fileloc_copy (loc));
4176 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
4177 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
4178 advanceField (s); defstate = sstate_fromInt (getInt (s));
4179 advanceField (s); isnull = nstate_fromInt (getInt (s));
4180 advanceField (s); aliased = alkind_fromInt (getInt (s));
4181 advanceField (s); exp = exkind_fromInt (getInt (s));
4182 advanceField (s); rtype = ctype_undump (s);
4184 name = getStringWord (s);
4186 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
4187 aliased, exp, defstate, isnull,
4188 fileloc_copy (loc));
4205 specialClauses specclauses;
4207 if (optCheckChar (s, '$'))
4209 defstate = SS_DEFINED;
4210 isnull = NS_UNKNOWN;
4211 exitCode = XK_UNKNOWN;
4213 nullPred = QU_UNKNOWN;
4217 advanceField (s); defstate = sstate_fromInt (getInt (s));
4218 advanceField (s); isnull = nstate_fromInt (getInt (s));
4219 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
4220 advanceField (s); specc = specCode_fromInt (getInt (s));
4221 advanceField (s); nullPred = qual_fromInt (getInt (s));
4224 if (optCheckChar (s, '$'))
4227 globs = globSet_undefined;
4229 mods = sRefSet_undefined;
4231 else if (optCheckChar (s, '^'))
4234 globs = globSet_undefined;
4236 mods = sRefSet_undefined;
4240 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
4241 advanceField (s); globs = globSet_undump (s);
4242 advanceField (s); hasMods = bool_fromInt (getInt (s));
4243 advanceField (s); mods = sRefSet_undump (s);
4246 if (optCheckChar (s, '$'))
4253 advanceField (s); ak = alkind_fromInt (getInt (s));
4254 advanceField (s); exp = exkind_fromInt (getInt (s));
4257 advanceField (s); access = typeIdSet_undump (s);
4259 if (optCheckChar (s, '@'))
4261 specclauses = specialClauses_undump (s);
4265 specclauses = specialClauses_undefined;
4268 advanceName (s); name = getStringWord (s);
4270 ue = uentry_makeFunctionBase (name, ct, access,
4273 ak, exp, defstate, isnull,
4274 exitCode, specc, nullPred,
4276 fileloc_copy (loc));
4277 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4284 advanceField (s); access = typeIdSet_undump (s);
4285 advanceName (s); name = getStringWord (s);
4287 ue = uentry_makeIterBase (name, access, ct,
4288 fileloc_copy (loc));
4295 advanceField (s); access = typeIdSet_undump (s);
4296 advanceName (s); name = getStringWord (s);
4298 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4308 if (optCheckChar (s, '$'))
4310 val = multiVal_undefined;
4311 access = typeIdSet_undefined;
4312 nullstate = NS_UNKNOWN;
4316 advanceField (s); val = multiVal_undump (s);
4317 advanceField (s); access = typeIdSet_undump (s);
4318 advanceField (s); nullstate = nstate_fromInt (getInt (s));
4321 advanceName (s); name = getStringWord (s);
4323 ue = uentry_makeConstantBase (name, ct, access,
4324 nullstate, fileloc_copy (loc), val);
4333 advanceField (s); rtype = ctype_undump (s);
4334 advanceName (s); name = getStringWord (s);
4335 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4339 llcontbuglit ("uentry_undump: invalid");
4340 ue = uentry_undefined;
4343 llcontbuglit ("uentry_undump: elips marker");
4344 ue = uentry_undefined;
4353 uentry_dump (uentry v)
4355 return (uentry_dumpAux (v, FALSE));
4359 uentry_dumpParam (uentry v)
4361 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4362 ("dump: %s", uentry_unparseFull (v)));
4364 return (uentry_dumpAux (v, TRUE));
4368 uentry_dumpAux (uentry v, bool isParam)
4370 llassert (uentry_isValid (v));
4372 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
4377 llcontbuglit ("uentry_dump: invalid entry");
4378 return cstring_undefined;
4380 return (message ("!."));
4384 vkind vk = v->info->var->kind;
4385 sstate dss = sRef_getDefState (v->sref);
4386 nstate nst = sRef_getNullState (v->sref);
4387 alkind alk = sRef_getAliasKind (v->sref);
4388 exkind exk = sRef_getExKind (v->sref);
4389 chkind chk = v->info->var->checked;
4391 DPRINTF (("Dumping var"));
4393 if (dss == SS_UNKNOWN
4394 && nst == NS_UNKNOWN
4395 && alk == AK_IMPTEMP
4396 && exk == XO_UNKNOWN
4397 && chk == CH_UNKNOWN)
4399 sdump = cstring_makeLiteral ("$");
4401 else if (dss == SS_DEFINED
4402 && nst == NS_UNKNOWN
4403 && alk == AK_IMPTEMP
4404 && exk == XO_UNKNOWN
4405 && chk == CH_UNKNOWN)
4407 sdump = cstring_makeLiteral ("&");
4409 else if (dss == SS_UNKNOWN
4410 && nst == NS_UNKNOWN
4411 && alk == AK_UNKNOWN
4412 && exk == XO_UNKNOWN
4413 && chk == CH_UNKNOWN)
4415 sdump = cstring_makeLiteral ("^");
4417 else if (exk == XO_UNKNOWN
4418 && chk == CH_UNKNOWN)
4420 sdump = message ("%d@%d@%d&",
4427 sdump = message ("%d@%d@%d@%d@%d",
4438 return (message ("%q|@%d|%q#%s",
4439 ctype_dump (v->utype),
4442 isParam ? cstring_undefined : v->uname));
4446 return (message ("%q|%q#%s",
4447 ctype_dump (v->utype),
4449 isParam ? cstring_undefined : v->uname));
4454 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
4455 ctype_dump (v->utype),
4456 ynm_unparseCode (v->info->datatype->abs),
4457 ynm_unparseCode (v->info->datatype->mut),
4458 (int) sRef_getDefState (v->sref),
4459 (int) sRef_getNullState (v->sref),
4460 (int) sRef_getAliasKind (v->sref),
4461 (int) sRef_getExKind (v->sref),
4462 ctype_dump (v->info->datatype->type),
4466 cstring sdump, gdump, adump;
4467 alkind alk = sRef_getAliasKind (v->sref);
4468 exkind exk = sRef_getExKind (v->sref);
4470 if (sRef_getDefState (v->sref) == SS_DEFINED
4471 && !nstate_isKnown (sRef_getNullState (v->sref))
4472 && !exitkind_isKnown (v->info->fcn->exitCode)
4473 && v->info->fcn->specialCode == SPC_NONE
4474 && v->info->fcn->nullPred == QU_UNKNOWN)
4476 sdump = cstring_makeLiteral ("$");
4480 sdump = message ("@%d@%d@%d@%d@%d",
4481 (int) sRef_getDefState (v->sref),
4482 (int) sRef_getNullState (v->sref),
4483 (int) v->info->fcn->exitCode,
4484 (int) v->info->fcn->specialCode,
4485 (int) v->info->fcn->nullPred);
4488 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
4490 gdump = cstring_makeLiteral ("$");
4492 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
4493 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
4495 gdump = cstring_makeLiteral ("^");
4499 gdump = message ("@%s@%q@%s@%q",
4500 bool_dump (uentry_hasGlobs (v)),
4501 globSet_dump (uentry_getGlobs (v)),
4502 bool_dump (uentry_hasMods (v)),
4503 sRefSet_dump (uentry_getMods (v)));
4506 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
4508 adump = cstring_makeLiteral ("$");
4512 adump = message ("@%d@%d", (int) alk, (int) exk);
4515 if (uentry_hasSpecialClauses (v))
4517 return (message ("%q%q%q%q@%q@%q#%s",
4518 ctype_dump (v->utype),
4522 typeIdSet_dump (uentry_accessType (v)),
4523 specialClauses_dump (v->info->fcn->specclauses),
4528 return (message ("%q%q%q%q@%q#%s",
4529 ctype_dump (v->utype),
4533 typeIdSet_dump (uentry_accessType (v)),
4538 return (message ("%q@%q#%s",
4539 ctype_dump (v->utype),
4540 typeIdSet_dump (v->info->iter->access),
4543 return (message ("%q@%q#%s",
4544 ctype_dump (v->utype),
4545 typeIdSet_dump (uentry_accessType (v)),
4552 if (multiVal_isUnknown (v->info->uconst->val)
4553 && typeIdSet_isEmpty (uentry_accessType (v))
4554 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
4556 sdump = cstring_makeLiteral ("$");
4560 sdump = message ("@%q@%q@%d",
4561 multiVal_dump (v->info->uconst->val),
4562 typeIdSet_dump (uentry_accessType (v)),
4563 (int) sRef_getNullState (v->sref));
4566 return (message ("%q%q#%s",
4567 ctype_dump (v->utype),
4574 return (message ("%q@%q#%s",
4575 ctype_dump (v->utype),
4576 ctype_dump (v->info->datatype->type), v->uname));
4583 uentry_unparseAbbrev (uentry v)
4585 if (!uentry_isVariable (v))
4587 llcontbuglit ("uentry_unparseAbbrev: not variable");
4588 return uentry_unparse (v);
4591 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
4595 uentry_unparse (uentry v)
4599 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
4600 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
4602 st = uentry_getName (v);
4604 if (cstring_isDefined (st))
4606 return (ctype_unparseDeclaration (v->utype, st));
4611 return (cstring_copy (ctype_unparse (v->utype)));
4616 uentry_unparseFull (uentry v)
4618 if (uentry_isUndefined (v))
4620 return (cstring_makeLiteral ("<undefined>"));
4622 else if (uentry_isDatatype (v))
4624 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
4626 ekind_unparse (v->ukind),
4630 ctype_isDefined (v->info->datatype->type)
4631 ? v->info->datatype->type : ctype_unknown,
4632 ynm_unparse (v->info->datatype->mut),
4633 ynm_unparse (v->info->datatype->abs),
4634 sRef_unparseState (v->sref),
4635 fileloc_unparse (v->whereSpecified),
4636 fileloc_unparse (v->whereDefined)));
4638 else if (uentry_isFunction (v))
4640 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
4641 "globs: %q / [s: %q; decl: %q; def: %q]",
4643 ekind_unparse (v->ukind),
4646 sRef_unparseFull (v->sref),
4647 sRefSet_unparse (v->info->fcn->mods),
4648 globSet_unparse (v->info->fcn->globs),
4649 fileloc_unparse (v->whereSpecified),
4650 fileloc_unparse (v->whereDeclared),
4651 fileloc_unparse (v->whereDefined)));
4653 else if (uentry_isIter (v))
4655 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
4656 ekind_unparse (v->ukind),
4659 sRef_unparseFull (v->sref),
4660 fileloc_unparse (v->whereSpecified),
4661 fileloc_unparse (v->whereDefined)));
4663 else if (uentry_isVariable (v))
4666 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
4667 "kind <%d> isout <%d> used <%d>",
4668 checkedName (v->info->var->checked),
4670 ekind_unparse (v->ukind),
4673 sRef_unparseDeep (v->sref),
4674 fileloc_unparse (v->whereSpecified),
4675 fileloc_unparse (v->whereDefined),
4676 fileloc_unparse (v->whereDeclared),
4677 (int) v->info->var->kind,
4678 (int) v->info->var->defstate,
4683 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
4684 ekind_unparse (v->ukind),
4687 sRef_unparseFull (v->sref),
4688 fileloc_unparse (v->whereSpecified),
4689 fileloc_unparse (v->whereDefined)));
4694 bool uentry_hasAccessType (uentry e)
4696 if (uentry_isValid (e))
4701 return (!typeIdSet_isEmpty (e->info->iter->access));
4703 return (!typeIdSet_isEmpty (e->info->enditer->access));
4705 return (!typeIdSet_isEmpty (e->info->fcn->access));
4708 return (!typeIdSet_isEmpty (e->info->uconst->access));
4717 typeIdSet uentry_accessType (uentry e)
4719 if (uentry_isValid (e))
4724 return (e->info->iter->access);
4726 return (e->info->enditer->access);
4728 return (e->info->fcn->access);
4731 return (e->info->uconst->access);
4737 return typeIdSet_undefined;
4741 uentry_isVariable (uentry e)
4743 return (uentry_isVar (e));
4747 uentry_isSpecified (uentry e)
4749 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
4753 uentry_isReallySpecified (uentry e)
4755 return (uentry_isValid (e)
4756 && fileloc_isRealSpec (e->whereSpecified));
4760 uentry_isVar (uentry e)
4762 return (!uentry_isUndefined (e) && e->ukind == KVAR);
4766 uentry_isFakeTag (uentry e)
4768 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
4772 uentry_isDatatype (uentry e)
4774 return (!uentry_isUndefined (e) &&
4775 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
4776 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
4780 uentry_setAbstract (uentry e)
4784 llassert (uentry_isDatatype (e)
4785 && (ynm_isMaybe (e->info->datatype->abs)));
4787 oldid = ctype_typeId (e->info->datatype->type);
4788 e->info->datatype->abs = YES;
4789 e->info->datatype->type = ctype_createAbstract (oldid);
4793 uentry_setConcrete (uentry e)
4795 llassert (uentry_isDatatype (e)
4796 && (ynm_isMaybe (e->info->datatype->abs)));
4798 e->info->datatype->abs = NO;
4802 uentry_isAbstractDatatype (uentry e)
4804 return (uentry_isDatatype (e)
4805 && (ynm_isOn (e->info->datatype->abs)));
4809 uentry_isMaybeAbstract (uentry e)
4811 return (uentry_isDatatype (e)
4812 && (ynm_isMaybe (e->info->datatype->abs)));
4816 uentry_isMutableDatatype (uentry e)
4818 bool res = uentry_isDatatype (e)
4819 && (ynm_toBoolRelaxed (e->info->datatype->mut));
4825 uentry_isRefCountedDatatype (uentry e)
4827 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
4831 uentry_isParam (uentry u)
4833 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
4834 || u->info->var->kind == VKYIELDPARAM));
4838 uentry_isExpandedMacro (uentry u)
4840 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
4844 uentry_isSefParam (uentry u)
4846 return (uentry_isVariable (u)
4847 && (u->info->var->kind == VKSEFPARAM
4848 || u->info->var->kind == VKREFSEFPARAM
4849 || u->info->var->kind == VKSEFRETPARAM
4850 || u->info->var->kind == VKREFSEFRETPARAM));
4854 uentry_isRefParam (uentry u)
4856 return (uentry_isVariable (u)
4857 && (u->info->var->kind == VKREFPARAM
4858 || u->info->var->kind == VKREFYIELDPARAM
4859 || u->info->var->kind == VKREFSEFPARAM
4860 || u->info->var->kind == VKREFSEFRETPARAM));
4864 uentry_isAnyParam (uentry u)
4866 return (uentry_isVariable (u)
4867 && ((u->info->var->kind == VKPARAM)
4868 || (u->info->var->kind == VKSEFPARAM)
4869 || (u->info->var->kind == VKYIELDPARAM)
4870 || (u->info->var->kind == VKRETPARAM)
4871 || (u->info->var->kind == VKSEFRETPARAM)));
4875 uentry_getDefState (uentry u)
4877 if (uentry_isValid (u))
4879 return (sRef_getDefState (u->sref));
4883 return (SS_UNKNOWN);
4888 uentry_isOut (uentry u)
4890 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
4891 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4895 uentry_isPartial (uentry u)
4897 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
4898 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
4902 uentry_isStateSpecial (uentry u)
4904 return ((uentry_isVariable (u)
4905 && (u->info->var->defstate == SS_SPECIAL))
4906 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
4909 exitkind uentry_getExitCode (uentry ue)
4911 if (uentry_isFunction (ue))
4913 return ue->info->fcn->exitCode;
4922 uentry_nullPred (uentry u)
4924 llassert (uentry_isRealFunction (u));
4926 if (uentry_isFunction (u))
4928 return (u->info->fcn->nullPred);
4937 uentry_possiblyNull (uentry u)
4939 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
4940 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
4944 uentry_getAliasKind (uentry u)
4946 if (uentry_isValid (u))
4948 return (sRef_getAliasKind (uentry_getSref (u)));
4957 uentry_getExpKind (uentry u)
4959 if (uentry_isValid (u))
4961 return (sRef_getExKind (uentry_getSref (u)));
4970 uentry_isIter (uentry e)
4972 return (!uentry_isUndefined (e) && e->ukind == KITER);
4976 uentry_isEndIter (uentry e)
4978 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
4982 uentry_isRealFunction (uentry e)
4984 return (uentry_isFunction (e) ||
4985 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
4989 uentry_hasName (uentry e)
4991 if (uentry_isValid (e))
4993 cstring s = e->uname;
4995 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
5003 bool uentry_hasRealName (uentry e)
5005 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
5009 /*@observer@*/ globSet
5010 uentry_getGlobs (uentry l)
5012 if (uentry_isInvalid (l))
5014 return globSet_undefined;
5017 if (l->ukind != KFCN)
5019 if (l->ukind != KITER && l->ukind != KENDITER)
5021 if (l->ukind == KVAR)
5023 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5025 ekind_unparse (l->ukind)));
5029 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5031 ekind_unparse (l->ukind)));
5034 return globSet_undefined;
5037 return l->info->fcn->globs;
5040 /*@observer@*/ sRefSet
5041 uentry_getMods (uentry l)
5043 llassert (uentry_isValid (l));
5045 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5047 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5048 return sRefSet_undefined;
5051 return l->info->fcn->mods;
5055 uentry_getKind (uentry e)
5057 llassert (uentry_isValid (e));
5062 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5064 llassert (uentry_isEitherConstant (e));
5066 return (e->info->uconst->val);
5069 /*@observer@*/ uentryList
5070 uentry_getParams (uentry l)
5072 if (uentry_isInvalid (l)) return uentryList_undefined;
5079 ctype ct = l->utype;
5081 if (ctype_isFunction (ct))
5083 return (ctype_argsFunction (ct));
5087 return uentryList_undefined;
5092 ctype ct = l->utype;
5094 llassert (ctype_isFunction (ct));
5095 return (ctype_argsFunction (ct));
5102 /*@observer@*/ cstring
5103 uentry_rawName (uentry e)
5105 if (uentry_isValid (e))
5111 return cstring_undefined;
5116 uentry_getOptName (uentry e)
5118 cstring s = uentry_getName (e);
5120 if (cstring_isDefined (s))
5122 s = cstring_appendChar (s, ' ');
5129 uentry_getName (uentry e)
5131 cstring ret = cstring_undefined;
5133 if (uentry_isValid (e))
5136 if (uentry_isAnyTag (e))
5138 ret = fixTagName (e->uname);
5140 else if (uentry_isAnyParam (e))
5142 ret = cstring_copy (fixParamName (e->uname));
5146 ret = cstring_copy (e->uname);
5153 cstring uentry_getRealName (uentry e)
5155 if (uentry_isValid (e))
5157 if (uentry_isAnyTag (e))
5159 return (cstring_undefined);
5166 return cstring_undefined;
5169 ctype uentry_getType (uentry e)
5171 if (uentry_isValid (e))
5177 return ctype_unknown;
5181 fileloc uentry_whereLast (uentry e)
5185 if (uentry_isInvalid (e))
5187 return fileloc_undefined;
5190 loc = e->whereDefined;
5192 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5197 loc = uentry_whereDeclared (e);
5199 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5204 loc = uentry_whereSpecified (e);
5208 fileloc uentry_whereEither (uentry e)
5210 if (uentry_isInvalid (e)) return fileloc_undefined;
5212 if (fileloc_isDefined (e->whereDefined)
5213 && !fileloc_isExternal (e->whereDefined))
5215 return e->whereDefined;
5217 else if (fileloc_isDefined (e->whereDeclared))
5219 return e->whereDeclared;
5223 return e->whereSpecified;
5227 fileloc uentry_whereSpecified (uentry e)
5229 if (uentry_isInvalid (e)) return fileloc_undefined;
5231 return (e->whereSpecified);
5234 fileloc uentry_whereDefined (uentry e)
5236 if (uentry_isInvalid (e)) return fileloc_undefined;
5238 return (e->whereDefined);
5241 fileloc uentry_whereDeclared (uentry e)
5243 if (uentry_isInvalid (e)) return fileloc_undefined;
5245 return (e->whereDeclared);
5248 /*@observer@*/ fileloc
5249 uentry_whereEarliest (uentry e)
5251 if (uentry_isInvalid (e)) return fileloc_undefined;
5253 if (fileloc_isDefined (e->whereSpecified))
5255 return (e->whereSpecified);
5257 else if (fileloc_isDefined (e->whereDeclared))
5259 return (e->whereDeclared);
5263 return e->whereDefined;
5268 uentry_setFunctionDefined (uentry e, fileloc loc)
5270 if (uentry_isValid (e))
5272 llassert (uentry_isFunction (e));
5274 if (fileloc_isUndefined (e->whereDeclared))
5276 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5279 if (!fileloc_isDefined (e->whereDefined))
5281 e->whereDefined = fileloc_update (e->whereDefined, loc);
5287 uentry_setDeclDef (uentry e, fileloc f)
5289 uentry_setDeclared (e, f);
5291 if (!uentry_isFunction (e)
5292 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5294 uentry_setDefined (e, f);
5299 uentry_setDeclaredForce (uentry e, fileloc f)
5301 llassert (uentry_isValid (e));
5302 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5306 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5308 llassert (uentry_isValid (e));
5309 fileloc_free (e->whereDeclared);
5310 e->whereDeclared = f;
5314 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5318 llassert (uentry_isValid (e));
5319 oldloc = e->whereDeclared;
5321 if (fileloc_isDefined (oldloc))
5323 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5325 e->whereDeclared = f;
5326 fileloc_free (oldloc);
5335 e->whereDeclared = f;
5336 fileloc_free (oldloc);
5341 uentry_setDeclared (uentry e, fileloc f)
5345 llassert (uentry_isValid (e));
5346 oldloc = e->whereDeclared;
5348 if (fileloc_isDefined (oldloc))
5350 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5352 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5361 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5366 uentry_clearDefined (uentry e)
5368 if (uentry_isValid (e))
5370 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5375 uentry_setDefined (uentry e, fileloc f)
5379 llassert (uentry_isValid (e));
5380 oldloc = e->whereDefined;
5382 if (fileloc_isDefined (oldloc))
5384 if (fileloc_isLib (oldloc)
5385 || fileloc_isImport (oldloc)
5386 || fileloc_isBuiltin (oldloc)
5387 || fileloc_isPreproc (oldloc))
5389 e->whereDefined = fileloc_update (e->whereDefined, f);
5393 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5399 if (optgenerror (FLG_REDEF,
5400 message ("%s %q redefined",
5401 ekind_capName (e->ukind),
5402 uentry_getName (e)),
5405 llgenindentmsg (message ("Previous definition of %q",
5406 uentry_getName (e)),
5414 e->whereDefined = fileloc_update (e->whereDefined, f);
5419 uentry_isCodeDefined (uentry e)
5421 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
5425 uentry_isDeclared (uentry e)
5427 if (uentry_isValid (e))
5429 return (fileloc_isDefined (e->whereDeclared));
5435 sRef uentry_getSref (uentry e)
5437 /* not true, used for functions too (but shouldn't be? */
5438 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
5440 if (uentry_isInvalid (e)) return sRef_undefined;
5445 sRef uentry_getOrigSref (uentry e)
5447 if (uentry_isValid (e))
5449 sRef sr = sRef_copy (uentry_getSref (e));
5451 sRef_resetState (sr);
5452 sRef_clearDerived (sr);
5454 if (uentry_isVariable (e))
5456 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
5457 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
5464 return sRef_undefined;
5469 ** requires: uentry e is not in a hashed symbol table
5473 uentry_setName (uentry e, /*@only@*/ cstring n)
5475 llassert (uentry_isValid (e));
5477 cstring_free (e->uname);
5482 uentry_setType (uentry e, ctype t)
5484 if (uentry_isValid (e))
5487 sRef_setType (e->sref, t);
5492 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
5495 ctype rettype = ctype_unknown;
5497 llassert (uentry_isValid (ue));
5499 rct = ctype_realType (ue->utype);
5501 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
5503 uentry_makeVarFunction (ue);
5506 llassert (uentry_isFunction (ue));
5508 if (ctype_isFunction (rct))
5510 rettype = ctype_returnValue (rct);
5513 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
5517 uentry_setRefParam (uentry e)
5520 if (!uentry_isVar (e))
5522 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5526 if (e->info->var->kind == VKSEFPARAM)
5528 e->info->var->kind = VKREFSEFPARAM;
5530 else if (e->info->var->kind == VKSEFRETPARAM)
5532 e->info->var->kind = VKREFSEFRETPARAM;
5534 else if (e->info->var->kind == VKYIELDPARAM)
5536 e->info->var->kind = VKREFYIELDPARAM;
5540 e->info->var->kind = VKREFPARAM;
5546 uentry_setParam (uentry e)
5548 if (!uentry_isVar (e))
5550 if (uentry_isElipsisMarker (e))
5556 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5563 if (e->info->var->kind == VKYIELDPARAM
5564 || e->info->var->kind == VKSEFPARAM
5565 || e->info->var->kind == VKSEFRETPARAM)
5571 e->info->var->kind = VKPARAM;
5575 e->uname = makeParam (e->uname);
5576 cstring_free (oldname);
5581 uentry_setSref (uentry e, sRef s)
5583 if (uentry_isValid (e))
5585 if (sRef_isValid (e->sref))
5587 sRef_mergeStateQuietReverse (e->sref, s);
5591 e->sref = sRef_saveCopy (s);
5597 uentry_getAbstractType (uentry e)
5599 llassert (uentry_isDatatype (e));
5602 ** This assertion removed.
5603 ** Okay to have undefined type, for system types
5605 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
5606 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
5611 if (ctype_isUndefined (e->info->datatype->type))
5613 return ctype_unknown;
5617 ** Sadly, a kludge...
5620 if (ctype_isUserBool (e->info->datatype->type)) {
5624 return e->info->datatype->type;
5627 ctype uentry_getRealType (uentry e)
5630 typeId uid = USYMIDINVALID;
5632 if (uentry_isInvalid (e))
5634 return ctype_unknown;
5637 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5639 if (uentry_isAnyTag (e))
5644 if (uentry_isAbstractType (e))
5646 ct = uentry_getAbstractType (e);
5648 if (ctype_isManifestBool (ct)) {
5652 llassert (ctype_isUA (ct));
5654 uid = ctype_typeId (ct);
5656 if (!context_hasAccess (uid))
5662 ct = uentry_getType (e);
5664 /* if (ctype_isUserBool (ct)) return ct; */
5666 if (ctype_isManifestBool (ct)) {
5670 if (ctype_isUA (ct))
5672 usymId iid = ctype_typeId (ct);
5674 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5676 llcontbug (message ("uentry_getRealType: recursive type! %s",
5677 ctype_unparse (ct)));
5682 /* evs 2000-07-25: possible infinite recursion ? */
5683 uentry ue2 = usymtab_getTypeEntry (iid);
5684 llassertprint (ue2 != e, ("Bad recursion: %s", uentry_unparseFull (e)));
5686 return uentry_getRealType (ue2);
5695 ctype uentry_getForceRealType (uentry e)
5698 typeId uid = USYMIDINVALID;
5700 if (uentry_isInvalid (e))
5702 return ctype_unknown;
5705 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5707 if (uentry_isAnyTag (e))
5712 if (uentry_isAbstractType (e))
5714 ct = uentry_getAbstractType (e);
5715 llassert (ctype_isUA (ct));
5717 uid = ctype_typeId (ct);
5718 /* no check for access! */
5721 ct = uentry_getType (e);
5723 /* evs 2000-07-25 */
5724 /* if (ctype_isUserBool (ct)) return ct; */
5726 if (ctype_isManifestBool (ct)) {
5730 if (ctype_isUA (ct))
5732 usymId iid = ctype_typeId (ct);
5734 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5736 llcontbug (message ("uentry_getRealType: recursive type! %s",
5737 ctype_unparse (ct)));
5742 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
5751 uentry uentry_nameCopy (cstring name, uentry e)
5753 uentry enew = uentry_alloc ();
5755 llassert (uentry_isValid (e));
5757 /* enew->shallowCopy = FALSE; */
5758 enew->ukind = e->ukind;
5760 enew->utype = e->utype;
5761 enew->whereSpecified = fileloc_copy (e->whereSpecified);
5762 enew->whereDefined = fileloc_copy (e->whereDefined);
5763 enew->whereDeclared = fileloc_copy (e->whereDeclared);
5764 enew->sref = sRef_copy (e->sref);
5765 enew->used = e->used;
5767 enew->isPrivate = e->isPrivate;
5768 enew->hasNameError = FALSE;
5770 enew->uses = filelocList_new ();
5772 enew->storageclass = e->storageclass;
5773 enew->info = uinfo_copy (e->info, e->ukind);
5779 uentry_setDatatype (uentry e, usymId uid)
5781 llassert (uentry_isDatatype (e));
5783 if (uentry_isAbstractType (e))
5785 e->info->datatype->type = ctype_createAbstract (uid);
5789 e->info->datatype->type = ctype_createUser (uid);
5794 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
5795 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
5798 llassert (uentry_isValid (e));
5800 if (fileloc_isSpec (f) || fileloc_isImport (f))
5802 e->whereSpecified = f;
5803 e->whereDeclared = fileloc_undefined;
5804 e->whereDefined = fileloc_undefined;
5808 e->whereSpecified = fileloc_undefined;
5809 e->whereDeclared = f;
5810 e->whereDefined = fileloc_undefined;
5815 ucinfo_free (/*@only@*/ ucinfo u)
5817 multiVal_free (u->val);
5822 uvinfo_free (/*@only@*/ uvinfo u)
5828 udinfo_free (/*@only@*/ udinfo u)
5834 ufinfo_free (/*@only@*/ ufinfo u)
5836 globSet_free (u->globs);
5837 sRefSet_free (u->mods);
5838 specialClauses_free (u->specclauses);
5844 uiinfo_free (/*@only@*/ uiinfo u)
5850 ueinfo_free (/*@only@*/ ueinfo u)
5855 static /*@only@*/ ucinfo
5856 ucinfo_copy (ucinfo u)
5858 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
5860 ret->val = multiVal_copy (u->val);
5861 ret->access = u->access;
5866 static /*@only@*/ uvinfo
5867 uvinfo_copy (uvinfo u)
5869 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
5871 ret->kind = u->kind;
5872 ret->nullstate = u->nullstate;
5873 ret->defstate = u->defstate;
5874 ret->checked = u->checked;
5876 //ret->bufinfo = u->bufinfo;
5877 /*@i334@*/ return ret;
5880 static /*@only@*/ udinfo
5881 udinfo_copy (udinfo u)
5883 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
5887 ret->type = u->type;
5892 static /*@only@*/ ufinfo
5893 ufinfo_copy (ufinfo u)
5895 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
5897 ret->hasGlobs = u->hasGlobs;
5898 ret->hasMods = u->hasMods;
5899 ret->exitCode = u->exitCode;
5900 ret->specialCode = u->specialCode;
5901 ret->nullPred = u->nullPred;
5902 ret->access = u->access;
5903 ret->globs = globSet_newCopy (u->globs);
5904 ret->mods = sRefSet_newCopy (u->mods);
5905 ret->defparams = u->defparams;
5906 ret->specclauses = specialClauses_copy (u->specclauses);
5911 static /*@only@*/ uiinfo
5912 uiinfo_copy (uiinfo u)
5914 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
5916 ret->access = u->access;
5917 ret->globs = globSet_newCopy (u->globs);
5918 ret->mods = sRefSet_newCopy (u->mods);
5923 static /*@only@*/ ueinfo
5924 ueinfo_copy (ueinfo u)
5926 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
5928 ret->access = u->access;
5933 uinfo_free (uinfo u, ekind kind)
5938 case KCONST: ucinfo_free (u->uconst); break;
5939 case KVAR: uvinfo_free (u->var); break;
5943 case KDATATYPE: udinfo_free (u->datatype); break;
5944 case KFCN: ufinfo_free (u->fcn); break;
5945 case KITER: uiinfo_free (u->iter); break;
5946 case KENDITER: ueinfo_free (u->enditer); break;
5947 case KELIPSMARKER: break;
5948 case KINVALID: break;
5954 static /*@only@*/ /*@null@*/ uinfo
5955 uinfo_copy (uinfo u, ekind kind)
5957 if (kind == KELIPSMARKER || kind == KINVALID)
5963 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
5968 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
5969 case KVAR: ret->var = uvinfo_copy (u->var); break;
5973 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
5974 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
5975 case KITER: ret->iter = uiinfo_copy (u->iter); break;
5976 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
5984 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
5986 filelocList_free (e->uses);
5987 cstring_free (e->uname);
5989 uinfo_free (e->info, e->ukind);
5991 fileloc_free (e->whereSpecified);
5992 fileloc_free (e->whereDefined);
5993 fileloc_free (e->whereDeclared);
5999 extern void uentry_markOwned (/*@owned@*/ uentry u)
6001 sfreeEventually (u);
6005 uentry_free (/*@only@*/ uentry e)
6007 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6009 uentry_reallyFree (e);
6014 ** For uentry's in the global or file scope
6018 uentry_freeComplete (/*@only@*/ uentry e)
6020 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6022 /*@i@*/ sRef_free (e->sref);
6023 e->sref = sRef_undefined;
6024 uentry_reallyFree (e);
6029 ** requires old->kind != new->kind, old->uname = new->uname
6033 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6035 llassert (uentry_isValid (old));
6036 llassert (uentry_isValid (unew));
6038 if (uentry_isEitherConstant (unew)
6039 && (fileloc_isPreproc (uentry_whereDeclared (old))
6040 || ctype_isUnknown (old->utype))
6041 && !uentry_isSpecified (old))
6049 if (!uentry_isDeclared (old))
6051 if (uentry_isSpecified (old))
6053 if (uentry_isSpecified (unew))
6055 llbuglit ("Respecification!");
6057 else if (uentry_isDeclared (unew))
6061 message ("%s %q inconsistently declared as %s: %t",
6062 ekind_capName (old->ukind),
6063 uentry_getName (unew),
6064 ekind_unparseLong (unew->ukind),
6066 uentry_whereDeclared (unew)))
6068 uentry_showWhereLast (old);
6080 message ("%s %q inconsistently declared as %s: %t",
6081 ekind_capName (old->ukind),
6082 uentry_getName (unew),
6083 ekind_unparseLong (unew->ukind),
6085 uentry_whereDeclared (unew)))
6087 uentry_showWhereLast (old);
6093 llassert (uentry_isDeclared (unew));
6097 message ("%s %q inconsistently redeclared as %s",
6098 ekind_capName (old->ukind),
6099 uentry_getName (unew),
6100 ekind_unparseLong (unew->ukind)),
6101 uentry_whereDeclared (unew)))
6103 uentry_showWhereLast (old);
6109 uentry_copyInto (old, unew);
6113 ** def is the definition of spec, modifies spec
6115 ** reports any inconsistencies
6116 ** returns the summary of all available information
6117 ** if spec and def are inconsistent, def is returned
6121 uentry_showWhereLast (uentry spec)
6123 if (uentry_isValid (spec))
6125 if (fileloc_isDefined (spec->whereDefined)
6126 && !fileloc_isLib (spec->whereDefined)
6127 && !fileloc_isPreproc (spec->whereDefined))
6129 llgenindentmsg (message ("Previous definition of %q: %t",
6130 uentry_getName (spec),
6131 uentry_getType (spec)),
6132 uentry_whereDefined (spec));
6134 else if (uentry_isDeclared (spec))
6136 llgenindentmsg (message ("Previous declaration of %q: %t",
6137 uentry_getName (spec),
6138 uentry_getType (spec)),
6139 uentry_whereDeclared (spec));
6141 else if (uentry_isSpecified (spec))
6143 if (uentry_hasName (spec))
6145 llgenindentmsg (message ("Specification of %q: %t",
6146 uentry_getName (spec),
6147 uentry_getType (spec)),
6148 uentry_whereSpecified (spec));
6152 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6153 uentry_whereSpecified (spec));
6158 /* nothing to show */
6164 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6166 fileloc loc = uentry_whereDefined (ce);
6168 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6170 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6174 loc = uentry_whereSpecified (ce);
6176 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6178 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6183 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6185 if (uentry_isDeclared (spec))
6187 llgenindentmsg (message ("Previous declaration of %q: %q",
6188 uentry_getName (spec), extra),
6189 uentry_whereDeclared (spec));
6191 else if (uentry_isSpecified (spec))
6193 llgenindentmsg (message ("Specification of %q: %q",
6194 uentry_getName (spec), extra),
6195 uentry_whereSpecified (spec));
6199 cstring_free (extra);
6204 uentry_showWhereDeclared (uentry spec)
6206 if (uentry_isDeclared (spec))
6208 if (uentry_hasName (spec))
6210 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6211 uentry_whereDeclared (spec));
6215 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6218 else if (uentry_isSpecified (spec))
6220 if (uentry_hasName (spec))
6222 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6223 uentry_whereSpecified (spec));
6227 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6232 /* nothing to show */
6238 uentry_showWhereAny (uentry spec)
6240 if (uentry_isDeclared (spec))
6242 if (uentry_hasName (spec))
6244 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6245 uentry_whereDeclared (spec));
6249 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6252 else if (uentry_isSpecified (spec))
6254 if (uentry_hasName (spec))
6256 llgenindentmsg (message ("Specification of %q",
6257 uentry_getName (spec)),
6258 uentry_whereSpecified (spec));
6262 llgenindentmsg (cstring_makeLiteral ("Specification"),
6263 uentry_whereSpecified (spec));
6266 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6268 if (uentry_hasName (spec))
6270 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6271 uentry_whereDefined (spec));
6275 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6280 /* nothing to show */
6285 uentry_showWhereDefined (uentry spec)
6287 if (uentry_isCodeDefined (spec))
6289 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6290 uentry_whereDefined (spec));
6295 uentry_showWhereLastPlain (uentry spec)
6297 if (uentry_isDeclared (spec))
6299 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6300 uentry_whereDeclared (spec));
6302 else if (uentry_isSpecified (spec))
6304 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6305 uentry_whereSpecified (spec));
6313 uentry_showWhereLastVal (uentry spec, cstring val)
6315 if (uentry_isDeclared (spec))
6317 llgenindentmsg (message ("Previous declaration of %q: %s",
6318 uentry_getName (spec), val),
6319 uentry_whereDeclared (spec));
6321 else if (uentry_isSpecified (spec))
6323 llgenindentmsg (message ("Specification of %q: %s",
6324 uentry_getName (spec), val),
6325 uentry_whereSpecified (spec));
6333 uentry_showWhereSpecified (uentry spec)
6335 if (uentry_isSpecified (spec))
6337 if (uentry_hasName (spec))
6339 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6340 uentry_whereSpecified (spec));
6344 llgenindentmsg (cstring_makeLiteral ("Specification"),
6345 uentry_whereSpecified (spec));
6348 else if (uentry_isDeclared (spec))
6350 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6351 uentry_whereDeclared (spec));
6355 /* nothing to show */
6360 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6362 if (uentry_isSpecified (spec))
6364 if (uentry_hasName (spec))
6366 llgenindentmsg (message ("Specification of %q: %q",
6367 uentry_getName (spec), s),
6368 uentry_whereSpecified (spec));
6372 llgenindentmsg (message ("Specification: %q", s),
6373 uentry_whereSpecified (spec));
6376 else if (uentry_isDeclared (spec))
6378 llgenindentmsg (message ("Declaration of %q: %q",
6379 uentry_getName (spec), s),
6380 uentry_whereDeclared (spec));
6384 llgenindentmsg (message ("Previous: %q", s),
6385 uentry_whereLast (spec));
6394 checkStructConformance (uentry old, uentry unew)
6397 uentryList fold, fnew;
6400 ** requires: types of old and new are structs or unions
6403 llassert (uentry_isValid (old));
6404 llassert (uentry_isValid (unew));
6406 oldr = ctype_realType (old->utype);
6407 fold = ctype_getFields (oldr);
6409 newr = ctype_realType (unew->utype);
6410 fnew = ctype_getFields (newr);
6412 if (!uentryList_matchFields (fold, fnew))
6414 if (fileloc_equal (uentry_whereLast (old),
6415 uentry_whereLast (unew)))
6423 message ("%q %q %rdeclared with fields { %q }, %s "
6424 "with fields { %q }",
6425 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
6426 uentry_getName (old),
6427 uentry_isDeclared (old),
6428 uentryList_unparseAbbrev (fnew),
6429 uentry_specOrDefName (old),
6430 uentryList_unparseAbbrev (fold)),
6431 uentry_whereDeclared (unew)))
6433 uentry_showWhereLastPlain (old);
6434 uentryList_showFieldDifference (fold, fnew);
6438 old->utype = unew->utype;
6443 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6446 ** requires old and new are enums
6449 ctype rold = ctype_realType (old->utype);
6450 ctype rnew = ctype_realType (unew->utype);
6451 enumNameList eold = ctype_elist (rold);
6452 enumNameList enew = ctype_elist (rnew);
6454 if (!enumNameList_match (eold, enew))
6458 message ("Enum %q declared with members { %q } but "
6459 "specified with members { %q }",
6460 uentry_getName (old),
6461 enumNameList_unparse (enew),
6462 enumNameList_unparse (eold)),
6463 uentry_whereDeclared (unew)))
6465 uentry_showWhereSpecified (old);
6466 old->utype = unew->utype;
6472 ** either oldCurrent or newCurrent may be undefined!
6476 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
6477 uentry unew, uentry newCurrent, ctype newType,
6480 bool hasError = FALSE;
6482 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
6484 if (uentry_hasName (newCurrent))
6486 hasError = optgenerror
6488 message ("Parameter %d, %q, of function %q has inconsistent type: "
6489 "declared %t, %s %t",
6490 paramno + 1, uentry_getName (newCurrent),
6491 uentry_getName (unew),
6492 newType, uentry_specOrDefName (old), oldType),
6493 uentry_whereDeclared (newCurrent));
6497 hasError = optgenerror
6499 message ("Parameter %d of function %q has inconsistent type: "
6500 "declared %t, %s %t",
6501 paramno + 1, uentry_getName (unew),
6502 newType, uentry_specOrDefName (old), oldType),
6503 uentry_whereDeclared (newCurrent));
6505 DPRINTF (("type: %s / %s",
6506 ctype_unparse (newType),
6507 ctype_unparse (ctype_realType (newType))));
6512 if (uentry_isDeclared (unew))
6514 hasError = optgenerror
6516 message ("Parameter %d of function %s has inconsistent type: "
6517 "declared %t, %s %t",
6518 paramno + 1, unew->uname,
6519 newType, uentry_specOrDefName (old), oldType),
6520 uentry_whereDeclared (unew));
6524 hasError = optgenerror
6526 message ("Parameter %d of function %s has inconsistent type: "
6527 "declared %t, %s %t",
6528 paramno + 1, unew->uname,
6529 newType, uentry_specOrDefName (old), oldType),
6530 uentry_whereDeclared (unew));
6536 if (!uentry_isUndefined (oldCurrent))
6538 if (!uentry_isUndefined (newCurrent)
6539 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
6541 uentry_showWhereLast (oldCurrent);
6545 uentry_showWhereLastPlain (old);
6548 uentry_setType (oldCurrent, newType);
6552 uentry_showWhereLastPlain (old);
6558 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6562 message ("Function %s %rdeclared with %d arg%p, %s with %d",
6564 uentry_isDeclared (old),
6565 uentryList_size (uentry_getParams (unew)),
6566 uentry_specOrDefName (old),
6567 uentryList_size (uentry_getParams (old))),
6568 uentry_whereDeclared (unew)))
6570 uentry_showWhereLastPlain (old);
6575 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6579 message ("Function %s inconsistently %rdeclared to return %t",
6581 uentry_isDeclared (old),
6582 ctype_returnValue (unew->utype)),
6583 uentry_whereDeclared (unew)))
6585 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
6589 static cstring paramStorageName (uentry ue)
6591 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
6594 static cstring fcnErrName (uentry ue)
6596 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
6599 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
6601 if (uentry_isVar (ue))
6603 return (checkedName (ue->info->var->checked));
6607 return (cstring_makeLiteralTemp ("<checked invalid>"));
6611 static cstring checkedName (chkind checked)
6615 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
6616 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
6617 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
6618 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
6619 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
6625 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
6630 if (uentry_isVar (unew))
6632 llassert (uentry_isVar (old));
6634 oldState = old->info->var->nullstate;
6635 newState = unew->info->var->nullstate;
6639 oldState = sRef_getNullState (old->sref);
6640 newState = sRef_getNullState (unew->sref);
6643 if (oldState == NS_ABSNULL)
6645 if (uentry_isVar (old))
6647 old->info->var->nullstate = newState;
6650 sRef_mergeNullState (old->sref, newState);
6652 else if (newState == NS_UNKNOWN)
6654 if (completeConform && newState != oldState
6655 && uentry_isReallySpecified (old))
6659 message ("%s %q specified as %s, but declared without %s qualifier",
6660 ekind_capName (unew->ukind),
6661 uentry_getName (unew),
6662 nstate_unparse (oldState),
6663 nstate_unparse (oldState)),
6664 uentry_whereDeclared (unew)))
6666 uentry_showWhereSpecified (old);
6670 if (uentry_isVar (unew))
6672 unew->info->var->nullstate = oldState;
6675 sRef_mergeNullState (unew->sref, oldState);
6677 else if (newState == NS_POSNULL)
6679 if (oldState == NS_MNOTNULL
6680 && (ctype_isUA (unew->utype)
6681 || (uentry_isFunction (unew)
6682 && ctype_isUA (ctype_returnValue (unew->utype)))))
6684 if (uentry_isVar (unew))
6686 unew->info->var->nullstate = oldState;
6689 sRef_mergeNullState (unew->sref, oldState);
6693 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
6694 || oldState == NS_UNKNOWN)
6701 ("%s %q inconsistently %rdeclared %s possibly null storage, "
6703 uentry_ekindName (unew),
6704 uentry_getName (unew),
6705 uentry_isDeclared (old),
6707 uentry_specOrDefName (old),
6708 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
6709 uentry_whereDeclared (unew)))
6711 uentry_showWhereSpecified (old);
6716 if (uentry_isVar (old))
6718 old->info->var->nullstate = newState;
6721 sRef_mergeNullState (old->sref, newState);
6724 else if (newState == NS_MNOTNULL)
6726 if (oldState != NS_MNOTNULL)
6732 message ("%s %q inconsistently %rdeclared %s notnull storage, "
6733 "%s without notnull qualifier",
6734 uentry_ekindName (unew),
6735 uentry_getName (unew),
6736 uentry_isDeclared (old),
6738 uentry_specOrDefName (old)),
6739 uentry_whereDeclared (unew)))
6741 uentry_showWhereSpecified (old);
6745 if (uentry_isVar (old))
6747 old->info->var->nullstate = newState;
6750 sRef_mergeNullState (old->sref, newState);
6755 if (uentry_isVar (unew))
6757 unew->info->var->nullstate = oldState;
6760 sRef_mergeNullState (unew->sref, oldState);
6765 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6766 bool mustConform, bool completeConform)
6772 if (uentry_isVar (old) && uentry_isVar (unew))
6774 oldState = old->info->var->defstate;
6775 newState = unew->info->var->defstate;
6780 oldState = sRef_getDefState (old->sref);
6781 newState = sRef_getDefState (unew->sref);
6784 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
6790 message ("%s %q inconsistently %rdeclared %s %s %s, "
6792 uentry_ekindName (unew),
6793 uentry_getName (unew),
6794 uentry_isDeclared (old),
6796 sstate_unparse (newState),
6797 paramStorageName (unew),
6798 uentry_specOrDefName (old),
6800 sstate_unparse (oldState),
6801 paramStorageName (unew)),
6802 uentry_whereDeclared (unew)))
6804 uentry_showWhereSpecified (old);
6808 if (vars) old->info->var->defstate = newState;
6809 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
6814 && (newState != oldState) && (oldState != SS_DEFINED)
6815 && uentry_isReallySpecified (old))
6819 message ("%s %q specified as %s, but declared without %s qualifier",
6820 ekind_capName (unew->ukind),
6821 uentry_getName (unew),
6822 sstate_unparse (oldState),
6823 sstate_unparse (oldState)),
6824 uentry_whereDeclared (unew)))
6826 uentry_showWhereSpecified (old);
6830 if (vars) unew->info->var->defstate = oldState;
6831 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
6836 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6837 bool mustConform, bool completeConform)
6842 oldKind = sRef_getAliasKind (old->sref);
6843 newKind = sRef_getAliasKind (unew->sref);
6845 if (alkind_isImplicit (newKind)
6846 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
6848 if (completeConform && !alkind_equal (newKind, oldKind)
6849 && uentry_isReallySpecified (old))
6853 message ("%s %q specified as %s, but declared without "
6854 "explicit alias qualifier",
6855 ekind_capName (unew->ukind),
6856 uentry_getName (unew),
6857 alkind_unparse (oldKind)),
6858 uentry_whereDeclared (unew)))
6860 uentry_showWhereSpecified (old);
6865 ** This really shouldn't be necessary, but it is!
6866 ** Function params (?) use new here.
6869 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
6873 if (alkind_isKnown (newKind))
6875 if (!alkind_equal (oldKind, newKind))
6877 if (alkind_isKnown (oldKind))
6882 message ("%s %q inconsistently %rdeclared %s %s storage, "
6884 uentry_ekindName (unew),
6885 uentry_getName (unew),
6886 uentry_isDeclared (old),
6888 alkind_unparse (newKind),
6889 uentry_specOrDefName (old),
6890 alkind_unparse (oldKind)),
6891 uentry_whereDeclared (unew)))
6893 uentry_showWhereSpecified (old);
6895 sRef_setAliasKind (old->sref, AK_ERROR,
6896 uentry_whereDeclared (unew));
6900 sRef_setAliasKind (old->sref, newKind,
6901 uentry_whereDeclared (unew));
6906 if (!(alkind_isImplicit (newKind)))
6909 !uentry_isFunction (unew) &&
6912 message ("%s %q inconsistently %rdeclared %s %s storage, "
6913 "implicitly %s as temp storage",
6914 uentry_ekindName (unew),
6915 uentry_getName (unew),
6916 uentry_isDeclared (old),
6918 alkind_unparse (newKind),
6919 uentry_specOrDefName (old)),
6920 uentry_whereDeclared (unew)))
6922 uentry_showWhereSpecified (old);
6926 sRef_setAliasKind (old->sref, newKind,
6927 uentry_whereDeclared (unew));
6929 else /* newKind is temp or refcounted */
6936 else /* newKind unknown */
6943 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6944 bool mustConform, bool completeConform)
6949 oldKind = sRef_getExKind (old->sref);
6950 newKind = sRef_getExKind (unew->sref);
6952 if (exkind_isKnown (newKind))
6954 if (oldKind != newKind)
6956 if (exkind_isKnown (oldKind))
6961 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
6962 uentry_ekindName (unew),
6963 uentry_getName (unew),
6964 uentry_isDeclared (old),
6966 exkind_unparse (newKind),
6967 uentry_specOrDefName (old),
6968 exkind_unparse (oldKind)),
6969 uentry_whereDeclared (unew)))
6971 uentry_showWhereSpecified (old);
6974 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
6981 message ("%s %q inconsistently %rdeclared %s %s, "
6982 "implicitly %s without exposure qualifier",
6983 uentry_ekindName (unew),
6984 uentry_getName (unew),
6985 uentry_isDeclared (old),
6987 exkind_unparse (newKind),
6988 uentry_specOrDefName (old)),
6989 uentry_whereDeclared (unew)))
6991 uentry_showWhereSpecified (old);
6994 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7000 if (completeConform && exkind_isKnown (oldKind)
7001 && uentry_isReallySpecified (old))
7005 message ("%s %q specified as %s, but declared without "
7006 "exposure qualifier",
7007 ekind_capName (unew->ukind),
7008 uentry_getName (unew),
7009 exkind_unparse (oldKind)),
7010 uentry_whereDeclared (unew)))
7012 uentry_showWhereSpecified (old);
7016 /* yes, this is necessary! (if its a param) */
7017 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7022 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7023 /*@notnull@*/ uentry unew,
7024 bool mustConform, bool completeConform)
7026 checkDefState (old, unew, mustConform, completeConform);
7027 checkNullState (old, unew, mustConform, completeConform);
7028 checkAliasState (old, unew, mustConform, completeConform);
7029 checkExpState (old, unew, mustConform, completeConform);
7031 sRef_storeState (old->sref);
7032 sRef_storeState (unew->sref);
7036 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7038 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7043 llassert (uentry_isVar (old));
7044 llassert (uentry_isVar (unew));
7046 if (cstring_isEmpty (old->uname))
7048 cstring_free (old->uname);
7049 old->uname = cstring_copy (unew->uname);
7052 if (unew->info->var->kind == VKRETPARAM
7053 || unew->info->var->kind == VKSEFRETPARAM)
7055 if (old->info->var->kind != VKRETPARAM
7056 && old->info->var->kind != VKSEFRETPARAM)
7060 message ("Parameter %q inconsistently %rdeclared as "
7061 "returned parameter",
7062 uentry_getName (unew),
7063 uentry_isDeclared (old)),
7064 uentry_whereDeclared (unew)))
7066 uentry_showWhereSpecified (old);
7067 old->info->var->kind = unew->info->var->kind;
7073 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7075 if (old->info->var->kind != VKSEFPARAM
7076 && old->info->var->kind != VKSEFRETPARAM)
7080 message ("Parameter %qinconsistently %rdeclared as "
7082 uentry_getOptName (unew),
7083 uentry_isDeclared (old)),
7084 uentry_whereDeclared (unew)))
7086 uentry_showWhereSpecified (old);
7087 old->info->var->kind = unew->info->var->kind;
7092 if (old->info->var->kind == VKSPEC)
7094 old->info->var->kind = unew->info->var->kind;
7098 unew->info->var->kind = old->info->var->kind;
7101 if (unew->info->var->checked != CH_UNKNOWN
7102 && unew->info->var->checked != old->info->var->checked)
7104 if (old->info->var->checked == CH_UNKNOWN
7105 && !fileloc_isUser (uentry_whereLast (old)))
7113 message ("Variable %q inconsistently %rdeclared as "
7114 "%s parameter (was %s)",
7115 uentry_getName (unew),
7116 uentry_isDeclared (old),
7117 checkedName (unew->info->var->checked),
7118 checkedName (old->info->var->checked)),
7119 uentry_whereDeclared (unew)))
7121 uentry_showWhereSpecified (old);
7125 old->info->var->checked = unew->info->var->checked;
7130 && (old->info->var->checked != CH_UNKNOWN)
7131 && uentry_isReallySpecified (old))
7135 message ("%s %q specified as %s, but declared without %s qualifier",
7136 ekind_capName (unew->ukind),
7137 uentry_getName (unew),
7138 checkedName (old->info->var->checked),
7139 checkedName (old->info->var->checked)),
7140 uentry_whereDeclared (unew)))
7142 uentry_showWhereSpecified (old);
7146 unew->info->var->checked = old->info->var->checked;
7149 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7152 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7154 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7159 llassert (uentry_isVar (u1));
7160 llassert (uentry_isVar (u2));
7162 if (u1->info->var->kind != u2->info->var->kind) {
7163 if (u1->info->var->kind == VKSEFRETPARAM) {
7164 if (u2->info->var->kind == VKRETPARAM) {
7167 message ("Function types are inconsistent. Parameter %d is "
7168 "sef parameter, but non-sef parameter in "
7169 "assigned function: %s",
7170 paramno, exprNode_unparse (e)),
7172 } else if (u2->info->var->kind == VKSEFPARAM) {
7175 message ("Function types are inconsistent. Parameter %d is "
7176 "returns parameter, but non-returns parameter in "
7177 "assigned function: %s",
7178 paramno, exprNode_unparse (e)),
7183 message ("Function types are inconsistent. Parameter %d is "
7184 "sef returns parameter, but non-sef returns parameter in "
7185 "assigned function: %s",
7186 paramno, exprNode_unparse (e)),
7189 } else if (u1->info->var->kind == VKRETPARAM) {
7192 message ("Function types are inconsistent. Parameter %d is "
7193 "returns parameter, but non-returns parameter in "
7194 "assigned function: %s",
7195 paramno, exprNode_unparse (e)),
7197 } else if (u1->info->var->kind == VKSEFPARAM) {
7200 message ("Function types are inconsistent. Parameter %d is "
7201 "sef parameter, but non-sef parameter in "
7202 "assigned function: %s",
7203 paramno, exprNode_unparse (e)),
7206 if (u2->info->var->kind == VKSEFRETPARAM) {
7209 message ("Function types are inconsistent. Parameter %d is "
7210 "normal parameter, but sef returns parameter in "
7211 "assigned function: %s",
7212 paramno, exprNode_unparse (e)),
7214 } else if (u2->info->var->kind == VKSEFPARAM) {
7217 message ("Function types are inconsistent. Parameter %d is "
7218 "normal parameter, but sef parameter in "
7219 "assigned function: %s",
7220 paramno, exprNode_unparse (e)),
7222 } else if (u2->info->var->kind == VKRETPARAM) {
7225 message ("Function types are inconsistent. Parameter %d is "
7226 "normal parameter, but returns parameter in "
7227 "assigned function: %s",
7228 paramno, exprNode_unparse (e)),
7236 if (u1->info->var->defstate != u2->info->var->defstate)
7240 message ("Function types are inconsistent. Parameter %d is "
7241 "%s, but %s in assigned function: %s",
7243 sstate_unparse (u1->info->var->defstate),
7244 sstate_unparse (u2->info->var->defstate),
7245 exprNode_unparse (e)),
7249 if (u1->info->var->nullstate != u2->info->var->nullstate)
7253 message ("Function types are inconsistent. Parameter %d is "
7254 "%s, but %s in assigned function: %s",
7256 nstate_unparse (u1->info->var->nullstate),
7257 nstate_unparse (u2->info->var->nullstate),
7258 exprNode_unparse (e)),
7262 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7266 message ("Function types are inconsistent. Parameter %d is "
7267 "%s, but %s in assigned function: %s",
7269 alkind_unparse (sRef_getAliasKind (u1->sref)),
7270 alkind_unparse (sRef_getAliasKind (u2->sref)),
7271 exprNode_unparse (e)),
7275 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7279 message ("Function types are inconsistent. Parameter %d is "
7280 "%s, but %s in assigned function: %s",
7282 exkind_unparse (sRef_getExKind (u1->sref)),
7283 exkind_unparse (sRef_getExKind (u2->sref)),
7284 exprNode_unparse (e)),
7290 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7291 /*@notnull@*/ uentry unew,
7292 bool mustConform, /*@unused@*/ bool completeConform)
7294 uentryList oldParams = uentry_getParams (old);
7295 uentryList newParams = uentry_getParams (unew);
7296 ctype newType = unew->utype;
7297 ctype oldType = old->utype;
7298 ctype oldRetType = ctype_unknown;
7299 ctype newRetType = ctype_unknown;
7301 if (uentry_isForward (old))
7303 mustConform = FALSE;
7304 uentry_copyInto (old, unew);
7309 ** check return values
7312 if (ctype_isKnown (oldType))
7314 llassert (ctype_isFunction (oldType));
7316 oldRetType = ctype_returnValue (oldType);
7319 if (ctype_isKnown (newType))
7321 llassert (ctype_isFunction (newType));
7323 newRetType = ctype_returnValue (newType);
7326 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
7327 && !ctype_matchDef (newRetType, oldRetType))
7329 if (mustConform) returnValueError (old, unew);
7333 if (ctype_isConj (newRetType))
7335 if (ctype_isConj (oldRetType))
7337 if (!ctype_sameAltTypes (newRetType, oldRetType))
7341 message ("Function %q inconsistently %rdeclared to "
7342 "return alternate types %s "
7343 "(types match, but alternates are not identical, "
7344 "so checking may not be correct)",
7345 uentry_getName (unew),
7346 uentry_isDeclared (old),
7347 ctype_unparse (newRetType)),
7348 uentry_whereDeclared (unew)))
7350 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
7356 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
7361 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7363 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
7365 if (exitkind_isKnown (unew->info->fcn->exitCode))
7369 message ("Function %q inconsistently %rdeclared using %s",
7370 uentry_getName (unew),
7371 uentry_isDeclared (old),
7372 exitkind_unparse (unew->info->fcn->exitCode)),
7373 uentry_whereDeclared (unew)))
7375 uentry_showWhereSpecified (old);
7380 unew->info->fcn->exitCode = old->info->fcn->exitCode;
7384 if (!qual_isUnknown (unew->info->fcn->nullPred))
7386 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
7390 message ("Function %q inconsistently %rdeclared using %s",
7391 uentry_getName (unew),
7392 uentry_isDeclared (old),
7393 qual_unparse (unew->info->fcn->nullPred)),
7394 uentry_whereDeclared (unew)))
7396 uentry_showWhereSpecified (old);
7402 unew->info->fcn->nullPred = old->info->fcn->nullPred;
7405 if (unew->info->fcn->specialCode != SPC_NONE)
7407 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
7411 message ("Function %q inconsistently %rdeclared using %s",
7412 uentry_getName (unew),
7413 uentry_isDeclared (old),
7414 specCode_unparse (unew->info->fcn->specialCode)),
7415 uentry_whereDeclared (unew)))
7417 uentry_showWhereSpecified (old);
7423 unew->info->fcn->specialCode = old->info->fcn->specialCode;
7430 if (!uentryList_sameObject (oldParams, newParams)
7431 && (!uentryList_isMissingParams (oldParams)))
7433 if (!uentryList_isMissingParams (newParams))
7436 int nparams = uentryList_size (oldParams);
7437 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
7439 if (nparams != uentryList_size (newParams))
7441 nargsError (old, unew);
7444 if (uentryList_size (newParams) < nparams)
7446 nparams = uentryList_size (newParams);
7449 while (paramno < nparams)
7451 uentry oldCurrent = uentryList_getN (oldParams, paramno);
7452 uentry newCurrent = uentryList_getN (newParams, paramno);
7453 ctype oldCurrentType = uentry_getType (oldCurrent);
7454 ctype newCurrentType = uentry_getType (newCurrent);
7456 llassert (uentry_isValid (oldCurrent)
7457 && uentry_isValid (newCurrent));
7459 if (!uentry_isElipsisMarker (oldCurrent)
7460 && !uentry_isElipsisMarker (newCurrent))
7462 checkVarConformance (oldCurrent, newCurrent,
7463 mustConform, completeConform);
7468 if (uentry_hasName (oldCurrent)
7469 && uentry_hasName (newCurrent))
7471 cstring oldname = uentry_getName (oldCurrent);
7472 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
7474 cstring nname = uentry_getName (newCurrent);
7477 if (cstring_isDefined (pfx)
7478 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
7480 oname = cstring_suffix (oldname, cstring_length (pfx));
7485 /*@-branchstate@*/ } /*@=branchstate@*/
7487 if (cstring_isDefined (pfx)
7488 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
7490 nnamefix = cstring_suffix (nname, cstring_length (pfx));
7495 /*@-branchstate@*/ } /*@=branchstate@*/
7497 if (!cstring_equal (oname, nnamefix))
7500 (FLG_DECLPARAMMATCH,
7501 message ("Definition parameter name %s does not match "
7502 "name of corresponding parameter in "
7505 uentry_whereLast (newCurrent)))
7507 uentry_showWhereLastPlain (oldCurrent);
7511 cstring_free (oldname);
7512 cstring_free (nname);
7516 if (!ctype_match (oldCurrentType, newCurrentType))
7518 paramTypeError (old, oldCurrent, oldCurrentType,
7519 unew, newCurrent, newCurrentType, paramno);
7523 if (ctype_isMissingParamsMarker (newCurrentType)
7524 || ctype_isElips (newCurrentType)
7525 || ctype_isMissingParamsMarker (oldCurrentType)
7526 || ctype_isElips (oldCurrentType))
7532 if (ctype_isConj (newCurrentType))
7534 if (ctype_isConj (oldCurrentType))
7536 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
7540 message ("Parameter %q inconsistently %rdeclared with "
7541 "alternate types %s "
7542 "(types match, but alternates are not identical, "
7543 "so checking may not be correct)",
7544 uentry_getName (newCurrent),
7545 uentry_isDeclared (oldCurrent),
7546 ctype_unparse (newCurrentType)),
7547 uentry_whereDeclared (unew)))
7549 uentry_showWhereLastVal (oldCurrent,
7550 ctype_unparse (oldCurrentType));
7558 message ("Parameter %q inconsistently %rdeclared with "
7559 "alternate types %s",
7560 uentry_getName (newCurrent),
7561 uentry_isDeclared (oldCurrent),
7562 ctype_unparse (newCurrentType)),
7563 uentry_whereDeclared (unew)))
7565 uentry_showWhereLastVal (oldCurrent,
7566 ctype_unparse (oldCurrentType));
7573 if (ctype_isConj (oldCurrentType))
7575 uentry_setType (newCurrent, oldCurrentType);
7583 ** Forgot this! detected by lclint:
7584 ** uentry.c:1257,15: Suspected infinite loop
7590 if (!uentryList_isMissingParams (newParams))
7592 if (ctype_isConj (oldRetType))
7594 old->utype = ctype_makeFunction (oldRetType,
7595 uentryList_copy (newParams));
7599 old->utype = unew->utype;
7603 checkGlobalsConformance (old, unew, mustConform, completeConform);
7604 checkModifiesConformance (old, unew, mustConform, completeConform);
7606 if (specialClauses_isDefined (unew->info->fcn->specclauses))
7608 if (!specialClauses_isDefined (old->info->fcn->specclauses))
7612 message ("Function %q redeclared using special clauses (can only "
7613 "be used in first declaration)",
7614 uentry_getName (unew)),
7615 uentry_whereDeclared (unew)))
7617 uentry_showWhereLast (old);
7622 specialClauses_checkEqual (old, unew);
7626 if (fileloc_isUndefined (old->whereDeclared))
7628 old->whereDeclared = fileloc_copy (unew->whereDeclared);
7630 else if (fileloc_isUndefined (unew->whereDeclared))
7632 unew->whereDeclared = fileloc_copy (old->whereDeclared);
7641 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
7645 llassert (uentry_isValid (ue));
7646 llassert (uentry_isEitherConstant (ue));
7648 uval = ue->info->uconst->val;
7650 if (multiVal_isDefined (uval))
7652 if (multiVal_isDefined (m))
7654 if (!multiVal_equiv (uval, m))
7658 message ("%s %q defined with inconsistent value: %q",
7659 ekind_capName (ue->ukind),
7660 uentry_getName (ue),
7661 multiVal_unparse (m)),
7664 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
7672 ue->info->uconst->val = m;
7673 multiVal_free (uval);
7678 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7681 bool typeError = FALSE;
7683 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
7685 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
7689 checkStructConformance (old, unew);
7694 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7696 llbug (message ("struct tags: bad types: %t / %t",
7697 old->utype, unew->utype));
7701 else if (uentry_isEnumTag (old))
7703 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
7705 if (mustConform) checkEnumConformance (old, unew);
7709 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7711 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
7712 ctype_unparse (unew->utype)));
7716 else if (!ctype_match (old->utype, unew->utype))
7718 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
7720 ctype realt = ctype_realType (unew->utype);
7722 if (ctype_isRealInt (realt) || ctype_isChar (realt))
7724 unew->utype = ctype_bool;
7730 typeError = optgenerror
7732 message ("%q defined as %s", uentry_getName (old),
7733 ctype_unparse (realt)),
7734 uentry_whereDeclared (unew));
7742 ctype oldr = ctype_realType (old->utype);
7743 ctype newr = ctype_realType (unew->utype);
7745 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
7747 checkStructConformance (old, unew);
7749 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
7751 checkStructConformance (old, unew);
7753 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
7755 checkEnumConformance (old, unew);
7757 else if (uentry_isConstant (old)
7758 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
7760 /* okay...for now! (should check the type is reset later... */
7764 DPRINTF (("YABA!"));
7767 message ("%s %q %rdeclared with inconsistent type: %t",
7768 ekind_capName (unew->ukind),
7769 uentry_getName (unew),
7770 uentry_isDeclared (old),
7772 uentry_whereDeclared (unew)))
7774 uentry_showWhereLast (old);
7790 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
7791 /*@notnull@*/ uentry unew,
7792 bool mustConform, bool completeConform)
7794 if (ctype_isDefined (unew->info->datatype->type))
7797 ** bool is hard coded here, since it is built into LCL.
7798 ** For now, we're stuck with LCL's types.
7801 if (ctype_isDirectBool (old->utype) &&
7802 cstring_equalLit (unew->uname, "bool"))
7804 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
7805 evs 2000-07-25: removed
7807 unew->utype = ctype_bool;
7810 if (ctype_isUnknown (old->info->datatype->type))
7812 old->info->datatype->type = unew->info->datatype->type;
7816 DPRINTF (("Old: %s / New: %s",
7817 uentry_unparseFull (old),
7818 uentry_unparseFull (unew)));
7819 DPRINTF (("Types: %s / %s",
7820 ctype_unparse (old->info->datatype->type),
7821 ctype_unparse (unew->info->datatype->type)));
7823 if (ctype_matchDef (old->info->datatype->type,
7824 unew->info->datatype->type))
7833 ("Type %q %s with inconsistent type: %t",
7834 uentry_getName (unew),
7835 uentry_reDefDecl (old, unew),
7836 unew->info->datatype->type),
7837 uentry_whereDeclared (unew)))
7839 uentry_showWhereLastExtra
7840 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
7843 old->info->datatype->type = unew->info->datatype->type;
7848 if (unew->info->datatype->abs != MAYBE)
7850 if (ynm_isOff (old->info->datatype->abs)
7851 && ynm_isOn (unew->info->datatype->abs))
7853 if (!ctype_isDirectBool (old->utype))
7858 ("Datatype %q inconsistently %rdeclared as abstract type",
7859 uentry_getName (unew),
7860 uentry_isDeclared (old)),
7861 uentry_whereDeclared (unew)))
7863 uentry_showWhereLastPlain (old);
7867 else if (ynm_isOn (old->info->datatype->abs)
7868 && ynm_isOff (unew->info->datatype->abs))
7870 if (!ctype_isDirectBool (old->utype))
7875 ("Datatype %q inconsistently %rdeclared as concrete type",
7876 uentry_getName (unew),
7877 uentry_isDeclared (old)),
7878 uentry_whereDeclared (unew)))
7880 uentry_showWhereLastPlain (old);
7891 if (ynm_isOn (old->info->datatype->abs))
7893 old->sref = unew->sref;
7894 unew->info->datatype->mut = old->info->datatype->mut;
7897 && uentry_isReallySpecified (old))
7902 ("Datatype %q specified as abstract, "
7903 "but abstract annotation not used in declaration",
7904 uentry_getName (unew)),
7905 uentry_whereDeclared (unew)))
7907 uentry_showWhereLastPlain (old);
7913 unew->info->datatype->abs = old->info->datatype->abs;
7915 if (ynm_isMaybe (unew->info->datatype->mut))
7917 if (completeConform && ynm_isOff (old->info->datatype->mut)
7918 && uentry_isReallySpecified (old))
7923 ("Datatype %q specified as immutable, "
7924 "but immutable annotation not used in declaration",
7925 uentry_getName (unew)),
7926 uentry_whereDeclared (unew)))
7928 uentry_showWhereLastPlain (old);
7932 unew->info->datatype->mut = old->info->datatype->mut;
7934 else if (ynm_isMaybe (old->info->datatype->mut))
7936 old->info->datatype->mut = unew->info->datatype->mut;
7940 if (ynm_isOn (old->info->datatype->abs))
7942 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
7946 message ("Datatype %q inconsistently %rdeclared as immutable",
7947 uentry_getName (unew),
7948 uentry_isDeclared (old)),
7949 uentry_whereDeclared (unew)))
7951 uentry_showWhereLastPlain (old);
7956 if (ynm_isOff (old->info->datatype->mut)
7957 && ynm_isOn (unew->info->datatype->mut))
7961 message ("Datatype %q inconsistently %rdeclared as mutable",
7962 uentry_getName (unew),
7963 uentry_isDeclared (old)),
7964 uentry_whereDeclared (unew)))
7966 uentry_showWhereLastPlain (old);
7971 old->info->datatype->mut = unew->info->datatype->mut;
7974 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7978 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
7979 /*@notnull@*/ uentry unew,
7981 /*@unused@*/ bool completeConform)
7983 multiVal oldVal = old->info->uconst->val;
7984 multiVal newVal = unew->info->uconst->val;
7986 if (multiVal_isDefined (oldVal))
7988 if (multiVal_isDefined (newVal))
7990 if (!multiVal_equiv (oldVal, newVal))
7995 message ("%s %q %rdeclared with inconsistent value: %q",
7996 ekind_capName (unew->ukind),
7997 uentry_getName (unew),
7998 uentry_isDeclared (old),
7999 multiVal_unparse (newVal)),
8000 uentry_whereDeclared (unew)))
8002 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
8006 unew->info->uconst->val = multiVal_copy (oldVal);
8007 multiVal_free (newVal);
8016 old->info->uconst->val = multiVal_copy (newVal);
8021 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8022 /*@notnull@*/ uentry unew, bool mustConform,
8023 bool completeConform)
8025 bool typeError = FALSE;
8026 bool fcnConformance = FALSE;
8028 if (!ekind_equal (unew->ukind, old->ukind))
8031 ** okay, only if one is a function and the other is
8032 ** a variable of type function.
8035 if (unew->ukind == KENUMCONST
8036 && old->ukind == KCONST)
8038 old->ukind = KENUMCONST;
8042 if (unew->ukind == KFCN
8043 && old->ukind == KCONST
8044 && ctype_isUnknown (old->utype))
8047 ** When a function is defined with an unparam macro
8050 uentry_copyInto (old, unew);
8054 if (uentry_isExpandedMacro (old)
8055 && uentry_isEitherConstant (unew))
8057 uentry_copyInto (old, unew);
8061 if (uentry_isEndIter (unew))
8063 if (ctype_isUnknown (old->utype))
8065 if (!uentry_isSpecified (old)
8066 && uentry_isCodeDefined (unew))
8068 if (!fileloc_withinLines (uentry_whereDefined (old),
8069 uentry_whereDeclared (unew), 2))
8070 { /* bogus! will give errors if there is too much whitespace */
8074 ("Iterator finalized name %q does not match name in "
8075 "previous iter declaration (should be end_%q). This iter "
8076 "is declared at %q",
8077 uentry_getName (unew),
8078 uentry_getName (old),
8079 fileloc_unparse (uentry_whereDefined (old))),
8080 uentry_whereDeclared (old));
8084 uentry_copyInto (old, unew);
8089 KindConformanceError (old, unew, mustConform);
8093 if (uentry_isFunction (unew))
8095 if (uentry_isVariable (old))
8097 if (!ctype_isUnknown (old->utype))
8099 if (ctype_isFunction (old->utype))
8101 uentry_makeVarFunction (old);
8102 checkFunctionConformance (old, unew, mustConform,
8104 fcnConformance = TRUE;
8108 KindConformanceError (old, unew, mustConform);
8113 if (uentry_isExpandedMacro (old))
8115 if (fileloc_isUndefined (unew->whereDefined))
8117 unew->whereDefined = fileloc_update (unew->whereDefined,
8121 uentry_copyInto (old, unew);
8122 old->used = unew->used = TRUE;
8127 /* undeclared identifier */
8128 old->utype = unew->utype;
8129 uentry_makeVarFunction (old);
8130 checkFunctionConformance (old, unew, FALSE, FALSE);
8131 fcnConformance = TRUE;
8137 KindConformanceError (old, unew, mustConform);
8140 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8142 if (!ctype_isUnknown (unew->utype))
8144 if (ctype_isFunction (unew->utype))
8146 uentry_makeVarFunction (unew);
8147 checkFunctionConformance (old, unew, mustConform, completeConform);
8148 fcnConformance = TRUE;
8152 KindConformanceError (old, unew, mustConform);
8157 KindConformanceError (old, unew, mustConform);
8162 KindConformanceError (old, unew, mustConform);
8168 ** check parameter lists for functions
8169 ** (before type errors, to get better messages
8172 if (uentry_isFunction (old))
8174 checkFunctionConformance (old, unew, mustConform, completeConform);
8175 fcnConformance = TRUE;
8179 if (!ctype_isUndefined (old->utype))
8181 typeError = checkTypeConformance (old, unew, mustConform);
8188 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8190 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8193 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8195 DPRINTF (("Check datatype: %s / %s",
8196 uentry_unparseFull (old),
8197 uentry_unparseFull (unew)));
8199 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8202 if (uentry_isVariable (old) && uentry_isVariable (unew))
8205 !ctype_matchDef (old->utype, unew->utype))
8210 ("Variable %q %s with inconsistent type (arrays and pointers are "
8211 "not identical in variable declarations): %t",
8212 uentry_getName (unew),
8213 uentry_reDefDecl (old, unew),
8215 uentry_whereDeclared (unew)))
8217 uentry_showWhereLast (old);
8220 ** Avoid repeated errors.
8223 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8225 old->whereDefined = fileloc_update (old->whereDefined,
8233 checkVarConformance (old, unew, mustConform, completeConform);
8238 /* old->utype = unew->utype; */
8242 if (ctype_isConj (old->utype))
8244 if (ctype_isConj (unew->utype))
8246 if (!ctype_sameAltTypes (old->utype, unew->utype))
8250 message ("%s %q inconsistently %rdeclared with "
8251 "alternate types %s "
8252 "(types match, but alternates are not identical, "
8253 "so checking may not be correct)",
8254 ekind_capName (uentry_getKind (old)),
8255 uentry_getName (unew),
8256 uentry_isDeclared (old),
8257 ctype_unparse (unew->utype)),
8258 uentry_whereDeclared (unew)))
8260 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
8264 old->utype = unew->utype;
8271 if (ctype_isUnknown (old->utype))
8273 old->utype = unew->utype;
8278 if (unew->ukind == old->ukind)
8281 unew->info = uinfo_copy (old->info, old->ukind);
8284 sRef_storeState (old->sref);
8285 sRef_storeState (unew->sref);
8289 ** modifies spec to reflect def, reports any inconsistencies
8293 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
8295 llassert (uentry_isValid (spec));
8296 llassert (uentry_isValid (def));
8297 llassert (cstring_equal (spec->uname, def->uname));
8299 uentry_checkConformance (spec, def, TRUE,
8300 context_getFlag (FLG_NEEDSPEC));
8302 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
8305 ** okay, declarations conform. Propagate extra information.
8308 uentry_setDefined (spec, uentry_whereDefined (def));
8309 uentry_setDeclared (spec, uentry_whereDeclared (def));
8311 if (uentry_isStatic (def))
8315 message ("%s %q specified, but declared as static",
8316 ekind_capName (def->ukind),
8317 uentry_getName (def)),
8318 uentry_whereDeclared (def)))
8320 uentry_showWhereSpecified (spec);
8325 spec->storageclass = def->storageclass;
8328 sRef_storeState (spec->sref);
8330 spec->used = def->used || spec->used;
8331 spec->hasNameError |= def->hasNameError;
8335 if (!spec->hasNameError)
8337 uentry_checkName (spec);
8346 ** Can't generate function redeclaration errors when the
8347 ** entries are merged, since we don't yet know if its the
8348 ** definition of the function.
8352 uentry_clearDecl (void)
8354 posRedeclared = uentry_undefined;
8355 fileloc_free (posLoc);
8356 posLoc = fileloc_undefined;
8360 uentry_checkDecl (void)
8362 if (uentry_isValid (posRedeclared))
8364 llassert (fileloc_isDefined (posLoc));
8366 if (uentry_isCodeDefined (posRedeclared))
8368 if (optgenerror (FLG_REDECL,
8369 message ("%s %q declared after definition",
8370 ekind_capName (posRedeclared->ukind),
8371 uentry_getName (posRedeclared)),
8374 llgenindentmsg (message ("Definition of %q",
8375 uentry_getName (posRedeclared)),
8376 posRedeclared->whereDeclared);
8381 if (optgenerror (FLG_REDECL,
8382 message ("%s %q declared more than once",
8383 ekind_capName (posRedeclared->ukind),
8384 uentry_getName (posRedeclared)),
8387 llgenindentmsg (message ("Previous declaration of %q",
8388 uentry_getName (posRedeclared)),
8389 posRedeclared->whereDeclared);
8394 fileloc_free (posLoc);
8395 posLoc = fileloc_undefined;
8396 posRedeclared = uentry_undefined;
8400 ** Redefinition of old as unew.
8401 ** modifies old to reflect unew, reports any inconsistencies
8405 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
8407 fileloc olddef = uentry_whereDeclared (old);
8408 fileloc unewdef = uentry_whereDeclared (unew);
8412 if (uentry_isExtern (unew))
8414 uentry_setUsed (old, unewdef);
8418 fileloc_isUndefined (olddef)
8419 && fileloc_isDefined (uentry_whereDefined (old))
8420 && !uentry_isExpandedMacro (old);
8422 if (!context_getFlag (FLG_INCONDEFSLIB)
8423 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8425 mustConform = FALSE;
8432 llassert (uentry_isValid (old));
8433 llassert (uentry_isValid (unew));
8434 llassert (cstring_equal (old->uname, unew->uname));
8437 ** should check old one was extern!
8440 if (uentry_isStatic (old))
8442 if (!(uentry_isStatic (unew)))
8446 message ("%s %q shadows static declaration",
8447 ekind_capName (unew->ukind),
8448 uentry_getName (unew)),
8451 uentry_showWhereLast (old);
8456 uentry_setDeclDef (old, unewdef);
8459 else if (uentry_isStatic (unew))
8461 uentry_setDeclDef (old, unewdef);
8463 else if (uentry_isExtern (old))
8465 uentry_setDeclared (old, unewdef);
8469 if (!uentry_isExtern (unew) && !uentry_isForward (old)
8470 && !fileloc_equal (olddef, unewdef)
8471 && !fileloc_isUndefined (olddef)
8472 && !fileloc_isUndefined (unewdef)
8473 && !fileloc_isBuiltin (olddef)
8474 && !fileloc_isBuiltin (unewdef)
8475 && !uentry_isYield (old)
8476 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8478 if (uentry_isVariable (old) || uentry_isVariable (unew))
8480 ; /* will report redeclaration error later */
8484 if (fileloc_isDefined (uentry_whereDefined (old)))
8488 message ("%s %q defined more than once",
8489 ekind_capName (unew->ukind),
8490 uentry_getName (unew)),
8491 uentry_whereLast (unew)))
8494 (message ("Previous definition of %q",
8495 uentry_getName (old)),
8496 uentry_whereLast (old));
8499 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
8501 uentry_copyInto (old, unew);
8502 old->sref = sRef_saveCopy (old->sref);
8510 if (fileloc_isLib (olddef)
8511 || fileloc_isUndefined (olddef)
8512 || fileloc_isImport (olddef))
8514 if (uentry_isExtern (unew))
8516 if (uentry_isExtern (old)
8517 || (fileloc_isDefined (uentry_whereDeclared (old))
8518 && (!fileloc_equal (uentry_whereDeclared (old),
8519 uentry_whereDefined (old)))))
8523 message ("%s %q declared more than once",
8524 ekind_capName (unew->ukind),
8525 uentry_getName (unew)),
8526 unew->whereDeclared))
8529 (message ("Previous declaration of %q",
8530 uentry_getName (old)),
8531 old->whereDeclared);
8535 uentry_setExtern (old);
8539 uentry_setDefined (old, unewdef);
8545 uentry_checkConformance (old, unew, mustConform, FALSE);
8547 old->used = old->used || unew->used;
8548 old->uses = filelocList_append (old->uses, unew->uses);
8549 unew->uses = filelocList_undefined;
8551 sRef_storeState (old->sref);
8552 sRef_storeState (unew->sref);
8556 old->whereDefined = fileloc_update (old->whereDefined,
8561 ** No redeclaration errors for functions here, since we
8562 ** don't know if this is the definition of the function.
8565 if (fileloc_isUser (old->whereDeclared)
8566 && fileloc_isUser (unew->whereDeclared)
8567 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
8568 && !fileloc_isDefined (unew->whereDefined))
8570 if (uentry_isFunction (old))
8572 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
8573 posLoc = fileloc_update (posLoc, unew->whereDeclared);
8577 if (optgenerror (FLG_REDECL,
8578 message ("%s %q declared more than once",
8579 ekind_capName (unew->ukind),
8580 uentry_getName (unew)),
8581 unew->whereDeclared))
8583 llgenindentmsg (message ("Previous declaration of %q",
8584 uentry_getName (old)),
8585 old->whereDeclared);
8590 if (fileloc_isUndefined (old->whereDefined))
8592 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
8596 if (!context_processingMacros ()
8597 && fileloc_isUser (old->whereDefined)
8598 && fileloc_isUser (unew->whereDefined)
8599 && !fileloc_equal (old->whereDefined, unew->whereDefined))
8601 if (uentry_isVariable (unew) || uentry_isFunction (unew))
8603 if (uentry_isVariable (unew)
8604 && uentry_isExtern (unew))
8606 if (optgenerror (FLG_REDECL,
8607 message ("%s %q declared after definition",
8608 ekind_capName (unew->ukind),
8609 uentry_getName (unew)),
8610 unew->whereDeclared))
8612 llgenindentmsg (message ("Definition of %q",
8613 uentry_getName (old)),
8619 if (optgenerror (FLG_REDEF,
8620 message ("%s %q redefined",
8621 ekind_capName (unew->ukind),
8622 uentry_getName (unew)),
8623 unew->whereDefined))
8625 llgenindentmsg (message ("Previous definition of %q",
8626 uentry_getName (old)),
8634 if (uentry_isExternal (unew))
8636 old->whereDefined = fileloc_createExternal ();
8639 if (unew->hasNameError)
8641 old->hasNameError = TRUE;
8646 if (!old->hasNameError)
8648 uentry_checkName (old);
8651 llassert (!ctype_isUndefined (old->utype));
8655 uentry_copyState (uentry res, uentry other)
8657 llassert (uentry_isValid (res));
8658 llassert (uentry_isValid (other));
8660 res->used = other->used;
8662 res->info->var->kind = other->info->var->kind;
8663 res->info->var->defstate = other->info->var->defstate;
8664 res->info->var->nullstate = other->info->var->nullstate;
8665 res->info->var->checked = other->info->var->checked;
8667 sRef_copyState (res->sref, other->sref);
8671 uentry_sameKind (uentry u1, uentry u2)
8673 if (uentry_isValid (u1) && uentry_isValid (u2))
8675 if (uentry_isVar (u1) && uentry_isVar (u2))
8677 ctype c1 = u1->utype;
8678 ctype c2 = u2->utype;
8680 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
8683 ** both functions, or both not functions
8686 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
8690 return ((u1->ukind == u2->ukind));
8697 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
8699 llassert (uentry_isValid (unew));
8700 llassert (uentry_isValid (old));
8702 unew->ukind = old->ukind;
8703 unew->uname = cstring_copy (old->uname);
8704 unew->utype = old->utype;
8706 unew->whereSpecified = fileloc_copy (old->whereSpecified);
8707 unew->whereDefined = fileloc_copy (old->whereDefined);
8708 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8710 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
8711 unew->used = old->used;
8713 unew->isPrivate = old->isPrivate;
8714 unew->hasNameError = old->hasNameError;
8715 unew->uses = filelocList_undefined;
8717 unew->storageclass = old->storageclass;
8718 unew->info = uinfo_copy (old->info, old->ukind);
8723 uentry_copy (uentry e)
8725 if (uentry_isValid (e))
8727 uentry enew = uentry_alloc ();
8728 DPRINTF (("copy: %s", uentry_unparseFull (e)));
8729 uentry_copyInto (enew, e);
8730 DPRINTF (("Here we are..."));
8731 DPRINTF (("original: %s", uentry_unparseFull (e)));
8732 DPRINTF (("copy: %s", uentry_unparse (enew)));
8733 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
8738 return uentry_undefined;
8743 uentry_setState (uentry res, uentry other)
8745 llassert (uentry_isValid (res));
8746 llassert (uentry_isValid (other));
8748 llassert (res->ukind == other->ukind);
8749 llassert (res->ukind == KVAR);
8751 res->sref = sRef_saveCopy (other->sref);
8752 res->used = other->used;
8753 filelocList_free (res->uses);
8754 res->uses = other->uses;
8755 other->uses = filelocList_undefined;
8756 res->lset = other->lset;
8760 uentry_mergeUses (uentry res, uentry other)
8762 llassert (uentry_isValid (res));
8763 llassert (uentry_isValid (other));
8765 res->used = other->used || res->used;
8766 res->lset = other->lset || res->lset;
8767 res->uses = filelocList_append (res->uses, other->uses);
8768 other->uses = filelocList_undefined;
8773 ** This is a really ugly routine.
8775 ** gack...fix this one day.
8780 ** >> res is the false branch, other is the true branch (or continuation)
8782 ** >> res is the true branch, other is the false branch (or continutation)
8789 ** References not effected by res are propagated from other.
8793 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
8794 bool flip, clause cl, fileloc loc)
8798 message ("%s %q is %s %s, but %s %s.",
8799 ekind_capName (res->ukind), uentry_getName (res),
8800 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
8801 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
8804 if (sRef_isDead (res->sref))
8806 sRef_showStateInfo (res->sref);
8808 else if (sRef_isKept (res->sref))
8810 sRef_showAliasInfo (res->sref);
8812 else /* dependent */
8814 sRef_showAliasInfo (res->sref);
8815 sRef_showAliasInfo (other->sref);
8818 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8822 static bool incompatibleStates (sRef rs, sRef os)
8824 alkind rk = sRef_getAliasKind (rs);
8825 alkind ok = sRef_getAliasKind (os);
8827 if (alkind_isError (rk) || alkind_isError (ok))
8833 return ((sRef_isDead (rs)
8834 || (alkind_isKept (rk) && !alkind_isKept (ok))
8835 || (alkind_isDependent (rk)
8836 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
8837 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
8842 branchStateAltError (/*@notnull@*/ uentry res,
8843 /*@notnull@*/ uentry other, bool flip,
8844 clause cl, fileloc loc)
8848 message ("%s %q is %s %s, but %s %s.",
8849 ekind_capName (res->ukind), uentry_getName (res),
8850 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
8851 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
8854 if (sRef_isDead (other->sref))
8856 sRef_showStateInfo (other->sref);
8860 sRef_showAliasInfo (other->sref);
8863 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8864 sRef_setDefinedComplete (res->sref, fileloc_undefined);
8866 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
8867 sRef_setDefinedComplete (other->sref, fileloc_undefined);
8871 static bool notNull (sRef sr, bool flip)
8873 return (!sRef_definitelyNull (sr)
8874 && !(sRef_isKept (sr))
8875 && !(sRef_isDependent (sr))
8876 && !(flip ? usymtab_isProbableDeepNull (sr)
8877 : usymtab_isAltProbablyDeepNull (sr)));
8881 uentry_mergeState (uentry res, uentry other, fileloc loc,
8882 bool mustReturn, bool flip, bool opt,
8885 llassert (uentry_isValid (res));
8886 llassert (uentry_isValid (other));
8888 llassert (res->ukind == other->ukind);
8889 llassert (res->ukind == KVAR);
8891 DPRINTF (("Merge state: %s / %s",
8892 uentry_unparse (res),
8893 uentry_unparse (other)));
8895 if (sRef_isValid (res->sref))
8899 if (incompatibleStates (res->sref, other->sref))
8901 if (sRef_isThroughArrayFetch (res->sref)
8902 && !context_getFlag (FLG_STRICTBRANCHSTATE))
8904 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
8906 sRef_maybeKill (res->sref, loc);
8908 else if (sRef_isPossiblyDead (other->sref))
8910 sRef_maybeKill (res->sref, loc);
8919 if (notNull (other->sref, flip))
8921 if (sRef_isLocalParamVar (res->sref)
8922 && (sRef_isLocalState (other->sref)
8923 || sRef_isDependent (other->sref)))
8925 if (sRef_isDependent (res->sref))
8927 sRef_setDependent (other->sref, loc);
8931 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8936 branchStateError (res, other, flip, cl, loc);
8941 if (sRef_isKept (res->sref))
8943 sRef_setKept (other->sref, loc);
8948 if (incompatibleStates (other->sref, res->sref))
8950 if (notNull (res->sref, !flip))
8952 if (sRef_isLocalParamVar (res->sref)
8953 && (sRef_isDependent (res->sref)
8954 || sRef_isLocalState (res->sref)))
8956 if (sRef_isDependent (other->sref))
8958 sRef_setDependent (res->sref, loc);
8962 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
8967 if (sRef_isParam (other->sref))
8970 ** If the local variable associated
8971 ** with the param has the correct state,
8973 ** (e.g., free (s); s = new(); ...
8976 uentry uvar = usymtab_lookupSafe (other->uname);
8978 if (uentry_isValid (uvar)
8979 && ((sRef_isDead (other->sref)
8980 && sRef_isOnly (uvar->sref))
8981 || (sRef_isDependent (other->sref)
8982 && sRef_isOwned (uvar->sref))))
8988 branchStateAltError (res, other,
8994 branchStateAltError (res, other,
9001 if (sRef_isKept (other->sref))
9003 sRef_setKept (res->sref, loc);
9009 DPRINTF (("Merge opt..."));
9010 sRef_mergeOptState (res->sref, other->sref, cl, loc);
9011 DPRINTF (("Done!"));
9015 sRef_mergeState (res->sref, other->sref, cl, loc);
9020 if (sRef_isModified (other->sref))
9022 sRef_setModified (res->sref);
9026 if (cl == DOWHILECLAUSE)
9028 res->used = other->used || res->used;
9029 res->lset = other->lset || res->lset;
9030 res->uses = filelocList_append (res->uses, other->uses);
9031 other->uses = filelocList_undefined;
9035 if (sRef_isMacroParamRef (res->sref)
9036 && !uentry_isSefParam (other)
9037 && !uentry_isSefParam (res))
9039 bool hasError = FALSE;
9041 if (bool_equal (res->used, other->used))
9043 res->used = other->used;
9047 if (other->used && !flip)
9052 message ("Macro parameter %q used in true clause, "
9053 "but not in false clause",
9054 uentry_getName (res)),
9055 uentry_whereDeclared (res));
9062 message ("Macro parameter %q used in false clause, "
9063 "but not in true clause",
9064 uentry_getName (res)),
9065 uentry_whereDeclared (res));
9071 /* make it sef now, prevent more errors */
9072 res->info->var->kind = VKREFSEFPARAM;
9078 res->used = other->used || res->used;
9079 res->lset = other->lset || res->lset;
9080 res->uses = filelocList_append (res->uses, other->uses);
9081 other->uses = filelocList_undefined;
9087 void uentry_setUsed (uentry e, fileloc loc)
9089 static bool firstTime = TRUE;
9090 static bool showUses = FALSE;
9091 static bool exportLocal = FALSE;
9095 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
9097 showUses = context_getFlag (FLG_SHOWUSES);
9098 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
9103 if (uentry_isValid (e))
9107 if (sRef_isMacroParamRef (e->sref))
9109 if (uentry_isYield (e) || uentry_isSefParam (e))
9115 if (context_inConditional ())
9119 message ("Macro parameter %q used in conditionally "
9120 "executed code (may or may not be "
9121 "evaluated exactly once)",
9122 uentry_getName (e)),
9125 e->info->var->kind = VKREFSEFPARAM;
9134 message ("Macro parameter %q used more than once",
9135 uentry_getName (e)),
9136 uentry_whereDeclared (e)))
9138 e->info->var->kind = VKREFSEFPARAM;
9145 if ((dp = uentry_directParamNo (e)) >= 0)
9147 uentry_setUsed (usymtab_getParam (dp), loc);
9152 if (!sRef_isLocalVar (e->sref))
9156 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
9162 if (context_inMacro ())
9164 e->uses = filelocList_addUndefined (e->uses);
9168 e->uses = filelocList_addDifferentFile
9170 uentry_whereDeclared (e),
9179 bool uentry_isReturned (uentry u)
9181 return (uentry_isValid (u) && uentry_isVar (u)
9182 && (u->info->var->kind == VKRETPARAM
9183 || u->info->var->kind == VKSEFRETPARAM));
9186 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
9188 llassert (uentry_isRealFunction (u));
9190 if (ctype_isFunction (u->utype)
9191 && sRef_isStateSpecial (uentry_getSref (u)))
9193 specialClauses clauses = uentry_getSpecialClauses (u);
9194 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9196 sRef_setAllocated (res, g_currentloc);
9198 specialClauses_postElements (clauses, cl)
9200 sRefSet refs = specialClause_getRefs (cl);
9201 sRefMod modf = specialClause_getEffectFunction (cl);
9203 sRefSet_elements (refs, el)
9205 sRef base = sRef_getRootBase (el);
9207 if (sRef_isResult (base))
9211 sRef sr = sRef_fixBase (el, res);
9212 modf (sr, g_currentloc);
9219 } end_sRefSet_elements ;
9221 } end_specialClauses_postElements ;
9229 sRefSet prefs = sRefSet_new ();
9230 sRef res = sRef_undefined;
9233 params = uentry_getParams (u);
9235 uentryList_elements (params, current)
9237 if (uentry_isReturned (current))
9239 if (exprNodeList_size (args) >= paramno)
9241 exprNode ecur = exprNodeList_nth (args, paramno);
9242 sRef tref = exprNode_getSref (ecur);
9244 if (sRef_isValid (tref))
9246 sRef tcref = sRef_copy (tref);
9248 if (sRef_isDead (tcref))
9250 sRef_setDefined (tcref, g_currentloc);
9251 sRef_setOnly (tcref, g_currentloc);
9254 if (sRef_isRefCounted (tcref))
9256 /* could be a new ref now (but only if its returned) */
9257 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
9260 sRef_makeSafe (tcref);
9262 prefs = sRefSet_insert (prefs, tcref);
9268 } end_uentryList_elements ;
9270 if (sRefSet_size (prefs) > 0)
9272 nstate n = sRef_getNullState (u->sref);
9274 if (sRefSet_size (prefs) == 1)
9276 res = sRefSet_choose (prefs);
9280 res = sRefSet_mergeIntoOne (prefs);
9283 if (nstate_isKnown (n))
9285 sRef_setNullState (res, n, g_currentloc);
9290 if (ctype_isFunction (u->utype))
9292 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9296 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
9299 if (sRef_isRefCounted (res))
9301 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9305 if (sRef_getNullState (res) == NS_ABSNULL)
9307 ctype ct = ctype_realType (u->utype);
9309 if (ctype_isAbstract (ct))
9311 sRef_setNotNull (res, g_currentloc);
9315 if (ctype_isUser (ct))
9317 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
9321 sRef_setNotNull (res, g_currentloc);
9326 if (sRef_isRefCounted (res))
9328 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9330 else if (sRef_isKillRef (res))
9332 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
9339 ak = sRef_getAliasKind (res);
9341 if (alkind_isImplicit (ak))
9343 sRef_setAliasKind (res,
9344 alkind_fixImplicit (ak),
9348 sRefSet_free (prefs);
9354 static bool uentry_isRefCounted (uentry ue)
9356 ctype ct = uentry_getType (ue);
9358 if (ctype_isFunction (ct))
9360 return (ctype_isRefCounted (ctype_returnValue (ct)));
9364 return (ctype_isRefCounted (ct));
9369 ** old was declared yield in the specification.
9370 ** new is declared in the iter implementation.
9373 void uentry_checkYieldParam (uentry old, uentry unew)
9377 llassert (uentry_isVariable (old));
9378 llassert (uentry_isVariable (unew));
9380 unew->info->var->kind = VKYIELDPARAM;
9381 (void) checkTypeConformance (old, unew, TRUE);
9382 checkVarConformance (old, unew, TRUE, FALSE);
9384 /* get rid of param marker */
9386 name = uentry_getName (unew);
9387 cstring_free (unew->uname);
9389 unew->info->var->kind = VKREFYIELDPARAM;
9391 uentry_setUsed (old, fileloc_undefined);
9392 uentry_setUsed (unew, fileloc_undefined);
9395 /*@observer@*/ cstring
9396 uentry_ekindName (uentry ue)
9398 if (uentry_isValid (ue))
9403 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
9405 return cstring_makeLiteralTemp ("Datatype");
9407 return cstring_makeLiteralTemp ("Enum member");
9409 return cstring_makeLiteralTemp ("Constant");
9411 if (uentry_isParam (ue))
9413 return cstring_makeLiteralTemp ("Parameter");
9415 else if (uentry_isExpandedMacro (ue))
9417 return cstring_makeLiteralTemp ("Expanded macro");
9421 return cstring_makeLiteralTemp ("Variable");
9424 return cstring_makeLiteralTemp ("Function");
9426 return cstring_makeLiteralTemp ("Iterator");
9428 return cstring_makeLiteralTemp ("Iterator finalizer");
9430 return cstring_makeLiteralTemp ("Struct tag");
9432 return cstring_makeLiteralTemp ("Union tag");
9434 return cstring_makeLiteralTemp ("Enum tag");
9436 return cstring_makeLiteralTemp ("Optional parameters");
9441 return cstring_makeLiteralTemp ("<Undefined>");
9447 void uentry_setHasNameError (uentry ue)
9449 llassert (uentry_isValid (ue));
9451 ue->hasNameError = TRUE;
9454 void uentry_checkName (uentry ue)
9456 if (uentry_isValid (ue)
9457 && !uentry_isElipsisMarker (ue)
9458 && context_getFlag (FLG_NAMECHECKS)
9459 && !ue->hasNameError
9460 && !uentry_isEndIter (ue)
9461 && !fileloc_isBuiltin (uentry_whereLast (ue))
9462 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
9465 if (uentry_isPriv (ue))
9467 ; /* any checks here? */
9469 else if (fileloc_isExternal (uentry_whereDefined (ue)))
9471 ; /* no errors for externals */
9477 if (uentry_isExpandedMacro (ue))
9483 if (uentry_isExpandedMacro (ue))
9487 else if (uentry_isVariable (ue))
9489 sRef sr = uentry_getSref (ue);
9491 if (sRef_isValid (sr))
9493 scope = sRef_getScope (sr);
9500 else if (uentry_isFunction (ue)
9501 || uentry_isIter (ue)
9502 || uentry_isEndIter (ue)
9503 || uentry_isConstant (ue))
9505 scope = uentry_isStatic (ue) ? fileScope : globScope;
9507 else /* datatypes, etc. must be global */
9512 usymtab_checkDistinctName (ue, scope);
9515 if (context_getFlag (FLG_CPPNAMES))
9517 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
9519 uentry_setHasNameError (ue);
9523 if (scope == globScope)
9525 checkGlobalName (ue);
9527 if (context_getFlag (FLG_ANSIRESERVED))
9529 if (uentry_hasName (ue)
9530 && !uentry_isAnyTag (ue))
9532 if (checkAnsiName (uentry_rawName (ue),
9533 uentry_whereLast (ue)))
9535 uentry_setHasNameError (ue);
9542 checkLocalName (ue);
9544 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
9546 if (uentry_hasName (ue)
9547 && !uentry_isAnyTag (ue))
9549 if (checkAnsiName (uentry_rawName (ue),
9550 uentry_whereLast (ue)))
9552 uentry_setHasNameError (ue);
9558 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
9564 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
9570 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
9571 if (!context_inMacro ())
9573 sRef_setGlobalScopeSafe ();
9576 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
9577 uentry_setUsed (ue, loc);
9579 tloc = fileloc_createExternal ();
9580 uentry_setDefined (ue, tloc);
9581 fileloc_free (tloc);
9582 uentry_setHasNameError (ue);
9584 if (context_getFlag (FLG_REPEATUNRECOG))
9586 uentry_markOwned (ue);
9590 ue = usymtab_supReturnFileEntry (ue);
9593 if (!context_inMacro ())
9595 sRef_clearGlobalScopeSafe ();
9601 /* new start modifications */
9603 void uentry_testInRange (uentry p_e, uentry cconstant) {
9604 if( uentry_isValid(p_e) ) {
9605 if( p_e->sref != NULL) {
9606 char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
9607 int index = atoi( t );
9609 usymtab_testInRange (p_e->sref, index);
9614 void uentry_setStringLength (uentry p_e, uentry cconstant) {
9615 if( uentry_isValid(p_e) ) {
9616 if( p_e->info != NULL) {
9617 if( p_e->info->var != NULL) {
9618 char *t = cstring_toCharsSafe (uentry_unparse(cconstant));
9619 int length = atoi( t );
9621 p_e->info->var->bufinfo->len = length;
9622 p_e->sref->bufinfo.len = length;
9623 printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size);
9630 void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
9631 if( uentry_isValid(p_e) ) {
9632 if( p_e->info != NULL) {
9633 if( p_e->info->var != NULL) {
9634 int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
9635 p_e->info->var->bufinfo->size = size;
9636 p_e->sref->bufinfo.size = size;
9637 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
9638 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
9639 // fprintf(stderr, "and %d\n", size );
9647 /* start modifications */
9649 requires: p_e is defined, is a ptr/array variable
9651 effects: sets the state of the variable
9654 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
9655 if( uentry_isValid(p_e) ) {
9656 if( p_e->info != NULL) {
9657 if( p_e->info->var != NULL) {
9658 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
9659 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9665 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
9669 requires: p_e is defined, is a ptr/array variable
9671 effects: sets the size of the buffer
9674 void uentry_setNullTerminatedState (uentry p_e) {
9675 if( uentry_isValid(p_e) ) {
9676 if( p_e->info != NULL) {
9677 if( p_e->info->var != NULL) {
9678 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
9679 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
9685 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
9690 requires: p_e is defined, is a ptr/array variable
9692 effects: sets the state of the variable
9695 void uentry_setNotNullTerminatedState (uentry p_e) {
9696 if( uentry_isValid(p_e) ) {
9697 if( p_e->info != NULL) {
9698 if( p_e->info->var != NULL) {
9699 p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
9700 p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED;
9706 fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n");
9711 requires: p_e is defined, is a ptr/array variable
9713 effects: sets the size of the buffer
9716 void uentry_setSize (uentry p_e, int size) {
9717 if( uentry_isValid(p_e) ) {
9718 if( p_e->info != NULL) {
9719 if( p_e->info->var != NULL) {
9720 p_e->info->var->bufinfo->size = size;
9721 p_e->sref->bufinfo.size = size;
9727 fprintf(stderr, "uentry:Error in setSize\n");
9732 requires: p_e is defined, is a ptr/array variable
9734 effects: sets the length of the buffer
9737 void uentry_setLen (uentry p_e, int len) {
9738 if( uentry_isValid(p_e) ) {
9739 if( p_e->info != NULL) {
9740 if( p_e->info->var != NULL) {
9741 p_e->info->var->bufinfo->len = len;
9742 p_e->sref->bufinfo.len = len;
9748 fprintf(stderr, "uentry:Error in setLen\n");