]> andersk Git - splint.git/blob - src/uentry.c
Fixed bug in makefile causing unnecessary remaking of cgrammar.c.
[splint.git] / src / uentry.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
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.
10 ** 
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.
15 ** 
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.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** uentry.c
26 */
27
28 # include "splintMacros.nf"
29 # include "basic.h"
30 # include "structNames.h"
31 # include "nameChecks.h"
32
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
37
38 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43 static void uentry_checkIterArgs (uentry p_ue);
44 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
45
46 static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_warningstream@*/ ; 
47
48 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr) 
49      /*@modifies p_ue@*/ ;
50
51 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
52      /*@modifies p_ue@*/ ;
53
54 /*@access ekind@*/
55 static void checkAliasState (/*@notnull@*/ uentry p_old,
56                                /*@notnull@*/ uentry p_unew, 
57                                bool p_mustConform, bool p_completeConform) 
58    /*@modifies p_old, p_unew@*/ ;
59 static void checkNullState (/*@notnull@*/ uentry p_old,
60                             /*@notnull@*/ uentry p_unew, 
61                             bool p_mustConform, bool p_completeConform) 
62    /*@modifies p_old, p_unew@*/ ;
63
64 static void checkVarConformance (/*@notnull@*/ uentry p_old,
65                                  /*@notnull@*/ uentry p_unew, 
66                                  bool p_mustConform, bool p_completeConform) 
67    /*@modifies p_old, p_unew@*/;
68
69 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
70 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
71
72 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
73
74 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
75    /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
76    /*@modifies p_e@*/;
77
78 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
79 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
80 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
81 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
82 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
83 static void 
84   paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
85                   ctype p_oldType, /*@notnull@*/ uentry p_unew,
86                   /*@notnull@*/ uentry p_newCurrent, 
87                   ctype p_newType, int p_paramno) /*@modifies g_warningstream@*/ ;
88
89 static /*@only@*/ /*@notnull@*/ uentry 
90   uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
91                           /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
92
93 static /*@only@*/ /*@notnull@*/ uentry 
94   uentry_makeConstantAux (cstring p_n, ctype p_t, 
95                           /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
96                           /*@only@*/ multiVal p_m) /*@*/ ;
97
98 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
99 {
100   if (uentry_isVariable (ue) 
101       && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
102           || ctype_isUnknown (uentry_getType (ue))))
103     {
104       uentry_makeVarFunction (ue);
105     }
106 }
107
108 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/ 
109 {
110   uentry ue = (uentry) dmalloc (sizeof (*ue));
111   ue->warn = warnClause_undefined; /*@i32@*/
112   nuentries++;
113   totuentries++;
114   
115   return ue;
116 }
117
118 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
119 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
120
121 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
122 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
123 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
124 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
125 static void ucinfo_free (/*@only@*/ ucinfo p_u);
126 static void uvinfo_free (/*@only@*/ uvinfo p_u);
127
128 # ifdef DOANNOTS
129
130 static /*@only@*/ cstring ancontext_unparse (ancontext an)
131 {
132   switch (an)
133     {
134     case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
135     case AN_FCNRETURN: return cstring_makeLiteral ("return value");
136     case AN_FCNPARAM: return cstring_makeLiteral ("function param");
137     case AN_SUFIELD: return cstring_makeLiteral ("su field");
138     case AN_TDEFN: return cstring_makeLiteral ("type definition");
139     case AN_GSVAR: return cstring_makeLiteral ("global/static var");
140     case AN_CONST: return cstring_makeLiteral ("constant");
141     BADDEFAULT;
142     }
143   BADEXIT;
144 }
145
146 static int annots[AN_LAST][QU_LAST];
147 static int decls[AN_LAST];
148 static int shdecls[AN_LAST];
149 static int idecls[AN_LAST];
150
151 void initAnnots ()
152 {
153   int i, j;
154
155   for (i = AN_UNKNOWN; i < AN_LAST; i++)
156     {
157       decls[i] = 0;
158       shdecls[i] = 0;
159       idecls[i] = 0;
160
161       for (j = QU_UNKNOWN; j < QU_LAST; j++)
162         {
163           annots[i][j] = 0;
164         }
165     }
166 }
167
168 static void tallyAnnot (ancontext ac, qual q)
169 {
170   (annots[ac][q])++;
171 }
172
173 void printAnnots ()
174 {
175   int total[QU_LAST];
176   int alltotals = 0;
177   int totdecls = 0;
178   int totshdecls = 0;
179   int totidecls = 0;
180   int i, j;
181
182   for (j = QU_UNKNOWN; j < QU_LAST; j++)
183     {
184       total[j] = 0;
185     }
186
187   for (i = AN_UNKNOWN; i < AN_LAST; i++)
188     {
189       int tmptot;
190
191       if (decls[i] > 0)
192         {
193           printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n", 
194                   ancontext_unparse (i),
195                   decls[i], shdecls[i], idecls[i]);
196           
197           totdecls += decls[i];
198           totshdecls += shdecls[i];
199           totidecls += idecls[i];
200           
201           for (j = QU_UNKNOWN; j < QU_LAST; j++)
202             {
203               total[j] += annots[i][j];
204               alltotals += annots[i][j];
205             }
206           
207           printf ("   Allocation:\n");
208           
209           tmptot = 0;
210           
211           for (j = QU_UNKNOWN; j < QU_LAST; j++)
212             {
213               if (qual_isAliasQual (j) && !qual_isUnique (j))
214                 {
215                   if (annots[i][j] > 0)
216                     {
217                       printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
218                               100.0 * (double)annots[i][j] / (double)decls[i]);
219                       tmptot += annots[i][j];
220                     }
221                 }
222             }
223
224           printf ("   Exposure:\n");
225           
226           tmptot = 0;
227           
228           for (j = QU_UNKNOWN; j < QU_LAST; j++)
229             {
230               if (qual_isExQual (j))
231                 {
232                   if (annots[i][j] > 0)
233                     {
234                       printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
235                               100.0 * (double)annots[i][j] / (double)decls[i]);
236                       tmptot += annots[i][j];
237                     }
238                 }
239             }
240           
241           printf ("   Definition:\n");
242           
243           for (j = QU_UNKNOWN; j < QU_LAST; j++)
244             {
245               if (qual_isAllocQual (j))
246                 {
247                   if (annots[i][j] > 0)
248                     {
249                       printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
250                               100.0 * (double)annots[i][j] / (double)decls[i]);
251                     }
252                 }
253             }
254           
255           printf ("   Null:\n");
256           
257           for (j = QU_UNKNOWN; j < QU_LAST; j++)
258             {
259               if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
260                 {
261                   if (annots[i][j] > 0)
262                     {
263                       printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
264                               100.0 * (double)annots[i][j] / (double)decls[i]);
265                     }
266                 }
267             }
268
269           printf ("\n");
270         }
271     }
272
273   for (j = QU_UNKNOWN; j < QU_LAST; j++)
274     {
275       bool hasone = FALSE;
276
277       for (i = AN_UNKNOWN; i < AN_LAST; i++)
278         {
279           if (annots[i][j] > 0)
280             {
281               hasone = TRUE;
282               break;
283             }
284         }
285
286       if (hasone)
287         {
288           printf ("Annotation: %s\n", qual_unparse (j));
289           
290           for (i = AN_UNKNOWN; i < AN_LAST; i++)
291             {
292               if (annots[i][j] > 0)
293                 {
294                   printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
295                 }
296             }
297           printf ("\n");
298         }
299     }
300
301   printf ("All Contexts\n");
302   
303   for (j = QU_UNKNOWN; j < QU_LAST; j++)
304     {
305       if (total[j] > 0)
306         {
307           printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
308                   100.0 * (double)total[j] / (double)(totdecls));
309         }
310     }
311   printf ("\n");
312
313   printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
314
315 extern void uentry_tallyAnnots (uentry u, ancontext kind)
316 {
317   alkind ak = sRef_getAliasKind (u->sref);
318   exkind ek = sRef_getExKind (u->sref);
319   nstate ns = sRef_getNullState (u->sref);
320   sstate ss = sRef_getDefState (u->sref);
321   bool recordUnknown = FALSE;
322   
323   if (kind == AN_UNKNOWN)
324     {
325       ekind e = u->ukind;
326
327       if (e == KENDITER)
328         {
329           return;
330         }
331       else if (e == KCONST || e == KENUMCONST)
332         {
333           kind = AN_CONST;
334         }
335       else if (e == KFCN || e == KITER)
336         {
337           uentryList params = uentry_getParams (u);
338           bool hasRet = FALSE;
339
340           uentryList_elements (params, current)
341             {
342               if (uentry_isReturned (current))
343                 {
344                   hasRet = TRUE;
345                 }
346               if (!uentry_isElipsisMarker (current))
347                 {
348                   uentry_tallyAnnots (current, AN_FCNPARAM);
349                 }
350             } end_uentryList_elements;
351           
352           kind = AN_FCNRETURN;
353           
354           if (ctype_isFunction (u->utype)
355               && !hasRet
356               && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
357             {
358               recordUnknown = TRUE;
359             }
360         }
361       else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
362         {
363           ctype t = ctype_realType (u->utype);
364
365           if (ctype_isSU (t))
366             {
367               uentryList fields = ctype_getFields (t);
368
369               uentryList_elements (fields, current)
370                 {
371                   uentry_tallyAnnots (current, AN_SUFIELD);
372                 }
373             } end_uentryList_elements;
374           
375           kind = AN_TDEFN;
376
377           if (ctype_isVisiblySharable (u->utype))
378             {
379               recordUnknown = TRUE;
380             }
381         }
382       else 
383         {
384           kind = AN_GSVAR;
385           
386           
387           if (ctype_isVisiblySharable (ctype_realType (u->utype)))
388             {
389               recordUnknown = TRUE;
390             }
391         }
392     }
393
394   decls[kind]++;
395
396   if (kind == AN_FCNRETURN)
397     {
398       if (recordUnknown) 
399         {
400           shdecls[kind]++;
401           idecls[kind]++;
402         }
403       else 
404         {
405           ;
406         }
407     }
408   else
409     {
410       if (ctype_isVisiblySharable (ctype_realType (u->utype)))
411         {
412           shdecls[kind]++;
413                 }
414       
415       if (ctype_isRealPointer (ctype_realType (u->utype)))
416         {
417           idecls[kind]++;
418         }
419     }
420   
421   switch (ss)
422     {
423     case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
424     case SS_PARTIAL:   tallyAnnot (kind, QU_PARTIAL); break;
425     case SS_RELDEF:    tallyAnnot (kind, QU_RELDEF); break;
426     case SS_SPECIAL:   tallyAnnot (kind, QU_SPECIAL); break;
427     default: break;
428     }
429
430   if (uentry_isReturned (u))
431     {
432       tallyAnnot (kind, QU_RETURNED); 
433     }
434
435   switch (ak)
436     {
437     case AK_UNKNOWN:    
438       if (ctype_isRefCounted (ctype_realType (u->utype))
439           || (ctype_isFunction (u->utype) &&
440               ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
441         {
442           ;
443         }
444       else
445         {
446           if (kind == AN_FCNPARAM) 
447             { 
448               tallyAnnot (kind, QU_TEMP); 
449             } 
450           else if (recordUnknown) 
451             { 
452               if (kind == AN_FCNRETURN)
453                 {
454                                 }
455               tallyAnnot (kind, QU_UNKNOWN); 
456             }
457         }
458       break;
459     case AK_ONLY:       tallyAnnot (kind, QU_ONLY); break;
460     case AK_IMPONLY:    tallyAnnot (kind, QU_ONLY); break;
461     case AK_KEEP:       tallyAnnot (kind, QU_KEEP); break;
462     case AK_KEPT:       tallyAnnot (kind, QU_KEPT); break;
463     case AK_IMPTEMP:
464     case AK_TEMP:       tallyAnnot (kind, QU_TEMP); break;
465     case AK_SHARED:     tallyAnnot (kind, QU_SHARED); break;
466     case AK_UNIQUE:     tallyAnnot (kind, QU_UNIQUE); break;
467     case AK_RETURNED:   tallyAnnot (kind, QU_RETURNED); break;
468     case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
469     case AK_REFS:       tallyAnnot (kind, QU_REFS); break;
470     case AK_KILLREF:    tallyAnnot (kind, QU_KILLREF); break;
471     case AK_NEWREF:     tallyAnnot (kind, QU_NEWREF); break;
472     case AK_OWNED:      tallyAnnot (kind, QU_OWNED); break;
473     case AK_IMPDEPENDENT:
474     case AK_DEPENDENT:  tallyAnnot (kind, QU_DEPENDENT); break;
475     case AK_ERROR:    
476     case AK_FRESH:
477     case AK_STACK:
478     case AK_LOCAL:
479       break;
480     }
481
482   switch (ek)
483     {
484     case XO_EXPOSED:    tallyAnnot (kind, QU_EXPOSED); break;
485     case XO_OBSERVER:   tallyAnnot (kind, QU_OBSERVER); break;
486     default:  break;
487     }
488
489   switch (ns)
490     {
491     case NS_ERROR:   break;
492     case NS_UNKNOWN:   break;
493     case NS_NOTNULL:   break;
494     case NS_MNOTNULL:  tallyAnnot (kind, QU_NOTNULL); break;
495     case NS_RELNULL:   tallyAnnot (kind, QU_RELNULL); break;
496     case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
497     case NS_POSNULL:   tallyAnnot (kind, QU_NULL); break;
498     case NS_DEFNULL: 
499     case NS_ABSNULL:   break;   
500     }
501 }
502
503 # endif
504
505 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
506 {
507   switch (s)
508     {
509     case SPC_NONE: return cstring_makeLiteralTemp ("normal");
510     case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
511     case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
512     case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
513     case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
514     }
515
516   BADEXIT;
517 }
518
519 static specCode specCode_fromInt (int i)
520 {
521   /*@+enumint@*/
522   llassert (i >= SPC_NONE && i < SPC_LAST);
523
524   return ((specCode) i);
525   /*@=enumint@*/
526 }
527
528 /*@observer@*/ cstring uentry_specOrDefName (uentry u) 
529 {
530   if (uentry_isDeclared (u))
531     {
532       return cstring_makeLiteralTemp ("previously declared");
533     }
534   else
535     {
536       return cstring_makeLiteralTemp ("specified");
537     }
538 }
539
540 /*@observer@*/ cstring uentry_specDeclName (uentry u) 
541 {
542   if (uentry_isDeclared (u))
543     {
544       return cstring_makeLiteralTemp ("previous declaration");
545     }
546   else
547     {
548       return cstring_makeLiteralTemp ("specification");
549     }
550 }
551
552 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew)  /*@*/ 
553 {
554   if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
555     {
556       return cstring_makeLiteralTemp ("redefined");
557     }
558   else if (uentry_isCodeDefined (unew))
559     {
560       return cstring_makeLiteralTemp ("defined");
561     }
562   else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
563     {
564       return cstring_makeLiteralTemp ("redeclared");
565     }
566   else
567     {
568       return cstring_makeLiteralTemp ("declared");
569     }
570 }
571
572 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
573 {
574   if (uentry_isValid (ue))
575     {
576       functionConstraint constraint;
577
578       DPRINTF((message ("called uentry_getFcnPostconditions on  %s",
579                          uentry_unparse (ue) ) ) );
580       
581       if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
582         {
583           DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
584                              uentry_unparse (ue) ) ) );
585           if (!uentry_isFunction (ue) )
586             {
587               DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
588                                 uentry_unparse (ue) ) ));
589               return constraintList_undefined;
590             }
591           
592           
593           return constraintList_undefined;
594         }
595       
596       if (!uentry_isFunction(ue))
597         {
598           
599           DPRINTF((message ("called uentry_getFunctionConditions on non function  %s",
600                              uentry_unparse (ue) ) ) );
601           return constraintList_undefined;
602           
603         }
604
605       llassert (uentry_isFunction (ue));
606
607       if (isPost)
608         {
609           constraint = ue->info->fcn->postconditions;
610         }
611       else
612         {
613           constraint = ue->info->fcn->preconditions;
614         }
615
616       return functionConstraint_getBufferConstraints (constraint);
617     }
618   
619   return constraintList_undefined;
620   
621 }
622
623 /*drl7x*/
624 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
625 {
626   return uentry_getFunctionConditions (ue, FALSE);
627 }
628
629 /*drl
630   12/28/2000
631 */
632
633 constraintList uentry_getFcnPostconditions (uentry ue)
634 {
635   return uentry_getFunctionConditions (ue, TRUE);
636 }
637
638 static /*@only@*/ fileloc setLocation (void)
639 {
640   fileloc fl = context_getSaveLocation ();
641
642   if (fileloc_isDefined (fl)) 
643     {
644       return fl;
645     }
646   else
647     {
648       return fileloc_copy (g_currentloc);
649     }
650 }
651
652 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
653 {
654   llassert (uentry_isEitherConstant (ue));
655   sRef_setValue (ue->sref, val);
656 }
657
658 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
659 {
660   fileloc loc = setLocation ();
661   uentry ue = uentry_makeConstant (n, t, loc);
662
663   ue->ukind = KENUMCONST;
664   uentry_setDefined (ue, loc);
665   return ue;
666 }
667
668 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
669 {
670   fileloc loc = setLocation ();
671   uentry ue = uentry_makeConstant (n, t, loc);
672   ctype etype = exprNode_getType (expr);
673
674   if (!ctype_isRealInt (etype)) {
675     voptgenerror 
676       (FLG_ENUMMEMBERS,
677        message
678        ("Value of enum member is not an integeral type (type %s): %s",
679         ctype_unparse (etype), exprNode_unparse (expr)),
680        exprNode_loc (expr));
681   }
682   
683   ue->ukind = KENUMCONST;
684   uentry_setDefined (ue, loc);
685   return ue;
686 }
687
688 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
689 {
690   uentry ue = uentry_makeConstant (n, t, loc);
691
692   ue->ukind = KENUMCONST;
693   return ue;
694 }
695
696 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
697 {
698   return uentry_makeVariable (n, t, setLocation (), FALSE);
699 }
700
701 bool uentry_isUnnamedVariable (uentry ue)
702 {
703   return uentry_isVariable (ue) && cstring_isUndefined (ue->uname);
704 }
705
706 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
707 {
708   return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
709 }
710
711 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
712 {
713   ctype ct = idDecl_getCtype (id);
714   uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct, 
715                                    MAYBE, MAYBE, setLocation ());
716
717   uentry_reflectQualifiers (ue, idDecl_getQuals (id));
718   
719   if (!ynm_isOn (ue->info->datatype->abs))
720     {
721       if (ctype_isUnknown (ct))
722         {
723           ue->info->datatype->mut = MAYBE;
724         }
725       else
726         {
727           ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
728         }
729     }
730   
731   return ue;
732 }
733
734 void uentry_checkParams (uentry ue)
735 {
736   if (uentry_isValid (ue))
737     {
738       bool isExt = uentry_isExtern (ue);
739
740       if (uentry_isRealFunction (ue))
741         {
742           uentryList params = uentry_getParams (ue);
743           int paramno = 0;
744
745           uentryList_elements (params, current)
746             {
747               paramno++;
748
749               if (uentry_isValid (current))
750                 {
751                   ctype ct = current->utype;                  
752                   
753                   if (ctype_isFixedArray (ct))
754                     {
755                       if (ctype_isArray (ctype_baseArrayPtr (ct))
756                           && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
757                         {
758                           ;
759                         }
760                       else
761                         {
762                           if (uentry_hasName (current))
763                             {
764                               voptgenerror 
765                                 (FLG_FIXEDFORMALARRAY,
766                                  message ("Function parameter %q declared as "
767                                           "manifest array (size constant is meaningless)",
768                                           uentry_getName (current)),
769                                  uentry_whereDeclared (current));
770                             }
771                           else
772                             {
773                               voptgenerror 
774                                 (FLG_FIXEDFORMALARRAY,
775                                  message ("Unnamed function parameter %d declared as "
776                                           "manifest array (size constant is meaningless)",
777                                           paramno),
778                                  uentry_whereDeclared (current));
779                             }
780                         }
781                     }
782                   else 
783                     {
784                       if (ctype_isArray (ct))
785                         {
786                           if (uentry_hasName (current))
787                             {
788                               voptgenerror 
789                                 (FLG_FORMALARRAY,
790                                  message ("Function parameter %q declared as "
791                                           "array (treated as pointer)", 
792                                           uentry_getName (current)),
793                                  uentry_whereDeclared (current));
794                             }
795                           else
796                             {
797                               voptgenerror 
798                                 (FLG_FORMALARRAY,
799                                  message ("Unnamed function parameter %d declared as "
800                                           "array (treated as pointer)", 
801                                           paramno),
802                                  uentry_whereDeclared (current));
803                             }
804                         }
805                     }
806
807                   if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
808                     {
809                       if (ctype_isAbstract (ct) && 
810                           (isExt || (ctype_isAbstract (ctype_realType (ct))
811                                      && !context_hasFileAccess (ctype_typeId (ct)))))
812                         {
813                           vgenhinterror 
814                             (FLG_INCONDEFS,
815                              message 
816                              ("Function %q declared with notnull parameter %q of abstract "
817                               "type %s",
818                               uentry_getName (ue),
819                               uentry_getName (current),
820                               ctype_unparse (ct)),
821                              message 
822                              ("Since %s is an abstract type, notnull can only be "
823                               "used for parameters if the function is static to a "
824                               "module where %s is accessible.",
825                               ctype_unparse (ct),
826                               ctype_unparse (ct)),
827                              uentry_whereDeclared (current));
828                         }
829                     }
830                 }
831             } end_uentryList_elements;
832           
833           if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
834             {
835               ctype ct = ue->utype;
836                   
837               if (ctype_isAbstract (ct) 
838                   && (isExt || (ctype_isAbstract (ctype_realType (ct))
839                                 && !context_hasFileAccess (ctype_typeId (ct)))))
840                 {
841                   vgenhinterror 
842                     (FLG_INCONDEFS,
843                      message 
844                      ("%s %q declared %s notnull storage of abstract type %s",
845                       ekind_capName (uentry_getKind (ue)),
846                       uentry_getName (ue),
847                       fcnErrName (ue),
848                       ctype_unparse (ct)),
849                      message 
850                      ("Since %s is an abstract type, notnull can only be used "
851                       "if it is static to a module where %s is accessible.",
852                       ctype_unparse (ct),
853                       ctype_unparse (ct)),
854                      uentry_whereDeclared (ue));
855                 }
856             }
857         }
858     }
859 }
860
861 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
862 {
863   alkind ak = sRef_getAliasKind (ue->sref);
864
865   if (alkind_isRefCounted (ak))
866     {
867       sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
868     }
869   else 
870     {
871       if (alkind_isUnknown (ak))
872         {
873           exkind ek = sRef_getExKind (ue->sref);
874           
875           if (exkind_isKnown (ek))
876             {
877               DPRINTF (("Setting imp dependent: %s",
878                         uentry_unparseFull (ue)));
879               sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
880             }
881           else 
882             {
883               if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
884                 {
885                   /* evans 2000-12-22 removed ctype_realType so it will
886                      not apply to immutable abstract types. */
887
888                   if (ctype_isVisiblySharable 
889                       (ctype_realType (ctype_getReturnType (ue->utype))))
890                     {
891                       if (uentryList_hasReturned (uentry_getParams (ue)))
892                         {
893                           ;
894                         }
895                       else 
896                         {
897                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
898                             {
899                               ; /* Immutable objects are not shared. */
900                             }
901                           else
902                             {
903                               sRef_setAliasKind (ue->sref, AK_IMPONLY, 
904                                                  fileloc_undefined);
905                               DPRINTF (("Ret imp only: %s",
906                                         ctype_unparse (ctype_getReturnType (ue->utype))));
907                             }
908                         }
909                     }
910                 }
911             }
912         }
913     }
914 }
915
916 static /*@notnull@*/ uentry 
917 uentry_makeFunctionAux (cstring n, ctype t, 
918                         typeIdSet access,
919                         /*@only@*/ globSet globs, 
920                         /*@only@*/ sRefSet mods,
921                         /*@only@*/ warnClause warn,
922                         /*@keep@*/ fileloc f, bool priv,
923                         /*@unused@*/ bool isForward)
924 {
925   uentry e = uentry_alloc ();
926   ctype ret;
927
928   llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
929
930   DPRINTF (("Make function: %s", n));
931
932   if (ctype_isFunction (t))
933     {
934       ret = ctype_getReturnType (t);
935     }
936   else
937     {
938       if (ctype_isKnown (t))
939         {
940           llbug (message ("not function: %s", ctype_unparse (t)));
941         }
942       ret = ctype_unknown;
943     }
944
945   e->ukind = KFCN;
946
947   if (fileloc_isSpec (f) || fileloc_isImport (f))
948     {
949       e->whereSpecified = f;
950       e->whereDeclared = fileloc_undefined;
951     }
952   else
953     {
954       e->whereSpecified = fileloc_undefined;
955       e->whereDeclared = f;
956     }
957
958   /* e->shallowCopy = FALSE; */
959   e->uname = cstring_copy (n);
960   e->utype = t;
961   e->storageclass = SCNONE;
962
963   e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
964
965   DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
966
967   if (ctype_isUA (ret))
968     {
969       sRef_setStateFromType (e->sref, ret);
970     }
971   
972   e->used = FALSE;
973   e->lset = FALSE;
974   e->uses = filelocList_new ();
975   e->isPrivate = priv;
976   e->hasNameError = FALSE;
977
978   e->warn = warn;
979
980   e->info = (uinfo) dmalloc (sizeof (*e->info));
981   e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
982
983   e->info->fcn->hasMods = sRefSet_isDefined (mods);
984   e->info->fcn->hasGlobs = globSet_isDefined (globs);
985
986   e->info->fcn->exitCode = XK_UNKNOWN;
987   e->info->fcn->nullPred = qual_createUnknown ();
988   e->info->fcn->specialCode = SPC_NONE;
989
990   e->info->fcn->access = access;
991   e->info->fcn->globs = globs;
992   e->info->fcn->defparams = uentryList_undefined;
993
994   sRef_setDefined (e->sref, f);
995   e->whereDefined = fileloc_undefined;
996   
997   e->info->fcn->mods = sRefSet_undefined;
998   e->info->fcn->specclauses = NULL;
999
1000   /*drl 11 29 2000*/
1001   e->info->fcn->preconditions = NULL;
1002   /*end drl*/
1003   
1004   /*drl 12 28 2000*/
1005   e->info->fcn->postconditions = NULL;
1006   /*end drl*/
1007   
1008   checkGlobalsModifies (e, mods);
1009   e->info->fcn->mods = mods;
1010
1011   return (e);
1012 }
1013
1014 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
1015 {
1016   functionClauseList_elements (clauses, el)
1017     {
1018       DPRINTF (("Reflect clause: %s on %s",
1019                 functionClause_unparse (el), uentry_getName (ue)));
1020       
1021       if (functionClause_isNoMods (el))
1022         {
1023           modifiesClause mel = functionClause_getModifies (el);
1024           
1025           if (uentry_hasGlobs (ue))
1026             {
1027               voptgenerror 
1028                 (FLG_SYNTAX,
1029                  message
1030                  ("No globals and modifies inconsistent to globals clause for %q: %q",
1031                   uentry_getName (ue),
1032                   globSet_unparse (uentry_getGlobs (ue))),
1033                  modifiesClause_getLoc (mel));
1034               
1035             }
1036
1037           if (uentry_hasMods (ue))
1038             {
1039               voptgenerror 
1040                 (FLG_SYNTAX,
1041                  message
1042                  ("No globals and modifies inconsistent to modifies clause for %q: %q",
1043                   uentry_getName (ue),
1044                   sRefSet_unparse (uentry_getMods (ue))),
1045                  modifiesClause_getLoc (mel));
1046             }
1047
1048           uentry_setGlobals (ue, globSet_undefined);
1049           uentry_setModifies (ue, sRefSet_undefined);
1050         }
1051       else if (functionClause_isGlobals (el))
1052         {
1053           globalsClause glc = functionClause_getGlobals (el);
1054           
1055           DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1056                     globalsClause_unparse (glc)));
1057
1058           if (uentry_hasGlobs (ue))
1059             {
1060               voptgenerror 
1061                 (FLG_SYNTAX,
1062                  message
1063                  ("Multiple globals clauses for %q: %q",
1064                   uentry_getName (ue),
1065                   globalsClause_unparse (glc)),
1066                  globalsClause_getLoc (glc));
1067               uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1068             }
1069           else
1070             {
1071               DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1072               uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1073               DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1074             }
1075         }
1076       else if (functionClause_isModifies (el))
1077         {
1078           modifiesClause mlc = functionClause_getModifies (el);
1079
1080           DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1081
1082           if (uentry_hasMods (ue))
1083             {
1084               /* 
1085               ** Not an error:
1086
1087               if (optgenerror 
1088                   (FLG_SYNTAX,
1089                    message
1090                    ("Multiple modifies clauses for %s: %s",
1091                     uentry_getName (ue),
1092                     modifiesClause_unparse (mlc)),
1093                    modifiesClause_getLoc (mlc)))
1094                 {
1095                   llhint (message ("Previous modifies clause: ", 
1096                                    sRefSet_unparse (uentry_getMods (ue))));
1097                 }
1098
1099               **
1100               */
1101
1102               uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1103             }
1104           else
1105             {
1106               uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1107             }
1108         }
1109       else if (functionClause_isEnsures (el))
1110         {
1111           functionConstraint cl = functionClause_takeEnsures (el);
1112           DPRINTF (("Setting post: %s / %s",
1113                     uentry_unparse (ue), functionConstraint_unparse (cl)));
1114           uentry_setPostconditions (ue, cl);
1115         }
1116       else if (functionClause_isRequires (el))
1117         {
1118           functionConstraint cl = functionClause_takeRequires (el);
1119           uentry_setPreconditions (ue, cl);
1120         }
1121       else if (functionClause_isState (el))
1122         {
1123           stateClause sc = functionClause_takeState (el);
1124
1125           if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1126             {
1127               sRefSet rfs = stateClause_getRefs (sc);
1128
1129               sRefSet_elements (rfs, s)
1130                 {
1131                   if (sRef_isParam (s))
1132                     {
1133                       /* 
1134                       ** Can't use requires on parameters
1135                       */
1136                       
1137                       voptgenerror
1138                         (FLG_ANNOTATIONERROR,
1139                          message ("Requires clauses for %q concerns parameters %q should be "
1140                                   "a parameter annotation instead: %q",
1141                                   uentry_unparse (ue),
1142                                   sRef_unparse (s),
1143                                   stateClause_unparse (sc)),
1144                          stateClause_loc (sc));
1145                     }
1146                 } end_sRefSet_elements ;
1147             }
1148
1149           DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1150           uentry_addStateClause (ue, sc);
1151         }
1152       else if (functionClause_isWarn (el))
1153         {
1154           warnClause wc = functionClause_takeWarn (el);
1155           uentry_addWarning (ue, wc);
1156         }
1157       else 
1158         {
1159           DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1160         }
1161     } end_functionClauseList_elements ;
1162
1163   DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1164   stateClauseList_checkAll (ue);
1165 }
1166
1167 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1168 {
1169   bool leaveFunc = FALSE;
1170   uentry ue = 
1171     uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id), 
1172                          typeId_invalid, globSet_undefined, 
1173                          sRefSet_undefined, warnClause_undefined,
1174                          setLocation ());
1175
1176   DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1177
1178   /*
1179   ** This makes parameters names print out correctly.
1180   ** (But we might be a local variable declaration for a function type...)
1181   */
1182
1183   if (context_inFunctionLike ())
1184     {
1185       DPRINTF (("Header: %s / %s",
1186                 uentry_unparse (context_getHeader ()),
1187                 idDecl_unparse (id)));
1188     }
1189   else
1190     {
1191       context_enterFunctionDeclaration (ue);
1192       leaveFunc = TRUE;
1193     }
1194
1195   DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1196   uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1197   DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1198   reflectImplicitFunctionQualifiers (ue, FALSE);
1199   DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1200   uentry_reflectClauses (ue, idDecl_getClauses (id));
1201   DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1202
1203   if (!uentry_isStatic (ue)
1204       && cstring_equalLit (ue->uname, "main"))
1205     {
1206       ctype typ = ue->utype;
1207       ctype retval;
1208       uentryList args;
1209
1210       llassert (ctype_isFunction (typ));
1211
1212       retval = ctype_getReturnType (typ);
1213
1214       if (!ctype_isInt (retval))
1215         {
1216           voptgenerror 
1217             (FLG_MAINTYPE,
1218              message ("Function main declared to return %s, should return int",
1219                       ctype_unparse (retval)),
1220              uentry_whereDeclared (ue));
1221         }
1222
1223       args = ctype_argsFunction (typ);
1224
1225       if (uentryList_isMissingParams (args) 
1226           || uentryList_size (args) == 0)
1227         {
1228           ;
1229         }
1230       else
1231         {
1232           if (uentryList_size (args) != 2)
1233             {
1234               voptgenerror 
1235                 (FLG_MAINTYPE,
1236                  message ("Function main declared with %d arg%&, "
1237                           "should have 2 (int argc, char *argv[])",
1238                           uentryList_size (args)),
1239                  uentry_whereLast (ue));
1240             }
1241           else
1242             {
1243               uentry arg = uentryList_getN (args, 0);
1244               ctype ct = uentry_getType (arg);
1245
1246               if (!ctype_isInt (ct))
1247                 {
1248                   voptgenerror 
1249                     (FLG_MAINTYPE,
1250                      message ("Parameter 1, %q, of function main declared "
1251                               "with type %t, should have type int",
1252                               uentry_getName (arg), ct),
1253                      uentry_whereDeclared (arg));
1254                 }
1255
1256               arg = uentryList_getN (args, 1);
1257               ct = uentry_getType (arg);
1258
1259               if (ctype_isArrayPtr (ct)
1260                   && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1261                   && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1262                 {
1263                   ;
1264                 }
1265               else
1266                 {
1267                   voptgenerror 
1268                     (FLG_MAINTYPE,
1269                      message ("Parameter 2, %q, of function main declared "
1270                               "with type %t, should have type char **",
1271                               uentry_getName (arg), ct),
1272                      uentry_whereDeclared (arg));
1273                 }
1274             }
1275         }
1276     }
1277
1278   if (leaveFunc)
1279     {
1280       context_exitFunctionDeclaration ();
1281     }
1282
1283   return ue;
1284 }
1285
1286 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1287 {
1288   alkind ak = sRef_getAliasKind (e->sref);
1289
1290   if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1291       && context_getFlag (FLG_PARAMIMPTEMP))
1292     {
1293       exkind ek = sRef_getExKind (e->sref);
1294       
1295       if (exkind_isKnown (ek))
1296         {
1297           DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1298           sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1299           sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1300         }
1301       else
1302         {
1303           sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1304           sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1305         }
1306     }
1307 }
1308
1309 static /*@only@*/ /*@notnull@*/ uentry 
1310 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s, 
1311                              /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1312 {
1313   cstring pname = makeParam (n);
1314   uentry e;
1315
1316   DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1317   e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1318
1319   cstring_free (pname);
1320   DPRINTF (("Param: %s", uentry_unparseFull (e)));
1321   uentry_implicitParamAnnots (e);
1322   DPRINTF (("Param: %s", uentry_unparseFull (e)));
1323
1324   if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1325     {
1326       DPRINTF (("Param: %s", uentry_unparseFull (e)));
1327       sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1328       e->info->var->defstate = defstate;
1329     }
1330
1331   DPRINTF (("Param: %s", uentry_unparseFull (e)));
1332   return (e);
1333 }
1334
1335 void
1336 uentry_setRefCounted (uentry e)
1337 {
1338   if (uentry_isValid (e))
1339     {
1340       uentry_setAliasKind (e, AK_REFCOUNTED);
1341       sRef_storeState (e->sref);
1342     }
1343 }
1344
1345 void
1346 uentry_setStatic (uentry c)
1347 {
1348   if (uentry_isValid (c)) 
1349     {
1350       alkind ak = sRef_getAliasKind (c->sref);
1351       c->storageclass = SCSTATIC;
1352
1353       if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1354         {
1355           if (!alkind_isUnknown (ak)
1356               && !alkind_isStatic (ak))
1357             {
1358               if  (!(ctype_isRealPointer (uentry_getType (c)))
1359                    && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1360                    && !alkind_isRefCounted (ak))
1361                 {
1362                   if (alkind_isImplicit (ak)
1363                       && alkind_isDependent (ak)
1364                       && ctype_isArray (uentry_getType (c)))
1365                     {
1366                       ; /* no error for observer arrays */
1367                     }
1368                   else
1369                     {
1370                       voptgenerror 
1371                         (FLG_INCONDEFS,
1372                          message ("Static storage %q declared as %s",
1373                                   uentry_getName (c),
1374                                   alkind_unparse (ak)),
1375                          uentry_whereDeclared (c));
1376                     }
1377                 }
1378             }
1379           else
1380             {
1381               if (alkind_isUnknown (ak)
1382                   || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1383                       && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1384                 {
1385                   sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1386                   sRef_setOrigAliasKind (c->sref, AK_STATIC);
1387                 }
1388             }
1389         }
1390     }
1391 }
1392
1393 void
1394 uentry_setExtern (uentry c)
1395 {
1396   if (uentry_isValid (c)) 
1397     c->storageclass = SCEXTERN;
1398 }
1399
1400 void
1401 uentry_setParamNo (uentry ue, int pno)
1402 {
1403   llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1404   sRef_setParamNo (ue->sref, pno);
1405 }
1406
1407 static
1408 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1409 {
1410   sRefSet_allElements (sr, el)
1411     {
1412       sRef base = sRef_getRootBase (el);
1413       
1414       if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1415           || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1416         {
1417           if (!globSet_member (ue->info->fcn->globs, base))
1418             {
1419               if (uentry_hasGlobs (ue)
1420                   || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1421                 {
1422                   if (optgenerror 
1423                       (FLG_WARNMISSINGGLOBALS,
1424                        message
1425                        ("Modifies list for %q uses global %q, "
1426                         "not included in globals list.",
1427                         uentry_getName (ue),
1428                         sRef_unparse (base)),
1429                        uentry_whereLast (ue)))
1430                     {
1431                       uentry_showWhereSpecified (ue);
1432                     } 
1433                 }
1434               
1435               ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs, 
1436                                                      base);
1437               if (sRef_isFileStatic (base))
1438                 {
1439                   context_recordFileGlobals (ue->info->fcn->globs);
1440                 }
1441             }
1442         }
1443     } end_sRefSet_allElements;
1444 }
1445
1446 uentry
1447 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1448 {
1449   return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1450 }
1451
1452 void
1453 uentry_fixupSref (uentry ue)
1454 {
1455   sRef sr;
1456   
1457   if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue)) 
1458     {
1459       return;
1460     }
1461   
1462   sr = uentry_getSref (ue);
1463
1464   sRef_resetState (sr);
1465   sRef_clearDerived (sr);
1466   
1467   llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1468   llassert (sRef_isValid (sr)); 
1469   
1470   if (uentry_isVariable (ue))
1471     {
1472       
1473            /*@i634        ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1474       sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1475       sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1476     }
1477 }
1478
1479 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1480 {
1481   /*
1482   ** Okay to allow multiple clauses of the same kind.
1483   */ /*@i834 is this true?@*/
1484
1485   ue->info->fcn->specclauses = 
1486     stateClauseList_add (ue->info->fcn->specclauses, sc);
1487
1488   /* Will call checkAll to check later... */
1489 }
1490
1491 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1492 {
1493   llassert (uentry_isFunction (ue));
1494   llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1495
1496   DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1497   ue->info->fcn->specclauses = clauses;
1498   stateClauseList_checkAll (ue);
1499   DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1500 }
1501
1502 /*
1503 ** Used for @modifies@ @endmodifies@ syntax.
1504 **
1505 ** If ue is specified, sr must contain *only*:
1506 **
1507 **      o file static globals
1508 **      o sRef's derived from modifies spec (i.e., more specific than
1509 **        what was specified)
1510 **
1511 ** Otherwise, if sr has modifies it must match sr.
1512 **
1513 ** If it doesn't have modifies, set them to sr.
1514 */
1515
1516 static bool
1517 uentry_checkModifiesContext (void) 
1518 {
1519   if (sRef_modInFunction ())
1520     {
1521       llparseerror
1522         (message
1523          ("Modifies list not in function context.  "
1524           "A modifies list can only appear following the parameter list "
1525           "in a function declaration or header."));
1526       
1527       return FALSE;
1528     }
1529   
1530   return TRUE;
1531 }
1532
1533 void
1534 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1535 {
1536   if (!uentry_checkModifiesContext ())
1537     {
1538       sRefSet_free (sr);
1539       return;
1540     }
1541
1542   if (uentry_isValid (ue))
1543     {
1544       if (uentry_isIter (ue))
1545         {
1546           llassert (sRefSet_isUndefined (ue->info->iter->mods));
1547           ue->info->iter->mods = sr;
1548         }
1549       else
1550         {
1551           uentry_convertVarFunction (ue);
1552           llassertfatal (uentry_isFunction (ue));
1553           llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1554           
1555           ue->info->fcn->mods = sr;
1556           ue->info->fcn->hasMods = TRUE;
1557           
1558           checkGlobalsModifies (ue, sr);
1559         }
1560       
1561       if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1562         {
1563           ue->info->fcn->hasGlobs = TRUE;
1564         }
1565
1566       if (sRefSet_hasStatic (ue->info->fcn->mods))
1567         {
1568           context_recordFileModifies (ue->info->fcn->mods);
1569         }
1570     }
1571   else
1572     {
1573       sRefSet_free (sr);
1574     }
1575 }
1576
1577 static void
1578 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1579 {
1580   /* 
1581   ** Function already has one modifies clause (possibly from
1582   ** a specification).
1583   */
1584
1585   if (!uentry_checkModifiesContext ())
1586     {
1587       BADBRANCH;
1588     }
1589   
1590   llassert (uentry_isValid (ue));
1591
1592   if (uentry_isIter (ue))
1593     {
1594       ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1595     }
1596   else
1597     {
1598       llassertfatal (uentry_isFunction (ue));
1599       llassert (ue->info->fcn->hasMods);
1600       
1601       checkGlobalsModifies (ue, sr);
1602       ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1603       
1604       if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1605         {
1606           ue->info->fcn->hasGlobs = TRUE;
1607         }
1608     }
1609
1610   if (sRefSet_hasStatic (ue->info->fcn->mods))
1611     {
1612       context_recordFileModifies (ue->info->fcn->mods);
1613     }
1614 }
1615
1616 bool uentry_hasWarning (uentry ue)
1617 {
1618   return (uentry_isValid (ue)
1619           && warnClause_isDefined (ue->warn));
1620 }
1621
1622 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1623 {
1624   llassert (uentry_isValid (ue));
1625   llassert (warnClause_isUndefined (ue->warn));
1626   ue->warn = warn;
1627 }
1628
1629 void
1630 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1631 {
1632   if (sRef_modInFunction ())
1633     {
1634       llparseerror
1635         (message ("Precondition list not in function context.  "
1636                   "A precondition list can only appear following the parameter list "
1637                   "in a function declaration or header."));
1638
1639       /*@-mustfree@*/ return; /*@=mustfree@*/ 
1640     }
1641
1642   if (uentry_isValid (ue))
1643     {
1644       uentry_convertVarFunction (ue);
1645       llassertfatal (uentry_isFunction (ue));
1646       
1647       if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1648         {
1649           /*drl oops this date is wronge...*/
1650           /* drl 11-29-2002
1651              I changed this so it didn't appear as a Splint bug
1652              among other things this gets triggered when there is
1653              a function with two requires clauses.  Now Splint
1654              prints an error and tries to conjoin the lists.
1655           */
1656       llparseerror
1657         (message ("Duplicate precondition list"
1658                   "Attemping the conjoin the requires clauses"
1659                   ));
1660
1661
1662           /* should conjoin constraints? */
1663           /*@notreached@*/ 
1664           ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1665         }
1666       else
1667         {
1668           ue->info->fcn->preconditions = preconditions;
1669         }
1670     }
1671   else
1672     {
1673       llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1674     }
1675 }
1676
1677 /*
1678   drl
1679   added 12/28/2000
1680 */
1681 void
1682 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1683 {
1684   if (sRef_modInFunction ())
1685     {
1686       llparseerror
1687         (message ("Postcondition list not in function context.  "
1688                   "A postcondition list can only appear following the parameter list "
1689                   "in a function declaration or header."));
1690       
1691       /*@-mustfree@*/ return; /*@=mustfree@*/ 
1692     }
1693
1694   if (uentry_isValid (ue))
1695     {
1696       uentry_convertVarFunction (ue);
1697       llassertfatal (uentry_isFunction (ue));
1698       
1699       if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1700         {
1701           ue->info->fcn->postconditions = postconditions;
1702         }
1703       else
1704         {
1705           ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1706         }           
1707     }
1708   else
1709     {
1710       llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1711     }
1712 }
1713
1714 /*
1715 ** requires: new and old are functions
1716 */
1717  
1718 static void
1719 checkGlobalsConformance (/*@notnull@*/ uentry old, 
1720                          /*@notnull@*/ uentry unew, 
1721                          bool mustConform, bool completeConform)
1722 {
1723   bool hasInternalState = FALSE;
1724
1725   old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1726
1727   if (globSet_isDefined (unew->info->fcn->globs))
1728     {
1729       globSet_allElements (unew->info->fcn->globs, el)
1730         {
1731           if (sRef_isFileStatic (el))
1732             {
1733               sRef sr = globSet_lookup (old->info->fcn->globs, el);
1734
1735               if (sRef_isInvalid (sr))
1736                 {
1737                   bool hasError = FALSE;
1738
1739                   if (!hasInternalState 
1740                       && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1741                                                          sRef_makeInternalState ()))
1742                       && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1743                                                          sRef_makeSpecState ())))
1744                     {
1745                       if (mustConform 
1746                           && !uentry_isStatic (old)
1747                           && optgenerror 
1748                           (FLG_INCONDEFS,
1749                            message ("Globals list for %q includes internal state, %q, "
1750                                     "but %s without globals internalState.",
1751                                     uentry_getName (old),
1752                                     sRef_unparse (el),
1753                                     uentry_specOrDefName (old)),
1754                            uentry_whereLast (unew)))
1755                         {
1756                           uentry_showWhereSpecified (old);
1757                           hasError = TRUE;
1758                         }
1759                       
1760                       old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1761                                                               sRef_makeInternalState ());
1762                       hasInternalState = TRUE;
1763                     }
1764
1765                   if (!hasError
1766                       && fileloc_sameFile (uentry_whereDeclared (unew),
1767                                            uentry_whereDeclared (old)))
1768                     {
1769                       if (mustConform
1770                           && optgenerror 
1771                           (FLG_INCONDEFS,
1772                            message ("Function %q inconsistently %rdeclared (in "
1773                                     "same file) with file static global %q in "
1774                                     "globals list",
1775                                     uentry_getName (unew),
1776                                     uentry_isDeclared (old),
1777                                     sRef_unparse (el)),
1778                            uentry_whereDeclared (unew)))
1779                         {
1780                           uentry_showWhereSpecified (old);
1781                         }
1782                     }
1783                 }
1784
1785               old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1786               context_recordFileGlobals (old->info->fcn->globs);
1787             }
1788           else
1789             {
1790               sRef sr = globSet_lookup (old->info->fcn->globs, el);
1791               
1792               if (sRef_isInvalid (sr))
1793                 {
1794                   if (mustConform
1795                       && optgenerror 
1796                       (FLG_INCONDEFS,
1797                        message ("Function %q inconsistently %rdeclared with "
1798                                 "%q in globals list",
1799                                 uentry_getName (unew),
1800                                 uentry_isDeclared (old),
1801                                 sRef_unparse (el)),
1802                        uentry_whereDeclared (unew)))
1803                     {
1804                       old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1805                       uentry_showWhereSpecified (old);
1806                     }
1807                 }
1808               else
1809                 {
1810                   if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1811                     {
1812                       if (mustConform
1813                           && optgenerror 
1814                           (FLG_INCONDEFS,
1815                            message 
1816                            ("Function %q global %q inconsistently "
1817                             "%rdeclared as %qout global",
1818                             uentry_getName (unew),
1819                             sRef_unparse (el),
1820                             uentry_isDeclared (old),
1821                             cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1822                            uentry_whereDeclared (unew)))
1823                         {
1824                           uentry_showWhereSpecified (old);
1825                         }
1826                     }
1827                 }
1828             }
1829         } end_globSet_allElements ;
1830
1831       if (completeConform)
1832         {
1833           globSet_allElements (old->info->fcn->globs, el)
1834             {
1835               sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1836               
1837               if (sRef_isInvalid (sr))
1838                 {
1839                   if (mustConform
1840                       && uentry_isReallySpecified (old)
1841                       && optgenerror 
1842                       (FLG_NEEDSPEC,
1843                        message ("Function %q specified with %q in globals list, "
1844                                 "but declared without %q",
1845                                 uentry_getName (unew),
1846                                 sRef_unparse (el),
1847                                 sRef_unparse (el)),
1848                        uentry_whereDeclared (unew)))
1849                     {
1850                       uentry_showWhereSpecified (old);
1851                     }
1852                 }
1853             } end_globSet_allElements;
1854         }
1855     }
1856   else
1857     {
1858       if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1859         {
1860           if (uentry_isReallySpecified (old)
1861               && optgenerror 
1862               (FLG_NEEDSPEC,
1863                message ("%s %q specified with globals list, but "
1864                         "declared with no globals",
1865                         ekind_capName (unew->ukind),
1866                         uentry_getName (unew)),
1867                uentry_whereDeclared (unew)))
1868             {
1869               llgenindentmsg 
1870                 (message ("Specification globals: %q", 
1871                           globSet_unparse (old->info->fcn->globs)),
1872                  uentry_whereSpecified (old));
1873             }
1874         }
1875       
1876       unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs, 
1877                                                  old->info->fcn->globs);
1878     }
1879 }
1880
1881 /*
1882 ** new modifies list must be included by old modifies list.
1883 **
1884 ** file static state may be added to new, if old has internal.
1885 */
1886
1887 static void
1888 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
1889                           bool mustConform, bool completeConform)
1890 {
1891   sRefSet newMods;
1892   bool changedMods = FALSE;
1893   bool modInternal = FALSE;
1894
1895   llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1896
1897   old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1898   newMods = unew->info->fcn->mods;
1899             
1900   if (sRefSet_isEmpty (newMods))
1901     {
1902       if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1903           && uentry_isReallySpecified (old))
1904         {
1905           if (optgenerror 
1906               (FLG_NEEDSPEC,
1907                message ("%s %q specified with modifies clause, "
1908                         "but declared with no modifies clause",
1909                         ekind_capName (unew->ukind),
1910                         uentry_getName (unew)),
1911                uentry_whereDeclared (unew)))
1912             {
1913               llgenindentmsg (message ("Specification has modifies %q", 
1914                                        sRefSet_unparse (old->info->fcn->mods)),
1915                               uentry_whereSpecified (old));
1916             }
1917         }
1918
1919       return;
1920     }
1921
1922   sRefSet_allElements (newMods, current)
1923     {
1924       if (sRef_isValid (current))
1925         {
1926           sRef rb = sRef_getRootBase (current);
1927           
1928           if (sRef_isFileStatic (rb))
1929             {
1930               if (!modInternal)
1931                 {
1932                   if (!sRefSet_isSameMember (old->info->fcn->mods, 
1933                                              sRef_makeInternalState ())
1934                       && !sRefSet_isSameMember (old->info->fcn->mods, 
1935                                                 sRef_makeSpecState ()))
1936                     {
1937                       if (mustConform 
1938                           && !uentry_isStatic (old)
1939                           && optgenerror 
1940                           (FLG_INCONDEFS,
1941                            message
1942                            ("Modifies list for %q includes internal state, "
1943                             "but %s without modifies internal.",
1944                             uentry_getName (old),
1945                             uentry_specOrDefName (old)),
1946                            uentry_whereLast (unew)))
1947                         {
1948                           uentry_showWhereSpecified (old);
1949                         }
1950                       
1951                       old->info->fcn->mods = 
1952                         sRefSet_insert (old->info->fcn->mods, 
1953                                         sRef_makeInternalState ());
1954                       modInternal = TRUE;
1955                     }
1956                 }
1957               
1958               old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1959                                                      current);
1960               changedMods = TRUE;
1961             }
1962           else
1963             {
1964               if (sRef_canModifyVal (current, old->info->fcn->mods))
1965                 {
1966                   int size = sRefSet_size (old->info->fcn->mods);
1967
1968                   old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1969                                                          current);
1970
1971                   if (sRefSet_size (old->info->fcn->mods) != size)
1972                     {
1973                       changedMods = TRUE;
1974                     }
1975                 }
1976               else
1977                 {
1978                   if (mustConform
1979                       && optgenerror 
1980                       (FLG_INCONDEFS,
1981                        message 
1982                        ("Modifies list for %q contains %q, not modifiable "
1983                         "according to %s",
1984                         uentry_getName (old),
1985                         sRef_unparse (current),
1986                         uentry_specDeclName (old)),
1987                        uentry_whereLast (unew)))
1988                     {
1989                       uentry_showWhereSpecified (old);
1990                     }
1991                 }
1992             }
1993         }
1994     } end_sRefSet_allElements;
1995
1996   if (completeConform && uentry_isReallySpecified (old))
1997     {
1998       sRefSet_allElements (old->info->fcn->mods, el)
1999         {
2000           if (sRef_canModify (el, newMods))
2001             {
2002               ; /* okay */
2003             }
2004           else
2005             {
2006               if (optgenerror 
2007                   (FLG_NEEDSPEC,
2008                    message 
2009                    ("Specification modifies clause for %q contains %q, "
2010                     "not included in declaration modifies clause",
2011                     uentry_getName (old),
2012                     sRef_unparse (el)),
2013                    uentry_whereLast (unew)))
2014                 {
2015                   uentry_showWhereSpecified (old);
2016                 }
2017             }
2018         } end_sRefSet_allElements ;
2019     } 
2020
2021   /*
2022   ** Make sure file static elements will be removed.
2023   */
2024
2025   if (changedMods)
2026     {
2027       context_recordFileModifies (old->info->fcn->mods);
2028     }
2029 }
2030
2031 static void 
2032   uentry_checkMutableType (uentry ue)
2033 {
2034   ctype ct = uentry_getType (ue);
2035
2036   if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2037     {
2038       DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2039
2040       voptgenerror (FLG_MUTREP,
2041                     message ("Mutable abstract type %q declared without pointer "
2042                              "indirection: %t (violates assignment semantics)",
2043                              uentry_getName (ue), ct),
2044                     uentry_whereDeclared (ue));
2045     }
2046 }
2047
2048 void
2049 uentry_setMutable (uentry e)
2050 {
2051   llassert (uentry_isDatatype (e));
2052   e->info->datatype->mut = YES;
2053 }
2054
2055 static void
2056 uentry_checkIterArgs (uentry ue)
2057 {
2058   bool hasYield = FALSE;
2059   uentryList args;
2060
2061   llassert (uentry_isIter (ue));
2062
2063   args = uentry_getParams (ue);
2064
2065   uentryList_elements (args, el)
2066     {
2067       sstate ds = uentry_getDefState (el);
2068
2069       if (uentry_isYield (el))
2070         {
2071           hasYield = TRUE;
2072         }
2073
2074       if (sstate_isUnknown (ds))
2075         {
2076           uentry_setDefState (el, SS_DEFINED);
2077         }
2078       else
2079         {
2080           ;
2081         }
2082     } end_uentryList_elements;
2083
2084   if (!hasYield)
2085     {
2086       voptgenerror (FLG_HASYIELD,
2087                     message ("Iterator %q declared with no yield parameters",
2088                              uentry_getName (ue)),
2089                     uentry_whereDeclared (ue));
2090     }
2091 }
2092
2093 static chkind
2094 chkind_fromQual (qual qel)
2095 {
2096   if (qual_isChecked (qel))
2097     {
2098       return CH_CHECKED;
2099     }
2100   else if (qual_isCheckMod (qel))
2101     {
2102       return CH_CHECKMOD;
2103     }
2104   else if (qual_isCheckedStrict (qel))
2105     {
2106       return CH_CHECKEDSTRICT;
2107     }
2108   else if (qual_isUnchecked (qel))
2109     {
2110       return CH_UNCHECKED;
2111     }
2112   else
2113     {
2114       BADEXIT;
2115       /*@notreached@*/ return CH_UNKNOWN;
2116     }
2117 }
2118
2119 static void
2120 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2121 {
2122   if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2123     {
2124       if (!uentry_isRefCounted (ue))
2125         {
2126           voptgenerror
2127             (FLG_ANNOTATIONERROR,
2128              message ("Reference counting qualifier %s used on non-reference "
2129                       "counted storage: %q",
2130                       qual_unparse (qel), 
2131                       uentry_unparse (ue)),
2132              uentry_whereLast (ue));
2133         }
2134       else
2135         {
2136           alkind ak = alkind_fromQual (qel);
2137           
2138           uentry_setAliasKind (ue, ak);
2139         }
2140     }
2141   else if (qual_isRefCounted (qel))
2142     {
2143       ctype ct = ctype_realType (uentry_getType (ue));
2144       ctype rt;
2145       
2146       if (ctype_isPointer (ct) 
2147           && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2148         {
2149           /* check there is a refs field */
2150           uentryList fields = ctype_getFields (rt);
2151           uentry refs = uentry_undefined;
2152
2153           uentryList_elements (fields, field)
2154             {
2155               if (uentry_isRefsField (field))
2156                 {
2157                   if (uentry_isValid (refs))
2158                     {
2159                       voptgenerror
2160                         (FLG_ANNOTATIONERROR, 
2161                          message ("Reference counted structure type %s has "
2162                                   "multiple refs fields: %q and %q",
2163                                   ctype_unparse (ct),
2164                                   uentry_getName (refs),
2165                                   uentry_getName (field)),
2166                          uentry_whereLast (field));
2167                     }
2168                   
2169                   refs = field;
2170                 }
2171             } end_uentryList_elements;
2172
2173           if (uentry_isInvalid (refs))
2174             {
2175               vgenhinterror 
2176                 (FLG_SYNTAX, 
2177                  message ("Reference counted structure type %s has "
2178                           "no refs field",
2179                           ctype_unparse (ct)),
2180                  cstring_makeLiteral
2181                  ("To count reference, the structure must have a field named "
2182                   "refs of type int."),
2183                  g_currentloc);           
2184             }
2185           else if (!ctype_isInt (uentry_getType (refs)))
2186             {
2187               voptgenerror
2188                 (FLG_ANNOTATIONERROR, 
2189                  message ("Reference counted structure type %s refs field has "
2190                           "type %s (should be int)", ctype_unparse (ct),
2191                           ctype_unparse (uentry_getType (refs))),
2192                  uentry_whereLast (refs));
2193             }
2194           else
2195             {
2196               sRef_setAliasKind (ue->sref, alkind_fromQual (qel), 
2197                                  uentry_whereDeclared (ue));
2198             }
2199         }
2200       else
2201         {
2202           if ((ctype_isPointer (ct) 
2203                && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2204               ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2205             {
2206               sRef_setAliasKind (ue->sref, alkind_fromQual (qel), 
2207                                  uentry_whereDeclared (ue));
2208             }
2209           else
2210             {
2211               voptgenerror
2212                 (FLG_ANNOTATIONERROR, 
2213                  message ("Non-pointer to structure type %s declared with "
2214                           "refcounted qualifier",
2215                           ctype_unparse (ct)),
2216                  uentry_whereLast (ue));
2217             }
2218         }
2219     }
2220   else if (qual_isRefs (qel))
2221     {
2222       if (uentry_isVariable (ue) && !uentry_isParam (ue))
2223         {
2224           uentry_setAliasKind (ue, AK_REFS);
2225         }
2226       else
2227         {
2228           voptgenerror 
2229             (FLG_ANNOTATIONERROR,
2230              message ("Refs qualifier used on non-structure field: %q",
2231                       uentry_unparse (ue)),
2232              uentry_whereLast (ue));
2233         }
2234     }
2235   else if (qual_isAliasQual (qel))
2236     {
2237       alkind ak = alkind_fromQual (qel);
2238       bool okay = TRUE;
2239       alkind oldak = uentry_getAliasKind (ue);
2240       ctype ut = uentry_getType (ue);
2241       
2242       if (alkind_isImplicit (ak) 
2243           && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2244         {
2245           /* ignore the implied qualifier */
2246           okay = FALSE;
2247         }
2248       
2249       if (uentry_isEitherConstant (ue))
2250         {
2251           voptgenerror 
2252             (FLG_ANNOTATIONERROR, 
2253              message ("Alias qualifier %s used on constant: %q",
2254                       alkind_unparse (ak), uentry_unparse (ue)),
2255              uentry_whereLast (ue));
2256
2257           okay = FALSE;
2258         }
2259       
2260       if (ctype_isFunction (ut))
2261         {
2262           ut = ctype_getReturnType (ut);
2263         }
2264       
2265       if (!(ctype_isVisiblySharable (ut) 
2266             || ctype_isRealArray (ut)
2267             || ctype_isRealSU (ut)))
2268         {
2269           if (!qual_isImplied (qel))
2270             {
2271               voptgenerror
2272                 (FLG_ANNOTATIONERROR, 
2273                  message ("Alias qualifier %s used on unsharable storage type %t: %q",
2274                           alkind_unparse (ak), ut, uentry_getName (ue)),
2275                  uentry_whereLast (ue));
2276             }
2277           
2278           okay = FALSE;
2279         }
2280       else
2281         {
2282           if (uentry_isRefCounted (ue))
2283             {
2284               if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2285                     || qual_isExposed (qel) 
2286                     || qual_isObserver (qel)))
2287                 {
2288                   if (!qual_isImplied (qel))
2289                     {
2290                       voptgenerror
2291                         (FLG_ANNOTATIONERROR, 
2292                          message 
2293                          ("Alias qualifier %s used on reference counted storage: %q",
2294                           alkind_unparse (ak), 
2295                           uentry_unparse (ue)),
2296                          uentry_whereLast (ue));
2297                     }
2298                   
2299                   okay = FALSE;
2300                 }
2301             }
2302           else
2303             {
2304               if (qual_isRefQual (qel))
2305                 {
2306                   voptgenerror 
2307                     (FLG_ANNOTATIONERROR,
2308                      message ("Qualifier %s used on non-reference counted storage: %q",
2309                               alkind_unparse (ak), uentry_unparse (ue)),
2310                      uentry_whereLast (ue));
2311                   
2312                   okay = FALSE;
2313                 }
2314             }
2315         }
2316       
2317       if (okay)
2318         {
2319           uentry_setAliasKind (ue, ak);
2320         }
2321     }
2322   else if (qual_isNull (qel))
2323     {
2324       if (uentry_isConstant (ue))
2325         {
2326           sRef_setNullState 
2327             (ue->sref, 
2328              ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL, 
2329              uentry_whereDeclared (ue));
2330         }
2331       else
2332         {
2333           uentry_setNullState (ue, NS_POSNULL);
2334         }
2335     }
2336   else if (qual_isRelNull (qel))
2337     {
2338       uentry_setNullState (ue, NS_RELNULL);
2339     }
2340   else if (qual_isNotNull (qel))
2341     {
2342       uentry_setNullState (ue, NS_MNOTNULL);
2343     }
2344   else if (qual_isAbstract (qel)
2345            || qual_isConcrete (qel))
2346     {
2347       if (!uentry_isDatatype (ue))
2348         {
2349           voptgenerror 
2350             (FLG_ANNOTATIONERROR, 
2351              message ("Qualifier %s used with non-datatype", 
2352                       qual_unparse (qel)),
2353              uentry_whereLast (ue));
2354         }
2355       else
2356         {
2357           ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2358         }
2359     }
2360   else if (qual_isMutable (qel))
2361     {
2362       if (!uentry_isDatatype (ue))
2363         {
2364           voptgenerror
2365             (FLG_ANNOTATIONERROR,
2366              message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2367              uentry_whereLast (ue));
2368         }
2369       else
2370         {
2371           if (!ynm_isOn (ue->info->datatype->mut))
2372             {
2373               uentry_checkMutableType (ue);
2374             }
2375           
2376           ue->info->datatype->mut = YES;
2377         }
2378     }
2379   else if (qual_isImmutable (qel))
2380     {
2381       if (!uentry_isDatatype (ue))
2382         {
2383           voptgenerror (FLG_ANNOTATIONERROR, 
2384                         message ("Qualifier %s used with non-datatype", 
2385                                  qual_unparse (qel)),
2386                         uentry_whereLast (ue));
2387         }
2388       else
2389         {
2390           ue->info->datatype->mut = NO;
2391         }
2392     }
2393   else if (qual_isNullPred (qel))
2394     {
2395       uentry_convertVarFunction (ue);
2396
2397       if (uentry_isFunction (ue))
2398         {
2399           ctype typ = uentry_getType (ue);
2400           ctype rtype = ctype_getReturnType (uentry_getType (ue));
2401           
2402           if (ctype_isRealBool (rtype))
2403             {
2404               uentryList pl = ctype_argsFunction (typ);
2405               
2406               if (uentryList_size (pl) == 1)
2407                 {
2408                   ue->info->fcn->nullPred = qel;
2409                 }
2410               else
2411                 {
2412                   voptgenerror (FLG_ANNOTATIONERROR,
2413                                 message ("Qualifier %s used with function having %d "
2414                                          "arguments (should have 1)", 
2415                                          qual_unparse (qel),
2416                                          uentryList_size (pl)),
2417                                 uentry_whereLast (ue));
2418                 }
2419             }
2420           else
2421             {
2422               voptgenerror (FLG_ANNOTATIONERROR,
2423                             message ("Qualifier %s used with function returning %s "
2424                                      "(should return bool)", 
2425                                      qual_unparse (qel),
2426                                      ctype_unparse (rtype)),
2427                             uentry_whereLast (ue));
2428             }
2429         }
2430       else
2431         {
2432           voptgenerror (FLG_ANNOTATIONERROR,
2433                         message ("Qualifier %s used with non-function", 
2434                                  qual_unparse (qel)),
2435                         uentry_whereLast (ue));
2436         }
2437     }
2438   else if (qual_isExitQual (qel))
2439     {
2440       exitkind exk = exitkind_fromQual (qel);
2441       
2442       if (uentry_isFunction (ue))
2443         {
2444           if (exitkind_isKnown (ue->info->fcn->exitCode))
2445             {
2446               voptgenerror (FLG_ANNOTATIONERROR,
2447                             message ("Multiple exit qualifiers used on function %q:  %s, %s", 
2448                                      uentry_getName (ue),
2449                                      exitkind_unparse (ue->info->fcn->exitCode),
2450                                      exitkind_unparse (exk)),
2451                             uentry_whereLast (ue));
2452             }
2453           
2454           ue->info->fcn->exitCode = exk;
2455         }
2456       else
2457         {
2458           if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2459             {
2460               uentry_makeVarFunction (ue);
2461               ue->info->fcn->exitCode = exk;
2462             }
2463           else
2464             {
2465               voptgenerror (FLG_ANNOTATIONERROR,
2466                             message ("Exit qualifier %s used with non-function (type %s)", 
2467                                      qual_unparse (qel),
2468                                      ctype_unparse (uentry_getType (ue))),
2469                             uentry_whereLast (ue));
2470             }
2471         }
2472     }
2473   else if (qual_isMetaState (qel)) 
2474     {
2475       annotationInfo ainfo = qual_getAnnotationInfo (qel);
2476
2477       if (annotationInfo_matchesContext (ainfo, ue))
2478         {
2479           DPRINTF (("Reflecting %s on %s", 
2480                     annotationInfo_unparse (ainfo),
2481                     uentry_unparseFull (ue)));
2482           
2483           sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2484           DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2485           DPRINTF (("==> %s", uentry_unparseFull (ue)));
2486         }
2487       else
2488         {
2489           if (optgenerror
2490               (FLG_ANNOTATIONERROR,
2491                message ("Attribute annotation %s used in inconsistent context: %q",
2492                         qual_unparse (qel),
2493                         uentry_unparse (ue)),
2494                uentry_whereLast (ue)))
2495             {
2496               /*@i! annotationInfo_showContextError (ainfo, ue); */
2497             }
2498         }
2499     }
2500   else
2501     {
2502       if (qual_isCQual (qel))
2503         {
2504           ; /* okay */
2505         }
2506       else
2507         {
2508           llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2509         }
2510     }
2511 }
2512
2513 void
2514 uentry_reflectQualifiers (uentry ue, qualList q)
2515 {
2516   llassert (uentry_isValid (ue)); 
2517
2518   DPRINTF (("Reflect qualifiers: %s / %s",
2519             uentry_unparseFull (ue), qualList_unparse (q)));
2520
2521   qualList_elements (q, qel)
2522     {
2523       if (qual_isStatic (qel))
2524         {
2525           uentry_setStatic (ue);
2526         }
2527       else if (qual_isUnused (qel))
2528         {
2529           uentry_setUsed (ue, fileloc_undefined);         
2530           DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2531         }
2532       else if (qual_isExternal (qel))
2533         {
2534           fileloc_free (ue->whereDefined);
2535           ue->whereDefined = fileloc_createExternal ();
2536         }
2537       else if (qual_isSef (qel))
2538         {
2539           if (uentry_isVariable (ue))
2540             {
2541               vkind vk = ue->info->var->kind;
2542
2543               llassert (vk != VKREFPARAM);
2544
2545               if (vk == VKYIELDPARAM)
2546                 {
2547                   voptgenerror
2548                     (FLG_ANNOTATIONERROR,
2549                      message ("Qualifier sef cannot be used with %s: %q",
2550                               cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2551                               uentry_unparse (ue)),
2552                      uentry_whereLast (ue));
2553                 }
2554               else if (vk == VKRETPARAM)
2555                 {
2556                   ue->info->var->kind = VKSEFRETPARAM;
2557                 }
2558               else
2559                 {
2560                   ue->info->var->kind = VKSEFPARAM;
2561                 }
2562             }
2563           else
2564             {
2565               voptgenerror 
2566                 (FLG_ANNOTATIONERROR,
2567                  message ("Qualifier sef is meaningful only on parameters: %q", 
2568                           uentry_unparse (ue)),
2569                  uentry_whereLast (ue));
2570             }
2571         }
2572       else if (qual_isExtern (qel))
2573         {
2574           ue->storageclass = SCEXTERN;
2575         }
2576       else if (qual_isGlobalQual (qel)) /* undef, killed */
2577         {
2578           DPRINTF (("Reflecting qual: %s / %s",
2579                     qual_unparse (qel), uentry_unparse (ue)));
2580
2581           if (uentry_isVariable (ue))
2582             {
2583               sstate oldstate = ue->info->var->defstate;
2584               sstate defstate = sstate_fromQual (qel);
2585
2586
2587               if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2588                   || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2589                 {
2590                   defstate = SS_UNDEFKILLED;
2591                 }
2592               else 
2593                 {
2594                   ; /* any errors? */
2595                 }
2596
2597               sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2598               ue->info->var->defstate = defstate;
2599             }
2600           else
2601             {
2602               voptgenerror 
2603                 (FLG_ANNOTATIONERROR,
2604                  message ("Qualifier %s used on non-variable: %q",
2605                           qual_unparse (qel), uentry_unparse (ue)),
2606                  uentry_whereLast (ue));
2607             }
2608
2609           DPRINTF (("After: %s", uentry_unparseFull (ue)));
2610         }
2611       /* start modifications */
2612       else if( qual_isBufQualifier(qel) ) {
2613         ctype ct = ctype_realType(uentry_getType(ue));
2614         if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2615
2616             if( uentry_hasBufStateInfo(ue) )  {
2617                 if( qual_isNullTerminated(qel) ) {  /* handle Nullterm */
2618                     
2619                    if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2620                                                /* If formal func param */
2621                        uentry_setNullTerminatedState(ue); 
2622                        uentry_setLen (ue, 1);
2623                        uentry_setSize (ue, 1);
2624
2625                        sRef_setNullTerminatedState(uentry_getSref(ue));
2626                        sRef_setLen (uentry_getSref(ue), 1);
2627                        sRef_setSize (uentry_getSref(ue), 1);
2628                    } else {
2629                        uentry_setPossiblyNullTerminatedState(ue); 
2630
2631                        sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2632                    }
2633
2634                 } 
2635                 /* put other BufState Qualifiers here */
2636             } else {
2637               cstring s =  uentry_getName(ue);
2638               llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2639                         struct for identifier %s\n", s) );
2640             }
2641          } else if (ctype_isFunction (ct)) { /* We have to handle function */
2642
2643             sRef retSref = uentry_getSref (ue);
2644             ctype retType = sRef_getType (retSref);
2645
2646             if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2647                sRef_setNullTerminatedState (retSref);
2648
2649             } else {
2650               
2651                 llerror 
2652                   (FLG_SYNTAX,
2653                        message ("Qualifier %s used on non-pointer on \
2654                             function return: %q", qual_unparse (qel),
2655                                                     uentry_unparse (ue)));
2656              }
2657          }
2658               
2659          else  {
2660                 llerror 
2661                   (FLG_SYNTAX,
2662                        message ("Qualifier %s used on non-pointer: %q",
2663                           qual_unparse (qel), uentry_unparse (ue)));          
2664          }
2665         DPRINTF (("After: %s", uentry_unparseFull (ue)));
2666       }/* end else if */    
2667       else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2668         {
2669           ctype realType = ctype_realType (ue->utype);
2670           sstate defstate = sstate_fromQual (qel);
2671
2672           if (ctype_isFunction (realType))
2673             {
2674               realType = ctype_realType (ctype_getReturnType (realType));
2675             }
2676
2677           if (qual_isRelDef (qel))
2678             {
2679               ; /* okay anywhere */
2680             }
2681           else
2682             {
2683               if (!ctype_isAP (realType) 
2684                   && !ctype_isSU (realType)
2685                   && !ctype_isUnknown (realType)
2686                   && !ctype_isAbstract (ue->utype))
2687                 {
2688                   voptgenerror 
2689                     (FLG_ANNOTATIONERROR,
2690                      message ("Qualifier %s used on non-pointer or struct: %q",
2691                               qual_unparse (qel), uentry_unparse (ue)),
2692                      uentry_whereLast (ue));
2693                 }
2694             }
2695
2696           uentry_setDefState (ue, defstate);
2697
2698           if (sRef_isStateSpecial (ue->sref)
2699               && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2700             {
2701               sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2702             }
2703         }
2704       else if (qual_isYield (qel))
2705         {
2706           if (uentry_isVariable (ue))
2707             {
2708               ue->info->var->kind = VKYIELDPARAM;
2709             }
2710           else
2711             {
2712               voptgenerror 
2713                 (FLG_ANNOTATIONERROR,
2714                  message ("Qualifier %s used on non-iterator parameter: %q",
2715                           qual_unparse (qel), uentry_unparse (ue)),
2716                  uentry_whereLast (ue));
2717             }
2718         }
2719       else if (qual_isExQual (qel))
2720         {
2721           exkind ek = exkind_fromQual (qel);
2722           ctype ut = uentry_getType (ue);
2723
2724           DPRINTF (("Reflect ex qual: %s / %s",
2725                     uentry_unparse (ue), exkind_unparse (ek)));
2726
2727           if (ctype_isFunction (ut))
2728             {
2729               ut = ctype_getReturnType (ut);
2730             }
2731           
2732           if (!(ctype_isVisiblySharable (ut))
2733               && !(ctype_isArray (ut)) /* can apply to arrays also! */
2734               && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2735             {
2736               if (!qual_isImplied (qel))
2737                 {
2738                   if (ctype_isImmutableAbstract (ut)) {
2739                     voptgenerror 
2740                       (FLG_REDUNDANTSHAREQUAL, 
2741                        message ("Qualifier %s used on unsharable storage type %t: %q",
2742                                 exkind_unparse (ek), ut, uentry_getName (ue)),
2743                        uentry_whereLast (ue));
2744                   } else {
2745                     voptgenerror 
2746                       (FLG_MISPLACEDSHAREQUAL, 
2747                        message ("Qualifier %s used on unsharable storage type %t: %q",
2748                                 exkind_unparse (ek), ut, uentry_getName (ue)),
2749                        uentry_whereLast (ue));
2750                   }
2751                 }
2752             }
2753           else
2754             {
2755               alkind ak = sRef_getAliasKind (ue->sref);
2756
2757               sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2758               DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2759
2760               if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2761                 {
2762                   if (!alkind_isTemp (ak))
2763                     {
2764                       DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2765                       uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2766                     }
2767                 }
2768               else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2769                        || alkind_isOwned (ak))
2770                 {
2771                   ; /* okay */
2772                 }
2773               else
2774                 {
2775                   llerror 
2776                     (FLG_SYNTAX, 
2777                      message ("Exposure qualifier %s used on %s storage (should "
2778                               "be dependent): %q",
2779                               qual_unparse (qel), 
2780                               alkind_unparse (ak),
2781                               uentry_unparse (ue)));
2782                 }
2783             }
2784         }
2785       else if (qual_isGlobCheck (qel))
2786         {
2787           if (uentry_isVariable (ue))
2788             {
2789               chkind ch = chkind_fromQual (qel);                
2790                        
2791               if (ue->info->var->checked != CH_UNKNOWN)
2792                 {
2793                   if (ch == ue->info->var->checked)
2794                     {
2795                       llerror (FLG_SYNTAX, 
2796                                message ("Redundant %s qualifier on %q",
2797                                         qual_unparse (qel),
2798                                         uentry_getName (ue)));
2799                     }
2800                   else
2801                     {
2802                       llerror (FLG_SYNTAX, 
2803                                message
2804                                ("Contradictory %s and %s qualifiers on %q",
2805                                 qual_unparse (qel),
2806                                 checkedName (ue->info->var->checked),
2807                                 uentry_getName (ue)));
2808                     }
2809                 }
2810
2811               ue->info->var->checked = ch;
2812             }
2813           else
2814             {
2815               llerror
2816                 (FLG_SYNTAX, 
2817                  message ("Qualifier %s used with non-variable", 
2818                           qual_unparse (qel)));
2819             }
2820         }
2821       else if (qual_isReturned (qel))
2822         {
2823           if (uentry_isVariable (ue))
2824             {
2825               ue->info->var->kind = VKRETPARAM;
2826             }
2827           else
2828             {
2829               llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable", 
2830                                             qual_unparse (qel)));
2831             }
2832         }
2833       else
2834         {
2835           uentry_reflectOtherQualifier (ue, qel);
2836         }
2837
2838       sRef_storeState (ue->sref);
2839     } end_qualList_elements;
2840
2841   qualList_clear (q);
2842
2843   DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2844 }
2845         
2846 bool
2847 uentry_isOnly (uentry ue)
2848 {
2849   return (!uentry_isUndefined (ue) 
2850           && uentry_isVariable (ue) 
2851           && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2852 }
2853
2854 static void
2855 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2856 {
2857   sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2858   sRef_setOrigAliasKind (ue->sref, ak);
2859 }
2860
2861 static void
2862 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2863 {
2864   if (uentry_isVariable (ue))
2865     {
2866       ue->info->var->nullstate = ns;
2867     }
2868
2869   sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2870 }
2871
2872 bool
2873 uentry_isUnique (uentry ue)
2874 {
2875   return (!uentry_isUndefined (ue) 
2876           && uentry_isVariable (ue) 
2877           && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2878 }
2879
2880 bool
2881 uentry_isFileStatic (uentry ue)
2882 {
2883   return (uentry_isStatic (ue) 
2884           && (!uentry_isVariable (ue)
2885               || sRef_isFileStatic (uentry_getSref (ue))));
2886 }
2887
2888 bool
2889 uentry_isExported (uentry ue)
2890 {
2891   if (uentry_isValid (ue))
2892     {
2893       if (uentry_isVariable (ue))
2894         {
2895           return (sRef_isRealGlobal (uentry_getSref (ue)));
2896         }
2897       else
2898         {
2899           return !uentry_isStatic (ue);
2900         }
2901     }
2902
2903   return FALSE;
2904 }
2905
2906 bool
2907 uentry_isNonLocal (uentry ue)
2908 {
2909   return (uentry_isValid (ue) && uentry_isVariable (ue)
2910           && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2911 }
2912
2913 bool
2914 uentry_isGlobalVariable (uentry ue)
2915 {
2916   return (uentry_isValid (ue) && uentry_isVariable (ue) 
2917           && sRef_isFileOrGlobalScope (ue->sref));
2918 }
2919
2920 bool
2921 uentry_isVisibleExternally (uentry ue)
2922 {
2923   return (uentry_isValid (ue) 
2924           && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2925               || (!uentry_isStatic (ue) 
2926                   && (uentry_isFunction (ue)
2927                       || uentry_isIter (ue)
2928                       || uentry_isEndIter (ue)
2929                       || uentry_isConstant (ue)
2930                       || uentry_isDatatype (ue)
2931                       || uentry_isAnyTag (ue)))));
2932 }
2933
2934 bool
2935 uentry_isPrintfLike (uentry ue)
2936 {
2937   return (uentry_isFunction (ue) 
2938           && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2939 }
2940
2941 bool
2942 uentry_isScanfLike (uentry ue)
2943 {
2944   return (uentry_isFunction (ue) 
2945           && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2946 }
2947
2948 bool
2949 uentry_isMessageLike (uentry ue)
2950 {
2951   return (uentry_isFunction (ue) 
2952           && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2953 }
2954
2955 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2956 {
2957   uentryList args = uentry_getParams (ue);
2958
2959   if (!uentryList_isMissingParams (args))
2960     {
2961       uentry last = uentry_undefined;
2962
2963       uentryList_elements (args, current)
2964         {
2965           if (uentry_isElipsisMarker (current))
2966             {
2967               if (uentry_isUndefined (last))
2968                 {
2969                   voptgenerror 
2970                     (FLG_SYNTAX,
2971                      message ("Function %q is marked %s, but has no format "
2972                               "string argument before elipsis",
2973                               uentry_getName (ue),
2974                               specCode_unparse (ue->info->fcn->specialCode)),
2975                      uentry_whereLast (ue));
2976                   ue->info->fcn->specialCode = SPC_NONE;
2977                 }
2978               else
2979                 {
2980                   ctype rt = ctype_realType (uentry_getType (last));
2981
2982                   if (!ctype_match (rt, ctype_string))
2983                     {
2984                       bool okay = FALSE;
2985
2986                       /* wchar_t * is okay too */
2987                       if (ctype_isAP (rt))
2988                         {
2989                           ctype base = ctype_baseArrayPtr (rt);
2990                           
2991                           if (ctype_isArbitraryIntegral (base)) 
2992                             {
2993                               okay = TRUE;
2994                             }
2995                         }
2996                       
2997                       if (!okay) 
2998                         {
2999                           voptgenerror
3000                             (FLG_SYNTAX,
3001                              message ("Function %q is marked %s, but the argument "
3002                                       "before the elipsis has type %s (should be char *)",
3003                                       uentry_getName (ue),
3004                                       specCode_unparse (ue->info->fcn->specialCode),
3005                                       ctype_unparse (uentry_getType (last))),
3006                              uentry_whereLast (ue));
3007                           
3008                           ue->info->fcn->specialCode = SPC_NONE;
3009                         }
3010                     }
3011                 }
3012               return;
3013             }
3014           last = current;
3015         } end_uentryList_elements ;
3016
3017       voptgenerror 
3018         (FLG_SYNTAX,
3019          message ("Function %q is marked %s, but has no elipsis parameter",
3020                   uentry_getName (ue),
3021                   specCode_unparse (ue->info->fcn->specialCode)),
3022          uentry_whereLast (ue));
3023
3024       ue->info->fcn->specialCode = SPC_NONE;
3025     }
3026 }
3027
3028 void
3029 uentry_setPrintfLike (uentry ue)
3030 {
3031   uentry_convertVarFunction (ue);
3032   llassertfatal (uentry_isFunction (ue));
3033   ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3034   checkSpecialFunction (ue);
3035 }
3036
3037 void
3038 uentry_setScanfLike (uentry ue)
3039 {
3040   uentry_convertVarFunction (ue);
3041   llassertfatal (uentry_isFunction (ue));
3042   ue->info->fcn->specialCode = SPC_SCANFLIKE;
3043   checkSpecialFunction (ue);
3044 }
3045
3046 void
3047 uentry_setMessageLike (uentry ue)
3048 {
3049   uentry_convertVarFunction (ue);  
3050   llassertfatal (uentry_isFunction (ue));
3051   ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3052   checkSpecialFunction (ue);
3053 }
3054
3055 bool
3056 uentry_isSpecialFunction (uentry ue)
3057 {
3058   return (uentry_isFunction (ue) 
3059           && (ue->info->fcn->specialCode != SPC_NONE));
3060 }
3061
3062 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3063 {
3064   ctype ct = idDecl_getCtype (t);
3065   ctype base = ct;
3066   fileloc loc = setLocation ();
3067   sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3068   uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3069
3070   DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3071   uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3072   uentry_implicitParamAnnots (ue);
3073
3074   /* Parameter type [][] or [x][] is invalid */
3075
3076   while (ctype_isFixedArray (base)) {
3077     base = ctype_baseArrayPtr (base);
3078   }
3079   
3080   if (ctype_isIncompleteArray (base)) {
3081     base = ctype_baseArrayPtr (base);
3082
3083     if (ctype_isArray (base)) {
3084       if (!uentry_hasName (ue)) {
3085         (void) optgenerror (FLG_INCOMPLETETYPE, 
3086                             message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3087                                      i + 1,
3088                                      ctype_unparse (ct)),
3089                             uentry_whereLast (ue));
3090       } else {
3091         (void) optgenerror (FLG_INCOMPLETETYPE, 
3092                             message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3093                                      uentry_getName (ue),
3094                                      ctype_unparse (ct)),
3095                             uentry_whereLast (ue));
3096       }
3097     }
3098   }
3099
3100   DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3101   return ue;
3102 }
3103
3104 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3105 {
3106   ctype ct = idDecl_getCtype (t);
3107
3108   if (ctype_isFunction (ct))
3109     {
3110             return (uentry_makeIdFunction (t));
3111     }
3112   else
3113     {
3114       fileloc loc = setLocation ();
3115       uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3116
3117       uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3118
3119       if (!uentry_isExtern (ue))
3120         {
3121           uentry_setDefined (ue, loc);
3122         }
3123
3124       return ue;
3125     }
3126 }
3127
3128 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3129 {
3130   return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3131 }
3132
3133 /*
3134 ** constants
3135 */
3136
3137 static /*@only@*/ /*@notnull@*/ 
3138 uentry uentry_makeConstantAux (cstring n, ctype t, 
3139                                /*@keep@*/ fileloc f, bool priv, bool macro,
3140                                /*@only@*/ multiVal m)
3141 {
3142   uentry e = uentry_alloc ();
3143
3144   e->ukind = KCONST;
3145   e->uname = cstring_copy (n);
3146   e->utype = t;
3147   e->storageclass = SCNONE;
3148
3149   e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3150
3151   e->sref  = sRef_makeConst (t);
3152
3153   e->lset = FALSE;
3154   e->used = FALSE;
3155   
3156   e->uses = filelocList_new ();
3157   e->isPrivate = priv;
3158   e->hasNameError = FALSE;
3159
3160   e->info = (uinfo) dmalloc (sizeof (*e->info));
3161   e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3162   e->info->uconst->access = typeIdSet_undefined;
3163   e->info->uconst->macro = macro;
3164
3165   uentry_setSpecDef (e, f);
3166
3167   if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3168     {
3169       sRef_setDefNull (e->sref, uentry_whereDeclared (e)); 
3170     }
3171
3172   uentry_setConstantValue (e, m);
3173
3174   return (e);
3175 }
3176
3177 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3178 {
3179   uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3180   return ue;
3181 }
3182
3183 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3184 {
3185   uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3186   return ue;
3187 }
3188
3189 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3190 {
3191   uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3192   return ue;
3193 }
3194
3195 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3196 {
3197   uentry ue = uentry_makeConstant (idDecl_observeId (t), 
3198                                    idDecl_getCtype (t), 
3199                                    fileloc_undefined);
3200
3201   llassert (fileloc_isUndefined (ue->whereDeclared));
3202   ue->whereDeclared = setLocation ();
3203   uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3204
3205   DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3206   DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3207   return ue;
3208 }
3209
3210 /*
3211 ** variables
3212 */
3213
3214 void uentry_setDefState (uentry ue, sstate defstate)
3215 {
3216   if (uentry_isValid (ue))
3217     {
3218       sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3219
3220       if (uentry_isVariable (ue))
3221         {
3222           ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3223         }
3224     }
3225 }
3226
3227 bool uentry_isCheckedUnknown (uentry ue)
3228 {
3229   return (uentry_isVar (ue) 
3230           && (ue->info->var->checked == CH_UNKNOWN));
3231 }
3232
3233 bool uentry_isCheckMod (uentry ue)
3234 {
3235   return (uentry_isVar (ue) 
3236           && (ue->info->var->checked == CH_CHECKMOD));
3237 }
3238
3239 bool uentry_isUnchecked (uentry ue)
3240 {
3241   return (uentry_isVar (ue) 
3242           && (ue->info->var->checked == CH_UNCHECKED));
3243 }
3244
3245 bool uentry_isChecked (uentry ue)
3246 {
3247   return (uentry_isVar (ue) 
3248           && (ue->info->var->checked == CH_CHECKED));
3249 }
3250
3251 bool uentry_isCheckedModify (uentry ue)
3252 {
3253   return (uentry_isVar (ue) 
3254           && (ue->info->var->checked == CH_CHECKED
3255               || ue->info->var->checked == CH_CHECKMOD
3256               || ue->info->var->checked == CH_CHECKEDSTRICT));
3257 }
3258
3259 bool uentry_isCheckedStrict (uentry ue)
3260 {
3261   return (uentry_isVar (ue) 
3262           && (ue->info->var->checked == CH_CHECKEDSTRICT));
3263 }
3264
3265 void uentry_setUnchecked (uentry ue)
3266 {
3267   llassert (uentry_isVar (ue));
3268
3269   ue->info->var->checked = CH_UNCHECKED;
3270 }
3271
3272 void uentry_setChecked (uentry ue)
3273 {
3274   llassert (uentry_isVar (ue));
3275
3276   ue->info->var->checked = CH_CHECKED;
3277 }
3278
3279 void uentry_setCheckMod (uentry ue)
3280 {
3281   llassert (uentry_isVar (ue));
3282
3283   ue->info->var->checked = CH_CHECKMOD;
3284 }
3285
3286 void uentry_setCheckedStrict (uentry ue)
3287 {
3288   llassert (uentry_isVar (ue));
3289   
3290   ue->info->var->checked = CH_CHECKEDSTRICT;
3291 }
3292
3293 static /*@only@*/ /*@notnull@*/ 
3294 uentry uentry_makeVariableAux (cstring n, ctype t, 
3295                                fileloc f,
3296                                /*@exposed@*/ sRef s,
3297                                bool priv, vkind kind)
3298 {
3299   uentry e = uentry_alloc ();
3300   ctype rt = t;
3301   
3302   DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3303
3304   e->ukind = KVAR;
3305   e->uname = cstring_copy (n);
3306   e->utype = t;
3307
3308   e->storageclass = SCNONE;
3309
3310   e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3311
3312   e->sref  = s;
3313
3314   e->used = FALSE;
3315   e->lset = FALSE;
3316
3317   e->uses = filelocList_new ();
3318   e->isPrivate = priv;
3319   e->hasNameError = FALSE;
3320
3321   e->info = (uinfo) dmalloc (sizeof (*e->info));
3322   e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3323   e->info->var->kind = kind;
3324
3325   /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3326   e->info->var->checked = CH_UNKNOWN;
3327
3328   DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3329   uentry_setSpecDef (e, f);
3330   DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3331
3332   if (ctype_isFunction (rt))
3333     {
3334       rt = ctype_getReturnType (rt);
3335     }
3336
3337   if (ctype_isUA (rt))
3338     {
3339       DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3340       sRef_setStateFromType (e->sref, rt);
3341     }
3342
3343   DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3344   e->info->var->defstate = sRef_getDefState (e->sref);  
3345   e->info->var->nullstate = sRef_getNullState (e->sref);
3346
3347   /* start modifications */
3348   /* This function sets the uentry for a pointer or array variable declaration,
3349      it allocates memory and sets the fields. We check if the type of the variable
3350      is a pointer or array and allocate a `bbufinfo' struct accordingly */
3351   
3352   if (ctype_isArray (t) || ctype_isPointer(t))
3353     {
3354       /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3355       e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3356       sRef_setNotNullTerminatedState (s);
3357     } 
3358   else 
3359     {
3360       e->info->var->bufinfo = NULL;
3361     }/* end else */
3362   /* end modification */
3363
3364   return (e);
3365 }
3366
3367 bool
3368 uentry_isYield (uentry ue)
3369 {
3370   return (uentry_isVariable (ue) 
3371           && (ue->info->var->kind == VKYIELDPARAM
3372               || ue->info->var->kind == VKREFYIELDPARAM));
3373 }
3374
3375 static bool
3376 uentry_isRefsField (uentry ue)
3377 {
3378   return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3379 }
3380
3381 /*@only@*/ /*@notnull@*/ 
3382 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3383 {
3384   return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv, 
3385                                   fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3386 }
3387
3388 /*
3389 ** functions
3390 */
3391
3392 void uentry_makeVarFunction (uentry ue)
3393 {
3394   alkind ak;
3395   exkind ek;
3396   uvinfo oldInfo;
3397   fileloc loc;
3398
3399   llassert (uentry_isValid (ue));
3400   llassert (!sRef_modInFunction ());
3401
3402   ak = sRef_getOrigAliasKind (ue->sref);
3403   ek = sRef_getOrigExKind (ue->sref);
3404
3405   llassert (uentry_isVariable (ue));
3406   oldInfo = ue->info->var;
3407
3408   DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3409   llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3410
3411   /*
3412   ** expanded macro is marked used 
3413   */
3414
3415   ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3416
3417   ue->ukind = KFCN;
3418   ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3419   ue->info->fcn->exitCode = XK_UNKNOWN;
3420   ue->info->fcn->nullPred = qual_createUnknown ();
3421   ue->info->fcn->specialCode = SPC_NONE;
3422   ue->info->fcn->access = typeIdSet_undefined;
3423   ue->info->fcn->hasGlobs = FALSE;
3424   ue->info->fcn->globs = globSet_undefined;
3425   ue->info->fcn->hasMods = FALSE;
3426   ue->info->fcn->mods = sRefSet_undefined;
3427   ue->info->fcn->specclauses = NULL;
3428   ue->info->fcn->defparams = uentryList_undefined;
3429
3430   /*drl*/
3431   ue->info->fcn->preconditions = functionConstraint_undefined;
3432   /*end */
3433
3434   /*drl 12/28/2000*/
3435   ue->info->fcn->postconditions = functionConstraint_undefined; 
3436   /*end */
3437   
3438   if (ctype_isFunction (ue->utype))
3439     {
3440       ue->sref = sRef_makeType (ctype_getReturnType (ue->utype)); 
3441     }
3442   else
3443     {
3444       ue->sref = sRef_makeType (ctype_unknown); 
3445     }
3446
3447   if (sRef_isRefCounted (ue->sref))
3448     {
3449       ak = AK_NEWREF;
3450     }
3451   else
3452     {
3453       if (alkind_isUnknown (ak))
3454         {
3455           if (exkind_isKnown (ek))
3456             {
3457               DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3458               ak = AK_IMPDEPENDENT;
3459             }
3460           else 
3461             {
3462               if (context_getFlag (FLG_RETIMPONLY))
3463                 {
3464                   if (ctype_isFunction (ue->utype)
3465                       && ctype_isVisiblySharable 
3466                       (ctype_realType (ctype_getReturnType (ue->utype))))
3467                     {
3468                       if (uentryList_hasReturned (uentry_getParams (ue)))
3469                         {
3470                           ;
3471                         }
3472                       else
3473                         {
3474                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
3475                             {
3476                               ;
3477                             }
3478                           else 
3479                             {
3480                               ak = AK_IMPONLY;
3481                             }
3482                         }
3483                     }
3484                 }
3485             }
3486         }
3487     }
3488
3489   loc = ue->whereDeclared;
3490
3491   sRef_setAliasKind (ue->sref, ak, loc);
3492   sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3493   sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3494   sRef_setExKind (ue->sref, ek, loc);
3495
3496   if (oldInfo->kind == VKEXPMACRO)
3497     {
3498       ;
3499     }
3500   else
3501     {
3502       fileloc_free (ue->whereDefined);
3503       ue->whereDefined = fileloc_undefined;
3504     }
3505
3506   uvinfo_free (oldInfo);
3507 }
3508
3509 void uentry_makeConstantFunction (uentry ue)
3510 {
3511   alkind ak;
3512   exkind ek;
3513   ucinfo oldInfo;
3514   fileloc loc;
3515
3516   llassert (uentry_isValid (ue));
3517   llassert (!sRef_modInFunction ());
3518
3519   ak = sRef_getOrigAliasKind (ue->sref);
3520   ek = sRef_getOrigExKind (ue->sref);
3521
3522   llassert (uentry_isConstant (ue));
3523   oldInfo = ue->info->uconst;
3524
3525   llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3526
3527   /*
3528   ** expanded macro is marked used (until I write a pre-processor)
3529   */
3530
3531   ue->ukind = KFCN;
3532   ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3533   ue->info->fcn->exitCode = XK_UNKNOWN;
3534   ue->info->fcn->nullPred = qual_createUnknown ();
3535   ue->info->fcn->specialCode = SPC_NONE;
3536   ue->info->fcn->access = typeIdSet_undefined;
3537   ue->info->fcn->hasGlobs = FALSE;
3538   ue->info->fcn->globs = globSet_undefined;
3539   ue->info->fcn->hasMods = FALSE;
3540   ue->info->fcn->mods = sRefSet_undefined;
3541   ue->info->fcn->specclauses = NULL;
3542   ue->info->fcn->defparams = uentryList_undefined;
3543
3544   /*drl*/
3545   ue->info->fcn->preconditions = functionConstraint_undefined;
3546   /*end */
3547
3548   /*drl 12/28/2000*/
3549   ue->info->fcn->postconditions = functionConstraint_undefined;
3550   /*end */
3551
3552   
3553   if (ctype_isFunction (ue->utype))
3554     {
3555       ue->sref = sRef_makeType (ctype_getReturnType (ue->utype)); 
3556     }
3557   else
3558     {
3559       ue->sref = sRef_makeType (ctype_unknown); 
3560     }
3561
3562   if (sRef_isRefCounted (ue->sref))
3563     {
3564       ak = AK_NEWREF;
3565     }
3566   else
3567     {
3568       if (alkind_isUnknown (ak))
3569         {
3570           if (exkind_isKnown (ek))
3571             {
3572               DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3573               ak = AK_IMPDEPENDENT;
3574             }
3575           else 
3576             {
3577               if (context_getFlag (FLG_RETIMPONLY))
3578                 {
3579                   if (ctype_isFunction (ue->utype)
3580                       && ctype_isVisiblySharable 
3581                       (ctype_realType (ctype_getReturnType (ue->utype))))
3582                     {
3583                       if (uentryList_hasReturned (uentry_getParams (ue)))
3584                         {
3585                           ;
3586                         }
3587                       else
3588                         {
3589                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
3590                             {
3591                               ;
3592                             }
3593                           else 
3594                             {
3595                               ak = AK_IMPONLY;
3596                             }
3597                         }
3598                     }
3599                 }
3600             }
3601         }
3602     }
3603
3604   loc = ue->whereDeclared;
3605
3606   sRef_setAliasKind (ue->sref, ak, loc);
3607   sRef_setExKind (ue->sref, ek, loc);
3608
3609   fileloc_free (ue->whereDefined);
3610   ue->whereDefined = fileloc_undefined;
3611   ucinfo_free (oldInfo);
3612 }
3613
3614 void
3615 uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
3616 {
3617   llassert (uentry_isValid (ue));
3618
3619   globSet_markImmutable (globs);
3620
3621   if (uentry_isIter (ue))
3622     {
3623       ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
3624     }
3625   else
3626     {
3627       uentry_convertVarFunction (ue);
3628       llassert (uentry_isFunction (ue));
3629
3630       ue->info->fcn->hasGlobs = TRUE;
3631       ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
3632     }
3633
3634   if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3635     {
3636       ue->info->fcn->hasMods = TRUE;
3637     }
3638 }
3639
3640 void uentry_addAccessType (uentry ue, typeId tid)
3641 {
3642   if (uentry_isFunction (ue))
3643     {
3644       ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3645     }
3646   else if (uentry_isEitherConstant (ue))
3647     {
3648       ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3649     }
3650   else if (uentry_isIter (ue))
3651     {
3652       ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3653     }
3654   else if (uentry_isEndIter (ue))
3655     {
3656       ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3657     }
3658   else
3659     {
3660       llbug (message ("no access for: %q", uentry_unparse (ue)));
3661     }
3662 }
3663
3664 /*@only@*/ /*@notnull@*/ uentry 
3665   uentry_makeFunction (cstring n, ctype t, 
3666                        typeId access, 
3667                        /*@only@*/ globSet globs, /*@only@*/ sRefSet mods, 
3668                        /*@only@*/ warnClause warn,
3669                        fileloc f)
3670 {
3671   llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3672   return (uentry_makeFunctionAux (n, t, 
3673                                   ((typeId_isInvalid (access)) ? typeIdSet_emptySet () 
3674                                    : typeIdSet_single (access)),
3675                                   globs, mods, warn,
3676                                   f,
3677                                   FALSE, FALSE));
3678 }
3679
3680 /*@notnull@*/ uentry 
3681   uentry_makePrivFunction2 (cstring n, ctype t, 
3682                             typeIdSet access, 
3683                             globSet globs, sRefSet mods, 
3684                             fileloc f)
3685 {
3686   return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3687                                   f, TRUE, FALSE));
3688 }
3689
3690
3691 /*@notnull@*/ uentry 
3692   uentry_makeSpecFunction (cstring n, ctype t, 
3693                            typeIdSet access,
3694                            /*@only@*/ globSet globs, 
3695                            /*@only@*/ sRefSet mods, 
3696                            fileloc f)
3697 {
3698   uentry ue = uentry_makeFunctionAux (n, t, access, 
3699                                       globs, mods, warnClause_undefined, 
3700                                       f, FALSE, FALSE);
3701
3702   uentry_setHasGlobs (ue);
3703   uentry_setHasMods (ue);
3704
3705   reflectImplicitFunctionQualifiers (ue, TRUE);
3706   return (ue);
3707 }
3708
3709 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3710 {
3711   uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined, 
3712                                       sRef_undefined, FALSE, VKEXPMACRO);
3713
3714   uentry_setDefined (ue, f);
3715   return ue;
3716 }
3717
3718 /*@notnull@*/ /*@notnull@*/ uentry 
3719   uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3720 {
3721   uentry ue = uentry_makeFunctionAux (n, ctype_unknown, 
3722                                       typeIdSet_singleOpt (access),
3723                                       globSet_undefined, sRefSet_undefined, 
3724                                       warnClause_undefined,
3725                                       fileloc_undefined,
3726                                       FALSE, TRUE);
3727
3728   ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3729   return ue;
3730 }
3731
3732 bool uentry_isForward (uentry e)
3733 {
3734   if (uentry_isValid (e))
3735     {
3736       ctype ct = uentry_getType (e);
3737
3738       return (ctype_isUnknown (ct)
3739               || (ctype_isFunction (ct)
3740                   && ctype_isUnknown (ctype_getReturnType (ct))));
3741     }
3742
3743   return FALSE;
3744 }
3745
3746 /*@notnull@*/ uentry 
3747 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3748 {
3749   return (uentry_makeFunctionAux (n, ctype_unknown, access,
3750                                   globSet_undefined, sRefSet_undefined, warnClause_undefined,
3751                                   f,FALSE, TRUE));
3752 }
3753
3754 /*@notnull@*/ uentry 
3755 uentry_makeUnspecFunction (cstring n, ctype t, 
3756                            typeIdSet access, 
3757                            fileloc f)
3758 {
3759   uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3760                                       sRefSet_undefined, warnClause_undefined,
3761                                       f, FALSE, TRUE);
3762
3763   reflectImplicitFunctionQualifiers (ue, TRUE);
3764   return ue;
3765 }
3766
3767 /*
3768 ** datatypes
3769 */
3770
3771 /* is exported for use by usymtab_interface */
3772
3773 /*@notnull@*/ uentry 
3774   uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract, 
3775                           fileloc f, bool priv)
3776 {
3777   uentry e = uentry_alloc ();
3778
3779   DPRINTF (("Make datatype: %s / %s",
3780             n, ctype_unparse (t)));
3781
3782   /* e->shallowCopy = FALSE; */
3783   e->ukind = KDATATYPE;
3784   e->uname = cstring_copy (n);
3785   e->utype = t;
3786   e->storageclass = SCNONE;
3787   e->sref  = sRef_makeUnknown ();
3788
3789   if (ctype_isUA (t))
3790     {
3791       sRef_setStateFromType (e->sref, t);
3792     }
3793
3794   uentry_setSpecDef (e, f);
3795
3796   e->warn = warnClause_undefined; /*@i634@*/ 
3797   e->uses = filelocList_new ();
3798   e->isPrivate = priv;
3799   e->hasNameError = FALSE;
3800
3801   e->used = FALSE;
3802   e->lset = FALSE;
3803
3804   e->info = (uinfo) dmalloc (sizeof (*e->info));
3805   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3806   e->info->datatype->abs = abstract;
3807   e->info->datatype->mut = mut;
3808   e->info->datatype->type = ctype_undefined;
3809
3810   if (uentry_isDeclared (e))
3811     {
3812       uentry_setDefined (e, f);
3813     }
3814
3815   if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3816     {
3817       sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3818     }
3819
3820   return (e);
3821 }
3822
3823 /*@notnull@*/ uentry
3824   uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3825 {
3826   return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3827 }
3828
3829 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3830 {
3831   uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3832                                        ctype_bool, NO, abstract, 
3833                                        fileloc_getBuiltin (),
3834                                        FALSE);
3835   
3836   ret->info->datatype->type = ctype_bool;
3837   return ret;
3838 }
3839
3840 /*
3841 ** iters
3842 */
3843
3844 static /*@only@*/ /*@notnull@*/ uentry 
3845   uentry_makeIterAux (cstring n, typeIdSet access, ctype ct, 
3846                       /*@only@*/ fileloc f)
3847 {
3848   uentry e = uentry_alloc ();
3849
3850   e->ukind = KITER;
3851   e->uname = cstring_copy (n);
3852   e->utype = ct;
3853   e->sref  = sRef_makeUnknown ();
3854   e->storageclass = SCNONE;
3855   e->used = FALSE;
3856   e->lset = FALSE;
3857
3858   uentry_setSpecDef (e, f);
3859
3860   e->warn = warnClause_undefined; /*@i452@*/
3861   e->uses = filelocList_new ();
3862   e->isPrivate = FALSE;
3863   e->hasNameError = FALSE;
3864
3865   e->info = (uinfo) dmalloc (sizeof (*e->info));
3866   e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3867   e->info->iter->access = access;
3868   e->info->iter->mods = sRefSet_undefined;
3869   e->info->iter->globs = globSet_undefined;
3870
3871   uentry_checkIterArgs (e);
3872   return (e);
3873 }
3874
3875 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3876 {
3877   return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3878 }
3879
3880 static /*@notnull@*/ uentry
3881 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3882 {
3883   uentry e = uentry_alloc ();
3884
3885   /* e->shallowCopy = FALSE; */
3886   e->ukind = KENDITER;
3887   e->storageclass = SCNONE;
3888   e->uname = message ("end_%s", n);
3889   e->utype = ctype_unknown;
3890   e->sref  = sRef_makeUnknown ();
3891
3892   uentry_setSpecDef (e, f);
3893
3894   e->used = FALSE;
3895   e->lset = FALSE;
3896
3897   e->uses = filelocList_new ();
3898   e->isPrivate = FALSE;
3899   e->hasNameError = FALSE;
3900
3901   e->info = (uinfo) dmalloc (sizeof (*e->info));
3902   e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3903
3904   e->info->enditer->access = access;
3905
3906   e->warn = warnClause_undefined; /*@i452@*/
3907   return (e);
3908 }
3909
3910 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3911 {
3912   return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3913 }
3914
3915 /*
3916 ** tags
3917 */
3918
3919 static /*@only@*/ /*@notnull@*/ uentry 
3920   uentry_makeTagAux (cstring n, ctype t, 
3921                      /*@only@*/ fileloc fl, 
3922                      bool priv, ekind kind)
3923 {
3924   uentry e = uentry_alloc ();
3925   
3926   if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3927     {
3928       llbuglit ("uentry_makeTagAux: not a tag type");
3929     }
3930   
3931   e->ukind = kind;
3932   /* e->shallowCopy = FALSE; */
3933   e->uname = cstring_copy (n);
3934
3935   e->utype = t;
3936   e->sref  = sRef_makeUnknown ();
3937   e->storageclass = SCNONE;
3938
3939   uentry_setSpecDef (e, fl);
3940   
3941   e->used = FALSE;
3942   e->lset = FALSE;
3943
3944   e->uses = filelocList_new ();
3945   e->isPrivate = priv;
3946   e->hasNameError = FALSE;
3947
3948   e->info = (uinfo) dmalloc (sizeof (*e->info));
3949   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3950   e->info->datatype->abs = NO;
3951   e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3952   e->info->datatype->type = t;
3953   e->warn = warnClause_undefined; /*@i452@*/
3954
3955   if (uentry_isDeclared (e))
3956     {
3957       uentry_setDefined (e, fl);
3958     }
3959
3960   return (e);  
3961 }
3962
3963 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3964 {
3965   cstring sname = makeStruct (n);
3966   uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3967
3968   cstring_free (sname);
3969   return (ret);
3970 }
3971
3972 /*@only@*/ uentry
3973 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3974 {
3975   cstring sname = makeStruct (n);
3976   uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3977
3978   cstring_free (sname);
3979   return ret;
3980 }
3981
3982 /*@only@*/ uentry
3983 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3984 {
3985   cstring uname = makeUnion (n);
3986   uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3987
3988   cstring_free (uname);
3989   return (ret);
3990 }
3991
3992 uentry
3993 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3994 {
3995   cstring ename = makeEnum (n);
3996   uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3997
3998   cstring_free (ename);
3999   return ret;
4000 }
4001
4002 uentry
4003 uentry_makeUnionTagLoc (cstring n, ctype t)
4004 {
4005   cstring uname = makeUnion (n);
4006   uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4007
4008   cstring_free (uname);
4009   return ret;
4010 }
4011
4012 uentry
4013 uentry_makeEnumTagLoc (cstring n, ctype t)
4014 {
4015   cstring ename = makeEnum (n);
4016   uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4017
4018   cstring_free (ename);
4019   return ret;
4020 }
4021
4022 bool 
4023 uentry_isStructTag (uentry ue) 
4024 {
4025   return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4026 }
4027
4028 bool 
4029 uentry_isUnionTag (uentry ue) 
4030 {
4031   return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4032 }
4033
4034 bool 
4035 uentry_isEnumTag (uentry ue) 
4036 {
4037   return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4038 }
4039
4040 bool
4041 uentry_isAnyTag (uentry ue)
4042 {
4043   return (uentry_isStructTag (ue) 
4044           || uentry_isUnionTag (ue)
4045           || uentry_isEnumTag (ue));
4046 }
4047
4048 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4049
4050 extern void uentry_destroyMod (void)
4051    /*@globals killed emarker@*/ /*@modifies emarker@*/
4052 {
4053   static bool wasDestroyed = FALSE;
4054
4055   llassert (!wasDestroyed);
4056
4057   if (emarker != NULL)
4058     {
4059       uentry_reallyFree (emarker);
4060     }
4061
4062   wasDestroyed = TRUE;
4063 }
4064
4065 uentry
4066 uentry_makeElipsisMarker (void)
4067 {
4068   if (emarker == NULL)
4069     {
4070       emarker = uentry_alloc ();
4071
4072       emarker->ukind = KELIPSMARKER;
4073       emarker->uname = cstring_makeLiteral ("...");
4074       emarker->utype = ctype_elipsMarker;
4075       emarker->sref  = sRef_undefined;
4076       emarker->storageclass = SCNONE;
4077       emarker->used = FALSE;
4078       emarker->lset = FALSE;
4079       emarker->info = NULL;
4080
4081       uentry_setSpecDef (emarker, fileloc_undefined);
4082       emarker->uses = filelocList_new ();
4083       emarker->isPrivate = FALSE;
4084       emarker->hasNameError = FALSE;
4085     }
4086
4087   /*@ignore@*/ return (emarker); /*@end@*/
4088
4089
4090 /*
4091 ** comparisons
4092 */
4093
4094 bool
4095 uentry_equiv (uentry p1, uentry p2)
4096 {
4097   if (uentry_compare (p1, p2) != 0)
4098     {
4099       return FALSE;
4100     }
4101   else
4102     {
4103       return TRUE;
4104     }
4105 }
4106
4107 int
4108 uentry_xcomparealpha (uentry *p1, uentry *p2)
4109 {
4110   int res;
4111
4112   if ((res = uentry_compare (*p1, *p2)) == 0) {
4113     if ((*p1 != NULL) && (*p2 != NULL)) {
4114       res = cstring_compare ((*p1)->uname,
4115                              (*p2)->uname);
4116     }
4117   }
4118
4119   return res;
4120 }
4121
4122 int
4123 uentry_xcompareuses (uentry *p1, uentry *p2)
4124 {
4125   uentry u1 = *p1;
4126   uentry u2 = *p2;
4127
4128   if (uentry_isValid (u1))
4129     {
4130       if (uentry_isValid (u2))
4131         {
4132           return (-1 * int_compare (filelocList_size (u1->uses), 
4133                                     filelocList_size (u2->uses)));
4134         }
4135       else
4136         {
4137           return 1;
4138         }
4139     }
4140   else
4141     {
4142       if (uentry_isValid (u2))
4143         {
4144           return -1;
4145         }
4146       else
4147         {
4148           return 0;
4149         }
4150     }
4151 }
4152
4153 int 
4154 uentry_compareStrict (uentry v1, uentry v2)
4155 {
4156   COMPARERETURN (uentry_compare (v1, v2));
4157
4158   if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4159     {
4160       COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4161       COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4162       COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4163     }
4164
4165   return 0;
4166 }
4167
4168 int
4169 uentry_compare (uentry u1, uentry u2)
4170 {
4171   if (u1 == u2) return 0;
4172   
4173   if (uentry_isInvalid (u1)) return -1;
4174   if (uentry_isInvalid (u2)) return 1;
4175
4176   INTCOMPARERETURN (u1->ukind, u2->ukind);
4177   COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4178   COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4179   COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4180
4181   switch (u1->ukind)
4182     {
4183     case KINVALID:
4184     case KELIPSMARKER:
4185       /* bug detected by splint:  
4186       ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE 
4187       */
4188       return 0;
4189     case KENUMCONST:
4190     case KCONST:
4191       return (multiVal_compare (uentry_getConstantValue (u1),
4192                                 uentry_getConstantValue (u2)));
4193     case KSTRUCTTAG: 
4194     case KUNIONTAG: 
4195     case KENUMTAG: 
4196       return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4197     case KITER:
4198       COMPARERETURN (typeIdSet_compare (uentry_accessType (u1), 
4199                                          uentry_accessType (u2)));
4200       return (uentryList_compareParams (uentry_getParams (u1), 
4201                                         uentry_getParams (u2)));
4202     case KENDITER:
4203       return (typeIdSet_compare (uentry_accessType (u1), 
4204                                   uentry_accessType (u2)));
4205     case KFCN:
4206       /*
4207       ** Functions are never equivalent
4208       */
4209       
4210       if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4211         {
4212           return -1;
4213         }
4214       else
4215         {
4216           return 1;
4217         }
4218     case KVAR:
4219       
4220       COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4221       COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4222                                       sRef_getOrigAliasKind (u2->sref)));
4223       COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4224                                       sRef_getOrigExKind (u2->sref)));
4225       COMPARERETURN (generic_compare (u1->info->var->checked,
4226                                       u2->info->var->checked));
4227       COMPARERETURN (generic_compare (u1->info->var->defstate, 
4228                                       u2->info->var->defstate));
4229       return        (generic_compare (u1->info->var->nullstate, 
4230                                       u2->info->var->nullstate));
4231     case KDATATYPE:
4232       COMPARERETURN (ctype_compare (u1->info->datatype->type,
4233                                     u2->info->datatype->type));
4234       COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4235                                   u2->info->datatype->mut));
4236       return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4237     }
4238   
4239   BADEXIT;
4240 }
4241
4242 /*
4243 ** library format:
4244 **
4245 ** all entries are: <type>[@<info>]*#<name>
4246 **
4247 ** info depends on kind:
4248 */
4249
4250 static void
4251 advanceField (char **s)
4252 {
4253   reader_checkChar (s, '@');
4254 }
4255
4256 static void
4257 advanceName (char **s)
4258 {
4259   reader_checkChar (s, '#');
4260 }
4261
4262 static vkind
4263 vkind_fromInt (int i)
4264 {
4265   if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4266     {
4267       llbuglit ("vkind_fromInt: out of range");
4268     }
4269
4270   return (vkind)i;
4271 }
4272
4273 static uentry  
4274   uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct, 
4275                            typeIdSet access, nstate nullstate,
4276                            /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4277 {
4278   uentry e = uentry_alloc ();
4279   
4280   e->ukind = KCONST;
4281   e->uname = name;
4282   e->utype = ct;
4283   e->sref  = sRef_makeConst (ct);
4284
4285   sRef_setNullState (e->sref, nullstate, loc);
4286   e->storageclass = SCNONE;
4287
4288   if (fileloc_isSpec (loc))
4289     {
4290       e->whereSpecified = loc;
4291       e->whereDeclared = fileloc_undefined;
4292     }
4293   else
4294     {
4295       e->whereSpecified = fileloc_undefined;
4296       e->whereDeclared = loc;
4297     }
4298
4299   e->whereDefined = fileloc_undefined;
4300   e->uses = filelocList_new ();
4301   e->isPrivate = FALSE;
4302   e->hasNameError = FALSE;
4303
4304   e->used = FALSE;
4305   e->lset = FALSE;
4306
4307   e->warn = warnClause_undefined; /*@i452@*/
4308
4309   e->info = (uinfo) dmalloc (sizeof (*e->info));
4310   e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4311   e->info->uconst->access = access;
4312   e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4313   uentry_setConstantValue (e, m);
4314   sRef_storeState (e->sref);
4315
4316   return (e);
4317 }
4318
4319 static /*@only@*/ uentry  
4320   uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind, 
4321                            sstate defstate, nstate isnull, alkind aliased,
4322                            exkind exp, chkind checked, 
4323                            /*@only@*/ fileloc loc)
4324 {
4325   uentry e = uentry_alloc ();
4326
4327   e->ukind = KVAR;
4328   e->uname = name;
4329   e->utype = ct;
4330   e->storageclass = SCNONE;
4331
4332   e->sref  = sRef_makeType (ct);
4333   sRef_setNullState (e->sref, isnull, loc);
4334
4335   e->whereDefined = fileloc_undefined;
4336
4337   if (fileloc_isSpec (loc))
4338     {
4339       e->whereSpecified = loc;
4340       e->whereDeclared = fileloc_undefined;
4341     }
4342   else
4343     {
4344       e->whereSpecified = fileloc_undefined;
4345       e->whereDeclared = loc;
4346     }
4347
4348   e->isPrivate = FALSE;
4349   e->hasNameError = FALSE;
4350
4351   e->used = FALSE;
4352   e->lset = FALSE;
4353
4354   e->uses = filelocList_new ();
4355   e->warn = warnClause_undefined; /*@i452@*/
4356
4357   e->info = (uinfo) dmalloc (sizeof (*e->info));
4358   e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4359   e->info->var->kind = kind;
4360   e->info->var->checked = checked;
4361   e->info->var->defstate = defstate;
4362
4363   sRef_setDefState (e->sref, defstate, loc);
4364
4365   e->info->var->nullstate = sRef_getNullState (e->sref);
4366
4367   sRef_setExKind (e->sref, exp, loc);
4368   sRef_setAliasKind (e->sref, aliased, loc);
4369
4370   sRef_storeState (e->sref);
4371
4372   /*DRL ADDED 9-1-2000 */
4373   e->info->var->bufinfo = NULL;
4374   
4375   return (e);
4376 }
4377
4378 static /*@only@*/ uentry  
4379 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract, 
4380                          ynm mut, ctype rtype, alkind ak, exkind exp, 
4381                          sstate defstate, nstate isnull,
4382                          /*@only@*/ fileloc loc)
4383 {
4384   uentry e = uentry_alloc ();
4385
4386   e->ukind = KDATATYPE;
4387   /* e->shallowCopy = FALSE; */
4388   e->uname = name;
4389   e->utype = ct;
4390   e->storageclass = SCNONE;
4391   e->sref  = sRef_makeUnknown ();
4392   DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4393
4394   /*
4395   ** This is only setting null state.  (I think?)
4396   */
4397
4398   if (ctype_isUA (ct))
4399     {
4400       uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4401
4402       if (uentry_isValid (te))
4403         {
4404           sRef_setStateFromUentry (e->sref, te);
4405         }
4406       else
4407         {
4408           /* problem for recursive type definitions */
4409         }
4410     }
4411   
4412   sRef_setAliasKind (e->sref, ak, loc);
4413   sRef_setExKind (e->sref, exp, loc);
4414
4415   sRef_setDefState (e->sref, defstate, loc);
4416
4417   if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4418     {
4419       isnull = NS_ABSNULL;
4420     }
4421
4422   DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4423   sRef_mergeNullState (e->sref, isnull);
4424
4425   e->whereDefined = fileloc_copy (loc); /*< bogus!  (but necessary for lexer) >*/
4426
4427   if (fileloc_isSpec (loc))
4428     {
4429       e->whereSpecified = loc;
4430       e->whereDeclared = fileloc_undefined;
4431     }
4432   else
4433     {
4434       e->whereSpecified = fileloc_undefined;
4435       e->whereDeclared = loc;
4436     }
4437   
4438   e->isPrivate = FALSE;
4439   e->hasNameError = FALSE;
4440
4441   e->warn = warnClause_undefined; /*@i452@*/
4442
4443   e->used = FALSE;
4444   e->lset = FALSE;
4445   e->uses = filelocList_new ();
4446
4447   e->info = (uinfo) dmalloc (sizeof (*e->info));
4448   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4449   e->info->datatype->abs = abstract;
4450   e->info->datatype->mut = mut;
4451   e->info->datatype->type = rtype;
4452
4453   DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4454   sRef_storeState (e->sref);
4455   DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4456
4457   return (e);
4458 }
4459
4460 static void uentry_setHasGlobs (uentry ue)
4461 {
4462   llassert (uentry_isFunction (ue));
4463
4464   ue->info->fcn->hasGlobs = TRUE;
4465 }
4466
4467 static void uentry_setHasMods (uentry ue)
4468 {
4469   llassert (uentry_isFunction (ue));
4470
4471   ue->info->fcn->hasMods = TRUE;
4472 }
4473
4474 bool uentry_hasGlobs (uentry ue)
4475 {
4476   if (uentry_isFunction (ue))
4477     {
4478       return (ue->info->fcn->hasGlobs);
4479     }
4480
4481   return FALSE;
4482 }
4483
4484 bool uentry_hasStateClauseList (uentry ue)
4485 {
4486   return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4487 }
4488
4489 bool uentry_hasConditions (uentry ue)
4490 {
4491   return (uentry_isFunction (ue) 
4492           && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4493               || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4494 }
4495
4496 stateClauseList uentry_getStateClauseList (uentry ue)
4497 {
4498   if (!uentry_isFunction (ue))
4499     {
4500       llassert (uentry_isFunction (ue));
4501       return stateClauseList_undefined;
4502     }
4503
4504   DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4505   return ue->info->fcn->specclauses;
4506 }
4507
4508 bool uentry_hasMods (uentry ue)
4509 {
4510   if (uentry_isFunction (ue))
4511     {
4512       return (ue->info->fcn->hasMods);
4513     }
4514
4515   return FALSE;
4516 }
4517
4518 static uentry  
4519   uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct, 
4520                            typeIdSet access, 
4521                            bool hasGlobs, /*@only@*/ globSet globs, 
4522                            bool hasMods, /*@only@*/ sRefSet mods, 
4523                            alkind ak, exkind exp, 
4524                            sstate defstate, nstate isnull,
4525                            exitkind exitCode,
4526                            specCode sCode,
4527                            qual nullPred,
4528                            /*@only@*/ stateClauseList specclauses,
4529                            /*@only@*/ warnClause warnclause,
4530                            /*@only@*/ fileloc loc)
4531 {
4532   uentry e = uentry_alloc ();
4533   ctype ret;
4534
4535   /* e->shallowCopy = FALSE; */
4536   e->ukind = KFCN;
4537   e->uname = name;
4538   e->utype = ct;
4539   e->storageclass = SCNONE;
4540
4541   if (ctype_isFunction (ct))
4542     {
4543       ret = ctype_getReturnType (ct);
4544     }
4545   else
4546     {
4547       if (ctype_isKnown (ct))
4548         {
4549           llbug (message ("not function: %s", ctype_unparse (ct)));
4550         }
4551
4552       ret = ctype_unknown;
4553     }
4554
4555   e->sref  = sRef_makeType (ret);
4556
4557   if (ctype_isUA (ret))
4558     {
4559       sRef_setStateFromType (e->sref, ret);
4560     }
4561
4562   sRef_setDefined (e->sref, loc);
4563   sRef_setNullState (e->sref, isnull, loc);
4564
4565   sRef_setAliasKind (e->sref, ak, loc);
4566   sRef_setExKind (e->sref, exp, loc);
4567   sRef_setDefState (e->sref, defstate, loc);
4568
4569   e->whereSpecified = loc;
4570   e->whereDefined = fileloc_undefined;
4571
4572   e->isPrivate = FALSE;
4573   e->hasNameError = FALSE;
4574
4575   e->used = FALSE;
4576   e->lset = FALSE;
4577   e->uses = filelocList_new ();  
4578   e->warn = warnclause;
4579
4580   e->info = (uinfo) dmalloc (sizeof (*e->info));
4581   e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4582   
4583   e->info->fcn->exitCode = exitCode;
4584   e->info->fcn->specialCode = sCode;
4585   e->info->fcn->nullPred = nullPred;
4586   e->info->fcn->access = access;
4587
4588   e->info->fcn->specclauses = specclauses;
4589   e->info->fcn->hasGlobs = hasGlobs;
4590   e->info->fcn->globs = globs;
4591
4592   e->info->fcn->hasMods = hasMods;
4593   e->info->fcn->mods = mods;
4594
4595   e->info->fcn->defparams = uentryList_undefined; 
4596   e->whereDeclared = fileloc_undefined;
4597
4598   sRef_storeState (e->sref);
4599
4600   /*drl 111  30 2000*/
4601   e->info->fcn->preconditions = NULL;
4602     /* end drl */
4603
4604   /*drl 12  28 2000*/
4605   e->info->fcn->postconditions = NULL;
4606     /* end drl */
4607   
4608   return (e);
4609 }
4610
4611 static /*@only@*/ uentry  
4612   uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind, 
4613                       ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4614 {
4615   uentry e = uentry_alloc ();
4616   
4617   if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4618     {
4619       llbuglit ("uentry_makeTagBase: not a tag type");
4620     }
4621
4622   /* e->shallowCopy = FALSE; */
4623   e->ukind = tagkind;
4624   e->uname = name;
4625   e->utype = ct;
4626   e->sref  = sRef_makeUnknown ();
4627   e->storageclass = SCNONE;
4628
4629   if (fileloc_isSpec (loc))
4630     {
4631       e->whereSpecified = loc;
4632       e->whereDeclared = fileloc_undefined;
4633     }
4634   else
4635     {
4636       e->whereDeclared = loc;
4637       e->whereSpecified = fileloc_undefined;
4638     }
4639
4640   e->whereDefined = fileloc_undefined;
4641
4642   e->isPrivate = FALSE;
4643   e->hasNameError = FALSE;
4644
4645   e->used = FALSE;
4646   e->lset = FALSE;
4647   e->uses = filelocList_new ();
4648   e->warn = warnClause_undefined; /*@i452@*/
4649
4650   e->info = (uinfo) dmalloc (sizeof (*e->info));
4651   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4652   e->info->datatype->abs  = NO;
4653   e->info->datatype->mut  = MAYBE;
4654   e->info->datatype->type = rtype;
4655
4656   sRef_storeState (e->sref);
4657
4658   return (e);  
4659 }
4660
4661 static uentry  
4662   uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access, 
4663                        ctype ct, /*@only@*/ fileloc loc)
4664 {
4665   uentry e = uentry_alloc ();
4666   
4667   /* e->shallowCopy = FALSE; */
4668   e->ukind = KITER;
4669   e->uname = name;
4670   e->utype = ct;
4671   e->sref  = sRef_makeUnknown ();
4672   e->storageclass = SCNONE;
4673
4674   if (fileloc_isSpec (loc))
4675     {
4676       e->whereSpecified = loc;
4677       e->whereDeclared = fileloc_undefined;
4678     }
4679   else
4680     {
4681       e->whereDeclared = loc;
4682       e->whereSpecified = fileloc_undefined;
4683     }
4684
4685   e->whereDefined = fileloc_undefined;
4686   
4687   e->isPrivate = FALSE;
4688   e->hasNameError = FALSE;
4689
4690   e->used = FALSE;
4691   e->lset = FALSE;
4692   e->uses = filelocList_new ();
4693   e->warn = warnClause_undefined; /*@i452@*/
4694
4695   e->info = (uinfo) dmalloc (sizeof (*e->info));
4696   e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4697   e->info->iter->access = access;
4698   e->info->iter->mods = sRefSet_undefined;
4699   e->info->iter->globs = globSet_undefined;
4700   
4701   sRef_storeState (e->sref);
4702   return (e);
4703 }
4704
4705 static uentry  
4706   uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access, 
4707                           /*@only@*/ fileloc loc)
4708 {
4709   uentry e = uentry_alloc ();
4710
4711   /* e->shallowCopy = FALSE; */
4712   e->ukind = KENDITER;
4713   e->storageclass = SCNONE;
4714   e->uname = name;
4715   e->utype = ctype_unknown;
4716   e->sref  = sRef_makeUnknown ();
4717   
4718   if (fileloc_isSpec (loc))
4719     {
4720       e->whereSpecified = loc;
4721       e->whereDeclared = fileloc_undefined;
4722     }
4723   else
4724     {
4725       e->whereDeclared = loc;
4726       e->whereSpecified = fileloc_undefined;
4727     }
4728
4729   e->whereDefined = fileloc_undefined;
4730
4731   e->isPrivate = FALSE;
4732   e->hasNameError = FALSE;
4733
4734   e->used = FALSE;
4735   e->lset = FALSE;
4736   e->uses = filelocList_new ();
4737   e->warn = warnClause_undefined; /*@i452@*/
4738
4739   e->info = (uinfo) dmalloc (sizeof (*e->info));
4740   e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4741   e->info->enditer->access = access;
4742   sRef_storeState (e->sref);
4743
4744   return (e);
4745 }
4746
4747 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4748 {
4749   /* should save u */
4750 /*@-mustfree@*/
4751 }
4752 /*@=mustfree@*/
4753
4754 /*@only@*/ uentry
4755 uentry_undump (ekind kind, fileloc loc, char **s)
4756 {
4757   uentry ue;
4758   
4759   DPRINTF (("Uentry undump: %s", *s));
4760
4761   if (**s == '!')
4762     {
4763       reader_checkChar (s, '!');
4764       reader_checkChar (s, '.');
4765       ue = uentry_makeElipsisMarker ();
4766     }
4767   else
4768     {
4769       ctype ct = ctype_undump (s);
4770       cstring name;
4771
4772       switch (kind)
4773         {
4774         case KVAR:
4775           {
4776             vkind  tkind;
4777             sstate defstate;
4778             nstate isnull;
4779             alkind aliased;
4780             exkind exp;
4781             chkind checked;
4782             
4783             reader_checkChar (s, '|');
4784
4785             if (reader_optCheckChar (s, '@'))
4786               {
4787                 tkind = vkind_fromInt (reader_getInt (s));
4788                 reader_checkChar (s, '|');
4789               }
4790             else
4791               {
4792                 tkind = VKPARAM;
4793               }
4794
4795             if (reader_optCheckChar (s, '$'))
4796               {
4797                 defstate = SS_UNKNOWN;
4798                 isnull = NS_UNKNOWN;
4799                 aliased = AK_IMPTEMP;
4800                 exp = XO_UNKNOWN;
4801                 checked = CH_UNKNOWN;
4802               }         
4803             else if (reader_optCheckChar (s, '&'))
4804               {
4805                 defstate = SS_DEFINED;
4806                 isnull = NS_UNKNOWN;
4807                 aliased = AK_IMPTEMP;
4808                 exp = XO_UNKNOWN;
4809                 checked = CH_UNKNOWN;
4810               }         
4811             else if (reader_optCheckChar (s, '^'))
4812               {
4813                 defstate = SS_UNKNOWN;
4814                 isnull = NS_UNKNOWN;
4815                 aliased = AK_IMPTEMP;
4816                 exp = XO_UNKNOWN;
4817                 checked = CH_UNKNOWN;
4818               }         
4819             else
4820               {
4821                 defstate = sstate_fromInt (reader_getInt (s));      
4822                 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));      
4823                 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));      
4824
4825                 if (reader_optCheckChar (s, '&'))
4826                   {
4827                     exp = XO_UNKNOWN;
4828                     checked = CH_UNKNOWN;
4829                   }
4830                 else
4831                   {
4832                     advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4833                     advanceField (s); checked = (chkind) (reader_getInt (s));      
4834                   }
4835               }
4836
4837             advanceName (s);
4838             name = reader_getStringWord (s);
4839             
4840             llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4841
4842             ue = uentry_makeVariableBase (name, ct, tkind, defstate, 
4843                                           isnull, aliased, exp, 
4844                                           checked, fileloc_copy (loc));
4845           }
4846           break;
4847         case KDATATYPE: 
4848           {
4849             ynm abstract;
4850             ynm mut;
4851             ctype rtype;
4852             sstate defstate;
4853             nstate isnull;
4854             alkind aliased;
4855             exkind exp;
4856
4857             advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4858             advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4859             advanceField (s); defstate = sstate_fromInt (reader_getInt (s));      
4860             advanceField (s); isnull = nstate_fromInt (reader_getInt (s));      
4861             advanceField (s); aliased = alkind_fromInt (reader_getInt (s));      
4862             advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4863             advanceField (s); rtype = ctype_undump (s);
4864             advanceName (s); 
4865             name = reader_getStringWord (s);
4866             DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4867             ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype, 
4868                                           aliased, exp, defstate, isnull, 
4869                                           fileloc_copy (loc));
4870           }
4871           break;
4872         case KFCN:
4873           {
4874             alkind     ak;
4875             exkind     exp;
4876             sstate     defstate;
4877             nstate     isnull;
4878             exitkind   exitCode;
4879             specCode   specc;
4880             qual       nullPred;
4881             typeIdSet access;
4882             bool       hasGlobs;
4883             globSet    globs;
4884             bool       hasMods;
4885             sRefSet    mods;
4886             stateClauseList specclauses = stateClauseList_undefined;
4887             warnClause warnclause = warnClause_undefined;
4888
4889             if (reader_optCheckChar (s, '$'))
4890               {
4891                 defstate = SS_DEFINED;
4892                 isnull = NS_UNKNOWN;
4893                 exitCode = XK_UNKNOWN;
4894                 specc = SPC_NONE;
4895                 nullPred = qual_createUnknown ();
4896               }
4897             else
4898               {
4899                 advanceField (s); defstate = sstate_fromInt (reader_getInt (s)); 
4900                 advanceField (s); isnull = nstate_fromInt (reader_getInt (s)); 
4901                 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s)); 
4902                 advanceField (s); specc = specCode_fromInt (reader_getInt (s)); 
4903                 advanceField (s); nullPred = qual_undump (s);
4904               }
4905
4906             if (reader_optCheckChar (s, '$'))
4907               {
4908                 hasGlobs = FALSE;
4909                 globs = globSet_undefined;
4910                 hasMods = FALSE;
4911                 mods = sRefSet_undefined;
4912               }
4913             else if (reader_optCheckChar (s, '^'))
4914               {
4915                 hasGlobs = TRUE;
4916                 globs = globSet_undefined;
4917                 hasMods = TRUE;
4918                 mods = sRefSet_undefined;
4919               }
4920             else
4921               {
4922                 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4923                 advanceField (s); globs  = globSet_undump (s);
4924                 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4925                 advanceField (s); mods   = sRefSet_undump (s);      
4926               }
4927
4928             if (reader_optCheckChar (s, '$'))
4929               {
4930                 ak = AK_UNKNOWN;
4931                 exp = XO_UNKNOWN;
4932               }
4933             else
4934               {
4935                 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4936                 advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4937               }
4938
4939             advanceField (s); access = typeIdSet_undump (s);
4940
4941             /*
4942             ** Optional clauses: Start with @<code>:
4943             */
4944
4945             while (reader_optCheckChar (s, '@'))
4946               {
4947                 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4948                   {
4949                     reader_checkChar (s, ':');
4950                     warnclause = warnClause_undump (s);
4951                   }
4952                 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4953                   {
4954                     reader_checkChar (s, ':');
4955                     specclauses = stateClauseList_undump (s);
4956                   }
4957                 else
4958                   {
4959                     BADBRANCH;
4960                   }
4961               }
4962
4963             advanceName (s);  name = reader_getStringWord (s);
4964
4965             ue = uentry_makeFunctionBase (name, ct, access, 
4966                                           hasGlobs, globs, 
4967                                           hasMods, mods, 
4968                                           ak, exp, defstate, isnull, 
4969                                           exitCode, specc, nullPred,
4970                                           specclauses,
4971                                           warnclause,
4972                                           fileloc_copy (loc));
4973             DPRINTF (("Undump: %s", uentry_unparse (ue)));
4974           }
4975           break;
4976         case KITER:
4977           {
4978             typeIdSet access;
4979             
4980             advanceField (s); access = typeIdSet_undump (s);
4981             advanceName (s);  name = reader_getStringWord (s);
4982             
4983             ue = uentry_makeIterBase (name, access, ct,
4984                                       fileloc_copy (loc));
4985           }
4986           break;
4987         case KENDITER:
4988           {
4989             typeIdSet access;
4990
4991             advanceField (s); access = typeIdSet_undump (s);
4992             advanceName (s);  name = reader_getStringWord (s);
4993             
4994             ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4995           }
4996           break;
4997         case KENUMCONST:  
4998         case KCONST:  
4999           {
5000             typeIdSet access;
5001             multiVal val;
5002             nstate nullstate;
5003
5004             if (reader_optCheckChar (s, '$'))
5005               {
5006                 val = multiVal_undefined;
5007                 access = typeIdSet_undefined;
5008                 nullstate = NS_UNKNOWN;
5009               }
5010             else
5011               {
5012                 advanceField (s); val = multiVal_undump (s);
5013                 advanceField (s); access = typeIdSet_undump (s);
5014                 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5015               }
5016
5017             advanceName (s);  name = reader_getStringWord (s);
5018             
5019             ue = uentry_makeConstantBase (name, ct, access,
5020                                           nullstate, fileloc_copy (loc), val);
5021             break;
5022           }
5023         case KSTRUCTTAG:
5024         case KUNIONTAG:
5025         case KENUMTAG:
5026           {
5027             ctype rtype;
5028             
5029             advanceField (s); rtype = ctype_undump (s);
5030             advanceName (s);  name = reader_getStringWord (s);
5031             ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5032           }
5033           break;
5034         case KINVALID:
5035           llcontbuglit ("uentry_undump: invalid");
5036           ue = uentry_undefined;
5037           break;
5038         case KELIPSMARKER:
5039           llcontbuglit ("uentry_undump: elips marker");
5040           ue = uentry_undefined;
5041           break;
5042         }
5043     }
5044   
5045   return (ue);
5046 }
5047
5048 cstring
5049 uentry_dump (uentry v)
5050 {
5051   return (uentry_dumpAux (v, FALSE));
5052 }
5053
5054 cstring
5055 uentry_dumpParam (uentry v)
5056 {
5057   llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5058                  ("dump: %s", uentry_unparseFull (v)));
5059
5060   return (uentry_dumpAux (v, TRUE));
5061 }
5062
5063 static cstring
5064 uentry_dumpAux (uentry v, bool isParam)
5065 {
5066   llassert (uentry_isValid (v));
5067   llassert (!uentry_isGlobalMarker (v));
5068
5069   DPRINTF (("Dump uentry: [%p]", v));
5070   DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5071   
5072   switch (v->ukind)
5073     {
5074     case KINVALID: 
5075       llcontbuglit ("uentry_dump: invalid entry"); 
5076       return cstring_undefined;
5077     case KELIPSMARKER: 
5078       return (message ("!."));
5079     case KVAR:     
5080       {
5081         cstring sdump;
5082         vkind vk  = v->info->var->kind;
5083         sstate dss = sRef_getDefState (v->sref);
5084         nstate nst = sRef_getNullState (v->sref);
5085         alkind alk = sRef_getAliasKind (v->sref);
5086         exkind exk = sRef_getExKind (v->sref);
5087         chkind chk = v->info->var->checked;
5088
5089         DPRINTF (("Dumping var"));
5090
5091         if (dss == SS_UNKNOWN
5092             && nst == NS_UNKNOWN
5093             && alk == AK_IMPTEMP
5094             && exk == XO_UNKNOWN
5095             && chk == CH_UNKNOWN)
5096           {
5097             sdump = cstring_makeLiteral ("$");
5098           }
5099         else if (dss == SS_DEFINED
5100                  && nst == NS_UNKNOWN
5101                  && alk == AK_IMPTEMP
5102                  && exk == XO_UNKNOWN
5103                  && chk == CH_UNKNOWN)
5104           {
5105             sdump = cstring_makeLiteral ("&");
5106           }
5107         else if (dss == SS_UNKNOWN
5108                  && nst == NS_UNKNOWN
5109                  && alk == AK_UNKNOWN
5110                  && exk == XO_UNKNOWN
5111                  && chk == CH_UNKNOWN)
5112           {
5113             sdump = cstring_makeLiteral ("^");
5114           }
5115         else if (exk == XO_UNKNOWN
5116                  && chk == CH_UNKNOWN)
5117           {
5118             sdump = message ("%d@%d@%d&",
5119                              (int) dss,
5120                              (int) nst,
5121                              (int) alk);
5122           }
5123         else
5124           {
5125             sdump = message ("%d@%d@%d@%d@%d",  
5126                      (int) dss,
5127                              (int) nst,
5128                              (int) alk,
5129                              (int) exk,
5130                              (int) chk);
5131           }
5132         
5133
5134         if (vk != VKPARAM)
5135           {
5136             return (message ("%q|@%d|%q#%s", 
5137                              ctype_dump (v->utype), 
5138                              (int) vk,
5139                              sdump,
5140                              isParam ? cstring_undefined : v->uname));
5141           }
5142         else
5143           {
5144             return (message ("%q|%q#%s", 
5145                              ctype_dump (v->utype), 
5146                              sdump,
5147                              isParam ? cstring_undefined : v->uname));
5148           }
5149
5150       }
5151     case KDATATYPE: 
5152       /*
5153       DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5154                 uentry_unparse (v), 
5155                 exkind_unparse (sRef_getExKind (v->sref)),
5156                 ctype_unparse (v->utype), (int) v->utype));
5157       */
5158
5159       return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s", 
5160                        ctype_dump (v->utype),
5161                        ynm_unparseCode (v->info->datatype->abs),
5162                        ynm_unparseCode (v->info->datatype->mut),
5163                        (int) sRef_getDefState (v->sref),
5164                        (int) sRef_getNullState (v->sref),
5165                        (int) sRef_getAliasKind (v->sref),
5166                        (int) sRef_getExKind (v->sref),
5167                        ctype_dump (v->info->datatype->type),
5168                        v->uname));
5169     case KFCN:
5170       {
5171         cstring sdump, gdump, adump, xdump;
5172         alkind alk = sRef_getAliasKind (v->sref);
5173         exkind exk = sRef_getExKind (v->sref);
5174
5175         if (sRef_getDefState (v->sref) == SS_DEFINED
5176             && !nstate_isKnown (sRef_getNullState (v->sref))
5177             && !exitkind_isKnown (v->info->fcn->exitCode)
5178             && v->info->fcn->specialCode == SPC_NONE
5179             && qual_isUnknown (v->info->fcn->nullPred))
5180           {
5181             sdump = cstring_makeLiteral ("$");
5182           }
5183         else
5184           {
5185             sdump = message ("@%d@%d@%d@%d@%x",
5186                              (int) sRef_getDefState (v->sref),
5187                              (int) sRef_getNullState (v->sref),
5188                              (int) v->info->fcn->exitCode,
5189                              (int) v->info->fcn->specialCode,
5190                              qual_dump (v->info->fcn->nullPred));
5191           }
5192
5193         if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5194           {
5195             gdump = cstring_makeLiteral ("$");
5196           }
5197         else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5198                  && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5199           {
5200             gdump = cstring_makeLiteral ("^");
5201           }
5202         else
5203           {
5204             gdump = message ("@%s@%q@%s@%q",
5205                              bool_dump (uentry_hasGlobs (v)),
5206                              globSet_dump (uentry_getGlobs (v)),
5207                              bool_dump (uentry_hasMods (v)),
5208                              sRefSet_dump (uentry_getMods (v)));
5209           }
5210
5211         if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5212           {
5213             adump = cstring_makeLiteral ("$");
5214           }
5215         else
5216           {
5217             adump = message ("@%d@%d", (int) alk, (int) exk);
5218           }
5219
5220         xdump = cstring_undefined;
5221
5222         if (uentry_hasWarning (v))
5223           {
5224             xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5225           }
5226
5227         if (uentry_hasStateClauseList (v))
5228           {
5229             xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5230           }
5231
5232         return (message ("%q%q%q%q@%q%q#%s",
5233                          ctype_dump (v->utype),
5234                          sdump,
5235                          gdump,
5236                          adump,
5237                          typeIdSet_dump (uentry_accessType (v)),
5238                          xdump,
5239                          v->uname));
5240       }
5241     case KITER:
5242       return (message ("%q@%q#%s",
5243                        ctype_dump (v->utype),
5244                        typeIdSet_dump (v->info->iter->access),
5245                        v->uname));
5246     case KENDITER:
5247       return (message ("%q@%q#%s",
5248                        ctype_dump (v->utype),
5249                        typeIdSet_dump (uentry_accessType (v)),
5250                        v->uname));
5251     case KENUMCONST:  
5252     case KCONST:  
5253       {
5254         cstring sdump;
5255
5256         if (multiVal_isUnknown (uentry_getConstantValue (v))
5257             && typeIdSet_isEmpty (uentry_accessType (v))
5258             && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5259           {
5260             sdump = cstring_makeLiteral ("$");
5261           }
5262         else
5263           {
5264             sdump = message ("@%q@%q@%d",
5265                              multiVal_dump (uentry_getConstantValue (v)),
5266                              typeIdSet_dump (uentry_accessType (v)),
5267                              (int) sRef_getNullState (v->sref));
5268           }
5269
5270         return (message ("%q%q#%s", 
5271                          ctype_dump (v->utype), 
5272                          sdump,
5273                          v->uname));
5274       }
5275     case KSTRUCTTAG:
5276     case KUNIONTAG:
5277     case KENUMTAG:
5278       return (message ("%q@%q#%s", 
5279                        ctype_dump (v->utype), 
5280                        ctype_dump (v->info->datatype->type), v->uname));
5281     }
5282
5283   BADEXIT;
5284 }
5285
5286 /*@only@*/ cstring
5287 uentry_unparseAbbrev (uentry v)
5288 {
5289   if (!uentry_isVariable (v))
5290     {
5291       llcontbuglit ("uentry_unparseAbbrev: not variable");
5292       return uentry_unparse (v);
5293     }
5294
5295   return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5296 }
5297
5298 /*@only@*/ cstring
5299 uentry_unparse (uentry v)
5300 {
5301   cstring st;
5302
5303     if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5304   if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5305
5306   st = uentry_getName (v);
5307
5308   if (cstring_isDefined (st))
5309     {
5310       return (ctype_unparseDeclaration (v->utype, st)); 
5311     }
5312   else
5313     {
5314       cstring_free (st);
5315       return (cstring_copy (ctype_unparse (v->utype)));
5316     }
5317 }
5318
5319 /*@only@*/ cstring
5320 uentry_unparseFull (uentry v)
5321 {
5322   if (uentry_isUndefined (v))
5323     {
5324       return (cstring_makeLiteral ("<undefined>"));
5325     }
5326   else
5327     {
5328       cstring res;
5329
5330       res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5331                      (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5332                      ctype_unparse (v->utype),
5333                      fileloc_unparse (uentry_whereSpecified (v)),
5334                      fileloc_unparse (uentry_whereDeclared (v)),
5335                      fileloc_unparse (uentry_whereDefined (v)));
5336
5337       DPRINTF (("uentry: %s", res));
5338
5339       if (uentry_isDatatype (v))
5340         {
5341           res = message ("%q / type: %s mut: %s abs: %s state: %q",
5342                          res,
5343                          ctype_unparse 
5344                          (ctype_isDefined (v->info->datatype->type) 
5345                           ? v->info->datatype->type : ctype_unknown),
5346                          ynm_unparse (v->info->datatype->mut),
5347                          ynm_unparse (v->info->datatype->abs),
5348                          sRef_unparseState (v->sref));
5349         }
5350       else if (uentry_isFunction (v))
5351         {
5352           res = message ("%q / sref: %q / mods: %q / "
5353                          "globs: %q / clauses: %q / pre: %q / post: %q",
5354                          res,
5355                          sRef_unparseFull (v->sref),
5356                          sRefSet_unparse (v->info->fcn->mods),
5357                          globSet_unparse  (v->info->fcn->globs),
5358                          stateClauseList_unparse (v->info->fcn->specclauses),
5359                          functionConstraint_unparse (v->info->fcn->preconditions),
5360                          functionConstraint_unparse (v->info->fcn->postconditions));
5361         }
5362       else if (uentry_isIter (v))
5363         {
5364           res = message ("%q / sref: %q",
5365                          res,
5366                          sRef_unparseFull (v->sref));
5367         }
5368       else if (uentry_isVariable (v))
5369         {
5370           res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5371                          res,
5372                          sRef_unparseFull (v->sref),
5373                          (int) v->info->var->kind,
5374                          (int) v->info->var->defstate,
5375                          (int) v->info->var->nullstate,
5376                          (int) v->used);
5377           DPRINTF (("sref: [%p]", v->sref));
5378           DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5379           /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref)));           */
5380         }
5381       else if (uentry_isConstant (v))
5382         {
5383           res = message ("%q = %q / %q",
5384                          res, multiVal_unparse (uentry_getConstantValue (v)),
5385                          sRef_unparseFull (v->sref));
5386         }
5387       else
5388         {
5389           res = message ("%q :: %q", res, uentry_unparse (v));
5390         }
5391
5392       return res;
5393     }
5394 }
5395
5396 bool uentry_hasAccessType (uentry e)
5397 {
5398   if (uentry_isValid (e))
5399     {
5400       switch (e->ukind)
5401         {
5402         case KITER:
5403           return (!typeIdSet_isEmpty (e->info->iter->access));
5404         case KENDITER:
5405           return (!typeIdSet_isEmpty (e->info->enditer->access));
5406         case KFCN:
5407           return (!typeIdSet_isEmpty (e->info->fcn->access));
5408         case KENUMCONST:
5409         case KCONST:
5410           return (!typeIdSet_isEmpty (e->info->uconst->access));
5411         default:
5412           return FALSE;
5413         }
5414     }
5415
5416   return FALSE;
5417 }
5418   
5419 typeIdSet uentry_accessType (uentry e)
5420 {
5421   if (uentry_isValid (e))
5422     {
5423       switch (e->ukind)
5424         {
5425         case KITER:
5426           return (e->info->iter->access);
5427         case KENDITER:
5428           return (e->info->enditer->access);
5429         case KFCN:
5430           return (e->info->fcn->access);
5431         case KENUMCONST:
5432         case KCONST:
5433           return (e->info->uconst->access);
5434         default:
5435           break;
5436         }
5437     }
5438
5439   return typeIdSet_undefined;
5440 }
5441
5442 bool
5443 uentry_isVariable (uentry e)
5444 {
5445   return (uentry_isVar (e));
5446 }
5447
5448 bool
5449 uentry_isSpecified (uentry e)
5450 {
5451   return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5452 }
5453
5454 static bool
5455 uentry_isReallySpecified (uentry e)
5456 {
5457   return (uentry_isValid (e) 
5458           && fileloc_isRealSpec (e->whereSpecified));
5459 }
5460
5461 bool
5462 uentry_isVar (uentry e)
5463 {
5464   return (!uentry_isUndefined (e) && e->ukind == KVAR);
5465 }
5466
5467 bool 
5468 uentry_isFakeTag (uentry e)
5469 {
5470   return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5471 }
5472
5473 bool
5474 uentry_isDatatype (uentry e)
5475 {
5476   return (!uentry_isUndefined (e) &&
5477           (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5478            e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5479 }
5480
5481 void
5482 uentry_setAbstract (uentry e)
5483 {
5484   typeId oldid;
5485
5486   llassert (uentry_isDatatype (e) 
5487             && (ynm_isMaybe (e->info->datatype->abs)));
5488
5489   oldid = ctype_typeId (e->info->datatype->type);
5490   e->info->datatype->abs = YES;
5491   e->info->datatype->type = ctype_createAbstract (oldid);
5492 }
5493
5494 void
5495 uentry_setConcrete (uentry e)
5496 {
5497   llassert (uentry_isDatatype (e) 
5498             && (ynm_isMaybe (e->info->datatype->abs)));
5499
5500   e->info->datatype->abs = NO;
5501 }
5502
5503 bool
5504 uentry_isAbstractDatatype (uentry e)
5505 {
5506   return (uentry_isDatatype (e) 
5507           && (ynm_isOn (e->info->datatype->abs)));
5508 }
5509
5510 bool
5511 uentry_isMaybeAbstract (uentry e)
5512 {
5513   return (uentry_isDatatype (e) 
5514           && (ynm_isMaybe (e->info->datatype->abs)));
5515 }
5516
5517 bool
5518 uentry_isMutableDatatype (uentry e)
5519 {
5520   bool res = uentry_isDatatype (e) 
5521     && (ynm_toBoolRelaxed (e->info->datatype->mut));
5522   
5523   return res;
5524 }
5525
5526 bool
5527 uentry_isRefCountedDatatype (uentry e)
5528 {
5529   return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5530 }
5531
5532 bool
5533 uentry_isParam (uentry u)
5534 {
5535   return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5536                                     || u->info->var->kind == VKYIELDPARAM));
5537 }
5538
5539 bool
5540 uentry_isExpandedMacro (uentry u)
5541 {
5542   return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5543 }
5544
5545 bool
5546 uentry_isSefParam (uentry u)
5547 {
5548   return (uentry_isVariable (u) 
5549           && (u->info->var->kind == VKSEFPARAM
5550               || u->info->var->kind == VKREFSEFPARAM
5551               || u->info->var->kind == VKSEFRETPARAM
5552               || u->info->var->kind == VKREFSEFRETPARAM));
5553 }
5554
5555 bool
5556 uentry_isRefParam (uentry u)
5557 {
5558   return (uentry_isVariable (u) 
5559           && (u->info->var->kind == VKREFPARAM
5560               || u->info->var->kind == VKREFYIELDPARAM
5561               || u->info->var->kind == VKREFSEFPARAM
5562               || u->info->var->kind == VKREFSEFRETPARAM));
5563 }
5564
5565 bool
5566 uentry_isAnyParam (uentry u)
5567 {
5568   return (uentry_isVariable (u) 
5569           && ((u->info->var->kind == VKPARAM)
5570               || (u->info->var->kind == VKSEFPARAM)
5571               || (u->info->var->kind == VKYIELDPARAM)
5572               || (u->info->var->kind == VKRETPARAM)
5573               || (u->info->var->kind == VKSEFRETPARAM)));
5574 }
5575
5576 sstate 
5577 uentry_getDefState (uentry u)
5578 {
5579   if (uentry_isValid (u))
5580     {
5581       return (sRef_getDefState (u->sref));
5582     }
5583   else
5584     {
5585       return (SS_UNKNOWN);
5586     }
5587 }
5588
5589 bool
5590 uentry_isOut (uentry u)
5591 {
5592   return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5593           || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5594 }
5595
5596 bool
5597 uentry_isPartial (uentry u)
5598 {
5599   return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5600           || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5601 }
5602
5603 bool
5604 uentry_isStateSpecial (uentry u)
5605 {
5606   return ((uentry_isVariable (u) 
5607            && (u->info->var->defstate == SS_SPECIAL))
5608           || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5609 }
5610
5611 exitkind uentry_getExitCode (uentry ue) 
5612 {
5613   if (uentry_isFunction (ue))
5614     {
5615       return ue->info->fcn->exitCode;
5616     }
5617   else
5618     {
5619       return XK_UNKNOWN;
5620     }
5621 }
5622
5623 qual uentry_nullPred (uentry u)
5624 {
5625   llassert (uentry_isRealFunction (u));
5626
5627   if (uentry_isFunction (u))
5628     {
5629       return (u->info->fcn->nullPred);
5630     }
5631   else
5632     {
5633       return qual_createUnknown ();
5634     }
5635 }
5636
5637 /*
5638 ** Note for variables, this is checking the declared state, not the current state.
5639 */
5640
5641 bool
5642 uentry_possiblyNull (uentry u)
5643 {
5644   return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5645           || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5646 }
5647
5648 alkind 
5649 uentry_getAliasKind (uentry u)
5650 {
5651   if (uentry_isValid (u))
5652     {
5653       return (sRef_getAliasKind (uentry_getSref (u)));
5654     }
5655   else
5656     {
5657       return AK_UNKNOWN;
5658     }
5659 }
5660
5661 exkind 
5662 uentry_getExpKind (uentry u)
5663 {
5664   if (uentry_isValid (u))
5665     {
5666       return (sRef_getExKind (uentry_getSref (u)));
5667     }
5668   else
5669     {
5670       return XO_UNKNOWN;
5671     }
5672 }
5673
5674 bool
5675 uentry_isIter (uentry e)
5676 {
5677   return (!uentry_isUndefined (e) && e->ukind == KITER);
5678 }
5679
5680 bool
5681 uentry_isEndIter (uentry e)
5682 {
5683   return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5684 }
5685
5686 bool
5687 uentry_isRealFunction (uentry e)
5688 {
5689   return (uentry_isFunction (e) ||
5690           (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5691 }
5692
5693 bool
5694 uentry_hasName (uentry e)
5695 {
5696   if (uentry_isValid (e))
5697     {
5698       cstring s = e->uname;
5699       
5700       return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5701                 || uentry_isFakeTag (e)));
5702     }
5703   else
5704     {
5705       return FALSE;
5706     }
5707 }
5708
5709 /*
5710 ** Returns true for fake tags.
5711 ** This is used for dumping the library
5712 */
5713
5714 bool uentry_hasRealName (uentry e)
5715 {
5716   return (uentry_isValid (e) 
5717           && cstring_isNonEmpty (e->uname)
5718           && !uentry_isGlobalMarker (e));
5719 }
5720
5721
5722 /*@observer@*/ globSet
5723 uentry_getGlobs (uentry l)
5724 {
5725   if (uentry_isInvalid (l)) 
5726     {
5727       return globSet_undefined;
5728     }
5729
5730   if (uentry_isFunction (l))
5731     {
5732       return l->info->fcn->globs;
5733     }
5734   else if (uentry_isIter (l))
5735     {
5736       return l->info->iter->globs;
5737     }
5738   else if (uentry_isEndIter (l))
5739     {
5740       return globSet_undefined;
5741     }
5742   else
5743     {
5744       if (l->ukind == KVAR)
5745         {
5746           llcontbug (message ("Bad call to uentry_getGlobs (var): %q (%s)", 
5747                               uentry_unparse (l), 
5748                               ekind_unparse (l->ukind)));
5749         }
5750       else
5751         {
5752           llcontbug (message ("Bad call to uentry_getGlobs: %q (%s)", 
5753                               uentry_unparse (l), 
5754                               ekind_unparse (l->ukind)));
5755         }
5756
5757       return globSet_undefined;
5758     }
5759 }
5760
5761 /*@observer@*/ sRefSet
5762 uentry_getMods (uentry l)
5763 {
5764   llassert (uentry_isValid (l));
5765
5766   if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5767     {
5768       llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5769       return sRefSet_undefined; 
5770     }
5771
5772   if (uentry_isFunction (l))
5773     {
5774       return l->info->fcn->mods;
5775     }
5776   else if (uentry_isIter (l))
5777     {
5778       return l->info->iter->mods;
5779     }
5780   else if (uentry_isEndIter (l))
5781     {
5782       return sRefSet_undefined;
5783     }
5784   else
5785     {
5786       BADBRANCH;
5787     }
5788 }
5789
5790 ekind
5791 uentry_getKind (uentry e)
5792 {
5793   llassert (uentry_isValid (e));
5794
5795   return (e->ukind);
5796 }
5797
5798 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5799 {
5800   llassert (uentry_isEitherConstant (e)); 
5801   return (sRef_getValue (e->sref));
5802 }
5803
5804 /*@observer@*/ uentryList
5805 uentry_getParams (uentry l)
5806 {
5807   if (uentry_isInvalid (l)) return uentryList_undefined;
5808
5809   switch (l->ukind)
5810     {
5811     case KFCN:  
5812     case KITER:
5813       {
5814         ctype ct = l->utype;
5815
5816         if (ctype_isFunction (ct))
5817           {
5818             return (ctype_argsFunction (ct));
5819           }
5820         else
5821           {
5822             return uentryList_undefined;
5823           }
5824       }
5825     case KVAR:  
5826       {
5827         ctype ct = l->utype;
5828
5829         llassert (ctype_isFunction (ct));
5830         return (ctype_argsFunction (ct));
5831       }
5832     BADDEFAULT;
5833     }
5834   BADEXIT;
5835 }
5836
5837 /*@observer@*/ cstring
5838 uentry_rawName (uentry e)
5839 {
5840   if (uentry_isValid (e))
5841     {
5842       return (e->uname);
5843     }
5844   else
5845     {
5846       return cstring_undefined;
5847     }
5848 }
5849
5850 static cstring
5851 uentry_getOptName (uentry e)
5852 {
5853   cstring s = uentry_getName (e);
5854
5855   if (cstring_isDefined (s))
5856     {
5857       s = cstring_appendChar (s, ' ');
5858     }
5859   
5860   return s;
5861 }
5862
5863 /*@only@*/ cstring
5864 uentry_getName (uentry e)
5865 {
5866   cstring ret = cstring_undefined;
5867
5868   if (uentry_isValid (e))
5869     {
5870       if (uentry_isAnyTag (e))
5871         {
5872           ret = fixTagName (e->uname);  
5873         }
5874       else if (uentry_isAnyParam (e))
5875         {
5876           ret = cstring_copy (fixParamName (e->uname));
5877         }
5878       else
5879         {
5880           ret = cstring_copy (e->uname);
5881         }
5882     }
5883
5884   return ret;
5885 }
5886
5887 cstring uentry_observeRealName (uentry e)
5888 {
5889   cstring ret = cstring_undefined;
5890
5891   if (uentry_isValid (e))
5892     {      
5893       if (uentry_isAnyTag (e))
5894         {
5895           if (isFakeTag (e->uname))
5896             {
5897               ret = cstring_undefined;
5898             }
5899           else
5900             {
5901               ret = plainTagName (e->uname); 
5902             }
5903         }
5904       else if (uentry_isAnyParam (e))
5905         {
5906           ret = fixParamName (e->uname);
5907         }
5908       else
5909         {
5910           ret = e->uname;
5911         }
5912     }
5913
5914   return ret;
5915 }
5916
5917 cstring uentry_getRealName (uentry e)
5918 {
5919   if (uentry_isValid (e))
5920     {
5921       if (uentry_isAnyTag (e))
5922         {
5923           return (cstring_undefined);
5924         }
5925       else
5926         {
5927           return (e->uname);
5928         }
5929     }
5930   return cstring_undefined;
5931 }
5932
5933 ctype uentry_getType (uentry e)
5934 {
5935   if (uentry_isValid (e))
5936     {
5937       return e->utype;
5938     }
5939   else
5940     {
5941       return ctype_unknown;
5942     }
5943 }
5944
5945 fileloc uentry_whereLast (uentry e)
5946 {
5947   fileloc loc;
5948
5949   if (uentry_isInvalid (e)) 
5950     {
5951       return fileloc_undefined;
5952     }
5953   
5954   loc = e->whereDefined;
5955
5956   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5957     {
5958       return loc;
5959     }
5960
5961   loc = uentry_whereDeclared (e);
5962
5963   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5964     {
5965       return loc;
5966     }
5967
5968   loc = uentry_whereSpecified (e);
5969   return loc;
5970 }
5971
5972 fileloc uentry_whereEither (uentry e)
5973 {
5974   if (uentry_isInvalid (e)) return fileloc_undefined;
5975
5976   if (fileloc_isDefined (e->whereDefined) 
5977       && !fileloc_isExternal (e->whereDefined))
5978     {
5979       return e->whereDefined;
5980     }
5981   else if (fileloc_isDefined (e->whereDeclared))
5982     {
5983       return e->whereDeclared;
5984     }
5985   else
5986     {
5987       return e->whereSpecified;
5988     }
5989 }
5990
5991 fileloc uentry_whereSpecified (uentry e)
5992 {
5993   if (uentry_isInvalid (e)) return fileloc_undefined;
5994
5995   return (e->whereSpecified);
5996 }
5997
5998 fileloc uentry_whereDefined (uentry e)
5999 {
6000   if (uentry_isInvalid (e)) return fileloc_undefined;
6001
6002   return (e->whereDefined);
6003 }
6004
6005 fileloc uentry_whereDeclared (uentry e)
6006 {
6007   if (uentry_isInvalid (e)) return fileloc_undefined;
6008
6009   return (e->whereDeclared);
6010 }
6011
6012 /*@observer@*/ fileloc
6013 uentry_whereEarliest (uentry e)
6014 {
6015   if (uentry_isInvalid (e)) return fileloc_undefined;
6016   
6017   if (fileloc_isDefined (e->whereSpecified))
6018     {
6019       return (e->whereSpecified);
6020     }
6021   else if (fileloc_isDefined (e->whereDeclared))
6022     {
6023       return (e->whereDeclared);
6024     }
6025   else
6026     {
6027       return e->whereDefined;
6028     }
6029 }
6030
6031 void
6032 uentry_setFunctionDefined (uentry e, fileloc loc)
6033 {
6034   if (uentry_isValid (e))
6035     {
6036       llassert (uentry_isFunction (e));
6037
6038       if (fileloc_isUndefined (e->whereDeclared))
6039         {
6040           e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6041         }
6042       
6043       if (!fileloc_isDefined (e->whereDefined))
6044         {
6045           e->whereDefined = fileloc_update (e->whereDefined, loc);
6046         }
6047     }
6048 }
6049
6050 void
6051 uentry_setDeclDef (uentry e, fileloc f)
6052 {
6053   uentry_setDeclared (e, f);
6054   
6055   if (!uentry_isFunction (e)
6056       && !(uentry_isVariable (e) && uentry_isExtern (e)))
6057     {
6058       uentry_setDefined (e, f);
6059     }
6060 }
6061
6062 void
6063 uentry_setDeclaredForce (uentry e, fileloc f)
6064 {
6065   llassert (uentry_isValid (e));
6066   e->whereDeclared = fileloc_update (e->whereDeclared, f);
6067 }
6068
6069 void
6070 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6071 {
6072   llassert (uentry_isValid (e));
6073   fileloc_free (e->whereDeclared);
6074   e->whereDeclared = f;
6075 }
6076
6077 void
6078 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6079 {
6080   fileloc oldloc;
6081
6082   llassert (uentry_isValid (e));
6083   oldloc = e->whereDeclared;  
6084
6085   if (fileloc_isDefined (oldloc))
6086     {
6087       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6088         {
6089           e->whereDeclared = f;
6090           fileloc_free (oldloc);
6091         }
6092       else
6093         {
6094           fileloc_free (f);
6095         }
6096     }
6097   else
6098     {
6099       e->whereDeclared = f;
6100       fileloc_free (oldloc);
6101     }
6102 }
6103   
6104 void
6105 uentry_setDeclared (uentry e, fileloc f)
6106 {
6107   fileloc oldloc;
6108
6109   llassert (uentry_isValid (e));
6110   oldloc = e->whereDeclared;  
6111
6112   if (fileloc_isDefined (oldloc))
6113     {
6114       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6115         {
6116           e->whereDeclared = fileloc_update (e->whereDeclared, f);
6117         }
6118       else
6119         {
6120           ;
6121         }
6122     }
6123   else
6124     {
6125       e->whereDeclared = fileloc_update (e->whereDeclared, f);
6126     }
6127 }
6128
6129 void
6130 uentry_clearDefined (uentry e)
6131 {
6132   if (uentry_isValid (e))
6133     {
6134       e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6135     }
6136 }
6137
6138 void
6139 uentry_setDefined (uentry e, fileloc f)
6140 {
6141   fileloc oldloc;
6142
6143   llassert (uentry_isValid (e));
6144   oldloc = e->whereDefined;
6145
6146   if (fileloc_isDefined (oldloc))
6147     {
6148       if (fileloc_isLib (oldloc) 
6149           || fileloc_isImport (oldloc)
6150           || fileloc_isBuiltin (oldloc) 
6151           || fileloc_isPreproc (oldloc))
6152         {
6153           e->whereDefined = fileloc_update (e->whereDefined, f);
6154         }
6155       else
6156         {
6157           if (fileloc_equal (oldloc, f) || context_processingMacros ())
6158             {
6159               ; /* okay */
6160             }
6161           else
6162             {
6163               if (optgenerror (FLG_REDEF,
6164                                message ("%s %q redefined", 
6165                                         ekind_capName (e->ukind),
6166                                         uentry_getName (e)),
6167                                f))
6168                 {
6169                   llgenindentmsg (message ("Previous definition of %q", 
6170                                            uentry_getName (e)),
6171                                   e->whereDefined);
6172                 }
6173             }
6174         }
6175     }
6176   else
6177     {
6178       e->whereDefined = fileloc_update (e->whereDefined, f);
6179     }
6180 }
6181
6182 bool
6183 uentry_isCodeDefined (uentry e)
6184 {
6185   llassert (uentry_isValid (e));
6186
6187   return (fileloc_isDefined (e->whereDefined));
6188 }
6189
6190 bool
6191 uentry_isDeclared (uentry e)
6192 {
6193   if (uentry_isValid (e))
6194     {
6195       return (fileloc_isDefined (e->whereDeclared));
6196     }
6197
6198   return FALSE;
6199 }
6200
6201 sRef uentry_getSref (uentry e)
6202 {
6203   /* not true, used for functions too (but shouldn't be? */
6204   /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6205
6206   if (uentry_isInvalid (e)) return sRef_undefined;
6207   
6208   return (e->sref);
6209 }
6210
6211 sRef uentry_getOrigSref (uentry e)
6212 {
6213   /*@i523*/ /* evans 2001-09-09 - need to fix this 
6214   if (uentry_isValid (e))
6215     {
6216       if (uentry_isVariable (e))
6217         {
6218           return e->info->var->origsref;
6219         }
6220       else
6221         {
6222           sRef sr = sRef_copy (uentry_getSref (e));
6223           
6224           sRef_resetState (sr);
6225           sRef_clearDerived (sr);
6226           return (sr);
6227         }
6228     }
6229   else
6230     {
6231       return sRef_undefined;
6232     }
6233   */
6234
6235   if (uentry_isValid (e))
6236     {
6237       sRef sr = sRef_copy (uentry_getSref (e));
6238       
6239       sRef_resetState (sr);
6240       sRef_clearDerived (sr);
6241       
6242       if (uentry_isVariable (e))
6243         {
6244           sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6245           sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6246         }
6247       
6248       return (sr);
6249     }
6250   else
6251     {
6252       return sRef_undefined;
6253     }
6254 }
6255
6256 /*
6257 ** requires: uentry e is not in a hashed symbol table
6258 */
6259
6260 void 
6261 uentry_setName (uentry e, /*@only@*/ cstring n)
6262 {
6263   llassert (uentry_isValid (e));
6264
6265   cstring_free (e->uname);
6266   e->uname = n;
6267 }
6268
6269 void
6270 uentry_setType (uentry e, ctype t)
6271 {
6272   if (uentry_isValid (e)) 
6273     {
6274       e->utype = t;
6275       sRef_setType (e->sref, t);
6276     }
6277 }
6278
6279 void
6280 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6281 {
6282   ctype rct;
6283   ctype rettype = ctype_unknown;
6284   
6285   llassert (uentry_isValid (ue));
6286
6287   uentry_convertVarFunction (ue);
6288   llassert (uentry_isFunction (ue));
6289
6290   rct = ctype_realType (ue->utype);
6291
6292   if (ctype_isFunction (rct))
6293     {
6294       rettype = ctype_getReturnType (rct);
6295     }
6296
6297   ue->utype = ctype_makeNFParamsFunction (rettype, pn);      
6298 }
6299
6300 void
6301 uentry_setRefParam (uentry e)
6302 {
6303   if (!uentry_isVar (e))
6304     {
6305       llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6306     }
6307   else
6308     {
6309       if (e->info->var->kind == VKSEFPARAM)
6310         {
6311           e->info->var->kind = VKREFSEFPARAM;
6312         }
6313       else if (e->info->var->kind == VKSEFRETPARAM)
6314         {
6315           e->info->var->kind = VKREFSEFRETPARAM;
6316         }
6317       else if (e->info->var->kind == VKYIELDPARAM)
6318         {
6319           e->info->var->kind = VKREFYIELDPARAM;
6320         }
6321       else
6322         {
6323           e->info->var->kind = VKREFPARAM;
6324         }
6325     }
6326 }
6327
6328 void
6329 uentry_setParam (uentry e)
6330 {
6331   if (!uentry_isVar (e))
6332     {
6333       if (uentry_isElipsisMarker (e))
6334         {
6335
6336         }
6337       else
6338         {
6339           llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6340         }
6341     }
6342   else
6343     {
6344       cstring oldname;
6345
6346       if (e->info->var->kind == VKYIELDPARAM 
6347           || e->info->var->kind == VKSEFPARAM
6348           || e->info->var->kind == VKSEFRETPARAM)
6349         {
6350           ;
6351         }
6352       else
6353         {
6354           e->info->var->kind = VKPARAM;
6355         }
6356
6357       oldname = e->uname;
6358       e->uname = makeParam (e->uname);
6359       cstring_free (oldname);
6360     }
6361 }
6362
6363 void
6364 uentry_setSref (uentry e, sRef s)
6365 {
6366   if (uentry_isValid (e))
6367     {
6368       if (sRef_isValid (e->sref))
6369         {
6370           sRef_mergeStateQuietReverse (e->sref, s);
6371         }
6372       else
6373         {
6374           e->sref = sRef_saveCopy (s);
6375         }
6376     }
6377 }
6378
6379 ctype
6380 uentry_getAbstractType (uentry e)
6381 {
6382   llassert (uentry_isDatatype (e));
6383
6384   /*
6385   ** This assertion removed.
6386   ** Okay to have undefined type, for system types
6387   
6388   llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6389                     ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6390                     e->utype);
6391                     
6392   */
6393
6394   if (ctype_isUndefined (e->info->datatype->type))
6395     {
6396       return ctype_unknown;
6397     }
6398
6399   /*
6400   ** Sadly, a kludge...
6401   */
6402
6403   if (ctype_isUserBool (e->info->datatype->type)) {
6404     return ctype_bool;
6405   }
6406
6407   return e->info->datatype->type;
6408 }
6409
6410 ctype uentry_getRealType (uentry e)
6411 {
6412   ctype ct;
6413   typeId uid = USYMIDINVALID;
6414
6415   if (uentry_isInvalid (e))
6416     {
6417       return ctype_unknown;
6418     }
6419
6420   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6421
6422   if (uentry_isAnyTag (e))
6423     {
6424       return (e->utype);
6425     }
6426   
6427   if (uentry_isAbstractType (e))
6428     {
6429       ct = uentry_getAbstractType (e);      
6430
6431       if (ctype_isManifestBool (ct)) {
6432         return ct;
6433       }
6434
6435       llassert (ctype_isUA (ct));
6436       
6437       uid = ctype_typeId (ct);
6438       
6439       if (!context_hasAccess (uid))
6440         {
6441           return (ct);
6442         }
6443     }
6444
6445   ct = uentry_getType (e);
6446
6447   /* if (ctype_isUserBool (ct)) return ct; */
6448
6449   if (ctype_isManifestBool (ct)) {
6450     return ctype_bool;
6451   }
6452   
6453   if (ctype_isUA (ct))
6454     {
6455       usymId iid = ctype_typeId (ct);
6456       
6457       if (usymId_equal (iid, uid))
6458         {         
6459           llcontbug (message ("uentry_getRealType: recursive type! %s",
6460                               ctype_unparse (ct)));
6461           return ct;
6462         }
6463       else
6464         {
6465           /* evs 2000-07-25: possible infinite recursion ? */
6466           uentry ue2 = usymtab_getTypeEntry (iid);
6467
6468           if (ue2 == e)
6469             {
6470               llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6471               return ctype_unknown;
6472             }
6473
6474           return uentry_getRealType (ue2);
6475         }
6476     }
6477   else
6478     {
6479       return ct;
6480     }
6481 }
6482
6483 ctype uentry_getForceRealType (uentry e)
6484 {
6485   ctype   ct;
6486   typeId uid = USYMIDINVALID;
6487
6488   if (uentry_isInvalid (e))
6489     {
6490       return ctype_unknown;
6491     }
6492
6493   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6494   
6495   if (uentry_isAnyTag (e))
6496     {
6497       return (e->utype);
6498     }
6499   
6500   if (uentry_isAbstractType (e))
6501     {
6502       ct = uentry_getAbstractType (e);      
6503       llassert (ctype_isUA (ct));
6504       
6505       uid = ctype_typeId (ct);
6506       /* no check for access! */
6507     }
6508   
6509   ct = uentry_getType (e);
6510
6511   /* evs 2000-07-25 */
6512   /* if (ctype_isUserBool (ct)) return ct; */
6513
6514   if (ctype_isManifestBool (ct)) {
6515     return ctype_bool;
6516   }
6517   
6518   if (ctype_isUA (ct))
6519     {
6520       usymId iid = ctype_typeId (ct);
6521       
6522       if (usymId_equal (iid, uid))
6523         {         
6524           llcontbug (message ("uentry_getRealType: recursive type! %s",
6525                               ctype_unparse (ct)));
6526           return ct;
6527         }
6528       else
6529         {
6530           return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6531         }
6532     }
6533   else
6534     {
6535       return ct;
6536     }
6537 }
6538
6539 uentry uentry_nameCopy (cstring name, uentry e)
6540 {
6541   uentry enew = uentry_alloc ();
6542
6543   llassert (uentry_isValid (e));
6544
6545   /* enew->shallowCopy = FALSE; */
6546   enew->ukind = e->ukind;
6547   enew->uname = name;
6548   enew->utype = e->utype;
6549   enew->whereSpecified = fileloc_copy (e->whereSpecified);
6550   enew->whereDefined = fileloc_copy (e->whereDefined);
6551   enew->whereDeclared = fileloc_copy (e->whereDeclared);
6552   enew->sref = sRef_copy (e->sref); 
6553   enew->used = e->used;
6554   enew->lset = FALSE;
6555   enew->isPrivate = e->isPrivate;
6556   enew->hasNameError = FALSE;
6557
6558   enew->uses = filelocList_new ();
6559   enew->warn = warnClause_undefined; 
6560
6561   enew->storageclass = e->storageclass;
6562   enew->info = uinfo_copy (e->info, e->ukind);
6563
6564   return enew;
6565 }
6566
6567 void
6568 uentry_setDatatype (uentry e, usymId uid)
6569 {
6570   llassert (uentry_isDatatype (e));
6571
6572   if (uentry_isAbstractType (e))
6573     {
6574       e->info->datatype->type = ctype_createAbstract (uid);
6575     }
6576   else
6577     {
6578       e->info->datatype->type = ctype_createUser (uid);
6579     }
6580 }
6581
6582 static void 
6583 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6584    /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6585    /*@modifies e@*/
6586 {
6587   llassert (uentry_isValid (e));
6588
6589   if (fileloc_isSpec (f) || fileloc_isImport (f))
6590     {
6591       e->whereSpecified = f;
6592       e->whereDeclared  = fileloc_undefined;
6593       e->whereDefined  = fileloc_undefined;
6594     }
6595   else
6596     {
6597       e->whereSpecified = fileloc_undefined;
6598       e->whereDeclared  = f;
6599       e->whereDefined  = fileloc_undefined;
6600     }
6601
6602   llassert (fileloc_storable (f));
6603 }
6604
6605 static void
6606 ucinfo_free (/*@only@*/ ucinfo u)
6607 {
6608   sfree (u);
6609 }
6610
6611 static void
6612 uvinfo_free (/*@only@*/ uvinfo u)
6613 {
6614   /*drl7x added 6/29/01 */
6615   free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6616   sfree (u);
6617 }
6618
6619 static void
6620 udinfo_free (/*@only@*/ udinfo u)
6621 {
6622   sfree (u);
6623 }
6624
6625 static void
6626 ufinfo_free (/*@only@*/ ufinfo u)
6627 {
6628   globSet_free (u->globs);
6629   sRefSet_free (u->mods);
6630   stateClauseList_free (u->specclauses);
6631   sfree (u);
6632 }
6633
6634 static void
6635 uiinfo_free (/*@only@*/ uiinfo u)
6636 {
6637   sfree (u);
6638 }
6639
6640 static void
6641 ueinfo_free (/*@only@*/ ueinfo u)
6642 {
6643   sfree (u);
6644 }
6645
6646 static /*@only@*/ ucinfo
6647 ucinfo_copy (ucinfo u)
6648 {
6649   ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6650   ret->access = u->access;
6651   ret->macro = u->macro;
6652   return ret;
6653 }
6654
6655 static /*@only@*/ uvinfo
6656 uvinfo_copy (uvinfo u)
6657 {
6658   uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6659   
6660   ret->kind = u->kind;
6661   ret->nullstate = u->nullstate;
6662   ret->defstate = u->defstate;
6663   ret->checked = u->checked;
6664
6665   /*@i523 ret->origsref = sRef_copy (u->origsref); */
6666
6667   /* drl added 07-02-001 */
6668   /* copy null terminated information */
6669
6670   if (u->bufinfo != NULL)
6671     {
6672       ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6673       ret->bufinfo->bufstate = u->bufinfo->bufstate;
6674       ret->bufinfo->size     = u->bufinfo->size;
6675       ret->bufinfo->len      = u->bufinfo->len;
6676       return ret;
6677     }
6678   else
6679     {
6680       ret->bufinfo = NULL;
6681       return ret;
6682     }
6683     
6684 }
6685
6686 static /*@only@*/ udinfo
6687 udinfo_copy (udinfo u)
6688 {
6689   udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6690
6691   ret->abs = u->abs;
6692   ret->mut = u->mut;
6693   ret->type = u->type;
6694
6695   return ret;
6696 }
6697
6698 static /*@only@*/ ufinfo
6699 ufinfo_copy (ufinfo u)
6700 {
6701   ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6702
6703   ret->hasGlobs = u->hasGlobs;
6704   ret->hasMods = u->hasMods;
6705   ret->exitCode = u->exitCode;
6706   ret->specialCode = u->specialCode;
6707   ret->nullPred = u->nullPred;
6708   ret->access = u->access;
6709   ret->globs = globSet_newCopy (u->globs);
6710   ret->mods = sRefSet_newCopy (u->mods);
6711   ret->defparams = u->defparams;
6712   ret->specclauses = stateClauseList_copy (u->specclauses);
6713
6714   ret->preconditions = functionConstraint_copy (u->preconditions);
6715   ret->postconditions = functionConstraint_copy (u->postconditions);
6716   
6717   return ret;
6718 }
6719
6720 static /*@only@*/ uiinfo
6721 uiinfo_copy (uiinfo u)
6722 {
6723   uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6724
6725   ret->access = u->access;
6726   ret->globs = globSet_newCopy (u->globs);
6727   ret->mods = sRefSet_newCopy (u->mods);
6728
6729   return (ret);
6730 }
6731
6732 static /*@only@*/ ueinfo
6733 ueinfo_copy (ueinfo u)
6734 {
6735   ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6736
6737   ret->access = u->access;
6738   return ret;
6739 }
6740
6741 static void
6742 uinfo_free (uinfo u, ekind kind)
6743 {
6744   switch (kind)
6745     {
6746     case KENUMCONST:
6747     case KCONST:       ucinfo_free (u->uconst); break;
6748     case KVAR:         uvinfo_free (u->var); break;
6749     case KSTRUCTTAG:
6750     case KUNIONTAG:
6751     case KENUMTAG:
6752     case KDATATYPE:    udinfo_free (u->datatype); break;
6753     case KFCN:         ufinfo_free (u->fcn); break;
6754     case KITER:        uiinfo_free (u->iter); break;
6755     case KENDITER:     ueinfo_free (u->enditer); break;
6756     case KELIPSMARKER: break;
6757     case KINVALID:     break;
6758     }
6759   
6760     sfree (u);
6761 }
6762
6763 static /*@only@*/ /*@null@*/ uinfo
6764 uinfo_copy (uinfo u, ekind kind)
6765 {
6766   if (kind == KELIPSMARKER || kind == KINVALID)
6767     {
6768       return NULL;
6769     }
6770   else
6771     {
6772       uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6773       
6774       switch (kind)
6775         {
6776         case KENUMCONST:
6777         case KCONST:    ret->uconst = ucinfo_copy (u->uconst); break;
6778         case KVAR:      ret->var = uvinfo_copy (u->var); break;
6779         case KSTRUCTTAG:
6780         case KUNIONTAG:
6781         case KENUMTAG:
6782         case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6783         case KFCN:      ret->fcn = ufinfo_copy (u->fcn); break;
6784         case KITER:     ret->iter = uiinfo_copy (u->iter); break;
6785         case KENDITER:  ret->enditer = ueinfo_copy (u->enditer); break;
6786         BADDEFAULT;
6787         }
6788       return ret;
6789     }
6790 }
6791
6792 static void
6793 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6794 {
6795   filelocList_free (e->uses);
6796   cstring_free (e->uname);
6797   
6798   uinfo_free (e->info, e->ukind);
6799   
6800   fileloc_free (e->whereSpecified); 
6801   fileloc_free (e->whereDefined); 
6802   fileloc_free (e->whereDeclared); 
6803
6804   warnClause_free (e->warn);
6805
6806   nuentries--;
6807   sfree (e);
6808 }
6809
6810 extern void uentry_markOwned (/*@owned@*/ uentry u)
6811 {
6812   sfreeEventually (u);
6813 }
6814
6815 void
6816 uentry_free (/*@only@*/ uentry e)
6817 {
6818   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6819     {
6820       uentry_reallyFree (e);
6821     }
6822 }
6823
6824 /*
6825 ** For uentry's in the global or file scope
6826 */
6827
6828 void
6829 uentry_freeComplete (/*@only@*/ uentry e)
6830 {
6831   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6832     {
6833       DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6834       /*@i@*/ sRef_free (e->sref);
6835       e->sref = sRef_undefined;
6836       uentry_reallyFree (e);
6837     }
6838 }
6839
6840 /*
6841 ** requires old->kind != new->kind, old->uname = new->uname
6842 */
6843
6844 static void
6845 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6846 {
6847   llassert (uentry_isValid (old));
6848   llassert (uentry_isValid (unew));
6849
6850   if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
6851       && (fileloc_isPreproc (uentry_whereDeclared (old))
6852           || ctype_isUnknown (old->utype))
6853       && !uentry_isSpecified (old))
6854     {
6855       ; /* no error */
6856     }
6857   else 
6858     {
6859       if (mustConform)
6860         {
6861           if (!uentry_isDeclared (old))
6862             {
6863               if (uentry_isSpecified (old))
6864                 {
6865                   if (uentry_isSpecified (unew))
6866                     {
6867                       llbuglit ("Respecification!");
6868                     }
6869                   else if (uentry_isDeclared (unew))
6870                     {
6871                       if (optgenerror
6872                           (FLG_INCONDEFS,
6873                            message ("%s %q inconsistently declared as %s: %t",
6874                                     ekind_capName (old->ukind),
6875                                     uentry_getName (unew),
6876                                     ekind_unparseLong (unew->ukind),
6877                                     unew->utype),
6878                            uentry_whereLast (unew)))  /* evans 2001-12-30: was uentry_whereDeclared */
6879                         {
6880                           uentry_showWhereLastKind (old);
6881                         }
6882                     }
6883                   else
6884                     {
6885                       BADEXIT;
6886                     }
6887                 }
6888               else
6889                 {
6890                   if (optgenerror
6891                       (FLG_INCONDEFS,
6892                        message ("%s %q inconsistently declared as %s: %t",
6893                                 ekind_capName (old->ukind),
6894                                 uentry_getName (unew),
6895                                 ekind_unparseLong (unew->ukind),
6896                                 unew->utype),
6897                        uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6898                     {
6899                       uentry_showWhereLastKind (old);
6900                     }
6901                 }
6902             }
6903           else
6904             {
6905               llassert (uentry_isDeclared (unew));
6906
6907               DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6908               DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6909
6910               if (optgenerror
6911                   (FLG_INCONDEFS,
6912                    message ("%s %q inconsistently redeclared as %s",
6913                             ekind_capName (old->ukind),
6914                             uentry_getName (unew),
6915                             ekind_unparseLong (unew->ukind)),
6916                    uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6917                 {
6918                   uentry_showWhereLastKind (old);
6919                 }
6920             }
6921         }
6922     }
6923
6924   uentry_updateInto (old, unew);
6925 }
6926
6927 /*
6928 ** def is the definition of spec, modifies spec
6929 **
6930 ** reports any inconsistencies
6931 ** returns the summary of all available information
6932 ** if spec and def are inconsistent, def is returned
6933 */
6934
6935 void
6936 uentry_showWhereLast (uentry spec)
6937 {
6938   if (uentry_isValid (spec))
6939     {
6940       if (fileloc_isDefined (spec->whereDefined)
6941           && !fileloc_isLib (spec->whereDefined)
6942           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6943         {
6944           llgenindentmsg (message ("Previous definition of %q: %t", 
6945                                    uentry_getName (spec),
6946                                    uentry_getType (spec)),
6947                           uentry_whereDefined (spec));
6948         }
6949       else if (uentry_isDeclared (spec))
6950         {
6951           llgenindentmsg (message ("Previous declaration of %q: %t", 
6952                                    uentry_getName (spec),
6953                                    uentry_getType (spec)),
6954                           uentry_whereDeclared (spec));
6955         }
6956       else if (uentry_isSpecified (spec))
6957         {
6958           if (uentry_hasName (spec))
6959             {
6960               llgenindentmsg (message ("Specification of %q: %t", 
6961                                        uentry_getName (spec),
6962                                        uentry_getType (spec)),
6963                               uentry_whereSpecified (spec));
6964             }
6965           else
6966             {
6967               llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6968                               uentry_whereSpecified (spec));
6969             }
6970         }
6971       else
6972         {
6973           /* nothing to show */
6974         }
6975     }
6976 }
6977
6978 static void
6979 uentry_showWhereLastKind (uentry spec)
6980 {
6981   if (uentry_isValid (spec))
6982     {
6983       if (fileloc_isDefined (spec->whereDefined)
6984           && !fileloc_isLib (spec->whereDefined)
6985           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6986         {
6987           llgenindentmsg (message ("Previous definition of %q as %s: %t", 
6988                                    uentry_getName (spec),
6989                                    ekind_unparseLong (spec->ukind),
6990                                    uentry_getType (spec)),
6991                           uentry_whereDefined (spec));
6992         }
6993       else if (uentry_isDeclared (spec))
6994         {
6995           llgenindentmsg (message ("Previous declaration of %q as %s: %t", 
6996                                    uentry_getName (spec),
6997                                    ekind_unparseLong (spec->ukind),
6998                                    uentry_getType (spec)),
6999                           uentry_whereDeclared (spec));
7000         }
7001       else if (uentry_isSpecified (spec))
7002         {
7003           if (uentry_hasName (spec))
7004             {
7005               llgenindentmsg (message ("Specification of %q as %s: %t", 
7006                                        uentry_getName (spec),
7007                                        ekind_unparseLong (spec->ukind),
7008                                        uentry_getType (spec)),
7009                               uentry_whereSpecified (spec));
7010             }
7011           else
7012             {
7013               llgenindentmsg (message ("Specification as %s: %t",
7014                                        ekind_unparseLong (spec->ukind),
7015                                        uentry_getType (spec)),
7016                               uentry_whereSpecified (spec));
7017             }
7018         }
7019       else
7020         {
7021           /* nothing to show */
7022         }
7023     }
7024 }
7025
7026 void
7027 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7028 {
7029   fileloc loc = uentry_whereDefined (ce);
7030   
7031   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7032     {
7033       llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7034                       loc);
7035     }
7036
7037   loc = uentry_whereSpecified (ce);
7038   
7039   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7040     {
7041       llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7042                       loc);
7043     }
7044 }
7045
7046 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7047 {
7048   if (uentry_isDeclared (spec))
7049     {
7050       llgenindentmsg (message ("Previous declaration of %q: %q", 
7051                                uentry_getName (spec), extra),
7052                       uentry_whereDeclared (spec));
7053     }
7054   else if (uentry_isSpecified (spec))
7055     {
7056       llgenindentmsg (message ("Specification of %q: %q", 
7057                                uentry_getName (spec), extra),
7058                       uentry_whereSpecified (spec));
7059     }
7060   else
7061     {
7062       cstring_free (extra);
7063     }
7064 }
7065
7066 void
7067 uentry_showWhereDeclared (uentry spec)
7068 {
7069   if (uentry_isDeclared (spec))
7070     {
7071       if (uentry_hasName (spec))
7072         {
7073           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7074                           uentry_whereDeclared (spec));
7075         }
7076       else
7077         {
7078           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7079         }
7080     }
7081   else if (uentry_isSpecified (spec))
7082     {
7083       if (uentry_hasName (spec))
7084         {
7085           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7086                           uentry_whereSpecified (spec));
7087         }
7088       else
7089         {
7090           llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7091         }
7092     }
7093   else
7094     {
7095       /* nothing to show */
7096     }
7097     
7098 }
7099
7100 void
7101 uentry_showWhereAny (uentry spec)
7102 {
7103   if (uentry_isDeclared (spec))
7104     {
7105       if (uentry_hasName (spec))
7106         {
7107           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7108                           uentry_whereDeclared (spec));
7109         }
7110       else
7111         {
7112           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7113         }
7114     }
7115   else if (uentry_isSpecified (spec))
7116     {
7117       if (uentry_hasName (spec))
7118         {
7119           llgenindentmsg (message ("Specification of %q",
7120                                    uentry_getName (spec)),
7121                           uentry_whereSpecified (spec));
7122         }
7123       else
7124         {
7125           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7126                           uentry_whereSpecified (spec));
7127         }
7128     }
7129   else if (fileloc_isDefined (uentry_whereDefined (spec))) 
7130     {
7131       if (uentry_hasName (spec))
7132         {
7133           llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7134                           uentry_whereDefined (spec));
7135         }
7136       else
7137         {
7138           llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7139         }
7140     }
7141   else
7142     {
7143       /* nothing to show */
7144     }
7145 }
7146
7147 void
7148 uentry_showWhereDefined (uentry spec)
7149 {
7150   if (uentry_isCodeDefined (spec))
7151     {
7152       llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7153                       uentry_whereDefined (spec));
7154     }
7155 }
7156
7157 void
7158 uentry_showWhereLastPlain (uentry spec)
7159 {
7160   if (uentry_isDeclared (spec))
7161     {
7162       llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7163                       uentry_whereDeclared (spec));
7164     }
7165   else if (uentry_isSpecified (spec))
7166     {
7167       llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7168                       uentry_whereSpecified (spec));
7169     }
7170   else
7171     {
7172           }
7173 }
7174
7175 static void
7176 uentry_showWhereLastVal (uentry spec, cstring val)
7177 {
7178   if (uentry_isDeclared (spec))
7179     {
7180       llgenindentmsg (message ("Previous declaration of %q: %s", 
7181                                uentry_getName (spec), val),
7182                       uentry_whereDeclared (spec));
7183     }
7184   else if (uentry_isSpecified (spec))
7185     {
7186       llgenindentmsg (message ("Specification of %q: %s", 
7187                                uentry_getName (spec), val),
7188                       uentry_whereSpecified (spec));
7189     }
7190   else
7191     {
7192     }
7193 }
7194
7195 void
7196 uentry_showWhereSpecified (uentry spec)
7197 {
7198   if (uentry_isSpecified (spec))
7199     {
7200       if (uentry_hasName (spec))
7201         {
7202           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7203                           uentry_whereSpecified (spec));
7204         }
7205       else
7206         {
7207           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7208                           uentry_whereSpecified (spec));
7209         }
7210     }
7211   else if (uentry_isDeclared (spec))
7212     {
7213       llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7214                       uentry_whereDeclared (spec));
7215     }
7216   else
7217     {
7218       /* nothing to show */
7219     }
7220 }
7221
7222 void
7223 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7224 {
7225   if (uentry_isSpecified (spec))
7226     {
7227       if (uentry_hasName (spec))
7228         {
7229           llgenindentmsg (message ("Specification of %q: %q", 
7230                                    uentry_getName (spec), s),
7231                           uentry_whereSpecified (spec));
7232         }
7233       else
7234         {
7235           llgenindentmsg (message ("Specification: %q", s), 
7236                           uentry_whereSpecified (spec));
7237         }
7238     }
7239   else if (uentry_isDeclared (spec))
7240     {
7241       llgenindentmsg (message ("Declaration of %q: %q", 
7242                                uentry_getName (spec), s),
7243                       uentry_whereDeclared (spec));
7244     }
7245   else
7246     {
7247       llgenindentmsg (message ("Previous: %q", s),
7248                       uentry_whereLast (spec));
7249     }
7250 }
7251
7252 /*
7253 **
7254 */
7255
7256 static void
7257 checkStructConformance (uentry old, uentry unew)
7258 {
7259   ctype oldr, newr; 
7260   uentryList fold, fnew;
7261
7262   /*
7263   ** requires: types of old and new are structs or unions
7264   */
7265
7266   llassert (uentry_isValid (old));
7267   llassert (uentry_isValid (unew));
7268
7269   oldr = ctype_realType (old->utype);
7270   fold =  ctype_getFields (oldr);
7271
7272   newr = ctype_realType (unew->utype);
7273   fnew = ctype_getFields (newr);
7274
7275   if (!uentryList_matchFields (fold, fnew))
7276     {
7277       if (fileloc_equal (uentry_whereLast (old),
7278                          uentry_whereLast (unew)))
7279         {
7280           ; /* cheat! */
7281         }
7282       else 
7283         {
7284           if (optgenerror 
7285               (FLG_MATCHFIELDS,
7286                message ("%q %q %rdeclared with fields { %q }, %s "
7287                         "with fields { %q }",
7288                         cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7289                         uentry_getName (old), 
7290                         uentry_isDeclared (old),
7291                         uentryList_unparseAbbrev (fnew),
7292                         uentry_specOrDefName (old),
7293                         uentryList_unparseAbbrev (fold)),
7294                uentry_whereDeclared (unew)))
7295             {
7296               uentry_showWhereLastPlain (old);
7297               uentryList_showFieldDifference (fold, fnew);
7298             }
7299         }
7300
7301       old->utype = unew->utype;
7302     }
7303 }
7304
7305 static void
7306 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7307 {
7308   /*
7309   ** requires old and new are enums
7310   */
7311   
7312   ctype        rold = ctype_realType (old->utype);
7313   ctype        rnew = ctype_realType (unew->utype);
7314   enumNameList eold = ctype_elist (rold);
7315   enumNameList enew = ctype_elist (rnew);
7316   
7317   if (!enumNameList_match (eold, enew))
7318     {
7319       if (optgenerror 
7320           (FLG_MATCHFIELDS,
7321            message ("Enum %q declared with members { %q } but "
7322                     "%s with members { %q }",
7323                     uentry_getName (old), 
7324                     enumNameList_unparse (enew),
7325                     uentry_specOrDefName (old),
7326                     enumNameList_unparse (eold)),
7327            uentry_whereDeclared (unew)))
7328         {
7329           uentry_showWhereSpecified (old);
7330           old->utype = unew->utype;
7331         }
7332     }
7333 }
7334
7335 /*
7336 ** either oldCurrent or newCurrent may be undefined!
7337 */
7338
7339 static void
7340 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7341                 uentry unew, uentry newCurrent, ctype newType,
7342                 int paramno)
7343 {
7344   bool hasError = FALSE;
7345
7346   if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7347     {
7348       if (uentry_hasName (newCurrent))
7349         {
7350           hasError = optgenerror 
7351             (FLG_TYPE,
7352              message ("Parameter %d, %q, of function %q has inconsistent type: "
7353                       "declared %t, %s %t",
7354                       paramno + 1, uentry_getName (newCurrent), 
7355                       uentry_getName (unew),
7356                       newType, uentry_specOrDefName (old), oldType),
7357              uentry_whereDeclared (newCurrent));
7358         }
7359       else
7360         {
7361           hasError = optgenerror
7362             (FLG_TYPE,
7363              message ("Parameter %d of function %q has inconsistent type: "
7364                       "declared %t, %s %t",
7365                       paramno + 1, uentry_getName (unew),
7366                       newType, uentry_specOrDefName (old), oldType),
7367              uentry_whereDeclared (newCurrent));
7368
7369           DPRINTF (("type: %s / %s",
7370                     ctype_unparse (newType),
7371                     ctype_unparse (ctype_realType (newType))));
7372         }
7373     }
7374   else 
7375     {
7376       if (uentry_isDeclared (unew))
7377         {
7378           hasError = optgenerror 
7379             (FLG_TYPE,
7380              message ("Parameter %d of function %s has inconsistent type: "
7381                       "declared %t, %s %t",
7382                       paramno + 1, unew->uname, 
7383                       newType, uentry_specOrDefName (old), oldType),
7384              uentry_whereDeclared (unew));
7385         }
7386       else
7387         {
7388           hasError = optgenerror
7389             (FLG_TYPE,
7390              message ("Parameter %d of function %s has inconsistent type: "
7391                       "declared %t, %s %t",
7392                       paramno + 1, unew->uname, 
7393                       newType, uentry_specOrDefName (old), oldType),
7394              uentry_whereDeclared (unew));
7395         }
7396     }
7397   
7398   if (hasError)
7399     {
7400       DPRINTF (("Here: %s / %s",
7401                 uentry_unparseFull (oldCurrent),
7402                 uentry_unparseFull (newCurrent)));
7403
7404       if (!uentry_isUndefined (oldCurrent))
7405         {
7406           if (!uentry_isUndefined (newCurrent) 
7407               && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7408             {
7409               uentry_showWhereLast (oldCurrent);
7410             }
7411           else
7412             {
7413               uentry_showWhereLastPlain (old);
7414             }
7415           
7416           uentry_setType (oldCurrent, newType);
7417         }
7418       else
7419         {
7420           uentry_showWhereLastPlain (old);
7421         }
7422     }
7423 }
7424
7425 static void
7426 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7427 {
7428   if (optgenerror 
7429       (FLG_TYPE,
7430        message ("Function %s %rdeclared with %d arg%&, %s with %d",
7431                 unew->uname, 
7432                 uentry_isDeclared (old),
7433                 uentryList_size (uentry_getParams (unew)),
7434                 uentry_specOrDefName (old),
7435                 uentryList_size (uentry_getParams (old))),
7436        uentry_whereDeclared (unew)))
7437     {
7438       uentry_showWhereLastPlain (old);
7439     }
7440 }
7441
7442 static void
7443 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7444 {
7445   if (optgenerror
7446       (FLG_INCONDEFS,
7447        message ("Function %s inconsistently %rdeclared to return %t",
7448                 unew->uname,
7449                 uentry_isDeclared (old),
7450                 ctype_getReturnType (unew->utype)),
7451        uentry_whereDeclared (unew)))
7452     {
7453       uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7454     }
7455 }
7456
7457 static cstring paramStorageName (uentry ue)
7458 {
7459   return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7460 }
7461
7462 static cstring fcnErrName (uentry ue)
7463 {
7464   return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7465 }
7466
7467 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7468 {
7469   if (uentry_isVar (ue))
7470     {
7471       return (checkedName (ue->info->var->checked));
7472     }
7473   else
7474     {
7475       return (cstring_makeLiteralTemp ("<checked invalid>"));
7476     }
7477 }
7478
7479 static cstring checkedName (chkind checked)
7480 {
7481   switch (checked)
7482     {
7483     case CH_UNKNOWN:       return (cstring_makeLiteralTemp ("unknown"));
7484     case CH_UNCHECKED:     return (cstring_makeLiteralTemp ("unchecked"));
7485     case CH_CHECKED:       return (cstring_makeLiteralTemp ("checked"));
7486     case CH_CHECKMOD:      return (cstring_makeLiteralTemp ("checkmod"));
7487     case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7488     }
7489   BADEXIT;
7490 }
7491
7492 static
7493 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7494 {
7495   nstate oldState;
7496   nstate newState;
7497   
7498   if (uentry_isVar (unew))
7499     {
7500       llassert (uentry_isVar (old));
7501       
7502       oldState = old->info->var->nullstate;
7503       newState = unew->info->var->nullstate;
7504     }
7505   else
7506     {
7507       oldState = sRef_getNullState (old->sref);
7508       newState = sRef_getNullState (unew->sref);
7509     }
7510
7511   if (oldState == NS_ABSNULL)
7512     {
7513       if (uentry_isVar (old))
7514         {
7515           old->info->var->nullstate = newState;
7516         }
7517       
7518       sRef_mergeNullState (old->sref, newState);
7519     }
7520   else if (newState == NS_UNKNOWN)
7521     {
7522       if (completeConform && newState != oldState
7523           && uentry_isReallySpecified (old))
7524         {
7525           if (optgenerror 
7526               (FLG_NEEDSPEC,
7527                message ("%s %q specified as %s, but declared without %s qualifier",
7528                         ekind_capName (unew->ukind),
7529                         uentry_getName (unew),
7530                         nstate_unparse (oldState),
7531                         nstate_unparse (oldState)),
7532                uentry_whereDeclared (unew)))
7533             {
7534               uentry_showWhereSpecified (old);
7535             }
7536         }
7537       
7538       if (uentry_isVar (unew))
7539         {
7540           unew->info->var->nullstate = oldState;
7541         }
7542
7543       sRef_mergeNullState (unew->sref, oldState);
7544     }
7545   else if (newState == NS_POSNULL)
7546     {
7547       if (oldState == NS_MNOTNULL 
7548           && (ctype_isUA (unew->utype) 
7549               || (uentry_isFunction (unew)
7550                   && ctype_isUA (ctype_getReturnType (unew->utype)))))
7551         {
7552           if (uentry_isVar (unew))
7553             {
7554               unew->info->var->nullstate = oldState;
7555             }
7556
7557           sRef_mergeNullState (unew->sref, oldState);
7558         }
7559       else 
7560         {
7561           if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL 
7562               || oldState == NS_UNKNOWN)
7563             {
7564               if (mustConform)
7565                 {
7566                   if (optgenerror 
7567                       (FLG_INCONDEFS,
7568                        message 
7569                        ("%s %q inconsistently %rdeclared %s possibly null storage, "
7570                         "%s %q qualifier",
7571                         uentry_ekindName (unew),
7572                         uentry_getName (unew),
7573                         uentry_isDeclared (old),
7574                         fcnErrName (unew),
7575                         uentry_specOrDefName (old),
7576                         cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7577                        uentry_whereDeclared (unew)))
7578                     {
7579                       uentry_showWhereSpecified (old);
7580                     }
7581                 }
7582             }
7583           
7584           if (uentry_isVar (old))
7585             {
7586               old->info->var->nullstate = newState;
7587             }
7588
7589           sRef_mergeNullState (old->sref, newState);
7590         }
7591     }
7592   else if (newState == NS_MNOTNULL)
7593     {
7594       if (oldState != NS_MNOTNULL)
7595         {
7596           if (mustConform)
7597             {
7598               if (optgenerror 
7599                   (FLG_INCONDEFS,
7600                    message ("%s %q inconsistently %rdeclared %s notnull storage, "
7601                             "%s without notnull qualifier",
7602                             uentry_ekindName (unew),
7603                             uentry_getName (unew),
7604                             uentry_isDeclared (old),
7605                             fcnErrName (unew),
7606                             uentry_specOrDefName (old)),
7607                    uentry_whereDeclared (unew)))
7608                 {
7609                   uentry_showWhereSpecified (old);
7610                 }
7611             }
7612           
7613           if (uentry_isVar (old))
7614             {
7615               old->info->var->nullstate = newState;
7616             }
7617
7618           sRef_mergeNullState (old->sref, newState);
7619         }
7620     }
7621   else
7622     {
7623       if (uentry_isVar (unew)) 
7624         {
7625           unew->info->var->nullstate = oldState;
7626         }
7627
7628       sRef_mergeNullState (unew->sref, oldState);
7629     }
7630 }
7631
7632 static
7633 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7634                     bool mustConform, bool completeConform)
7635 {
7636   sstate oldState;
7637   sstate newState;
7638   bool vars = FALSE;
7639
7640   if (uentry_isVar (old) && uentry_isVar (unew))
7641     {
7642       oldState = old->info->var->defstate;
7643       newState = unew->info->var->defstate;
7644       vars = TRUE;
7645     }
7646   else
7647     {
7648       oldState = sRef_getDefState (old->sref);
7649       newState = sRef_getDefState (unew->sref);
7650     }
7651
7652   if (newState != oldState 
7653       && newState != SS_UNKNOWN 
7654       && newState != SS_DEFINED)
7655     {
7656       if (mustConform)
7657         {
7658           if (optgenerror 
7659               (FLG_INCONDEFS,
7660                message ("%s %q inconsistently %rdeclared %s %s %s, "
7661                         "%s %s %s %s",
7662                         uentry_ekindName (unew),
7663                         uentry_getName (unew),
7664                         uentry_isDeclared (old),
7665                         fcnErrName (unew),
7666                         sstate_unparse (newState),
7667                         paramStorageName (unew),
7668                         uentry_specOrDefName (old),
7669                         fcnErrName (unew),
7670                         sstate_unparse (oldState),
7671                         paramStorageName (unew)),
7672                uentry_whereDeclared (unew)))
7673             {
7674               uentry_showWhereSpecified (old);
7675             }
7676         }
7677
7678       if (vars) old->info->var->defstate = newState;
7679       sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7680     }
7681   else
7682     {
7683       if (completeConform
7684           && (newState != oldState) && (oldState != SS_DEFINED)
7685           && uentry_isReallySpecified (old))
7686         {
7687           if (optgenerror 
7688               (FLG_NEEDSPEC,
7689                message ("%s %q specified as %s, but declared without %s qualifier",
7690                         ekind_capName (unew->ukind),
7691                         uentry_getName (unew),
7692                         sstate_unparse (oldState),
7693                         sstate_unparse (oldState)),
7694                uentry_whereDeclared (unew)))
7695             {
7696               uentry_showWhereSpecified (old);
7697             }
7698         }
7699       
7700       if (vars) unew->info->var->defstate = oldState;
7701       sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7702     }
7703 }
7704
7705 static void 
7706   checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7707                    bool mustConform, bool completeConform)
7708 {
7709   alkind newKind;
7710   alkind oldKind;
7711
7712   oldKind = sRef_getAliasKind (old->sref);
7713   newKind = sRef_getAliasKind (unew->sref);
7714
7715   if (alkind_isImplicit (newKind) 
7716       || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7717     {
7718       if (completeConform && !alkind_equal (newKind, oldKind)
7719           && uentry_isReallySpecified (old))
7720         {
7721           if (optgenerror 
7722               (FLG_NEEDSPEC,
7723                message ("%s %q specified as %s, but declared without "
7724                         "explicit alias qualifier",
7725                         ekind_capName (unew->ukind),
7726                         uentry_getName (unew),
7727                         alkind_unparse (oldKind)),
7728                uentry_whereDeclared (unew)))
7729             {
7730               uentry_showWhereSpecified (old);
7731             }
7732         }
7733
7734       /*  
7735       ** This really shouldn't be necessary, but it is!
7736       ** Function params (?) use new here.
7737       */
7738
7739       sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7740       return;
7741     }
7742
7743   if (alkind_isKnown (newKind))
7744     {
7745       if (!alkind_equal (oldKind, newKind))
7746         {
7747           if (alkind_isKnown (oldKind))
7748             {
7749               if (mustConform && 
7750                   optgenerror 
7751                   (FLG_INCONDEFS,
7752                    message ("%s %q inconsistently %rdeclared %s %s storage, "
7753                             "%s as %s storage",
7754                             uentry_ekindName (unew),
7755                             uentry_getName (unew),
7756                             uentry_isDeclared (old),
7757                             fcnErrName (unew),
7758                             alkind_unparse (newKind),
7759                             uentry_specOrDefName (old),
7760                             alkind_unparse (oldKind)),
7761                    uentry_whereDeclared (unew)))
7762                 {
7763                   uentry_showWhereSpecified (old);
7764
7765                   DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7766                   DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7767                   sRef_setAliasKind (old->sref, AK_ERROR, 
7768                                      uentry_whereDeclared (unew));
7769                 }
7770               else
7771                 {
7772                   sRef_setAliasKind (old->sref, newKind, 
7773                                      uentry_whereDeclared (unew));
7774                 }
7775             }
7776           else
7777             {
7778               if (!(alkind_isImplicit (newKind)))
7779                 {
7780                   if (mustConform &&
7781                       !uentry_isFunction (unew) &&
7782                       optgenerror 
7783                       (FLG_INCONDEFS,
7784                        message ("%s %q inconsistently %rdeclared %s %s storage, "
7785                                 "implicitly %s as temp storage",
7786                                 uentry_ekindName (unew),
7787                                 uentry_getName (unew),
7788                                 uentry_isDeclared (old),
7789                                 fcnErrName (unew),
7790                                 alkind_unparse (newKind),
7791                                 uentry_specOrDefName (old)),
7792                        uentry_whereDeclared (unew)))
7793                     {
7794                       uentry_showWhereSpecified (old);
7795                       oldKind = AK_ERROR;
7796                     }
7797                   
7798                   sRef_setAliasKind (old->sref, newKind, 
7799                                      uentry_whereDeclared (unew));
7800                 }
7801               else /* newKind is temp or refcounted */
7802                 {
7803                   ;
7804                 }
7805             }
7806         }
7807     }
7808   else /* newKind unknown */
7809     {
7810       ;
7811     }
7812 }
7813
7814 static void 
7815   checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7816                 bool mustConform, bool completeConform)
7817 {
7818   exkind newKind;
7819   exkind oldKind;
7820   
7821   oldKind = sRef_getExKind (old->sref);
7822   newKind = sRef_getExKind (unew->sref);
7823
7824   if (exkind_isKnown (newKind))
7825     {
7826       if (oldKind != newKind)
7827         {
7828           if (exkind_isKnown (oldKind))
7829             {
7830               if (mustConform && 
7831                   optgenerror 
7832                   (FLG_INCONDEFS,
7833                    message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7834                             uentry_ekindName (unew),
7835                             uentry_getName (unew),
7836                             uentry_isDeclared (old),
7837                             fcnErrName (unew),
7838                             exkind_unparse (newKind),
7839                             uentry_specOrDefName (old),
7840                             exkind_unparse (oldKind)),
7841                    uentry_whereDeclared (unew)))
7842                 {
7843                   uentry_showWhereSpecified (old);
7844                 }
7845
7846               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7847             }
7848           else
7849             {
7850               if (mustConform &&
7851                   optgenerror 
7852                   (FLG_INCONDEFS,
7853                    message ("%s %q inconsistently %rdeclared %s %s, "
7854                             "implicitly %s without exposure qualifier",
7855                             uentry_ekindName (unew),
7856                             uentry_getName (unew),
7857                             uentry_isDeclared (old),
7858                             fcnErrName (unew),
7859                             exkind_unparse (newKind),
7860                             uentry_specOrDefName (old)),
7861                    uentry_whereDeclared (unew)))
7862                 {
7863                   uentry_showWhereSpecified (old);
7864                 }
7865
7866               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7867             }
7868         }
7869     }
7870   else
7871     {
7872       if (completeConform && exkind_isKnown (oldKind)
7873           && uentry_isReallySpecified (old))
7874         {
7875           if (optgenerror 
7876               (FLG_NEEDSPEC,
7877                message ("%s %q specified as %s, but declared without "
7878                         "exposure qualifier",
7879                         ekind_capName (unew->ukind),
7880                         uentry_getName (unew),
7881                         exkind_unparse (oldKind)),
7882                uentry_whereDeclared (unew)))
7883             {
7884               uentry_showWhereSpecified (old);
7885             }
7886         }
7887
7888       /* yes, this is necessary! (if its a param) */
7889       sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7890     }
7891 }
7892
7893 static void 
7894 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7895                 bool mustConform, /*@unused@*/ bool completeConform)
7896 {
7897   valueTable newvals = sRef_getValueTable (unew->sref);
7898
7899   if (valueTable_isDefined (newvals))
7900     {
7901       DPRINTF (("Check meta state: %s -> %s",
7902                 uentry_unparseFull (old),
7903                 uentry_unparseFull (unew)));
7904       
7905       DPRINTF (("Check meta state refs: %s -> %s",
7906                 sRef_unparseFull (old->sref),
7907                 sRef_unparseFull (unew->sref)));
7908       
7909       DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7910       
7911       /*
7912       ** Copy the new values into the old ref
7913       */
7914
7915       valueTable_elements (newvals, key, newval)
7916         {
7917           metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7918           stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7919             
7920           llassert (metaStateInfo_isDefined (msinfo));
7921
7922           if (stateValue_isUndefined (oldval))
7923             {
7924               sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7925             }
7926           else
7927             {
7928               if (stateValue_isError (oldval))
7929                 {
7930                   if (!stateValue_isError (newval))
7931                     {
7932                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7933                     }
7934                   else
7935                     {
7936                       ; /* No change necessary. */
7937                     }
7938                 }
7939               else
7940                 {
7941                   if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7942                     {
7943                       if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7944                         {
7945                           ;
7946                         }
7947                       else
7948                         {
7949                           if (!stateValue_isError (newval) 
7950                               && !stateValue_isImplicit (newval))
7951                             {
7952                               if (uentry_hasName (unew)
7953                                   || !sRef_isParam (uentry_getSref (unew)))
7954                                 {
7955                                   if (mustConform 
7956                                       && optgenerror 
7957                                       (FLG_INCONDEFS,
7958                                        message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7959                                                 uentry_ekindName (unew),
7960                                                 uentry_getName (unew),
7961                                                 uentry_isDeclared (old),
7962                                                 fcnErrName (unew),
7963                                                 stateValue_unparseValue (newval, msinfo),
7964                                                 uentry_specOrDefName (old),
7965                                                 stateValue_unparseValue (oldval, msinfo)),
7966                                        uentry_whereDeclared (unew)))
7967                                     {
7968                                       uentry_showWhereSpecified (old);
7969                                     }
7970                                 }
7971                               else
7972                                 {
7973                                   if (mustConform 
7974                                       && optgenerror 
7975                                       (FLG_INCONDEFS,
7976                                        message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7977                                                 uentry_ekindName (unew),
7978                                                 sRef_getParam (uentry_getSref (unew)),
7979                                                 uentry_isDeclared (old),
7980                                                 fcnErrName (unew),
7981                                                 stateValue_unparseValue (newval, msinfo),
7982                                                 uentry_specOrDefName (old),
7983                                                 stateValue_unparseValue (oldval, msinfo)),
7984                                        uentry_whereDeclared (unew)))
7985                                     {
7986                                       uentry_showWhereSpecified (old);
7987                                     }
7988                                 }
7989                             }
7990                         }
7991                       
7992                       DPRINTF (("Updating!"));
7993                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7994                     }
7995                   else
7996                     {
7997                       DPRINTF (("Values match"));
7998                     }
7999                 }
8000             }
8001         } end_valueTable_elements ;
8002     }
8003 }
8004
8005 static void
8006 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8007                               /*@notnull@*/ uentry unew,
8008                               bool mustConform, bool completeConform)
8009 {
8010   checkDefState (old, unew, mustConform, completeConform);
8011   checkNullState (old, unew, mustConform, completeConform);
8012   checkAliasState (old, unew, mustConform, completeConform);
8013   checkExpState (old, unew, mustConform, completeConform);
8014   checkMetaState (old, unew, mustConform, completeConform);
8015
8016   sRef_storeState (old->sref);
8017   sRef_storeState (unew->sref);
8018 }
8019
8020 static void
8021 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8022 {
8023   if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8024     {
8025       return;
8026     }
8027
8028   llassert (uentry_isVar (old));
8029   llassert (uentry_isVar (unew));
8030
8031   if (cstring_isEmpty (old->uname)) 
8032     {
8033       cstring_free (old->uname);
8034       old->uname = cstring_copy (unew->uname);
8035     }
8036
8037   if (unew->info->var->kind == VKRETPARAM
8038       || unew->info->var->kind == VKSEFRETPARAM)
8039     {
8040       if (old->info->var->kind != VKRETPARAM
8041           && old->info->var->kind != VKSEFRETPARAM)
8042         {
8043           if (optgenerror 
8044               (FLG_INCONDEFS,
8045                message ("Parameter %q inconsistently %rdeclared as "
8046                         "returned parameter",
8047                         uentry_getName (unew),
8048                         uentry_isDeclared (old)),
8049                uentry_whereDeclared (unew)))
8050             {
8051               uentry_showWhereSpecified (old);
8052               old->info->var->kind = unew->info->var->kind;
8053             }
8054         }
8055     }
8056
8057
8058   if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8059     {
8060       if (old->info->var->kind != VKSEFPARAM 
8061           && old->info->var->kind != VKSEFRETPARAM)
8062         {
8063           if (optgenerror 
8064               (FLG_INCONDEFS,
8065                message ("Parameter %qinconsistently %rdeclared as "
8066                         "sef parameter",
8067                         uentry_getOptName (unew),
8068                         uentry_isDeclared (old)),
8069                uentry_whereDeclared (unew)))
8070             {
8071               uentry_showWhereSpecified (old);
8072               old->info->var->kind = unew->info->var->kind;
8073             }
8074         }
8075     }
8076
8077   if (old->info->var->kind == VKSPEC)
8078     {
8079       old->info->var->kind = unew->info->var->kind;
8080     }
8081   else
8082     {
8083       unew->info->var->kind = old->info->var->kind;
8084     }
8085
8086   if (unew->info->var->checked != CH_UNKNOWN
8087       && unew->info->var->checked != old->info->var->checked)
8088     {
8089       if (old->info->var->checked == CH_UNKNOWN
8090           && !fileloc_isUser (uentry_whereLast (old)))
8091         {
8092           ; /* no error */
8093         }
8094       else
8095         {
8096           if (optgenerror 
8097               (FLG_INCONDEFS,
8098                message ("Variable %q inconsistently %rdeclared as "
8099                         "%s parameter (was %s)",
8100                         uentry_getName (unew),
8101                         uentry_isDeclared (old),
8102                         checkedName (unew->info->var->checked),
8103                         checkedName (old->info->var->checked)),
8104                uentry_whereDeclared (unew)))
8105             {
8106               uentry_showWhereSpecified (old);
8107             }
8108         }
8109       
8110       old->info->var->checked = unew->info->var->checked;
8111     }
8112   else
8113     {
8114       if (completeConform 
8115           && (old->info->var->checked != CH_UNKNOWN)
8116           && uentry_isReallySpecified (old))
8117         {
8118           if (optgenerror 
8119               (FLG_NEEDSPEC,
8120                message ("%s %q specified as %s, but declared without %s qualifier",
8121                         ekind_capName (unew->ukind),
8122                         uentry_getName (unew),
8123                         checkedName (old->info->var->checked),
8124                         checkedName (old->info->var->checked)),
8125                uentry_whereDeclared (unew)))
8126             {
8127               uentry_showWhereSpecified (old);
8128             }
8129         }
8130       
8131       unew->info->var->checked = old->info->var->checked;
8132     }
8133
8134   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8135 }
8136
8137 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8138 {
8139   if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8140     {
8141       return;
8142     }
8143
8144   llassert (uentry_isVar (u1));
8145   llassert (uentry_isVar (u2));
8146
8147   if (u1->info->var->kind != u2->info->var->kind) {
8148     if (u1->info->var->kind == VKSEFRETPARAM) {
8149       if (u2->info->var->kind == VKRETPARAM) {
8150         voptgenerror 
8151           (FLG_TYPE,
8152            message ("Function types are inconsistent. Parameter %d is "
8153                     "sef parameter, but non-sef parameter in "
8154                     "assigned function: %s",
8155                     paramno, exprNode_unparse (e)),
8156            exprNode_loc (e));
8157       } else if (u2->info->var->kind == VKSEFPARAM) {
8158         voptgenerror 
8159           (FLG_TYPE,
8160            message ("Function types are inconsistent. Parameter %d is "
8161                     "returns parameter, but non-returns parameter in "
8162                     "assigned function: %s",
8163                     paramno, exprNode_unparse (e)),
8164            exprNode_loc (e));
8165       } else {
8166         voptgenerror 
8167           (FLG_TYPE,
8168            message ("Function types are inconsistent. Parameter %d is "
8169                     "sef returns parameter, but non-sef returns parameter in "
8170                     "assigned function: %s",
8171                     paramno, exprNode_unparse (e)),
8172            exprNode_loc (e));
8173       }
8174     } else if (u1->info->var->kind == VKRETPARAM) {
8175       voptgenerror 
8176         (FLG_TYPE,
8177          message ("Function types are inconsistent. Parameter %d is "
8178                   "returns parameter, but non-returns parameter in "
8179                   "assigned function: %s",
8180                   paramno, exprNode_unparse (e)),
8181          exprNode_loc (e));
8182     } else if (u1->info->var->kind == VKSEFPARAM) {
8183       voptgenerror 
8184         (FLG_TYPE,
8185          message ("Function types are inconsistent. Parameter %d is "
8186                   "sef parameter, but non-sef parameter in "
8187                   "assigned function: %s",
8188                   paramno, exprNode_unparse (e)),
8189          exprNode_loc (e));
8190     } else {
8191       if (u2->info->var->kind == VKSEFRETPARAM) {
8192         voptgenerror 
8193           (FLG_TYPE,
8194            message ("Function types are inconsistent. Parameter %d is "
8195                     "normal parameter, but sef returns parameter in "
8196                     "assigned function: %s",
8197                     paramno, exprNode_unparse (e)),
8198            exprNode_loc (e));
8199       } else if (u2->info->var->kind == VKSEFPARAM) {
8200         voptgenerror 
8201           (FLG_TYPE,
8202            message ("Function types are inconsistent. Parameter %d is "
8203                     "normal parameter, but sef parameter in "
8204                     "assigned function: %s",
8205                     paramno, exprNode_unparse (e)),
8206            exprNode_loc (e));
8207       } else if (u2->info->var->kind == VKRETPARAM) {
8208         voptgenerror 
8209           (FLG_TYPE,
8210            message ("Function types are inconsistent. Parameter %d is "
8211                     "normal parameter, but returns parameter in "
8212                     "assigned function: %s",
8213                     paramno, exprNode_unparse (e)),
8214            exprNode_loc (e));
8215       } else {
8216         BADBRANCH;
8217       }
8218     }
8219   }
8220
8221   if (u1->info->var->defstate != u2->info->var->defstate) 
8222     {
8223       voptgenerror 
8224         (FLG_TYPE,
8225          message ("Function types are inconsistent. Parameter %d is "
8226                   "%s, but %s in assigned function: %s",
8227                   paramno, 
8228                   sstate_unparse (u1->info->var->defstate),
8229                   sstate_unparse (u2->info->var->defstate),
8230                   exprNode_unparse (e)),
8231          exprNode_loc (e));
8232     }
8233
8234   if (u1->info->var->nullstate != u2->info->var->nullstate) 
8235     {
8236       voptgenerror 
8237         (FLG_TYPE,
8238          message ("Function types are inconsistent. Parameter %d is "
8239                   "%s, but %s in assigned function: %s",
8240                   paramno, 
8241                   nstate_unparse (u1->info->var->nullstate),
8242                   nstate_unparse (u2->info->var->nullstate),
8243                   exprNode_unparse (e)),
8244          exprNode_loc (e));
8245     }
8246       
8247   if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8248     {
8249       voptgenerror 
8250         (FLG_TYPE,
8251          message ("Function types are inconsistent. Parameter %d is "
8252                   "%s, but %s in assigned function: %s",
8253                   paramno, 
8254                   alkind_unparse (sRef_getAliasKind (u1->sref)),
8255                   alkind_unparse (sRef_getAliasKind (u2->sref)),
8256                   exprNode_unparse (e)),
8257          exprNode_loc (e));
8258     }
8259
8260   if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8261     {
8262       voptgenerror 
8263         (FLG_TYPE,
8264          message ("Function types are inconsistent. Parameter %d is "
8265                   "%s, but %s in assigned function: %s",
8266                   paramno, 
8267                   exkind_unparse (sRef_getExKind (u1->sref)),
8268                   exkind_unparse (sRef_getExKind (u2->sref)),
8269                   exprNode_unparse (e)),
8270          exprNode_loc (e));
8271     }
8272 }
8273
8274 static void
8275 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8276                           /*@notnull@*/ uentry unew, 
8277                           bool mustConform, /*@unused@*/ bool completeConform)
8278 {
8279   uentryList oldParams  = uentry_getParams (old);
8280   uentryList newParams  = uentry_getParams (unew);
8281   ctype      newType    = unew->utype;
8282   ctype      oldType    = ctype_realType (old->utype);
8283   ctype      oldRetType = ctype_unknown;
8284   ctype      newRetType = ctype_unknown;
8285
8286   DPRINTF (("Function conform: %s ==> %s",
8287             uentry_unparseFull (old),
8288             uentry_unparseFull (unew)));
8289
8290   if (uentry_isForward (old))
8291     {
8292       mustConform = FALSE;
8293       uentry_updateInto (old, unew);
8294       return;
8295     }
8296
8297   /*
8298   ** check return values
8299   */
8300   
8301   if (ctype_isKnown (oldType))
8302     {
8303       llassert (ctype_isFunction (oldType));
8304       oldRetType = ctype_getReturnType (oldType);
8305     }
8306
8307   if (ctype_isKnown (newType))
8308     {
8309       llassert (ctype_isFunction (newType));
8310       newRetType = ctype_getReturnType (newType);
8311     }
8312
8313   if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8314       && !ctype_matchDef (newRetType, oldRetType))
8315     {
8316       if (mustConform) returnValueError (old, unew);
8317     }
8318   else 
8319     {
8320       if (ctype_isConj (newRetType))
8321         {
8322           if (ctype_isConj (oldRetType))
8323             {
8324               if (!ctype_sameAltTypes (newRetType, oldRetType))
8325                 {
8326                   if (optgenerror 
8327                       (FLG_INCONDEFS,
8328                        message ("Function %q inconsistently %rdeclared to "
8329                                 "return alternate types %s "
8330                                 "(types match, but alternates are not identical, "
8331                                 "so checking may not be correct)",
8332                                 uentry_getName (unew),
8333                                 uentry_isDeclared (old),
8334                                 ctype_unparse (newRetType)),
8335                        uentry_whereDeclared (unew)))
8336                     {
8337                       uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8338                     }
8339                 }
8340             }
8341           else
8342             {
8343               old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8344             }
8345         }
8346     }
8347
8348   DPRINTF (("Before state: %s",
8349             uentry_unparseFull (old)));
8350   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8351   DPRINTF (("After state: %s",
8352             uentry_unparseFull (old)));
8353
8354   if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8355     {
8356       if (exitkind_isKnown (unew->info->fcn->exitCode))
8357         {
8358           if (optgenerror 
8359               (FLG_INCONDEFS,
8360                message ("Function %q inconsistently %rdeclared using %s",
8361                         uentry_getName (unew),
8362                         uentry_isDeclared (old),
8363                         exitkind_unparse (unew->info->fcn->exitCode)),
8364                uentry_whereDeclared (unew)))
8365             {
8366               uentry_showWhereSpecified (old);
8367             }
8368         }
8369       else
8370         {
8371           unew->info->fcn->exitCode = old->info->fcn->exitCode;
8372         }
8373     }
8374
8375   if (!qual_isUnknown (unew->info->fcn->nullPred))
8376     {
8377       if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8378         {
8379           if (optgenerror
8380               (FLG_INCONDEFS,
8381                message ("Function %q inconsistently %rdeclared using %s",
8382                         uentry_getName (unew),
8383                         uentry_isDeclared (old),
8384                         qual_unparse (unew->info->fcn->nullPred)),
8385                uentry_whereDeclared (unew)))
8386             {
8387               uentry_showWhereSpecified (old);
8388             }
8389         }
8390     }
8391   else
8392     {
8393       unew->info->fcn->nullPred = old->info->fcn->nullPred;
8394     }
8395
8396   if (unew->info->fcn->specialCode != SPC_NONE)
8397     {
8398       if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8399         {
8400           if (optgenerror
8401               (FLG_INCONDEFS,
8402                message ("Function %q inconsistently %rdeclared using %s",
8403                         uentry_getName (unew),
8404                         uentry_isDeclared (old),
8405                         specCode_unparse (unew->info->fcn->specialCode)),
8406                uentry_whereDeclared (unew)))
8407             {
8408               uentry_showWhereSpecified (old);
8409             }
8410         }
8411     }
8412   else
8413     {
8414       unew->info->fcn->specialCode = old->info->fcn->specialCode;
8415     }
8416           
8417   /*
8418   ** check parameters
8419   */
8420   
8421   if (!uentryList_sameObject (oldParams, newParams)
8422       && (!uentryList_isMissingParams (oldParams)))
8423     {
8424       if (!uentryList_isMissingParams (newParams))
8425         {
8426           int paramno = 0;
8427           int nparams = uentryList_size (oldParams);
8428           bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8429
8430           if (nparams != uentryList_size (newParams))
8431             {
8432               nargsError (old, unew);
8433             }
8434           
8435           if (uentryList_size (newParams) < nparams) 
8436             {
8437               nparams = uentryList_size (newParams);
8438             }
8439
8440           while (paramno < nparams)
8441             {
8442               uentry oldCurrent = uentryList_getN (oldParams, paramno);
8443               uentry newCurrent  = uentryList_getN (newParams, paramno);
8444               ctype  oldCurrentType = uentry_getType (oldCurrent);
8445               ctype  newCurrentType = uentry_getType (newCurrent);
8446
8447               llassert (uentry_isValid (oldCurrent)
8448                         && uentry_isValid (newCurrent));
8449               
8450               if (!uentry_isElipsisMarker (oldCurrent)
8451                   && !uentry_isElipsisMarker (newCurrent))
8452                 {
8453                   checkVarConformance (oldCurrent, newCurrent, 
8454                                        mustConform, completeConform);
8455                 }
8456
8457               if (checknames)
8458                 {
8459                   if (uentry_hasName (oldCurrent) 
8460                       && uentry_hasName (newCurrent))
8461                     {
8462                       cstring oldname = uentry_getName (oldCurrent);
8463                       cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8464                       cstring oname;
8465                       cstring nname = uentry_getName (newCurrent);
8466                       cstring nnamefix;
8467
8468                       if (cstring_isDefined (pfx)
8469                           && cstring_equalPrefix (oldname, pfx))
8470                         {
8471                           oname = cstring_suffix (oldname, cstring_length (pfx));
8472                         }
8473                       else
8474                         {
8475                           oname = oldname;
8476                         /*@-branchstate@*/ } /*@=branchstate@*/
8477
8478                       if (cstring_isDefined (pfx)
8479                           && cstring_equalPrefix (nname, pfx))
8480                         {
8481                           nnamefix = cstring_suffix (nname, cstring_length (pfx));
8482                         }
8483                       else
8484                         {
8485                           nnamefix = nname;
8486                         /*@-branchstate@*/ } /*@=branchstate@*/
8487
8488                       if (!cstring_equal (oname, nnamefix))
8489                         {
8490                           if (optgenerror
8491                               (FLG_DECLPARAMMATCH, 
8492                                message ("Definition parameter name %s does not match "
8493                                         "name of corresponding parameter in "
8494                                         "declaration: %s",
8495                                         nnamefix, oname),
8496                                uentry_whereLast (newCurrent)))
8497                             {
8498                               uentry_showWhereLastPlain (oldCurrent);
8499                             }
8500                         }
8501                       
8502                       cstring_free (oldname);
8503                       cstring_free (nname);
8504                     }
8505                 }
8506
8507               if (!ctype_match (oldCurrentType, newCurrentType))
8508                 {
8509                   paramTypeError (old, oldCurrent, oldCurrentType,
8510                                   unew, newCurrent, newCurrentType, paramno);
8511                 }
8512               else
8513                 {
8514                   if (ctype_isMissingParamsMarker (newCurrentType)
8515                       || ctype_isElips (newCurrentType)
8516                       || ctype_isMissingParamsMarker (oldCurrentType)
8517                       || ctype_isElips (oldCurrentType))
8518                     {
8519                       ;
8520                     }
8521                   else
8522                     {
8523                       if (ctype_isConj (newCurrentType))
8524                         {
8525                           if (ctype_isConj (oldCurrentType))
8526                             {
8527                               if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8528                                 {
8529                                   if (optgenerror 
8530                                       (FLG_INCONDEFS,
8531                                        message ("Parameter %q inconsistently %rdeclared with "
8532                                                 "alternate types %s "
8533                                                 "(types match, but alternates are not identical, "
8534                                                 "so checking may not be correct)",
8535                                                 uentry_getName (newCurrent),
8536                                                 uentry_isDeclared (oldCurrent),
8537                                                 ctype_unparse (newCurrentType)),
8538                                        uentry_whereDeclared (unew)))
8539                                     {
8540                                       uentry_showWhereLastVal (oldCurrent,
8541                                                                ctype_unparse (oldCurrentType));
8542                                     }
8543                                 }
8544                             }
8545                           else
8546                             {
8547                               if (optgenerror 
8548                                   (FLG_INCONDEFS,
8549                                    message ("Parameter %q inconsistently %rdeclared with "
8550                                             "alternate types %s",
8551                                             uentry_getName (newCurrent),
8552                                             uentry_isDeclared (oldCurrent),
8553                                             ctype_unparse (newCurrentType)),
8554                                    uentry_whereDeclared (unew)))
8555                                 {
8556                                   uentry_showWhereLastVal (oldCurrent,
8557                                                            ctype_unparse (oldCurrentType));
8558                                   
8559                                 }
8560                             }
8561                         }
8562                       else 
8563                         {
8564                           if (ctype_isConj (oldCurrentType))
8565                             {
8566                               uentry_setType (newCurrent, oldCurrentType);
8567                             }
8568                         }
8569                     }
8570                 }
8571
8572               paramno++;  
8573               /*
8574                ** Forgot this!  detected by splint:
8575                ** uentry.c:1257,15: Suspected infinite loop
8576                */
8577             }
8578         }
8579     }
8580
8581   if (!uentryList_isMissingParams (newParams))
8582     {
8583       if (ctype_isConj (oldRetType))
8584         {
8585           old->utype = ctype_makeFunction (oldRetType, 
8586                                            uentryList_copy (newParams));
8587         }
8588       else
8589         {
8590           old->utype = unew->utype;
8591         }
8592     }
8593
8594   checkGlobalsConformance (old, unew, mustConform, completeConform);
8595   checkModifiesConformance (old, unew, mustConform, completeConform);
8596
8597   DPRINTF (("Before list: %s",
8598             uentry_unparseFull (old)));
8599
8600   if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8601     {
8602       if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8603         {
8604           /*
8605           if (optgenerror
8606               (FLG_INCONDEFS,
8607                message ("Function %q redeclared using special clauses (can only "
8608                         "be used in first declaration)",
8609                         uentry_getName (unew)),
8610                uentry_whereDeclared (unew)))
8611             {
8612               uentry_showWhereLast (old);
8613             }
8614           */
8615
8616           /*@i23 need checking @*/ 
8617
8618           old->info->fcn->specclauses = unew->info->fcn->specclauses;
8619         }
8620       else
8621         {
8622           /*@i43 should be able to append? @*/
8623
8624           stateClauseList_checkEqual (old, unew);
8625           stateClauseList_free (unew->info->fcn->specclauses);
8626           unew->info->fcn->specclauses = stateClauseList_undefined;
8627           /*@-branchstate@*/ 
8628         }
8629     }
8630   /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8631
8632   if (fileloc_isUndefined (old->whereDeclared))
8633     {
8634       old->whereDeclared = fileloc_copy (unew->whereDeclared);
8635     }
8636   else if (fileloc_isUndefined (unew->whereDeclared))
8637     {
8638       unew->whereDeclared = fileloc_copy (old->whereDeclared);
8639     }
8640   else
8641     {
8642       /* no change */
8643     }
8644 /*@i523 @*/ }
8645
8646 void
8647 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8648 {
8649   multiVal uval;
8650
8651   llassert (uentry_isValid (ue));
8652   llassert (uentry_isEitherConstant (ue));
8653
8654   DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8655   uval = uentry_getConstantValue (ue);
8656
8657   if (multiVal_isDefined (uval))
8658     {
8659       if (multiVal_isDefined (m))
8660         {
8661           if (!multiVal_equiv (uval, m))
8662             {
8663               if (optgenerror 
8664                   (FLG_INCONDEFS,
8665                    message ("%s %q defined with inconsistent value: %q",
8666                             ekind_capName (ue->ukind),
8667                             uentry_getName (ue), 
8668                             multiVal_unparse (m)),
8669                    g_currentloc))
8670                 {
8671                   uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8672                 }
8673             }
8674         }
8675       multiVal_free (m);
8676     }
8677   else
8678     {
8679       uentry_setConstantValue (ue, m);
8680     }
8681 }
8682
8683 static
8684 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
8685                            bool mustConform)
8686 {
8687   bool typeError = FALSE;
8688
8689   if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8690     {
8691       if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8692         {
8693           if (mustConform)
8694             {
8695               DPRINTF (("Check struct conformance: %s / %s",
8696                         uentry_unparseFull (old),
8697                         uentry_unparseFull (unew)));
8698               checkStructConformance (old, unew); 
8699             }
8700         }
8701       else
8702         {
8703           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8704             {
8705               llbug (message ("struct tags: bad types: %t / %t", 
8706                               old->utype, unew->utype));
8707             }
8708         }
8709     }
8710   else if (uentry_isEnumTag (old))
8711     {
8712       if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8713         {
8714           if (mustConform) checkEnumConformance (old, unew);
8715         }
8716       else 
8717         {
8718           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8719             {
8720               llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8721                               ctype_unparse (unew->utype)));
8722             }
8723         }
8724     }
8725   else if (!ctype_match (old->utype, unew->utype))
8726     {
8727       DPRINTF (("Type mismatch: %s / %s",
8728                 ctype_unparse (old->utype),
8729                 ctype_unparse (unew->utype)));
8730
8731       if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8732         {
8733           ctype realt = ctype_realType (unew->utype);
8734           
8735           if (ctype_isRealInt (realt) || ctype_isChar (realt))
8736             {
8737               unew->utype = ctype_bool;
8738             }
8739           else
8740             {
8741               if (mustConform)
8742                 {
8743                   typeError = optgenerror
8744                     (FLG_INCONDEFS,
8745                      message ("%q defined as %s", uentry_getName (old), 
8746                               ctype_unparse (realt)),
8747                      uentry_whereDeclared (unew));
8748                 }
8749             }
8750         } 
8751       else 
8752         {
8753           if (mustConform)
8754             {
8755               ctype oldr = ctype_realType (old->utype);
8756               ctype newr = ctype_realType (unew->utype);
8757               
8758               if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8759                 {
8760                   checkStructConformance (old, unew);
8761                 }
8762               else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8763                 {
8764                   checkStructConformance (old, unew);
8765                 }
8766               else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8767                 {
8768                   checkEnumConformance (old, unew);
8769                 }
8770               else if (uentry_isConstant (old) 
8771                        && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8772                 {
8773                   /* okay...for now! (should check the type is reset later... */
8774                 }
8775               else
8776                 {
8777                   DPRINTF (("YABA!"));
8778                   if (optgenerror 
8779                       (FLG_INCONDEFS,
8780                        message ("%s %q %rdeclared with inconsistent type: %t",
8781                                 ekind_capName (unew->ukind),
8782                                 uentry_getName (unew), 
8783                                 uentry_isDeclared (old),
8784                                 unew->utype),
8785                        uentry_whereDeclared (unew)))
8786                     {
8787                       uentry_showWhereLast (old);
8788                       typeError = TRUE;
8789                     }
8790                 }
8791             }
8792         }
8793     }
8794   else
8795     {
8796       /* no error */
8797     }
8798
8799   return typeError;
8800 }
8801
8802 static void
8803 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8804                                  /*@notnull@*/ uentry unew,
8805                                  bool mustConform, bool completeConform)
8806 {
8807   if (ctype_isDefined (unew->info->datatype->type))
8808     {
8809       /*
8810       ** bool is hard coded here, since it is built into LCL.
8811       ** For now, we're stuck with LCL's types.
8812       */
8813
8814       if (ctype_isDirectBool (old->utype) &&
8815           cstring_equalLit (unew->uname, "bool"))
8816         {
8817           /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8818              evs 2000-07-25: removed
8819           */
8820               unew->utype = ctype_bool;
8821         }
8822       
8823       if (ctype_isUnknown (old->info->datatype->type))
8824         {
8825           old->info->datatype->type = unew->info->datatype->type;
8826         }
8827       else
8828         {
8829           DPRINTF (("Old: %s / New: %s",
8830                     uentry_unparseFull (old),
8831                     uentry_unparseFull (unew)));
8832           DPRINTF (("Types: %s / %s",
8833                     ctype_unparse (old->info->datatype->type),
8834                     ctype_unparse (unew->info->datatype->type)));
8835
8836           if (ctype_matchDef (old->info->datatype->type,
8837                               unew->info->datatype->type))
8838             {
8839               ;
8840             }
8841           else
8842             {
8843               if (optgenerror 
8844                   (FLG_INCONDEFS,
8845                    message
8846                    ("Type %q %s with inconsistent type: %t",
8847                     uentry_getName (unew), 
8848                     uentry_reDefDecl (old, unew),
8849                     unew->info->datatype->type),
8850                    uentry_whereDeclared (unew)))
8851                 {
8852                   uentry_showWhereLastExtra 
8853                     (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8854                 }
8855
8856               old->info->datatype->type = unew->info->datatype->type;
8857             }
8858         }
8859     }
8860   
8861   if (unew->info->datatype->abs != MAYBE)
8862     {
8863       if (ynm_isOff (old->info->datatype->abs)
8864           && ynm_isOn (unew->info->datatype->abs))
8865         {
8866           if (!ctype_isDirectBool (old->utype))
8867             {
8868               if (optgenerror 
8869                   (FLG_INCONDEFS,
8870                    message 
8871                    ("Datatype %q inconsistently %rdeclared as abstract type",
8872                     uentry_getName (unew), 
8873                     uentry_isDeclared (old)),
8874                    uentry_whereDeclared (unew)))
8875                 {
8876                   uentry_showWhereLastPlain (old);
8877                 }
8878             }
8879         }
8880       else if (ynm_isOn (old->info->datatype->abs)
8881                && ynm_isOff (unew->info->datatype->abs))
8882         {
8883           if (!ctype_isDirectBool (old->utype))
8884             {
8885               if (optgenerror 
8886                   (FLG_INCONDEFS,
8887                    message 
8888                    ("Datatype %q inconsistently %rdeclared as concrete type",
8889                     uentry_getName (unew), 
8890                     uentry_isDeclared (old)),
8891                    uentry_whereDeclared (unew)))
8892                 {
8893                   uentry_showWhereLastPlain (old);
8894                 }
8895             }
8896         }
8897       else
8898         {
8899           ;
8900         }
8901     }
8902   else 
8903     {
8904       if (ynm_isOn (old->info->datatype->abs))
8905         {
8906           old->sref = unew->sref;
8907           unew->info->datatype->mut = old->info->datatype->mut;
8908           
8909           if (completeConform
8910               && uentry_isReallySpecified (old))
8911             {
8912               if (optgenerror 
8913                   (FLG_NEEDSPEC,
8914                    message 
8915                    ("Datatype %q specified as abstract, "
8916                     "but abstract annotation not used in declaration",
8917                     uentry_getName (unew)), 
8918                    uentry_whereDeclared (unew)))
8919                 {
8920                   uentry_showWhereLastPlain (old);
8921                 }
8922             }
8923         }
8924     }
8925   
8926   unew->info->datatype->abs = old->info->datatype->abs;   
8927   
8928   if (ynm_isMaybe (unew->info->datatype->mut))
8929     {
8930       if (completeConform && ynm_isOff (old->info->datatype->mut)
8931           && uentry_isReallySpecified (old))
8932         {
8933           if (optgenerror 
8934               (FLG_NEEDSPEC,
8935                message 
8936                ("Datatype %q specified as immutable, "
8937                 "but immutable annotation not used in declaration",
8938                 uentry_getName (unew)), 
8939                uentry_whereDeclared (unew)))
8940             {
8941               uentry_showWhereLastPlain (old);
8942             }
8943         }
8944       
8945       unew->info->datatype->mut = old->info->datatype->mut;
8946     }
8947   else if (ynm_isMaybe (old->info->datatype->mut))
8948     {
8949       old->info->datatype->mut = unew->info->datatype->mut;
8950     }
8951   else
8952     {
8953       if (ynm_isOn (old->info->datatype->abs))
8954         {
8955           if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8956             {
8957               if (optgenerror
8958                   (FLG_INCONDEFS,
8959                    message ("Datatype %q inconsistently %rdeclared as immutable",
8960                             uentry_getName (unew), 
8961                             uentry_isDeclared (old)),
8962                    uentry_whereDeclared (unew)))
8963                 {
8964                   uentry_showWhereLastPlain (old);
8965                 }
8966             }
8967           else 
8968             {
8969               if (ynm_isOff (old->info->datatype->mut)
8970                   && ynm_isOn (unew->info->datatype->mut))
8971                 {
8972                   if (optgenerror
8973                       (FLG_INCONDEFS,
8974                        message ("Datatype %q inconsistently %rdeclared as mutable",
8975                                 uentry_getName (unew), 
8976                                 uentry_isDeclared (old)),
8977                        uentry_whereDeclared (unew)))
8978                     {
8979                       uentry_showWhereLastPlain (old);
8980                     }
8981                 }
8982             }
8983         }
8984       old->info->datatype->mut = unew->info->datatype->mut;       
8985     }
8986
8987   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8988 }
8989
8990 static void
8991 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8992                                  /*@notnull@*/ uentry unew,
8993                                  bool mustConform, 
8994                                  /*@unused@*/ bool completeConform)
8995 {
8996   multiVal oldval = uentry_getConstantValue (old);
8997   multiVal newval = uentry_getConstantValue (unew);
8998   
8999   if (multiVal_isDefined (oldval))
9000     {
9001       if (multiVal_isDefined (newval))
9002         {
9003           if (!multiVal_equiv (oldval, newval))
9004             {
9005               if (mustConform
9006                   && optgenerror 
9007                   (FLG_INCONDEFS,
9008                    message ("%s %q %rdeclared with inconsistent value: %q",
9009                             ekind_capName (unew->ukind),
9010                             uentry_getName (unew), 
9011                             uentry_isDeclared (old),
9012                             multiVal_unparse (newval)),
9013                    uentry_whereDeclared (unew)))
9014                 {
9015                   uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9016                 }
9017             }
9018           
9019           uentry_setConstantValue (unew, multiVal_copy (oldval));
9020         }
9021       else
9022         {
9023           ;
9024         }
9025     }
9026   else
9027     {
9028       uentry_setConstantValue (old, multiVal_copy (newval));
9029     }
9030 }
9031
9032 static void 
9033 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old, 
9034                          /*@notnull@*/ uentry unew, bool mustConform,
9035                          bool completeConform)
9036 {
9037   bool typeError = FALSE;
9038   bool fcnConformance = FALSE;
9039
9040   if (!ekind_equal (unew->ukind, old->ukind))
9041     {
9042       /*
9043       ** okay, only if one is a function and the other is
9044       ** a variable of type function.
9045       */
9046
9047       if (unew->ukind == KENUMCONST
9048           && old->ukind == KCONST)
9049         {
9050           old->ukind = KENUMCONST;
9051           goto nokinderror;
9052         }
9053
9054       if (unew->ukind == KFCN 
9055           && old->ukind == KCONST
9056           && ctype_isUnknown (old->utype))
9057         {
9058           /*
9059           ** When a function is defined with an unparam macro
9060           */
9061
9062           uentry_updateInto (old, unew);
9063           return;
9064         }
9065
9066       if (uentry_isExpandedMacro (old) 
9067           && uentry_isEitherConstant (unew))
9068         {
9069           uentry_updateInto (old, unew);
9070           return;
9071         }
9072
9073       if (uentry_isEndIter (unew))
9074         {
9075           if (ctype_isUnknown (old->utype))
9076             {
9077               if (!uentry_isSpecified (old)
9078                   && uentry_isCodeDefined (unew))
9079                 {
9080                   if (!fileloc_withinLines (uentry_whereDefined (old),
9081                                             uentry_whereDeclared (unew), 2))
9082                     { /* bogus!  will give errors if there is too much whitespace */
9083                       voptgenerror
9084                         (FLG_SYNTAX,
9085                          message
9086                          ("Iterator finalized name %q does not match name in "
9087                           "previous iter declaration (should be end_%q).  This iter "
9088                           "is declared at %q", 
9089                           uentry_getName (unew),
9090                           uentry_getName (old),
9091                           fileloc_unparse (uentry_whereDefined (old))),
9092                          uentry_whereDeclared (old));
9093                     }
9094                 }
9095
9096               uentry_updateInto (old, unew);
9097               return;
9098             }
9099           else
9100             {
9101               KindConformanceError (old, unew, mustConform);
9102             }
9103         }
9104
9105       if (uentry_isFunction (unew))
9106         {
9107           if (uentry_isVariable (old))
9108             {
9109               if (!ctype_isUnknown (old->utype))
9110                 {
9111                   if (ctype_isFunction (old->utype))
9112                     {
9113                       uentry_makeVarFunction (old);
9114                       checkFunctionConformance (old, unew, mustConform,
9115                                                 completeConform);
9116                       fcnConformance = TRUE;
9117                     }
9118                   else
9119                     {
9120                       KindConformanceError (old, unew, mustConform);
9121                     }
9122                 }
9123               else
9124                 {
9125                   if (uentry_isExpandedMacro (old))
9126                     {
9127                       if (fileloc_isUndefined (unew->whereDefined))
9128                         {
9129                           unew->whereDefined = fileloc_update (unew->whereDefined, 
9130                                                               old->whereDefined);
9131                         }
9132
9133                       uentry_updateInto (old, unew);
9134                       old->used = unew->used = TRUE;
9135                       return;
9136                     }
9137                   else
9138                     {
9139                       /* undeclared identifier */
9140                       old->utype = unew->utype;
9141                       uentry_makeVarFunction (old);
9142                       checkFunctionConformance (old, unew, FALSE, FALSE);
9143                       fcnConformance = TRUE;
9144                     }
9145                 }
9146             }
9147           else
9148             {
9149               KindConformanceError (old, unew, mustConform);
9150             }
9151         }
9152       else if (uentry_isFunction (old) && uentry_isVariable (unew))
9153         {
9154           if (!ctype_isUnknown (unew->utype))
9155             {
9156               if (ctype_isFunction (unew->utype))
9157                 {
9158                   uentry_makeVarFunction (unew);
9159                   checkFunctionConformance (old, unew, mustConform, completeConform);
9160                   fcnConformance = TRUE;
9161                 }
9162               else
9163                 {
9164                   KindConformanceError (old, unew, mustConform);
9165                 }
9166             }
9167           else
9168             {
9169               KindConformanceError (old, unew, mustConform);
9170             }
9171         }
9172       else
9173         {
9174           KindConformanceError (old, unew, mustConform);
9175         }
9176     }
9177   else
9178     {
9179       /*
9180       ** check parameter lists for functions 
9181       ** (before type errors, to get better messages
9182       */
9183
9184       if (uentry_isFunction (old))
9185         {
9186           checkFunctionConformance (old, unew, mustConform, completeConform);
9187           fcnConformance = TRUE;
9188         }
9189       else 
9190         {
9191           if (!ctype_isUndefined (old->utype))
9192             {
9193               typeError = checkTypeConformance (old, unew, mustConform);
9194             }
9195         }
9196     }
9197
9198  nokinderror:
9199
9200   if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9201     {
9202       uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9203     }
9204
9205   if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9206     {
9207       DPRINTF (("Check datatype: %s / %s",
9208                 uentry_unparseFull (old),
9209                 uentry_unparseFull (unew)));
9210
9211       uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9212     }
9213
9214   if (uentry_isVariable (old) && uentry_isVariable (unew))
9215     {
9216       if (!typeError && 
9217           !ctype_matchDef (old->utype, unew->utype))
9218         {
9219           if (optgenerror 
9220               (FLG_INCONDEFS,
9221                message
9222                ("Variable %q %s with inconsistent type (arrays and pointers are "
9223                 "not identical in variable declarations): %t",
9224                 uentry_getName (unew), 
9225                 uentry_reDefDecl (old, unew),
9226                 unew->utype),
9227                uentry_whereDeclared (unew)))
9228             {
9229               uentry_showWhereLast (old);
9230               
9231               /*
9232               ** Avoid repeated errors.
9233               */
9234
9235               if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9236                 {
9237                   old->whereDefined = fileloc_update (old->whereDefined,
9238                                                       fileloc_undefined);
9239                 }
9240
9241               typeError = TRUE;
9242             }
9243         }
9244
9245       checkVarConformance (old, unew, mustConform, completeConform);
9246     }
9247
9248   if (fcnConformance)
9249     {
9250       /* old->utype = unew->utype; */
9251     }
9252   else
9253     {
9254       if (ctype_isConj (old->utype))
9255         {
9256           if (ctype_isConj (unew->utype))
9257             {
9258               if (!ctype_sameAltTypes (old->utype, unew->utype))
9259                 {
9260                   if (optgenerror 
9261                       (FLG_INCONDEFS,
9262                        message ("%s %q inconsistently %rdeclared with "
9263                                 "alternate types %s "
9264                                 "(types match, but alternates are not identical, "
9265                                 "so checking may not be correct)",
9266                                 ekind_capName (uentry_getKind (old)),
9267                                 uentry_getName (unew),
9268                                 uentry_isDeclared (old),
9269                                 ctype_unparse (unew->utype)),
9270                        uentry_whereDeclared (unew)))
9271                     {
9272                       uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9273                     }
9274                   else
9275                     {
9276                       old->utype = unew->utype;
9277                     }
9278                 }
9279             }
9280         }
9281       else
9282         {
9283           if (ctype_isUnknown (old->utype))
9284             {
9285               old->utype = unew->utype;
9286             }
9287         }
9288     }  
9289
9290   if (unew->ukind == old->ukind) 
9291     {
9292       sfree (unew->info);
9293       unew->info = uinfo_copy (old->info, old->ukind);
9294     }
9295
9296   sRef_storeState (old->sref);
9297   sRef_storeState (unew->sref);
9298 }
9299
9300 static void uentry_mergeConstraints (uentry spec, uentry def)
9301 {
9302   if (uentry_isFunction (def))
9303     {
9304       DPRINTF (("Here: %s / %s",
9305                 uentry_unparseFull (spec),
9306                 uentry_unparseFull (def)));
9307       /* evans 2001-07-21 */
9308       llassert (uentry_isFunction (spec));
9309
9310       if (functionConstraint_isDefined (def->info->fcn->preconditions))
9311         {
9312           if (fileloc_isXHFile (uentry_whereLast (def)))
9313             {
9314               llassert (uentry_isFunction (spec));
9315               spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9316                                                                            def->info->fcn->preconditions);
9317             }
9318           else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9319             {
9320               ;
9321             }
9322           else
9323             {
9324               /* Check if the constraints are identical */
9325
9326               if (optgenerror 
9327                   (FLG_INCONDEFS,
9328                    message
9329                    ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9330                     uentry_getName (spec),
9331                     functionConstraint_unparse (spec->info->fcn->preconditions)),
9332                    uentry_whereLast (def)))
9333                 {
9334                   uentry_showWhereSpecified (spec);
9335                 }
9336
9337               functionConstraint_free (spec->info->fcn->preconditions);
9338               spec->info->fcn->preconditions = def->info->fcn->preconditions;
9339             }
9340           
9341           def->info->fcn->preconditions = functionConstraint_undefined;
9342         }
9343
9344       if (functionConstraint_isDefined (def->info->fcn->postconditions))
9345         {
9346           if (fileloc_isXHFile (uentry_whereLast (def)))
9347             {
9348               llassert (uentry_isFunction (spec));
9349               DPRINTF (("Post: %s /++/ %s",
9350                         functionConstraint_unparse (spec->info->fcn->postconditions),
9351                         functionConstraint_unparse (def->info->fcn->postconditions)));
9352               spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9353                                                                             def->info->fcn->postconditions);
9354               def->info->fcn->postconditions = functionConstraint_undefined;
9355               DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9356             }
9357           else
9358             {
9359               if (optgenerror 
9360                   (FLG_INCONDEFS,
9361                    message
9362                    ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9363                     uentry_getName (spec),
9364                     functionConstraint_unparse (spec->info->fcn->postconditions)),
9365                    uentry_whereLast (def)))
9366                 {
9367                   uentry_showWhereSpecified (spec);
9368                 }
9369               
9370               functionConstraint_free (spec->info->fcn->postconditions);
9371               spec->info->fcn->postconditions = def->info->fcn->postconditions;
9372               def->info->fcn->postconditions = functionConstraint_undefined;
9373             }
9374         }
9375     }
9376 }
9377
9378 /*
9379 ** modifies spec to reflect def, reports any inconsistencies
9380 */
9381
9382 void
9383 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9384 {
9385   llassert (uentry_isValid (spec));
9386   llassert (uentry_isValid (def));
9387   llassert (cstring_equal (spec->uname, def->uname));
9388
9389   if (uentry_isFunction (def))
9390     {
9391       if (uentry_isConstant (spec))
9392         {
9393           llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9394           uentry_makeConstantFunction (spec);
9395         }
9396       else
9397         {
9398           uentry_convertVarFunction (spec);
9399         }
9400
9401       llassert (uentry_isFunction (spec));
9402     }
9403   
9404   DPRINTF (("Merge entries: %s / %s",
9405             uentry_unparseFull (spec),
9406             uentry_unparseFull (def)));
9407
9408   uentry_mergeConstraints (spec, def);
9409
9410   uentry_checkConformance (spec, def, TRUE, 
9411                            context_getFlag (FLG_NEEDSPEC));
9412
9413   DPRINTF (("Merge entries after conform: %s / %s",
9414             uentry_unparseFull (spec),
9415             uentry_unparseFull (def)));
9416
9417   /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9418
9419   /*
9420   ** okay, declarations conform.  Propagate extra information.
9421   */
9422
9423   uentry_setDefined (spec, uentry_whereDefined (def));
9424   uentry_setDeclared (spec, uentry_whereDeclared (def));
9425
9426   if (uentry_isStatic (def))
9427     {
9428       if (optgenerror 
9429           (FLG_INCONDEFS,
9430            message ("%s %q specified, but declared as static",
9431                     ekind_capName (def->ukind),
9432                     uentry_getName (def)),
9433            uentry_whereDeclared (def)))
9434         {
9435           uentry_showWhereSpecified (spec);
9436         }
9437     }
9438   else 
9439     {
9440       spec->storageclass = def->storageclass;
9441     }
9442
9443   sRef_storeState (spec->sref);
9444
9445   spec->used = def->used || spec->used;
9446   spec->hasNameError |= def->hasNameError;
9447
9448   uentry_free (def);
9449
9450   if (!spec->hasNameError)
9451     {
9452       uentry_checkName (spec);
9453     }
9454   else
9455     {
9456       ;
9457     }
9458 }
9459
9460 /*
9461 ** Can't generate function redeclaration errors when the 
9462 ** entries are merged, since we don't yet know if its the
9463 ** definition of the function.
9464 */
9465
9466 void
9467 uentry_clearDecl (void)
9468 {
9469   posRedeclared = uentry_undefined;
9470   fileloc_free (posLoc);
9471   posLoc = fileloc_undefined;
9472 }
9473
9474 void
9475 uentry_checkDecl (void)
9476 {
9477   if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9478     {
9479       llassert (fileloc_isDefined (posLoc));
9480
9481       if (uentry_isCodeDefined (posRedeclared))
9482         {
9483           if (optgenerror (FLG_REDECL,
9484                            message ("%s %q declared after definition", 
9485                                     ekind_capName (posRedeclared->ukind),
9486                                     uentry_getName (posRedeclared)),
9487                            posLoc))
9488             {
9489               llgenindentmsg (message ("Definition of %q", 
9490                                        uentry_getName (posRedeclared)),
9491                               posRedeclared->whereDeclared);
9492             }
9493         }
9494       else
9495         {
9496           if (optgenerror (FLG_REDECL,
9497                            message ("%s %q declared more than once", 
9498                                     ekind_capName (posRedeclared->ukind),
9499                                     uentry_getName (posRedeclared)),
9500                            posLoc))
9501             {
9502               llgenindentmsg (message ("Previous declaration of %q", 
9503                                        uentry_getName (posRedeclared)),
9504                               posRedeclared->whereDeclared);
9505             }
9506         }
9507     }
9508
9509   fileloc_free (posLoc);
9510   posLoc = fileloc_undefined;
9511   posRedeclared = uentry_undefined;
9512 }
9513
9514 /*
9515 ** Redefinition of old as unew.
9516 ** modifies old to reflect unew, reports any inconsistencies
9517 */
9518
9519 void
9520 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9521 {
9522   fileloc olddef = uentry_whereDeclared (old); 
9523   fileloc unewdef = uentry_whereDeclared (unew);
9524   bool mustConform;
9525   bool wasForward;
9526
9527   DPRINTF (("uentry merge: %s / %s",
9528             uentry_unparseFull (old),
9529             uentry_unparseFull (unew)));
9530  
9531   wasForward = 
9532     fileloc_isUndefined (olddef) 
9533     && fileloc_isDefined (uentry_whereDefined (old)) 
9534     && !uentry_isExpandedMacro (old);
9535   
9536   if (!context_getFlag (FLG_INCONDEFSLIB)
9537       && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9538     {
9539       mustConform = FALSE;
9540     }
9541   else
9542     {
9543       mustConform = TRUE;
9544     }
9545   
9546   llassert (uentry_isValid (old));
9547   llassert (uentry_isValid (unew));
9548   llassert (cstring_equal (old->uname, unew->uname));
9549
9550   if (uentry_isFunction (unew) && !uentry_isFunction (old))
9551     {
9552       if (uentry_isConstant (old))
9553         {
9554           llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9555           uentry_makeConstantFunction (old);
9556         }
9557       else
9558         {
9559           uentry_convertVarFunction (old);
9560         }
9561
9562       llassert (uentry_isFunction (old));
9563     }
9564
9565   DPRINTF (("uentry merge: %s / %s",
9566             uentry_unparseFull (old),
9567             uentry_unparseFull (unew)));
9568
9569   if (uentry_isExtern (unew))
9570     {
9571       uentry_setUsed (old, unewdef);
9572     }
9573
9574   /*
9575   ** should check old one was extern!
9576   */
9577
9578   if (uentry_isStatic (old))
9579     {
9580       if (!(uentry_isStatic (unew)))
9581         {
9582           if (optgenerror 
9583               (FLG_SHADOW,
9584                message ("%s %q shadows static declaration",
9585                         ekind_capName (unew->ukind),
9586                         uentry_getName (unew)),
9587                unewdef))
9588             {
9589               uentry_showWhereLast (old);
9590             }
9591         }
9592       else
9593         {
9594           uentry_setDeclDef (old, unewdef);
9595         }
9596     }
9597   else if (uentry_isStatic (unew))
9598     {
9599       uentry_setDeclDef (old, unewdef);
9600     }
9601   else if (uentry_isExtern (old))
9602     {
9603       uentry_setDeclared (old, unewdef);
9604     }
9605   else
9606     {
9607       if (!uentry_isExtern (unew) 
9608           && !uentry_isForward (old)
9609           && !fileloc_equal (olddef, unewdef)
9610           && !fileloc_isUndefined (olddef)
9611           && !fileloc_isUndefined (unewdef)
9612           && !fileloc_isBuiltin (olddef)
9613           && !fileloc_isBuiltin (unewdef)
9614           && !uentry_isYield (old)
9615           && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9616         {
9617           if (uentry_isVariable (old) || uentry_isVariable (unew))
9618             {
9619               ; /* will report redeclaration error later */
9620             }
9621           else
9622             {
9623               if (fileloc_isDefined (uentry_whereDefined (old)))
9624                 {
9625                   if (optgenerror
9626                       (FLG_REDEF,
9627                        message ("%s %q defined more than once", 
9628                                 ekind_capName (unew->ukind),
9629                                 uentry_getName (unew)),
9630                        uentry_whereLast (unew)))
9631                     {
9632                       llgenindentmsg
9633                         (message ("Previous definition of %q", 
9634                                   uentry_getName (old)),
9635                          uentry_whereLast (old));
9636                     }
9637                   /*
9638                   if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9639                     {
9640                       uentry_updateInto (old, unew);
9641                       old->sref = sRef_saveCopy (old->sref);
9642                     }
9643                     */
9644                 }
9645             }
9646         }
9647       else
9648         {
9649           if (fileloc_isLib (olddef)
9650               || fileloc_isUndefined (olddef)
9651               || fileloc_isImport (olddef))
9652             {
9653               if (uentry_isExtern (unew)) 
9654                 {
9655                   if (uentry_isExtern (old)
9656                       || (fileloc_isDefined (uentry_whereDeclared (old))
9657                           && (!fileloc_equal (uentry_whereDeclared (old),
9658                                               uentry_whereDefined (old)))))
9659                     {
9660                       if (optgenerror
9661                           (FLG_REDECL,
9662                            message ("%s %q declared more than once", 
9663                                     ekind_capName (unew->ukind),
9664                                     uentry_getName (unew)),
9665                            unew->whereDeclared))
9666                         {
9667                           llgenindentmsg
9668                             (message ("Previous declaration of %q", 
9669                                       uentry_getName (old)),
9670                              old->whereDeclared);
9671                         }
9672                     }
9673                   
9674                   uentry_setExtern (old);
9675                 }
9676               else
9677                 {
9678                   uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9679                 }
9680             }
9681         }
9682     }
9683
9684   DPRINTF (("uentry merge: %s / %s",
9685             uentry_unparseFull (old),
9686             uentry_unparseFull (unew)));
9687
9688   uentry_mergeConstraints (old, unew);
9689   DPRINTF (("uentry merge: %s / %s",
9690             uentry_unparseFull (old),
9691             uentry_unparseFull (unew)));
9692
9693   uentry_checkConformance (old, unew, mustConform, FALSE);
9694   DPRINTF (("uentry merge: %s / %s",
9695             uentry_unparseFull (old),
9696             uentry_unparseFull (unew)));
9697
9698   old->used = old->used || unew->used;
9699   old->uses = filelocList_append (old->uses, unew->uses);
9700   unew->uses = filelocList_undefined; 
9701
9702   sRef_storeState (old->sref); 
9703   sRef_storeState (unew->sref);
9704
9705   if (wasForward)
9706     {
9707       old->whereDefined = fileloc_update (old->whereDefined,
9708                                           fileloc_undefined);
9709     }
9710
9711   DPRINTF (("here: %s", uentry_unparseFull (old)));
9712
9713   /*
9714   ** No redeclaration errors for functions here, since we
9715   ** don't know if this is the definition of the function.
9716   */
9717
9718   if (fileloc_isUser (old->whereDeclared)
9719       && fileloc_isUser (unew->whereDeclared)
9720       && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9721       && !fileloc_isDefined (unew->whereDefined))
9722     {
9723       if (uentry_isFunction (old))
9724         {
9725           /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9726           posLoc = fileloc_update (posLoc, unew->whereDeclared);
9727         }
9728       else
9729         {
9730           if (optgenerror (FLG_REDECL,
9731                            message ("%s %q declared more than once", 
9732                                     ekind_capName (unew->ukind),
9733                                     uentry_getName (unew)),
9734                            unew->whereDeclared))
9735             {
9736               llgenindentmsg (message ("Previous declaration of %q", 
9737                                        uentry_getName (old)),
9738                               old->whereDeclared);
9739             }
9740         }
9741     }
9742
9743   if (fileloc_isUndefined (old->whereDefined))
9744     {
9745       old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9746     }
9747   else
9748     {
9749       if (!context_processingMacros ()
9750           && fileloc_isUser (old->whereDefined) 
9751           && fileloc_isUser (unew->whereDefined)
9752           && !fileloc_equal (old->whereDefined, unew->whereDefined))
9753         {
9754           if (uentry_isVariable (unew) || uentry_isFunction (unew))
9755             {
9756               if (uentry_isVariable (unew) 
9757                   && uentry_isExtern (unew))
9758                 {
9759                   if (optgenerror (FLG_REDECL,
9760                                    message ("%s %q declared after definition", 
9761                                             ekind_capName (unew->ukind),
9762                                             uentry_getName (unew)),
9763                                    unew->whereDeclared))
9764                     {
9765                       llgenindentmsg (message ("Definition of %q", 
9766                                                uentry_getName (old)),
9767                                       old->whereDefined);
9768                     }
9769                 }
9770               else
9771                 {
9772                   if (optgenerror (FLG_REDEF,
9773                                    message ("%s %q redefined", 
9774                                             ekind_capName (unew->ukind),
9775                                             uentry_getName (unew)),
9776                                    unew->whereDefined))
9777                     {
9778                       llgenindentmsg (message ("Previous definition of %q", 
9779                                                uentry_getName (old)),
9780                                       old->whereDefined);
9781                     }
9782                 }
9783             }
9784         }
9785     }
9786
9787   if (uentry_isExternal (unew))
9788     {
9789       old->whereDefined = fileloc_createExternal ();
9790     }
9791
9792   if (unew->hasNameError)
9793     {
9794       old->hasNameError = TRUE;
9795     }
9796
9797   uentry_free (unew);
9798
9799   if (!old->hasNameError)
9800     {
9801       uentry_checkName (old);
9802     }
9803
9804   DPRINTF (("After: %s", uentry_unparseFull (old)));
9805   llassert (!ctype_isUndefined (old->utype));
9806 }
9807
9808 void
9809 uentry_copyState (uentry res, uentry other)
9810 {
9811   llassert (uentry_isValid (res));
9812   llassert (uentry_isValid (other));
9813
9814   res->used = other->used;
9815
9816   res->info->var->kind = other->info->var->kind;
9817   res->info->var->defstate = other->info->var->defstate;
9818   res->info->var->nullstate = other->info->var->nullstate;
9819   res->info->var->checked = other->info->var->checked;
9820
9821   sRef_copyState (res->sref, other->sref);
9822 }
9823
9824 bool
9825 uentry_sameKind (uentry u1, uentry u2)
9826 {
9827   if (uentry_isValid (u1) && uentry_isValid (u2))
9828     {
9829       if (uentry_isVar (u1) && uentry_isVar (u2))
9830         {
9831           ctype c1 = u1->utype;
9832           ctype c2 = u2->utype;
9833
9834           if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9835
9836           /*
9837           ** both functions, or both not functions
9838           */
9839
9840           return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9841         }
9842       else
9843         {
9844           return ((u1->ukind == u2->ukind));
9845         }
9846     }
9847   
9848   return FALSE;
9849 }
9850    
9851 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9852 {
9853   ekind okind;
9854   llassert (uentry_isValid (unew));
9855   llassert (uentry_isValid (old));
9856
9857   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9858   okind = unew->ukind;
9859   unew->ukind = old->ukind;
9860   llassert (cstring_equal (unew->uname, old->uname));
9861   unew->utype = old->utype;
9862
9863   if (fileloc_isDefined (unew->whereSpecified) 
9864       && !fileloc_isDefined (old->whereSpecified))
9865     {
9866       ; /* Keep the old value */
9867     }
9868   else
9869     {
9870       fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9871       unew->whereSpecified = fileloc_copy (old->whereSpecified);
9872     }
9873
9874   if (fileloc_isDefined (unew->whereDefined) 
9875       && !fileloc_isDefined (old->whereDefined))
9876     {
9877       ; /* Keep the old value */
9878     }
9879   else
9880     {
9881       fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9882       unew->whereDefined = fileloc_copy (old->whereDefined);
9883     }
9884
9885   if (fileloc_isDefined (unew->whereDeclared) 
9886       && !fileloc_isDefined (old->whereDeclared))
9887     {
9888       ; /* Keep the old value */
9889     }
9890   else
9891     {
9892       fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9893       unew->whereDeclared = fileloc_copy (old->whereDeclared);
9894     }
9895
9896   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9897
9898   unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9899   unew->used = old->used;
9900   unew->lset = FALSE;
9901   unew->isPrivate = old->isPrivate;
9902   unew->hasNameError = old->hasNameError;
9903   unew->uses = filelocList_append (unew->uses, old->uses);
9904   old->uses = filelocList_undefined;
9905
9906   unew->storageclass = old->storageclass;
9907   uinfo_free (unew->info, okind);
9908   unew->info = uinfo_copy (old->info, old->ukind);
9909 }
9910
9911 static uentry
9912 uentry_copyAux (uentry e, bool saveCopy)
9913 {
9914   
9915   if (uentry_isValid (e))
9916     {
9917       uentry enew = uentry_alloc ();
9918       DPRINTF (("copy: %s", uentry_unparseFull (e)));
9919       enew->ukind = e->ukind;
9920       enew->uname = cstring_copy (e->uname);
9921       enew->utype = e->utype;
9922       
9923       enew->whereSpecified = fileloc_copy (e->whereSpecified);
9924       enew->whereDefined = fileloc_copy (e->whereDefined);
9925       enew->whereDeclared = fileloc_copy (e->whereDeclared);
9926       
9927       if (saveCopy)
9928         {
9929           enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9930         }
9931       else
9932         {
9933           enew->sref = sRef_copy (e->sref);
9934         }
9935       
9936       enew->used = e->used;
9937       enew->lset = FALSE;
9938       enew->isPrivate = e->isPrivate;
9939       enew->hasNameError = e->hasNameError;
9940       enew->uses = filelocList_undefined;
9941       
9942       enew->storageclass = e->storageclass;
9943       enew->info = uinfo_copy (e->info, e->ukind);
9944       enew->warn = warnClause_copy (e->warn);
9945
9946       DPRINTF (("Here we are..."));
9947       DPRINTF (("original: %s", uentry_unparseFull (e)));
9948       DPRINTF (("copy: %s", uentry_unparse (enew)));
9949       DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9950       return enew;
9951     }
9952   else
9953     {
9954       return uentry_undefined;
9955     }
9956 }
9957
9958 uentry
9959 uentry_copy (uentry e)
9960 {
9961   return uentry_copyAux (e, TRUE);
9962 }
9963
9964 uentry
9965 uentry_copyNoSave (uentry e)
9966 {
9967   return uentry_copyAux (e, FALSE);
9968 }
9969
9970 void
9971 uentry_setState (uentry res, uentry other)
9972 {
9973   llassert (uentry_isValid (res));
9974   llassert (uentry_isValid (other));
9975
9976   llassert (res->ukind == other->ukind);
9977   llassert (res->ukind == KVAR);
9978
9979   res->sref = sRef_saveCopy (other->sref);
9980   res->used = other->used;
9981   filelocList_free (res->uses); 
9982   res->uses = other->uses; 
9983   other->uses = filelocList_undefined; 
9984   res->lset = other->lset;
9985 }
9986
9987 void
9988 uentry_mergeUses (uentry res, uentry other)
9989 {
9990   llassert (uentry_isValid (res));
9991   llassert (uentry_isValid (other));
9992
9993   res->used = other->used || res->used;
9994   res->lset = other->lset || res->lset;
9995   res->uses = filelocList_append (res->uses, other->uses);
9996   other->uses = filelocList_undefined;
9997 }
9998
9999
10000 /*
10001 ** This is a really ugly routine.
10002 **
10003 ** gack...fix this one day.
10004 */
10005
10006 /*
10007 ** flip == TRUE
10008 **   >> res is the false branch, other is the true branch (or continuation)
10009 ** flip == FALSE
10010 **   >> res is the true branch, other is the false branch (or continutation)
10011 **
10012 ** opt == TRUE if,
10013 **
10014 ** <other>
10015 ** if <res> ;
10016 **
10017 ** References not effected by res are propagated from other.
10018 */
10019
10020 static void
10021 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10022                   bool flip, clause cl, fileloc loc)
10023 {
10024   if (optgenerror 
10025       (FLG_BRANCHSTATE,
10026        message ("%s %q is %s %s, but %s %s.",
10027                 ekind_capName (res->ukind), uentry_getName (res),
10028                 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10029                 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10030        loc))
10031     {
10032       if (sRef_isDead (res->sref))
10033         {
10034           sRef_showStateInfo (res->sref);
10035           sRef_showStateInfo (other->sref);
10036         }
10037       else if (sRef_isKept (res->sref))
10038         {
10039           sRef_showAliasInfo (res->sref);
10040           sRef_showAliasInfo (other->sref);
10041         }
10042       else /* dependent */
10043         {
10044           sRef_showAliasInfo (res->sref);
10045           sRef_showAliasInfo (other->sref);
10046         }
10047       
10048       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10049     }
10050 }
10051
10052 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10053 {
10054   alkind rk = sRef_getAliasKind (rs);
10055   alkind ok = sRef_getAliasKind (os);
10056
10057   if (alkind_isError (rk) || alkind_isError (ok))
10058     {
10059       return FALSE;
10060     }
10061   else
10062     {
10063       return ((sRef_isDead (rs)
10064                || (alkind_isKept (rk) && !alkind_isKept (ok))
10065                || (alkind_isDependent (rk) 
10066                    && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10067               && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10068     }
10069 }
10070
10071 static void
10072   branchStateAltError (/*@notnull@*/ uentry res,
10073                        /*@notnull@*/ uentry other, bool flip,
10074                        clause cl, fileloc loc)
10075 {
10076   if (optgenerror 
10077       (FLG_BRANCHSTATE,
10078        message ("%s %q is %s %s, but %s %s.",
10079                 ekind_capName (res->ukind), uentry_getName (res),
10080                 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10081                 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10082        loc))
10083     {
10084       if (sRef_isDead (other->sref))
10085         {
10086           sRef_showStateInfo (other->sref);
10087         }
10088       else /* kept */
10089         {
10090           sRef_showAliasInfo (other->sref);
10091         }
10092       
10093       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10094       sRef_setDefinedComplete (res->sref, fileloc_undefined);
10095       
10096       sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10097       sRef_setDefinedComplete (other->sref, fileloc_undefined);
10098     }
10099 }
10100
10101 /*
10102 ** A reference is relevant for certain checks, only if it 
10103 ** is not definitely null on this path (but not declared
10104 ** to always be null.)
10105 */
10106
10107 static bool uentry_relevantReference (sRef sr, bool flip)
10108 {
10109   if (sRef_isKept (sr) || sRef_isDependent (sr))
10110     {
10111       return FALSE;
10112     }
10113   else
10114     {
10115       if (flip)
10116         {
10117           return !sRef_definitelyNullContext (sr);
10118         }
10119       else
10120         {
10121           return !sRef_definitelyNullAltContext (sr);
10122         }
10123     }
10124 }
10125
10126 static void
10127 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10128                          fileloc loc, bool mustReturn, bool flip, bool opt,
10129                          clause cl)    
10130 {
10131   sRef rs = res->sref;
10132   sRef os = other->sref;
10133
10134   DPRINTF (("Merge alias states: %s / %s",
10135             uentry_unparseFull (res),
10136             uentry_unparseFull (other)));
10137
10138   if (sRef_isValid (rs))
10139     {
10140       if (!mustReturn)
10141         {
10142           if (uentry_incompatibleMemoryStates (rs, os))
10143             {
10144               DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10145                         sRef_unparseFull (rs), sRef_unparseFull (os)));
10146
10147               if (sRef_isThroughArrayFetch (rs)
10148                   && !context_getFlag (FLG_STRICTBRANCHSTATE))
10149                 {
10150                   if (sRef_isKept (rs) || sRef_isKept (os))
10151                     {
10152                       sRef_maybeKill (rs, loc);
10153                     }
10154                   else if (sRef_isPossiblyDead (os))
10155                     {
10156                       sRef_maybeKill (rs, loc);
10157                     }
10158                   else
10159                     {
10160                       ;
10161                     }
10162                 }
10163               else
10164                 {
10165                   if (uentry_relevantReference (os, flip))
10166                     {
10167                       if (sRef_isLocalParamVar (rs) 
10168                           && (sRef_isLocalState (os) 
10169                               || sRef_isDependent (os)))
10170                         {
10171                           if (sRef_isDependent (rs))
10172                             {
10173                               sRef_setDependent (os, loc);
10174                             }
10175                           else
10176                             {
10177                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10178                             }
10179                         }
10180                       else 
10181                         {
10182                           branchStateError (res, other, flip, cl, loc);
10183                         }
10184                     }
10185                 }
10186               
10187               if (sRef_isKept (rs))
10188                 {
10189                   DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10190                   sRef_setKept (os, loc);
10191                 }
10192             }
10193           else
10194             {
10195               if (uentry_incompatibleMemoryStates (os, rs))
10196                 {
10197                   if (uentry_relevantReference (rs, !flip))
10198                     {
10199                       if (sRef_isLocalParamVar (rs) 
10200                           && (sRef_isDependent (rs)
10201                               || sRef_isLocalState (rs)))
10202                         {
10203                           if (sRef_isDependent (os))
10204                             {
10205                               sRef_setDependent (rs, loc);
10206                             }
10207                           else
10208                             {
10209                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10210                             }
10211                         }
10212                       else
10213                         {
10214                           if (sRef_isParam (os))
10215                             {
10216                               /* 
10217                               ** If the local variable associated
10218                               ** with the param has the correct state,
10219                               ** its okay.
10220                               ** (e.g., free (s); s = new(); ...
10221                               */
10222                               
10223                               uentry uvar = usymtab_lookupSafe (other->uname);
10224                               
10225                               if (uentry_isValid (uvar)
10226                                   && ((sRef_isDead (os) 
10227                                        && sRef_isOnly (uvar->sref))
10228                                       || (sRef_isDependent (os)
10229                                           && sRef_isOwned (uvar->sref))))
10230                                 {
10231                                   /* no error */
10232                                 }
10233                               else
10234                                 {
10235                                   branchStateAltError (res, other,
10236                                                        flip, cl, loc);
10237                                 }
10238                             }
10239                           else
10240                             {
10241                               DPRINTF (("Here: %s / %s",
10242                                         uentry_unparseFull (res),
10243                                         uentry_unparseFull (other)));
10244
10245                               branchStateAltError (res, other, 
10246                                                    flip, cl, loc);
10247                             }
10248                         }
10249                     }
10250                 }
10251               
10252               if (sRef_isKept (os))
10253                 {
10254                   sRef_setKept (rs, loc);
10255                 }
10256             }
10257           
10258           if (opt)
10259             {
10260               DPRINTF (("Merge opt..."));
10261               sRef_mergeOptState (rs, os, cl, loc);
10262               DPRINTF (("Done!"));
10263             }
10264           else
10265             {
10266               DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10267               sRef_mergeState (rs, os, cl, loc);
10268               DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10269             }
10270         }
10271       else
10272         {
10273           if (sRef_isModified (os))
10274             {
10275               sRef_setModified (rs);
10276             }
10277         }
10278     }
10279
10280   DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10281 }
10282
10283 static void
10284 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10285                          fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10286 {
10287   valueTable rvalues;
10288   valueTable ovalues;
10289
10290   DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10291   
10292   if (mustReturn)
10293     {
10294       return;
10295     }
10296   /* flip? */
10297
10298   rvalues = sRef_getValueTable (res->sref);
10299   ovalues = sRef_getValueTable (other->sref);
10300   
10301   if (valueTable_isUndefined (ovalues))
10302     {
10303       DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10304       ;
10305     }
10306   else if (valueTable_isUndefined (rvalues))
10307     {
10308       /*
10309       ** Copy values from other
10310       */
10311       
10312       /*@i$@#@*/
10313       DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10314       DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10315       ;
10316     }
10317   else
10318     {
10319       valueTable_elements (ovalues, fkey, fval) {
10320         stateValue tval;
10321         metaStateInfo minfo;
10322         stateCombinationTable sctable;
10323         cstring msg;
10324         int nval;
10325
10326         tval = valueTable_lookup (rvalues, fkey);
10327         
10328         DPRINTF (("Merge value: %s / %s X %s", fkey, 
10329                   stateValue_unparse (fval), stateValue_unparse (tval)));
10330
10331         minfo = context_lookupMetaStateInfo (fkey);
10332         llassert (stateValue_isDefined (tval));
10333         
10334         if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval)) 
10335           {
10336             DPRINTF (("Cannot find meta state for: %s", fkey));
10337             BADBRANCH;
10338           }
10339         else
10340           {
10341             llassert (metaStateInfo_isDefined (minfo));
10342
10343             if (stateValue_isError (fval)
10344                 || sRef_definitelyNullContext (res->sref))
10345               {
10346                 sRef_setMetaStateValueComplete (res->sref, 
10347                                                 fkey, stateValue_getValue (fval), 
10348                                                 stateValue_getLoc (fval));
10349                 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10350               }
10351             else if (stateValue_isError (tval)
10352                      || sRef_definitelyNullAltContext (other->sref))
10353               {
10354                 DPRINTF (("Other branch is definitely null!"));
10355               }
10356             else if (sRef_isStateUndefined (res->sref)
10357                      || sRef_isDead (res->sref))
10358               {
10359                 ; /* Combination state doesn't matter if it is undefined or dead */
10360               }
10361             else 
10362               {
10363                 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10364                           metaStateInfo_unparse (minfo),
10365                           stateValue_unparse (fval),
10366                           stateValue_unparse (tval)));
10367                 
10368                 DPRINTF (("state values: %d / %d",
10369                           stateValue_getValue (fval), stateValue_getValue (tval)));
10370                 
10371                 sctable = metaStateInfo_getMergeTable (minfo);
10372
10373                 DPRINTF (("Merge table: %s",
10374                           stateCombinationTable_unparse (sctable)));
10375                 
10376                 msg = cstring_undefined;
10377                 
10378                 nval = stateCombinationTable_lookup (sctable, 
10379                                                      stateValue_getValue (fval), 
10380                                                      stateValue_getValue (tval), 
10381                                                      &msg);
10382
10383                 DPRINTF (("nval: %d / %d / %d", nval,
10384                           stateValue_getValue (fval), stateValue_getValue (tval)));
10385
10386                 if (nval == stateValue_error)
10387                   {
10388                     /*@i32 print extra info for assignments@*/
10389
10390                     if (uentry_isGlobalMarker (res))
10391                       {
10392                         if (optgenerror 
10393                             (FLG_STATEMERGE,
10394                              message
10395                              ("Control branches merge with incompatible global states (%s and %s)%q",
10396                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10397                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10398                               cstring_isDefined (msg) 
10399                               ? message (": %s", msg) : cstring_undefined),
10400                              loc))
10401                           {
10402                             sRef_showMetaStateInfo (res->sref, fkey);
10403                             sRef_showMetaStateInfo (other->sref, fkey);
10404                           }
10405                       }
10406                     else
10407                       {
10408                         if (optgenerror 
10409                             (FLG_STATEMERGE,
10410                              message
10411                              ("Control branches merge with incompatible states for %q (%s and %s)%q",
10412                               uentry_getName (res),
10413                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10414                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10415                               cstring_isDefined (msg) 
10416                               ? message (": %s", msg) : cstring_undefined),
10417                              loc))
10418                           {
10419                             sRef_showMetaStateInfo (res->sref, fkey);
10420                             sRef_showMetaStateInfo (other->sref, fkey);
10421                             DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10422                             DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10423                             DPRINTF (("Null: %s / %s",
10424                                       bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10425                                       bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10426
10427                           }
10428                       }
10429                   }
10430
10431                 if (nval == stateValue_getValue (fval)
10432                     && nval != stateValue_getValue (tval))
10433                   {
10434                     loc = stateValue_getLoc (fval);
10435                   }
10436                 else if (nval == stateValue_getValue (tval)
10437                          && nval != stateValue_getValue (fval))
10438                   {
10439                     loc = stateValue_getLoc (tval);
10440                   }
10441                 else
10442                   {
10443                     ;
10444                   }
10445
10446                 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10447                     && nval == stateValue_getValue (fval)
10448                     && nval == stateValue_getValue (tval))
10449                   {
10450                     ;
10451                   }
10452                 else
10453                   {
10454                     sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10455                   }
10456               }
10457           }
10458       } end_valueTable_elements ;
10459     } 
10460 }
10461
10462
10463 static void
10464 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10465                        /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10466                        bool flip, clause cl)
10467 {
10468   if (cl == DOWHILECLAUSE)
10469     {
10470       res->used = other->used || res->used;
10471       res->lset = other->lset || res->lset;
10472       res->uses = filelocList_append (res->uses, other->uses);
10473       other->uses = filelocList_undefined;
10474     }
10475   else
10476     {
10477       if (sRef_isMacroParamRef (res->sref)
10478           && !uentry_isSefParam (other)
10479           && !uentry_isSefParam (res))
10480         {
10481           bool hasError = FALSE;
10482           
10483           if (bool_equal (res->used, other->used))
10484             {
10485               res->used = other->used;
10486             }
10487           else
10488             {
10489               if (other->used && !flip)
10490                 {
10491                   hasError = 
10492                     optgenerror 
10493                     (FLG_MACROPARAMS,
10494                      message ("Macro parameter %q used in true clause, "
10495                               "but not in false clause",
10496                               uentry_getName (res)),
10497                      uentry_whereDeclared (res));
10498                 }
10499               else
10500                 {       
10501                   hasError = 
10502                     optgenerror 
10503                     (FLG_MACROPARAMS,
10504                      message ("Macro parameter %q used in false clause, "
10505                               "but not in true clause",
10506                               uentry_getName (res)),
10507                      uentry_whereDeclared (res));
10508                 }
10509               res->used = TRUE;
10510               
10511               if (hasError)
10512                 {
10513                   /* make it sef now, prevent more errors */
10514                   res->info->var->kind = VKREFSEFPARAM;
10515                 }
10516             }
10517         }
10518       else
10519         {
10520           res->used = other->used || res->used;
10521           res->lset = other->lset || res->lset;
10522           res->uses = filelocList_append (res->uses, other->uses);
10523           other->uses = filelocList_undefined;
10524         }
10525     }
10526 }
10527
10528 void
10529 uentry_mergeState (uentry res, uentry other, fileloc loc,
10530                    bool mustReturn, bool flip, bool opt,
10531                    clause cl)
10532 {
10533   llassert (uentry_isValid (res));
10534   llassert (uentry_isValid (other));
10535
10536   llassert (res->ukind == other->ukind);
10537   llassert (res->ukind == KVAR);
10538
10539   DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10540             uentry_unparseFull (other)));
10541   
10542   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10543   uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10544   uentry_mergeSetStates (res, other, loc, flip, cl);
10545
10546   DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10547 }
10548
10549 void uentry_setUsed (uentry e, fileloc loc)
10550 {
10551   static bool firstTime = TRUE;
10552   static bool showUses = FALSE;
10553   static bool exportLocal = FALSE;
10554
10555   DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10556
10557   if (firstTime)
10558     {
10559       /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10560
10561       showUses = context_getFlag (FLG_SHOWUSES); 
10562       exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10563
10564       firstTime = FALSE;
10565     }
10566
10567   if (uentry_isValid (e))
10568     {
10569       int dp;
10570
10571       if (warnClause_isDefined (e->warn))
10572         {
10573           flagSpec flg = warnClause_getFlag (e->warn);
10574           cstring msg;
10575
10576           if (warnClause_hasMessage (e->warn))
10577             {
10578               msg = cstring_copy (warnClause_getMessage (e->warn));
10579             }
10580           else
10581             {
10582               msg = message ("Use of possibly dangerous %s",
10583                              uentry_ekindNameLC (e));
10584             }
10585
10586           vfsgenerror (flg, 
10587                        message ("%q: %q", msg, uentry_getName (e)),
10588                        loc);
10589         }
10590
10591       if (sRef_isMacroParamRef (e->sref))
10592         {
10593           if (uentry_isYield (e) || uentry_isSefParam (e))
10594             {
10595               ;
10596             }
10597           else 
10598             {
10599               if (context_inConditional ())
10600                 {
10601                   if (optgenerror
10602                       (FLG_MACROPARAMS,
10603                        message ("Macro parameter %q used in conditionally "
10604                                 "executed code (may or may not be "
10605                                 "evaluated exactly once)", 
10606                                 uentry_getName (e)),
10607                        loc))
10608                     {
10609                       e->info->var->kind = VKREFSEFPARAM;
10610                     }
10611                 }
10612               else
10613                 {
10614                   if ((e)->used)
10615                     {
10616                       if (optgenerror
10617                           (FLG_MACROPARAMS,
10618                            message ("Macro parameter %q used more than once", 
10619                                     uentry_getName (e)),
10620                            uentry_whereDeclared (e)))
10621                         {
10622                           e->info->var->kind = VKREFSEFPARAM;
10623                         }
10624                     }
10625                 }
10626             }
10627         }
10628       
10629       if ((dp = uentry_directParamNo (e)) >= 0)
10630         {
10631           uentry_setUsed (usymtab_getParam (dp), loc);
10632         }
10633       
10634       e->used = TRUE;
10635
10636       if (!sRef_isLocalVar (e->sref))
10637         {
10638           if (showUses)
10639             {
10640               e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10641             }
10642           else 
10643             {
10644               if (exportLocal)
10645                 {
10646                   if (context_inMacro ())
10647                     {
10648                       e->uses = filelocList_addUndefined (e->uses);
10649                     }
10650                   else 
10651                     {
10652                       e->uses = filelocList_addDifferentFile
10653                         (e->uses, 
10654                          uentry_whereDeclared (e),
10655                          loc);
10656                     }
10657                 }
10658             }
10659         }
10660     }
10661 }
10662
10663 bool uentry_isReturned (uentry u)
10664 {
10665   return (uentry_isValid (u) && uentry_isVar (u) 
10666           && (u->info->var->kind == VKRETPARAM
10667               || u->info->var->kind == VKSEFRETPARAM));
10668 }
10669
10670 /*@i52323@*/
10671 # if 0
10672 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10673 {
10674   llassert (uentry_isRealFunction (u));
10675
10676   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10677     {
10678       stateClauseList clauses = uentry_getStateClauseList (u);
10679       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10680
10681       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10682       sRef_setAllocated (res, g_currentloc);
10683
10684       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10685                 stateClauseList_unparse (clauses)));
10686
10687       /*
10688       ** This should be in exprNode_reflectEnsuresClause
10689       */
10690
10691       stateClauseList_postElements (clauses, cl)
10692         {
10693           if (!stateClause_isGlobal (cl))
10694             {
10695               sRefSet refs = stateClause_getRefs (cl);
10696               sRefMod modf = stateClause_getEffectFunction (cl);
10697               
10698               sRefSet_elements (refs, el)
10699                 {
10700                   sRef base = sRef_getRootBase (el);
10701                   
10702                   if (sRef_isResult (base))
10703                     {
10704                       if (modf != NULL)
10705                         {
10706                           sRef sr = sRef_fixBase (el, res);
10707                           modf (sr, g_currentloc);
10708                         }
10709                     }
10710                   else
10711                     {
10712                       ;
10713                     }
10714                 } end_sRefSet_elements ;
10715             }
10716         } end_stateClauseList_postElements ;
10717         
10718       return res;
10719     }
10720   else
10721     {
10722       uentryList params;
10723       alkind ak;
10724       sRefSet prefs = sRefSet_new ();
10725       sRef res = sRef_undefined;
10726       sRef tcref = sRef_undefined;
10727       sRef tref = sRef_undefined;
10728       int paramno = 0;
10729       
10730       params = uentry_getParams (u);
10731
10732       /*
10733       ** Setting up aliases has to happen *after* setting null state!
10734       */
10735
10736       uentryList_elements (params, current)
10737         {
10738           if (uentry_isReturned (current))
10739             {
10740               if (exprNodeList_size (args) >= paramno)
10741                 {
10742                   exprNode ecur = exprNodeList_nth (args, paramno);
10743                   tref = exprNode_getSref (ecur);
10744                   
10745                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10746
10747                   if (sRef_isValid (tref))
10748                     {
10749                       tcref = sRef_copy (tref);
10750                       
10751                       if (sRef_isDead (tcref))
10752                         {
10753                           sRef_setDefined (tcref, g_currentloc);
10754                           sRef_setOnly (tcref, g_currentloc);
10755                         }
10756                       
10757                       if (sRef_isRefCounted (tcref))
10758                         {
10759                           /* could be a new ref now (but only if its returned) */
10760                           sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10761                         }
10762                       
10763                       sRef_makeSafe (tcref);
10764                       prefs = sRefSet_insert (prefs, tcref);
10765                     }
10766                 }
10767             }
10768           
10769           paramno++;
10770         } end_uentryList_elements ;
10771
10772       if (sRefSet_size (prefs) > 0)
10773         {
10774           nstate n = sRef_getNullState (u->sref);
10775
10776           if (sRefSet_size (prefs) == 1)
10777             {
10778               sRef rref = sRefSet_choose (prefs);
10779               tref = rref;
10780               res = sRef_makeType (sRef_getType (rref));
10781               sRef_copyState (res, tref);
10782             }
10783           else
10784             {
10785               /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10786               res = sRefSet_mergeIntoOne (prefs);
10787             }
10788           
10789           if (nstate_isKnown (n))
10790             {
10791               sRef_setNullState (res, n, g_currentloc);
10792               DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10793             }
10794         }
10795       else
10796         {
10797           if (ctype_isFunction (u->utype))
10798             {
10799               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10800               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10801             }
10802           else
10803             {
10804               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10805               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10806             }
10807           
10808           if (sRef_isRefCounted (res))
10809             {
10810               sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10811             }
10812         }
10813       
10814       if (sRef_getNullState (res) == NS_ABSNULL)
10815         {
10816           ctype ct = ctype_realType (u->utype);
10817           
10818           if (ctype_isAbstract (ct))
10819             {
10820               sRef_setNotNull (res, g_currentloc);
10821             }
10822           else
10823             {
10824               if (ctype_isUser (ct))
10825                 {
10826                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10827                 }
10828               else
10829                 {
10830                   sRef_setNotNull (res, g_currentloc);
10831                 }
10832             }
10833         }
10834       
10835       if (sRef_isRefCounted (res))
10836         {
10837           sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10838         }
10839       else if (sRef_isKillRef (res))
10840         {
10841           sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10842         }
10843       else
10844         {
10845           ;
10846         }
10847       
10848       ak = sRef_getAliasKind (res);
10849       
10850       if (alkind_isImplicit (ak))
10851         {
10852           sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10853         }
10854
10855 # if 0
10856       DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10857       usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10858
10859       /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10860       usymtab_addReallyForceMustAlias (res, tref);
10861 # endif
10862
10863       sRefSet_free (prefs);
10864       
10865       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10866       return res;
10867     }
10868 }
10869 # endif
10870
10871 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
10872 {
10873   llassert (uentry_isRealFunction (u));
10874
10875   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10876     {
10877       stateClauseList clauses = uentry_getStateClauseList (u);
10878       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10879
10880       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10881       sRef_setAllocated (res, loc);
10882
10883       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10884                 stateClauseList_unparse (clauses)));
10885
10886       /*
10887       ** This should be in exprNode_reflectEnsuresClause
10888       */
10889
10890       stateClauseList_postElements (clauses, cl)
10891         {
10892           if (!stateClause_isGlobal (cl))
10893             {
10894               sRefSet refs = stateClause_getRefs (cl);
10895               sRefMod modf = stateClause_getEffectFunction (cl);
10896               
10897               sRefSet_elements (refs, el)
10898                 {
10899                   sRef base = sRef_getRootBase (el);
10900                   
10901                   if (sRef_isResult (base))
10902                     {
10903                       if (modf != NULL)
10904                         {
10905                           sRef sr = sRef_fixBase (el, res);
10906                           modf (sr, loc);
10907                         }
10908                     }
10909                   else
10910                     {
10911                       ;
10912                     }
10913                 } end_sRefSet_elements ;
10914             }
10915         } end_stateClauseList_postElements ;
10916         
10917       return res;
10918     }
10919   else
10920     {
10921       uentryList params;
10922       alkind ak;
10923       sRefSet prefs = sRefSet_new ();
10924       sRef res = sRef_undefined;
10925       int paramno = 0;
10926       
10927       params = uentry_getParams (u);
10928       
10929       uentryList_elements (params, current)
10930         {
10931           if (uentry_isReturned (current))
10932             {
10933               if (exprNodeList_size (args) >= paramno)
10934                 {
10935                   exprNode ecur = exprNodeList_nth (args, paramno);
10936                   sRef tref = exprNode_getSref (ecur);
10937                   
10938                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10939
10940                   if (sRef_isValid (tref))
10941                     {
10942                       sRef tcref = sRef_copy (tref);
10943                       
10944                       usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10945
10946                       if (sRef_isNew (tcref))
10947                         {
10948                           /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
10949                         }
10950
10951                       if (sRef_isDead (tcref))
10952                         {
10953                           sRef_setDefined (tcref, loc);
10954                           sRef_setOnly (tcref, loc);
10955                         }
10956                       
10957                       if (sRef_isRefCounted (tcref))
10958                         {
10959                           /* could be a new ref now (but only if its returned) */
10960                           sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
10961                         }
10962                       
10963                       sRef_makeSafe (tcref);
10964                       DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
10965                       prefs = sRefSet_insert (prefs, tcref);
10966                     }
10967                 }
10968             }
10969           
10970           paramno++;
10971         } end_uentryList_elements ;
10972       
10973       if (sRefSet_size (prefs) > 0)
10974         {
10975           nstate n = sRef_getNullState (u->sref);
10976           
10977           if (sRefSet_size (prefs) == 1)
10978             {
10979               res = sRefSet_choose (prefs);
10980             }
10981           else
10982             {
10983               /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10984               res = sRefSet_mergeIntoOne (prefs);
10985             }
10986           
10987           if (nstate_isKnown (n))
10988             {
10989               sRef_setNullState (res, n, loc);
10990             }
10991         }
10992       else
10993         {
10994           if (ctype_isFunction (u->utype))
10995             {
10996               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10997               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10998             }
10999           else
11000             {
11001               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
11002             }
11003           
11004           if (sRef_isRefCounted (res))
11005             {
11006               sRef_setAliasKind (res, AK_NEWREF, loc);
11007             }
11008         }
11009       
11010
11011       if (sRef_getNullState (res) == NS_ABSNULL)
11012         {
11013           ctype ct = ctype_realType (u->utype);
11014           
11015           if (ctype_isAbstract (ct))
11016             {
11017               sRef_setNotNull (res, loc);
11018             }
11019           else
11020             {
11021               if (ctype_isUser (ct))
11022                 {
11023                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
11024                 }
11025               else
11026                 {
11027                   sRef_setNotNull (res, loc);
11028                 }
11029             }
11030         }
11031       
11032       if (sRef_isRefCounted (res))
11033         {
11034           sRef_setAliasKind (res, AK_NEWREF, loc);
11035         }
11036       else if (sRef_isKillRef (res))
11037         {
11038           sRef_setAliasKind (res, AK_REFCOUNTED, loc);
11039         }
11040       else
11041         {
11042           ;
11043         }
11044       
11045       ak = sRef_getAliasKind (res);
11046       
11047       if (alkind_isImplicit (ak))
11048         {
11049           sRef_setAliasKind (res, 
11050                              alkind_fixImplicit (ak),
11051                              loc);
11052         }
11053       
11054       sRefSet_free (prefs);
11055
11056       /*
11057       if (sRef_isOnly (res))
11058         {
11059           sRef_setFresh (res, loc);
11060         }
11061       */
11062
11063       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11064       return res;
11065     }
11066 }
11067
11068 static bool uentry_isRefCounted (uentry ue)
11069 {
11070   ctype ct = uentry_getType (ue);
11071
11072   if (ctype_isFunction (ct))
11073     {
11074       return (ctype_isRefCounted (ctype_getReturnType (ct)));
11075     }
11076   else
11077     {
11078       return (ctype_isRefCounted (ct));
11079     }
11080 }
11081
11082 /*
11083 ** old was declared yield in the specification.  
11084 ** new is declared in the iter implementation.
11085 */
11086
11087 void uentry_checkYieldParam (uentry old, uentry unew)
11088 {
11089   cstring name;
11090
11091   llassert (uentry_isVariable (old));
11092   llassert (uentry_isVariable (unew));
11093
11094   unew->info->var->kind = VKYIELDPARAM;
11095   (void) checkTypeConformance (old, unew, TRUE);
11096   checkVarConformance (old, unew, TRUE, FALSE);
11097
11098   /* get rid of param marker */
11099
11100   name = uentry_getName (unew);
11101   cstring_free (unew->uname);
11102   unew->uname = name;
11103   unew->info->var->kind = VKREFYIELDPARAM;
11104
11105   uentry_setUsed (old, fileloc_undefined);
11106   uentry_setUsed (unew, fileloc_undefined);
11107 }
11108
11109 /*@observer@*/ cstring
11110 uentry_ekindName (uentry ue)
11111 {
11112   if (uentry_isValid (ue))
11113     {
11114       switch (ue->ukind)
11115         {
11116         case KINVALID:
11117           return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11118         case KDATATYPE: 
11119           return cstring_makeLiteralTemp ("Datatype");
11120         case KENUMCONST:
11121           return cstring_makeLiteralTemp ("Enum member");
11122         case KCONST:  
11123           return cstring_makeLiteralTemp ("Constant");
11124         case KVAR:      
11125           if (uentry_isParam (ue))
11126             {
11127               return cstring_makeLiteralTemp ("Parameter");
11128             }
11129           else if (uentry_isExpandedMacro (ue))
11130             {
11131               return cstring_makeLiteralTemp ("Expanded macro");
11132             }
11133           else
11134             {
11135               return cstring_makeLiteralTemp ("Variable");
11136             }
11137         case KFCN:   
11138           return cstring_makeLiteralTemp ("Function");
11139         case KITER: 
11140           return cstring_makeLiteralTemp ("Iterator");
11141         case KENDITER:
11142           return cstring_makeLiteralTemp ("Iterator finalizer");
11143         case KSTRUCTTAG:
11144           return cstring_makeLiteralTemp ("Struct tag");
11145         case KUNIONTAG:
11146           return cstring_makeLiteralTemp ("Union tag");
11147         case KENUMTAG: 
11148           return cstring_makeLiteralTemp ("Enum tag");
11149         case KELIPSMARKER: 
11150           return cstring_makeLiteralTemp ("Optional parameters");
11151         }
11152     }
11153   else
11154     {
11155       return cstring_makeLiteralTemp ("<Undefined>");
11156     }
11157
11158   BADEXIT;
11159 }
11160
11161 /*@observer@*/ cstring
11162 uentry_ekindNameLC (uentry ue)
11163 {
11164   if (uentry_isValid (ue))
11165     {
11166       switch (ue->ukind)
11167         {
11168         case KINVALID:
11169           return cstring_makeLiteralTemp ("<error: invalid uentry>");
11170         case KDATATYPE: 
11171           return cstring_makeLiteralTemp ("datatype");
11172         case KENUMCONST:
11173           return cstring_makeLiteralTemp ("enum member");
11174         case KCONST:  
11175           return cstring_makeLiteralTemp ("constant");
11176         case KVAR:      
11177           if (uentry_isParam (ue))
11178             {
11179               return cstring_makeLiteralTemp ("parameter");
11180             }
11181           else if (uentry_isExpandedMacro (ue))
11182             {
11183               return cstring_makeLiteralTemp ("expanded macro");
11184             }
11185           else
11186             {
11187               return cstring_makeLiteralTemp ("variable");
11188             }
11189         case KFCN:   
11190           return cstring_makeLiteralTemp ("function");
11191         case KITER: 
11192           return cstring_makeLiteralTemp ("iterator");
11193         case KENDITER:
11194           return cstring_makeLiteralTemp ("iterator finalizer");
11195         case KSTRUCTTAG:
11196           return cstring_makeLiteralTemp ("struct tag");
11197         case KUNIONTAG:
11198           return cstring_makeLiteralTemp ("union tag");
11199         case KENUMTAG: 
11200           return cstring_makeLiteralTemp ("enum tag");
11201         case KELIPSMARKER: 
11202           return cstring_makeLiteralTemp ("optional parameters");
11203         }
11204     }
11205   else
11206     {
11207       return cstring_makeLiteralTemp ("<Undefined>");
11208     }
11209
11210   BADEXIT;
11211 }
11212
11213 void uentry_setHasNameError (uentry ue)
11214 {
11215   llassert (uentry_isValid (ue));
11216
11217   ue->hasNameError = TRUE;
11218 }
11219
11220 void uentry_checkName (uentry ue)
11221 {
11222   DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11223             uentry_observeRealName (ue),
11224             bool_unparse (uentry_isVisibleExternally (ue))));
11225   
11226   if (uentry_isValid (ue) 
11227       && !context_inXHFile ()
11228       && uentry_hasName (ue)
11229       && !uentry_isElipsisMarker (ue)
11230       && context_getFlag (FLG_NAMECHECKS)
11231       && !ue->hasNameError 
11232       && !uentry_isEndIter (ue)
11233       && !fileloc_isBuiltin (uentry_whereLast (ue))
11234       && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11235     {      
11236       DPRINTF (("Here..."));
11237
11238       if (uentry_isPriv (ue))
11239         {
11240           ; /* any checks here? */
11241         }
11242       else if (fileloc_isExternal (uentry_whereDefined (ue)))
11243         {
11244           ; /* no errors for externals */
11245         }
11246       else
11247         {
11248           int scope;
11249           
11250           if (uentry_isExpandedMacro (ue))
11251             {
11252               scope = globScope;
11253             }
11254           else
11255             {
11256               if (uentry_isExpandedMacro (ue))
11257                 {
11258                   scope = fileScope;
11259                 }
11260               else if (uentry_isVariable (ue))
11261                 {
11262                   sRef sr = uentry_getSref (ue);
11263
11264                   if (sRef_isValid (sr))
11265                     {
11266                       scope = sRef_getScope (sr);
11267                     }
11268                   else
11269                     {
11270                       scope = fileScope; 
11271                     }
11272                 }
11273               else if (uentry_isFunction (ue)
11274                        || uentry_isIter (ue)
11275                        || uentry_isEndIter (ue)
11276                        || uentry_isConstant (ue))
11277                 {
11278                   scope = uentry_isStatic (ue) ? fileScope : globScope;
11279                 }
11280               else /* datatypes, etc. must be global */
11281                 {
11282                   scope = globScope;
11283                 }
11284               
11285               usymtab_checkDistinctName (ue, scope);
11286             }
11287         
11288           if (context_getFlag (FLG_CPPNAMES)) 
11289             {
11290               checkCppName (ue);
11291             }
11292
11293           if (scope == globScope)
11294             {
11295               checkExternalName (ue);
11296             }
11297           else if (scope == fileScope)
11298             {
11299               checkFileScopeName (ue);
11300             }
11301           else 
11302             {
11303               checkLocalName (ue);
11304             }
11305
11306           checkPrefix (ue);
11307           checkAnsiName (ue);
11308         }
11309     }
11310 }
11311
11312 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11313 {
11314   uentry ue;
11315   fileloc tloc;
11316
11317   /*
11318   ** Can't but unrecognized ids in macros in global scope, because srefs will break! 
11319   */
11320
11321   if (!context_inMacro ())
11322     {
11323       sRef_setGlobalScopeSafe ();
11324     }
11325
11326   ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11327   uentry_setUsed (ue, loc);               
11328   
11329   tloc = fileloc_createExternal ();
11330   uentry_setDefined (ue, tloc);
11331   fileloc_free (tloc);
11332   uentry_setHasNameError (ue);
11333   
11334   if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11335     {
11336       uentry_markOwned (ue);
11337     }
11338   else
11339     {
11340       ue = usymtab_supReturnFileEntry (ue);
11341     }
11342   
11343   if (!context_inMacro ())
11344     {
11345       sRef_clearGlobalScopeSafe ();
11346     }
11347
11348   return ue;
11349 }
11350
11351 uentry uentry_makeGlobalMarker ()
11352 {
11353   uentry ue;
11354   fileloc tloc;
11355
11356   llassert (sRef_inGlobalScope ());
11357   
11358   ue = uentry_makeVariableAux
11359     (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined, 
11360      sRef_makeGlobalMarker (),
11361      FALSE, VKNORMAL);
11362
11363   tloc = fileloc_createExternal ();
11364   uentry_setUsed (ue, tloc);              
11365   uentry_setDefined (ue, tloc);
11366   fileloc_free (tloc);
11367   uentry_setHasNameError (ue);  
11368
11369   return ue;
11370 }
11371
11372
11373 bool uentry_isGlobalMarker (uentry ue)
11374 {
11375   return (uentry_isValid (ue)
11376           && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11377 }
11378
11379 /* new start modifications */
11380
11381 /* start modifications */
11382 /*
11383 requires: p_e is defined, is a ptr/array variable 
11384 modifies: p_e
11385 effects: sets the state of the variable
11386 */
11387
11388
11389 void uentry_setPossiblyNullTerminatedState (uentry p_e)  
11390 {
11391   llassert (uentry_isValid (p_e));
11392
11393   if (p_e->info != NULL)
11394     {
11395       if (p_e->info->var != NULL) 
11396         {
11397           llassert (p_e->info->var->bufinfo != NULL);
11398           p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11399           sRef_setPossiblyNullTerminatedState (p_e->sref);
11400         }
11401     }
11402 }
11403
11404 /*
11405 requires: p_e is defined, is a ptr/array variable 
11406 modifies: p_e
11407 effects: sets the size of the buffer
11408 */
11409
11410 void uentry_setNullTerminatedState (uentry p_e)  {
11411   llassert (uentry_isValid (p_e));
11412
11413   if (p_e->info != NULL)
11414     {
11415       if (p_e->info->var != NULL)
11416         {
11417           llassert (p_e->info->var->bufinfo != NULL);
11418           p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11419           sRef_setNullTerminatedState (p_e->sref);
11420         }
11421     }
11422 }
11423
11424 /*
11425 requires: p_e is defined, is a ptr/array variable 
11426 modifies: p_e
11427 effects: sets the size of the buffer
11428 */
11429
11430 void uentry_setSize (uentry p_e, int size)  
11431 {
11432   if (uentry_isValid (p_e))
11433     {
11434       if (p_e->info != NULL) 
11435         {
11436           if (p_e->info->var != NULL) 
11437             {
11438               llassert (p_e->info->var->bufinfo != NULL);
11439               p_e->info->var->bufinfo->size = size;
11440               sRef_setSize (p_e->sref, size);
11441             }
11442         }
11443     }
11444 }
11445
11446 /*
11447 requires: p_e is defined, is a ptr/array variable 
11448 modifies: p_e
11449 effects: sets the length of the buffer
11450 */
11451
11452 void uentry_setLen (uentry p_e, int len)  
11453 {
11454   if (uentry_isValid (p_e)) 
11455     {
11456       if (p_e->info != NULL
11457           && p_e->info->var != NULL) 
11458         {
11459           llassert (p_e->info->var->bufinfo != NULL);
11460           p_e->info->var->bufinfo->len = len;
11461           sRef_setLen (p_e->sref, len);
11462         }
11463     }
11464 }
11465
11466 /*@=type*/
11467
11468 bool uentry_hasMetaStateEnsures (uentry e)
11469 {
11470   if (uentry_isValid (e) && uentry_isFunction (e))
11471     {
11472       return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11473     }
11474   else
11475     {
11476       return FALSE;
11477     }
11478 }
11479
11480 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11481 {
11482   llassert (uentry_isValid (e) && uentry_isFunction (e));
11483   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11484 }
11485
11486 # ifdef DEBUGSPLINT
11487
11488 /*
11489 ** For debugging only
11490 */
11491
11492 void uentry_checkValid (uentry ue)
11493 {
11494   if (uentry_isValid (ue))
11495     {
11496       sRef_checkCompletelyReasonable (ue->sref);
11497     }
11498 }
11499
11500 # endif
This page took 2.725091 seconds and 5 git commands to generate.