2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
28 # include "lclintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
35 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
36 static /*@only@*/ fileloc posLoc = fileloc_undefined;
37 static int nuentries = 0;
38 static int totuentries = 0;
40 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
41 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
42 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
43 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
44 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
45 static void uentry_checkIterArgs (uentry p_ue);
46 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
49 static void checkAliasState (/*@notnull@*/ uentry p_old,
50 /*@notnull@*/ uentry p_unew,
51 bool p_mustConform, bool p_completeConform)
52 /*@modifies p_old, p_unew@*/ ;
53 static void checkNullState (/*@notnull@*/ uentry p_old,
54 /*@notnull@*/ uentry p_unew,
55 bool p_mustConform, bool p_completeConform)
56 /*@modifies p_old, p_unew@*/ ;
58 static void checkVarConformance (/*@notnull@*/ uentry p_old,
59 /*@notnull@*/ uentry p_unew,
60 bool p_mustConform, bool p_completeConform)
61 /*@modifies p_old, p_unew@*/;
64 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
65 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
68 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
70 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
71 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
74 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
75 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
76 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
77 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
78 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
80 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
81 ctype p_oldType, /*@notnull@*/ uentry p_unew,
82 /*@notnull@*/ uentry p_newCurrent,
83 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
85 static /*@only@*/ /*@notnull@*/ uentry
86 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
87 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
89 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
91 uentry ue = (uentry) dmalloc (sizeof (*ue));
98 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
99 static void uentry_copyInto (/*@out@*/ /*@unique@*/ uentry p_unew, uentry p_old);
100 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
101 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
102 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
103 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
104 static void uvinfo_free (/*@only@*/ uvinfo p_u);
108 static /*@only@*/ cstring ancontext_unparse (ancontext an)
112 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
113 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
114 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
115 case AN_SUFIELD: return cstring_makeLiteral ("su field");
116 case AN_TDEFN: return cstring_makeLiteral ("type definition");
117 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
118 case AN_CONST: return cstring_makeLiteral ("constant");
124 static int annots[AN_LAST][QU_LAST];
125 static int decls[AN_LAST];
126 static int shdecls[AN_LAST];
127 static int idecls[AN_LAST];
133 for (i = AN_UNKNOWN; i < AN_LAST; i++)
139 for (j = QU_UNKNOWN; j < QU_LAST; j++)
146 static void tallyAnnot (ancontext ac, qual q)
160 for (j = QU_UNKNOWN; j < QU_LAST; j++)
165 for (i = AN_UNKNOWN; i < AN_LAST; i++)
171 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
172 ancontext_unparse (i),
173 decls[i], shdecls[i], idecls[i]);
175 totdecls += decls[i];
176 totshdecls += shdecls[i];
177 totidecls += idecls[i];
179 for (j = QU_UNKNOWN; j < QU_LAST; j++)
181 total[j] += annots[i][j];
182 alltotals += annots[i][j];
185 printf (" Allocation:\n");
189 for (j = QU_UNKNOWN; j < QU_LAST; j++)
191 if (qual_isAliasQual (j) && !qual_isUnique (j))
193 if (annots[i][j] > 0)
195 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
196 100.0 * (double)annots[i][j] / (double)decls[i]);
197 tmptot += annots[i][j];
202 printf (" Exposure:\n");
206 for (j = QU_UNKNOWN; j < QU_LAST; j++)
208 if (qual_isExQual (j))
210 if (annots[i][j] > 0)
212 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
213 100.0 * (double)annots[i][j] / (double)decls[i]);
214 tmptot += annots[i][j];
219 printf (" Definition:\n");
221 for (j = QU_UNKNOWN; j < QU_LAST; j++)
223 if (qual_isAllocQual (j))
225 if (annots[i][j] > 0)
227 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
228 100.0 * (double)annots[i][j] / (double)decls[i]);
235 for (j = QU_UNKNOWN; j < QU_LAST; j++)
237 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
239 if (annots[i][j] > 0)
241 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
242 100.0 * (double)annots[i][j] / (double)decls[i]);
251 for (j = QU_UNKNOWN; j < QU_LAST; j++)
255 for (i = AN_UNKNOWN; i < AN_LAST; i++)
257 if (annots[i][j] > 0)
266 printf ("Annotation: %s\n", qual_unparse (j));
268 for (i = AN_UNKNOWN; i < AN_LAST; i++)
270 if (annots[i][j] > 0)
272 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
279 printf ("All Contexts\n");
281 for (j = QU_UNKNOWN; j < QU_LAST; j++)
285 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
286 100.0 * (double)total[j] / (double)(totdecls));
291 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
293 extern void uentry_tallyAnnots (uentry u, ancontext kind)
295 alkind ak = sRef_getAliasKind (u->sref);
296 exkind ek = sRef_getExKind (u->sref);
297 nstate ns = sRef_getNullState (u->sref);
298 sstate ss = sRef_getDefState (u->sref);
299 bool recordUnknown = FALSE;
302 if (kind == AN_UNKNOWN)
310 else if (e == KCONST || e == KENUMCONST)
314 else if (e == KFCN || e == KITER)
316 uentryList params = uentry_getParams (u);
319 uentryList_elements (params, current)
321 if (uentry_isReturned (current))
325 if (!uentry_isElipsisMarker (current))
327 uentry_tallyAnnots (current, AN_FCNPARAM);
329 } end_uentryList_elements;
333 if (ctype_isFunction (u->utype)
335 && ctype_isVisiblySharable (ctype_realType (ctype_returnValue (u->utype))))
337 recordUnknown = TRUE;
340 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
342 ctype t = ctype_realType (u->utype);
346 uentryList fields = ctype_getFields (t);
348 uentryList_elements (fields, current)
350 uentry_tallyAnnots (current, AN_SUFIELD);
352 } end_uentryList_elements;
356 if (ctype_isVisiblySharable (u->utype))
358 recordUnknown = TRUE;
366 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
368 recordUnknown = TRUE;
375 if (kind == AN_FCNRETURN)
389 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
394 if (ctype_isRealPointer (ctype_realType (u->utype)))
411 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
412 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
413 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
414 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
418 if (uentry_isReturned (u))
420 tallyAnnot (kind, QU_RETURNED);
426 if (ctype_isRefCounted (ctype_realType (u->utype))
427 || (ctype_isFunction (u->utype) &&
428 ctype_isRefCounted (ctype_realType (ctype_returnValue (u->utype)))))
434 if (kind == AN_FCNPARAM)
436 tallyAnnot (kind, QU_TEMP);
438 else if (recordUnknown)
440 if (kind == AN_FCNRETURN)
443 tallyAnnot (kind, QU_UNKNOWN);
447 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
448 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
449 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
450 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
452 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
453 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
454 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
455 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
456 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
457 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
458 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
459 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
460 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
461 case AK_IMPDEPENDENT:
462 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
472 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
473 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
479 case NS_ERROR: break;
480 case NS_UNKNOWN: break;
481 case NS_NOTNULL: break;
482 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
483 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
484 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
485 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
487 case NS_ABSNULL: break;
493 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
497 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
498 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
499 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
500 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
501 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
507 static specCode specCode_fromInt (int i)
510 llassert (i >= SPC_NONE && i < SPC_LAST);
512 return ((specCode) i);
516 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
518 if (uentry_isDeclared (u))
520 return cstring_makeLiteralTemp ("previously declared");
524 return cstring_makeLiteralTemp ("specified");
528 /*@observer@*/ cstring uentry_specDeclName (uentry u)
530 if (uentry_isDeclared (u))
532 return cstring_makeLiteralTemp ("previous declaration");
536 return cstring_makeLiteralTemp ("specification");
540 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
542 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
544 return cstring_makeLiteralTemp ("redefined");
546 else if (uentry_isCodeDefined (unew))
548 return cstring_makeLiteralTemp ("defined");
550 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
552 return cstring_makeLiteralTemp ("redeclared");
556 return cstring_makeLiteralTemp ("declared");
562 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
564 if (uentry_isValid (ue))
567 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
569 TPRINTF(( (message( "Function pointer %s not doing uentry_makeVarFunction", uentry_unparse(ue) )) ));
570 // uentry_makeVarFunction (ue);
573 //llassert (uentry_isFunction (ue));
574 //llassert ((ue->info->fcn->preconditions));
575 //llassert ((ue->info->fcn->preconditions));
576 if (!uentry_isFunction (ue))
578 DPRINTF ( (message ("called uentry_getFcnPreconditions on nonfunction %s",
579 uentry_unparse (ue) ) ) );
580 if (!uentry_isSpecified (ue) )
582 DPRINTF((message ("called uentry_getFcnPreconditions on nonfunction %s",
583 uentry_unparse (ue) ) ));
584 return constraintList_undefined;
588 return constraintList_undefined;
591 if (ue->info->fcn->preconditions != NULL)
593 return constraintList_copy (ue->info->fcn->preconditions);
603 return constraintList_undefined;
611 constraintList uentry_getFcnPostconditions (uentry ue)
613 if (uentry_isValid (ue))
616 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
618 TPRINTF(( (message( "Function pointer %s not doing uentry_makeVarFunction", uentry_unparse(ue) )) ));
619 //uentry_makeVarFunction (ue);
622 //llassert (uentry_isFunction (ue));
623 //llassert ((ue->info->fcn->preconditions));
624 /* if (!uentry_isSpecified (ue) )
626 TPRINTF((message ("called uentry_getFcnPostconditions on nonfunction %s",
627 uentry_unparse (ue) ) ));
628 // return constraintList_undefined;
631 if (!uentry_isFunction (ue))
633 /*llcontbug*/ DPRINTF( (message ("called uentry_getFcnPostconditions on nonfunction %s",
634 uentry_unparse (ue) ) ) );
635 return constraintList_undefined;
638 if (ue->info->fcn->postconditions)
640 return constraintList_copy (ue->info->fcn->postconditions);
650 return constraintList_undefined;
655 static /*@only@*/ fileloc setLocation (void)
657 fileloc fl = context_getSaveLocation ();
659 if (fileloc_isDefined (fl))
665 return fileloc_copy (g_currentloc);
669 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
671 fileloc loc = setLocation ();
672 uentry ue = uentry_makeConstant (n, t, loc);
674 ue->ukind = KENUMCONST;
675 uentry_setDefined (ue, loc);
679 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
681 fileloc loc = setLocation ();
682 uentry ue = uentry_makeConstant (n, t, loc);
683 ctype etype = exprNode_getType (expr);
685 if (!ctype_isRealInt (etype)) {
689 ("Value of enum member is not an integeral type (type %s): %s",
690 ctype_unparse (etype), exprNode_unparse (expr)),
691 exprNode_loc (expr));
694 ue->ukind = KENUMCONST;
695 uentry_setDefined (ue, loc);
700 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
702 uentry ue = uentry_makeConstant (n, t, loc);
704 ue->ukind = KENUMCONST;
709 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
711 return uentry_makeVariable (n, t, setLocation (), FALSE);
715 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
717 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
721 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
723 ctype ct = idDecl_getCtype (id);
724 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
725 MAYBE, MAYBE, setLocation ());
727 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
729 if (!ynm_isOn (ue->info->datatype->abs))
731 if (ctype_isUnknown (ct))
733 ue->info->datatype->mut = MAYBE;
737 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
744 void uentry_checkParams (uentry ue)
746 if (uentry_isValid (ue))
748 bool isExt = uentry_isExtern (ue);
750 if (uentry_isRealFunction (ue))
752 uentryList params = uentry_getParams (ue);
754 uentryList_elements (params, current)
756 if (uentry_isValid (current))
758 ctype ct = current->utype;
760 if (ctype_isFixedArray (ct))
762 if (ctype_isArray (ctype_baseArrayPtr (ct))
763 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
770 (FLG_FIXEDFORMALARRAY,
771 message ("Function parameter %q declared as "
772 "manifest array (size constant is meaningless)",
773 uentry_getName (current)),
774 uentry_whereDeclared (current));
779 if (ctype_isArray (ct))
783 message ("Function parameter %q declared as "
784 "array (treated as pointer)",
785 uentry_getName (current)),
786 uentry_whereDeclared (current));
790 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
792 if (ctype_isAbstract (ct) &&
793 (isExt || (ctype_isAbstract (ctype_realType (ct))
794 && !context_hasFileAccess (ctype_typeId (ct)))))
799 ("Function %q declared with notnull parameter %q of abstract "
802 uentry_getName (current),
805 ("Since %s is an abstract type, notnull can only be "
806 "used for parameters if the function is static to a "
807 "module where %s is accessible.",
810 uentry_whereDeclared (current));
814 } end_uentryList_elements;
816 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
818 ctype ct = ue->utype;
820 if (ctype_isAbstract (ct)
821 && (isExt || (ctype_isAbstract (ctype_realType (ct))
822 && !context_hasFileAccess (ctype_typeId (ct)))))
827 ("%s %q declared %s notnull storage of abstract type %s",
828 ekind_capName (uentry_getKind (ue)),
833 ("Since %s is an abstract type, notnull can only be used "
834 "if it is static to a module where %s is accessible.",
837 uentry_whereDeclared (ue));
844 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
846 alkind ak = sRef_getAliasKind (ue->sref);
848 if (alkind_isRefCounted (ak))
850 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
854 if (alkind_isUnknown (ak))
856 exkind ek = sRef_getExKind (ue->sref);
858 if (exkind_isKnown (ek))
860 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
864 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
866 if (ctype_isVisiblySharable
867 (ctype_realType (ctype_returnValue (ue->utype))))
869 if (uentryList_hasReturned (uentry_getParams (ue)))
875 sRef_setAliasKind (ue->sref, AK_IMPONLY,
885 static /*@notnull@*/ uentry
886 uentry_makeFunctionAux (cstring n, ctype t,
888 /*@only@*/ globSet globs,
889 /*@only@*/ sRefSet mods,
890 /*@keep@*/ fileloc f, bool priv,
891 /*@unused@*/ bool isForward)
893 uentry e = uentry_alloc ();
896 if (ctype_isFunction (t))
898 ret = ctype_returnValue (t);
902 if (ctype_isKnown (t))
904 llbug (message ("not function: %s", ctype_unparse (t)));
911 if (fileloc_isSpec (f) || fileloc_isImport (f))
913 e->whereSpecified = f;
914 e->whereDeclared = fileloc_undefined;
918 e->whereSpecified = fileloc_undefined;
919 e->whereDeclared = f;
922 /* e->shallowCopy = FALSE; */
923 e->uname = cstring_copy (n);
925 e->storageclass = SCNONE;
927 e->sref = sRef_makeType (ret);
929 if (ctype_isUA (ret))
931 sRef_setStateFromType (e->sref, ret);
936 e->uses = filelocList_new ();
938 e->hasNameError = FALSE;
940 e->info = (uinfo) dmalloc (sizeof (*e->info));
941 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
943 e->info->fcn->hasMods = sRefSet_isDefined (mods);
944 e->info->fcn->hasGlobs = globSet_isDefined (globs);
946 e->info->fcn->exitCode = XK_UNKNOWN;
947 e->info->fcn->nullPred = QU_UNKNOWN;
948 e->info->fcn->specialCode = SPC_NONE;
950 e->info->fcn->access = access;
951 e->info->fcn->globs = globs;
952 e->info->fcn->defparams = uentryList_undefined;
954 sRef_setDefined (e->sref, f);
955 e->whereDefined = fileloc_undefined;
957 e->info->fcn->mods = sRefSet_undefined;
958 e->info->fcn->specclauses = NULL;
961 e->info->fcn->preconditions = NULL;
965 e->info->fcn->postconditions = NULL;
968 checkGlobalsModifies (e, mods);
969 e->info->fcn->mods = mods;
974 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
977 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
978 typeId_invalid, globSet_undefined,
982 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
983 reflectImplicitFunctionQualifiers (ue, FALSE);
985 if (!uentry_isStatic (ue)
986 && cstring_equalLit (ue->uname, "main"))
988 ctype typ = ue->utype;
992 llassert (ctype_isFunction (typ));
994 retval = ctype_returnValue (typ);
996 if (!ctype_isInt (retval))
1000 message ("Function main declared to return %s, should return int",
1001 ctype_unparse (retval)),
1002 uentry_whereDeclared (ue));
1005 args = ctype_argsFunction (typ);
1007 if (uentryList_isMissingParams (args)
1008 || uentryList_size (args) == 0)
1014 if (uentryList_size (args) != 2)
1018 message ("Function main declared with %d arg%p, "
1019 "should have 2 (int argc, char *argv[])",
1020 uentryList_size (args)),
1021 uentry_whereLast (ue));
1025 uentry arg = uentryList_getN (args, 0);
1026 ctype ct = uentry_getType (arg);
1028 if (!ctype_isInt (ct))
1032 message ("Parameter 1, %q, of function main declared "
1033 "with type %t, should have type int",
1034 uentry_getName (arg), ct),
1035 uentry_whereDeclared (arg));
1038 arg = uentryList_getN (args, 1);
1039 ct = uentry_getType (arg);
1041 if (ctype_isArrayPtr (ct)
1042 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1043 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1051 message ("Parameter 2, %q, of function main declared "
1052 "with type %t, should have type char **",
1053 uentry_getName (arg), ct),
1054 uentry_whereDeclared (arg));
1063 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1065 alkind ak = sRef_getAliasKind (e->sref);
1067 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1068 && context_getFlag (FLG_PARAMIMPTEMP))
1070 exkind ek = sRef_getExKind (e->sref);
1072 if (exkind_isKnown (ek))
1074 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1075 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1079 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1080 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1085 static /*@only@*/ /*@notnull@*/ uentry
1086 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
1088 cstring pname = makeParam (n);
1089 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
1091 cstring_free (pname);
1092 uentry_implicitParamAnnots (e);
1094 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1096 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1097 e->info->var->defstate = defstate;
1105 uentry_setRefCounted (uentry e)
1107 if (uentry_isValid (e))
1109 uentry_setAliasKind (e, AK_REFCOUNTED);
1110 sRef_storeState (e->sref);
1116 uentry_setStatic (uentry c)
1118 if (uentry_isValid (c))
1120 alkind ak = sRef_getAliasKind (c->sref);
1121 c->storageclass = SCSTATIC;
1123 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1125 if (!alkind_isUnknown (ak)
1126 && !alkind_isStatic (ak))
1128 if (!(ctype_isRealPointer (uentry_getType (c)))
1129 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1130 && !alkind_isRefCounted (ak))
1132 if (alkind_isImplicit (ak)
1133 && alkind_isDependent (ak)
1134 && ctype_isArray (uentry_getType (c)))
1136 ; /* no error for observer arrays */
1142 message ("Static storage %q declared as %s",
1144 alkind_unparse (ak)),
1145 uentry_whereDeclared (c));
1151 if (alkind_isUnknown (ak)
1152 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1153 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1155 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1156 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1164 uentry_setExtern (uentry c)
1166 if (uentry_isValid (c))
1167 c->storageclass = SCEXTERN;
1171 uentry_setParamNo (uentry ue, int pno)
1173 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1174 sRef_setParamNo (ue->sref, pno);
1178 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1180 sRefSet_allElements (sr, el)
1182 sRef base = sRef_getRootBase (el);
1184 if (sRef_isGlobal (base) || sRef_isInternalState (base)
1185 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1187 if (!globSet_member (ue->info->fcn->globs, base))
1189 if (uentry_hasGlobs (ue)
1190 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1193 (FLG_WARNMISSINGGLOBALS,
1195 ("Modifies list for %q uses global %q, "
1196 "not included in globals list.",
1197 uentry_getName (ue),
1198 sRef_unparse (base)),
1199 uentry_whereLast (ue)))
1201 uentry_showWhereSpecified (ue);
1205 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1207 if (sRef_isFileStatic (base))
1209 context_recordFileGlobals (ue->info->fcn->globs);
1213 } end_sRefSet_allElements;
1217 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
1219 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
1223 uentry_fixupSref (uentry ue)
1227 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1232 sr = uentry_getSref (ue);
1234 sRef_resetState (sr);
1235 sRef_clearDerived (sr);
1237 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1238 llassert (sRef_isValid (sr));
1240 if (uentry_isVariable (ue))
1242 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1243 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1247 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
1249 llassert (uentry_isFunction (ue));
1250 llassert (!specialClauses_isDefined (ue->info->fcn->specclauses));
1252 ue->info->fcn->specclauses = clauses;
1253 specialClauses_checkAll (ue);
1257 ** Used for @modifies@ @endmodifies@ syntax.
1259 ** If ue is specified, sr must contain *only*:
1261 ** o file static globals
1262 ** o sRef's derived from modifies spec (i.e., more specific than
1263 ** what was specified)
1265 ** Otherwise, if sr has modifies it must match sr.
1267 ** If it doesn't have modifies, set them to sr.
1271 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1273 if (sRef_modInFunction ())
1276 (message ("Modifies list not in function context. "
1277 "A modifies list can only appear following the parameter list "
1278 "in a function declaration or header."));
1280 /*@-mustfree@*/ return; /*@=mustfree@*/
1283 if (sRefSet_hasStatic (sr))
1285 context_recordFileModifies (sr);
1288 if (uentry_isValid (ue))
1290 if (uentry_isIter (ue))
1292 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1293 ue->info->iter->mods = sr;
1297 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1299 uentry_makeVarFunction (ue);
1302 llassertfatal (uentry_isFunction (ue));
1303 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1305 ue->info->fcn->mods = sr;
1306 ue->info->fcn->hasMods = TRUE;
1308 checkGlobalsModifies (ue, sr);
1311 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1313 ue->info->fcn->hasGlobs = TRUE;
1323 uentry_setPreconditions (uentry ue, /*@owned@*/ constraintList preconditions)
1325 if (sRef_modInFunction ())
1328 (message ("Precondition list not in function context. "
1329 "A precondition list can only appear following the parameter list "
1330 "in a function declaration or header."));
1332 /*@-mustfree@*/ return; /*@=mustfree@*/
1335 if (uentry_isValid (ue))
1338 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1340 uentry_makeVarFunction (ue);
1343 llassertfatal (uentry_isFunction (ue));
1344 // llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1346 if ((ue->info->fcn->preconditions) != NULL )
1348 constraintList_free(ue->info->fcn->preconditions);
1349 ue->info->fcn->preconditions = preconditions;
1352 ue->info->fcn->preconditions = preconditions;
1367 uentry_setPostconditions (uentry ue, /*@owned@*/ constraintList postconditions)
1369 if (sRef_modInFunction ())
1372 (message ("Postcondition list not in function context. "
1373 "A postcondition list can only appear following the parameter list "
1374 "in a function declaration or header."));
1376 /*@-mustfree@*/ return; /*@=mustfree@*/
1379 if (uentry_isValid (ue))
1382 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
1384 uentry_makeVarFunction (ue);
1387 llassertfatal (uentry_isFunction (ue));
1388 // llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1390 if ((ue->info->fcn->postconditions ) == NULL)
1391 ue->info->fcn->postconditions = postconditions;
1394 constraintList_free(ue->info->fcn->postconditions);
1395 ue->info->fcn->postconditions = postconditions;
1408 ** requires: new and old are functions
1412 checkGlobalsConformance (/*@notnull@*/ uentry old,
1413 /*@notnull@*/ uentry unew,
1414 bool mustConform, bool completeConform)
1416 bool hasInternalState = FALSE;
1418 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1420 if (globSet_isDefined (unew->info->fcn->globs))
1422 globSet_allElements (unew->info->fcn->globs, el)
1424 if (sRef_isFileStatic (el))
1426 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1428 if (sRef_isInvalid (sr))
1430 bool hasError = FALSE;
1432 if (!hasInternalState
1433 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1434 sRef_makeInternalState ()))
1435 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1436 sRef_makeSpecState ())))
1439 && !uentry_isStatic (old)
1442 message ("Globals list for %q includes internal state, %q, "
1443 "but %s without globals internalState.",
1444 uentry_getName (old),
1446 uentry_specOrDefName (old)),
1447 uentry_whereLast (unew)))
1449 uentry_showWhereSpecified (old);
1453 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1454 sRef_makeInternalState ());
1455 hasInternalState = TRUE;
1459 && fileloc_sameFile (uentry_whereDeclared (unew),
1460 uentry_whereDeclared (old)))
1465 message ("Function %q inconsistently %rdeclared (in "
1466 "same file) with file static global %q in "
1468 uentry_getName (unew),
1469 uentry_isDeclared (old),
1471 uentry_whereDeclared (unew)))
1473 uentry_showWhereSpecified (old);
1478 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1479 context_recordFileGlobals (old->info->fcn->globs);
1483 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1485 if (sRef_isInvalid (sr))
1490 message ("Function %q inconsistently %rdeclared with "
1491 "%q in globals list",
1492 uentry_getName (unew),
1493 uentry_isDeclared (old),
1495 uentry_whereDeclared (unew)))
1497 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1498 uentry_showWhereSpecified (old);
1503 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1509 ("Function %q global %q inconsistently "
1510 "%rdeclared as %qout global",
1511 uentry_getName (unew),
1513 uentry_isDeclared (old),
1514 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1515 uentry_whereDeclared (unew)))
1517 uentry_showWhereSpecified (old);
1522 } end_globSet_allElements ;
1524 if (completeConform)
1526 globSet_allElements (old->info->fcn->globs, el)
1528 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1530 if (sRef_isInvalid (sr))
1533 && uentry_isReallySpecified (old)
1536 message ("Function %q specified with %q in globals list, "
1537 "but declared without %q",
1538 uentry_getName (unew),
1541 uentry_whereDeclared (unew)))
1543 uentry_showWhereSpecified (old);
1546 } end_globSet_allElements;
1551 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1553 if (uentry_isReallySpecified (old)
1556 message ("%s %q specified with globals list, but "
1557 "declared with no globals",
1558 ekind_capName (unew->ukind),
1559 uentry_getName (unew)),
1560 uentry_whereDeclared (unew)))
1563 (message ("Specification globals: %q",
1564 globSet_unparse (old->info->fcn->globs)),
1565 uentry_whereSpecified (old));
1569 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
1570 old->info->fcn->globs);
1575 ** new modifies list must be included by old modifies list.
1577 ** file static state may be added to new, if old has internal.
1581 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1582 bool mustConform, bool completeConform)
1585 bool changedMods = FALSE;
1586 bool modInternal = FALSE;
1588 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1590 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1591 newMods = unew->info->fcn->mods;
1593 if (sRefSet_isEmpty (newMods))
1595 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1596 && uentry_isReallySpecified (old))
1600 message ("%s %q specified with modifies clause, "
1601 "but declared with no modifies clause",
1602 ekind_capName (unew->ukind),
1603 uentry_getName (unew)),
1604 uentry_whereDeclared (unew)))
1606 llgenindentmsg (message ("Specification has modifies %q",
1607 sRefSet_unparse (old->info->fcn->mods)),
1608 uentry_whereSpecified (old));
1615 sRefSet_allElements (newMods, current)
1617 if (sRef_isValid (current))
1619 sRef rb = sRef_getRootBase (current);
1621 if (sRef_isFileStatic (rb))
1625 if (!sRefSet_isSameMember (old->info->fcn->mods,
1626 sRef_makeInternalState ())
1627 && !sRefSet_isSameMember (old->info->fcn->mods,
1628 sRef_makeSpecState ()))
1631 && !uentry_isStatic (old)
1635 ("Modifies list for %q includes internal state, "
1636 "but %s without modifies internal.",
1637 uentry_getName (old),
1638 uentry_specOrDefName (old)),
1639 uentry_whereLast (unew)))
1641 uentry_showWhereSpecified (old);
1644 old->info->fcn->mods =
1645 sRefSet_insert (old->info->fcn->mods,
1646 sRef_makeInternalState ());
1651 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1657 if (sRef_canModifyVal (current, old->info->fcn->mods))
1659 int size = sRefSet_size (old->info->fcn->mods);
1661 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1664 if (sRefSet_size (old->info->fcn->mods) != size)
1675 ("Modifies list for %q contains %q, not modifiable "
1677 uentry_getName (old),
1678 sRef_unparse (current),
1679 uentry_specDeclName (old)),
1680 uentry_whereLast (unew)))
1682 uentry_showWhereSpecified (old);
1687 } end_sRefSet_allElements;
1689 if (completeConform && uentry_isReallySpecified (old))
1691 sRefSet_allElements (old->info->fcn->mods, el)
1693 if (sRef_canModify (el, newMods))
1702 ("Specification modifies clause for %q contains %q, "
1703 "not included in declaration modifies clause",
1704 uentry_getName (old),
1706 uentry_whereLast (unew)))
1708 uentry_showWhereSpecified (old);
1711 } end_sRefSet_allElements ;
1715 ** Make sure file static elements will be removed.
1720 context_recordFileModifies (old->info->fcn->mods);
1725 uentry_checkMutableType (uentry ue)
1727 ctype ct = uentry_getType (ue);
1729 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1731 voptgenerror (FLG_MUTREP,
1732 message ("Mutable abstract type %q declared without pointer "
1733 "indirection: %t (violates assignment semantics)",
1734 uentry_getName (ue), ct),
1735 uentry_whereDeclared (ue));
1740 uentry_setMutable (uentry e)
1742 llassert (uentry_isDatatype (e));
1743 e->info->datatype->mut = YES;
1747 uentry_checkIterArgs (uentry ue)
1749 bool hasYield = FALSE;
1752 llassert (uentry_isIter (ue));
1754 args = uentry_getParams (ue);
1756 uentryList_elements (args, el)
1758 sstate ds = uentry_getDefState (el);
1760 if (uentry_isYield (el))
1765 if (sstate_isUnknown (ds))
1767 uentry_setDefState (el, SS_DEFINED);
1773 } end_uentryList_elements;
1777 voptgenerror (FLG_HASYIELD,
1778 message ("Iterator %q declared with no yield parameters",
1779 uentry_getName (ue)),
1780 uentry_whereDeclared (ue));
1785 chkind_fromQual (qual qel)
1787 if (qual_isChecked (qel))
1791 else if (qual_isCheckMod (qel))
1795 else if (qual_isCheckedStrict (qel))
1797 return CH_CHECKEDSTRICT;
1799 else if (qual_isUnchecked (qel))
1801 return CH_UNCHECKED;
1806 /*@notreached@*/ return CH_UNKNOWN;
1811 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
1813 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
1815 if (!uentry_isRefCounted (ue))
1819 message ("Reference counting qualifier %s used on non-reference "
1820 "counted storage: %q",
1822 uentry_unparse (ue)));
1826 alkind ak = alkind_fromQual (qel);
1828 uentry_setAliasKind (ue, ak);
1831 else if (qual_isRefCounted (qel))
1833 ctype ct = ctype_realType (uentry_getType (ue));
1836 if (ctype_isPointer (ct)
1837 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
1839 /* check there is a refs field */
1840 uentryList fields = ctype_getFields (rt);
1841 uentry refs = uentry_undefined;
1843 uentryList_elements (fields, field)
1845 if (uentry_isRefsField (field))
1847 if (uentry_isValid (refs))
1851 message ("Reference counted structure type %s has "
1852 "multiple refs fields: %q and %q",
1854 uentry_getName (refs),
1855 uentry_getName (field)));
1860 } end_uentryList_elements;
1862 if (uentry_isInvalid (refs))
1866 message ("Reference counted structure type %s has "
1868 ctype_unparse (ct)),
1870 ("To count reference, the structure must have a field named "
1871 "refs of type int."),
1874 else if (!ctype_isInt (uentry_getType (refs)))
1878 message ("Reference counted structure type %s refs field has "
1879 "type %s (should be int)", ctype_unparse (ct),
1880 ctype_unparse (uentry_getType (refs))));
1884 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1885 uentry_whereDeclared (ue));
1890 if ((ctype_isPointer (ct)
1891 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
1892 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
1894 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
1895 uentry_whereDeclared (ue));
1901 message ("Non-pointer to structure type %s declared with "
1902 "refcounted qualifier",
1903 ctype_unparse (ct)));
1907 else if (qual_isRefs (qel))
1909 if (uentry_isVariable (ue) && !uentry_isParam (ue))
1911 uentry_setAliasKind (ue, AK_REFS);
1917 message ("Refs qualifier used on non-structure field: %q",
1918 uentry_unparse (ue)));
1921 else if (qual_isAliasQual (qel))
1923 alkind ak = alkind_fromQual (qel);
1925 alkind oldak = uentry_getAliasKind (ue);
1926 ctype ut = uentry_getType (ue);
1928 if (alkind_isImplicit (ak)
1929 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
1931 /* ignore the implied qualifier */
1935 if (uentry_isEitherConstant (ue))
1939 message ("Alias qualifier %s used on constant: %q",
1940 alkind_unparse (ak), uentry_unparse (ue)));
1944 if (ctype_isFunction (ut))
1946 ut = ctype_returnValue (ut);
1949 if (!(ctype_isVisiblySharable (ut)
1950 || ctype_isRealArray (ut)
1951 || ctype_isRealSU (ut)))
1953 if (!qual_isImplied (qel))
1957 message ("Alias qualifier %s used on unsharable storage type %t: %q",
1958 alkind_unparse (ak), ut, uentry_getName (ue)));
1965 if (uentry_isRefCounted (ue))
1967 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
1968 || qual_isExposed (qel)
1969 || qual_isObserver (qel)))
1971 if (!qual_isImplied (qel))
1976 ("Alias qualifier %s used on reference counted storage: %q",
1977 alkind_unparse (ak),
1978 uentry_unparse (ue)));
1986 if (qual_isRefQual (qel))
1990 message ("Qualifier %s used on non-reference counted storage: %q",
1991 alkind_unparse (ak), uentry_unparse (ue)));
2000 uentry_setAliasKind (ue, ak);
2003 else if (qual_isNull (qel))
2005 if (uentry_isConstant (ue))
2009 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2010 uentry_whereDeclared (ue));
2014 uentry_setNullState (ue, NS_POSNULL);
2017 else if (qual_isRelNull (qel))
2019 uentry_setNullState (ue, NS_RELNULL);
2021 else if (qual_isNotNull (qel))
2023 uentry_setNullState (ue, NS_MNOTNULL);
2025 else if (qual_isAbstract (qel)
2026 || qual_isConcrete (qel))
2028 if (!uentry_isDatatype (ue))
2032 message ("Qualifier %s used with non-datatype",
2033 qual_unparse (qel)));
2037 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2040 else if (qual_isMutable (qel))
2042 if (!uentry_isDatatype (ue))
2044 llerror (FLG_SYNTAX,
2045 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
2049 if (!ynm_isOn (ue->info->datatype->mut))
2051 uentry_checkMutableType (ue);
2054 ue->info->datatype->mut = YES;
2057 else if (qual_isImmutable (qel))
2059 if (!uentry_isDatatype (ue))
2061 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
2062 qual_unparse (qel)));
2066 ue->info->datatype->mut = NO;
2069 else if (qual_isNullPred (qel))
2071 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2073 uentry_makeVarFunction (ue);
2076 if (uentry_isFunction (ue))
2078 ctype typ = uentry_getType (ue);
2079 ctype rtype = ctype_returnValue (uentry_getType (ue));
2081 if (ctype_isRealBool (rtype))
2083 uentryList pl = ctype_argsFunction (typ);
2085 if (uentryList_size (pl) == 1)
2087 ue->info->fcn->nullPred = qel;
2091 llerror (FLG_SYNTAX,
2092 message ("Qualifier %s used with function having %d "
2093 "arguments (should have 1)",
2095 uentryList_size (pl)));
2100 llerror (FLG_SYNTAX,
2101 message ("Qualifier %s used with function returning %s "
2102 "(should return bool)",
2104 ctype_unparse (rtype)));
2109 llerror (FLG_SYNTAX,
2110 message ("Qualifier %s used with non-function",
2111 qual_unparse (qel)));
2114 else if (qual_isExitQual (qel))
2116 exitkind exk = exitkind_fromQual (qel);
2118 if (uentry_isFunction (ue))
2120 if (exitkind_isKnown (ue->info->fcn->exitCode))
2122 llerror (FLG_SYNTAX,
2123 message ("Multiple exit qualifiers used on function %q: %s, %s",
2124 uentry_getName (ue),
2125 exitkind_unparse (ue->info->fcn->exitCode),
2126 exitkind_unparse (exk)));
2129 ue->info->fcn->exitCode = exk;
2133 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2135 uentry_makeVarFunction (ue);
2136 ue->info->fcn->exitCode = exk;
2140 llerror (FLG_SYNTAX,
2141 message ("Exit qualifier %s used with non-function (type %s)",
2143 ctype_unparse (uentry_getType (ue))));
2149 if (qual_isCQual (qel))
2155 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
2161 uentry_reflectQualifiers (uentry ue, qualList q)
2163 llassert (uentry_isValid (ue));
2165 qualList_elements (q, qel)
2167 if (qual_isStatic (qel))
2169 uentry_setStatic (ue);
2171 else if (qual_isUnused (qel))
2173 uentry_setUsed (ue, fileloc_undefined);
2175 else if (qual_isExternal (qel))
2177 fileloc_free (ue->whereDefined);
2178 ue->whereDefined = fileloc_createExternal ();
2180 else if (qual_isSef (qel))
2182 if (uentry_isVariable (ue))
2184 vkind vk = ue->info->var->kind;
2186 llassert (vk != VKREFPARAM);
2188 if (vk == VKYIELDPARAM)
2192 message ("Qualifier sef cannot be used with %s: %q",
2193 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2194 uentry_unparse (ue)));
2196 else if (vk == VKRETPARAM)
2198 ue->info->var->kind = VKSEFRETPARAM;
2202 ue->info->var->kind = VKSEFPARAM;
2209 message ("Qualifier sef is meaningful only on parameters: %q",
2210 uentry_unparse (ue)));
2213 else if (qual_isExtern (qel))
2215 ue->storageclass = SCEXTERN;
2217 else if (qual_isGlobalQual (qel)) /* undef, killed */
2219 if (uentry_isVariable (ue))
2221 sstate oldstate = ue->info->var->defstate;
2222 sstate defstate = sstate_fromQual (qel);
2225 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2226 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2228 defstate = SS_UNDEFKILLED;
2235 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2236 ue->info->var->defstate = defstate;
2242 message ("Qualifier %s used on non-variable: %q",
2243 qual_unparse (qel), uentry_unparse (ue)));
2246 /* start modifications */
2248 else if( qual_isBufQualifier(qel) ) {
2249 ctype ct = ctype_realType(uentry_getType(ue));
2251 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2253 if( uentry_hasBufStateInfo(ue) ) {
2255 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2257 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2258 /* If formal func param */
2259 uentry_setNullTerminatedState(ue);
2260 uentry_setLen (ue, 1);
2261 uentry_setSize (ue, 1);
2263 sRef_setNullTerminatedState(uentry_getSref(ue));
2264 sRef_setLen (uentry_getSref(ue), 1);
2265 sRef_setSize (uentry_getSref(ue), 1);
2267 uentry_setPossiblyNullTerminatedState(ue);
2269 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2273 /* put other BufState Qualifiers here */
2275 cstring s = uentry_getName(ue);
2276 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2277 struct for identifier %s\n", s) );
2279 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2281 sRef retSref = uentry_getSref (ue);
2282 ctype retType = sRef_getType (retSref);
2284 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2285 sRef_setNullTerminatedState (retSref);
2291 message ("Qualifier %s used on non-pointer on \
2292 function return: %q", qual_unparse (qel),
2293 uentry_unparse (ue)));
2300 message ("Qualifier %s used on non-pointer: %q",
2301 qual_unparse (qel), uentry_unparse (ue)));
2304 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2306 ctype realType = ctype_realType (ue->utype);
2307 sstate defstate = sstate_fromQual (qel);
2309 if (ctype_isFunction (realType))
2311 realType = ctype_realType (ctype_returnValue (realType));
2314 if (qual_isRelDef (qel))
2316 ; /* okay anywhere */
2320 if (!ctype_isAP (realType)
2321 && !ctype_isSU (realType)
2322 && !ctype_isUnknown (realType)
2323 && !ctype_isAbstract (ue->utype))
2327 message ("Qualifier %s used on non-pointer or struct: %q",
2328 qual_unparse (qel), uentry_unparse (ue)));
2332 uentry_setDefState (ue, defstate);
2334 if (sRef_isStateSpecial (ue->sref)
2335 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2337 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2340 else if (qual_isYield (qel))
2342 if (uentry_isVariable (ue))
2344 ue->info->var->kind = VKYIELDPARAM;
2350 message ("Qualifier %s used on non-iterator parameter: %q",
2351 qual_unparse (qel), uentry_unparse (ue)));
2354 else if (qual_isExQual (qel))
2356 exkind ek = exkind_fromQual (qel);
2357 ctype ut = uentry_getType (ue);
2359 if (ctype_isFunction (ut))
2361 ut = ctype_returnValue (ut);
2364 if (!(ctype_isVisiblySharable (ut))
2365 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2366 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2368 if (!qual_isImplied (qel))
2372 message ("Qualifier %s used on unsharable storage type %t: %q",
2373 exkind_unparse (ek), ut, uentry_getName (ue)));
2378 alkind ak = sRef_getAliasKind (ue->sref);
2380 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2382 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2384 if (!alkind_isTemp (ak))
2386 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2389 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2390 || alkind_isOwned (ak))
2398 message ("Exposure qualifier %s used on %s storage (should "
2399 "be dependent): %q",
2401 alkind_unparse (ak),
2402 uentry_unparse (ue)));
2406 else if (qual_isGlobCheck (qel))
2408 if (uentry_isVariable (ue))
2410 chkind ch = chkind_fromQual (qel);
2412 if (ue->info->var->checked != CH_UNKNOWN)
2414 if (ch == ue->info->var->checked)
2416 llerror (FLG_SYNTAX,
2417 message ("Redundant %s qualifier on %q",
2419 uentry_getName (ue)));
2423 llerror (FLG_SYNTAX,
2425 ("Contradictory %s and %s qualifiers on %q",
2427 checkedName (ue->info->var->checked),
2428 uentry_getName (ue)));
2432 ue->info->var->checked = ch;
2438 message ("Qualifier %s used with non-variable",
2439 qual_unparse (qel)));
2442 else if (qual_isReturned (qel))
2444 if (uentry_isVariable (ue))
2446 ue->info->var->kind = VKRETPARAM;
2450 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2451 qual_unparse (qel)));
2456 uentry_reflectOtherQualifier (ue, qel);
2459 sRef_storeState (ue->sref);
2460 } end_qualList_elements;
2466 uentry_isOnly (uentry ue)
2468 return (!uentry_isUndefined (ue)
2469 && uentry_isVariable (ue)
2470 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2474 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2476 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2477 sRef_setOrigAliasKind (ue->sref, ak);
2481 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2483 if (uentry_isVariable (ue))
2485 ue->info->var->nullstate = ns;
2488 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2492 uentry_isUnique (uentry ue)
2494 return (!uentry_isUndefined (ue)
2495 && uentry_isVariable (ue)
2496 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2500 uentry_isFileStatic (uentry ue)
2502 return (uentry_isStatic (ue)
2503 && (!uentry_isVariable (ue)
2504 || sRef_isFileStatic (uentry_getSref (ue))));
2508 uentry_isExported (uentry ue)
2510 if (uentry_isValid (ue))
2512 if (uentry_isVariable (ue))
2514 return (sRef_isRealGlobal (uentry_getSref (ue)));
2518 return !uentry_isStatic (ue);
2526 uentry_isNonLocal (uentry ue)
2528 return (uentry_isValid (ue) && uentry_isVariable (ue)
2529 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
2533 uentry_isGlobal (uentry ue)
2535 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
2536 sRef_isGlobal (ue->sref));
2540 uentry_isPrintfLike (uentry ue)
2542 return (uentry_isFunction (ue)
2543 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2547 uentry_isScanfLike (uentry ue)
2549 return (uentry_isFunction (ue)
2550 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2554 uentry_isMessageLike (uentry ue)
2556 return (uentry_isFunction (ue)
2557 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2560 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2562 uentryList args = uentry_getParams (ue);
2564 if (!uentryList_isMissingParams (args))
2566 uentry last = uentry_undefined;
2568 uentryList_elements (args, current)
2570 if (uentry_isElipsisMarker (current))
2572 if (uentry_isUndefined (last))
2576 message ("Function %q is marked %s, but has no format "
2577 "string argument before elipsis",
2578 uentry_getName (ue),
2579 specCode_unparse (ue->info->fcn->specialCode)),
2580 uentry_whereLast (ue));
2581 ue->info->fcn->specialCode = SPC_NONE;
2585 ctype rt = ctype_realType (uentry_getType (last));
2587 if (!ctype_match (rt, ctype_string))
2591 /* wchar_t * is okay too */
2592 if (ctype_isAP (rt))
2594 ctype base = ctype_baseArrayPtr (rt);
2596 if (ctype_isArbitraryIntegral (base))
2606 message ("Function %q is marked %s, but the argument "
2607 "before the elipsis has type %s (should be char *)",
2608 uentry_getName (ue),
2609 specCode_unparse (ue->info->fcn->specialCode),
2610 ctype_unparse (uentry_getType (last))),
2611 uentry_whereLast (ue));
2613 ue->info->fcn->specialCode = SPC_NONE;
2620 } end_uentryList_elements ;
2624 message ("Function %q is marked %s, but has no elipsis parameter",
2625 uentry_getName (ue),
2626 specCode_unparse (ue->info->fcn->specialCode)),
2627 uentry_whereLast (ue));
2629 ue->info->fcn->specialCode = SPC_NONE;
2634 uentry_setPrintfLike (uentry ue)
2636 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2638 uentry_makeVarFunction (ue);
2641 llassertfatal (uentry_isFunction (ue));
2642 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2643 checkSpecialFunction (ue);
2647 uentry_setScanfLike (uentry ue)
2649 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2651 uentry_makeVarFunction (ue);
2654 llassertfatal (uentry_isFunction (ue));
2655 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2656 checkSpecialFunction (ue);
2660 uentry_setMessageLike (uentry ue)
2662 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2664 uentry_makeVarFunction (ue);
2667 llassertfatal (uentry_isFunction (ue));
2668 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
2669 checkSpecialFunction (ue);
2673 uentry_isSpecialFunction (uentry ue)
2675 return (uentry_isFunction (ue)
2676 && (ue->info->fcn->specialCode != SPC_NONE));
2679 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
2681 ctype ct = idDecl_getCtype (t);
2683 sRef pref = sRef_makeParam (i, ct);
2684 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
2686 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2687 uentry_implicitParamAnnots (ue);
2689 /* Parameter type [][] or [x][] is invalid */
2691 while (ctype_isFixedArray (base)) {
2692 base = ctype_baseArrayPtr (base);
2695 if (ctype_isIncompleteArray (base)) {
2696 base = ctype_baseArrayPtr (base);
2698 if (ctype_isArray (base)) {
2699 if (!uentry_hasName (ue)) {
2700 (void) optgenerror (FLG_INCOMPLETETYPE,
2701 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
2703 ctype_unparse (ct)),
2704 uentry_whereLast (ue));
2706 (void) optgenerror (FLG_INCOMPLETETYPE,
2707 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
2708 uentry_getName (ue),
2709 ctype_unparse (ct)),
2710 uentry_whereLast (ue));
2718 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
2720 ctype ct = idDecl_getCtype (t);
2722 if (ctype_isFunction (ct))
2724 return (uentry_makeIdFunction (t));
2728 fileloc loc = setLocation ();
2729 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
2731 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2733 if (!uentry_isExtern (ue))
2735 uentry_setDefined (ue, loc);
2743 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
2745 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
2753 /*@only@*/ /*@notnull@*/
2754 uentry uentry_makeConstantAux (cstring n, ctype t,
2755 /*@keep@*/ fileloc f, bool priv,
2756 /*@only@*/ multiVal m)
2758 uentry e = uentry_alloc ();
2761 e->uname = cstring_copy (n);
2763 e->storageclass = SCNONE;
2765 e->sref = sRef_makeConst (t);
2770 e->uses = filelocList_new ();
2771 e->isPrivate = priv;
2772 e->hasNameError = FALSE;
2774 e->info = (uinfo) dmalloc (sizeof (*e->info));
2775 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
2776 e->info->uconst->val = m;
2777 e->info->uconst->access = typeIdSet_undefined;
2779 uentry_setSpecDef (e, f);
2781 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
2783 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
2789 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
2791 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
2794 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
2796 uentry ue = uentry_makeConstant (idDecl_observeId (t),
2797 idDecl_getCtype (t),
2800 llassert (fileloc_isUndefined (ue->whereDeclared));
2801 ue->whereDeclared = setLocation ();
2803 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
2812 void uentry_setDefState (uentry ue, sstate defstate)
2814 if (uentry_isValid (ue))
2816 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2818 if (uentry_isVariable (ue))
2820 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
2825 bool uentry_isCheckedUnknown (uentry ue)
2827 return (uentry_isVar (ue)
2828 && (ue->info->var->checked == CH_UNKNOWN));
2831 bool uentry_isCheckMod (uentry ue)
2833 return (uentry_isVar (ue)
2834 && (ue->info->var->checked == CH_CHECKMOD));
2837 bool uentry_isUnchecked (uentry ue)
2839 return (uentry_isVar (ue)
2840 && (ue->info->var->checked == CH_UNCHECKED));
2843 bool uentry_isChecked (uentry ue)
2845 return (uentry_isVar (ue)
2846 && (ue->info->var->checked == CH_CHECKED));
2849 bool uentry_isCheckedModify (uentry ue)
2851 return (uentry_isVar (ue)
2852 && (ue->info->var->checked == CH_CHECKED
2853 || ue->info->var->checked == CH_CHECKMOD
2854 || ue->info->var->checked == CH_CHECKEDSTRICT));
2857 bool uentry_isCheckedStrict (uentry ue)
2859 return (uentry_isVar (ue)
2860 && (ue->info->var->checked == CH_CHECKEDSTRICT));
2863 void uentry_setUnchecked (uentry ue)
2865 llassert (uentry_isVar (ue));
2867 ue->info->var->checked = CH_UNCHECKED;
2870 void uentry_setChecked (uentry ue)
2872 llassert (uentry_isVar (ue));
2874 ue->info->var->checked = CH_CHECKED;
2877 void uentry_setCheckMod (uentry ue)
2879 llassert (uentry_isVar (ue));
2881 ue->info->var->checked = CH_CHECKMOD;
2884 void uentry_setCheckedStrict (uentry ue)
2886 llassert (uentry_isVar (ue));
2888 ue->info->var->checked = CH_CHECKEDSTRICT;
2891 static /*@only@*/ /*@notnull@*/
2892 uentry uentry_makeVariableAux (cstring n, ctype t,
2894 /*@exposed@*/ sRef s,
2895 bool priv, vkind kind)
2897 uentry e = uentry_alloc ();
2900 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
2903 e->uname = cstring_copy (n);
2906 e->storageclass = SCNONE;
2913 e->uses = filelocList_new ();
2914 e->isPrivate = priv;
2915 e->hasNameError = FALSE;
2917 e->info = (uinfo) dmalloc (sizeof (*e->info));
2918 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
2919 e->info->var->kind = kind;
2921 e->info->var->checked = CH_UNKNOWN;
2923 uentry_setSpecDef (e, f);
2925 if (ctype_isFunction (rt))
2927 rt = ctype_returnValue (rt);
2930 if (ctype_isUA (rt))
2932 sRef_setStateFromType (e->sref, rt);
2935 e->info->var->defstate = sRef_getDefState (e->sref);
2936 e->info->var->nullstate = sRef_getNullState (e->sref);
2938 /* start modifications */
2939 /* This function sets the uentry for a pointer or array variable declaration,
2940 it allocates memory and sets the fields. We check if the type of the variable
2941 is a pointer or array and allocate a `bbufinfo' struct accordingly */
2943 if( ctype_isArray (t) || ctype_isPointer(t)) {
2944 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
2945 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
2946 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
2948 e->info->var->bufinfo = NULL;
2950 /* end modification */
2956 uentry_isYield (uentry ue)
2958 return (uentry_isVariable (ue)
2959 && (ue->info->var->kind == VKYIELDPARAM
2960 || ue->info->var->kind == VKREFYIELDPARAM));
2964 uentry_isRefsField (uentry ue)
2966 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
2969 /*@only@*/ /*@notnull@*/
2970 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
2972 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
2973 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
2980 void uentry_makeVarFunction (uentry ue)
2987 llassert (uentry_isValid (ue));
2988 llassert (!sRef_modInFunction ());
2990 ak = sRef_getOrigAliasKind (ue->sref);
2991 ek = sRef_getOrigExKind (ue->sref);
2993 oldInfo = ue->info->var;
2995 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
2998 ** expanded macro is marked used (until I write a pre-processor)
3001 ue->used |= (oldInfo->kind == VKEXPMACRO);
3004 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3005 ue->info->fcn->exitCode = XK_UNKNOWN;
3006 ue->info->fcn->nullPred = QU_UNKNOWN;
3007 ue->info->fcn->specialCode = SPC_NONE;
3008 ue->info->fcn->access = typeIdSet_undefined;
3009 ue->info->fcn->hasGlobs = FALSE;
3010 ue->info->fcn->globs = globSet_undefined;
3011 ue->info->fcn->hasMods = FALSE;
3012 ue->info->fcn->mods = sRefSet_undefined;
3013 ue->info->fcn->specclauses = NULL;
3014 ue->info->fcn->defparams = uentryList_undefined;
3017 ue->info->fcn->preconditions = constraintList_undefined;
3021 ue->info->fcn->postconditions = constraintList_undefined;
3025 if (ctype_isFunction (ue->utype))
3027 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
3031 ue->sref = sRef_makeType (ctype_unknown);
3034 if (sRef_isRefCounted (ue->sref))
3040 if (alkind_isUnknown (ak))
3042 if (exkind_isKnown (ek))
3044 ak = AK_IMPDEPENDENT;
3048 if (context_getFlag (FLG_RETIMPONLY))
3050 if (ctype_isFunction (ue->utype)
3051 && ctype_isVisiblySharable
3052 (ctype_realType (ctype_returnValue (ue->utype))))
3054 if (uentryList_hasReturned (uentry_getParams (ue)))
3068 loc = ue->whereDeclared;
3070 sRef_setAliasKind (ue->sref, ak, loc);
3071 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3072 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3073 sRef_setExKind (ue->sref, ek, loc);
3075 if (oldInfo->kind == VKEXPMACRO)
3078 ue->whereDeclared = fileloc_undefined;
3082 fileloc_free (ue->whereDefined);
3083 ue->whereDefined = fileloc_undefined;
3086 uvinfo_free (oldInfo);
3090 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3092 llassert (uentry_isValid (ue));
3094 if (uentry_isIter (ue))
3096 llassert (globSet_isUndefined (ue->info->iter->globs));
3097 ue->info->iter->globs = globs;
3101 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
3103 uentry_makeVarFunction (ue);
3106 llassert (uentry_isFunction (ue));
3107 llassert (!ue->info->fcn->hasGlobs
3108 && globSet_isUndefined (ue->info->fcn->globs));
3110 ue->info->fcn->hasGlobs = TRUE;
3111 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3115 if (globSet_hasStatic (globs))
3117 context_recordFileGlobals (globs);
3120 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3122 ue->info->fcn->hasMods = TRUE;
3126 void uentry_addAccessType (uentry ue, typeId tid)
3128 if (uentry_isFunction (ue))
3130 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3132 else if (uentry_isEitherConstant (ue))
3134 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3136 else if (uentry_isIter (ue))
3138 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3140 else if (uentry_isEndIter (ue))
3142 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3146 llbug (message ("no access for: %q", uentry_unparse (ue)));
3150 /*@only@*/ /*@notnull@*/ uentry
3151 uentry_makeFunction (cstring n, ctype t,
3153 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3156 return (uentry_makeFunctionAux (n, t,
3157 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3158 : typeIdSet_single (access)),
3164 /*@notnull@*/ uentry
3165 uentry_makePrivFunction2 (cstring n, ctype t,
3167 globSet globs, sRefSet mods,
3170 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
3174 /*@notnull@*/ uentry
3175 uentry_makeSpecFunction (cstring n, ctype t,
3177 /*@only@*/ globSet globs,
3178 /*@only@*/ sRefSet mods,
3181 uentry ue = uentry_makeFunctionAux (n, t, access,
3185 uentry_setHasGlobs (ue);
3186 uentry_setHasMods (ue);
3188 reflectImplicitFunctionQualifiers (ue, TRUE);
3193 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3195 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3196 sRef_undefined, FALSE, VKEXPMACRO);
3198 uentry_setDefined (ue, f);
3202 /*@notnull@*/ /*@notnull@*/ uentry
3203 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3205 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3206 typeIdSet_singleOpt (access),
3207 globSet_undefined, sRefSet_undefined,
3211 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3215 bool uentry_isForward (uentry e)
3217 if (uentry_isValid (e))
3219 ctype ct = uentry_getType (e);
3221 return (ctype_isUnknown (ct)
3222 || (ctype_isFunction (ct)
3223 && ctype_isUnknown (ctype_returnValue (ct))));
3230 /*@notnull@*/ uentry
3231 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3233 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3239 /*@notnull@*/ uentry
3240 uentry_makeUnspecFunction (cstring n, ctype t,
3244 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
3245 sRefSet_new (), f, FALSE, TRUE);
3247 reflectImplicitFunctionQualifiers (ue, TRUE);
3256 /* is exported for use by usymtab_interface */
3258 /*@notnull@*/ uentry
3259 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
3260 fileloc f, bool priv)
3262 uentry e = uentry_alloc ();
3264 DPRINTF (("Make datatype: %s / %s",
3265 n, ctype_unparse (t)));
3267 /* e->shallowCopy = FALSE; */
3268 e->ukind = KDATATYPE;
3269 e->uname = cstring_copy (n);
3271 e->storageclass = SCNONE;
3272 e->sref = sRef_makeUnknown ();
3276 sRef_setStateFromType (e->sref, t);
3279 uentry_setSpecDef (e, f);
3281 e->uses = filelocList_new ();
3282 e->isPrivate = priv;
3283 e->hasNameError = FALSE;
3288 e->info = (uinfo) dmalloc (sizeof (*e->info));
3289 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3290 e->info->datatype->abs = abs;
3291 e->info->datatype->mut = mut;
3292 e->info->datatype->type = ctype_undefined;
3294 if (uentry_isDeclared (e))
3296 uentry_setDefined (e, f);
3299 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
3301 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3307 /*@notnull@*/ uentry
3308 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
3311 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
3314 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abs)
3316 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3317 ctype_bool, NO, abs,
3318 fileloc_getBuiltin (),
3321 ret->info->datatype->type = ctype_bool;
3329 static /*@only@*/ /*@notnull@*/ uentry
3330 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3331 /*@only@*/ fileloc f)
3333 uentry e = uentry_alloc ();
3336 e->uname = cstring_copy (n);
3338 e->sref = sRef_makeUnknown ();
3339 e->storageclass = SCNONE;
3343 uentry_setSpecDef (e, f);
3345 e->uses = filelocList_new ();
3346 e->isPrivate = FALSE;
3347 e->hasNameError = FALSE;
3349 e->info = (uinfo) dmalloc (sizeof (*e->info));
3350 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3351 e->info->iter->access = access;
3352 e->info->iter->mods = sRefSet_undefined;
3353 e->info->iter->globs = globSet_undefined;
3355 uentry_checkIterArgs (e);
3359 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3361 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3364 static /*@notnull@*/ uentry
3365 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3367 uentry e = uentry_alloc ();
3369 /* e->shallowCopy = FALSE; */
3370 e->ukind = KENDITER;
3371 e->storageclass = SCNONE;
3372 e->uname = message ("end_%s", n);
3373 e->utype = ctype_unknown;
3374 e->sref = sRef_makeUnknown ();
3376 uentry_setSpecDef (e, f);
3381 e->uses = filelocList_new ();
3382 e->isPrivate = FALSE;
3383 e->hasNameError = FALSE;
3385 e->info = (uinfo) dmalloc (sizeof (*e->info));
3386 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3388 e->info->enditer->access = access;
3393 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3395 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3402 static /*@only@*/ /*@notnull@*/ uentry
3403 uentry_makeTagAux (cstring n, ctype t,
3404 /*@only@*/ fileloc fl,
3405 bool priv, ekind kind)
3407 uentry e = uentry_alloc ();
3409 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3411 llbuglit ("uentry_makeTagAux: not a tag type");
3415 /* e->shallowCopy = FALSE; */
3416 e->uname = cstring_copy (n);
3419 e->sref = sRef_makeUnknown ();
3420 e->storageclass = SCNONE;
3422 uentry_setSpecDef (e, fl);
3427 e->uses = filelocList_new ();
3428 e->isPrivate = priv;
3429 e->hasNameError = FALSE;
3431 e->info = (uinfo) dmalloc (sizeof (*e->info));
3432 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3433 e->info->datatype->abs = NO;
3434 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3435 e->info->datatype->type = t;
3437 if (uentry_isDeclared (e))
3439 uentry_setDefined (e, fl);
3445 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3447 cstring sname = makeStruct (n);
3448 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3450 cstring_free (sname);
3455 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3457 cstring sname = makeStruct (n);
3458 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3460 cstring_free (sname);
3465 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3467 cstring uname = makeUnion (n);
3468 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3470 cstring_free (uname);
3476 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3478 cstring ename = makeEnum (n);
3479 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3481 cstring_free (ename);
3487 uentry_makeUnionTagLoc (cstring n, ctype t)
3489 cstring uname = makeUnion (n);
3490 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3492 cstring_free (uname);
3497 uentry_makeEnumTagLoc (cstring n, ctype t)
3499 cstring ename = makeEnum (n);
3500 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3502 cstring_free (ename);
3507 uentry_isStructTag (uentry ue)
3509 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3513 uentry_isUnionTag (uentry ue)
3515 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3519 uentry_isEnumTag (uentry ue)
3521 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3525 uentry_isAnyTag (uentry ue)
3527 return (uentry_isStructTag (ue)
3528 || uentry_isUnionTag (ue)
3529 || uentry_isEnumTag (ue));
3532 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
3534 extern void uentry_destroyMod (void)
3535 /*@globals killed emarker@*/ /*@modifies emarker@*/
3537 static bool wasDestroyed = FALSE;
3539 llassert (!wasDestroyed);
3541 if (emarker != NULL)
3543 uentry_reallyFree (emarker);
3546 wasDestroyed = TRUE;
3550 uentry_makeElipsisMarker (void)
3552 if (emarker == NULL)
3554 emarker = uentry_alloc ();
3556 emarker->ukind = KELIPSMARKER;
3557 emarker->uname = cstring_makeLiteral ("...");
3558 emarker->utype = ctype_elipsMarker;
3559 emarker->sref = sRef_undefined;
3560 emarker->storageclass = SCNONE;
3561 emarker->used = FALSE;
3562 emarker->lset = FALSE;
3563 emarker->info = NULL;
3565 uentry_setSpecDef (emarker, fileloc_undefined);
3566 emarker->uses = filelocList_new ();
3567 emarker->isPrivate = FALSE;
3568 emarker->hasNameError = FALSE;
3571 /*@ignore@*/ return (emarker); /*@end@*/
3579 uentry_equiv (uentry p1, uentry p2)
3581 if (uentry_compare (p1, p2) != 0)
3592 uentry_xcomparealpha (uentry *p1, uentry *p2)
3596 if ((res = uentry_compare (*p1, *p2)) == 0) {
3597 if ((*p1 != NULL) && (*p2 != NULL)) {
3598 res = cstring_compare ((*p1)->uname,
3607 uentry_xcompareuses (uentry *p1, uentry *p2)
3612 if (uentry_isValid (u1))
3614 if (uentry_isValid (u2))
3616 return (-1 * int_compare (filelocList_size (u1->uses),
3617 filelocList_size (u2->uses)));
3626 if (uentry_isValid (u2))
3638 uentry_compareStrict (uentry v1, uentry v2)
3640 COMPARERETURN (uentry_compare (v1, v2));
3642 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
3644 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
3645 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
3646 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
3653 uentry_compare (uentry u1, uentry u2)
3655 if (u1 == u2) return 0;
3657 if (uentry_isInvalid (u1)) return -1;
3658 if (uentry_isInvalid (u2)) return 1;
3660 INTCOMPARERETURN (u1->ukind, u2->ukind);
3661 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
3662 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
3664 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
3670 /* bug detected by lclint:
3671 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
3676 return (multiVal_compare (u1->info->uconst->val,
3677 u2->info->uconst->val));
3681 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
3683 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3684 uentry_accessType (u2)));
3685 return (uentryList_compareParams (uentry_getParams (u1),
3686 uentry_getParams (u2)));
3688 return (typeIdSet_compare (uentry_accessType (u1),
3689 uentry_accessType (u2)));
3691 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
3692 uentry_accessType (u2)));
3693 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
3694 uentry_getGlobs (u2)));
3695 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
3696 uentry_getParams (u2)));
3697 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
3698 u2->info->fcn->specialCode));
3699 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
3700 u2->info->fcn->nullPred));
3702 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
3704 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
3705 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
3706 sRef_getOrigAliasKind (u2->sref)));
3707 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
3708 sRef_getOrigExKind (u2->sref)));
3709 COMPARERETURN (generic_compare (u1->info->var->checked,
3710 u2->info->var->checked));
3711 COMPARERETURN (generic_compare (u1->info->var->defstate,
3712 u2->info->var->defstate));
3713 return (generic_compare (u1->info->var->nullstate,
3714 u2->info->var->nullstate));
3716 COMPARERETURN (ctype_compare (u1->info->datatype->type,
3717 u2->info->datatype->type));
3718 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
3719 u2->info->datatype->mut));
3720 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
3729 ** all entries are: <type>[@<info>]*#<name>
3731 ** info depends on kind:
3735 advanceField (char **s)
3741 advanceName (char **s)
3747 vkind_fromInt (int i)
3749 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
3751 llbuglit ("vkind_fromInt: out of range");
3758 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
3759 typeIdSet access, nstate nullstate,
3760 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
3762 uentry e = uentry_alloc ();
3767 e->sref = sRef_makeConst (ct);
3769 sRef_setNullState (e->sref, nullstate, loc);
3770 e->storageclass = SCNONE;
3772 if (fileloc_isSpec (loc))
3774 e->whereSpecified = loc;
3775 e->whereDeclared = fileloc_undefined;
3779 e->whereSpecified = fileloc_undefined;
3780 e->whereDeclared = loc;
3783 e->whereDefined = fileloc_undefined;
3784 e->uses = filelocList_new ();
3785 e->isPrivate = FALSE;
3786 e->hasNameError = FALSE;
3791 e->info = (uinfo) dmalloc (sizeof (*e->info));
3792 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3793 e->info->uconst->val = m;
3794 e->info->uconst->access = access;
3796 sRef_storeState (e->sref);
3801 static /*@only@*/ uentry
3802 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
3803 sstate defstate, nstate isnull, alkind aliased,
3804 exkind exp, chkind checked,
3805 /*@only@*/ fileloc loc)
3807 uentry e = uentry_alloc ();
3812 e->storageclass = SCNONE;
3814 e->sref = sRef_makeType (ct);
3815 sRef_setNullState (e->sref, isnull, loc);
3817 e->whereDefined = fileloc_undefined;
3819 if (fileloc_isSpec (loc))
3821 e->whereSpecified = loc;
3822 e->whereDeclared = fileloc_undefined;
3826 e->whereSpecified = fileloc_undefined;
3827 e->whereDeclared = loc;
3830 e->isPrivate = FALSE;
3831 e->hasNameError = FALSE;
3836 e->uses = filelocList_new ();
3838 e->info = (uinfo) dmalloc (sizeof (*e->info));
3839 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3840 e->info->var->kind = kind;
3841 e->info->var->checked = checked;
3842 e->info->var->defstate = defstate;
3844 sRef_setDefState (e->sref, defstate, loc);
3846 e->info->var->nullstate = sRef_getNullState (e->sref);
3848 sRef_setExKind (e->sref, exp, loc);
3849 sRef_setAliasKind (e->sref, aliased, loc);
3851 sRef_storeState (e->sref);
3853 /*DRL ADDED 9-1-2000 */
3854 e->info->var->bufinfo = NULL;
3859 static /*@only@*/ uentry
3860 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abs,
3861 ynm mut, ctype rtype, alkind ak, exkind exp,
3862 sstate defstate, nstate isnull,
3863 /*@only@*/ fileloc loc)
3865 uentry e = uentry_alloc ();
3867 e->ukind = KDATATYPE;
3868 /* e->shallowCopy = FALSE; */
3871 e->storageclass = SCNONE;
3872 e->sref = sRef_makeUnknown ();
3875 ** This is only setting null state. (I think?)
3878 if (ctype_isUA (ct))
3880 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
3882 if (uentry_isValid (te))
3884 sRef_setStateFromUentry (e->sref, te);
3888 /* problem for recursive type definitions */
3892 sRef_setAliasKind (e->sref, ak, loc);
3893 sRef_setExKind (e->sref, exp, loc);
3895 sRef_setDefState (e->sref, defstate, loc);
3897 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
3899 isnull = NS_ABSNULL;
3902 sRef_mergeNullState (e->sref, isnull);
3904 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
3906 if (fileloc_isSpec (loc))
3908 e->whereSpecified = loc;
3909 e->whereDeclared = fileloc_undefined;
3913 e->whereSpecified = fileloc_undefined;
3914 e->whereDeclared = loc;
3917 e->isPrivate = FALSE;
3918 e->hasNameError = FALSE;
3922 e->uses = filelocList_new ();
3924 e->info = (uinfo) dmalloc (sizeof (*e->info));
3925 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3926 e->info->datatype->abs = abs;
3927 e->info->datatype->mut = mut;
3928 e->info->datatype->type = rtype;
3930 sRef_storeState (e->sref);
3936 static void uentry_setHasGlobs (uentry ue)
3938 llassert (uentry_isFunction (ue));
3940 ue->info->fcn->hasGlobs = TRUE;
3943 static void uentry_setHasMods (uentry ue)
3945 llassert (uentry_isFunction (ue));
3947 ue->info->fcn->hasMods = TRUE;
3951 bool uentry_hasGlobs (uentry ue)
3953 if (uentry_isFunction (ue))
3955 return (ue->info->fcn->hasGlobs);
3961 bool uentry_hasSpecialClauses (uentry ue)
3963 return (uentry_isFunction (ue) && specialClauses_isDefined (ue->info->fcn->specclauses));
3966 specialClauses uentry_getSpecialClauses (uentry ue)
3968 llassert (uentry_isFunction (ue));
3969 return ue->info->fcn->specclauses;
3972 bool uentry_hasMods (uentry ue)
3974 if (uentry_isFunction (ue))
3976 return (ue->info->fcn->hasMods);
3983 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
3985 bool hasGlobs, /*@only@*/ globSet globs,
3986 bool hasMods, /*@only@*/ sRefSet mods,
3987 alkind ak, exkind exp,
3988 sstate defstate, nstate isnull,
3992 /*@only@*/ specialClauses specclauses,
3993 /*@only@*/ fileloc loc)
3995 uentry e = uentry_alloc ();
3998 /* e->shallowCopy = FALSE; */
4002 e->storageclass = SCNONE;
4004 if (ctype_isFunction (ct))
4006 ret = ctype_returnValue (ct);
4010 if (ctype_isKnown (ct))
4012 llbug (message ("not function: %s", ctype_unparse (ct)));
4015 ret = ctype_unknown;
4018 e->sref = sRef_makeType (ret);
4020 if (ctype_isUA (ret))
4022 sRef_setStateFromType (e->sref, ret);
4025 sRef_setDefined (e->sref, loc);
4026 sRef_setNullState (e->sref, isnull, loc);
4028 sRef_setAliasKind (e->sref, ak, loc);
4029 sRef_setExKind (e->sref, exp, loc);
4030 sRef_setDefState (e->sref, defstate, loc);
4032 e->whereSpecified = loc;
4033 e->whereDefined = fileloc_undefined;
4035 e->isPrivate = FALSE;
4036 e->hasNameError = FALSE;
4040 e->uses = filelocList_new ();
4042 e->info = (uinfo) dmalloc (sizeof (*e->info));
4043 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4045 e->info->fcn->exitCode = exitCode;
4046 e->info->fcn->specialCode = sCode;
4047 e->info->fcn->nullPred = nullPred;
4048 e->info->fcn->access = access;
4050 e->info->fcn->specclauses = specclauses;
4051 e->info->fcn->hasGlobs = hasGlobs;
4052 e->info->fcn->globs = globs;
4054 e->info->fcn->hasMods = hasMods;
4055 e->info->fcn->mods = mods;
4057 e->info->fcn->defparams = uentryList_undefined;
4058 e->whereDeclared = fileloc_undefined;
4060 sRef_storeState (e->sref);
4063 e->info->fcn->preconditions = NULL;
4067 e->info->fcn->postconditions = NULL;
4073 static /*@only@*/ uentry
4074 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4075 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4077 uentry e = uentry_alloc ();
4079 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4081 llbuglit ("uentry_makeTagBase: not a tag type");
4084 /* e->shallowCopy = FALSE; */
4088 e->sref = sRef_makeUnknown ();
4089 e->storageclass = SCNONE;
4091 if (fileloc_isSpec (loc))
4093 e->whereSpecified = loc;
4094 e->whereDeclared = fileloc_undefined;
4098 e->whereDeclared = loc;
4099 e->whereSpecified = fileloc_undefined;
4102 e->whereDefined = fileloc_undefined;
4104 e->isPrivate = FALSE;
4105 e->hasNameError = FALSE;
4109 e->uses = filelocList_new ();
4111 e->info = (uinfo) dmalloc (sizeof (*e->info));
4112 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4113 e->info->datatype->abs = NO;
4114 e->info->datatype->mut = MAYBE;
4115 e->info->datatype->type = rtype;
4117 sRef_storeState (e->sref);
4123 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4124 ctype ct, /*@only@*/ fileloc loc)
4126 uentry e = uentry_alloc ();
4128 /* e->shallowCopy = FALSE; */
4132 e->sref = sRef_makeUnknown ();
4133 e->storageclass = SCNONE;
4135 if (fileloc_isSpec (loc))
4137 e->whereSpecified = loc;
4138 e->whereDeclared = fileloc_undefined;
4142 e->whereDeclared = loc;
4143 e->whereSpecified = fileloc_undefined;
4146 e->whereDefined = fileloc_undefined;
4148 e->isPrivate = FALSE;
4149 e->hasNameError = FALSE;
4153 e->uses = filelocList_new ();
4155 e->info = (uinfo) dmalloc (sizeof (*e->info));
4156 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4157 e->info->iter->access = access;
4158 e->info->iter->mods = sRefSet_undefined;
4159 e->info->iter->globs = globSet_undefined;
4161 sRef_storeState (e->sref);
4166 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4167 /*@only@*/ fileloc loc)
4169 uentry e = uentry_alloc ();
4171 /* e->shallowCopy = FALSE; */
4172 e->ukind = KENDITER;
4173 e->storageclass = SCNONE;
4175 e->utype = ctype_unknown;
4176 e->sref = sRef_makeUnknown ();
4178 if (fileloc_isSpec (loc))
4180 e->whereSpecified = loc;
4181 e->whereDeclared = fileloc_undefined;
4185 e->whereDeclared = loc;
4186 e->whereSpecified = fileloc_undefined;
4189 e->whereDefined = fileloc_undefined;
4191 e->isPrivate = FALSE;
4192 e->hasNameError = FALSE;
4196 e->uses = filelocList_new ();
4198 e->info = (uinfo) dmalloc (sizeof (*e->info));
4199 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4200 e->info->enditer->access = access;
4201 sRef_storeState (e->sref);
4206 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4214 uentry_undump (ekind kind, fileloc loc, char **s)
4222 ue = uentry_makeElipsisMarker ();
4226 ctype ct = ctype_undump (s);
4242 if (optCheckChar (s, '@'))
4244 tkind = vkind_fromInt (getInt (s));
4252 if (optCheckChar (s, '$'))
4254 defstate = SS_UNKNOWN;
4255 isnull = NS_UNKNOWN;
4256 aliased = AK_IMPTEMP;
4258 checked = CH_UNKNOWN;
4260 else if (optCheckChar (s, '&'))
4262 defstate = SS_DEFINED;
4263 isnull = NS_UNKNOWN;
4264 aliased = AK_IMPTEMP;
4266 checked = CH_UNKNOWN;
4268 else if (optCheckChar (s, '^'))
4270 defstate = SS_UNKNOWN;
4271 isnull = NS_UNKNOWN;
4272 aliased = AK_IMPTEMP;
4274 checked = CH_UNKNOWN;
4278 defstate = sstate_fromInt (getInt (s));
4279 advanceField (s); isnull = nstate_fromInt (getInt (s));
4280 advanceField (s); aliased = alkind_fromInt (getInt (s));
4282 if (optCheckChar (s, '&'))
4285 checked = CH_UNKNOWN;
4289 advanceField (s); exp = exkind_fromInt (getInt (s));
4290 advanceField (s); checked = (chkind) (getInt (s));
4295 name = getStringWord (s);
4297 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4298 isnull, aliased, exp,
4299 checked, fileloc_copy (loc));
4312 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
4313 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
4314 advanceField (s); defstate = sstate_fromInt (getInt (s));
4315 advanceField (s); isnull = nstate_fromInt (getInt (s));
4316 advanceField (s); aliased = alkind_fromInt (getInt (s));
4317 advanceField (s); exp = exkind_fromInt (getInt (s));
4318 advanceField (s); rtype = ctype_undump (s);
4320 name = getStringWord (s);
4322 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
4323 aliased, exp, defstate, isnull,
4324 fileloc_copy (loc));
4341 specialClauses specclauses;
4343 if (optCheckChar (s, '$'))
4345 defstate = SS_DEFINED;
4346 isnull = NS_UNKNOWN;
4347 exitCode = XK_UNKNOWN;
4349 nullPred = QU_UNKNOWN;
4353 advanceField (s); defstate = sstate_fromInt (getInt (s));
4354 advanceField (s); isnull = nstate_fromInt (getInt (s));
4355 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
4356 advanceField (s); specc = specCode_fromInt (getInt (s));
4357 advanceField (s); nullPred = qual_fromInt (getInt (s));
4360 if (optCheckChar (s, '$'))
4363 globs = globSet_undefined;
4365 mods = sRefSet_undefined;
4367 else if (optCheckChar (s, '^'))
4370 globs = globSet_undefined;
4372 mods = sRefSet_undefined;
4376 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
4377 advanceField (s); globs = globSet_undump (s);
4378 advanceField (s); hasMods = bool_fromInt (getInt (s));
4379 advanceField (s); mods = sRefSet_undump (s);
4382 if (optCheckChar (s, '$'))
4389 advanceField (s); ak = alkind_fromInt (getInt (s));
4390 advanceField (s); exp = exkind_fromInt (getInt (s));
4393 advanceField (s); access = typeIdSet_undump (s);
4395 if (optCheckChar (s, '@'))
4397 specclauses = specialClauses_undump (s);
4401 specclauses = specialClauses_undefined;
4404 advanceName (s); name = getStringWord (s);
4406 ue = uentry_makeFunctionBase (name, ct, access,
4409 ak, exp, defstate, isnull,
4410 exitCode, specc, nullPred,
4412 fileloc_copy (loc));
4413 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4420 advanceField (s); access = typeIdSet_undump (s);
4421 advanceName (s); name = getStringWord (s);
4423 ue = uentry_makeIterBase (name, access, ct,
4424 fileloc_copy (loc));
4431 advanceField (s); access = typeIdSet_undump (s);
4432 advanceName (s); name = getStringWord (s);
4434 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4444 if (optCheckChar (s, '$'))
4446 val = multiVal_undefined;
4447 access = typeIdSet_undefined;
4448 nullstate = NS_UNKNOWN;
4452 advanceField (s); val = multiVal_undump (s);
4453 advanceField (s); access = typeIdSet_undump (s);
4454 advanceField (s); nullstate = nstate_fromInt (getInt (s));
4457 advanceName (s); name = getStringWord (s);
4459 ue = uentry_makeConstantBase (name, ct, access,
4460 nullstate, fileloc_copy (loc), val);
4469 advanceField (s); rtype = ctype_undump (s);
4470 advanceName (s); name = getStringWord (s);
4471 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4475 llcontbuglit ("uentry_undump: invalid");
4476 ue = uentry_undefined;
4479 llcontbuglit ("uentry_undump: elips marker");
4480 ue = uentry_undefined;
4489 uentry_dump (uentry v)
4491 return (uentry_dumpAux (v, FALSE));
4495 uentry_dumpParam (uentry v)
4497 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
4498 ("dump: %s", uentry_unparseFull (v)));
4500 return (uentry_dumpAux (v, TRUE));
4504 uentry_dumpAux (uentry v, bool isParam)
4506 llassert (uentry_isValid (v));
4508 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
4513 llcontbuglit ("uentry_dump: invalid entry");
4514 return cstring_undefined;
4516 return (message ("!."));
4520 vkind vk = v->info->var->kind;
4521 sstate dss = sRef_getDefState (v->sref);
4522 nstate nst = sRef_getNullState (v->sref);
4523 alkind alk = sRef_getAliasKind (v->sref);
4524 exkind exk = sRef_getExKind (v->sref);
4525 chkind chk = v->info->var->checked;
4527 DPRINTF (("Dumping var"));
4529 if (dss == SS_UNKNOWN
4530 && nst == NS_UNKNOWN
4531 && alk == AK_IMPTEMP
4532 && exk == XO_UNKNOWN
4533 && chk == CH_UNKNOWN)
4535 sdump = cstring_makeLiteral ("$");
4537 else if (dss == SS_DEFINED
4538 && nst == NS_UNKNOWN
4539 && alk == AK_IMPTEMP
4540 && exk == XO_UNKNOWN
4541 && chk == CH_UNKNOWN)
4543 sdump = cstring_makeLiteral ("&");
4545 else if (dss == SS_UNKNOWN
4546 && nst == NS_UNKNOWN
4547 && alk == AK_UNKNOWN
4548 && exk == XO_UNKNOWN
4549 && chk == CH_UNKNOWN)
4551 sdump = cstring_makeLiteral ("^");
4553 else if (exk == XO_UNKNOWN
4554 && chk == CH_UNKNOWN)
4556 sdump = message ("%d@%d@%d&",
4563 sdump = message ("%d@%d@%d@%d@%d",
4574 return (message ("%q|@%d|%q#%s",
4575 ctype_dump (v->utype),
4578 isParam ? cstring_undefined : v->uname));
4582 return (message ("%q|%q#%s",
4583 ctype_dump (v->utype),
4585 isParam ? cstring_undefined : v->uname));
4590 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
4591 ctype_dump (v->utype),
4592 ynm_unparseCode (v->info->datatype->abs),
4593 ynm_unparseCode (v->info->datatype->mut),
4594 (int) sRef_getDefState (v->sref),
4595 (int) sRef_getNullState (v->sref),
4596 (int) sRef_getAliasKind (v->sref),
4597 (int) sRef_getExKind (v->sref),
4598 ctype_dump (v->info->datatype->type),
4602 cstring sdump, gdump, adump;
4603 alkind alk = sRef_getAliasKind (v->sref);
4604 exkind exk = sRef_getExKind (v->sref);
4606 if (sRef_getDefState (v->sref) == SS_DEFINED
4607 && !nstate_isKnown (sRef_getNullState (v->sref))
4608 && !exitkind_isKnown (v->info->fcn->exitCode)
4609 && v->info->fcn->specialCode == SPC_NONE
4610 && v->info->fcn->nullPred == QU_UNKNOWN)
4612 sdump = cstring_makeLiteral ("$");
4616 sdump = message ("@%d@%d@%d@%d@%d",
4617 (int) sRef_getDefState (v->sref),
4618 (int) sRef_getNullState (v->sref),
4619 (int) v->info->fcn->exitCode,
4620 (int) v->info->fcn->specialCode,
4621 (int) v->info->fcn->nullPred);
4624 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
4626 gdump = cstring_makeLiteral ("$");
4628 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
4629 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
4631 gdump = cstring_makeLiteral ("^");
4635 gdump = message ("@%s@%q@%s@%q",
4636 bool_dump (uentry_hasGlobs (v)),
4637 globSet_dump (uentry_getGlobs (v)),
4638 bool_dump (uentry_hasMods (v)),
4639 sRefSet_dump (uentry_getMods (v)));
4642 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
4644 adump = cstring_makeLiteral ("$");
4648 adump = message ("@%d@%d", (int) alk, (int) exk);
4651 if (uentry_hasSpecialClauses (v))
4653 return (message ("%q%q%q%q@%q@%q#%s",
4654 ctype_dump (v->utype),
4658 typeIdSet_dump (uentry_accessType (v)),
4659 specialClauses_dump (v->info->fcn->specclauses),
4664 return (message ("%q%q%q%q@%q#%s",
4665 ctype_dump (v->utype),
4669 typeIdSet_dump (uentry_accessType (v)),
4674 return (message ("%q@%q#%s",
4675 ctype_dump (v->utype),
4676 typeIdSet_dump (v->info->iter->access),
4679 return (message ("%q@%q#%s",
4680 ctype_dump (v->utype),
4681 typeIdSet_dump (uentry_accessType (v)),
4688 if (multiVal_isUnknown (v->info->uconst->val)
4689 && typeIdSet_isEmpty (uentry_accessType (v))
4690 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
4692 sdump = cstring_makeLiteral ("$");
4696 sdump = message ("@%q@%q@%d",
4697 multiVal_dump (v->info->uconst->val),
4698 typeIdSet_dump (uentry_accessType (v)),
4699 (int) sRef_getNullState (v->sref));
4702 return (message ("%q%q#%s",
4703 ctype_dump (v->utype),
4710 return (message ("%q@%q#%s",
4711 ctype_dump (v->utype),
4712 ctype_dump (v->info->datatype->type), v->uname));
4719 uentry_unparseAbbrev (uentry v)
4721 if (!uentry_isVariable (v))
4723 llcontbuglit ("uentry_unparseAbbrev: not variable");
4724 return uentry_unparse (v);
4727 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
4731 uentry_unparse (uentry v)
4735 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
4736 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
4738 st = uentry_getName (v);
4740 if (cstring_isDefined (st))
4742 return (ctype_unparseDeclaration (v->utype, st));
4747 return (cstring_copy (ctype_unparse (v->utype)));
4752 uentry_unparseFull (uentry v)
4754 if (uentry_isUndefined (v))
4756 return (cstring_makeLiteral ("<undefined>"));
4758 else if (uentry_isDatatype (v))
4760 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
4762 ekind_unparse (v->ukind),
4766 ctype_isDefined (v->info->datatype->type)
4767 ? v->info->datatype->type : ctype_unknown,
4768 ynm_unparse (v->info->datatype->mut),
4769 ynm_unparse (v->info->datatype->abs),
4770 sRef_unparseState (v->sref),
4771 fileloc_unparse (v->whereSpecified),
4772 fileloc_unparse (v->whereDefined)));
4774 else if (uentry_isFunction (v))
4776 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
4777 "globs: %q / [s: %q; decl: %q; def: %q]",
4779 ekind_unparse (v->ukind),
4782 sRef_unparseFull (v->sref),
4783 sRefSet_unparse (v->info->fcn->mods),
4784 globSet_unparse (v->info->fcn->globs),
4785 fileloc_unparse (v->whereSpecified),
4786 fileloc_unparse (v->whereDeclared),
4787 fileloc_unparse (v->whereDefined)));
4789 else if (uentry_isIter (v))
4791 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
4792 ekind_unparse (v->ukind),
4795 sRef_unparseFull (v->sref),
4796 fileloc_unparse (v->whereSpecified),
4797 fileloc_unparse (v->whereDefined)));
4799 else if (uentry_isVariable (v))
4802 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
4803 "kind <%d> isout <%d> used <%d>",
4804 checkedName (v->info->var->checked),
4806 ekind_unparse (v->ukind),
4809 sRef_unparseDeep (v->sref),
4810 fileloc_unparse (v->whereSpecified),
4811 fileloc_unparse (v->whereDefined),
4812 fileloc_unparse (v->whereDeclared),
4813 (int) v->info->var->kind,
4814 (int) v->info->var->defstate,
4819 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
4820 ekind_unparse (v->ukind),
4823 sRef_unparseFull (v->sref),
4824 fileloc_unparse (v->whereSpecified),
4825 fileloc_unparse (v->whereDefined)));
4830 bool uentry_hasAccessType (uentry e)
4832 if (uentry_isValid (e))
4837 return (!typeIdSet_isEmpty (e->info->iter->access));
4839 return (!typeIdSet_isEmpty (e->info->enditer->access));
4841 return (!typeIdSet_isEmpty (e->info->fcn->access));
4844 return (!typeIdSet_isEmpty (e->info->uconst->access));
4853 typeIdSet uentry_accessType (uentry e)
4855 if (uentry_isValid (e))
4860 return (e->info->iter->access);
4862 return (e->info->enditer->access);
4864 return (e->info->fcn->access);
4867 return (e->info->uconst->access);
4873 return typeIdSet_undefined;
4877 uentry_isVariable (uentry e)
4879 return (uentry_isVar (e));
4883 uentry_isSpecified (uentry e)
4885 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
4889 uentry_isReallySpecified (uentry e)
4891 return (uentry_isValid (e)
4892 && fileloc_isRealSpec (e->whereSpecified));
4896 uentry_isVar (uentry e)
4898 return (!uentry_isUndefined (e) && e->ukind == KVAR);
4902 uentry_isFakeTag (uentry e)
4904 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
4908 uentry_isDatatype (uentry e)
4910 return (!uentry_isUndefined (e) &&
4911 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
4912 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
4916 uentry_setAbstract (uentry e)
4920 llassert (uentry_isDatatype (e)
4921 && (ynm_isMaybe (e->info->datatype->abs)));
4923 oldid = ctype_typeId (e->info->datatype->type);
4924 e->info->datatype->abs = YES;
4925 e->info->datatype->type = ctype_createAbstract (oldid);
4929 uentry_setConcrete (uentry e)
4931 llassert (uentry_isDatatype (e)
4932 && (ynm_isMaybe (e->info->datatype->abs)));
4934 e->info->datatype->abs = NO;
4938 uentry_isAbstractDatatype (uentry e)
4940 return (uentry_isDatatype (e)
4941 && (ynm_isOn (e->info->datatype->abs)));
4945 uentry_isMaybeAbstract (uentry e)
4947 return (uentry_isDatatype (e)
4948 && (ynm_isMaybe (e->info->datatype->abs)));
4952 uentry_isMutableDatatype (uentry e)
4954 bool res = uentry_isDatatype (e)
4955 && (ynm_toBoolRelaxed (e->info->datatype->mut));
4961 uentry_isRefCountedDatatype (uentry e)
4963 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
4967 uentry_isParam (uentry u)
4969 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
4970 || u->info->var->kind == VKYIELDPARAM));
4974 uentry_isExpandedMacro (uentry u)
4976 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
4980 uentry_isSefParam (uentry u)
4982 return (uentry_isVariable (u)
4983 && (u->info->var->kind == VKSEFPARAM
4984 || u->info->var->kind == VKREFSEFPARAM
4985 || u->info->var->kind == VKSEFRETPARAM
4986 || u->info->var->kind == VKREFSEFRETPARAM));
4990 uentry_isRefParam (uentry u)
4992 return (uentry_isVariable (u)
4993 && (u->info->var->kind == VKREFPARAM
4994 || u->info->var->kind == VKREFYIELDPARAM
4995 || u->info->var->kind == VKREFSEFPARAM
4996 || u->info->var->kind == VKREFSEFRETPARAM));
5000 uentry_isAnyParam (uentry u)
5002 return (uentry_isVariable (u)
5003 && ((u->info->var->kind == VKPARAM)
5004 || (u->info->var->kind == VKSEFPARAM)
5005 || (u->info->var->kind == VKYIELDPARAM)
5006 || (u->info->var->kind == VKRETPARAM)
5007 || (u->info->var->kind == VKSEFRETPARAM)));
5011 uentry_getDefState (uentry u)
5013 if (uentry_isValid (u))
5015 return (sRef_getDefState (u->sref));
5019 return (SS_UNKNOWN);
5024 uentry_isOut (uentry u)
5026 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5027 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5031 uentry_isPartial (uentry u)
5033 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5034 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5038 uentry_isStateSpecial (uentry u)
5040 return ((uentry_isVariable (u)
5041 && (u->info->var->defstate == SS_SPECIAL))
5042 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5045 exitkind uentry_getExitCode (uentry ue)
5047 if (uentry_isFunction (ue))
5049 return ue->info->fcn->exitCode;
5058 uentry_nullPred (uentry u)
5060 llassert (uentry_isRealFunction (u));
5062 if (uentry_isFunction (u))
5064 return (u->info->fcn->nullPred);
5073 uentry_possiblyNull (uentry u)
5075 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5076 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5080 uentry_getAliasKind (uentry u)
5082 if (uentry_isValid (u))
5084 return (sRef_getAliasKind (uentry_getSref (u)));
5093 uentry_getExpKind (uentry u)
5095 if (uentry_isValid (u))
5097 return (sRef_getExKind (uentry_getSref (u)));
5106 uentry_isIter (uentry e)
5108 return (!uentry_isUndefined (e) && e->ukind == KITER);
5112 uentry_isEndIter (uentry e)
5114 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5118 uentry_isRealFunction (uentry e)
5120 return (uentry_isFunction (e) ||
5121 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5125 uentry_hasName (uentry e)
5127 if (uentry_isValid (e))
5129 cstring s = e->uname;
5131 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
5139 bool uentry_hasRealName (uentry e)
5141 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
5145 /*@observer@*/ globSet
5146 uentry_getGlobs (uentry l)
5148 if (uentry_isInvalid (l))
5150 return globSet_undefined;
5153 if (l->ukind != KFCN)
5155 if (l->ukind != KITER && l->ukind != KENDITER)
5157 if (l->ukind == KVAR)
5159 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5161 ekind_unparse (l->ukind)));
5165 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5167 ekind_unparse (l->ukind)));
5170 return globSet_undefined;
5173 return l->info->fcn->globs;
5176 /*@observer@*/ sRefSet
5177 uentry_getMods (uentry l)
5179 llassert (uentry_isValid (l));
5181 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5183 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5184 return sRefSet_undefined;
5187 return l->info->fcn->mods;
5191 uentry_getKind (uentry e)
5193 llassert (uentry_isValid (e));
5198 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5200 llassert (uentry_isEitherConstant (e));
5202 return (e->info->uconst->val);
5205 /*@observer@*/ uentryList
5206 uentry_getParams (uentry l)
5208 if (uentry_isInvalid (l)) return uentryList_undefined;
5215 ctype ct = l->utype;
5217 if (ctype_isFunction (ct))
5219 return (ctype_argsFunction (ct));
5223 return uentryList_undefined;
5228 ctype ct = l->utype;
5230 llassert (ctype_isFunction (ct));
5231 return (ctype_argsFunction (ct));
5238 /*@observer@*/ cstring
5239 uentry_rawName (uentry e)
5241 if (uentry_isValid (e))
5247 return cstring_undefined;
5252 uentry_getOptName (uentry e)
5254 cstring s = uentry_getName (e);
5256 if (cstring_isDefined (s))
5258 s = cstring_appendChar (s, ' ');
5265 uentry_getName (uentry e)
5267 cstring ret = cstring_undefined;
5269 if (uentry_isValid (e))
5272 if (uentry_isAnyTag (e))
5274 ret = fixTagName (e->uname);
5276 else if (uentry_isAnyParam (e))
5278 ret = cstring_copy (fixParamName (e->uname));
5282 ret = cstring_copy (e->uname);
5289 cstring uentry_getRealName (uentry e)
5291 if (uentry_isValid (e))
5293 if (uentry_isAnyTag (e))
5295 return (cstring_undefined);
5302 return cstring_undefined;
5305 ctype uentry_getType (uentry e)
5307 if (uentry_isValid (e))
5313 return ctype_unknown;
5317 fileloc uentry_whereLast (uentry e)
5321 if (uentry_isInvalid (e))
5323 return fileloc_undefined;
5326 loc = e->whereDefined;
5328 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5333 loc = uentry_whereDeclared (e);
5335 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5340 loc = uentry_whereSpecified (e);
5344 fileloc uentry_whereEither (uentry e)
5346 if (uentry_isInvalid (e)) return fileloc_undefined;
5348 if (fileloc_isDefined (e->whereDefined)
5349 && !fileloc_isExternal (e->whereDefined))
5351 return e->whereDefined;
5353 else if (fileloc_isDefined (e->whereDeclared))
5355 return e->whereDeclared;
5359 return e->whereSpecified;
5363 fileloc uentry_whereSpecified (uentry e)
5365 if (uentry_isInvalid (e)) return fileloc_undefined;
5367 return (e->whereSpecified);
5370 fileloc uentry_whereDefined (uentry e)
5372 if (uentry_isInvalid (e)) return fileloc_undefined;
5374 return (e->whereDefined);
5377 fileloc uentry_whereDeclared (uentry e)
5379 if (uentry_isInvalid (e)) return fileloc_undefined;
5381 return (e->whereDeclared);
5384 /*@observer@*/ fileloc
5385 uentry_whereEarliest (uentry e)
5387 if (uentry_isInvalid (e)) return fileloc_undefined;
5389 if (fileloc_isDefined (e->whereSpecified))
5391 return (e->whereSpecified);
5393 else if (fileloc_isDefined (e->whereDeclared))
5395 return (e->whereDeclared);
5399 return e->whereDefined;
5404 uentry_setFunctionDefined (uentry e, fileloc loc)
5406 if (uentry_isValid (e))
5408 llassert (uentry_isFunction (e));
5410 if (fileloc_isUndefined (e->whereDeclared))
5412 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5415 if (!fileloc_isDefined (e->whereDefined))
5417 e->whereDefined = fileloc_update (e->whereDefined, loc);
5423 uentry_setDeclDef (uentry e, fileloc f)
5425 uentry_setDeclared (e, f);
5427 if (!uentry_isFunction (e)
5428 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5430 uentry_setDefined (e, f);
5435 uentry_setDeclaredForce (uentry e, fileloc f)
5437 llassert (uentry_isValid (e));
5438 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5442 uentry_setDeclaredForceOnly (uentry e, fileloc f)
5444 llassert (uentry_isValid (e));
5445 fileloc_free (e->whereDeclared);
5446 e->whereDeclared = f;
5450 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
5454 llassert (uentry_isValid (e));
5455 oldloc = e->whereDeclared;
5457 if (fileloc_isDefined (oldloc))
5459 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5461 e->whereDeclared = f;
5462 fileloc_free (oldloc);
5471 e->whereDeclared = f;
5472 fileloc_free (oldloc);
5477 uentry_setDeclared (uentry e, fileloc f)
5481 llassert (uentry_isValid (e));
5482 oldloc = e->whereDeclared;
5484 if (fileloc_isDefined (oldloc))
5486 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
5488 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5497 e->whereDeclared = fileloc_update (e->whereDeclared, f);
5502 uentry_clearDefined (uentry e)
5504 if (uentry_isValid (e))
5506 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
5511 uentry_setDefined (uentry e, fileloc f)
5515 llassert (uentry_isValid (e));
5516 oldloc = e->whereDefined;
5518 if (fileloc_isDefined (oldloc))
5520 if (fileloc_isLib (oldloc)
5521 || fileloc_isImport (oldloc)
5522 || fileloc_isBuiltin (oldloc)
5523 || fileloc_isPreproc (oldloc))
5525 e->whereDefined = fileloc_update (e->whereDefined, f);
5529 if (fileloc_equal (oldloc, f) || context_processingMacros ())
5535 if (optgenerror (FLG_REDEF,
5536 message ("%s %q redefined",
5537 ekind_capName (e->ukind),
5538 uentry_getName (e)),
5541 llgenindentmsg (message ("Previous definition of %q",
5542 uentry_getName (e)),
5550 e->whereDefined = fileloc_update (e->whereDefined, f);
5555 uentry_isCodeDefined (uentry e)
5557 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
5561 uentry_isDeclared (uentry e)
5563 if (uentry_isValid (e))
5565 return (fileloc_isDefined (e->whereDeclared));
5571 sRef uentry_getSref (uentry e)
5573 /* not true, used for functions too (but shouldn't be? */
5574 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
5576 if (uentry_isInvalid (e)) return sRef_undefined;
5581 sRef uentry_getOrigSref (uentry e)
5583 if (uentry_isValid (e))
5585 sRef sr = sRef_copy (uentry_getSref (e));
5587 sRef_resetState (sr);
5588 sRef_clearDerived (sr);
5590 if (uentry_isVariable (e))
5592 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
5593 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
5600 return sRef_undefined;
5605 ** requires: uentry e is not in a hashed symbol table
5609 uentry_setName (uentry e, /*@only@*/ cstring n)
5611 llassert (uentry_isValid (e));
5613 cstring_free (e->uname);
5618 uentry_setType (uentry e, ctype t)
5620 if (uentry_isValid (e))
5623 sRef_setType (e->sref, t);
5628 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
5631 ctype rettype = ctype_unknown;
5633 llassert (uentry_isValid (ue));
5635 rct = ctype_realType (ue->utype);
5637 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
5639 uentry_makeVarFunction (ue);
5642 llassert (uentry_isFunction (ue));
5644 if (ctype_isFunction (rct))
5646 rettype = ctype_returnValue (rct);
5649 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
5653 uentry_setRefParam (uentry e)
5656 if (!uentry_isVar (e))
5658 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5662 if (e->info->var->kind == VKSEFPARAM)
5664 e->info->var->kind = VKREFSEFPARAM;
5666 else if (e->info->var->kind == VKSEFRETPARAM)
5668 e->info->var->kind = VKREFSEFRETPARAM;
5670 else if (e->info->var->kind == VKYIELDPARAM)
5672 e->info->var->kind = VKREFYIELDPARAM;
5676 e->info->var->kind = VKREFPARAM;
5682 uentry_setParam (uentry e)
5684 if (!uentry_isVar (e))
5686 if (uentry_isElipsisMarker (e))
5692 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
5699 if (e->info->var->kind == VKYIELDPARAM
5700 || e->info->var->kind == VKSEFPARAM
5701 || e->info->var->kind == VKSEFRETPARAM)
5707 e->info->var->kind = VKPARAM;
5711 e->uname = makeParam (e->uname);
5712 cstring_free (oldname);
5717 uentry_setSref (uentry e, sRef s)
5719 if (uentry_isValid (e))
5721 if (sRef_isValid (e->sref))
5723 sRef_mergeStateQuietReverse (e->sref, s);
5727 e->sref = sRef_saveCopy (s);
5733 uentry_getAbstractType (uentry e)
5735 llassert (uentry_isDatatype (e));
5738 ** This assertion removed.
5739 ** Okay to have undefined type, for system types
5741 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
5742 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
5747 if (ctype_isUndefined (e->info->datatype->type))
5749 return ctype_unknown;
5753 ** Sadly, a kludge...
5756 if (ctype_isUserBool (e->info->datatype->type)) {
5760 return e->info->datatype->type;
5763 ctype uentry_getRealType (uentry e)
5766 typeId uid = USYMIDINVALID;
5768 if (uentry_isInvalid (e))
5770 return ctype_unknown;
5773 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5775 if (uentry_isAnyTag (e))
5780 if (uentry_isAbstractType (e))
5782 ct = uentry_getAbstractType (e);
5784 if (ctype_isManifestBool (ct)) {
5788 llassert (ctype_isUA (ct));
5790 uid = ctype_typeId (ct);
5792 if (!context_hasAccess (uid))
5798 ct = uentry_getType (e);
5800 /* if (ctype_isUserBool (ct)) return ct; */
5802 if (ctype_isManifestBool (ct)) {
5806 if (ctype_isUA (ct))
5808 usymId iid = ctype_typeId (ct);
5810 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5812 llcontbug (message ("uentry_getRealType: recursive type! %s",
5813 ctype_unparse (ct)));
5818 /* evs 2000-07-25: possible infinite recursion ? */
5819 uentry ue2 = usymtab_getTypeEntry (iid);
5820 llassertprint (ue2 != e, ("Bad recursion: %s", uentry_unparseFull (e)));
5822 return uentry_getRealType (ue2);
5831 ctype uentry_getForceRealType (uentry e)
5834 typeId uid = USYMIDINVALID;
5836 if (uentry_isInvalid (e))
5838 return ctype_unknown;
5841 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
5843 if (uentry_isAnyTag (e))
5848 if (uentry_isAbstractType (e))
5850 ct = uentry_getAbstractType (e);
5851 llassert (ctype_isUA (ct));
5853 uid = ctype_typeId (ct);
5854 /* no check for access! */
5857 ct = uentry_getType (e);
5859 /* evs 2000-07-25 */
5860 /* if (ctype_isUserBool (ct)) return ct; */
5862 if (ctype_isManifestBool (ct)) {
5866 if (ctype_isUA (ct))
5868 usymId iid = ctype_typeId (ct);
5870 if /*@access usymId@*/ (iid == uid) /*@noaccess usymId@*/
5872 llcontbug (message ("uentry_getRealType: recursive type! %s",
5873 ctype_unparse (ct)));
5878 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
5887 uentry uentry_nameCopy (cstring name, uentry e)
5889 uentry enew = uentry_alloc ();
5891 llassert (uentry_isValid (e));
5893 /* enew->shallowCopy = FALSE; */
5894 enew->ukind = e->ukind;
5896 enew->utype = e->utype;
5897 enew->whereSpecified = fileloc_copy (e->whereSpecified);
5898 enew->whereDefined = fileloc_copy (e->whereDefined);
5899 enew->whereDeclared = fileloc_copy (e->whereDeclared);
5900 enew->sref = sRef_copy (e->sref);
5901 enew->used = e->used;
5903 enew->isPrivate = e->isPrivate;
5904 enew->hasNameError = FALSE;
5906 enew->uses = filelocList_new ();
5908 enew->storageclass = e->storageclass;
5909 enew->info = uinfo_copy (e->info, e->ukind);
5915 uentry_setDatatype (uentry e, usymId uid)
5917 llassert (uentry_isDatatype (e));
5919 if (uentry_isAbstractType (e))
5921 e->info->datatype->type = ctype_createAbstract (uid);
5925 e->info->datatype->type = ctype_createUser (uid);
5930 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
5931 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
5934 llassert (uentry_isValid (e));
5936 if (fileloc_isSpec (f) || fileloc_isImport (f))
5938 e->whereSpecified = f;
5939 e->whereDeclared = fileloc_undefined;
5940 e->whereDefined = fileloc_undefined;
5944 e->whereSpecified = fileloc_undefined;
5945 e->whereDeclared = f;
5946 e->whereDefined = fileloc_undefined;
5951 ucinfo_free (/*@only@*/ ucinfo u)
5953 multiVal_free (u->val);
5958 uvinfo_free (/*@only@*/ uvinfo u)
5964 udinfo_free (/*@only@*/ udinfo u)
5970 ufinfo_free (/*@only@*/ ufinfo u)
5972 globSet_free (u->globs);
5973 sRefSet_free (u->mods);
5974 specialClauses_free (u->specclauses);
5977 /*fix up if this is the right way to handle this --drl*/
5978 if (u->preconditions)
5979 constraintList_free(u->preconditions);
5980 if (u->postconditions)
5981 constraintList_free(u->postconditions);
5987 uiinfo_free (/*@only@*/ uiinfo u)
5993 ueinfo_free (/*@only@*/ ueinfo u)
5998 static /*@only@*/ ucinfo
5999 ucinfo_copy (ucinfo u)
6001 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6003 ret->val = multiVal_copy (u->val);
6004 ret->access = u->access;
6009 static /*@only@*/ uvinfo
6010 uvinfo_copy (uvinfo u)
6012 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6014 ret->kind = u->kind;
6015 ret->nullstate = u->nullstate;
6016 ret->defstate = u->defstate;
6017 ret->checked = u->checked;
6019 //ret->bufinfo = u->bufinfo;
6020 /*@i334@*/ return ret;
6023 static /*@only@*/ udinfo
6024 udinfo_copy (udinfo u)
6026 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6030 ret->type = u->type;
6035 static /*@only@*/ ufinfo
6036 ufinfo_copy (ufinfo u)
6038 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6040 ret->hasGlobs = u->hasGlobs;
6041 ret->hasMods = u->hasMods;
6042 ret->exitCode = u->exitCode;
6043 ret->specialCode = u->specialCode;
6044 ret->nullPred = u->nullPred;
6045 ret->access = u->access;
6046 ret->globs = globSet_newCopy (u->globs);
6047 ret->mods = sRefSet_newCopy (u->mods);
6048 ret->defparams = u->defparams;
6049 ret->specclauses = specialClauses_copy (u->specclauses);
6052 ret->preconditions = u->preconditions? constraintList_copy(u->preconditions): NULL;
6057 ret->postconditions = u->postconditions? constraintList_copy(u->postconditions): NULL;
6063 static /*@only@*/ uiinfo
6064 uiinfo_copy (uiinfo u)
6066 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6068 ret->access = u->access;
6069 ret->globs = globSet_newCopy (u->globs);
6070 ret->mods = sRefSet_newCopy (u->mods);
6075 static /*@only@*/ ueinfo
6076 ueinfo_copy (ueinfo u)
6078 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6080 ret->access = u->access;
6085 uinfo_free (uinfo u, ekind kind)
6090 case KCONST: ucinfo_free (u->uconst); break;
6091 case KVAR: uvinfo_free (u->var); break;
6095 case KDATATYPE: udinfo_free (u->datatype); break;
6096 case KFCN: ufinfo_free (u->fcn); break;
6097 case KITER: uiinfo_free (u->iter); break;
6098 case KENDITER: ueinfo_free (u->enditer); break;
6099 case KELIPSMARKER: break;
6100 case KINVALID: break;
6106 static /*@only@*/ /*@null@*/ uinfo
6107 uinfo_copy (uinfo u, ekind kind)
6109 if (kind == KELIPSMARKER || kind == KINVALID)
6115 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6120 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6121 case KVAR: ret->var = uvinfo_copy (u->var); break;
6125 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6126 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6127 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6128 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6136 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6138 filelocList_free (e->uses);
6139 cstring_free (e->uname);
6141 uinfo_free (e->info, e->ukind);
6143 fileloc_free (e->whereSpecified);
6144 fileloc_free (e->whereDefined);
6145 fileloc_free (e->whereDeclared);
6151 extern void uentry_markOwned (/*@owned@*/ uentry u)
6153 sfreeEventually (u);
6157 uentry_free (/*@only@*/ uentry e)
6159 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6161 uentry_reallyFree (e);
6166 ** For uentry's in the global or file scope
6170 uentry_freeComplete (/*@only@*/ uentry e)
6172 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6174 /*@i@*/ sRef_free (e->sref);
6175 e->sref = sRef_undefined;
6176 uentry_reallyFree (e);
6181 ** requires old->kind != new->kind, old->uname = new->uname
6185 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6187 llassert (uentry_isValid (old));
6188 llassert (uentry_isValid (unew));
6190 if (uentry_isEitherConstant (unew)
6191 && (fileloc_isPreproc (uentry_whereDeclared (old))
6192 || ctype_isUnknown (old->utype))
6193 && !uentry_isSpecified (old))
6201 if (!uentry_isDeclared (old))
6203 if (uentry_isSpecified (old))
6205 if (uentry_isSpecified (unew))
6207 llbuglit ("Respecification!");
6209 else if (uentry_isDeclared (unew))
6213 message ("%s %q inconsistently declared as %s: %t",
6214 ekind_capName (old->ukind),
6215 uentry_getName (unew),
6216 ekind_unparseLong (unew->ukind),
6218 uentry_whereDeclared (unew)))
6220 uentry_showWhereLast (old);
6232 message ("%s %q inconsistently declared as %s: %t",
6233 ekind_capName (old->ukind),
6234 uentry_getName (unew),
6235 ekind_unparseLong (unew->ukind),
6237 uentry_whereDeclared (unew)))
6239 uentry_showWhereLast (old);
6245 llassert (uentry_isDeclared (unew));
6249 message ("%s %q inconsistently redeclared as %s",
6250 ekind_capName (old->ukind),
6251 uentry_getName (unew),
6252 ekind_unparseLong (unew->ukind)),
6253 uentry_whereDeclared (unew)))
6255 uentry_showWhereLast (old);
6261 uentry_copyInto (old, unew);
6265 ** def is the definition of spec, modifies spec
6267 ** reports any inconsistencies
6268 ** returns the summary of all available information
6269 ** if spec and def are inconsistent, def is returned
6273 uentry_showWhereLast (uentry spec)
6275 if (uentry_isValid (spec))
6277 if (fileloc_isDefined (spec->whereDefined)
6278 && !fileloc_isLib (spec->whereDefined)
6279 && !fileloc_isPreproc (spec->whereDefined))
6281 llgenindentmsg (message ("Previous definition of %q: %t",
6282 uentry_getName (spec),
6283 uentry_getType (spec)),
6284 uentry_whereDefined (spec));
6286 else if (uentry_isDeclared (spec))
6288 llgenindentmsg (message ("Previous declaration of %q: %t",
6289 uentry_getName (spec),
6290 uentry_getType (spec)),
6291 uentry_whereDeclared (spec));
6293 else if (uentry_isSpecified (spec))
6295 if (uentry_hasName (spec))
6297 llgenindentmsg (message ("Specification of %q: %t",
6298 uentry_getName (spec),
6299 uentry_getType (spec)),
6300 uentry_whereSpecified (spec));
6304 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6305 uentry_whereSpecified (spec));
6310 /* nothing to show */
6316 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6318 fileloc loc = uentry_whereDefined (ce);
6320 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6322 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6326 loc = uentry_whereSpecified (ce);
6328 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6330 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6335 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6337 if (uentry_isDeclared (spec))
6339 llgenindentmsg (message ("Previous declaration of %q: %q",
6340 uentry_getName (spec), extra),
6341 uentry_whereDeclared (spec));
6343 else if (uentry_isSpecified (spec))
6345 llgenindentmsg (message ("Specification of %q: %q",
6346 uentry_getName (spec), extra),
6347 uentry_whereSpecified (spec));
6351 cstring_free (extra);
6356 uentry_showWhereDeclared (uentry spec)
6358 if (uentry_isDeclared (spec))
6360 if (uentry_hasName (spec))
6362 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6363 uentry_whereDeclared (spec));
6367 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6370 else if (uentry_isSpecified (spec))
6372 if (uentry_hasName (spec))
6374 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6375 uentry_whereSpecified (spec));
6379 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6384 /* nothing to show */
6390 uentry_showWhereAny (uentry spec)
6392 if (uentry_isDeclared (spec))
6394 if (uentry_hasName (spec))
6396 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6397 uentry_whereDeclared (spec));
6401 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6404 else if (uentry_isSpecified (spec))
6406 if (uentry_hasName (spec))
6408 llgenindentmsg (message ("Specification of %q",
6409 uentry_getName (spec)),
6410 uentry_whereSpecified (spec));
6414 llgenindentmsg (cstring_makeLiteral ("Specification"),
6415 uentry_whereSpecified (spec));
6418 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6420 if (uentry_hasName (spec))
6422 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6423 uentry_whereDefined (spec));
6427 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6432 /* nothing to show */
6437 uentry_showWhereDefined (uentry spec)
6439 if (uentry_isCodeDefined (spec))
6441 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
6442 uentry_whereDefined (spec));
6447 uentry_showWhereLastPlain (uentry spec)
6449 if (uentry_isDeclared (spec))
6451 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
6452 uentry_whereDeclared (spec));
6454 else if (uentry_isSpecified (spec))
6456 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6457 uentry_whereSpecified (spec));
6465 uentry_showWhereLastVal (uentry spec, cstring val)
6467 if (uentry_isDeclared (spec))
6469 llgenindentmsg (message ("Previous declaration of %q: %s",
6470 uentry_getName (spec), val),
6471 uentry_whereDeclared (spec));
6473 else if (uentry_isSpecified (spec))
6475 llgenindentmsg (message ("Specification of %q: %s",
6476 uentry_getName (spec), val),
6477 uentry_whereSpecified (spec));
6485 uentry_showWhereSpecified (uentry spec)
6487 if (uentry_isSpecified (spec))
6489 if (uentry_hasName (spec))
6491 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6492 uentry_whereSpecified (spec));
6496 llgenindentmsg (cstring_makeLiteral ("Specification"),
6497 uentry_whereSpecified (spec));
6500 else if (uentry_isDeclared (spec))
6502 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6503 uentry_whereDeclared (spec));
6507 /* nothing to show */
6512 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
6514 if (uentry_isSpecified (spec))
6516 if (uentry_hasName (spec))
6518 llgenindentmsg (message ("Specification of %q: %q",
6519 uentry_getName (spec), s),
6520 uentry_whereSpecified (spec));
6524 llgenindentmsg (message ("Specification: %q", s),
6525 uentry_whereSpecified (spec));
6528 else if (uentry_isDeclared (spec))
6530 llgenindentmsg (message ("Declaration of %q: %q",
6531 uentry_getName (spec), s),
6532 uentry_whereDeclared (spec));
6536 llgenindentmsg (message ("Previous: %q", s),
6537 uentry_whereLast (spec));
6546 checkStructConformance (uentry old, uentry unew)
6549 uentryList fold, fnew;
6552 ** requires: types of old and new are structs or unions
6555 llassert (uentry_isValid (old));
6556 llassert (uentry_isValid (unew));
6558 oldr = ctype_realType (old->utype);
6559 fold = ctype_getFields (oldr);
6561 newr = ctype_realType (unew->utype);
6562 fnew = ctype_getFields (newr);
6564 if (!uentryList_matchFields (fold, fnew))
6566 if (fileloc_equal (uentry_whereLast (old),
6567 uentry_whereLast (unew)))
6575 message ("%q %q %rdeclared with fields { %q }, %s "
6576 "with fields { %q }",
6577 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
6578 uentry_getName (old),
6579 uentry_isDeclared (old),
6580 uentryList_unparseAbbrev (fnew),
6581 uentry_specOrDefName (old),
6582 uentryList_unparseAbbrev (fold)),
6583 uentry_whereDeclared (unew)))
6585 uentry_showWhereLastPlain (old);
6586 uentryList_showFieldDifference (fold, fnew);
6590 old->utype = unew->utype;
6595 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6598 ** requires old and new are enums
6601 ctype rold = ctype_realType (old->utype);
6602 ctype rnew = ctype_realType (unew->utype);
6603 enumNameList eold = ctype_elist (rold);
6604 enumNameList enew = ctype_elist (rnew);
6606 if (!enumNameList_match (eold, enew))
6610 message ("Enum %q declared with members { %q } but "
6611 "specified with members { %q }",
6612 uentry_getName (old),
6613 enumNameList_unparse (enew),
6614 enumNameList_unparse (eold)),
6615 uentry_whereDeclared (unew)))
6617 uentry_showWhereSpecified (old);
6618 old->utype = unew->utype;
6624 ** either oldCurrent or newCurrent may be undefined!
6628 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
6629 uentry unew, uentry newCurrent, ctype newType,
6632 bool hasError = FALSE;
6634 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
6636 if (uentry_hasName (newCurrent))
6638 hasError = optgenerror
6640 message ("Parameter %d, %q, of function %q has inconsistent type: "
6641 "declared %t, %s %t",
6642 paramno + 1, uentry_getName (newCurrent),
6643 uentry_getName (unew),
6644 newType, uentry_specOrDefName (old), oldType),
6645 uentry_whereDeclared (newCurrent));
6649 hasError = optgenerror
6651 message ("Parameter %d of function %q has inconsistent type: "
6652 "declared %t, %s %t",
6653 paramno + 1, uentry_getName (unew),
6654 newType, uentry_specOrDefName (old), oldType),
6655 uentry_whereDeclared (newCurrent));
6657 DPRINTF (("type: %s / %s",
6658 ctype_unparse (newType),
6659 ctype_unparse (ctype_realType (newType))));
6664 if (uentry_isDeclared (unew))
6666 hasError = optgenerror
6668 message ("Parameter %d of function %s has inconsistent type: "
6669 "declared %t, %s %t",
6670 paramno + 1, unew->uname,
6671 newType, uentry_specOrDefName (old), oldType),
6672 uentry_whereDeclared (unew));
6676 hasError = optgenerror
6678 message ("Parameter %d of function %s has inconsistent type: "
6679 "declared %t, %s %t",
6680 paramno + 1, unew->uname,
6681 newType, uentry_specOrDefName (old), oldType),
6682 uentry_whereDeclared (unew));
6688 if (!uentry_isUndefined (oldCurrent))
6690 if (!uentry_isUndefined (newCurrent)
6691 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
6693 uentry_showWhereLast (oldCurrent);
6697 uentry_showWhereLastPlain (old);
6700 uentry_setType (oldCurrent, newType);
6704 uentry_showWhereLastPlain (old);
6710 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6714 message ("Function %s %rdeclared with %d arg%p, %s with %d",
6716 uentry_isDeclared (old),
6717 uentryList_size (uentry_getParams (unew)),
6718 uentry_specOrDefName (old),
6719 uentryList_size (uentry_getParams (old))),
6720 uentry_whereDeclared (unew)))
6722 uentry_showWhereLastPlain (old);
6727 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
6731 message ("Function %s inconsistently %rdeclared to return %t",
6733 uentry_isDeclared (old),
6734 ctype_returnValue (unew->utype)),
6735 uentry_whereDeclared (unew)))
6737 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
6741 static cstring paramStorageName (uentry ue)
6743 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
6746 static cstring fcnErrName (uentry ue)
6748 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
6751 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
6753 if (uentry_isVar (ue))
6755 return (checkedName (ue->info->var->checked));
6759 return (cstring_makeLiteralTemp ("<checked invalid>"));
6763 static cstring checkedName (chkind checked)
6767 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
6768 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
6769 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
6770 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
6771 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
6777 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
6782 if (uentry_isVar (unew))
6784 llassert (uentry_isVar (old));
6786 oldState = old->info->var->nullstate;
6787 newState = unew->info->var->nullstate;
6791 oldState = sRef_getNullState (old->sref);
6792 newState = sRef_getNullState (unew->sref);
6795 if (oldState == NS_ABSNULL)
6797 if (uentry_isVar (old))
6799 old->info->var->nullstate = newState;
6802 sRef_mergeNullState (old->sref, newState);
6804 else if (newState == NS_UNKNOWN)
6806 if (completeConform && newState != oldState
6807 && uentry_isReallySpecified (old))
6811 message ("%s %q specified as %s, but declared without %s qualifier",
6812 ekind_capName (unew->ukind),
6813 uentry_getName (unew),
6814 nstate_unparse (oldState),
6815 nstate_unparse (oldState)),
6816 uentry_whereDeclared (unew)))
6818 uentry_showWhereSpecified (old);
6822 if (uentry_isVar (unew))
6824 unew->info->var->nullstate = oldState;
6827 sRef_mergeNullState (unew->sref, oldState);
6829 else if (newState == NS_POSNULL)
6831 if (oldState == NS_MNOTNULL
6832 && (ctype_isUA (unew->utype)
6833 || (uentry_isFunction (unew)
6834 && ctype_isUA (ctype_returnValue (unew->utype)))))
6836 if (uentry_isVar (unew))
6838 unew->info->var->nullstate = oldState;
6841 sRef_mergeNullState (unew->sref, oldState);
6845 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
6846 || oldState == NS_UNKNOWN)
6853 ("%s %q inconsistently %rdeclared %s possibly null storage, "
6855 uentry_ekindName (unew),
6856 uentry_getName (unew),
6857 uentry_isDeclared (old),
6859 uentry_specOrDefName (old),
6860 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
6861 uentry_whereDeclared (unew)))
6863 uentry_showWhereSpecified (old);
6868 if (uentry_isVar (old))
6870 old->info->var->nullstate = newState;
6873 sRef_mergeNullState (old->sref, newState);
6876 else if (newState == NS_MNOTNULL)
6878 if (oldState != NS_MNOTNULL)
6884 message ("%s %q inconsistently %rdeclared %s notnull storage, "
6885 "%s without notnull qualifier",
6886 uentry_ekindName (unew),
6887 uentry_getName (unew),
6888 uentry_isDeclared (old),
6890 uentry_specOrDefName (old)),
6891 uentry_whereDeclared (unew)))
6893 uentry_showWhereSpecified (old);
6897 if (uentry_isVar (old))
6899 old->info->var->nullstate = newState;
6902 sRef_mergeNullState (old->sref, newState);
6907 if (uentry_isVar (unew))
6909 unew->info->var->nullstate = oldState;
6912 sRef_mergeNullState (unew->sref, oldState);
6917 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6918 bool mustConform, bool completeConform)
6924 if (uentry_isVar (old) && uentry_isVar (unew))
6926 oldState = old->info->var->defstate;
6927 newState = unew->info->var->defstate;
6932 oldState = sRef_getDefState (old->sref);
6933 newState = sRef_getDefState (unew->sref);
6936 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
6942 message ("%s %q inconsistently %rdeclared %s %s %s, "
6944 uentry_ekindName (unew),
6945 uentry_getName (unew),
6946 uentry_isDeclared (old),
6948 sstate_unparse (newState),
6949 paramStorageName (unew),
6950 uentry_specOrDefName (old),
6952 sstate_unparse (oldState),
6953 paramStorageName (unew)),
6954 uentry_whereDeclared (unew)))
6956 uentry_showWhereSpecified (old);
6960 if (vars) old->info->var->defstate = newState;
6961 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
6966 && (newState != oldState) && (oldState != SS_DEFINED)
6967 && uentry_isReallySpecified (old))
6971 message ("%s %q specified as %s, but declared without %s qualifier",
6972 ekind_capName (unew->ukind),
6973 uentry_getName (unew),
6974 sstate_unparse (oldState),
6975 sstate_unparse (oldState)),
6976 uentry_whereDeclared (unew)))
6978 uentry_showWhereSpecified (old);
6982 if (vars) unew->info->var->defstate = oldState;
6983 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
6988 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
6989 bool mustConform, bool completeConform)
6994 oldKind = sRef_getAliasKind (old->sref);
6995 newKind = sRef_getAliasKind (unew->sref);
6997 if (alkind_isImplicit (newKind)
6998 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7000 if (completeConform && !alkind_equal (newKind, oldKind)
7001 && uentry_isReallySpecified (old))
7005 message ("%s %q specified as %s, but declared without "
7006 "explicit alias qualifier",
7007 ekind_capName (unew->ukind),
7008 uentry_getName (unew),
7009 alkind_unparse (oldKind)),
7010 uentry_whereDeclared (unew)))
7012 uentry_showWhereSpecified (old);
7017 ** This really shouldn't be necessary, but it is!
7018 ** Function params (?) use new here.
7021 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7025 if (alkind_isKnown (newKind))
7027 if (!alkind_equal (oldKind, newKind))
7029 if (alkind_isKnown (oldKind))
7034 message ("%s %q inconsistently %rdeclared %s %s storage, "
7036 uentry_ekindName (unew),
7037 uentry_getName (unew),
7038 uentry_isDeclared (old),
7040 alkind_unparse (newKind),
7041 uentry_specOrDefName (old),
7042 alkind_unparse (oldKind)),
7043 uentry_whereDeclared (unew)))
7045 uentry_showWhereSpecified (old);
7047 sRef_setAliasKind (old->sref, AK_ERROR,
7048 uentry_whereDeclared (unew));
7052 sRef_setAliasKind (old->sref, newKind,
7053 uentry_whereDeclared (unew));
7058 if (!(alkind_isImplicit (newKind)))
7061 !uentry_isFunction (unew) &&
7064 message ("%s %q inconsistently %rdeclared %s %s storage, "
7065 "implicitly %s as temp storage",
7066 uentry_ekindName (unew),
7067 uentry_getName (unew),
7068 uentry_isDeclared (old),
7070 alkind_unparse (newKind),
7071 uentry_specOrDefName (old)),
7072 uentry_whereDeclared (unew)))
7074 uentry_showWhereSpecified (old);
7078 sRef_setAliasKind (old->sref, newKind,
7079 uentry_whereDeclared (unew));
7081 else /* newKind is temp or refcounted */
7088 else /* newKind unknown */
7095 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7096 bool mustConform, bool completeConform)
7101 oldKind = sRef_getExKind (old->sref);
7102 newKind = sRef_getExKind (unew->sref);
7104 if (exkind_isKnown (newKind))
7106 if (oldKind != newKind)
7108 if (exkind_isKnown (oldKind))
7113 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7114 uentry_ekindName (unew),
7115 uentry_getName (unew),
7116 uentry_isDeclared (old),
7118 exkind_unparse (newKind),
7119 uentry_specOrDefName (old),
7120 exkind_unparse (oldKind)),
7121 uentry_whereDeclared (unew)))
7123 uentry_showWhereSpecified (old);
7126 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7133 message ("%s %q inconsistently %rdeclared %s %s, "
7134 "implicitly %s without exposure qualifier",
7135 uentry_ekindName (unew),
7136 uentry_getName (unew),
7137 uentry_isDeclared (old),
7139 exkind_unparse (newKind),
7140 uentry_specOrDefName (old)),
7141 uentry_whereDeclared (unew)))
7143 uentry_showWhereSpecified (old);
7146 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7152 if (completeConform && exkind_isKnown (oldKind)
7153 && uentry_isReallySpecified (old))
7157 message ("%s %q specified as %s, but declared without "
7158 "exposure qualifier",
7159 ekind_capName (unew->ukind),
7160 uentry_getName (unew),
7161 exkind_unparse (oldKind)),
7162 uentry_whereDeclared (unew)))
7164 uentry_showWhereSpecified (old);
7168 /* yes, this is necessary! (if its a param) */
7169 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7174 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7175 /*@notnull@*/ uentry unew,
7176 bool mustConform, bool completeConform)
7178 checkDefState (old, unew, mustConform, completeConform);
7179 checkNullState (old, unew, mustConform, completeConform);
7180 checkAliasState (old, unew, mustConform, completeConform);
7181 checkExpState (old, unew, mustConform, completeConform);
7183 sRef_storeState (old->sref);
7184 sRef_storeState (unew->sref);
7188 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7190 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7195 llassert (uentry_isVar (old));
7196 llassert (uentry_isVar (unew));
7198 if (cstring_isEmpty (old->uname))
7200 cstring_free (old->uname);
7201 old->uname = cstring_copy (unew->uname);
7204 if (unew->info->var->kind == VKRETPARAM
7205 || unew->info->var->kind == VKSEFRETPARAM)
7207 if (old->info->var->kind != VKRETPARAM
7208 && old->info->var->kind != VKSEFRETPARAM)
7212 message ("Parameter %q inconsistently %rdeclared as "
7213 "returned parameter",
7214 uentry_getName (unew),
7215 uentry_isDeclared (old)),
7216 uentry_whereDeclared (unew)))
7218 uentry_showWhereSpecified (old);
7219 old->info->var->kind = unew->info->var->kind;
7225 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7227 if (old->info->var->kind != VKSEFPARAM
7228 && old->info->var->kind != VKSEFRETPARAM)
7232 message ("Parameter %qinconsistently %rdeclared as "
7234 uentry_getOptName (unew),
7235 uentry_isDeclared (old)),
7236 uentry_whereDeclared (unew)))
7238 uentry_showWhereSpecified (old);
7239 old->info->var->kind = unew->info->var->kind;
7244 if (old->info->var->kind == VKSPEC)
7246 old->info->var->kind = unew->info->var->kind;
7250 unew->info->var->kind = old->info->var->kind;
7253 if (unew->info->var->checked != CH_UNKNOWN
7254 && unew->info->var->checked != old->info->var->checked)
7256 if (old->info->var->checked == CH_UNKNOWN
7257 && !fileloc_isUser (uentry_whereLast (old)))
7265 message ("Variable %q inconsistently %rdeclared as "
7266 "%s parameter (was %s)",
7267 uentry_getName (unew),
7268 uentry_isDeclared (old),
7269 checkedName (unew->info->var->checked),
7270 checkedName (old->info->var->checked)),
7271 uentry_whereDeclared (unew)))
7273 uentry_showWhereSpecified (old);
7277 old->info->var->checked = unew->info->var->checked;
7282 && (old->info->var->checked != CH_UNKNOWN)
7283 && uentry_isReallySpecified (old))
7287 message ("%s %q specified as %s, but declared without %s qualifier",
7288 ekind_capName (unew->ukind),
7289 uentry_getName (unew),
7290 checkedName (old->info->var->checked),
7291 checkedName (old->info->var->checked)),
7292 uentry_whereDeclared (unew)))
7294 uentry_showWhereSpecified (old);
7298 unew->info->var->checked = old->info->var->checked;
7301 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7304 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7306 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7311 llassert (uentry_isVar (u1));
7312 llassert (uentry_isVar (u2));
7314 if (u1->info->var->kind != u2->info->var->kind) {
7315 if (u1->info->var->kind == VKSEFRETPARAM) {
7316 if (u2->info->var->kind == VKRETPARAM) {
7319 message ("Function types are inconsistent. Parameter %d is "
7320 "sef parameter, but non-sef parameter in "
7321 "assigned function: %s",
7322 paramno, exprNode_unparse (e)),
7324 } else if (u2->info->var->kind == VKSEFPARAM) {
7327 message ("Function types are inconsistent. Parameter %d is "
7328 "returns parameter, but non-returns parameter in "
7329 "assigned function: %s",
7330 paramno, exprNode_unparse (e)),
7335 message ("Function types are inconsistent. Parameter %d is "
7336 "sef returns parameter, but non-sef returns parameter in "
7337 "assigned function: %s",
7338 paramno, exprNode_unparse (e)),
7341 } else if (u1->info->var->kind == VKRETPARAM) {
7344 message ("Function types are inconsistent. Parameter %d is "
7345 "returns parameter, but non-returns parameter in "
7346 "assigned function: %s",
7347 paramno, exprNode_unparse (e)),
7349 } else if (u1->info->var->kind == VKSEFPARAM) {
7352 message ("Function types are inconsistent. Parameter %d is "
7353 "sef parameter, but non-sef parameter in "
7354 "assigned function: %s",
7355 paramno, exprNode_unparse (e)),
7358 if (u2->info->var->kind == VKSEFRETPARAM) {
7361 message ("Function types are inconsistent. Parameter %d is "
7362 "normal parameter, but sef returns parameter in "
7363 "assigned function: %s",
7364 paramno, exprNode_unparse (e)),
7366 } else if (u2->info->var->kind == VKSEFPARAM) {
7369 message ("Function types are inconsistent. Parameter %d is "
7370 "normal parameter, but sef parameter in "
7371 "assigned function: %s",
7372 paramno, exprNode_unparse (e)),
7374 } else if (u2->info->var->kind == VKRETPARAM) {
7377 message ("Function types are inconsistent. Parameter %d is "
7378 "normal parameter, but returns parameter in "
7379 "assigned function: %s",
7380 paramno, exprNode_unparse (e)),
7388 if (u1->info->var->defstate != u2->info->var->defstate)
7392 message ("Function types are inconsistent. Parameter %d is "
7393 "%s, but %s in assigned function: %s",
7395 sstate_unparse (u1->info->var->defstate),
7396 sstate_unparse (u2->info->var->defstate),
7397 exprNode_unparse (e)),
7401 if (u1->info->var->nullstate != u2->info->var->nullstate)
7405 message ("Function types are inconsistent. Parameter %d is "
7406 "%s, but %s in assigned function: %s",
7408 nstate_unparse (u1->info->var->nullstate),
7409 nstate_unparse (u2->info->var->nullstate),
7410 exprNode_unparse (e)),
7414 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
7418 message ("Function types are inconsistent. Parameter %d is "
7419 "%s, but %s in assigned function: %s",
7421 alkind_unparse (sRef_getAliasKind (u1->sref)),
7422 alkind_unparse (sRef_getAliasKind (u2->sref)),
7423 exprNode_unparse (e)),
7427 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
7431 message ("Function types are inconsistent. Parameter %d is "
7432 "%s, but %s in assigned function: %s",
7434 exkind_unparse (sRef_getExKind (u1->sref)),
7435 exkind_unparse (sRef_getExKind (u2->sref)),
7436 exprNode_unparse (e)),
7442 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
7443 /*@notnull@*/ uentry unew,
7444 bool mustConform, /*@unused@*/ bool completeConform)
7446 uentryList oldParams = uentry_getParams (old);
7447 uentryList newParams = uentry_getParams (unew);
7448 ctype newType = unew->utype;
7449 ctype oldType = old->utype;
7450 ctype oldRetType = ctype_unknown;
7451 ctype newRetType = ctype_unknown;
7453 if (uentry_isForward (old))
7455 mustConform = FALSE;
7456 uentry_copyInto (old, unew);
7461 ** check return values
7464 if (ctype_isKnown (oldType))
7466 llassert (ctype_isFunction (oldType));
7468 oldRetType = ctype_returnValue (oldType);
7471 if (ctype_isKnown (newType))
7473 llassert (ctype_isFunction (newType));
7475 newRetType = ctype_returnValue (newType);
7478 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
7479 && !ctype_matchDef (newRetType, oldRetType))
7481 if (mustConform) returnValueError (old, unew);
7485 if (ctype_isConj (newRetType))
7487 if (ctype_isConj (oldRetType))
7489 if (!ctype_sameAltTypes (newRetType, oldRetType))
7493 message ("Function %q inconsistently %rdeclared to "
7494 "return alternate types %s "
7495 "(types match, but alternates are not identical, "
7496 "so checking may not be correct)",
7497 uentry_getName (unew),
7498 uentry_isDeclared (old),
7499 ctype_unparse (newRetType)),
7500 uentry_whereDeclared (unew)))
7502 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
7508 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
7513 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7515 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
7517 if (exitkind_isKnown (unew->info->fcn->exitCode))
7521 message ("Function %q inconsistently %rdeclared using %s",
7522 uentry_getName (unew),
7523 uentry_isDeclared (old),
7524 exitkind_unparse (unew->info->fcn->exitCode)),
7525 uentry_whereDeclared (unew)))
7527 uentry_showWhereSpecified (old);
7532 unew->info->fcn->exitCode = old->info->fcn->exitCode;
7536 if (!qual_isUnknown (unew->info->fcn->nullPred))
7538 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
7542 message ("Function %q inconsistently %rdeclared using %s",
7543 uentry_getName (unew),
7544 uentry_isDeclared (old),
7545 qual_unparse (unew->info->fcn->nullPred)),
7546 uentry_whereDeclared (unew)))
7548 uentry_showWhereSpecified (old);
7554 unew->info->fcn->nullPred = old->info->fcn->nullPred;
7557 if (unew->info->fcn->specialCode != SPC_NONE)
7559 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
7563 message ("Function %q inconsistently %rdeclared using %s",
7564 uentry_getName (unew),
7565 uentry_isDeclared (old),
7566 specCode_unparse (unew->info->fcn->specialCode)),
7567 uentry_whereDeclared (unew)))
7569 uentry_showWhereSpecified (old);
7575 unew->info->fcn->specialCode = old->info->fcn->specialCode;
7582 if (!uentryList_sameObject (oldParams, newParams)
7583 && (!uentryList_isMissingParams (oldParams)))
7585 if (!uentryList_isMissingParams (newParams))
7588 int nparams = uentryList_size (oldParams);
7589 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
7591 if (nparams != uentryList_size (newParams))
7593 nargsError (old, unew);
7596 if (uentryList_size (newParams) < nparams)
7598 nparams = uentryList_size (newParams);
7601 while (paramno < nparams)
7603 uentry oldCurrent = uentryList_getN (oldParams, paramno);
7604 uentry newCurrent = uentryList_getN (newParams, paramno);
7605 ctype oldCurrentType = uentry_getType (oldCurrent);
7606 ctype newCurrentType = uentry_getType (newCurrent);
7608 llassert (uentry_isValid (oldCurrent)
7609 && uentry_isValid (newCurrent));
7611 if (!uentry_isElipsisMarker (oldCurrent)
7612 && !uentry_isElipsisMarker (newCurrent))
7614 checkVarConformance (oldCurrent, newCurrent,
7615 mustConform, completeConform);
7620 if (uentry_hasName (oldCurrent)
7621 && uentry_hasName (newCurrent))
7623 cstring oldname = uentry_getName (oldCurrent);
7624 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
7626 cstring nname = uentry_getName (newCurrent);
7629 if (cstring_isDefined (pfx)
7630 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
7632 oname = cstring_suffix (oldname, cstring_length (pfx));
7637 /*@-branchstate@*/ } /*@=branchstate@*/
7639 if (cstring_isDefined (pfx)
7640 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
7642 nnamefix = cstring_suffix (nname, cstring_length (pfx));
7647 /*@-branchstate@*/ } /*@=branchstate@*/
7649 if (!cstring_equal (oname, nnamefix))
7652 (FLG_DECLPARAMMATCH,
7653 message ("Definition parameter name %s does not match "
7654 "name of corresponding parameter in "
7657 uentry_whereLast (newCurrent)))
7659 uentry_showWhereLastPlain (oldCurrent);
7663 cstring_free (oldname);
7664 cstring_free (nname);
7668 if (!ctype_match (oldCurrentType, newCurrentType))
7670 paramTypeError (old, oldCurrent, oldCurrentType,
7671 unew, newCurrent, newCurrentType, paramno);
7675 if (ctype_isMissingParamsMarker (newCurrentType)
7676 || ctype_isElips (newCurrentType)
7677 || ctype_isMissingParamsMarker (oldCurrentType)
7678 || ctype_isElips (oldCurrentType))
7684 if (ctype_isConj (newCurrentType))
7686 if (ctype_isConj (oldCurrentType))
7688 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
7692 message ("Parameter %q inconsistently %rdeclared with "
7693 "alternate types %s "
7694 "(types match, but alternates are not identical, "
7695 "so checking may not be correct)",
7696 uentry_getName (newCurrent),
7697 uentry_isDeclared (oldCurrent),
7698 ctype_unparse (newCurrentType)),
7699 uentry_whereDeclared (unew)))
7701 uentry_showWhereLastVal (oldCurrent,
7702 ctype_unparse (oldCurrentType));
7710 message ("Parameter %q inconsistently %rdeclared with "
7711 "alternate types %s",
7712 uentry_getName (newCurrent),
7713 uentry_isDeclared (oldCurrent),
7714 ctype_unparse (newCurrentType)),
7715 uentry_whereDeclared (unew)))
7717 uentry_showWhereLastVal (oldCurrent,
7718 ctype_unparse (oldCurrentType));
7725 if (ctype_isConj (oldCurrentType))
7727 uentry_setType (newCurrent, oldCurrentType);
7735 ** Forgot this! detected by lclint:
7736 ** uentry.c:1257,15: Suspected infinite loop
7742 if (!uentryList_isMissingParams (newParams))
7744 if (ctype_isConj (oldRetType))
7746 old->utype = ctype_makeFunction (oldRetType,
7747 uentryList_copy (newParams));
7751 old->utype = unew->utype;
7755 checkGlobalsConformance (old, unew, mustConform, completeConform);
7756 checkModifiesConformance (old, unew, mustConform, completeConform);
7758 if (specialClauses_isDefined (unew->info->fcn->specclauses))
7760 if (!specialClauses_isDefined (old->info->fcn->specclauses))
7764 message ("Function %q redeclared using special clauses (can only "
7765 "be used in first declaration)",
7766 uentry_getName (unew)),
7767 uentry_whereDeclared (unew)))
7769 uentry_showWhereLast (old);
7774 specialClauses_checkEqual (old, unew);
7778 if (fileloc_isUndefined (old->whereDeclared))
7780 old->whereDeclared = fileloc_copy (unew->whereDeclared);
7782 else if (fileloc_isUndefined (unew->whereDeclared))
7784 unew->whereDeclared = fileloc_copy (old->whereDeclared);
7793 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
7797 llassert (uentry_isValid (ue));
7798 llassert (uentry_isEitherConstant (ue));
7800 uval = ue->info->uconst->val;
7802 if (multiVal_isDefined (uval))
7804 if (multiVal_isDefined (m))
7806 if (!multiVal_equiv (uval, m))
7810 message ("%s %q defined with inconsistent value: %q",
7811 ekind_capName (ue->ukind),
7812 uentry_getName (ue),
7813 multiVal_unparse (m)),
7816 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
7824 ue->info->uconst->val = m;
7825 multiVal_free (uval);
7830 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7833 bool typeError = FALSE;
7835 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
7837 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
7841 checkStructConformance (old, unew);
7846 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7848 llbug (message ("struct tags: bad types: %t / %t",
7849 old->utype, unew->utype));
7853 else if (uentry_isEnumTag (old))
7855 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
7857 if (mustConform) checkEnumConformance (old, unew);
7861 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
7863 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
7864 ctype_unparse (unew->utype)));
7868 else if (!ctype_match (old->utype, unew->utype))
7870 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
7872 ctype realt = ctype_realType (unew->utype);
7874 if (ctype_isRealInt (realt) || ctype_isChar (realt))
7876 unew->utype = ctype_bool;
7882 typeError = optgenerror
7884 message ("%q defined as %s", uentry_getName (old),
7885 ctype_unparse (realt)),
7886 uentry_whereDeclared (unew));
7894 ctype oldr = ctype_realType (old->utype);
7895 ctype newr = ctype_realType (unew->utype);
7897 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
7899 checkStructConformance (old, unew);
7901 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
7903 checkStructConformance (old, unew);
7905 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
7907 checkEnumConformance (old, unew);
7909 else if (uentry_isConstant (old)
7910 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
7912 /* okay...for now! (should check the type is reset later... */
7916 DPRINTF (("YABA!"));
7919 message ("%s %q %rdeclared with inconsistent type: %t",
7920 ekind_capName (unew->ukind),
7921 uentry_getName (unew),
7922 uentry_isDeclared (old),
7924 uentry_whereDeclared (unew)))
7926 uentry_showWhereLast (old);
7942 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
7943 /*@notnull@*/ uentry unew,
7944 bool mustConform, bool completeConform)
7946 if (ctype_isDefined (unew->info->datatype->type))
7949 ** bool is hard coded here, since it is built into LCL.
7950 ** For now, we're stuck with LCL's types.
7953 if (ctype_isDirectBool (old->utype) &&
7954 cstring_equalLit (unew->uname, "bool"))
7956 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
7957 evs 2000-07-25: removed
7959 unew->utype = ctype_bool;
7962 if (ctype_isUnknown (old->info->datatype->type))
7964 old->info->datatype->type = unew->info->datatype->type;
7968 DPRINTF (("Old: %s / New: %s",
7969 uentry_unparseFull (old),
7970 uentry_unparseFull (unew)));
7971 DPRINTF (("Types: %s / %s",
7972 ctype_unparse (old->info->datatype->type),
7973 ctype_unparse (unew->info->datatype->type)));
7975 if (ctype_matchDef (old->info->datatype->type,
7976 unew->info->datatype->type))
7985 ("Type %q %s with inconsistent type: %t",
7986 uentry_getName (unew),
7987 uentry_reDefDecl (old, unew),
7988 unew->info->datatype->type),
7989 uentry_whereDeclared (unew)))
7991 uentry_showWhereLastExtra
7992 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
7995 old->info->datatype->type = unew->info->datatype->type;
8000 if (unew->info->datatype->abs != MAYBE)
8002 if (ynm_isOff (old->info->datatype->abs)
8003 && ynm_isOn (unew->info->datatype->abs))
8005 if (!ctype_isDirectBool (old->utype))
8010 ("Datatype %q inconsistently %rdeclared as abstract type",
8011 uentry_getName (unew),
8012 uentry_isDeclared (old)),
8013 uentry_whereDeclared (unew)))
8015 uentry_showWhereLastPlain (old);
8019 else if (ynm_isOn (old->info->datatype->abs)
8020 && ynm_isOff (unew->info->datatype->abs))
8022 if (!ctype_isDirectBool (old->utype))
8027 ("Datatype %q inconsistently %rdeclared as concrete type",
8028 uentry_getName (unew),
8029 uentry_isDeclared (old)),
8030 uentry_whereDeclared (unew)))
8032 uentry_showWhereLastPlain (old);
8043 if (ynm_isOn (old->info->datatype->abs))
8045 old->sref = unew->sref;
8046 unew->info->datatype->mut = old->info->datatype->mut;
8049 && uentry_isReallySpecified (old))
8054 ("Datatype %q specified as abstract, "
8055 "but abstract annotation not used in declaration",
8056 uentry_getName (unew)),
8057 uentry_whereDeclared (unew)))
8059 uentry_showWhereLastPlain (old);
8065 unew->info->datatype->abs = old->info->datatype->abs;
8067 if (ynm_isMaybe (unew->info->datatype->mut))
8069 if (completeConform && ynm_isOff (old->info->datatype->mut)
8070 && uentry_isReallySpecified (old))
8075 ("Datatype %q specified as immutable, "
8076 "but immutable annotation not used in declaration",
8077 uentry_getName (unew)),
8078 uentry_whereDeclared (unew)))
8080 uentry_showWhereLastPlain (old);
8084 unew->info->datatype->mut = old->info->datatype->mut;
8086 else if (ynm_isMaybe (old->info->datatype->mut))
8088 old->info->datatype->mut = unew->info->datatype->mut;
8092 if (ynm_isOn (old->info->datatype->abs))
8094 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8098 message ("Datatype %q inconsistently %rdeclared as immutable",
8099 uentry_getName (unew),
8100 uentry_isDeclared (old)),
8101 uentry_whereDeclared (unew)))
8103 uentry_showWhereLastPlain (old);
8108 if (ynm_isOff (old->info->datatype->mut)
8109 && ynm_isOn (unew->info->datatype->mut))
8113 message ("Datatype %q inconsistently %rdeclared as mutable",
8114 uentry_getName (unew),
8115 uentry_isDeclared (old)),
8116 uentry_whereDeclared (unew)))
8118 uentry_showWhereLastPlain (old);
8123 old->info->datatype->mut = unew->info->datatype->mut;
8126 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8130 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8131 /*@notnull@*/ uentry unew,
8133 /*@unused@*/ bool completeConform)
8135 multiVal oldVal = old->info->uconst->val;
8136 multiVal newVal = unew->info->uconst->val;
8138 if (multiVal_isDefined (oldVal))
8140 if (multiVal_isDefined (newVal))
8142 if (!multiVal_equiv (oldVal, newVal))
8147 message ("%s %q %rdeclared with inconsistent value: %q",
8148 ekind_capName (unew->ukind),
8149 uentry_getName (unew),
8150 uentry_isDeclared (old),
8151 multiVal_unparse (newVal)),
8152 uentry_whereDeclared (unew)))
8154 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
8158 unew->info->uconst->val = multiVal_copy (oldVal);
8159 multiVal_free (newVal);
8168 old->info->uconst->val = multiVal_copy (newVal);
8173 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8174 /*@notnull@*/ uentry unew, bool mustConform,
8175 bool completeConform)
8177 bool typeError = FALSE;
8178 bool fcnConformance = FALSE;
8180 if (!ekind_equal (unew->ukind, old->ukind))
8183 ** okay, only if one is a function and the other is
8184 ** a variable of type function.
8187 if (unew->ukind == KENUMCONST
8188 && old->ukind == KCONST)
8190 old->ukind = KENUMCONST;
8194 if (unew->ukind == KFCN
8195 && old->ukind == KCONST
8196 && ctype_isUnknown (old->utype))
8199 ** When a function is defined with an unparam macro
8202 uentry_copyInto (old, unew);
8206 if (uentry_isExpandedMacro (old)
8207 && uentry_isEitherConstant (unew))
8209 uentry_copyInto (old, unew);
8213 if (uentry_isEndIter (unew))
8215 if (ctype_isUnknown (old->utype))
8217 if (!uentry_isSpecified (old)
8218 && uentry_isCodeDefined (unew))
8220 if (!fileloc_withinLines (uentry_whereDefined (old),
8221 uentry_whereDeclared (unew), 2))
8222 { /* bogus! will give errors if there is too much whitespace */
8226 ("Iterator finalized name %q does not match name in "
8227 "previous iter declaration (should be end_%q). This iter "
8228 "is declared at %q",
8229 uentry_getName (unew),
8230 uentry_getName (old),
8231 fileloc_unparse (uentry_whereDefined (old))),
8232 uentry_whereDeclared (old));
8236 uentry_copyInto (old, unew);
8241 KindConformanceError (old, unew, mustConform);
8245 if (uentry_isFunction (unew))
8247 if (uentry_isVariable (old))
8249 if (!ctype_isUnknown (old->utype))
8251 if (ctype_isFunction (old->utype))
8253 uentry_makeVarFunction (old);
8254 checkFunctionConformance (old, unew, mustConform,
8256 fcnConformance = TRUE;
8260 KindConformanceError (old, unew, mustConform);
8265 if (uentry_isExpandedMacro (old))
8267 if (fileloc_isUndefined (unew->whereDefined))
8269 unew->whereDefined = fileloc_update (unew->whereDefined,
8273 uentry_copyInto (old, unew);
8274 old->used = unew->used = TRUE;
8279 /* undeclared identifier */
8280 old->utype = unew->utype;
8281 uentry_makeVarFunction (old);
8282 checkFunctionConformance (old, unew, FALSE, FALSE);
8283 fcnConformance = TRUE;
8289 KindConformanceError (old, unew, mustConform);
8292 else if (uentry_isFunction (old) && uentry_isVariable (unew))
8294 if (!ctype_isUnknown (unew->utype))
8296 if (ctype_isFunction (unew->utype))
8298 uentry_makeVarFunction (unew);
8299 checkFunctionConformance (old, unew, mustConform, completeConform);
8300 fcnConformance = TRUE;
8304 KindConformanceError (old, unew, mustConform);
8309 KindConformanceError (old, unew, mustConform);
8314 KindConformanceError (old, unew, mustConform);
8320 ** check parameter lists for functions
8321 ** (before type errors, to get better messages
8324 if (uentry_isFunction (old))
8326 checkFunctionConformance (old, unew, mustConform, completeConform);
8327 fcnConformance = TRUE;
8331 if (!ctype_isUndefined (old->utype))
8333 typeError = checkTypeConformance (old, unew, mustConform);
8340 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
8342 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
8345 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
8347 DPRINTF (("Check datatype: %s / %s",
8348 uentry_unparseFull (old),
8349 uentry_unparseFull (unew)));
8351 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
8354 if (uentry_isVariable (old) && uentry_isVariable (unew))
8357 !ctype_matchDef (old->utype, unew->utype))
8362 ("Variable %q %s with inconsistent type (arrays and pointers are "
8363 "not identical in variable declarations): %t",
8364 uentry_getName (unew),
8365 uentry_reDefDecl (old, unew),
8367 uentry_whereDeclared (unew)))
8369 uentry_showWhereLast (old);
8372 ** Avoid repeated errors.
8375 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
8377 old->whereDefined = fileloc_update (old->whereDefined,
8385 checkVarConformance (old, unew, mustConform, completeConform);
8390 /* old->utype = unew->utype; */
8394 if (ctype_isConj (old->utype))
8396 if (ctype_isConj (unew->utype))
8398 if (!ctype_sameAltTypes (old->utype, unew->utype))
8402 message ("%s %q inconsistently %rdeclared with "
8403 "alternate types %s "
8404 "(types match, but alternates are not identical, "
8405 "so checking may not be correct)",
8406 ekind_capName (uentry_getKind (old)),
8407 uentry_getName (unew),
8408 uentry_isDeclared (old),
8409 ctype_unparse (unew->utype)),
8410 uentry_whereDeclared (unew)))
8412 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
8416 old->utype = unew->utype;
8423 if (ctype_isUnknown (old->utype))
8425 old->utype = unew->utype;
8430 if (unew->ukind == old->ukind)
8433 unew->info = uinfo_copy (old->info, old->ukind);
8436 sRef_storeState (old->sref);
8437 sRef_storeState (unew->sref);
8441 ** modifies spec to reflect def, reports any inconsistencies
8445 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
8447 llassert (uentry_isValid (spec));
8448 llassert (uentry_isValid (def));
8449 llassert (cstring_equal (spec->uname, def->uname));
8451 uentry_checkConformance (spec, def, TRUE,
8452 context_getFlag (FLG_NEEDSPEC));
8454 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
8457 ** okay, declarations conform. Propagate extra information.
8460 uentry_setDefined (spec, uentry_whereDefined (def));
8461 uentry_setDeclared (spec, uentry_whereDeclared (def));
8463 if (uentry_isStatic (def))
8467 message ("%s %q specified, but declared as static",
8468 ekind_capName (def->ukind),
8469 uentry_getName (def)),
8470 uentry_whereDeclared (def)))
8472 uentry_showWhereSpecified (spec);
8477 spec->storageclass = def->storageclass;
8480 sRef_storeState (spec->sref);
8482 spec->used = def->used || spec->used;
8483 spec->hasNameError |= def->hasNameError;
8487 if (!spec->hasNameError)
8489 uentry_checkName (spec);
8498 ** Can't generate function redeclaration errors when the
8499 ** entries are merged, since we don't yet know if its the
8500 ** definition of the function.
8504 uentry_clearDecl (void)
8506 posRedeclared = uentry_undefined;
8507 fileloc_free (posLoc);
8508 posLoc = fileloc_undefined;
8512 uentry_checkDecl (void)
8514 if (uentry_isValid (posRedeclared))
8516 llassert (fileloc_isDefined (posLoc));
8518 if (uentry_isCodeDefined (posRedeclared))
8520 if (optgenerror (FLG_REDECL,
8521 message ("%s %q declared after definition",
8522 ekind_capName (posRedeclared->ukind),
8523 uentry_getName (posRedeclared)),
8526 llgenindentmsg (message ("Definition of %q",
8527 uentry_getName (posRedeclared)),
8528 posRedeclared->whereDeclared);
8533 if (optgenerror (FLG_REDECL,
8534 message ("%s %q declared more than once",
8535 ekind_capName (posRedeclared->ukind),
8536 uentry_getName (posRedeclared)),
8539 llgenindentmsg (message ("Previous declaration of %q",
8540 uentry_getName (posRedeclared)),
8541 posRedeclared->whereDeclared);
8546 fileloc_free (posLoc);
8547 posLoc = fileloc_undefined;
8548 posRedeclared = uentry_undefined;
8552 ** Redefinition of old as unew.
8553 ** modifies old to reflect unew, reports any inconsistencies
8557 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
8559 fileloc olddef = uentry_whereDeclared (old);
8560 fileloc unewdef = uentry_whereDeclared (unew);
8564 if (uentry_isExtern (unew))
8566 uentry_setUsed (old, unewdef);
8570 fileloc_isUndefined (olddef)
8571 && fileloc_isDefined (uentry_whereDefined (old))
8572 && !uentry_isExpandedMacro (old);
8574 if (!context_getFlag (FLG_INCONDEFSLIB)
8575 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8577 mustConform = FALSE;
8584 llassert (uentry_isValid (old));
8585 llassert (uentry_isValid (unew));
8586 llassert (cstring_equal (old->uname, unew->uname));
8589 ** should check old one was extern!
8592 if (uentry_isStatic (old))
8594 if (!(uentry_isStatic (unew)))
8598 message ("%s %q shadows static declaration",
8599 ekind_capName (unew->ukind),
8600 uentry_getName (unew)),
8603 uentry_showWhereLast (old);
8608 uentry_setDeclDef (old, unewdef);
8611 else if (uentry_isStatic (unew))
8613 uentry_setDeclDef (old, unewdef);
8615 else if (uentry_isExtern (old))
8617 uentry_setDeclared (old, unewdef);
8621 if (!uentry_isExtern (unew) && !uentry_isForward (old)
8622 && !fileloc_equal (olddef, unewdef)
8623 && !fileloc_isUndefined (olddef)
8624 && !fileloc_isUndefined (unewdef)
8625 && !fileloc_isBuiltin (olddef)
8626 && !fileloc_isBuiltin (unewdef)
8627 && !uentry_isYield (old)
8628 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
8630 if (uentry_isVariable (old) || uentry_isVariable (unew))
8632 ; /* will report redeclaration error later */
8636 if (fileloc_isDefined (uentry_whereDefined (old)))
8640 message ("%s %q defined more than once",
8641 ekind_capName (unew->ukind),
8642 uentry_getName (unew)),
8643 uentry_whereLast (unew)))
8646 (message ("Previous definition of %q",
8647 uentry_getName (old)),
8648 uentry_whereLast (old));
8651 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
8653 uentry_copyInto (old, unew);
8654 old->sref = sRef_saveCopy (old->sref);
8662 if (fileloc_isLib (olddef)
8663 || fileloc_isUndefined (olddef)
8664 || fileloc_isImport (olddef))
8666 if (uentry_isExtern (unew))
8668 if (uentry_isExtern (old)
8669 || (fileloc_isDefined (uentry_whereDeclared (old))
8670 && (!fileloc_equal (uentry_whereDeclared (old),
8671 uentry_whereDefined (old)))))
8675 message ("%s %q declared more than once",
8676 ekind_capName (unew->ukind),
8677 uentry_getName (unew)),
8678 unew->whereDeclared))
8681 (message ("Previous declaration of %q",
8682 uentry_getName (old)),
8683 old->whereDeclared);
8687 uentry_setExtern (old);
8691 uentry_setDefined (old, unewdef);
8697 uentry_checkConformance (old, unew, mustConform, FALSE);
8699 old->used = old->used || unew->used;
8700 old->uses = filelocList_append (old->uses, unew->uses);
8701 unew->uses = filelocList_undefined;
8703 sRef_storeState (old->sref);
8704 sRef_storeState (unew->sref);
8708 old->whereDefined = fileloc_update (old->whereDefined,
8713 ** No redeclaration errors for functions here, since we
8714 ** don't know if this is the definition of the function.
8717 if (fileloc_isUser (old->whereDeclared)
8718 && fileloc_isUser (unew->whereDeclared)
8719 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
8720 && !fileloc_isDefined (unew->whereDefined))
8722 if (uentry_isFunction (old))
8724 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
8725 posLoc = fileloc_update (posLoc, unew->whereDeclared);
8729 if (optgenerror (FLG_REDECL,
8730 message ("%s %q declared more than once",
8731 ekind_capName (unew->ukind),
8732 uentry_getName (unew)),
8733 unew->whereDeclared))
8735 llgenindentmsg (message ("Previous declaration of %q",
8736 uentry_getName (old)),
8737 old->whereDeclared);
8742 if (fileloc_isUndefined (old->whereDefined))
8744 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
8748 if (!context_processingMacros ()
8749 && fileloc_isUser (old->whereDefined)
8750 && fileloc_isUser (unew->whereDefined)
8751 && !fileloc_equal (old->whereDefined, unew->whereDefined))
8753 if (uentry_isVariable (unew) || uentry_isFunction (unew))
8755 if (uentry_isVariable (unew)
8756 && uentry_isExtern (unew))
8758 if (optgenerror (FLG_REDECL,
8759 message ("%s %q declared after definition",
8760 ekind_capName (unew->ukind),
8761 uentry_getName (unew)),
8762 unew->whereDeclared))
8764 llgenindentmsg (message ("Definition of %q",
8765 uentry_getName (old)),
8771 if (optgenerror (FLG_REDEF,
8772 message ("%s %q redefined",
8773 ekind_capName (unew->ukind),
8774 uentry_getName (unew)),
8775 unew->whereDefined))
8777 llgenindentmsg (message ("Previous definition of %q",
8778 uentry_getName (old)),
8786 if (uentry_isExternal (unew))
8788 old->whereDefined = fileloc_createExternal ();
8791 if (unew->hasNameError)
8793 old->hasNameError = TRUE;
8798 if (!old->hasNameError)
8800 uentry_checkName (old);
8803 llassert (!ctype_isUndefined (old->utype));
8807 uentry_copyState (uentry res, uentry other)
8809 llassert (uentry_isValid (res));
8810 llassert (uentry_isValid (other));
8812 res->used = other->used;
8814 res->info->var->kind = other->info->var->kind;
8815 res->info->var->defstate = other->info->var->defstate;
8816 res->info->var->nullstate = other->info->var->nullstate;
8817 res->info->var->checked = other->info->var->checked;
8819 sRef_copyState (res->sref, other->sref);
8823 uentry_sameKind (uentry u1, uentry u2)
8825 if (uentry_isValid (u1) && uentry_isValid (u2))
8827 if (uentry_isVar (u1) && uentry_isVar (u2))
8829 ctype c1 = u1->utype;
8830 ctype c2 = u2->utype;
8832 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
8835 ** both functions, or both not functions
8838 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
8842 return ((u1->ukind == u2->ukind));
8849 static void uentry_copyInto (/*@unique@*/ uentry unew, uentry old)
8851 llassert (uentry_isValid (unew));
8852 llassert (uentry_isValid (old));
8854 unew->ukind = old->ukind;
8855 unew->uname = cstring_copy (old->uname);
8856 unew->utype = old->utype;
8858 unew->whereSpecified = fileloc_copy (old->whereSpecified);
8859 unew->whereDefined = fileloc_copy (old->whereDefined);
8860 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8862 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
8863 unew->used = old->used;
8865 unew->isPrivate = old->isPrivate;
8866 unew->hasNameError = old->hasNameError;
8867 unew->uses = filelocList_undefined;
8869 unew->storageclass = old->storageclass;
8870 unew->info = uinfo_copy (old->info, old->ukind);
8875 uentry_copy (uentry e)
8877 if (uentry_isValid (e))
8879 uentry enew = uentry_alloc ();
8880 DPRINTF (("copy: %s", uentry_unparseFull (e)));
8881 uentry_copyInto (enew, e);
8882 DPRINTF (("Here we are..."));
8883 DPRINTF (("original: %s", uentry_unparseFull (e)));
8884 DPRINTF (("copy: %s", uentry_unparse (enew)));
8885 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
8890 return uentry_undefined;
8895 uentry_setState (uentry res, uentry other)
8897 llassert (uentry_isValid (res));
8898 llassert (uentry_isValid (other));
8900 llassert (res->ukind == other->ukind);
8901 llassert (res->ukind == KVAR);
8903 res->sref = sRef_saveCopy (other->sref);
8904 res->used = other->used;
8905 filelocList_free (res->uses);
8906 res->uses = other->uses;
8907 other->uses = filelocList_undefined;
8908 res->lset = other->lset;
8912 uentry_mergeUses (uentry res, uentry other)
8914 llassert (uentry_isValid (res));
8915 llassert (uentry_isValid (other));
8917 res->used = other->used || res->used;
8918 res->lset = other->lset || res->lset;
8919 res->uses = filelocList_append (res->uses, other->uses);
8920 other->uses = filelocList_undefined;
8925 ** This is a really ugly routine.
8927 ** gack...fix this one day.
8932 ** >> res is the false branch, other is the true branch (or continuation)
8934 ** >> res is the true branch, other is the false branch (or continutation)
8941 ** References not effected by res are propagated from other.
8945 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
8946 bool flip, clause cl, fileloc loc)
8950 message ("%s %q is %s %s, but %s %s.",
8951 ekind_capName (res->ukind), uentry_getName (res),
8952 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
8953 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
8956 if (sRef_isDead (res->sref))
8958 sRef_showStateInfo (res->sref);
8960 else if (sRef_isKept (res->sref))
8962 sRef_showAliasInfo (res->sref);
8964 else /* dependent */
8966 sRef_showAliasInfo (res->sref);
8967 sRef_showAliasInfo (other->sref);
8970 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
8974 static bool incompatibleStates (sRef rs, sRef os)
8976 alkind rk = sRef_getAliasKind (rs);
8977 alkind ok = sRef_getAliasKind (os);
8979 if (alkind_isError (rk) || alkind_isError (ok))
8985 return ((sRef_isDead (rs)
8986 || (alkind_isKept (rk) && !alkind_isKept (ok))
8987 || (alkind_isDependent (rk)
8988 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
8989 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
8994 branchStateAltError (/*@notnull@*/ uentry res,
8995 /*@notnull@*/ uentry other, bool flip,
8996 clause cl, fileloc loc)
9000 message ("%s %q is %s %s, but %s %s.",
9001 ekind_capName (res->ukind), uentry_getName (res),
9002 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
9003 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
9006 if (sRef_isDead (other->sref))
9008 sRef_showStateInfo (other->sref);
9012 sRef_showAliasInfo (other->sref);
9015 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9016 sRef_setDefinedComplete (res->sref, fileloc_undefined);
9018 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
9019 sRef_setDefinedComplete (other->sref, fileloc_undefined);
9023 static bool notNull (sRef sr, bool flip)
9025 return (!sRef_definitelyNull (sr)
9026 && !(sRef_isKept (sr))
9027 && !(sRef_isDependent (sr))
9028 && !(flip ? usymtab_isProbableDeepNull (sr)
9029 : usymtab_isAltProbablyDeepNull (sr)));
9033 uentry_mergeState (uentry res, uentry other, fileloc loc,
9034 bool mustReturn, bool flip, bool opt,
9037 llassert (uentry_isValid (res));
9038 llassert (uentry_isValid (other));
9040 llassert (res->ukind == other->ukind);
9041 llassert (res->ukind == KVAR);
9043 DPRINTF (("Merge state: %s / %s",
9044 uentry_unparse (res),
9045 uentry_unparse (other)));
9047 if (sRef_isValid (res->sref))
9051 if (incompatibleStates (res->sref, other->sref))
9053 if (sRef_isThroughArrayFetch (res->sref)
9054 && !context_getFlag (FLG_STRICTBRANCHSTATE))
9056 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
9058 sRef_maybeKill (res->sref, loc);
9060 else if (sRef_isPossiblyDead (other->sref))
9062 sRef_maybeKill (res->sref, loc);
9071 if (notNull (other->sref, flip))
9073 if (sRef_isLocalParamVar (res->sref)
9074 && (sRef_isLocalState (other->sref)
9075 || sRef_isDependent (other->sref)))
9077 if (sRef_isDependent (res->sref))
9079 sRef_setDependent (other->sref, loc);
9083 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
9088 branchStateError (res, other, flip, cl, loc);
9093 if (sRef_isKept (res->sref))
9095 sRef_setKept (other->sref, loc);
9100 if (incompatibleStates (other->sref, res->sref))
9102 if (notNull (res->sref, !flip))
9104 if (sRef_isLocalParamVar (res->sref)
9105 && (sRef_isDependent (res->sref)
9106 || sRef_isLocalState (res->sref)))
9108 if (sRef_isDependent (other->sref))
9110 sRef_setDependent (res->sref, loc);
9114 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
9119 if (sRef_isParam (other->sref))
9122 ** If the local variable associated
9123 ** with the param has the correct state,
9125 ** (e.g., free (s); s = new(); ...
9128 uentry uvar = usymtab_lookupSafe (other->uname);
9130 if (uentry_isValid (uvar)
9131 && ((sRef_isDead (other->sref)
9132 && sRef_isOnly (uvar->sref))
9133 || (sRef_isDependent (other->sref)
9134 && sRef_isOwned (uvar->sref))))
9140 branchStateAltError (res, other,
9146 branchStateAltError (res, other,
9153 if (sRef_isKept (other->sref))
9155 sRef_setKept (res->sref, loc);
9161 DPRINTF (("Merge opt..."));
9162 sRef_mergeOptState (res->sref, other->sref, cl, loc);
9163 DPRINTF (("Done!"));
9167 sRef_mergeState (res->sref, other->sref, cl, loc);
9172 if (sRef_isModified (other->sref))
9174 sRef_setModified (res->sref);
9178 if (cl == DOWHILECLAUSE)
9180 res->used = other->used || res->used;
9181 res->lset = other->lset || res->lset;
9182 res->uses = filelocList_append (res->uses, other->uses);
9183 other->uses = filelocList_undefined;
9187 if (sRef_isMacroParamRef (res->sref)
9188 && !uentry_isSefParam (other)
9189 && !uentry_isSefParam (res))
9191 bool hasError = FALSE;
9193 if (bool_equal (res->used, other->used))
9195 res->used = other->used;
9199 if (other->used && !flip)
9204 message ("Macro parameter %q used in true clause, "
9205 "but not in false clause",
9206 uentry_getName (res)),
9207 uentry_whereDeclared (res));
9214 message ("Macro parameter %q used in false clause, "
9215 "but not in true clause",
9216 uentry_getName (res)),
9217 uentry_whereDeclared (res));
9223 /* make it sef now, prevent more errors */
9224 res->info->var->kind = VKREFSEFPARAM;
9230 res->used = other->used || res->used;
9231 res->lset = other->lset || res->lset;
9232 res->uses = filelocList_append (res->uses, other->uses);
9233 other->uses = filelocList_undefined;
9239 void uentry_setUsed (uentry e, fileloc loc)
9241 static bool firstTime = TRUE;
9242 static bool showUses = FALSE;
9243 static bool exportLocal = FALSE;
9247 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
9249 showUses = context_getFlag (FLG_SHOWUSES);
9250 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
9255 if (uentry_isValid (e))
9259 if (sRef_isMacroParamRef (e->sref))
9261 if (uentry_isYield (e) || uentry_isSefParam (e))
9267 if (context_inConditional ())
9271 message ("Macro parameter %q used in conditionally "
9272 "executed code (may or may not be "
9273 "evaluated exactly once)",
9274 uentry_getName (e)),
9277 e->info->var->kind = VKREFSEFPARAM;
9286 message ("Macro parameter %q used more than once",
9287 uentry_getName (e)),
9288 uentry_whereDeclared (e)))
9290 e->info->var->kind = VKREFSEFPARAM;
9297 if ((dp = uentry_directParamNo (e)) >= 0)
9299 uentry_setUsed (usymtab_getParam (dp), loc);
9304 if (!sRef_isLocalVar (e->sref))
9308 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
9314 if (context_inMacro ())
9316 e->uses = filelocList_addUndefined (e->uses);
9320 e->uses = filelocList_addDifferentFile
9322 uentry_whereDeclared (e),
9331 bool uentry_isReturned (uentry u)
9333 return (uentry_isValid (u) && uentry_isVar (u)
9334 && (u->info->var->kind == VKRETPARAM
9335 || u->info->var->kind == VKSEFRETPARAM));
9338 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
9340 llassert (uentry_isRealFunction (u));
9342 if (ctype_isFunction (u->utype)
9343 && sRef_isStateSpecial (uentry_getSref (u)))
9345 specialClauses clauses = uentry_getSpecialClauses (u);
9346 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9348 sRef_setAllocated (res, g_currentloc);
9350 specialClauses_postElements (clauses, cl)
9352 sRefSet refs = specialClause_getRefs (cl);
9353 sRefMod modf = specialClause_getEffectFunction (cl);
9355 sRefSet_elements (refs, el)
9357 sRef base = sRef_getRootBase (el);
9359 if (sRef_isResult (base))
9363 sRef sr = sRef_fixBase (el, res);
9364 modf (sr, g_currentloc);
9371 } end_sRefSet_elements ;
9373 } end_specialClauses_postElements ;
9381 sRefSet prefs = sRefSet_new ();
9382 sRef res = sRef_undefined;
9385 params = uentry_getParams (u);
9387 uentryList_elements (params, current)
9389 if (uentry_isReturned (current))
9391 if (exprNodeList_size (args) >= paramno)
9393 exprNode ecur = exprNodeList_nth (args, paramno);
9394 sRef tref = exprNode_getSref (ecur);
9396 if (sRef_isValid (tref))
9398 sRef tcref = sRef_copy (tref);
9400 if (sRef_isDead (tcref))
9402 sRef_setDefined (tcref, g_currentloc);
9403 sRef_setOnly (tcref, g_currentloc);
9406 if (sRef_isRefCounted (tcref))
9408 /* could be a new ref now (but only if its returned) */
9409 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
9412 sRef_makeSafe (tcref);
9414 prefs = sRefSet_insert (prefs, tcref);
9420 } end_uentryList_elements ;
9422 if (sRefSet_size (prefs) > 0)
9424 nstate n = sRef_getNullState (u->sref);
9426 if (sRefSet_size (prefs) == 1)
9428 res = sRefSet_choose (prefs);
9432 res = sRefSet_mergeIntoOne (prefs);
9435 if (nstate_isKnown (n))
9437 sRef_setNullState (res, n, g_currentloc);
9442 if (ctype_isFunction (u->utype))
9444 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
9448 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
9451 if (sRef_isRefCounted (res))
9453 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9457 if (sRef_getNullState (res) == NS_ABSNULL)
9459 ctype ct = ctype_realType (u->utype);
9461 if (ctype_isAbstract (ct))
9463 sRef_setNotNull (res, g_currentloc);
9467 if (ctype_isUser (ct))
9469 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
9473 sRef_setNotNull (res, g_currentloc);
9478 if (sRef_isRefCounted (res))
9480 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
9482 else if (sRef_isKillRef (res))
9484 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
9491 ak = sRef_getAliasKind (res);
9493 if (alkind_isImplicit (ak))
9495 sRef_setAliasKind (res,
9496 alkind_fixImplicit (ak),
9500 sRefSet_free (prefs);
9506 static bool uentry_isRefCounted (uentry ue)
9508 ctype ct = uentry_getType (ue);
9510 if (ctype_isFunction (ct))
9512 return (ctype_isRefCounted (ctype_returnValue (ct)));
9516 return (ctype_isRefCounted (ct));
9521 ** old was declared yield in the specification.
9522 ** new is declared in the iter implementation.
9525 void uentry_checkYieldParam (uentry old, uentry unew)
9529 llassert (uentry_isVariable (old));
9530 llassert (uentry_isVariable (unew));
9532 unew->info->var->kind = VKYIELDPARAM;
9533 (void) checkTypeConformance (old, unew, TRUE);
9534 checkVarConformance (old, unew, TRUE, FALSE);
9536 /* get rid of param marker */
9538 name = uentry_getName (unew);
9539 cstring_free (unew->uname);
9541 unew->info->var->kind = VKREFYIELDPARAM;
9543 uentry_setUsed (old, fileloc_undefined);
9544 uentry_setUsed (unew, fileloc_undefined);
9547 /*@observer@*/ cstring
9548 uentry_ekindName (uentry ue)
9550 if (uentry_isValid (ue))
9555 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
9557 return cstring_makeLiteralTemp ("Datatype");
9559 return cstring_makeLiteralTemp ("Enum member");
9561 return cstring_makeLiteralTemp ("Constant");
9563 if (uentry_isParam (ue))
9565 return cstring_makeLiteralTemp ("Parameter");
9567 else if (uentry_isExpandedMacro (ue))
9569 return cstring_makeLiteralTemp ("Expanded macro");
9573 return cstring_makeLiteralTemp ("Variable");
9576 return cstring_makeLiteralTemp ("Function");
9578 return cstring_makeLiteralTemp ("Iterator");
9580 return cstring_makeLiteralTemp ("Iterator finalizer");
9582 return cstring_makeLiteralTemp ("Struct tag");
9584 return cstring_makeLiteralTemp ("Union tag");
9586 return cstring_makeLiteralTemp ("Enum tag");
9588 return cstring_makeLiteralTemp ("Optional parameters");
9593 return cstring_makeLiteralTemp ("<Undefined>");
9599 void uentry_setHasNameError (uentry ue)
9601 llassert (uentry_isValid (ue));
9603 ue->hasNameError = TRUE;
9606 void uentry_checkName (uentry ue)
9608 if (uentry_isValid (ue)
9609 && !uentry_isElipsisMarker (ue)
9610 && context_getFlag (FLG_NAMECHECKS)
9611 && !ue->hasNameError
9612 && !uentry_isEndIter (ue)
9613 && !fileloc_isBuiltin (uentry_whereLast (ue))
9614 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
9617 if (uentry_isPriv (ue))
9619 ; /* any checks here? */
9621 else if (fileloc_isExternal (uentry_whereDefined (ue)))
9623 ; /* no errors for externals */
9629 if (uentry_isExpandedMacro (ue))
9635 if (uentry_isExpandedMacro (ue))
9639 else if (uentry_isVariable (ue))
9641 sRef sr = uentry_getSref (ue);
9643 if (sRef_isValid (sr))
9645 scope = sRef_getScope (sr);
9652 else if (uentry_isFunction (ue)
9653 || uentry_isIter (ue)
9654 || uentry_isEndIter (ue)
9655 || uentry_isConstant (ue))
9657 scope = uentry_isStatic (ue) ? fileScope : globScope;
9659 else /* datatypes, etc. must be global */
9664 usymtab_checkDistinctName (ue, scope);
9667 if (context_getFlag (FLG_CPPNAMES))
9669 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
9671 uentry_setHasNameError (ue);
9675 if (scope == globScope)
9677 checkGlobalName (ue);
9679 if (context_getFlag (FLG_ANSIRESERVED))
9681 if (uentry_hasName (ue)
9682 && !uentry_isAnyTag (ue))
9684 if (checkAnsiName (uentry_rawName (ue),
9685 uentry_whereLast (ue)))
9687 uentry_setHasNameError (ue);
9694 checkLocalName (ue);
9696 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
9698 if (uentry_hasName (ue)
9699 && !uentry_isAnyTag (ue))
9701 if (checkAnsiName (uentry_rawName (ue),
9702 uentry_whereLast (ue)))
9704 uentry_setHasNameError (ue);
9710 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
9716 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
9722 ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
9723 if (!context_inMacro ())
9725 sRef_setGlobalScopeSafe ();
9728 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
9729 uentry_setUsed (ue, loc);
9731 tloc = fileloc_createExternal ();
9732 uentry_setDefined (ue, tloc);
9733 fileloc_free (tloc);
9734 uentry_setHasNameError (ue);
9736 if (context_getFlag (FLG_REPEATUNRECOG))
9738 uentry_markOwned (ue);
9742 ue = usymtab_supReturnFileEntry (ue);
9745 if (!context_inMacro ())
9747 sRef_clearGlobalScopeSafe ();
9753 /* new start modifications */
9755 void uentry_testInRange (uentry p_e, uentry cconstant) {
9756 if( uentry_isValid(p_e) ) {
9757 if( sRef_isValid (p_e->sref) ) {
9758 char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
9759 int index = atoi( t );
9761 usymtab_testInRange (p_e->sref, index);
9767 /* void uentry_setStringLength (uentry p_e, uentry cconstant) { */
9768 /* if( uentry_isValid(p_e) ) { */
9769 /* if( p_e->info != NULL) { */
9770 /* if( p_e->info->var != NULL) { */
9771 /* char *t = cstring_toCharsSafe (uentry_unparse(cconstant)); */
9772 /* int length = atoi( t ); */
9774 /* p_e->info->var->bufinfo->len = length; */
9775 /* p_e->sref->bufinfo.len = length; */
9776 /* printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size); */
9783 static void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
9784 if( uentry_isValid(p_e) ) {
9785 if( p_e->info != NULL) {
9786 if( p_e->info->var != NULL) {
9787 int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
9788 p_e->info->var->bufinfo->size = size;
9789 p_e->sref->bufinfo.size = size;
9790 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
9791 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
9792 // fprintf(stderr, "and %d\n", size );
9800 /* start modifications */
9802 requires: p_e is defined, is a ptr/array variable
9804 effects: sets the state of the variable
9807 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
9808 if( uentry_isValid(p_e) ) {
9809 if( p_e->info != NULL) {
9810 if( p_e->info->var != NULL) {
9811 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
9812 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9818 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
9822 requires: p_e is defined, is a ptr/array variable
9824 effects: sets the size of the buffer
9827 void uentry_setNullTerminatedState (uentry p_e) {
9828 if( uentry_isValid(p_e) ) {
9829 if( p_e->info != NULL) {
9830 if( p_e->info->var != NULL) {
9831 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
9832 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
9838 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
9843 requires: p_e is defined, is a ptr/array variable
9845 effects: sets the state of the variable
9848 /* void uentry_setNotNullTerminatedState (uentry p_e) { */
9849 /* if( uentry_isValid(p_e) ) { */
9850 /* if( p_e->info != NULL) { */
9851 /* if( p_e->info->var != NULL) { */
9852 /* p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED; */
9853 /* p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED; */
9859 /* fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n"); */
9864 requires: p_e is defined, is a ptr/array variable
9866 effects: sets the size of the buffer
9869 void uentry_setSize (uentry p_e, int size) {
9870 if( uentry_isValid(p_e) ) {
9871 if( p_e->info != NULL) {
9872 if( p_e->info->var != NULL) {
9873 p_e->info->var->bufinfo->size = size;
9874 p_e->sref->bufinfo.size = size;
9880 fprintf(stderr, "uentry:Error in setSize\n");
9885 requires: p_e is defined, is a ptr/array variable
9887 effects: sets the length of the buffer
9890 void uentry_setLen (uentry p_e, int len) {
9891 if( uentry_isValid(p_e) ) {
9892 if( p_e->info != NULL) {
9893 if( p_e->info->var != NULL) {
9894 p_e->info->var->bufinfo->len = len;
9895 p_e->sref->bufinfo.len = len;
9901 fprintf(stderr, "uentry:Error in setLen\n");