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