]> andersk Git - splint.git/blob - src/uentry.c
string literal initialization sizes
[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   DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3146   return ue;
3147 }
3148
3149 /*
3150 ** variables
3151 */
3152
3153 void uentry_setDefState (uentry ue, sstate defstate)
3154 {
3155   if (uentry_isValid (ue))
3156     {
3157       sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3158
3159       if (uentry_isVariable (ue))
3160         {
3161           ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3162         }
3163     }
3164 }
3165
3166 bool uentry_isCheckedUnknown (uentry ue)
3167 {
3168   return (uentry_isVar (ue) 
3169           && (ue->info->var->checked == CH_UNKNOWN));
3170 }
3171
3172 bool uentry_isCheckMod (uentry ue)
3173 {
3174   return (uentry_isVar (ue) 
3175           && (ue->info->var->checked == CH_CHECKMOD));
3176 }
3177
3178 bool uentry_isUnchecked (uentry ue)
3179 {
3180   return (uentry_isVar (ue) 
3181           && (ue->info->var->checked == CH_UNCHECKED));
3182 }
3183
3184 bool uentry_isChecked (uentry ue)
3185 {
3186   return (uentry_isVar (ue) 
3187           && (ue->info->var->checked == CH_CHECKED));
3188 }
3189
3190 bool uentry_isCheckedModify (uentry ue)
3191 {
3192   return (uentry_isVar (ue) 
3193           && (ue->info->var->checked == CH_CHECKED
3194               || ue->info->var->checked == CH_CHECKMOD
3195               || ue->info->var->checked == CH_CHECKEDSTRICT));
3196 }
3197
3198 bool uentry_isCheckedStrict (uentry ue)
3199 {
3200   return (uentry_isVar (ue) 
3201           && (ue->info->var->checked == CH_CHECKEDSTRICT));
3202 }
3203
3204 void uentry_setUnchecked (uentry ue)
3205 {
3206   llassert (uentry_isVar (ue));
3207
3208   ue->info->var->checked = CH_UNCHECKED;
3209 }
3210
3211 void uentry_setChecked (uentry ue)
3212 {
3213   llassert (uentry_isVar (ue));
3214
3215   ue->info->var->checked = CH_CHECKED;
3216 }
3217
3218 void uentry_setCheckMod (uentry ue)
3219 {
3220   llassert (uentry_isVar (ue));
3221
3222   ue->info->var->checked = CH_CHECKMOD;
3223 }
3224
3225 void uentry_setCheckedStrict (uentry ue)
3226 {
3227   llassert (uentry_isVar (ue));
3228   
3229   ue->info->var->checked = CH_CHECKEDSTRICT;
3230 }
3231
3232 static /*@only@*/ /*@notnull@*/ 
3233   uentry uentry_makeVariableAux (cstring n, ctype t, 
3234                                  fileloc f,
3235                                  /*@exposed@*/ sRef s,
3236                                  bool priv, vkind kind)
3237 {
3238   uentry e = uentry_alloc ();
3239   ctype rt = t;
3240
3241   DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3242
3243   e->ukind = KVAR;
3244   e->uname = cstring_copy (n);
3245   e->utype = t;
3246
3247   e->storageclass = SCNONE;
3248
3249   e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3250
3251   e->sref  = s;
3252
3253   e->used = FALSE;
3254   e->lset = FALSE;
3255
3256   e->uses = filelocList_new ();
3257   e->isPrivate = priv;
3258   e->hasNameError = FALSE;
3259
3260   e->info = (uinfo) dmalloc (sizeof (*e->info));
3261   e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3262   e->info->var->kind = kind;
3263
3264   /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3265   e->info->var->checked = CH_UNKNOWN;
3266
3267   DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3268   uentry_setSpecDef (e, f);
3269   DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3270
3271   if (ctype_isFunction (rt))
3272     {
3273       rt = ctype_getReturnType (rt);
3274     }
3275
3276   if (ctype_isUA (rt))
3277     {
3278       DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3279       sRef_setStateFromType (e->sref, rt);
3280     }
3281
3282   DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3283   e->info->var->defstate = sRef_getDefState (e->sref);  
3284   e->info->var->nullstate = sRef_getNullState (e->sref);
3285
3286   /* start modifications */
3287   /* This function sets the uentry for a pointer or array variable declaration,
3288      it allocates memory and sets the fields. We check if the type of the variable
3289      is a pointer or array and allocate a `bbufinfo' struct accordingly */
3290   
3291   if( ctype_isArray (t) || ctype_isPointer(t)) {
3292     /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3293      e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3294      /*@access sRef@*/ /*i@222*/
3295      /* It probably isn't necessary to violate the abstraction here
3296       I'll fix this later
3297      */
3298      s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3299      /*@noaccess sRef@*/
3300   } else {
3301      e->info->var->bufinfo = NULL;
3302   }/* end else */
3303 /* end modification */
3304
3305   return (e);
3306 }
3307
3308 bool
3309 uentry_isYield (uentry ue)
3310 {
3311   return (uentry_isVariable (ue) 
3312           && (ue->info->var->kind == VKYIELDPARAM
3313               || ue->info->var->kind == VKREFYIELDPARAM));
3314 }
3315
3316 static bool
3317 uentry_isRefsField (uentry ue)
3318 {
3319   return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3320 }
3321
3322 /*@only@*/ /*@notnull@*/ 
3323 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3324 {
3325   return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv, 
3326                                   fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3327 }
3328
3329 /*
3330 ** functions
3331 */
3332
3333 void uentry_makeVarFunction (uentry ue)
3334 {
3335   alkind ak;
3336   exkind ek;
3337   uvinfo oldInfo;
3338   fileloc loc;
3339
3340   llassert (uentry_isValid (ue));
3341   llassert (!sRef_modInFunction ());
3342
3343   ak = sRef_getOrigAliasKind (ue->sref);
3344   ek = sRef_getOrigExKind (ue->sref);
3345
3346   llassert (uentry_isVariable (ue));
3347   oldInfo = ue->info->var;
3348
3349   llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3350
3351   /*
3352   ** expanded macro is marked used (until I write a pre-processor)
3353   */
3354
3355   ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3356
3357   ue->ukind = KFCN;
3358   ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3359   ue->info->fcn->exitCode = XK_UNKNOWN;
3360   ue->info->fcn->nullPred = qual_createUnknown ();
3361   ue->info->fcn->specialCode = SPC_NONE;
3362   ue->info->fcn->access = typeIdSet_undefined;
3363   ue->info->fcn->hasGlobs = FALSE;
3364   ue->info->fcn->globs = globSet_undefined;
3365   ue->info->fcn->hasMods = FALSE;
3366   ue->info->fcn->mods = sRefSet_undefined;
3367   ue->info->fcn->specclauses = NULL;
3368   ue->info->fcn->defparams = uentryList_undefined;
3369
3370   /*drl*/
3371   ue->info->fcn->preconditions = functionConstraint_undefined;
3372   /*end */
3373
3374   /*drl 12/28/2000*/
3375   ue->info->fcn->postconditions = functionConstraint_undefined; 
3376   /*end */
3377   
3378   if (ctype_isFunction (ue->utype))
3379     {
3380       ue->sref = sRef_makeType (ctype_getReturnType (ue->utype)); 
3381     }
3382   else
3383     {
3384       ue->sref = sRef_makeType (ctype_unknown); 
3385     }
3386
3387   if (sRef_isRefCounted (ue->sref))
3388     {
3389       ak = AK_NEWREF;
3390     }
3391   else
3392     {
3393       if (alkind_isUnknown (ak))
3394         {
3395           if (exkind_isKnown (ek))
3396             {
3397               DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3398               ak = AK_IMPDEPENDENT;
3399             }
3400           else 
3401             {
3402               if (context_getFlag (FLG_RETIMPONLY))
3403                 {
3404                   if (ctype_isFunction (ue->utype)
3405                       && ctype_isVisiblySharable 
3406                       (ctype_realType (ctype_getReturnType (ue->utype))))
3407                     {
3408                       if (uentryList_hasReturned (uentry_getParams (ue)))
3409                         {
3410                           ;
3411                         }
3412                       else
3413                         {
3414                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
3415                             {
3416                               ;
3417                             }
3418                           else 
3419                             {
3420                               ak = AK_IMPONLY;
3421                             }
3422                         }
3423                     }
3424                 }
3425             }
3426         }
3427     }
3428
3429   loc = ue->whereDeclared;
3430
3431   sRef_setAliasKind (ue->sref, ak, loc);
3432   sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3433   sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3434   sRef_setExKind (ue->sref, ek, loc);
3435
3436   if (oldInfo->kind == VKEXPMACRO)
3437     {
3438       ;
3439     }
3440   else
3441     {
3442       fileloc_free (ue->whereDefined);
3443       ue->whereDefined = fileloc_undefined;
3444     }
3445
3446   uvinfo_free (oldInfo);
3447 }
3448
3449 void uentry_makeConstantFunction (uentry ue)
3450 {
3451   alkind ak;
3452   exkind ek;
3453   ucinfo oldInfo;
3454   fileloc loc;
3455
3456   llassert (uentry_isValid (ue));
3457   llassert (!sRef_modInFunction ());
3458
3459   ak = sRef_getOrigAliasKind (ue->sref);
3460   ek = sRef_getOrigExKind (ue->sref);
3461
3462   llassert (uentry_isConstant (ue));
3463   oldInfo = ue->info->uconst;
3464
3465   llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3466
3467   /*
3468   ** expanded macro is marked used (until I write a pre-processor)
3469   */
3470
3471   ue->ukind = KFCN;
3472   ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3473   ue->info->fcn->exitCode = XK_UNKNOWN;
3474   ue->info->fcn->nullPred = qual_createUnknown ();
3475   ue->info->fcn->specialCode = SPC_NONE;
3476   ue->info->fcn->access = typeIdSet_undefined;
3477   ue->info->fcn->hasGlobs = FALSE;
3478   ue->info->fcn->globs = globSet_undefined;
3479   ue->info->fcn->hasMods = FALSE;
3480   ue->info->fcn->mods = sRefSet_undefined;
3481   ue->info->fcn->specclauses = NULL;
3482   ue->info->fcn->defparams = uentryList_undefined;
3483
3484   /*drl*/
3485   ue->info->fcn->preconditions = functionConstraint_undefined;
3486   /*end */
3487
3488   /*drl 12/28/2000*/
3489   ue->info->fcn->postconditions = functionConstraint_undefined;
3490   /*end */
3491
3492   
3493   if (ctype_isFunction (ue->utype))
3494     {
3495       ue->sref = sRef_makeType (ctype_getReturnType (ue->utype)); 
3496     }
3497   else
3498     {
3499       ue->sref = sRef_makeType (ctype_unknown); 
3500     }
3501
3502   if (sRef_isRefCounted (ue->sref))
3503     {
3504       ak = AK_NEWREF;
3505     }
3506   else
3507     {
3508       if (alkind_isUnknown (ak))
3509         {
3510           if (exkind_isKnown (ek))
3511             {
3512               DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3513               ak = AK_IMPDEPENDENT;
3514             }
3515           else 
3516             {
3517               if (context_getFlag (FLG_RETIMPONLY))
3518                 {
3519                   if (ctype_isFunction (ue->utype)
3520                       && ctype_isVisiblySharable 
3521                       (ctype_realType (ctype_getReturnType (ue->utype))))
3522                     {
3523                       if (uentryList_hasReturned (uentry_getParams (ue)))
3524                         {
3525                           ;
3526                         }
3527                       else
3528                         {
3529                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
3530                             {
3531                               ;
3532                             }
3533                           else 
3534                             {
3535                               ak = AK_IMPONLY;
3536                             }
3537                         }
3538                     }
3539                 }
3540             }
3541         }
3542     }
3543
3544   loc = ue->whereDeclared;
3545
3546   sRef_setAliasKind (ue->sref, ak, loc);
3547   sRef_setExKind (ue->sref, ek, loc);
3548
3549   fileloc_free (ue->whereDefined);
3550   ue->whereDefined = fileloc_undefined;
3551   ucinfo_free (oldInfo);
3552 }
3553
3554 void
3555 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3556 {
3557   llassert (uentry_isValid (ue));
3558
3559   if (uentry_isIter (ue))
3560     {
3561       llassert (globSet_isUndefined (ue->info->iter->globs));
3562       ue->info->iter->globs = globs;
3563     }
3564   else
3565     {
3566       uentry_convertVarFunction (ue);
3567       
3568       llassert (uentry_isFunction (ue));
3569       llassert (!ue->info->fcn->hasGlobs 
3570                 && globSet_isUndefined (ue->info->fcn->globs));
3571       
3572       ue->info->fcn->hasGlobs = TRUE;
3573       globSet_markImmutable (globs);
3574       /*@-mustfree@*/ ue->info->fcn->globs = globs;
3575       /*@=mustfree@*/
3576     }
3577
3578   /*@i23*/
3579   /* ???  - evans 2001-09-09 not sure what's going on here...?
3580   if (globSet_hasStatic (globs))
3581     {
3582       context_recordFileGlobals (globs);
3583     }
3584   */
3585
3586   if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3587     {
3588       ue->info->fcn->hasMods = TRUE;
3589     }
3590 }
3591
3592 void uentry_addAccessType (uentry ue, typeId tid)
3593 {
3594   if (uentry_isFunction (ue))
3595     {
3596       ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3597     }
3598   else if (uentry_isEitherConstant (ue))
3599     {
3600       ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3601     }
3602   else if (uentry_isIter (ue))
3603     {
3604       ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3605     }
3606   else if (uentry_isEndIter (ue))
3607     {
3608       ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3609     }
3610   else
3611     {
3612       llbug (message ("no access for: %q", uentry_unparse (ue)));
3613     }
3614 }
3615
3616 /*@only@*/ /*@notnull@*/ uentry 
3617   uentry_makeFunction (cstring n, ctype t, 
3618                        typeId access, 
3619                        /*@only@*/ globSet globs, /*@only@*/ sRefSet mods, 
3620                        /*@only@*/ warnClause warn,
3621                        fileloc f)
3622 {
3623   llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3624   return (uentry_makeFunctionAux (n, t, 
3625                                   ((typeId_isInvalid (access)) ? typeIdSet_emptySet () 
3626                                    : typeIdSet_single (access)),
3627                                   globs, mods, warn,
3628                                   f,
3629                                   FALSE, FALSE));
3630 }
3631
3632 # ifndef NOLCL
3633 /*@notnull@*/ uentry 
3634   uentry_makePrivFunction2 (cstring n, ctype t, 
3635                             typeIdSet access, 
3636                             globSet globs, sRefSet mods, 
3637                             fileloc f)
3638 {
3639   return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3640                                   f, TRUE, FALSE));
3641 }
3642
3643
3644 /*@notnull@*/ uentry 
3645   uentry_makeSpecFunction (cstring n, ctype t, 
3646                            typeIdSet access,
3647                            /*@only@*/ globSet globs, 
3648                            /*@only@*/ sRefSet mods, 
3649                            fileloc f)
3650 {
3651   uentry ue = uentry_makeFunctionAux (n, t, access, 
3652                                       globs, mods, warnClause_undefined, 
3653                                       f, FALSE, FALSE);
3654
3655   uentry_setHasGlobs (ue);
3656   uentry_setHasMods (ue);
3657
3658   reflectImplicitFunctionQualifiers (ue, TRUE);
3659   return (ue);
3660 }
3661 # endif
3662
3663 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3664 {
3665   uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined, 
3666                                       sRef_undefined, FALSE, VKEXPMACRO);
3667
3668   uentry_setDefined (ue, f);
3669   return ue;
3670 }
3671
3672 /*@notnull@*/ /*@notnull@*/ uentry 
3673   uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3674 {
3675   uentry ue = uentry_makeFunctionAux (n, ctype_unknown, 
3676                                       typeIdSet_singleOpt (access),
3677                                       globSet_undefined, sRefSet_undefined, 
3678                                       warnClause_undefined,
3679                                       fileloc_undefined,
3680                                       FALSE, TRUE);
3681
3682   ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3683   return ue;
3684 }
3685
3686 bool uentry_isForward (uentry e)
3687 {
3688   if (uentry_isValid (e))
3689     {
3690       ctype ct = uentry_getType (e);
3691
3692       return (ctype_isUnknown (ct)
3693               || (ctype_isFunction (ct)
3694                   && ctype_isUnknown (ctype_getReturnType (ct))));
3695     }
3696
3697   return FALSE;
3698 }
3699
3700 # ifndef NOLCL
3701 /*@notnull@*/ uentry 
3702 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3703 {
3704   return (uentry_makeFunctionAux (n, ctype_unknown, access,
3705                                   globSet_undefined, sRefSet_undefined, warnClause_undefined,
3706                                   f,FALSE, TRUE));
3707 }
3708
3709 /*@notnull@*/ uentry 
3710 uentry_makeUnspecFunction (cstring n, ctype t, 
3711                            typeIdSet access, 
3712                            fileloc f)
3713 {
3714   uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3715                                       sRefSet_undefined, warnClause_undefined,
3716                                       f, FALSE, TRUE);
3717
3718   reflectImplicitFunctionQualifiers (ue, TRUE);
3719   return ue;
3720 }
3721 # endif
3722
3723 /*
3724 ** datatypes
3725 */
3726
3727 /* is exported for use by usymtab_interface */
3728
3729 /*@notnull@*/ uentry 
3730   uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract, 
3731                           fileloc f, bool priv)
3732 {
3733   uentry e = uentry_alloc ();
3734
3735   DPRINTF (("Make datatype: %s / %s",
3736             n, ctype_unparse (t)));
3737
3738   /* e->shallowCopy = FALSE; */
3739   e->ukind = KDATATYPE;
3740   e->uname = cstring_copy (n);
3741   e->utype = t;
3742   e->storageclass = SCNONE;
3743   e->sref  = sRef_makeUnknown ();
3744
3745   if (ctype_isUA (t))
3746     {
3747       sRef_setStateFromType (e->sref, t);
3748     }
3749
3750   uentry_setSpecDef (e, f);
3751
3752   e->warn = warnClause_undefined; /*@i634@*/ 
3753   e->uses = filelocList_new ();
3754   e->isPrivate = priv;
3755   e->hasNameError = FALSE;
3756
3757   e->used = FALSE;
3758   e->lset = FALSE;
3759
3760   e->info = (uinfo) dmalloc (sizeof (*e->info));
3761   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3762   e->info->datatype->abs = abstract;
3763   e->info->datatype->mut = mut;
3764   e->info->datatype->type = ctype_undefined;
3765
3766   if (uentry_isDeclared (e))
3767     {
3768       uentry_setDefined (e, f);
3769     }
3770
3771   if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3772     {
3773       sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3774     }
3775
3776   return (e);
3777 }
3778
3779 /*@notnull@*/ uentry
3780   uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3781 {
3782   return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3783 }
3784
3785 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3786 {
3787   uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3788                                        ctype_bool, NO, abstract, 
3789                                        fileloc_getBuiltin (),
3790                                        FALSE);
3791   
3792   ret->info->datatype->type = ctype_bool;
3793   return ret;
3794 }
3795
3796 /*
3797 ** iters
3798 */
3799
3800 static /*@only@*/ /*@notnull@*/ uentry 
3801   uentry_makeIterAux (cstring n, typeIdSet access, ctype ct, 
3802                       /*@only@*/ fileloc f)
3803 {
3804   uentry e = uentry_alloc ();
3805
3806   e->ukind = KITER;
3807   e->uname = cstring_copy (n);
3808   e->utype = ct;
3809   e->sref  = sRef_makeUnknown ();
3810   e->storageclass = SCNONE;
3811   e->used = FALSE;
3812   e->lset = FALSE;
3813
3814   uentry_setSpecDef (e, f);
3815
3816   e->warn = warnClause_undefined; /*@i452@*/
3817   e->uses = filelocList_new ();
3818   e->isPrivate = FALSE;
3819   e->hasNameError = FALSE;
3820
3821   e->info = (uinfo) dmalloc (sizeof (*e->info));
3822   e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3823   e->info->iter->access = access;
3824   e->info->iter->mods = sRefSet_undefined;
3825   e->info->iter->globs = globSet_undefined;
3826
3827   uentry_checkIterArgs (e);
3828   return (e);
3829 }
3830
3831 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3832 {
3833   return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3834 }
3835
3836 static /*@notnull@*/ uentry
3837 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3838 {
3839   uentry e = uentry_alloc ();
3840
3841   /* e->shallowCopy = FALSE; */
3842   e->ukind = KENDITER;
3843   e->storageclass = SCNONE;
3844   e->uname = message ("end_%s", n);
3845   e->utype = ctype_unknown;
3846   e->sref  = sRef_makeUnknown ();
3847
3848   uentry_setSpecDef (e, f);
3849
3850   e->used = FALSE;
3851   e->lset = FALSE;
3852
3853   e->uses = filelocList_new ();
3854   e->isPrivate = FALSE;
3855   e->hasNameError = FALSE;
3856
3857   e->info = (uinfo) dmalloc (sizeof (*e->info));
3858   e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3859
3860   e->info->enditer->access = access;
3861
3862   e->warn = warnClause_undefined; /*@i452@*/
3863   return (e);
3864 }
3865
3866 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3867 {
3868   return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3869 }
3870
3871 /*
3872 ** tags
3873 */
3874
3875 static /*@only@*/ /*@notnull@*/ uentry 
3876   uentry_makeTagAux (cstring n, ctype t, 
3877                      /*@only@*/ fileloc fl, 
3878                      bool priv, ekind kind)
3879 {
3880   uentry e = uentry_alloc ();
3881   
3882   if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3883     {
3884       llbuglit ("uentry_makeTagAux: not a tag type");
3885     }
3886   
3887   e->ukind = kind;
3888   /* e->shallowCopy = FALSE; */
3889   e->uname = cstring_copy (n);
3890
3891   e->utype = t;
3892   e->sref  = sRef_makeUnknown ();
3893   e->storageclass = SCNONE;
3894
3895   uentry_setSpecDef (e, fl);
3896   
3897   e->used = FALSE;
3898   e->lset = FALSE;
3899
3900   e->uses = filelocList_new ();
3901   e->isPrivate = priv;
3902   e->hasNameError = FALSE;
3903
3904   e->info = (uinfo) dmalloc (sizeof (*e->info));
3905   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3906   e->info->datatype->abs = NO;
3907   e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3908   e->info->datatype->type = t;
3909   e->warn = warnClause_undefined; /*@i452@*/
3910
3911   if (uentry_isDeclared (e))
3912     {
3913       uentry_setDefined (e, fl);
3914     }
3915
3916   return (e);  
3917 }
3918
3919 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3920 {
3921   cstring sname = makeStruct (n);
3922   uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3923
3924   cstring_free (sname);
3925   return (ret);
3926 }
3927
3928 /*@only@*/ uentry
3929 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3930 {
3931   cstring sname = makeStruct (n);
3932   uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3933
3934   cstring_free (sname);
3935   return ret;
3936 }
3937
3938 /*@only@*/ uentry
3939 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3940 {
3941   cstring uname = makeUnion (n);
3942   uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3943
3944   cstring_free (uname);
3945   return (ret);
3946 }
3947
3948 # ifndef NOLCL
3949 uentry
3950 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3951 {
3952   cstring ename = makeEnum (n);
3953   uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3954
3955   cstring_free (ename);
3956   return ret;
3957 }
3958 # endif
3959
3960 uentry
3961 uentry_makeUnionTagLoc (cstring n, ctype t)
3962 {
3963   cstring uname = makeUnion (n);
3964   uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3965
3966   cstring_free (uname);
3967   return ret;
3968 }
3969
3970 uentry
3971 uentry_makeEnumTagLoc (cstring n, ctype t)
3972 {
3973   cstring ename = makeEnum (n);
3974   uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3975
3976   cstring_free (ename);
3977   return ret;
3978 }
3979
3980 bool 
3981 uentry_isStructTag (uentry ue) 
3982 {
3983   return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3984 }
3985
3986 bool 
3987 uentry_isUnionTag (uentry ue) 
3988 {
3989   return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3990 }
3991
3992 bool 
3993 uentry_isEnumTag (uentry ue) 
3994 {
3995   return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3996 }
3997
3998 bool
3999 uentry_isAnyTag (uentry ue)
4000 {
4001   return (uentry_isStructTag (ue) 
4002           || uentry_isUnionTag (ue)
4003           || uentry_isEnumTag (ue));
4004 }
4005
4006 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4007
4008 extern void uentry_destroyMod (void)
4009    /*@globals killed emarker@*/ /*@modifies emarker@*/
4010 {
4011   static bool wasDestroyed = FALSE;
4012
4013   llassert (!wasDestroyed);
4014
4015   if (emarker != NULL)
4016     {
4017       uentry_reallyFree (emarker);
4018     }
4019
4020   wasDestroyed = TRUE;
4021 }
4022
4023 uentry
4024 uentry_makeElipsisMarker (void)
4025 {
4026   if (emarker == NULL)
4027     {
4028       emarker = uentry_alloc ();
4029
4030       emarker->ukind = KELIPSMARKER;
4031       emarker->uname = cstring_makeLiteral ("...");
4032       emarker->utype = ctype_elipsMarker;
4033       emarker->sref  = sRef_undefined;
4034       emarker->storageclass = SCNONE;
4035       emarker->used = FALSE;
4036       emarker->lset = FALSE;
4037       emarker->info = NULL;
4038
4039       uentry_setSpecDef (emarker, fileloc_undefined);
4040       emarker->uses = filelocList_new ();
4041       emarker->isPrivate = FALSE;
4042       emarker->hasNameError = FALSE;
4043     }
4044
4045   /*@ignore@*/ return (emarker); /*@end@*/
4046
4047
4048 /*
4049 ** comparisons
4050 */
4051
4052 bool
4053 uentry_equiv (uentry p1, uentry p2)
4054 {
4055   if (uentry_compare (p1, p2) != 0)
4056     {
4057       return FALSE;
4058     }
4059   else
4060     {
4061       return TRUE;
4062     }
4063 }
4064
4065 int
4066 uentry_xcomparealpha (uentry *p1, uentry *p2)
4067 {
4068   int res;
4069
4070   if ((res = uentry_compare (*p1, *p2)) == 0) {
4071     if ((*p1 != NULL) && (*p2 != NULL)) {
4072       res = cstring_compare ((*p1)->uname,
4073                              (*p2)->uname);
4074     }
4075   }
4076
4077   return res;
4078 }
4079
4080 int
4081 uentry_xcompareuses (uentry *p1, uentry *p2)
4082 {
4083   uentry u1 = *p1;
4084   uentry u2 = *p2;
4085
4086   if (uentry_isValid (u1))
4087     {
4088       if (uentry_isValid (u2))
4089         {
4090           return (-1 * int_compare (filelocList_size (u1->uses), 
4091                                     filelocList_size (u2->uses)));
4092         }
4093       else
4094         {
4095           return 1;
4096         }
4097     }
4098   else
4099     {
4100       if (uentry_isValid (u2))
4101         {
4102           return -1;
4103         }
4104       else
4105         {
4106           return 0;
4107         }
4108     }
4109 }
4110
4111 int 
4112 uentry_compareStrict (uentry v1, uentry v2)
4113 {
4114   COMPARERETURN (uentry_compare (v1, v2));
4115
4116   if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4117     {
4118       COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4119       COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4120       COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4121     }
4122
4123   return 0;
4124 }
4125
4126 int
4127 uentry_compare (uentry u1, uentry u2)
4128 {
4129   if (u1 == u2) return 0;
4130   
4131   if (uentry_isInvalid (u1)) return -1;
4132   if (uentry_isInvalid (u2)) return 1;
4133
4134   INTCOMPARERETURN (u1->ukind, u2->ukind);
4135   COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4136   COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4137   COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4138
4139   switch (u1->ukind)
4140     {
4141     case KINVALID:
4142     case KELIPSMARKER:
4143       /* bug detected by lclint:  
4144       ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE 
4145       */
4146       return 0;
4147     case KENUMCONST:
4148     case KCONST:
4149       return (multiVal_compare (uentry_getConstantValue (u1),
4150                                 uentry_getConstantValue (u2)));
4151     case KSTRUCTTAG: 
4152     case KUNIONTAG: 
4153     case KENUMTAG: 
4154       return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4155     case KITER:
4156       COMPARERETURN (typeIdSet_compare (uentry_accessType (u1), 
4157                                          uentry_accessType (u2)));
4158       return (uentryList_compareParams (uentry_getParams (u1), 
4159                                         uentry_getParams (u2)));
4160     case KENDITER:
4161       return (typeIdSet_compare (uentry_accessType (u1), 
4162                                   uentry_accessType (u2)));
4163     case KFCN:
4164       /*
4165       ** Functions are never equivalent
4166       */
4167       
4168       if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4169         {
4170           return -1;
4171         }
4172       else
4173         {
4174           return 1;
4175         }
4176     case KVAR:
4177       
4178       COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4179       COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4180                                       sRef_getOrigAliasKind (u2->sref)));
4181       COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4182                                       sRef_getOrigExKind (u2->sref)));
4183       COMPARERETURN (generic_compare (u1->info->var->checked,
4184                                       u2->info->var->checked));
4185       COMPARERETURN (generic_compare (u1->info->var->defstate, 
4186                                       u2->info->var->defstate));
4187       return        (generic_compare (u1->info->var->nullstate, 
4188                                       u2->info->var->nullstate));
4189     case KDATATYPE:
4190       COMPARERETURN (ctype_compare (u1->info->datatype->type,
4191                                     u2->info->datatype->type));
4192       COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4193                                   u2->info->datatype->mut));
4194       return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4195     }
4196   
4197   BADEXIT;
4198 }
4199
4200 /*
4201 ** library format:
4202 **
4203 ** all entries are: <type>[@<info>]*#<name>
4204 **
4205 ** info depends on kind:
4206 */
4207
4208 static void
4209 advanceField (char **s)
4210 {
4211   reader_checkChar (s, '@');
4212 }
4213
4214 static void
4215 advanceName (char **s)
4216 {
4217   reader_checkChar (s, '#');
4218 }
4219
4220 static vkind
4221 vkind_fromInt (int i)
4222 {
4223   if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4224     {
4225       llbuglit ("vkind_fromInt: out of range");
4226     }
4227
4228   return (vkind)i;
4229 }
4230
4231 static uentry  
4232   uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct, 
4233                            typeIdSet access, nstate nullstate,
4234                            /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4235 {
4236   uentry e = uentry_alloc ();
4237   
4238   e->ukind = KCONST;
4239   e->uname = name;
4240   e->utype = ct;
4241   e->sref  = sRef_makeConst (ct);
4242
4243   sRef_setNullState (e->sref, nullstate, loc);
4244   e->storageclass = SCNONE;
4245
4246   if (fileloc_isSpec (loc))
4247     {
4248       e->whereSpecified = loc;
4249       e->whereDeclared = fileloc_undefined;
4250     }
4251   else
4252     {
4253       e->whereSpecified = fileloc_undefined;
4254       e->whereDeclared = loc;
4255     }
4256
4257   e->whereDefined = fileloc_undefined;
4258   e->uses = filelocList_new ();
4259   e->isPrivate = FALSE;
4260   e->hasNameError = FALSE;
4261
4262   e->used = FALSE;
4263   e->lset = FALSE;
4264
4265   e->warn = warnClause_undefined; /*@i452@*/
4266
4267   e->info = (uinfo) dmalloc (sizeof (*e->info));
4268   e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4269   e->info->uconst->access = access;
4270
4271   uentry_setConstantValue (e, m);
4272   sRef_storeState (e->sref);
4273
4274   return (e);
4275 }
4276
4277 static /*@only@*/ uentry  
4278   uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind, 
4279                            sstate defstate, nstate isnull, alkind aliased,
4280                            exkind exp, chkind checked, 
4281                            /*@only@*/ fileloc loc)
4282 {
4283   uentry e = uentry_alloc ();
4284
4285   e->ukind = KVAR;
4286   e->uname = name;
4287   e->utype = ct;
4288   e->storageclass = SCNONE;
4289
4290   e->sref  = sRef_makeType (ct);
4291   sRef_setNullState (e->sref, isnull, loc);
4292
4293   e->whereDefined = fileloc_undefined;
4294
4295   if (fileloc_isSpec (loc))
4296     {
4297       e->whereSpecified = loc;
4298       e->whereDeclared = fileloc_undefined;
4299     }
4300   else
4301     {
4302       e->whereSpecified = fileloc_undefined;
4303       e->whereDeclared = loc;
4304     }
4305
4306   e->isPrivate = FALSE;
4307   e->hasNameError = FALSE;
4308
4309   e->used = FALSE;
4310   e->lset = FALSE;
4311
4312   e->uses = filelocList_new ();
4313   e->warn = warnClause_undefined; /*@i452@*/
4314
4315   e->info = (uinfo) dmalloc (sizeof (*e->info));
4316   e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4317   e->info->var->kind = kind;
4318   e->info->var->checked = checked;
4319   e->info->var->defstate = defstate;
4320
4321   sRef_setDefState (e->sref, defstate, loc);
4322
4323   e->info->var->nullstate = sRef_getNullState (e->sref);
4324
4325   sRef_setExKind (e->sref, exp, loc);
4326   sRef_setAliasKind (e->sref, aliased, loc);
4327
4328   sRef_storeState (e->sref);
4329
4330   /*DRL ADDED 9-1-2000 */
4331   e->info->var->bufinfo = NULL;
4332   
4333   return (e);
4334 }
4335
4336 static /*@only@*/ uentry  
4337 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract, 
4338                          ynm mut, ctype rtype, alkind ak, exkind exp, 
4339                          sstate defstate, nstate isnull,
4340                          /*@only@*/ fileloc loc)
4341 {
4342   uentry e = uentry_alloc ();
4343
4344   e->ukind = KDATATYPE;
4345   /* e->shallowCopy = FALSE; */
4346   e->uname = name;
4347   e->utype = ct;
4348   e->storageclass = SCNONE;
4349   e->sref  = sRef_makeUnknown ();
4350   DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4351
4352   /*
4353   ** This is only setting null state.  (I think?)
4354   */
4355
4356   if (ctype_isUA (ct))
4357     {
4358       uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4359
4360       if (uentry_isValid (te))
4361         {
4362           sRef_setStateFromUentry (e->sref, te);
4363         }
4364       else
4365         {
4366           /* problem for recursive type definitions */
4367         }
4368     }
4369   
4370   sRef_setAliasKind (e->sref, ak, loc);
4371   sRef_setExKind (e->sref, exp, loc);
4372
4373   sRef_setDefState (e->sref, defstate, loc);
4374
4375   if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4376     {
4377       isnull = NS_ABSNULL;
4378     }
4379
4380   DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4381   sRef_mergeNullState (e->sref, isnull);
4382
4383   e->whereDefined = fileloc_copy (loc); /*< bogus!  (but necessary for lexer) >*/
4384
4385   if (fileloc_isSpec (loc))
4386     {
4387       e->whereSpecified = loc;
4388       e->whereDeclared = fileloc_undefined;
4389     }
4390   else
4391     {
4392       e->whereSpecified = fileloc_undefined;
4393       e->whereDeclared = loc;
4394     }
4395   
4396   e->isPrivate = FALSE;
4397   e->hasNameError = FALSE;
4398
4399   e->warn = warnClause_undefined; /*@i452@*/
4400
4401   e->used = FALSE;
4402   e->lset = FALSE;
4403   e->uses = filelocList_new ();
4404
4405   e->info = (uinfo) dmalloc (sizeof (*e->info));
4406   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4407   e->info->datatype->abs = abstract;
4408   e->info->datatype->mut = mut;
4409   e->info->datatype->type = rtype;
4410
4411   DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4412   sRef_storeState (e->sref);
4413   DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4414
4415   return (e);
4416 }
4417
4418 # ifndef NOLCL
4419 static void uentry_setHasGlobs (uentry ue)
4420 {
4421   llassert (uentry_isFunction (ue));
4422
4423   ue->info->fcn->hasGlobs = TRUE;
4424 }
4425
4426 static void uentry_setHasMods (uentry ue)
4427 {
4428   llassert (uentry_isFunction (ue));
4429
4430   ue->info->fcn->hasMods = TRUE;
4431 }
4432 # endif
4433
4434 bool uentry_hasGlobs (uentry ue)
4435 {
4436   if (uentry_isFunction (ue))
4437     {
4438       return (ue->info->fcn->hasGlobs);
4439     }
4440
4441   return FALSE;
4442 }
4443
4444 bool uentry_hasStateClauseList (uentry ue)
4445 {
4446   return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4447 }
4448
4449 bool uentry_hasConditions (uentry ue)
4450 {
4451   return (uentry_isFunction (ue) 
4452           && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4453               || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4454 }
4455
4456 stateClauseList uentry_getStateClauseList (uentry ue)
4457 {
4458   if (!uentry_isFunction (ue))
4459     {
4460       llassert (uentry_isFunction (ue));
4461       return stateClauseList_undefined;
4462     }
4463
4464   DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4465   return ue->info->fcn->specclauses;
4466 }
4467
4468 bool uentry_hasMods (uentry ue)
4469 {
4470   if (uentry_isFunction (ue))
4471     {
4472       return (ue->info->fcn->hasMods);
4473     }
4474
4475   return FALSE;
4476 }
4477
4478 static uentry  
4479   uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct, 
4480                            typeIdSet access, 
4481                            bool hasGlobs, /*@only@*/ globSet globs, 
4482                            bool hasMods, /*@only@*/ sRefSet mods, 
4483                            alkind ak, exkind exp, 
4484                            sstate defstate, nstate isnull,
4485                            exitkind exitCode,
4486                            specCode sCode,
4487                            qual nullPred,
4488                            /*@only@*/ stateClauseList specclauses,
4489                            /*@only@*/ warnClause warnclause,
4490                            /*@only@*/ fileloc loc)
4491 {
4492   uentry e = uentry_alloc ();
4493   ctype ret;
4494
4495   /* e->shallowCopy = FALSE; */
4496   e->ukind = KFCN;
4497   e->uname = name;
4498   e->utype = ct;
4499   e->storageclass = SCNONE;
4500
4501   if (ctype_isFunction (ct))
4502     {
4503       ret = ctype_getReturnType (ct);
4504     }
4505   else
4506     {
4507       if (ctype_isKnown (ct))
4508         {
4509           llbug (message ("not function: %s", ctype_unparse (ct)));
4510         }
4511
4512       ret = ctype_unknown;
4513     }
4514
4515   e->sref  = sRef_makeType (ret);
4516
4517   if (ctype_isUA (ret))
4518     {
4519       sRef_setStateFromType (e->sref, ret);
4520     }
4521
4522   sRef_setDefined (e->sref, loc);
4523   sRef_setNullState (e->sref, isnull, loc);
4524
4525   sRef_setAliasKind (e->sref, ak, loc);
4526   sRef_setExKind (e->sref, exp, loc);
4527   sRef_setDefState (e->sref, defstate, loc);
4528
4529   e->whereSpecified = loc;
4530   e->whereDefined = fileloc_undefined;
4531
4532   e->isPrivate = FALSE;
4533   e->hasNameError = FALSE;
4534
4535   e->used = FALSE;
4536   e->lset = FALSE;
4537   e->uses = filelocList_new ();  
4538   e->warn = warnclause;
4539
4540   e->info = (uinfo) dmalloc (sizeof (*e->info));
4541   e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4542   
4543   e->info->fcn->exitCode = exitCode;
4544   e->info->fcn->specialCode = sCode;
4545   e->info->fcn->nullPred = nullPred;
4546   e->info->fcn->access = access;
4547
4548   e->info->fcn->specclauses = specclauses;
4549   e->info->fcn->hasGlobs = hasGlobs;
4550   e->info->fcn->globs = globs;
4551
4552   e->info->fcn->hasMods = hasMods;
4553   e->info->fcn->mods = mods;
4554
4555   e->info->fcn->defparams = uentryList_undefined; 
4556   e->whereDeclared = fileloc_undefined;
4557
4558   sRef_storeState (e->sref);
4559
4560   /*drl 111  30 2000*/
4561   e->info->fcn->preconditions = NULL;
4562     /* end drl */
4563
4564   /*drl 12  28 2000*/
4565   e->info->fcn->postconditions = NULL;
4566     /* end drl */
4567   
4568   return (e);
4569 }
4570
4571 static /*@only@*/ uentry  
4572   uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind, 
4573                       ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4574 {
4575   uentry e = uentry_alloc ();
4576   
4577   if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4578     {
4579       llbuglit ("uentry_makeTagBase: not a tag type");
4580     }
4581
4582   /* e->shallowCopy = FALSE; */
4583   e->ukind = tagkind;
4584   e->uname = name;
4585   e->utype = ct;
4586   e->sref  = sRef_makeUnknown ();
4587   e->storageclass = SCNONE;
4588
4589   if (fileloc_isSpec (loc))
4590     {
4591       e->whereSpecified = loc;
4592       e->whereDeclared = fileloc_undefined;
4593     }
4594   else
4595     {
4596       e->whereDeclared = loc;
4597       e->whereSpecified = fileloc_undefined;
4598     }
4599
4600   e->whereDefined = fileloc_undefined;
4601
4602   e->isPrivate = FALSE;
4603   e->hasNameError = FALSE;
4604
4605   e->used = FALSE;
4606   e->lset = FALSE;
4607   e->uses = filelocList_new ();
4608   e->warn = warnClause_undefined; /*@i452@*/
4609
4610   e->info = (uinfo) dmalloc (sizeof (*e->info));
4611   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4612   e->info->datatype->abs  = NO;
4613   e->info->datatype->mut  = MAYBE;
4614   e->info->datatype->type = rtype;
4615
4616   sRef_storeState (e->sref);
4617
4618   return (e);  
4619 }
4620
4621 static uentry  
4622   uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access, 
4623                        ctype ct, /*@only@*/ fileloc loc)
4624 {
4625   uentry e = uentry_alloc ();
4626   
4627   /* e->shallowCopy = FALSE; */
4628   e->ukind = KITER;
4629   e->uname = name;
4630   e->utype = ct;
4631   e->sref  = sRef_makeUnknown ();
4632   e->storageclass = SCNONE;
4633
4634   if (fileloc_isSpec (loc))
4635     {
4636       e->whereSpecified = loc;
4637       e->whereDeclared = fileloc_undefined;
4638     }
4639   else
4640     {
4641       e->whereDeclared = loc;
4642       e->whereSpecified = fileloc_undefined;
4643     }
4644
4645   e->whereDefined = fileloc_undefined;
4646   
4647   e->isPrivate = FALSE;
4648   e->hasNameError = FALSE;
4649
4650   e->used = FALSE;
4651   e->lset = FALSE;
4652   e->uses = filelocList_new ();
4653   e->warn = warnClause_undefined; /*@i452@*/
4654
4655   e->info = (uinfo) dmalloc (sizeof (*e->info));
4656   e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4657   e->info->iter->access = access;
4658   e->info->iter->mods = sRefSet_undefined;
4659   e->info->iter->globs = globSet_undefined;
4660   
4661   sRef_storeState (e->sref);
4662   return (e);
4663 }
4664
4665 static uentry  
4666   uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access, 
4667                           /*@only@*/ fileloc loc)
4668 {
4669   uentry e = uentry_alloc ();
4670
4671   /* e->shallowCopy = FALSE; */
4672   e->ukind = KENDITER;
4673   e->storageclass = SCNONE;
4674   e->uname = name;
4675   e->utype = ctype_unknown;
4676   e->sref  = sRef_makeUnknown ();
4677   
4678   if (fileloc_isSpec (loc))
4679     {
4680       e->whereSpecified = loc;
4681       e->whereDeclared = fileloc_undefined;
4682     }
4683   else
4684     {
4685       e->whereDeclared = loc;
4686       e->whereSpecified = fileloc_undefined;
4687     }
4688
4689   e->whereDefined = fileloc_undefined;
4690
4691   e->isPrivate = FALSE;
4692   e->hasNameError = FALSE;
4693
4694   e->used = FALSE;
4695   e->lset = FALSE;
4696   e->uses = filelocList_new ();
4697   e->warn = warnClause_undefined; /*@i452@*/
4698
4699   e->info = (uinfo) dmalloc (sizeof (*e->info));
4700   e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4701   e->info->enditer->access = access;
4702   sRef_storeState (e->sref);
4703
4704   return (e);
4705 }
4706
4707 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4708 {
4709   /* should save u */
4710 /*@-mustfree@*/
4711 }
4712 /*@=mustfree@*/
4713
4714 /*@only@*/ uentry
4715 uentry_undump (ekind kind, fileloc loc, char **s)
4716 {
4717   uentry ue;
4718   
4719   DPRINTF (("Uentry undump: %s", *s));
4720
4721   if (**s == '!')
4722     {
4723       reader_checkChar (s, '!');
4724       reader_checkChar (s, '.');
4725       ue = uentry_makeElipsisMarker ();
4726     }
4727   else
4728     {
4729       ctype ct = ctype_undump (s);
4730       cstring name;
4731
4732       switch (kind)
4733         {
4734         case KVAR:
4735           {
4736             vkind  tkind;
4737             sstate defstate;
4738             nstate isnull;
4739             alkind aliased;
4740             exkind exp;
4741             chkind checked;
4742             
4743             reader_checkChar (s, '|');
4744
4745             if (reader_optCheckChar (s, '@'))
4746               {
4747                 tkind = vkind_fromInt (reader_getInt (s));
4748                 reader_checkChar (s, '|');
4749               }
4750             else
4751               {
4752                 tkind = VKPARAM;
4753               }
4754
4755             if (reader_optCheckChar (s, '$'))
4756               {
4757                 defstate = SS_UNKNOWN;
4758                 isnull = NS_UNKNOWN;
4759                 aliased = AK_IMPTEMP;
4760                 exp = XO_UNKNOWN;
4761                 checked = CH_UNKNOWN;
4762               }         
4763             else if (reader_optCheckChar (s, '&'))
4764               {
4765                 defstate = SS_DEFINED;
4766                 isnull = NS_UNKNOWN;
4767                 aliased = AK_IMPTEMP;
4768                 exp = XO_UNKNOWN;
4769                 checked = CH_UNKNOWN;
4770               }         
4771             else if (reader_optCheckChar (s, '^'))
4772               {
4773                 defstate = SS_UNKNOWN;
4774                 isnull = NS_UNKNOWN;
4775                 aliased = AK_IMPTEMP;
4776                 exp = XO_UNKNOWN;
4777                 checked = CH_UNKNOWN;
4778               }         
4779             else
4780               {
4781                 defstate = sstate_fromInt (reader_getInt (s));      
4782                 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));      
4783                 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));      
4784
4785                 if (reader_optCheckChar (s, '&'))
4786                   {
4787                     exp = XO_UNKNOWN;
4788                     checked = CH_UNKNOWN;
4789                   }
4790                 else
4791                   {
4792                     advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4793                     advanceField (s); checked = (chkind) (reader_getInt (s));      
4794                   }
4795               }
4796
4797             advanceName (s);
4798             name = reader_getStringWord (s);
4799             
4800             llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4801
4802             ue = uentry_makeVariableBase (name, ct, tkind, defstate, 
4803                                           isnull, aliased, exp, 
4804                                           checked, fileloc_copy (loc));
4805           }
4806           break;
4807         case KDATATYPE: 
4808           {
4809             ynm abstract;
4810             ynm mut;
4811             ctype rtype;
4812             sstate defstate;
4813             nstate isnull;
4814             alkind aliased;
4815             exkind exp;
4816
4817             advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4818             advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4819             advanceField (s); defstate = sstate_fromInt (reader_getInt (s));      
4820             advanceField (s); isnull = nstate_fromInt (reader_getInt (s));      
4821             advanceField (s); aliased = alkind_fromInt (reader_getInt (s));      
4822             advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4823             advanceField (s); rtype = ctype_undump (s);
4824             advanceName (s); 
4825             name = reader_getStringWord (s);
4826             DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4827             ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype, 
4828                                           aliased, exp, defstate, isnull, 
4829                                           fileloc_copy (loc));
4830           }
4831           break;
4832         case KFCN:
4833           {
4834             alkind     ak;
4835             exkind     exp;
4836             sstate     defstate;
4837             nstate     isnull;
4838             exitkind   exitCode;
4839             specCode   specc;
4840             qual       nullPred;
4841             typeIdSet access;
4842             bool       hasGlobs;
4843             globSet    globs;
4844             bool       hasMods;
4845             sRefSet    mods;
4846             stateClauseList specclauses = stateClauseList_undefined;
4847             warnClause warnclause = warnClause_undefined;
4848
4849             if (reader_optCheckChar (s, '$'))
4850               {
4851                 defstate = SS_DEFINED;
4852                 isnull = NS_UNKNOWN;
4853                 exitCode = XK_UNKNOWN;
4854                 specc = SPC_NONE;
4855                 nullPred = qual_createUnknown ();
4856               }
4857             else
4858               {
4859                 advanceField (s); defstate = sstate_fromInt (reader_getInt (s)); 
4860                 advanceField (s); isnull = nstate_fromInt (reader_getInt (s)); 
4861                 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s)); 
4862                 advanceField (s); specc = specCode_fromInt (reader_getInt (s)); 
4863                 advanceField (s); nullPred = qual_undump (s);
4864               }
4865
4866             if (reader_optCheckChar (s, '$'))
4867               {
4868                 hasGlobs = FALSE;
4869                 globs = globSet_undefined;
4870                 hasMods = FALSE;
4871                 mods = sRefSet_undefined;
4872               }
4873             else if (reader_optCheckChar (s, '^'))
4874               {
4875                 hasGlobs = TRUE;
4876                 globs = globSet_undefined;
4877                 hasMods = TRUE;
4878                 mods = sRefSet_undefined;
4879               }
4880             else
4881               {
4882                 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4883                 advanceField (s); globs  = globSet_undump (s);
4884                 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4885                 advanceField (s); mods   = sRefSet_undump (s);      
4886               }
4887
4888             if (reader_optCheckChar (s, '$'))
4889               {
4890                 ak = AK_UNKNOWN;
4891                 exp = XO_UNKNOWN;
4892               }
4893             else
4894               {
4895                 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4896                 advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4897               }
4898
4899             advanceField (s); access = typeIdSet_undump (s);
4900
4901             /*
4902             ** Optional clauses: Start with @<code>:
4903             */
4904
4905             while (reader_optCheckChar (s, '@'))
4906               {
4907                 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4908                   {
4909                     reader_checkChar (s, ':');
4910                     warnclause = warnClause_undump (s);
4911                   }
4912                 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4913                   {
4914                     reader_checkChar (s, ':');
4915                     specclauses = stateClauseList_undump (s);
4916                   }
4917                 else
4918                   {
4919                     BADBRANCH;
4920                   }
4921               }
4922
4923             advanceName (s);  name = reader_getStringWord (s);
4924
4925             ue = uentry_makeFunctionBase (name, ct, access, 
4926                                           hasGlobs, globs, 
4927                                           hasMods, mods, 
4928                                           ak, exp, defstate, isnull, 
4929                                           exitCode, specc, nullPred,
4930                                           specclauses,
4931                                           warnclause,
4932                                           fileloc_copy (loc));
4933             DPRINTF (("Undump: %s", uentry_unparse (ue)));
4934           }
4935           break;
4936         case KITER:
4937           {
4938             typeIdSet access;
4939             
4940             advanceField (s); access = typeIdSet_undump (s);
4941             advanceName (s);  name = reader_getStringWord (s);
4942             
4943             ue = uentry_makeIterBase (name, access, ct,
4944                                       fileloc_copy (loc));
4945           }
4946           break;
4947         case KENDITER:
4948           {
4949             typeIdSet access;
4950
4951             advanceField (s); access = typeIdSet_undump (s);
4952             advanceName (s);  name = reader_getStringWord (s);
4953             
4954             ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4955           }
4956           break;
4957         case KENUMCONST:  
4958         case KCONST:  
4959           {
4960             typeIdSet access;
4961             multiVal val;
4962             nstate nullstate;
4963
4964             if (reader_optCheckChar (s, '$'))
4965               {
4966                 val = multiVal_undefined;
4967                 access = typeIdSet_undefined;
4968                 nullstate = NS_UNKNOWN;
4969               }
4970             else
4971               {
4972                 advanceField (s); val = multiVal_undump (s);
4973                 advanceField (s); access = typeIdSet_undump (s);
4974                 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4975               }
4976
4977             advanceName (s);  name = reader_getStringWord (s);
4978             
4979             ue = uentry_makeConstantBase (name, ct, access,
4980                                           nullstate, fileloc_copy (loc), val);
4981             break;
4982           }
4983         case KSTRUCTTAG:
4984         case KUNIONTAG:
4985         case KENUMTAG:
4986           {
4987             ctype rtype;
4988             
4989             advanceField (s); rtype = ctype_undump (s);
4990             advanceName (s);  name = reader_getStringWord (s);
4991             ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4992           }
4993           break;
4994         case KINVALID:
4995           llcontbuglit ("uentry_undump: invalid");
4996           ue = uentry_undefined;
4997           break;
4998         case KELIPSMARKER:
4999           llcontbuglit ("uentry_undump: elips marker");
5000           ue = uentry_undefined;
5001           break;
5002         }
5003     }
5004   
5005   return (ue);
5006 }
5007
5008 cstring
5009 uentry_dump (uentry v)
5010 {
5011   return (uentry_dumpAux (v, FALSE));
5012 }
5013
5014 cstring
5015 uentry_dumpParam (uentry v)
5016 {
5017   llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5018                  ("dump: %s", uentry_unparseFull (v)));
5019
5020   return (uentry_dumpAux (v, TRUE));
5021 }
5022
5023 static cstring
5024 uentry_dumpAux (uentry v, bool isParam)
5025 {
5026   llassert (uentry_isValid (v));
5027   llassert (!uentry_isGlobalMarker (v));
5028
5029   DPRINTF (("Dump uentry: [%p]", v));
5030   DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5031   
5032   switch (v->ukind)
5033     {
5034     case KINVALID: 
5035       llcontbuglit ("uentry_dump: invalid entry"); 
5036       return cstring_undefined;
5037     case KELIPSMARKER: 
5038       return (message ("!."));
5039     case KVAR:     
5040       {
5041         cstring sdump;
5042         vkind vk  = v->info->var->kind;
5043         sstate dss = sRef_getDefState (v->sref);
5044         nstate nst = sRef_getNullState (v->sref);
5045         alkind alk = sRef_getAliasKind (v->sref);
5046         exkind exk = sRef_getExKind (v->sref);
5047         chkind chk = v->info->var->checked;
5048
5049         DPRINTF (("Dumping var"));
5050
5051         if (dss == SS_UNKNOWN
5052             && nst == NS_UNKNOWN
5053             && alk == AK_IMPTEMP
5054             && exk == XO_UNKNOWN
5055             && chk == CH_UNKNOWN)
5056           {
5057             sdump = cstring_makeLiteral ("$");
5058           }
5059         else if (dss == SS_DEFINED
5060                  && nst == NS_UNKNOWN
5061                  && alk == AK_IMPTEMP
5062                  && exk == XO_UNKNOWN
5063                  && chk == CH_UNKNOWN)
5064           {
5065             sdump = cstring_makeLiteral ("&");
5066           }
5067         else if (dss == SS_UNKNOWN
5068                  && nst == NS_UNKNOWN
5069                  && alk == AK_UNKNOWN
5070                  && exk == XO_UNKNOWN
5071                  && chk == CH_UNKNOWN)
5072           {
5073             sdump = cstring_makeLiteral ("^");
5074           }
5075         else if (exk == XO_UNKNOWN
5076                  && chk == CH_UNKNOWN)
5077           {
5078             sdump = message ("%d@%d@%d&",
5079                              (int) dss,
5080                              (int) nst,
5081                              (int) alk);
5082           }
5083         else
5084           {
5085             sdump = message ("%d@%d@%d@%d@%d",  
5086                      (int) dss,
5087                              (int) nst,
5088                              (int) alk,
5089                              (int) exk,
5090                              (int) chk);
5091           }
5092         
5093
5094         if (vk != VKPARAM)
5095           {
5096             return (message ("%q|@%d|%q#%s", 
5097                              ctype_dump (v->utype), 
5098                              (int) vk,
5099                              sdump,
5100                              isParam ? cstring_undefined : v->uname));
5101           }
5102         else
5103           {
5104             return (message ("%q|%q#%s", 
5105                              ctype_dump (v->utype), 
5106                              sdump,
5107                              isParam ? cstring_undefined : v->uname));
5108           }
5109
5110       }
5111     case KDATATYPE: 
5112       /*
5113       DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5114                 uentry_unparse (v), 
5115                 exkind_unparse (sRef_getExKind (v->sref)),
5116                 ctype_unparse (v->utype), (int) v->utype));
5117       */
5118
5119       return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s", 
5120                        ctype_dump (v->utype),
5121                        ynm_unparseCode (v->info->datatype->abs),
5122                        ynm_unparseCode (v->info->datatype->mut),
5123                        (int) sRef_getDefState (v->sref),
5124                        (int) sRef_getNullState (v->sref),
5125                        (int) sRef_getAliasKind (v->sref),
5126                        (int) sRef_getExKind (v->sref),
5127                        ctype_dump (v->info->datatype->type),
5128                        v->uname));
5129     case KFCN:
5130       {
5131         cstring sdump, gdump, adump, xdump;
5132         alkind alk = sRef_getAliasKind (v->sref);
5133         exkind exk = sRef_getExKind (v->sref);
5134
5135         if (sRef_getDefState (v->sref) == SS_DEFINED
5136             && !nstate_isKnown (sRef_getNullState (v->sref))
5137             && !exitkind_isKnown (v->info->fcn->exitCode)
5138             && v->info->fcn->specialCode == SPC_NONE
5139             && qual_isUnknown (v->info->fcn->nullPred))
5140           {
5141             sdump = cstring_makeLiteral ("$");
5142           }
5143         else
5144           {
5145             sdump = message ("@%d@%d@%d@%d@%x",
5146                              (int) sRef_getDefState (v->sref),
5147                              (int) sRef_getNullState (v->sref),
5148                              (int) v->info->fcn->exitCode,
5149                              (int) v->info->fcn->specialCode,
5150                              qual_dump (v->info->fcn->nullPred));
5151           }
5152
5153         if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5154           {
5155             gdump = cstring_makeLiteral ("$");
5156           }
5157         else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5158                  && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5159           {
5160             gdump = cstring_makeLiteral ("^");
5161           }
5162         else
5163           {
5164             gdump = message ("@%s@%q@%s@%q",
5165                              bool_dump (uentry_hasGlobs (v)),
5166                              globSet_dump (uentry_getGlobs (v)),
5167                              bool_dump (uentry_hasMods (v)),
5168                              sRefSet_dump (uentry_getMods (v)));
5169           }
5170
5171         if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5172           {
5173             adump = cstring_makeLiteral ("$");
5174           }
5175         else
5176           {
5177             adump = message ("@%d@%d", (int) alk, (int) exk);
5178           }
5179
5180         xdump = cstring_undefined;
5181
5182         if (uentry_hasWarning (v))
5183           {
5184             xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5185           }
5186
5187         if (uentry_hasStateClauseList (v))
5188           {
5189             xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5190           }
5191
5192         return (message ("%q%q%q%q@%q%q#%s",
5193                          ctype_dump (v->utype),
5194                          sdump,
5195                          gdump,
5196                          adump,
5197                          typeIdSet_dump (uentry_accessType (v)),
5198                          xdump,
5199                          v->uname));
5200       }
5201     case KITER:
5202       return (message ("%q@%q#%s",
5203                        ctype_dump (v->utype),
5204                        typeIdSet_dump (v->info->iter->access),
5205                        v->uname));
5206     case KENDITER:
5207       return (message ("%q@%q#%s",
5208                        ctype_dump (v->utype),
5209                        typeIdSet_dump (uentry_accessType (v)),
5210                        v->uname));
5211     case KENUMCONST:  
5212     case KCONST:  
5213       {
5214         cstring sdump;
5215
5216         if (multiVal_isUnknown (uentry_getConstantValue (v))
5217             && typeIdSet_isEmpty (uentry_accessType (v))
5218             && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5219           {
5220             sdump = cstring_makeLiteral ("$");
5221           }
5222         else
5223           {
5224             sdump = message ("@%q@%q@%d",
5225                              multiVal_dump (uentry_getConstantValue (v)),
5226                              typeIdSet_dump (uentry_accessType (v)),
5227                              (int) sRef_getNullState (v->sref));
5228           }
5229
5230         return (message ("%q%q#%s", 
5231                          ctype_dump (v->utype), 
5232                          sdump,
5233                          v->uname));
5234       }
5235     case KSTRUCTTAG:
5236     case KUNIONTAG:
5237     case KENUMTAG:
5238       return (message ("%q@%q#%s", 
5239                        ctype_dump (v->utype), 
5240                        ctype_dump (v->info->datatype->type), v->uname));
5241     }
5242
5243   BADEXIT;
5244 }
5245
5246 /*@only@*/ cstring
5247 uentry_unparseAbbrev (uentry v)
5248 {
5249   if (!uentry_isVariable (v))
5250     {
5251       llcontbuglit ("uentry_unparseAbbrev: not variable");
5252       return uentry_unparse (v);
5253     }
5254
5255   return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5256 }
5257
5258 /*@only@*/ cstring
5259 uentry_unparse (uentry v)
5260 {
5261   cstring st;
5262
5263     if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5264   if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5265
5266   st = uentry_getName (v);
5267
5268   if (cstring_isDefined (st))
5269     {
5270       return (ctype_unparseDeclaration (v->utype, st)); 
5271     }
5272   else
5273     {
5274       cstring_free (st);
5275       return (cstring_copy (ctype_unparse (v->utype)));
5276     }
5277 }
5278
5279 /*@only@*/ cstring
5280 uentry_unparseFull (uentry v)
5281 {
5282   if (uentry_isUndefined (v))
5283     {
5284       return (cstring_makeLiteral ("<undefined>"));
5285     }
5286   else
5287     {
5288       cstring res;
5289
5290       res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5291                      (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5292                      ctype_unparse (v->utype),
5293                      fileloc_unparse (uentry_whereSpecified (v)),
5294                      fileloc_unparse (uentry_whereDeclared (v)),
5295                      fileloc_unparse (uentry_whereDefined (v)));
5296
5297       DPRINTF (("uentry: %s", res));
5298
5299       if (uentry_isDatatype (v))
5300         {
5301           res = message ("%q / type: %s mut: %s abs: %s state: %q",
5302                          res,
5303                          ctype_unparse 
5304                          (ctype_isDefined (v->info->datatype->type) 
5305                           ? v->info->datatype->type : ctype_unknown),
5306                          ynm_unparse (v->info->datatype->mut),
5307                          ynm_unparse (v->info->datatype->abs),
5308                          sRef_unparseState (v->sref));
5309         }
5310       else if (uentry_isFunction (v))
5311         {
5312           res = message ("%q / sref: %q / mods: %q / "
5313                          "globs: %q / clauses: %q / pre: %q / post: %q",
5314                          res,
5315                          sRef_unparseFull (v->sref),
5316                          sRefSet_unparse (v->info->fcn->mods),
5317                          globSet_unparse  (v->info->fcn->globs),
5318                          stateClauseList_unparse (v->info->fcn->specclauses),
5319                          functionConstraint_unparse (v->info->fcn->preconditions),
5320                          functionConstraint_unparse (v->info->fcn->postconditions));
5321         }
5322       else if (uentry_isIter (v))
5323         {
5324           res = message ("%q / sref: %q",
5325                          res,
5326                          sRef_unparseFull (v->sref));
5327         }
5328       else if (uentry_isVariable (v))
5329         {
5330           res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5331                          res,
5332                          sRef_unparseFull (v->sref),
5333                          (int) v->info->var->kind,
5334                          (int) v->info->var->defstate,
5335                          (int) v->info->var->nullstate,
5336                          (int) v->used);
5337           DPRINTF (("sref: [%p]", v->sref));
5338           DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5339           /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref)));           */
5340         }
5341       else if (uentry_isConstant (v))
5342         {
5343           res = message ("%q = %q",
5344                          res, multiVal_unparse (uentry_getConstantValue (v)));
5345         }
5346       else
5347         {
5348           res = message ("%q :: %q", res, uentry_unparse (v));
5349         }
5350
5351       return res;
5352     }
5353 }
5354
5355 bool uentry_hasAccessType (uentry e)
5356 {
5357   if (uentry_isValid (e))
5358     {
5359       switch (e->ukind)
5360         {
5361         case KITER:
5362           return (!typeIdSet_isEmpty (e->info->iter->access));
5363         case KENDITER:
5364           return (!typeIdSet_isEmpty (e->info->enditer->access));
5365         case KFCN:
5366           return (!typeIdSet_isEmpty (e->info->fcn->access));
5367         case KENUMCONST:
5368         case KCONST:
5369           return (!typeIdSet_isEmpty (e->info->uconst->access));
5370         default:
5371           return FALSE;
5372         }
5373     }
5374
5375   return FALSE;
5376 }
5377   
5378 typeIdSet uentry_accessType (uentry e)
5379 {
5380   if (uentry_isValid (e))
5381     {
5382       switch (e->ukind)
5383         {
5384         case KITER:
5385           return (e->info->iter->access);
5386         case KENDITER:
5387           return (e->info->enditer->access);
5388         case KFCN:
5389           return (e->info->fcn->access);
5390         case KENUMCONST:
5391         case KCONST:
5392           return (e->info->uconst->access);
5393         default:
5394           break;
5395         }
5396     }
5397
5398   return typeIdSet_undefined;
5399 }
5400
5401 bool
5402 uentry_isVariable (uentry e)
5403 {
5404   return (uentry_isVar (e));
5405 }
5406
5407 bool
5408 uentry_isSpecified (uentry e)
5409 {
5410   return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5411 }
5412
5413 static bool
5414 uentry_isReallySpecified (uentry e)
5415 {
5416   return (uentry_isValid (e) 
5417           && fileloc_isRealSpec (e->whereSpecified));
5418 }
5419
5420 bool
5421 uentry_isVar (uentry e)
5422 {
5423   return (!uentry_isUndefined (e) && e->ukind == KVAR);
5424 }
5425
5426 bool 
5427 uentry_isFakeTag (uentry e)
5428 {
5429   return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5430 }
5431
5432 bool
5433 uentry_isDatatype (uentry e)
5434 {
5435   return (!uentry_isUndefined (e) &&
5436           (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5437            e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5438 }
5439
5440 void
5441 uentry_setAbstract (uentry e)
5442 {
5443   typeId oldid;
5444
5445   llassert (uentry_isDatatype (e) 
5446             && (ynm_isMaybe (e->info->datatype->abs)));
5447
5448   oldid = ctype_typeId (e->info->datatype->type);
5449   e->info->datatype->abs = YES;
5450   e->info->datatype->type = ctype_createAbstract (oldid);
5451 }
5452
5453 void
5454 uentry_setConcrete (uentry e)
5455 {
5456   llassert (uentry_isDatatype (e) 
5457             && (ynm_isMaybe (e->info->datatype->abs)));
5458
5459   e->info->datatype->abs = NO;
5460 }
5461
5462 bool
5463 uentry_isAbstractDatatype (uentry e)
5464 {
5465   return (uentry_isDatatype (e) 
5466           && (ynm_isOn (e->info->datatype->abs)));
5467 }
5468
5469 bool
5470 uentry_isMaybeAbstract (uentry e)
5471 {
5472   return (uentry_isDatatype (e) 
5473           && (ynm_isMaybe (e->info->datatype->abs)));
5474 }
5475
5476 bool
5477 uentry_isMutableDatatype (uentry e)
5478 {
5479   bool res = uentry_isDatatype (e) 
5480     && (ynm_toBoolRelaxed (e->info->datatype->mut));
5481   
5482   return res;
5483 }
5484
5485 bool
5486 uentry_isRefCountedDatatype (uentry e)
5487 {
5488   return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5489 }
5490
5491 bool
5492 uentry_isParam (uentry u)
5493 {
5494   return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5495                                     || u->info->var->kind == VKYIELDPARAM));
5496 }
5497
5498 bool
5499 uentry_isExpandedMacro (uentry u)
5500 {
5501   return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5502 }
5503
5504 bool
5505 uentry_isSefParam (uentry u)
5506 {
5507   return (uentry_isVariable (u) 
5508           && (u->info->var->kind == VKSEFPARAM
5509               || u->info->var->kind == VKREFSEFPARAM
5510               || u->info->var->kind == VKSEFRETPARAM
5511               || u->info->var->kind == VKREFSEFRETPARAM));
5512 }
5513
5514 bool
5515 uentry_isRefParam (uentry u)
5516 {
5517   return (uentry_isVariable (u) 
5518           && (u->info->var->kind == VKREFPARAM
5519               || u->info->var->kind == VKREFYIELDPARAM
5520               || u->info->var->kind == VKREFSEFPARAM
5521               || u->info->var->kind == VKREFSEFRETPARAM));
5522 }
5523
5524 bool
5525 uentry_isAnyParam (uentry u)
5526 {
5527   return (uentry_isVariable (u) 
5528           && ((u->info->var->kind == VKPARAM)
5529               || (u->info->var->kind == VKSEFPARAM)
5530               || (u->info->var->kind == VKYIELDPARAM)
5531               || (u->info->var->kind == VKRETPARAM)
5532               || (u->info->var->kind == VKSEFRETPARAM)));
5533 }
5534
5535 sstate 
5536 uentry_getDefState (uentry u)
5537 {
5538   if (uentry_isValid (u))
5539     {
5540       return (sRef_getDefState (u->sref));
5541     }
5542   else
5543     {
5544       return (SS_UNKNOWN);
5545     }
5546 }
5547
5548 bool
5549 uentry_isOut (uentry u)
5550 {
5551   return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5552           || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5553 }
5554
5555 bool
5556 uentry_isPartial (uentry u)
5557 {
5558   return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5559           || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5560 }
5561
5562 bool
5563 uentry_isStateSpecial (uentry u)
5564 {
5565   return ((uentry_isVariable (u) 
5566            && (u->info->var->defstate == SS_SPECIAL))
5567           || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5568 }
5569
5570 exitkind uentry_getExitCode (uentry ue) 
5571 {
5572   if (uentry_isFunction (ue))
5573     {
5574       return ue->info->fcn->exitCode;
5575     }
5576   else
5577     {
5578       return XK_UNKNOWN;
5579     }
5580 }
5581
5582 qual uentry_nullPred (uentry u)
5583 {
5584   llassert (uentry_isRealFunction (u));
5585
5586   if (uentry_isFunction (u))
5587     {
5588       return (u->info->fcn->nullPred);
5589     }
5590   else
5591     {
5592       return qual_createUnknown ();
5593     }
5594 }
5595
5596 /*
5597 ** Note for variables, this is checking the declared state, not the current state.
5598 */
5599
5600 bool
5601 uentry_possiblyNull (uentry u)
5602 {
5603   return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5604           || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5605 }
5606
5607 alkind 
5608 uentry_getAliasKind (uentry u)
5609 {
5610   if (uentry_isValid (u))
5611     {
5612       return (sRef_getAliasKind (uentry_getSref (u)));
5613     }
5614   else
5615     {
5616       return AK_UNKNOWN;
5617     }
5618 }
5619
5620 exkind 
5621 uentry_getExpKind (uentry u)
5622 {
5623   if (uentry_isValid (u))
5624     {
5625       return (sRef_getExKind (uentry_getSref (u)));
5626     }
5627   else
5628     {
5629       return XO_UNKNOWN;
5630     }
5631 }
5632
5633 bool
5634 uentry_isIter (uentry e)
5635 {
5636   return (!uentry_isUndefined (e) && e->ukind == KITER);
5637 }
5638
5639 bool
5640 uentry_isEndIter (uentry e)
5641 {
5642   return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5643 }
5644
5645 bool
5646 uentry_isRealFunction (uentry e)
5647 {
5648   return (uentry_isFunction (e) ||
5649           (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5650 }
5651
5652 bool
5653 uentry_hasName (uentry e)
5654 {
5655   if (uentry_isValid (e))
5656     {
5657       cstring s = e->uname;
5658       
5659       return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5660                 || uentry_isFakeTag (e)));
5661     }
5662   else
5663     {
5664       return FALSE;
5665     }
5666 }
5667
5668 /*
5669 ** Returns true for fake tags.
5670 ** This is used for dumping the library
5671 */
5672
5673 bool uentry_hasRealName (uentry e)
5674 {
5675   return (uentry_isValid (e) 
5676           && cstring_isNonEmpty (e->uname)
5677           && !uentry_isGlobalMarker (e));
5678 }
5679
5680
5681 /*@observer@*/ globSet
5682 uentry_getGlobs (uentry l)
5683 {
5684   if (uentry_isInvalid (l)) 
5685     {
5686       return globSet_undefined;
5687     }
5688
5689   if (l->ukind != KFCN)
5690     {
5691       if (l->ukind != KITER && l->ukind != KENDITER)
5692         {
5693           if (l->ukind == KVAR)
5694             {
5695               llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)", 
5696                               uentry_unparse (l), 
5697                               ekind_unparse (l->ukind)));
5698             }
5699           else
5700             {
5701               llbug (message ("Bad call to uentry_getGlobs: %q (%s)", 
5702                               uentry_unparse (l), 
5703                               ekind_unparse (l->ukind)));
5704             }
5705         }
5706       return globSet_undefined;
5707     }
5708
5709   return l->info->fcn->globs;
5710 }
5711
5712 /*@observer@*/ sRefSet
5713 uentry_getMods (uentry l)
5714 {
5715   llassert (uentry_isValid (l));
5716
5717   if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5718     {
5719       llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5720       return sRefSet_undefined; 
5721     }
5722
5723   return l->info->fcn->mods;
5724 }
5725
5726 ekind
5727 uentry_getKind (uentry e)
5728 {
5729   llassert (uentry_isValid (e));
5730
5731   return (e->ukind);
5732 }
5733
5734 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5735 {
5736   llassert (uentry_isEitherConstant (e)); 
5737   return (sRef_getValue (e->sref));
5738 }
5739
5740 /*@observer@*/ uentryList
5741 uentry_getParams (uentry l)
5742 {
5743   if (uentry_isInvalid (l)) return uentryList_undefined;
5744
5745   switch (l->ukind)
5746     {
5747     case KFCN:  
5748     case KITER:
5749       {
5750         ctype ct = l->utype;
5751
5752         if (ctype_isFunction (ct))
5753           {
5754             return (ctype_argsFunction (ct));
5755           }
5756         else
5757           {
5758             return uentryList_undefined;
5759           }
5760       }
5761     case KVAR:  
5762       {
5763         ctype ct = l->utype;
5764
5765         llassert (ctype_isFunction (ct));
5766         return (ctype_argsFunction (ct));
5767       }
5768     BADDEFAULT;
5769     }
5770   BADEXIT;
5771 }
5772
5773 /*@observer@*/ cstring
5774 uentry_rawName (uentry e)
5775 {
5776   if (uentry_isValid (e))
5777     {
5778       return (e->uname);
5779     }
5780   else
5781     {
5782       return cstring_undefined;
5783     }
5784 }
5785
5786 static cstring
5787 uentry_getOptName (uentry e)
5788 {
5789   cstring s = uentry_getName (e);
5790
5791   if (cstring_isDefined (s))
5792     {
5793       s = cstring_appendChar (s, ' ');
5794     }
5795   
5796   return s;
5797 }
5798
5799 /*@only@*/ cstring
5800 uentry_getName (uentry e)
5801 {
5802   cstring ret = cstring_undefined;
5803
5804   if (uentry_isValid (e))
5805     {
5806       if (uentry_isAnyTag (e))
5807         {
5808           ret = fixTagName (e->uname);  
5809         }
5810       else if (uentry_isAnyParam (e))
5811         {
5812           ret = cstring_copy (fixParamName (e->uname));
5813         }
5814       else
5815         {
5816           ret = cstring_copy (e->uname);
5817         }
5818     }
5819
5820   return ret;
5821 }
5822
5823 cstring uentry_observeRealName (uentry e)
5824 {
5825   cstring ret = cstring_undefined;
5826
5827   if (uentry_isValid (e))
5828     {      
5829       if (uentry_isAnyTag (e))
5830         {
5831           if (isFakeTag (e->uname))
5832             {
5833               ret = cstring_undefined;
5834             }
5835           else
5836             {
5837               ret = plainTagName (e->uname); 
5838             }
5839         }
5840       else if (uentry_isAnyParam (e))
5841         {
5842           ret = fixParamName (e->uname);
5843         }
5844       else
5845         {
5846           ret = e->uname;
5847         }
5848     }
5849
5850   return ret;
5851 }
5852
5853 cstring uentry_getRealName (uentry e)
5854 {
5855   if (uentry_isValid (e))
5856     {
5857       if (uentry_isAnyTag (e))
5858         {
5859           return (cstring_undefined);
5860         }
5861       else
5862         {
5863           return (e->uname);
5864         }
5865     }
5866   return cstring_undefined;
5867 }
5868
5869 ctype uentry_getType (uentry e)
5870 {
5871   if (uentry_isValid (e))
5872     {
5873       return e->utype;
5874     }
5875   else
5876     {
5877       return ctype_unknown;
5878     }
5879 }
5880
5881 fileloc uentry_whereLast (uentry e)
5882 {
5883   fileloc loc;
5884
5885   if (uentry_isInvalid (e)) 
5886     {
5887       return fileloc_undefined;
5888     }
5889   
5890   loc = e->whereDefined;
5891
5892   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5893     {
5894       return loc;
5895     }
5896
5897   loc = uentry_whereDeclared (e);
5898
5899   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5900     {
5901       return loc;
5902     }
5903
5904   loc = uentry_whereSpecified (e);
5905   return loc;
5906 }
5907
5908 fileloc uentry_whereEither (uentry e)
5909 {
5910   if (uentry_isInvalid (e)) return fileloc_undefined;
5911
5912   if (fileloc_isDefined (e->whereDefined) 
5913       && !fileloc_isExternal (e->whereDefined))
5914     {
5915       return e->whereDefined;
5916     }
5917   else if (fileloc_isDefined (e->whereDeclared))
5918     {
5919       return e->whereDeclared;
5920     }
5921   else
5922     {
5923       return e->whereSpecified;
5924     }
5925 }
5926
5927 fileloc uentry_whereSpecified (uentry e)
5928 {
5929   if (uentry_isInvalid (e)) return fileloc_undefined;
5930
5931   return (e->whereSpecified);
5932 }
5933
5934 fileloc uentry_whereDefined (uentry e)
5935 {
5936   if (uentry_isInvalid (e)) return fileloc_undefined;
5937
5938   return (e->whereDefined);
5939 }
5940
5941 fileloc uentry_whereDeclared (uentry e)
5942 {
5943   if (uentry_isInvalid (e)) return fileloc_undefined;
5944
5945   return (e->whereDeclared);
5946 }
5947
5948 /*@observer@*/ fileloc
5949 uentry_whereEarliest (uentry e)
5950 {
5951   if (uentry_isInvalid (e)) return fileloc_undefined;
5952   
5953   if (fileloc_isDefined (e->whereSpecified))
5954     {
5955       return (e->whereSpecified);
5956     }
5957   else if (fileloc_isDefined (e->whereDeclared))
5958     {
5959       return (e->whereDeclared);
5960     }
5961   else
5962     {
5963       return e->whereDefined;
5964     }
5965 }
5966
5967 void
5968 uentry_setFunctionDefined (uentry e, fileloc loc)
5969 {
5970   if (uentry_isValid (e))
5971     {
5972       llassert (uentry_isFunction (e));
5973
5974       if (fileloc_isUndefined (e->whereDeclared))
5975         {
5976           e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5977         }
5978       
5979       if (!fileloc_isDefined (e->whereDefined))
5980         {
5981           e->whereDefined = fileloc_update (e->whereDefined, loc);
5982         }
5983     }
5984 }
5985
5986 void
5987 uentry_setDeclDef (uentry e, fileloc f)
5988 {
5989   uentry_setDeclared (e, f);
5990   
5991   if (!uentry_isFunction (e)
5992       && !(uentry_isVariable (e) && uentry_isExtern (e)))
5993     {
5994       uentry_setDefined (e, f);
5995     }
5996 }
5997
5998 void
5999 uentry_setDeclaredForce (uentry e, fileloc f)
6000 {
6001   llassert (uentry_isValid (e));
6002   e->whereDeclared = fileloc_update (e->whereDeclared, f);
6003 }
6004
6005 void
6006 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6007 {
6008   llassert (uentry_isValid (e));
6009   fileloc_free (e->whereDeclared);
6010   e->whereDeclared = f;
6011 }
6012
6013 void
6014 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6015 {
6016   fileloc oldloc;
6017
6018   llassert (uentry_isValid (e));
6019   oldloc = e->whereDeclared;  
6020
6021   if (fileloc_isDefined (oldloc))
6022     {
6023       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6024         {
6025           e->whereDeclared = f;
6026           fileloc_free (oldloc);
6027         }
6028       else
6029         {
6030           fileloc_free (f);
6031         }
6032     }
6033   else
6034     {
6035       e->whereDeclared = f;
6036       fileloc_free (oldloc);
6037     }
6038 }
6039   
6040 void
6041 uentry_setDeclared (uentry e, fileloc f)
6042 {
6043   fileloc oldloc;
6044
6045   llassert (uentry_isValid (e));
6046   oldloc = e->whereDeclared;  
6047
6048   if (fileloc_isDefined (oldloc))
6049     {
6050       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6051         {
6052           e->whereDeclared = fileloc_update (e->whereDeclared, f);
6053         }
6054       else
6055         {
6056           ;
6057         }
6058     }
6059   else
6060     {
6061       e->whereDeclared = fileloc_update (e->whereDeclared, f);
6062     }
6063 }
6064
6065 void
6066 uentry_clearDefined (uentry e)
6067 {
6068   if (uentry_isValid (e))
6069     {
6070       e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6071     }
6072 }
6073
6074 void
6075 uentry_setDefined (uentry e, fileloc f)
6076 {
6077   fileloc oldloc;
6078
6079   llassert (uentry_isValid (e));
6080   oldloc = e->whereDefined;
6081
6082   if (fileloc_isDefined (oldloc))
6083     {
6084       if (fileloc_isLib (oldloc) 
6085           || fileloc_isImport (oldloc)
6086           || fileloc_isBuiltin (oldloc) 
6087           || fileloc_isPreproc (oldloc))
6088         {
6089           e->whereDefined = fileloc_update (e->whereDefined, f);
6090         }
6091       else
6092         {
6093           if (fileloc_equal (oldloc, f) || context_processingMacros ())
6094             {
6095               ; /* okay */
6096             }
6097           else
6098             {
6099               if (optgenerror (FLG_REDEF,
6100                                message ("%s %q redefined", 
6101                                         ekind_capName (e->ukind),
6102                                         uentry_getName (e)),
6103                                f))
6104                 {
6105                   llgenindentmsg (message ("Previous definition of %q", 
6106                                            uentry_getName (e)),
6107                                   e->whereDefined);
6108                 }
6109             }
6110         }
6111     }
6112   else
6113     {
6114       e->whereDefined = fileloc_update (e->whereDefined, f);
6115     }
6116 }
6117
6118 bool
6119 uentry_isCodeDefined (uentry e)
6120 {
6121   llassert (uentry_isValid (e));
6122
6123   return (fileloc_isDefined (e->whereDefined));
6124 }
6125
6126 bool
6127 uentry_isDeclared (uentry e)
6128 {
6129   if (uentry_isValid (e))
6130     {
6131       return (fileloc_isDefined (e->whereDeclared));
6132     }
6133
6134   return FALSE;
6135 }
6136
6137 sRef uentry_getSref (uentry e)
6138 {
6139   /* not true, used for functions too (but shouldn't be? */
6140   /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6141
6142   if (uentry_isInvalid (e)) return sRef_undefined;
6143   
6144   return (e->sref);
6145 }
6146
6147 sRef uentry_getOrigSref (uentry e)
6148 {
6149   /*@i523*/ /* evans 2001-09-09 - need to fix this 
6150   if (uentry_isValid (e))
6151     {
6152       if (uentry_isVariable (e))
6153         {
6154           return e->info->var->origsref;
6155         }
6156       else
6157         {
6158           sRef sr = sRef_copy (uentry_getSref (e));
6159           
6160           sRef_resetState (sr);
6161           sRef_clearDerived (sr);
6162           return (sr);
6163         }
6164     }
6165   else
6166     {
6167       return sRef_undefined;
6168     }
6169   */
6170
6171   if (uentry_isValid (e))
6172     {
6173       sRef sr = sRef_copy (uentry_getSref (e));
6174       
6175       sRef_resetState (sr);
6176       sRef_clearDerived (sr);
6177       
6178       if (uentry_isVariable (e))
6179         {
6180           sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6181           sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6182         }
6183       
6184       return (sr);
6185     }
6186   else
6187     {
6188       return sRef_undefined;
6189     }
6190 }
6191
6192 /*
6193 ** requires: uentry e is not in a hashed symbol table
6194 */
6195
6196 void 
6197 uentry_setName (uentry e, /*@only@*/ cstring n)
6198 {
6199   llassert (uentry_isValid (e));
6200
6201   cstring_free (e->uname);
6202   e->uname = n;
6203 }
6204
6205 void
6206 uentry_setType (uentry e, ctype t)
6207 {
6208   if (uentry_isValid (e)) 
6209     {
6210       e->utype = t;
6211       sRef_setType (e->sref, t);
6212     }
6213 }
6214
6215 void
6216 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6217 {
6218   ctype rct;
6219   ctype rettype = ctype_unknown;
6220   
6221   llassert (uentry_isValid (ue));
6222
6223   uentry_convertVarFunction (ue);
6224   llassert (uentry_isFunction (ue));
6225
6226   rct = ctype_realType (ue->utype);
6227
6228   if (ctype_isFunction (rct))
6229     {
6230       rettype = ctype_getReturnType (rct);
6231     }
6232
6233   ue->utype = ctype_makeNFParamsFunction (rettype, pn);      
6234 }
6235
6236 void
6237 uentry_setRefParam (uentry e)
6238 {
6239   if (!uentry_isVar (e))
6240     {
6241       llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6242     }
6243   else
6244     {
6245       if (e->info->var->kind == VKSEFPARAM)
6246         {
6247           e->info->var->kind = VKREFSEFPARAM;
6248         }
6249       else if (e->info->var->kind == VKSEFRETPARAM)
6250         {
6251           e->info->var->kind = VKREFSEFRETPARAM;
6252         }
6253       else if (e->info->var->kind == VKYIELDPARAM)
6254         {
6255           e->info->var->kind = VKREFYIELDPARAM;
6256         }
6257       else
6258         {
6259           e->info->var->kind = VKREFPARAM;
6260         }
6261     }
6262 }
6263
6264 void
6265 uentry_setParam (uentry e)
6266 {
6267   if (!uentry_isVar (e))
6268     {
6269       if (uentry_isElipsisMarker (e))
6270         {
6271
6272         }
6273       else
6274         {
6275           llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6276         }
6277     }
6278   else
6279     {
6280       cstring oldname;
6281
6282       if (e->info->var->kind == VKYIELDPARAM 
6283           || e->info->var->kind == VKSEFPARAM
6284           || e->info->var->kind == VKSEFRETPARAM)
6285         {
6286           ;
6287         }
6288       else
6289         {
6290           e->info->var->kind = VKPARAM;
6291         }
6292
6293       oldname = e->uname;
6294       e->uname = makeParam (e->uname);
6295       cstring_free (oldname);
6296     }
6297 }
6298
6299 void
6300 uentry_setSref (uentry e, sRef s)
6301 {
6302   if (uentry_isValid (e))
6303     {
6304       if (sRef_isValid (e->sref))
6305         {
6306           sRef_mergeStateQuietReverse (e->sref, s);
6307         }
6308       else
6309         {
6310           e->sref = sRef_saveCopy (s);
6311         }
6312     }
6313 }
6314
6315 ctype
6316 uentry_getAbstractType (uentry e)
6317 {
6318   llassert (uentry_isDatatype (e));
6319
6320   /*
6321   ** This assertion removed.
6322   ** Okay to have undefined type, for system types
6323   
6324   llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6325                     ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6326                     e->utype);
6327                     
6328   */
6329
6330   if (ctype_isUndefined (e->info->datatype->type))
6331     {
6332       return ctype_unknown;
6333     }
6334
6335   /*
6336   ** Sadly, a kludge...
6337   */
6338
6339   if (ctype_isUserBool (e->info->datatype->type)) {
6340     return ctype_bool;
6341   }
6342
6343   return e->info->datatype->type;
6344 }
6345
6346 ctype uentry_getRealType (uentry e)
6347 {
6348   ctype ct;
6349   typeId uid = USYMIDINVALID;
6350
6351   if (uentry_isInvalid (e))
6352     {
6353       return ctype_unknown;
6354     }
6355
6356   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6357
6358   if (uentry_isAnyTag (e))
6359     {
6360       return (e->utype);
6361     }
6362   
6363   if (uentry_isAbstractType (e))
6364     {
6365       ct = uentry_getAbstractType (e);      
6366
6367       if (ctype_isManifestBool (ct)) {
6368         return ct;
6369       }
6370
6371       llassert (ctype_isUA (ct));
6372       
6373       uid = ctype_typeId (ct);
6374       
6375       if (!context_hasAccess (uid))
6376         {
6377           return (ct);
6378         }
6379     }
6380
6381   ct = uentry_getType (e);
6382
6383   /* if (ctype_isUserBool (ct)) return ct; */
6384
6385   if (ctype_isManifestBool (ct)) {
6386     return ctype_bool;
6387   }
6388   
6389   if (ctype_isUA (ct))
6390     {
6391       usymId iid = ctype_typeId (ct);
6392       
6393       if (usymId_equal (iid, uid))
6394         {         
6395           llcontbug (message ("uentry_getRealType: recursive type! %s",
6396                               ctype_unparse (ct)));
6397           return ct;
6398         }
6399       else
6400         {
6401           /* evs 2000-07-25: possible infinite recursion ? */
6402           uentry ue2 = usymtab_getTypeEntry (iid);
6403
6404           if (ue2 == e)
6405             {
6406               llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6407               return ctype_unknown;
6408             }
6409
6410           return uentry_getRealType (ue2);
6411         }
6412     }
6413   else
6414     {
6415       return ct;
6416     }
6417 }
6418
6419 ctype uentry_getForceRealType (uentry e)
6420 {
6421   ctype   ct;
6422   typeId uid = USYMIDINVALID;
6423
6424   if (uentry_isInvalid (e))
6425     {
6426       return ctype_unknown;
6427     }
6428
6429   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6430   
6431   if (uentry_isAnyTag (e))
6432     {
6433       return (e->utype);
6434     }
6435   
6436   if (uentry_isAbstractType (e))
6437     {
6438       ct = uentry_getAbstractType (e);      
6439       llassert (ctype_isUA (ct));
6440       
6441       uid = ctype_typeId (ct);
6442       /* no check for access! */
6443     }
6444   
6445   ct = uentry_getType (e);
6446
6447   /* evs 2000-07-25 */
6448   /* if (ctype_isUserBool (ct)) return ct; */
6449
6450   if (ctype_isManifestBool (ct)) {
6451     return ctype_bool;
6452   }
6453   
6454   if (ctype_isUA (ct))
6455     {
6456       usymId iid = ctype_typeId (ct);
6457       
6458       if (usymId_equal (iid, uid))
6459         {         
6460           llcontbug (message ("uentry_getRealType: recursive type! %s",
6461                               ctype_unparse (ct)));
6462           return ct;
6463         }
6464       else
6465         {
6466           return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6467         }
6468     }
6469   else
6470     {
6471       return ct;
6472     }
6473 }
6474
6475 uentry uentry_nameCopy (cstring name, uentry e)
6476 {
6477   uentry enew = uentry_alloc ();
6478
6479   llassert (uentry_isValid (e));
6480
6481   /* enew->shallowCopy = FALSE; */
6482   enew->ukind = e->ukind;
6483   enew->uname = name;
6484   enew->utype = e->utype;
6485   enew->whereSpecified = fileloc_copy (e->whereSpecified);
6486   enew->whereDefined = fileloc_copy (e->whereDefined);
6487   enew->whereDeclared = fileloc_copy (e->whereDeclared);
6488   enew->sref = sRef_copy (e->sref); 
6489   enew->used = e->used;
6490   enew->lset = FALSE;
6491   enew->isPrivate = e->isPrivate;
6492   enew->hasNameError = FALSE;
6493
6494   enew->uses = filelocList_new ();
6495   enew->warn = warnClause_undefined; 
6496
6497   enew->storageclass = e->storageclass;
6498   enew->info = uinfo_copy (e->info, e->ukind);
6499
6500   return enew;
6501 }
6502
6503 void
6504 uentry_setDatatype (uentry e, usymId uid)
6505 {
6506   llassert (uentry_isDatatype (e));
6507
6508   if (uentry_isAbstractType (e))
6509     {
6510       e->info->datatype->type = ctype_createAbstract (uid);
6511     }
6512   else
6513     {
6514       e->info->datatype->type = ctype_createUser (uid);
6515     }
6516 }
6517
6518 static void 
6519 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6520    /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6521    /*@modifies e@*/
6522 {
6523   llassert (uentry_isValid (e));
6524
6525   if (fileloc_isSpec (f) || fileloc_isImport (f))
6526     {
6527       e->whereSpecified = f;
6528       e->whereDeclared  = fileloc_undefined;
6529       e->whereDefined  = fileloc_undefined;
6530     }
6531   else
6532     {
6533       e->whereSpecified = fileloc_undefined;
6534       e->whereDeclared  = f;
6535       e->whereDefined  = fileloc_undefined;
6536     }
6537
6538   llassert (fileloc_storable (f));
6539 }
6540
6541 static void
6542 ucinfo_free (/*@only@*/ ucinfo u)
6543 {
6544   sfree (u);
6545 }
6546
6547 static void
6548 uvinfo_free (/*@only@*/ uvinfo u)
6549 {
6550   /*drl7x added 6/29/01 */
6551   free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6552   sfree (u);
6553 }
6554
6555 static void
6556 udinfo_free (/*@only@*/ udinfo u)
6557 {
6558   sfree (u);
6559 }
6560
6561 static void
6562 ufinfo_free (/*@only@*/ ufinfo u)
6563 {
6564   globSet_free (u->globs);
6565   sRefSet_free (u->mods);
6566   stateClauseList_free (u->specclauses);
6567   sfree (u);
6568 }
6569
6570 static void
6571 uiinfo_free (/*@only@*/ uiinfo u)
6572 {
6573   sfree (u);
6574 }
6575
6576 static void
6577 ueinfo_free (/*@only@*/ ueinfo u)
6578 {
6579   sfree (u);
6580 }
6581
6582 static /*@only@*/ ucinfo
6583 ucinfo_copy (ucinfo u)
6584 {
6585   ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6586   ret->access = u->access;
6587   return ret;
6588 }
6589
6590 static /*@only@*/ uvinfo
6591 uvinfo_copy (uvinfo u)
6592 {
6593   uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6594   
6595   ret->kind = u->kind;
6596   ret->nullstate = u->nullstate;
6597   ret->defstate = u->defstate;
6598   ret->checked = u->checked;
6599
6600   /*@i523 ret->origsref = sRef_copy (u->origsref); */
6601
6602   /* drl added 07-02-001 */
6603   /* copy null terminated information */
6604
6605   if (u->bufinfo != NULL)
6606     {
6607       ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6608       ret->bufinfo->bufstate = u->bufinfo->bufstate;
6609       ret->bufinfo->size     = u->bufinfo->size;
6610       ret->bufinfo->len      = u->bufinfo->len;
6611       return ret;
6612     }
6613   else
6614     {
6615       ret->bufinfo = NULL;
6616       return ret;
6617     }
6618     
6619 }
6620
6621 static /*@only@*/ udinfo
6622 udinfo_copy (udinfo u)
6623 {
6624   udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6625
6626   ret->abs = u->abs;
6627   ret->mut = u->mut;
6628   ret->type = u->type;
6629
6630   return ret;
6631 }
6632
6633 static /*@only@*/ ufinfo
6634 ufinfo_copy (ufinfo u)
6635 {
6636   ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6637
6638   ret->hasGlobs = u->hasGlobs;
6639   ret->hasMods = u->hasMods;
6640   ret->exitCode = u->exitCode;
6641   ret->specialCode = u->specialCode;
6642   ret->nullPred = u->nullPred;
6643   ret->access = u->access;
6644   ret->globs = globSet_newCopy (u->globs);
6645   ret->mods = sRefSet_newCopy (u->mods);
6646   ret->defparams = u->defparams;
6647   ret->specclauses = stateClauseList_copy (u->specclauses);
6648
6649   ret->preconditions = functionConstraint_copy (u->preconditions);
6650   ret->postconditions = functionConstraint_copy (u->postconditions);
6651   
6652   return ret;
6653 }
6654
6655 static /*@only@*/ uiinfo
6656 uiinfo_copy (uiinfo u)
6657 {
6658   uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6659
6660   ret->access = u->access;
6661   ret->globs = globSet_newCopy (u->globs);
6662   ret->mods = sRefSet_newCopy (u->mods);
6663
6664   return (ret);
6665 }
6666
6667 static /*@only@*/ ueinfo
6668 ueinfo_copy (ueinfo u)
6669 {
6670   ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6671
6672   ret->access = u->access;
6673   return ret;
6674 }
6675
6676 static void
6677 uinfo_free (uinfo u, ekind kind)
6678 {
6679   switch (kind)
6680     {
6681     case KENUMCONST:
6682     case KCONST:       ucinfo_free (u->uconst); break;
6683     case KVAR:         uvinfo_free (u->var); break;
6684     case KSTRUCTTAG:
6685     case KUNIONTAG:
6686     case KENUMTAG:
6687     case KDATATYPE:    udinfo_free (u->datatype); break;
6688     case KFCN:         ufinfo_free (u->fcn); break;
6689     case KITER:        uiinfo_free (u->iter); break;
6690     case KENDITER:     ueinfo_free (u->enditer); break;
6691     case KELIPSMARKER: break;
6692     case KINVALID:     break;
6693     }
6694   
6695     sfree (u);
6696 }
6697
6698 static /*@only@*/ /*@null@*/ uinfo
6699 uinfo_copy (uinfo u, ekind kind)
6700 {
6701   if (kind == KELIPSMARKER || kind == KINVALID)
6702     {
6703       return NULL;
6704     }
6705   else
6706     {
6707       uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6708       
6709       switch (kind)
6710         {
6711         case KENUMCONST:
6712         case KCONST:    ret->uconst = ucinfo_copy (u->uconst); break;
6713         case KVAR:      ret->var = uvinfo_copy (u->var); break;
6714         case KSTRUCTTAG:
6715         case KUNIONTAG:
6716         case KENUMTAG:
6717         case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6718         case KFCN:      ret->fcn = ufinfo_copy (u->fcn); break;
6719         case KITER:     ret->iter = uiinfo_copy (u->iter); break;
6720         case KENDITER:  ret->enditer = ueinfo_copy (u->enditer); break;
6721         BADDEFAULT;
6722         }
6723       return ret;
6724     }
6725 }
6726
6727 static void
6728 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6729 {
6730   filelocList_free (e->uses);
6731   cstring_free (e->uname);
6732   
6733   uinfo_free (e->info, e->ukind);
6734   
6735   fileloc_free (e->whereSpecified); 
6736   fileloc_free (e->whereDefined); 
6737   fileloc_free (e->whereDeclared); 
6738
6739   warnClause_free (e->warn);
6740
6741   nuentries--;
6742   sfree (e);
6743   }
6744
6745 extern void uentry_markOwned (/*@owned@*/ uentry u)
6746 {
6747   sfreeEventually (u);
6748 }
6749
6750 void
6751 uentry_free (/*@only@*/ uentry e)
6752 {
6753   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6754     {
6755       uentry_reallyFree (e);
6756     }
6757 }
6758
6759 /*
6760 ** For uentry's in the global or file scope
6761 */
6762
6763 void
6764 uentry_freeComplete (/*@only@*/ uentry e)
6765 {
6766   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6767     {
6768       DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6769       /*@i@*/ sRef_free (e->sref);
6770       e->sref = sRef_undefined;
6771       uentry_reallyFree (e);
6772     }
6773 }
6774
6775 /*
6776 ** requires old->kind != new->kind, old->uname = new->uname
6777 */
6778
6779 static void
6780 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6781 {
6782   llassert (uentry_isValid (old));
6783   llassert (uentry_isValid (unew));
6784
6785   if (uentry_isEitherConstant (unew)
6786       && (fileloc_isPreproc (uentry_whereDeclared (old))
6787           || ctype_isUnknown (old->utype))
6788       && !uentry_isSpecified (old))
6789     {
6790       ; /* no error */
6791     }
6792   else 
6793     {
6794       if (mustConform)
6795         {
6796           if (!uentry_isDeclared (old))
6797             {
6798               if (uentry_isSpecified (old))
6799                 {
6800                   if (uentry_isSpecified (unew))
6801                     {
6802                       llbuglit ("Respecification!");
6803                     }
6804                   else if (uentry_isDeclared (unew))
6805                     {
6806                       if (optgenerror
6807                           (FLG_INCONDEFS,
6808                            message ("%s %q inconsistently declared as %s: %t",
6809                                     ekind_capName (old->ukind),
6810                                     uentry_getName (unew),
6811                                     ekind_unparseLong (unew->ukind),
6812                                     unew->utype),
6813                            uentry_whereDeclared (unew)))
6814                         {
6815                           uentry_showWhereLast (old);
6816                         }
6817                     }
6818                   else
6819                     {
6820                       BADEXIT;
6821                     }
6822                 }
6823               else
6824                 {
6825                   if (optgenerror
6826                       (FLG_INCONDEFS,
6827                        message ("%s %q inconsistently declared as %s: %t",
6828                                 ekind_capName (old->ukind),
6829                                 uentry_getName (unew),
6830                                 ekind_unparseLong (unew->ukind),
6831                                 unew->utype),
6832                        uentry_whereDeclared (unew)))
6833                     {
6834                       uentry_showWhereLast (old);
6835                     }
6836                 }
6837             }
6838           else
6839             {
6840               llassert (uentry_isDeclared (unew));
6841
6842               if (optgenerror
6843                   (FLG_INCONDEFS,
6844                    message ("%s %q inconsistently redeclared as %s",
6845                             ekind_capName (old->ukind),
6846                             uentry_getName (unew),
6847                             ekind_unparseLong (unew->ukind)),
6848                    uentry_whereDeclared (unew)))
6849                 {
6850                   uentry_showWhereLast (old);
6851                 }
6852             }
6853         }
6854     }
6855
6856   uentry_updateInto (old, unew);
6857 }
6858
6859 /*
6860 ** def is the definition of spec, modifies spec
6861 **
6862 ** reports any inconsistencies
6863 ** returns the summary of all available information
6864 ** if spec and def are inconsistent, def is returned
6865 */
6866
6867 void
6868 uentry_showWhereLast (uentry spec)
6869 {
6870   if (uentry_isValid (spec))
6871     {
6872       if (fileloc_isDefined (spec->whereDefined)
6873           && !fileloc_isLib (spec->whereDefined)
6874           && !fileloc_isPreproc (spec->whereDefined))
6875         {
6876           llgenindentmsg (message ("Previous definition of %q: %t", 
6877                                    uentry_getName (spec),
6878                                    uentry_getType (spec)),
6879                           uentry_whereDefined (spec));
6880         }
6881       else if (uentry_isDeclared (spec))
6882         {
6883           llgenindentmsg (message ("Previous declaration of %q: %t", 
6884                                    uentry_getName (spec),
6885                                    uentry_getType (spec)),
6886                           uentry_whereDeclared (spec));
6887         }
6888       else if (uentry_isSpecified (spec))
6889         {
6890           if (uentry_hasName (spec))
6891             {
6892               llgenindentmsg (message ("Specification of %q: %t", 
6893                                        uentry_getName (spec),
6894                                        uentry_getType (spec)),
6895                               uentry_whereSpecified (spec));
6896             }
6897           else
6898             {
6899               llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6900                               uentry_whereSpecified (spec));
6901             }
6902         }
6903       else
6904         {
6905           /* nothing to show */
6906         }
6907     }
6908 }
6909
6910 void
6911 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6912 {
6913   fileloc loc = uentry_whereDefined (ce);
6914   
6915   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6916     {
6917       llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6918                       loc);
6919     }
6920
6921   loc = uentry_whereSpecified (ce);
6922   
6923   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6924     {
6925       llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6926                       loc);
6927     }
6928 }
6929
6930 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6931 {
6932   if (uentry_isDeclared (spec))
6933     {
6934       llgenindentmsg (message ("Previous declaration of %q: %q", 
6935                                uentry_getName (spec), extra),
6936                       uentry_whereDeclared (spec));
6937     }
6938   else if (uentry_isSpecified (spec))
6939     {
6940       llgenindentmsg (message ("Specification of %q: %q", 
6941                                uentry_getName (spec), extra),
6942                       uentry_whereSpecified (spec));
6943     }
6944   else
6945     {
6946       cstring_free (extra);
6947     }
6948 }
6949
6950 void
6951 uentry_showWhereDeclared (uentry spec)
6952 {
6953   if (uentry_isDeclared (spec))
6954     {
6955       if (uentry_hasName (spec))
6956         {
6957           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6958                           uentry_whereDeclared (spec));
6959         }
6960       else
6961         {
6962           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6963         }
6964     }
6965   else if (uentry_isSpecified (spec))
6966     {
6967       if (uentry_hasName (spec))
6968         {
6969           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6970                           uentry_whereSpecified (spec));
6971         }
6972       else
6973         {
6974           llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6975         }
6976     }
6977   else
6978     {
6979       /* nothing to show */
6980     }
6981     
6982 }
6983
6984 void
6985 uentry_showWhereAny (uentry spec)
6986 {
6987   if (uentry_isDeclared (spec))
6988     {
6989       if (uentry_hasName (spec))
6990         {
6991           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6992                           uentry_whereDeclared (spec));
6993         }
6994       else
6995         {
6996           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6997         }
6998     }
6999   else if (uentry_isSpecified (spec))
7000     {
7001       if (uentry_hasName (spec))
7002         {
7003           llgenindentmsg (message ("Specification of %q",
7004                                    uentry_getName (spec)),
7005                           uentry_whereSpecified (spec));
7006         }
7007       else
7008         {
7009           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7010                           uentry_whereSpecified (spec));
7011         }
7012     }
7013   else if (fileloc_isDefined (uentry_whereDefined (spec))) 
7014     {
7015       if (uentry_hasName (spec))
7016         {
7017           llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7018                           uentry_whereDefined (spec));
7019         }
7020       else
7021         {
7022           llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7023         }
7024     }
7025   else
7026     {
7027       /* nothing to show */
7028     }
7029 }
7030
7031 void
7032 uentry_showWhereDefined (uentry spec)
7033 {
7034   if (uentry_isCodeDefined (spec))
7035     {
7036       llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7037                       uentry_whereDefined (spec));
7038     }
7039 }
7040
7041 void
7042 uentry_showWhereLastPlain (uentry spec)
7043 {
7044   if (uentry_isDeclared (spec))
7045     {
7046       llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7047                       uentry_whereDeclared (spec));
7048     }
7049   else if (uentry_isSpecified (spec))
7050     {
7051       llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7052                       uentry_whereSpecified (spec));
7053     }
7054   else
7055     {
7056           }
7057 }
7058
7059 static void
7060 uentry_showWhereLastVal (uentry spec, cstring val)
7061 {
7062   if (uentry_isDeclared (spec))
7063     {
7064       llgenindentmsg (message ("Previous declaration of %q: %s", 
7065                                uentry_getName (spec), val),
7066                       uentry_whereDeclared (spec));
7067     }
7068   else if (uentry_isSpecified (spec))
7069     {
7070       llgenindentmsg (message ("Specification of %q: %s", 
7071                                uentry_getName (spec), val),
7072                       uentry_whereSpecified (spec));
7073     }
7074   else
7075     {
7076     }
7077 }
7078
7079 void
7080 uentry_showWhereSpecified (uentry spec)
7081 {
7082   if (uentry_isSpecified (spec))
7083     {
7084       if (uentry_hasName (spec))
7085         {
7086           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7087                           uentry_whereSpecified (spec));
7088         }
7089       else
7090         {
7091           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7092                           uentry_whereSpecified (spec));
7093         }
7094     }
7095   else if (uentry_isDeclared (spec))
7096     {
7097       llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7098                       uentry_whereDeclared (spec));
7099     }
7100   else
7101     {
7102       /* nothing to show */
7103     }
7104 }
7105
7106 void
7107 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7108 {
7109   if (uentry_isSpecified (spec))
7110     {
7111       if (uentry_hasName (spec))
7112         {
7113           llgenindentmsg (message ("Specification of %q: %q", 
7114                                    uentry_getName (spec), s),
7115                           uentry_whereSpecified (spec));
7116         }
7117       else
7118         {
7119           llgenindentmsg (message ("Specification: %q", s), 
7120                           uentry_whereSpecified (spec));
7121         }
7122     }
7123   else if (uentry_isDeclared (spec))
7124     {
7125       llgenindentmsg (message ("Declaration of %q: %q", 
7126                                uentry_getName (spec), s),
7127                       uentry_whereDeclared (spec));
7128     }
7129   else
7130     {
7131       llgenindentmsg (message ("Previous: %q", s),
7132                       uentry_whereLast (spec));
7133     }
7134 }
7135
7136 /*
7137 **
7138 */
7139
7140 static void
7141 checkStructConformance (uentry old, uentry unew)
7142 {
7143   ctype oldr, newr; 
7144   uentryList fold, fnew;
7145
7146   /*
7147   ** requires: types of old and new are structs or unions
7148   */
7149
7150   llassert (uentry_isValid (old));
7151   llassert (uentry_isValid (unew));
7152
7153   oldr = ctype_realType (old->utype);
7154   fold =  ctype_getFields (oldr);
7155
7156   newr = ctype_realType (unew->utype);
7157   fnew = ctype_getFields (newr);
7158
7159   if (!uentryList_matchFields (fold, fnew))
7160     {
7161       if (fileloc_equal (uentry_whereLast (old),
7162                          uentry_whereLast (unew)))
7163         {
7164           ; /* cheat! */
7165         }
7166       else 
7167         {
7168           if (optgenerror 
7169               (FLG_MATCHFIELDS,
7170                message ("%q %q %rdeclared with fields { %q }, %s "
7171                         "with fields { %q }",
7172                         cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7173                         uentry_getName (old), 
7174                         uentry_isDeclared (old),
7175                         uentryList_unparseAbbrev (fnew),
7176                         uentry_specOrDefName (old),
7177                         uentryList_unparseAbbrev (fold)),
7178                uentry_whereDeclared (unew)))
7179             {
7180               uentry_showWhereLastPlain (old);
7181               uentryList_showFieldDifference (fold, fnew);
7182             }
7183         }
7184
7185       old->utype = unew->utype;
7186     }
7187 }
7188
7189 static void
7190 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7191 {
7192   /*
7193   ** requires old and new are enums
7194   */
7195   
7196   ctype        rold = ctype_realType (old->utype);
7197   ctype        rnew = ctype_realType (unew->utype);
7198   enumNameList eold = ctype_elist (rold);
7199   enumNameList enew = ctype_elist (rnew);
7200   
7201   if (!enumNameList_match (eold, enew))
7202     {
7203       if (optgenerror 
7204           (FLG_MATCHFIELDS,
7205            message ("Enum %q declared with members { %q } but "
7206                     "specified with members { %q }",
7207                     uentry_getName (old), 
7208                     enumNameList_unparse (enew),
7209                     enumNameList_unparse (eold)),
7210            uentry_whereDeclared (unew)))
7211         {
7212           uentry_showWhereSpecified (old);
7213           old->utype = unew->utype;
7214         }
7215     }
7216 }
7217
7218 /*
7219 ** either oldCurrent or newCurrent may be undefined!
7220 */
7221
7222 static void
7223 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7224                 uentry unew, uentry newCurrent, ctype newType,
7225                 int paramno)
7226 {
7227   bool hasError = FALSE;
7228
7229   if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7230     {
7231       if (uentry_hasName (newCurrent))
7232         {
7233           hasError = optgenerror 
7234             (FLG_TYPE,
7235              message ("Parameter %d, %q, of function %q has inconsistent type: "
7236                       "declared %t, %s %t",
7237                       paramno + 1, uentry_getName (newCurrent), 
7238                       uentry_getName (unew),
7239                       newType, uentry_specOrDefName (old), oldType),
7240              uentry_whereDeclared (newCurrent));
7241         }
7242       else
7243         {
7244           hasError = optgenerror
7245             (FLG_TYPE,
7246              message ("Parameter %d of function %q has inconsistent type: "
7247                       "declared %t, %s %t",
7248                       paramno + 1, uentry_getName (unew),
7249                       newType, uentry_specOrDefName (old), oldType),
7250              uentry_whereDeclared (newCurrent));
7251
7252           DPRINTF (("type: %s / %s",
7253                     ctype_unparse (newType),
7254                     ctype_unparse (ctype_realType (newType))));
7255         }
7256     }
7257   else 
7258     {
7259       if (uentry_isDeclared (unew))
7260         {
7261           hasError = optgenerror 
7262             (FLG_TYPE,
7263              message ("Parameter %d of function %s has inconsistent type: "
7264                       "declared %t, %s %t",
7265                       paramno + 1, unew->uname, 
7266                       newType, uentry_specOrDefName (old), oldType),
7267              uentry_whereDeclared (unew));
7268         }
7269       else
7270         {
7271           hasError = optgenerror
7272             (FLG_TYPE,
7273              message ("Parameter %d of function %s has inconsistent type: "
7274                       "declared %t, %s %t",
7275                       paramno + 1, unew->uname, 
7276                       newType, uentry_specOrDefName (old), oldType),
7277              uentry_whereDeclared (unew));
7278         }
7279     }
7280   
7281   if (hasError)
7282     {
7283       DPRINTF (("Here: %s / %s",
7284                 uentry_unparseFull (oldCurrent),
7285                 uentry_unparseFull (newCurrent)));
7286
7287       if (!uentry_isUndefined (oldCurrent))
7288         {
7289           if (!uentry_isUndefined (newCurrent) 
7290               && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7291             {
7292               uentry_showWhereLast (oldCurrent);
7293             }
7294           else
7295             {
7296               uentry_showWhereLastPlain (old);
7297             }
7298           
7299           uentry_setType (oldCurrent, newType);
7300         }
7301       else
7302         {
7303           uentry_showWhereLastPlain (old);
7304         }
7305     }
7306 }
7307
7308 static void
7309 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7310 {
7311   if (optgenerror 
7312       (FLG_TYPE,
7313        message ("Function %s %rdeclared with %d arg%&, %s with %d",
7314                 unew->uname, 
7315                 uentry_isDeclared (old),
7316                 uentryList_size (uentry_getParams (unew)),
7317                 uentry_specOrDefName (old),
7318                 uentryList_size (uentry_getParams (old))),
7319        uentry_whereDeclared (unew)))
7320     {
7321       uentry_showWhereLastPlain (old);
7322     }
7323 }
7324
7325 static void
7326 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7327 {
7328   if (optgenerror
7329       (FLG_INCONDEFS,
7330        message ("Function %s inconsistently %rdeclared to return %t",
7331                 unew->uname,
7332                 uentry_isDeclared (old),
7333                 ctype_getReturnType (unew->utype)),
7334        uentry_whereDeclared (unew)))
7335     {
7336       uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7337     }
7338 }
7339
7340 static cstring paramStorageName (uentry ue)
7341 {
7342   return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7343 }
7344
7345 static cstring fcnErrName (uentry ue)
7346 {
7347   return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7348 }
7349
7350 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7351 {
7352   if (uentry_isVar (ue))
7353     {
7354       return (checkedName (ue->info->var->checked));
7355     }
7356   else
7357     {
7358       return (cstring_makeLiteralTemp ("<checked invalid>"));
7359     }
7360 }
7361
7362 static cstring checkedName (chkind checked)
7363 {
7364   switch (checked)
7365     {
7366     case CH_UNKNOWN:       return (cstring_makeLiteralTemp ("unknown"));
7367     case CH_UNCHECKED:     return (cstring_makeLiteralTemp ("unchecked"));
7368     case CH_CHECKED:       return (cstring_makeLiteralTemp ("checked"));
7369     case CH_CHECKMOD:      return (cstring_makeLiteralTemp ("checkmod"));
7370     case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7371     }
7372   BADEXIT;
7373 }
7374
7375 static
7376 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7377 {
7378   nstate oldState;
7379   nstate newState;
7380   
7381   if (uentry_isVar (unew))
7382     {
7383       llassert (uentry_isVar (old));
7384       
7385       oldState = old->info->var->nullstate;
7386       newState = unew->info->var->nullstate;
7387     }
7388   else
7389     {
7390       oldState = sRef_getNullState (old->sref);
7391       newState = sRef_getNullState (unew->sref);
7392     }
7393
7394   if (oldState == NS_ABSNULL)
7395     {
7396       if (uentry_isVar (old))
7397         {
7398           old->info->var->nullstate = newState;
7399         }
7400       
7401       sRef_mergeNullState (old->sref, newState);
7402     }
7403   else if (newState == NS_UNKNOWN)
7404     {
7405       if (completeConform && newState != oldState
7406           && uentry_isReallySpecified (old))
7407         {
7408           if (optgenerror 
7409               (FLG_NEEDSPEC,
7410                message ("%s %q specified as %s, but declared without %s qualifier",
7411                         ekind_capName (unew->ukind),
7412                         uentry_getName (unew),
7413                         nstate_unparse (oldState),
7414                         nstate_unparse (oldState)),
7415                uentry_whereDeclared (unew)))
7416             {
7417               uentry_showWhereSpecified (old);
7418             }
7419         }
7420       
7421       if (uentry_isVar (unew))
7422         {
7423           unew->info->var->nullstate = oldState;
7424         }
7425
7426       sRef_mergeNullState (unew->sref, oldState);
7427     }
7428   else if (newState == NS_POSNULL)
7429     {
7430       if (oldState == NS_MNOTNULL 
7431           && (ctype_isUA (unew->utype) 
7432               || (uentry_isFunction (unew)
7433                   && ctype_isUA (ctype_getReturnType (unew->utype)))))
7434         {
7435           if (uentry_isVar (unew))
7436             {
7437               unew->info->var->nullstate = oldState;
7438             }
7439
7440           sRef_mergeNullState (unew->sref, oldState);
7441         }
7442       else 
7443         {
7444           if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL 
7445               || oldState == NS_UNKNOWN)
7446             {
7447               if (mustConform)
7448                 {
7449                   if (optgenerror 
7450                       (FLG_INCONDEFS,
7451                        message 
7452                        ("%s %q inconsistently %rdeclared %s possibly null storage, "
7453                         "%s %q qualifier",
7454                         uentry_ekindName (unew),
7455                         uentry_getName (unew),
7456                         uentry_isDeclared (old),
7457                         fcnErrName (unew),
7458                         uentry_specOrDefName (old),
7459                         cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7460                        uentry_whereDeclared (unew)))
7461                     {
7462                       uentry_showWhereSpecified (old);
7463                     }
7464                 }
7465             }
7466           
7467           if (uentry_isVar (old))
7468             {
7469               old->info->var->nullstate = newState;
7470             }
7471
7472           sRef_mergeNullState (old->sref, newState);
7473         }
7474     }
7475   else if (newState == NS_MNOTNULL)
7476     {
7477       if (oldState != NS_MNOTNULL)
7478         {
7479           if (mustConform)
7480             {
7481               if (optgenerror 
7482                   (FLG_INCONDEFS,
7483                    message ("%s %q inconsistently %rdeclared %s notnull storage, "
7484                             "%s without notnull qualifier",
7485                             uentry_ekindName (unew),
7486                             uentry_getName (unew),
7487                             uentry_isDeclared (old),
7488                             fcnErrName (unew),
7489                             uentry_specOrDefName (old)),
7490                    uentry_whereDeclared (unew)))
7491                 {
7492                   uentry_showWhereSpecified (old);
7493                 }
7494             }
7495           
7496           if (uentry_isVar (old))
7497             {
7498               old->info->var->nullstate = newState;
7499             }
7500
7501           sRef_mergeNullState (old->sref, newState);
7502         }
7503     }
7504   else
7505     {
7506       if (uentry_isVar (unew)) 
7507         {
7508           unew->info->var->nullstate = oldState;
7509         }
7510
7511       sRef_mergeNullState (unew->sref, oldState);
7512     }
7513 }
7514
7515 static
7516 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7517                     bool mustConform, bool completeConform)
7518 {
7519   sstate oldState;
7520   sstate newState;
7521   bool vars = FALSE;
7522
7523   if (uentry_isVar (old) && uentry_isVar (unew))
7524     {
7525       oldState = old->info->var->defstate;
7526       newState = unew->info->var->defstate;
7527       vars = TRUE;
7528     }
7529   else
7530     {
7531       oldState = sRef_getDefState (old->sref);
7532       newState = sRef_getDefState (unew->sref);
7533     }
7534
7535   if (newState != oldState 
7536       && newState != SS_UNKNOWN 
7537       && newState != SS_DEFINED)
7538     {
7539       if (mustConform)
7540         {
7541           if (optgenerror 
7542               (FLG_INCONDEFS,
7543                message ("%s %q inconsistently %rdeclared %s %s %s, "
7544                         "%s %s %s %s",
7545                         uentry_ekindName (unew),
7546                         uentry_getName (unew),
7547                         uentry_isDeclared (old),
7548                         fcnErrName (unew),
7549                         sstate_unparse (newState),
7550                         paramStorageName (unew),
7551                         uentry_specOrDefName (old),
7552                         fcnErrName (unew),
7553                         sstate_unparse (oldState),
7554                         paramStorageName (unew)),
7555                uentry_whereDeclared (unew)))
7556             {
7557               uentry_showWhereSpecified (old);
7558             }
7559         }
7560
7561       if (vars) old->info->var->defstate = newState;
7562       sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7563     }
7564   else
7565     {
7566       if (completeConform
7567           && (newState != oldState) && (oldState != SS_DEFINED)
7568           && uentry_isReallySpecified (old))
7569         {
7570           if (optgenerror 
7571               (FLG_NEEDSPEC,
7572                message ("%s %q specified as %s, but declared without %s qualifier",
7573                         ekind_capName (unew->ukind),
7574                         uentry_getName (unew),
7575                         sstate_unparse (oldState),
7576                         sstate_unparse (oldState)),
7577                uentry_whereDeclared (unew)))
7578             {
7579               uentry_showWhereSpecified (old);
7580             }
7581         }
7582       
7583       if (vars) unew->info->var->defstate = oldState;
7584       sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7585     }
7586 }
7587
7588 static void 
7589   checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7590                    bool mustConform, bool completeConform)
7591 {
7592   alkind newKind;
7593   alkind oldKind;
7594
7595   oldKind = sRef_getAliasKind (old->sref);
7596   newKind = sRef_getAliasKind (unew->sref);
7597
7598   if (alkind_isImplicit (newKind) 
7599       || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7600     {
7601       if (completeConform && !alkind_equal (newKind, oldKind)
7602           && uentry_isReallySpecified (old))
7603         {
7604           if (optgenerror 
7605               (FLG_NEEDSPEC,
7606                message ("%s %q specified as %s, but declared without "
7607                         "explicit alias qualifier",
7608                         ekind_capName (unew->ukind),
7609                         uentry_getName (unew),
7610                         alkind_unparse (oldKind)),
7611                uentry_whereDeclared (unew)))
7612             {
7613               uentry_showWhereSpecified (old);
7614             }
7615         }
7616
7617       /*  
7618       ** This really shouldn't be necessary, but it is!
7619       ** Function params (?) use new here.
7620       */
7621
7622       sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7623       return;
7624     }
7625
7626   if (alkind_isKnown (newKind))
7627     {
7628       if (!alkind_equal (oldKind, newKind))
7629         {
7630           if (alkind_isKnown (oldKind))
7631             {
7632               if (mustConform && 
7633                   optgenerror 
7634                   (FLG_INCONDEFS,
7635                    message ("%s %q inconsistently %rdeclared %s %s storage, "
7636                             "%s as %s storage",
7637                             uentry_ekindName (unew),
7638                             uentry_getName (unew),
7639                             uentry_isDeclared (old),
7640                             fcnErrName (unew),
7641                             alkind_unparse (newKind),
7642                             uentry_specOrDefName (old),
7643                             alkind_unparse (oldKind)),
7644                    uentry_whereDeclared (unew)))
7645                 {
7646                   uentry_showWhereSpecified (old);
7647
7648                   DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7649                   DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7650                   sRef_setAliasKind (old->sref, AK_ERROR, 
7651                                      uentry_whereDeclared (unew));
7652                 }
7653               else
7654                 {
7655                   sRef_setAliasKind (old->sref, newKind, 
7656                                      uentry_whereDeclared (unew));
7657                 }
7658             }
7659           else
7660             {
7661               if (!(alkind_isImplicit (newKind)))
7662                 {
7663                   if (mustConform &&
7664                       !uentry_isFunction (unew) &&
7665                       optgenerror 
7666                       (FLG_INCONDEFS,
7667                        message ("%s %q inconsistently %rdeclared %s %s storage, "
7668                                 "implicitly %s as temp storage",
7669                                 uentry_ekindName (unew),
7670                                 uentry_getName (unew),
7671                                 uentry_isDeclared (old),
7672                                 fcnErrName (unew),
7673                                 alkind_unparse (newKind),
7674                                 uentry_specOrDefName (old)),
7675                        uentry_whereDeclared (unew)))
7676                     {
7677                       uentry_showWhereSpecified (old);
7678                       oldKind = AK_ERROR;
7679                     }
7680                   
7681                   sRef_setAliasKind (old->sref, newKind, 
7682                                      uentry_whereDeclared (unew));
7683                 }
7684               else /* newKind is temp or refcounted */
7685                 {
7686                   ;
7687                 }
7688             }
7689         }
7690     }
7691   else /* newKind unknown */
7692     {
7693       ;
7694     }
7695 }
7696
7697 static void 
7698   checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7699                 bool mustConform, bool completeConform)
7700 {
7701   exkind newKind;
7702   exkind oldKind;
7703   
7704   oldKind = sRef_getExKind (old->sref);
7705   newKind = sRef_getExKind (unew->sref);
7706
7707   if (exkind_isKnown (newKind))
7708     {
7709       if (oldKind != newKind)
7710         {
7711           if (exkind_isKnown (oldKind))
7712             {
7713               if (mustConform && 
7714                   optgenerror 
7715                   (FLG_INCONDEFS,
7716                    message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7717                             uentry_ekindName (unew),
7718                             uentry_getName (unew),
7719                             uentry_isDeclared (old),
7720                             fcnErrName (unew),
7721                             exkind_unparse (newKind),
7722                             uentry_specOrDefName (old),
7723                             exkind_unparse (oldKind)),
7724                    uentry_whereDeclared (unew)))
7725                 {
7726                   uentry_showWhereSpecified (old);
7727                 }
7728
7729               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7730             }
7731           else
7732             {
7733               if (mustConform &&
7734                   optgenerror 
7735                   (FLG_INCONDEFS,
7736                    message ("%s %q inconsistently %rdeclared %s %s, "
7737                             "implicitly %s without exposure qualifier",
7738                             uentry_ekindName (unew),
7739                             uentry_getName (unew),
7740                             uentry_isDeclared (old),
7741                             fcnErrName (unew),
7742                             exkind_unparse (newKind),
7743                             uentry_specOrDefName (old)),
7744                    uentry_whereDeclared (unew)))
7745                 {
7746                   uentry_showWhereSpecified (old);
7747                 }
7748
7749               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7750             }
7751         }
7752     }
7753   else
7754     {
7755       if (completeConform && exkind_isKnown (oldKind)
7756           && uentry_isReallySpecified (old))
7757         {
7758           if (optgenerror 
7759               (FLG_NEEDSPEC,
7760                message ("%s %q specified as %s, but declared without "
7761                         "exposure qualifier",
7762                         ekind_capName (unew->ukind),
7763                         uentry_getName (unew),
7764                         exkind_unparse (oldKind)),
7765                uentry_whereDeclared (unew)))
7766             {
7767               uentry_showWhereSpecified (old);
7768             }
7769         }
7770
7771       /* yes, this is necessary! (if its a param) */
7772       sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7773     }
7774 }
7775
7776 static void 
7777 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7778                 bool mustConform, /*@unused@*/ bool completeConform)
7779 {
7780   valueTable newvals = sRef_getValueTable (unew->sref);
7781
7782   if (valueTable_isDefined (newvals))
7783     {
7784       DPRINTF (("Check meta state: %s -> %s",
7785                 uentry_unparseFull (old),
7786                 uentry_unparseFull (unew)));
7787       
7788       DPRINTF (("Check meta state refs: %s -> %s",
7789                 sRef_unparseFull (old->sref),
7790                 sRef_unparseFull (unew->sref)));
7791       
7792       DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7793       
7794       /*
7795       ** Copy the new values into the old ref
7796       */
7797
7798       valueTable_elements (newvals, key, newval)
7799         {
7800           metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7801           stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7802             
7803           llassert (metaStateInfo_isDefined (msinfo));
7804
7805           if (stateValue_isUndefined (oldval))
7806             {
7807               sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7808             }
7809           else
7810             {
7811               if (stateValue_isError (oldval))
7812                 {
7813                   if (!stateValue_isError (newval))
7814                     {
7815                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7816                     }
7817                   else
7818                     {
7819                       ; /* No change necessary. */
7820                     }
7821                 }
7822               else
7823                 {
7824                   if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7825                     {
7826                       if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7827                         {
7828                           ;
7829                         }
7830                       else
7831                         {
7832                           if (!stateValue_isError (newval) 
7833                               && !stateValue_isImplicit (newval))
7834                             {
7835                               if (uentry_hasName (unew)
7836                                   || !sRef_isParam (uentry_getSref (unew)))
7837                                 {
7838                                   if (mustConform 
7839                                       && optgenerror 
7840                                       (FLG_INCONDEFS,
7841                                        message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7842                                                 uentry_ekindName (unew),
7843                                                 uentry_getName (unew),
7844                                                 uentry_isDeclared (old),
7845                                                 fcnErrName (unew),
7846                                                 stateValue_unparseValue (newval, msinfo),
7847                                                 uentry_specOrDefName (old),
7848                                                 stateValue_unparseValue (oldval, msinfo)),
7849                                        uentry_whereDeclared (unew)))
7850                                     {
7851                                       uentry_showWhereSpecified (old);
7852                                     }
7853                                 }
7854                               else
7855                                 {
7856                                   if (mustConform 
7857                                       && optgenerror 
7858                                       (FLG_INCONDEFS,
7859                                        message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7860                                                 uentry_ekindName (unew),
7861                                                 sRef_getParam (uentry_getSref (unew)),
7862                                                 uentry_isDeclared (old),
7863                                                 fcnErrName (unew),
7864                                                 stateValue_unparseValue (newval, msinfo),
7865                                                 uentry_specOrDefName (old),
7866                                                 stateValue_unparseValue (oldval, msinfo)),
7867                                        uentry_whereDeclared (unew)))
7868                                     {
7869                                       uentry_showWhereSpecified (old);
7870                                     }
7871                                 }
7872                             }
7873                         }
7874                       
7875                       DPRINTF (("Updating!"));
7876                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7877                     }
7878                   else
7879                     {
7880                       DPRINTF (("Values match"));
7881                     }
7882                 }
7883             }
7884         } end_valueTable_elements ;
7885     }
7886 }
7887
7888 static void
7889 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7890                               /*@notnull@*/ uentry unew,
7891                               bool mustConform, bool completeConform)
7892 {
7893   checkDefState (old, unew, mustConform, completeConform);
7894   checkNullState (old, unew, mustConform, completeConform);
7895   checkAliasState (old, unew, mustConform, completeConform);
7896   checkExpState (old, unew, mustConform, completeConform);
7897   checkMetaState (old, unew, mustConform, completeConform);
7898
7899   sRef_storeState (old->sref);
7900   sRef_storeState (unew->sref);
7901 }
7902
7903 static void
7904 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7905 {
7906   if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7907     {
7908       return;
7909     }
7910
7911   llassert (uentry_isVar (old));
7912   llassert (uentry_isVar (unew));
7913
7914   if (cstring_isEmpty (old->uname)) 
7915     {
7916       cstring_free (old->uname);
7917       old->uname = cstring_copy (unew->uname);
7918     }
7919
7920   if (unew->info->var->kind == VKRETPARAM
7921       || unew->info->var->kind == VKSEFRETPARAM)
7922     {
7923       if (old->info->var->kind != VKRETPARAM
7924           && old->info->var->kind != VKSEFRETPARAM)
7925         {
7926           if (optgenerror 
7927               (FLG_INCONDEFS,
7928                message ("Parameter %q inconsistently %rdeclared as "
7929                         "returned parameter",
7930                         uentry_getName (unew),
7931                         uentry_isDeclared (old)),
7932                uentry_whereDeclared (unew)))
7933             {
7934               uentry_showWhereSpecified (old);
7935               old->info->var->kind = unew->info->var->kind;
7936             }
7937         }
7938     }
7939
7940
7941   if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7942     {
7943       if (old->info->var->kind != VKSEFPARAM 
7944           && old->info->var->kind != VKSEFRETPARAM)
7945         {
7946           if (optgenerror 
7947               (FLG_INCONDEFS,
7948                message ("Parameter %qinconsistently %rdeclared as "
7949                         "sef parameter",
7950                         uentry_getOptName (unew),
7951                         uentry_isDeclared (old)),
7952                uentry_whereDeclared (unew)))
7953             {
7954               uentry_showWhereSpecified (old);
7955               old->info->var->kind = unew->info->var->kind;
7956             }
7957         }
7958     }
7959
7960   if (old->info->var->kind == VKSPEC)
7961     {
7962       old->info->var->kind = unew->info->var->kind;
7963     }
7964   else
7965     {
7966       unew->info->var->kind = old->info->var->kind;
7967     }
7968
7969   if (unew->info->var->checked != CH_UNKNOWN
7970       && unew->info->var->checked != old->info->var->checked)
7971     {
7972       if (old->info->var->checked == CH_UNKNOWN
7973           && !fileloc_isUser (uentry_whereLast (old)))
7974         {
7975           ; /* no error */
7976         }
7977       else
7978         {
7979           if (optgenerror 
7980               (FLG_INCONDEFS,
7981                message ("Variable %q inconsistently %rdeclared as "
7982                         "%s parameter (was %s)",
7983                         uentry_getName (unew),
7984                         uentry_isDeclared (old),
7985                         checkedName (unew->info->var->checked),
7986                         checkedName (old->info->var->checked)),
7987                uentry_whereDeclared (unew)))
7988             {
7989               uentry_showWhereSpecified (old);
7990             }
7991         }
7992       
7993       old->info->var->checked = unew->info->var->checked;
7994     }
7995   else
7996     {
7997       if (completeConform 
7998           && (old->info->var->checked != CH_UNKNOWN)
7999           && uentry_isReallySpecified (old))
8000         {
8001           if (optgenerror 
8002               (FLG_NEEDSPEC,
8003                message ("%s %q specified as %s, but declared without %s qualifier",
8004                         ekind_capName (unew->ukind),
8005                         uentry_getName (unew),
8006                         checkedName (old->info->var->checked),
8007                         checkedName (old->info->var->checked)),
8008                uentry_whereDeclared (unew)))
8009             {
8010               uentry_showWhereSpecified (old);
8011             }
8012         }
8013       
8014       unew->info->var->checked = old->info->var->checked;
8015     }
8016
8017   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8018 }
8019
8020 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8021 {
8022   if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8023     {
8024       return;
8025     }
8026
8027   llassert (uentry_isVar (u1));
8028   llassert (uentry_isVar (u2));
8029
8030   if (u1->info->var->kind != u2->info->var->kind) {
8031     if (u1->info->var->kind == VKSEFRETPARAM) {
8032       if (u2->info->var->kind == VKRETPARAM) {
8033         voptgenerror 
8034           (FLG_TYPE,
8035            message ("Function types are inconsistent. Parameter %d is "
8036                     "sef parameter, but non-sef parameter in "
8037                     "assigned function: %s",
8038                     paramno, exprNode_unparse (e)),
8039            exprNode_loc (e));
8040       } else if (u2->info->var->kind == VKSEFPARAM) {
8041         voptgenerror 
8042           (FLG_TYPE,
8043            message ("Function types are inconsistent. Parameter %d is "
8044                     "returns parameter, but non-returns parameter in "
8045                     "assigned function: %s",
8046                     paramno, exprNode_unparse (e)),
8047            exprNode_loc (e));
8048       } else {
8049         voptgenerror 
8050           (FLG_TYPE,
8051            message ("Function types are inconsistent. Parameter %d is "
8052                     "sef returns parameter, but non-sef returns parameter in "
8053                     "assigned function: %s",
8054                     paramno, exprNode_unparse (e)),
8055            exprNode_loc (e));
8056       }
8057     } else if (u1->info->var->kind == VKRETPARAM) {
8058       voptgenerror 
8059         (FLG_TYPE,
8060          message ("Function types are inconsistent. Parameter %d is "
8061                   "returns parameter, but non-returns parameter in "
8062                   "assigned function: %s",
8063                   paramno, exprNode_unparse (e)),
8064          exprNode_loc (e));
8065     } else if (u1->info->var->kind == VKSEFPARAM) {
8066       voptgenerror 
8067         (FLG_TYPE,
8068          message ("Function types are inconsistent. Parameter %d is "
8069                   "sef parameter, but non-sef parameter in "
8070                   "assigned function: %s",
8071                   paramno, exprNode_unparse (e)),
8072          exprNode_loc (e));
8073     } else {
8074       if (u2->info->var->kind == VKSEFRETPARAM) {
8075         voptgenerror 
8076           (FLG_TYPE,
8077            message ("Function types are inconsistent. Parameter %d is "
8078                     "normal parameter, but sef returns parameter in "
8079                     "assigned function: %s",
8080                     paramno, exprNode_unparse (e)),
8081            exprNode_loc (e));
8082       } else if (u2->info->var->kind == VKSEFPARAM) {
8083         voptgenerror 
8084           (FLG_TYPE,
8085            message ("Function types are inconsistent. Parameter %d is "
8086                     "normal parameter, but sef parameter in "
8087                     "assigned function: %s",
8088                     paramno, exprNode_unparse (e)),
8089            exprNode_loc (e));
8090       } else if (u2->info->var->kind == VKRETPARAM) {
8091         voptgenerror 
8092           (FLG_TYPE,
8093            message ("Function types are inconsistent. Parameter %d is "
8094                     "normal parameter, but returns parameter in "
8095                     "assigned function: %s",
8096                     paramno, exprNode_unparse (e)),
8097            exprNode_loc (e));
8098       } else {
8099         BADBRANCH;
8100       }
8101     }
8102   }
8103
8104   if (u1->info->var->defstate != u2->info->var->defstate) 
8105     {
8106       voptgenerror 
8107         (FLG_TYPE,
8108          message ("Function types are inconsistent. Parameter %d is "
8109                   "%s, but %s in assigned function: %s",
8110                   paramno, 
8111                   sstate_unparse (u1->info->var->defstate),
8112                   sstate_unparse (u2->info->var->defstate),
8113                   exprNode_unparse (e)),
8114          exprNode_loc (e));
8115     }
8116
8117   if (u1->info->var->nullstate != u2->info->var->nullstate) 
8118     {
8119       voptgenerror 
8120         (FLG_TYPE,
8121          message ("Function types are inconsistent. Parameter %d is "
8122                   "%s, but %s in assigned function: %s",
8123                   paramno, 
8124                   nstate_unparse (u1->info->var->nullstate),
8125                   nstate_unparse (u2->info->var->nullstate),
8126                   exprNode_unparse (e)),
8127          exprNode_loc (e));
8128     }
8129       
8130   if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8131     {
8132       voptgenerror 
8133         (FLG_TYPE,
8134          message ("Function types are inconsistent. Parameter %d is "
8135                   "%s, but %s in assigned function: %s",
8136                   paramno, 
8137                   alkind_unparse (sRef_getAliasKind (u1->sref)),
8138                   alkind_unparse (sRef_getAliasKind (u2->sref)),
8139                   exprNode_unparse (e)),
8140          exprNode_loc (e));
8141     }
8142
8143   if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8144     {
8145       voptgenerror 
8146         (FLG_TYPE,
8147          message ("Function types are inconsistent. Parameter %d is "
8148                   "%s, but %s in assigned function: %s",
8149                   paramno, 
8150                   exkind_unparse (sRef_getExKind (u1->sref)),
8151                   exkind_unparse (sRef_getExKind (u2->sref)),
8152                   exprNode_unparse (e)),
8153          exprNode_loc (e));
8154     }
8155 }
8156
8157 static void
8158 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8159                           /*@notnull@*/ uentry unew, 
8160                           bool mustConform, /*@unused@*/ bool completeConform)
8161 {
8162   uentryList oldParams  = uentry_getParams (old);
8163   uentryList newParams  = uentry_getParams (unew);
8164   ctype      newType    = unew->utype;
8165   ctype      oldType    = old->utype;
8166   ctype      oldRetType = ctype_unknown;
8167   ctype      newRetType = ctype_unknown;
8168
8169   DPRINTF (("Function conform: %s ==> %s",
8170             uentry_unparseFull (old),
8171             uentry_unparseFull (unew)));
8172
8173   if (uentry_isForward (old))
8174     {
8175       mustConform = FALSE;
8176       uentry_updateInto (old, unew);
8177       return;
8178     }
8179
8180   /*
8181   ** check return values
8182   */
8183   
8184   if (ctype_isKnown (oldType))
8185     {
8186       llassert (ctype_isFunction (oldType));
8187
8188       oldRetType = ctype_getReturnType (oldType);
8189     }
8190
8191   if (ctype_isKnown (newType))
8192     {
8193       llassert (ctype_isFunction (newType));
8194
8195       newRetType = ctype_getReturnType (newType);
8196     }
8197
8198   if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8199       && !ctype_matchDef (newRetType, oldRetType))
8200     {
8201       if (mustConform) returnValueError (old, unew);
8202     }
8203   else 
8204     {
8205       if (ctype_isConj (newRetType))
8206         {
8207           if (ctype_isConj (oldRetType))
8208             {
8209               if (!ctype_sameAltTypes (newRetType, oldRetType))
8210                 {
8211                   if (optgenerror 
8212                       (FLG_INCONDEFS,
8213                        message ("Function %q inconsistently %rdeclared to "
8214                                 "return alternate types %s "
8215                                 "(types match, but alternates are not identical, "
8216                                 "so checking may not be correct)",
8217                                 uentry_getName (unew),
8218                                 uentry_isDeclared (old),
8219                                 ctype_unparse (newRetType)),
8220                        uentry_whereDeclared (unew)))
8221                     {
8222                       uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8223                     }
8224                 }
8225             }
8226           else
8227             {
8228               old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8229             }
8230         }
8231     }
8232
8233   DPRINTF (("Before state: %s",
8234             uentry_unparseFull (old)));
8235   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8236   DPRINTF (("After state: %s",
8237             uentry_unparseFull (old)));
8238
8239   if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8240     {
8241       if (exitkind_isKnown (unew->info->fcn->exitCode))
8242         {
8243           if (optgenerror 
8244               (FLG_INCONDEFS,
8245                message ("Function %q inconsistently %rdeclared using %s",
8246                         uentry_getName (unew),
8247                         uentry_isDeclared (old),
8248                         exitkind_unparse (unew->info->fcn->exitCode)),
8249                uentry_whereDeclared (unew)))
8250             {
8251               uentry_showWhereSpecified (old);
8252             }
8253         }
8254       else
8255         {
8256           unew->info->fcn->exitCode = old->info->fcn->exitCode;
8257         }
8258     }
8259
8260   if (!qual_isUnknown (unew->info->fcn->nullPred))
8261     {
8262       if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8263         {
8264           if (optgenerror
8265               (FLG_INCONDEFS,
8266                message ("Function %q inconsistently %rdeclared using %s",
8267                         uentry_getName (unew),
8268                         uentry_isDeclared (old),
8269                         qual_unparse (unew->info->fcn->nullPred)),
8270                uentry_whereDeclared (unew)))
8271             {
8272               uentry_showWhereSpecified (old);
8273             }
8274         }
8275     }
8276   else
8277     {
8278       unew->info->fcn->nullPred = old->info->fcn->nullPred;
8279     }
8280
8281   if (unew->info->fcn->specialCode != SPC_NONE)
8282     {
8283       if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8284         {
8285           if (optgenerror
8286               (FLG_INCONDEFS,
8287                message ("Function %q inconsistently %rdeclared using %s",
8288                         uentry_getName (unew),
8289                         uentry_isDeclared (old),
8290                         specCode_unparse (unew->info->fcn->specialCode)),
8291                uentry_whereDeclared (unew)))
8292             {
8293               uentry_showWhereSpecified (old);
8294             }
8295         }
8296     }
8297   else
8298     {
8299       unew->info->fcn->specialCode = old->info->fcn->specialCode;
8300     }
8301           
8302   /*
8303   ** check parameters
8304   */
8305   
8306   if (!uentryList_sameObject (oldParams, newParams)
8307       && (!uentryList_isMissingParams (oldParams)))
8308     {
8309       if (!uentryList_isMissingParams (newParams))
8310         {
8311           int paramno = 0;
8312           int nparams = uentryList_size (oldParams);
8313           bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8314
8315           if (nparams != uentryList_size (newParams))
8316             {
8317               nargsError (old, unew);
8318             }
8319           
8320           if (uentryList_size (newParams) < nparams) 
8321             {
8322               nparams = uentryList_size (newParams);
8323             }
8324
8325           while (paramno < nparams)
8326             {
8327               uentry oldCurrent = uentryList_getN (oldParams, paramno);
8328               uentry newCurrent  = uentryList_getN (newParams, paramno);
8329               ctype  oldCurrentType = uentry_getType (oldCurrent);
8330               ctype  newCurrentType = uentry_getType (newCurrent);
8331
8332               llassert (uentry_isValid (oldCurrent)
8333                         && uentry_isValid (newCurrent));
8334               
8335               if (!uentry_isElipsisMarker (oldCurrent)
8336                   && !uentry_isElipsisMarker (newCurrent))
8337                 {
8338                   checkVarConformance (oldCurrent, newCurrent, 
8339                                        mustConform, completeConform);
8340                 }
8341
8342               if (checknames)
8343                 {
8344                   if (uentry_hasName (oldCurrent) 
8345                       && uentry_hasName (newCurrent))
8346                     {
8347                       cstring oldname = uentry_getName (oldCurrent);
8348                       cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8349                       cstring oname;
8350                       cstring nname = uentry_getName (newCurrent);
8351                       cstring nnamefix;
8352
8353                       if (cstring_isDefined (pfx)
8354                           && cstring_equalPrefix (oldname, pfx))
8355                         {
8356                           oname = cstring_suffix (oldname, cstring_length (pfx));
8357                         }
8358                       else
8359                         {
8360                           oname = oldname;
8361                         /*@-branchstate@*/ } /*@=branchstate@*/
8362
8363                       if (cstring_isDefined (pfx)
8364                           && cstring_equalPrefix (nname, pfx))
8365                         {
8366                           nnamefix = cstring_suffix (nname, cstring_length (pfx));
8367                         }
8368                       else
8369                         {
8370                           nnamefix = nname;
8371                         /*@-branchstate@*/ } /*@=branchstate@*/
8372
8373                       if (!cstring_equal (oname, nnamefix))
8374                         {
8375                           if (optgenerror
8376                               (FLG_DECLPARAMMATCH, 
8377                                message ("Definition parameter name %s does not match "
8378                                         "name of corresponding parameter in "
8379                                         "declaration: %s",
8380                                         nnamefix, oname),
8381                                uentry_whereLast (newCurrent)))
8382                             {
8383                               uentry_showWhereLastPlain (oldCurrent);
8384                             }
8385                         }
8386                       
8387                       cstring_free (oldname);
8388                       cstring_free (nname);
8389                     }
8390                 }
8391
8392               if (!ctype_match (oldCurrentType, newCurrentType))
8393                 {
8394                   paramTypeError (old, oldCurrent, oldCurrentType,
8395                                   unew, newCurrent, newCurrentType, paramno);
8396                 }
8397               else
8398                 {
8399                   if (ctype_isMissingParamsMarker (newCurrentType)
8400                       || ctype_isElips (newCurrentType)
8401                       || ctype_isMissingParamsMarker (oldCurrentType)
8402                       || ctype_isElips (oldCurrentType))
8403                     {
8404                       ;
8405                     }
8406                   else
8407                     {
8408                       if (ctype_isConj (newCurrentType))
8409                         {
8410                           if (ctype_isConj (oldCurrentType))
8411                             {
8412                               if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8413                                 {
8414                                   if (optgenerror 
8415                                       (FLG_INCONDEFS,
8416                                        message ("Parameter %q inconsistently %rdeclared with "
8417                                                 "alternate types %s "
8418                                                 "(types match, but alternates are not identical, "
8419                                                 "so checking may not be correct)",
8420                                                 uentry_getName (newCurrent),
8421                                                 uentry_isDeclared (oldCurrent),
8422                                                 ctype_unparse (newCurrentType)),
8423                                        uentry_whereDeclared (unew)))
8424                                     {
8425                                       uentry_showWhereLastVal (oldCurrent,
8426                                                                ctype_unparse (oldCurrentType));
8427                                     }
8428                                 }
8429                             }
8430                           else
8431                             {
8432                               if (optgenerror 
8433                                   (FLG_INCONDEFS,
8434                                    message ("Parameter %q inconsistently %rdeclared with "
8435                                             "alternate types %s",
8436                                             uentry_getName (newCurrent),
8437                                             uentry_isDeclared (oldCurrent),
8438                                             ctype_unparse (newCurrentType)),
8439                                    uentry_whereDeclared (unew)))
8440                                 {
8441                                   uentry_showWhereLastVal (oldCurrent,
8442                                                            ctype_unparse (oldCurrentType));
8443                                   
8444                                 }
8445                             }
8446                         }
8447                       else 
8448                         {
8449                           if (ctype_isConj (oldCurrentType))
8450                             {
8451                               uentry_setType (newCurrent, oldCurrentType);
8452                             }
8453                         }
8454                     }
8455                 }
8456
8457               paramno++;  
8458               /*
8459                ** Forgot this!  detected by lclint:
8460                ** uentry.c:1257,15: Suspected infinite loop
8461                */
8462             }
8463         }
8464     }
8465
8466   if (!uentryList_isMissingParams (newParams))
8467     {
8468       if (ctype_isConj (oldRetType))
8469         {
8470           old->utype = ctype_makeFunction (oldRetType, 
8471                                            uentryList_copy (newParams));
8472         }
8473       else
8474         {
8475           old->utype = unew->utype;
8476         }
8477     }
8478
8479   checkGlobalsConformance (old, unew, mustConform, completeConform);
8480   checkModifiesConformance (old, unew, mustConform, completeConform);
8481
8482   DPRINTF (("Before list: %s",
8483             uentry_unparseFull (old)));
8484
8485   if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8486     {
8487       if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8488         {
8489           /*
8490           if (optgenerror
8491               (FLG_INCONDEFS,
8492                message ("Function %q redeclared using special clauses (can only "
8493                         "be used in first declaration)",
8494                         uentry_getName (unew)),
8495                uentry_whereDeclared (unew)))
8496             {
8497               uentry_showWhereLast (old);
8498             }
8499           */
8500
8501           /*@i23 need checking @*/ 
8502
8503           old->info->fcn->specclauses = unew->info->fcn->specclauses;
8504         }
8505       else
8506         {
8507           /*@i43 should be able to append? @*/
8508
8509           stateClauseList_checkEqual (old, unew);
8510           stateClauseList_free (unew->info->fcn->specclauses);
8511           unew->info->fcn->specclauses = stateClauseList_undefined;
8512           /*@-branchstate@*/ 
8513         }
8514       /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8515     }
8516
8517   if (fileloc_isUndefined (old->whereDeclared))
8518     {
8519       old->whereDeclared = fileloc_copy (unew->whereDeclared);
8520     }
8521   else if (fileloc_isUndefined (unew->whereDeclared))
8522     {
8523       unew->whereDeclared = fileloc_copy (old->whereDeclared);
8524     }
8525   else
8526     {
8527       /* no change */
8528     }
8529 }
8530
8531 void
8532 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8533 {
8534   multiVal uval;
8535
8536   llassert (uentry_isValid (ue));
8537   llassert (uentry_isEitherConstant (ue));
8538
8539   DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8540   uval = uentry_getConstantValue (ue);
8541
8542   if (multiVal_isDefined (uval))
8543     {
8544       if (multiVal_isDefined (m))
8545         {
8546           if (!multiVal_equiv (uval, m))
8547             {
8548               if (optgenerror 
8549                   (FLG_INCONDEFS,
8550                    message ("%s %q defined with inconsistent value: %q",
8551                             ekind_capName (ue->ukind),
8552                             uentry_getName (ue), 
8553                             multiVal_unparse (m)),
8554                    g_currentloc))
8555                 {
8556                   uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8557                 }
8558             }
8559         }
8560       multiVal_free (m);
8561     }
8562   else
8563     {
8564       uentry_setConstantValue (ue, m);
8565     }
8566 }
8567
8568 static
8569 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
8570                            bool mustConform)
8571 {
8572   bool typeError = FALSE;
8573
8574   if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8575     {
8576       if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8577         {
8578           if (mustConform)
8579             {
8580               DPRINTF (("Check struct conformance: %s / %s",
8581                         uentry_unparseFull (old),
8582                         uentry_unparseFull (unew)));
8583               checkStructConformance (old, unew); 
8584             }
8585         }
8586       else
8587         {
8588           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8589             {
8590               llbug (message ("struct tags: bad types: %t / %t", 
8591                               old->utype, unew->utype));
8592             }
8593         }
8594     }
8595   else if (uentry_isEnumTag (old))
8596     {
8597       if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8598         {
8599           if (mustConform) checkEnumConformance (old, unew);
8600         }
8601       else 
8602         {
8603           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8604             {
8605               llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8606                               ctype_unparse (unew->utype)));
8607             }
8608         }
8609     }
8610   else if (!ctype_match (old->utype, unew->utype))
8611     {
8612       DPRINTF (("Type mismatch: %s / %s",
8613                 ctype_unparse (old->utype),
8614                 ctype_unparse (unew->utype)));
8615
8616       if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8617         {
8618           ctype realt = ctype_realType (unew->utype);
8619           
8620           if (ctype_isRealInt (realt) || ctype_isChar (realt))
8621             {
8622               unew->utype = ctype_bool;
8623             }
8624           else
8625             {
8626               if (mustConform)
8627                 {
8628                   typeError = optgenerror
8629                     (FLG_INCONDEFS,
8630                      message ("%q defined as %s", uentry_getName (old), 
8631                               ctype_unparse (realt)),
8632                      uentry_whereDeclared (unew));
8633                 }
8634             }
8635         } 
8636       else 
8637         {
8638           if (mustConform)
8639             {
8640               ctype oldr = ctype_realType (old->utype);
8641               ctype newr = ctype_realType (unew->utype);
8642               
8643               if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8644                 {
8645                   checkStructConformance (old, unew);
8646                 }
8647               else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8648                 {
8649                   checkStructConformance (old, unew);
8650                 }
8651               else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8652                 {
8653                   checkEnumConformance (old, unew);
8654                 }
8655               else if (uentry_isConstant (old) 
8656                        && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8657                 {
8658                   /* okay...for now! (should check the type is reset later... */
8659                 }
8660               else
8661                 {
8662                   DPRINTF (("YABA!"));
8663                   if (optgenerror 
8664                       (FLG_INCONDEFS,
8665                        message ("%s %q %rdeclared with inconsistent type: %t",
8666                                 ekind_capName (unew->ukind),
8667                                 uentry_getName (unew), 
8668                                 uentry_isDeclared (old),
8669                                 unew->utype),
8670                        uentry_whereDeclared (unew)))
8671                     {
8672                       uentry_showWhereLast (old);
8673                       typeError = TRUE;
8674                     }
8675                 }
8676             }
8677         }
8678     }
8679   else
8680     {
8681       /* no error */
8682     }
8683
8684   return typeError;
8685 }
8686
8687 static void
8688 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8689                                  /*@notnull@*/ uentry unew,
8690                                  bool mustConform, bool completeConform)
8691 {
8692   if (ctype_isDefined (unew->info->datatype->type))
8693     {
8694       /*
8695       ** bool is hard coded here, since it is built into LCL.
8696       ** For now, we're stuck with LCL's types.
8697       */
8698
8699       if (ctype_isDirectBool (old->utype) &&
8700           cstring_equalLit (unew->uname, "bool"))
8701         {
8702           /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8703              evs 2000-07-25: removed
8704           */
8705               unew->utype = ctype_bool;
8706         }
8707       
8708       if (ctype_isUnknown (old->info->datatype->type))
8709         {
8710           old->info->datatype->type = unew->info->datatype->type;
8711         }
8712       else
8713         {
8714           DPRINTF (("Old: %s / New: %s",
8715                     uentry_unparseFull (old),
8716                     uentry_unparseFull (unew)));
8717           DPRINTF (("Types: %s / %s",
8718                     ctype_unparse (old->info->datatype->type),
8719                     ctype_unparse (unew->info->datatype->type)));
8720
8721           if (ctype_matchDef (old->info->datatype->type,
8722                               unew->info->datatype->type))
8723             {
8724               ;
8725             }
8726           else
8727             {
8728               if (optgenerror 
8729                   (FLG_INCONDEFS,
8730                    message
8731                    ("Type %q %s with inconsistent type: %t",
8732                     uentry_getName (unew), 
8733                     uentry_reDefDecl (old, unew),
8734                     unew->info->datatype->type),
8735                    uentry_whereDeclared (unew)))
8736                 {
8737                   uentry_showWhereLastExtra 
8738                     (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8739                 }
8740
8741               old->info->datatype->type = unew->info->datatype->type;
8742             }
8743         }
8744     }
8745   
8746   if (unew->info->datatype->abs != MAYBE)
8747     {
8748       if (ynm_isOff (old->info->datatype->abs)
8749           && ynm_isOn (unew->info->datatype->abs))
8750         {
8751           if (!ctype_isDirectBool (old->utype))
8752             {
8753               if (optgenerror 
8754                   (FLG_INCONDEFS,
8755                    message 
8756                    ("Datatype %q inconsistently %rdeclared as abstract type",
8757                     uentry_getName (unew), 
8758                     uentry_isDeclared (old)),
8759                    uentry_whereDeclared (unew)))
8760                 {
8761                   uentry_showWhereLastPlain (old);
8762                 }
8763             }
8764         }
8765       else if (ynm_isOn (old->info->datatype->abs)
8766                && ynm_isOff (unew->info->datatype->abs))
8767         {
8768           if (!ctype_isDirectBool (old->utype))
8769             {
8770               if (optgenerror 
8771                   (FLG_INCONDEFS,
8772                    message 
8773                    ("Datatype %q inconsistently %rdeclared as concrete type",
8774                     uentry_getName (unew), 
8775                     uentry_isDeclared (old)),
8776                    uentry_whereDeclared (unew)))
8777                 {
8778                   uentry_showWhereLastPlain (old);
8779                 }
8780             }
8781         }
8782       else
8783         {
8784           ;
8785         }
8786     }
8787   else 
8788     {
8789       if (ynm_isOn (old->info->datatype->abs))
8790         {
8791           old->sref = unew->sref;
8792           unew->info->datatype->mut = old->info->datatype->mut;
8793           
8794           if (completeConform
8795               && uentry_isReallySpecified (old))
8796             {
8797               if (optgenerror 
8798                   (FLG_NEEDSPEC,
8799                    message 
8800                    ("Datatype %q specified as abstract, "
8801                     "but abstract annotation not used in declaration",
8802                     uentry_getName (unew)), 
8803                    uentry_whereDeclared (unew)))
8804                 {
8805                   uentry_showWhereLastPlain (old);
8806                 }
8807             }
8808         }
8809     }
8810   
8811   unew->info->datatype->abs = old->info->datatype->abs;   
8812   
8813   if (ynm_isMaybe (unew->info->datatype->mut))
8814     {
8815       if (completeConform && ynm_isOff (old->info->datatype->mut)
8816           && uentry_isReallySpecified (old))
8817         {
8818           if (optgenerror 
8819               (FLG_NEEDSPEC,
8820                message 
8821                ("Datatype %q specified as immutable, "
8822                 "but immutable annotation not used in declaration",
8823                 uentry_getName (unew)), 
8824                uentry_whereDeclared (unew)))
8825             {
8826               uentry_showWhereLastPlain (old);
8827             }
8828         }
8829       
8830       unew->info->datatype->mut = old->info->datatype->mut;
8831     }
8832   else if (ynm_isMaybe (old->info->datatype->mut))
8833     {
8834       old->info->datatype->mut = unew->info->datatype->mut;
8835     }
8836   else
8837     {
8838       if (ynm_isOn (old->info->datatype->abs))
8839         {
8840           if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8841             {
8842               if (optgenerror
8843                   (FLG_INCONDEFS,
8844                    message ("Datatype %q inconsistently %rdeclared as immutable",
8845                             uentry_getName (unew), 
8846                             uentry_isDeclared (old)),
8847                    uentry_whereDeclared (unew)))
8848                 {
8849                   uentry_showWhereLastPlain (old);
8850                 }
8851             }
8852           else 
8853             {
8854               if (ynm_isOff (old->info->datatype->mut)
8855                   && ynm_isOn (unew->info->datatype->mut))
8856                 {
8857                   if (optgenerror
8858                       (FLG_INCONDEFS,
8859                        message ("Datatype %q inconsistently %rdeclared as mutable",
8860                                 uentry_getName (unew), 
8861                                 uentry_isDeclared (old)),
8862                        uentry_whereDeclared (unew)))
8863                     {
8864                       uentry_showWhereLastPlain (old);
8865                     }
8866                 }
8867             }
8868         }
8869       old->info->datatype->mut = unew->info->datatype->mut;       
8870     }
8871
8872   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8873 }
8874
8875 static void
8876 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8877                                  /*@notnull@*/ uentry unew,
8878                                  bool mustConform, 
8879                                  /*@unused@*/ bool completeConform)
8880 {
8881   multiVal oldval = uentry_getConstantValue (old);
8882   multiVal newval = uentry_getConstantValue (unew);
8883   
8884   if (multiVal_isDefined (oldval))
8885     {
8886       if (multiVal_isDefined (newval))
8887         {
8888           if (!multiVal_equiv (oldval, newval))
8889             {
8890               if (mustConform
8891                   && optgenerror 
8892                   (FLG_INCONDEFS,
8893                    message ("%s %q %rdeclared with inconsistent value: %q",
8894                             ekind_capName (unew->ukind),
8895                             uentry_getName (unew), 
8896                             uentry_isDeclared (old),
8897                             multiVal_unparse (newval)),
8898                    uentry_whereDeclared (unew)))
8899                 {
8900                   uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8901                 }
8902             }
8903           
8904           uentry_setConstantValue (unew, multiVal_copy (oldval));
8905         }
8906       else
8907         {
8908           ;
8909         }
8910     }
8911   else
8912     {
8913       uentry_setConstantValue (old, multiVal_copy (newval));
8914     }
8915 }
8916
8917 static void 
8918 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old, 
8919                          /*@notnull@*/ uentry unew, bool mustConform,
8920                          bool completeConform)
8921 {
8922   bool typeError = FALSE;
8923   bool fcnConformance = FALSE;
8924
8925   if (!ekind_equal (unew->ukind, old->ukind))
8926     {
8927       /*
8928       ** okay, only if one is a function and the other is
8929       ** a variable of type function.
8930       */
8931
8932       if (unew->ukind == KENUMCONST
8933           && old->ukind == KCONST)
8934         {
8935           old->ukind = KENUMCONST;
8936           goto nokinderror;
8937         }
8938
8939       if (unew->ukind == KFCN 
8940           && old->ukind == KCONST
8941           && ctype_isUnknown (old->utype))
8942         {
8943           /*
8944           ** When a function is defined with an unparam macro
8945           */
8946
8947           uentry_updateInto (old, unew);
8948           return;
8949         }
8950
8951       if (uentry_isExpandedMacro (old) 
8952           && uentry_isEitherConstant (unew))
8953         {
8954           uentry_updateInto (old, unew);
8955           return;
8956         }
8957
8958       if (uentry_isEndIter (unew))
8959         {
8960           if (ctype_isUnknown (old->utype))
8961             {
8962               if (!uentry_isSpecified (old)
8963                   && uentry_isCodeDefined (unew))
8964                 {
8965                   if (!fileloc_withinLines (uentry_whereDefined (old),
8966                                             uentry_whereDeclared (unew), 2))
8967                     { /* bogus!  will give errors if there is too much whitespace */
8968                       voptgenerror
8969                         (FLG_SYNTAX,
8970                          message
8971                          ("Iterator finalized name %q does not match name in "
8972                           "previous iter declaration (should be end_%q).  This iter "
8973                           "is declared at %q", 
8974                           uentry_getName (unew),
8975                           uentry_getName (old),
8976                           fileloc_unparse (uentry_whereDefined (old))),
8977                          uentry_whereDeclared (old));
8978                     }
8979                 }
8980
8981               uentry_updateInto (old, unew);
8982               return;
8983             }
8984           else
8985             {
8986               KindConformanceError (old, unew, mustConform);
8987             }
8988         }
8989
8990       if (uentry_isFunction (unew))
8991         {
8992           if (uentry_isVariable (old))
8993             {
8994               if (!ctype_isUnknown (old->utype))
8995                 {
8996                   if (ctype_isFunction (old->utype))
8997                     {
8998                       uentry_makeVarFunction (old);
8999                       checkFunctionConformance (old, unew, mustConform,
9000                                                 completeConform);
9001                       fcnConformance = TRUE;
9002                     }
9003                   else
9004                     {
9005                       KindConformanceError (old, unew, mustConform);
9006                     }
9007                 }
9008               else
9009                 {
9010                   if (uentry_isExpandedMacro (old))
9011                     {
9012                       if (fileloc_isUndefined (unew->whereDefined))
9013                         {
9014                           unew->whereDefined = fileloc_update (unew->whereDefined, 
9015                                                               old->whereDefined);
9016                         }
9017
9018                       uentry_updateInto (old, unew);
9019                       old->used = unew->used = TRUE;
9020                       return;
9021                     }
9022                   else
9023                     {
9024                       /* undeclared identifier */
9025                       old->utype = unew->utype;
9026                       uentry_makeVarFunction (old);
9027                       checkFunctionConformance (old, unew, FALSE, FALSE);
9028                       fcnConformance = TRUE;
9029                     }
9030                 }
9031             }
9032           else
9033             {
9034               KindConformanceError (old, unew, mustConform);
9035             }
9036         }
9037       else if (uentry_isFunction (old) && uentry_isVariable (unew))
9038         {
9039           if (!ctype_isUnknown (unew->utype))
9040             {
9041               if (ctype_isFunction (unew->utype))
9042                 {
9043                   uentry_makeVarFunction (unew);
9044                   checkFunctionConformance (old, unew, mustConform, completeConform);
9045                   fcnConformance = TRUE;
9046                 }
9047               else
9048                 {
9049                   KindConformanceError (old, unew, mustConform);
9050                 }
9051             }
9052           else
9053             {
9054               KindConformanceError (old, unew, mustConform);
9055             }
9056         }
9057       else
9058         {
9059           KindConformanceError (old, unew, mustConform);
9060         }
9061     }
9062   else
9063     {
9064       /*
9065       ** check parameter lists for functions 
9066       ** (before type errors, to get better messages
9067       */
9068
9069       if (uentry_isFunction (old))
9070         {
9071           checkFunctionConformance (old, unew, mustConform, completeConform);
9072           fcnConformance = TRUE;
9073         }
9074       else 
9075         {
9076           if (!ctype_isUndefined (old->utype))
9077             {
9078               typeError = checkTypeConformance (old, unew, mustConform);
9079             }
9080         }
9081     }
9082
9083  nokinderror:
9084
9085   if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9086     {
9087       uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9088     }
9089
9090   if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9091     {
9092       DPRINTF (("Check datatype: %s / %s",
9093                 uentry_unparseFull (old),
9094                 uentry_unparseFull (unew)));
9095
9096       uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9097     }
9098
9099   if (uentry_isVariable (old) && uentry_isVariable (unew))
9100     {
9101       if (!typeError && 
9102           !ctype_matchDef (old->utype, unew->utype))
9103         {
9104           if (optgenerror 
9105               (FLG_INCONDEFS,
9106                message
9107                ("Variable %q %s with inconsistent type (arrays and pointers are "
9108                 "not identical in variable declarations): %t",
9109                 uentry_getName (unew), 
9110                 uentry_reDefDecl (old, unew),
9111                 unew->utype),
9112                uentry_whereDeclared (unew)))
9113             {
9114               uentry_showWhereLast (old);
9115               
9116               /*
9117               ** Avoid repeated errors.
9118               */
9119
9120               if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9121                 {
9122                   old->whereDefined = fileloc_update (old->whereDefined,
9123                                                       fileloc_undefined);
9124                 }
9125
9126               typeError = TRUE;
9127             }
9128         }
9129
9130       checkVarConformance (old, unew, mustConform, completeConform);
9131     }
9132
9133   if (fcnConformance)
9134     {
9135       /* old->utype = unew->utype; */
9136     }
9137   else
9138     {
9139       if (ctype_isConj (old->utype))
9140         {
9141           if (ctype_isConj (unew->utype))
9142             {
9143               if (!ctype_sameAltTypes (old->utype, unew->utype))
9144                 {
9145                   if (optgenerror 
9146                       (FLG_INCONDEFS,
9147                        message ("%s %q inconsistently %rdeclared with "
9148                                 "alternate types %s "
9149                                 "(types match, but alternates are not identical, "
9150                                 "so checking may not be correct)",
9151                                 ekind_capName (uentry_getKind (old)),
9152                                 uentry_getName (unew),
9153                                 uentry_isDeclared (old),
9154                                 ctype_unparse (unew->utype)),
9155                        uentry_whereDeclared (unew)))
9156                     {
9157                       uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9158                     }
9159                   else
9160                     {
9161                       old->utype = unew->utype;
9162                     }
9163                 }
9164             }
9165         }
9166       else
9167         {
9168           if (ctype_isUnknown (old->utype))
9169             {
9170               old->utype = unew->utype;
9171             }
9172         }
9173     }  
9174
9175   if (unew->ukind == old->ukind) 
9176     {
9177       sfree (unew->info);
9178       unew->info = uinfo_copy (old->info, old->ukind);
9179     }
9180
9181   sRef_storeState (old->sref);
9182   sRef_storeState (unew->sref);
9183 }
9184
9185 static void uentry_mergeConstraints (uentry spec, uentry def)
9186 {
9187   if (uentry_isFunction (def))
9188     {
9189       DPRINTF (("Here: %s / %s",
9190                 uentry_unparseFull (spec),
9191                 uentry_unparseFull (def)));
9192       /* evans 2001-07-21 */
9193       llassert (uentry_isFunction (spec));
9194
9195       if (functionConstraint_isDefined (def->info->fcn->preconditions))
9196         {
9197           if (fileloc_isXHFile (uentry_whereLast (def)))
9198             {
9199               llassert (uentry_isFunction (spec));
9200               spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9201                                                                            def->info->fcn->preconditions);
9202             }
9203           else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9204             {
9205               ;
9206             }
9207           else
9208             {
9209               /* Check if the constraints are identical */
9210
9211               if (optgenerror 
9212                   (FLG_INCONDEFS,
9213                    message
9214                    ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9215                     uentry_getName (spec),
9216                     functionConstraint_unparse (spec->info->fcn->preconditions)),
9217                    uentry_whereLast (def)))
9218                 {
9219                   uentry_showWhereSpecified (spec);
9220                 }
9221
9222               functionConstraint_free (spec->info->fcn->preconditions);
9223               spec->info->fcn->preconditions = def->info->fcn->preconditions;
9224             }
9225           
9226           def->info->fcn->preconditions = functionConstraint_undefined;
9227         }
9228
9229       if (functionConstraint_isDefined (def->info->fcn->postconditions))
9230         {
9231           if (fileloc_isXHFile (uentry_whereLast (def)))
9232             {
9233               llassert (uentry_isFunction (spec));
9234               DPRINTF (("Post: %s /++/ %s",
9235                         functionConstraint_unparse (spec->info->fcn->postconditions),
9236                         functionConstraint_unparse (def->info->fcn->postconditions)));
9237               spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9238                                                                             def->info->fcn->postconditions);
9239               def->info->fcn->postconditions = functionConstraint_undefined;
9240               DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9241             }
9242           else
9243             {
9244               if (optgenerror 
9245                   (FLG_INCONDEFS,
9246                    message
9247                    ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9248                     uentry_getName (spec),
9249                     functionConstraint_unparse (spec->info->fcn->postconditions)),
9250                    uentry_whereLast (def)))
9251                 {
9252                   uentry_showWhereSpecified (spec);
9253                 }
9254               
9255               functionConstraint_free (spec->info->fcn->postconditions);
9256               spec->info->fcn->postconditions = def->info->fcn->postconditions;
9257               def->info->fcn->postconditions = functionConstraint_undefined;
9258             }
9259         }
9260     }
9261 }
9262
9263 /*
9264 ** modifies spec to reflect def, reports any inconsistencies
9265 */
9266
9267 void
9268 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9269 {
9270   llassert (uentry_isValid (spec));
9271   llassert (uentry_isValid (def));
9272   llassert (cstring_equal (spec->uname, def->uname));
9273
9274   if (uentry_isFunction (def))
9275     {
9276       if (uentry_isConstant (spec))
9277         {
9278           llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9279           uentry_makeConstantFunction (spec);
9280         }
9281       else
9282         {
9283           uentry_convertVarFunction (spec);
9284         }
9285
9286       llassert (uentry_isFunction (spec));
9287     }
9288   
9289   DPRINTF (("Merge entries: %s / %s",
9290             uentry_unparseFull (spec),
9291             uentry_unparseFull (def)));
9292
9293   uentry_mergeConstraints (spec, def);
9294
9295   uentry_checkConformance (spec, def, TRUE, 
9296                            context_getFlag (FLG_NEEDSPEC));
9297
9298   DPRINTF (("Merge entries after conform: %s / %s",
9299             uentry_unparseFull (spec),
9300             uentry_unparseFull (def)));
9301
9302   /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9303
9304   /*
9305   ** okay, declarations conform.  Propagate extra information.
9306   */
9307
9308   uentry_setDefined (spec, uentry_whereDefined (def));
9309   uentry_setDeclared (spec, uentry_whereDeclared (def));
9310
9311   if (uentry_isStatic (def))
9312     {
9313       if (optgenerror 
9314           (FLG_INCONDEFS,
9315            message ("%s %q specified, but declared as static",
9316                     ekind_capName (def->ukind),
9317                     uentry_getName (def)),
9318            uentry_whereDeclared (def)))
9319         {
9320           uentry_showWhereSpecified (spec);
9321         }
9322     }
9323   else 
9324     {
9325       spec->storageclass = def->storageclass;
9326     }
9327
9328   sRef_storeState (spec->sref);
9329
9330   spec->used = def->used || spec->used;
9331   spec->hasNameError |= def->hasNameError;
9332
9333   uentry_free (def);
9334
9335   if (!spec->hasNameError)
9336     {
9337       uentry_checkName (spec);
9338     }
9339   else
9340     {
9341       ;
9342     }
9343 }
9344
9345 /*
9346 ** Can't generate function redeclaration errors when the 
9347 ** entries are merged, since we don't yet know if its the
9348 ** definition of the function.
9349 */
9350
9351 void
9352 uentry_clearDecl (void)
9353 {
9354   posRedeclared = uentry_undefined;
9355   fileloc_free (posLoc);
9356   posLoc = fileloc_undefined;
9357 }
9358
9359 void
9360 uentry_checkDecl (void)
9361 {
9362   if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9363     {
9364       llassert (fileloc_isDefined (posLoc));
9365
9366       if (uentry_isCodeDefined (posRedeclared))
9367         {
9368           if (optgenerror (FLG_REDECL,
9369                            message ("%s %q declared after definition", 
9370                                     ekind_capName (posRedeclared->ukind),
9371                                     uentry_getName (posRedeclared)),
9372                            posLoc))
9373             {
9374               llgenindentmsg (message ("Definition of %q", 
9375                                        uentry_getName (posRedeclared)),
9376                               posRedeclared->whereDeclared);
9377             }
9378         }
9379       else
9380         {
9381           if (optgenerror (FLG_REDECL,
9382                            message ("%s %q declared more than once", 
9383                                     ekind_capName (posRedeclared->ukind),
9384                                     uentry_getName (posRedeclared)),
9385                            posLoc))
9386             {
9387               llgenindentmsg (message ("Previous declaration of %q", 
9388                                        uentry_getName (posRedeclared)),
9389                               posRedeclared->whereDeclared);
9390             }
9391         }
9392     }
9393
9394   fileloc_free (posLoc);
9395   posLoc = fileloc_undefined;
9396   posRedeclared = uentry_undefined;
9397 }
9398
9399 /*
9400 ** Redefinition of old as unew.
9401 ** modifies old to reflect unew, reports any inconsistencies
9402 */
9403
9404 void
9405 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9406 {
9407   fileloc olddef = uentry_whereDeclared (old); 
9408   fileloc unewdef = uentry_whereDeclared (unew);
9409   bool mustConform;
9410   bool wasForward;
9411
9412   DPRINTF (("uentry merge: %s / %s",
9413             uentry_unparseFull (old),
9414             uentry_unparseFull (unew)));
9415  
9416   wasForward = 
9417     fileloc_isUndefined (olddef) 
9418     && fileloc_isDefined (uentry_whereDefined (old)) 
9419     && !uentry_isExpandedMacro (old);
9420   
9421   if (!context_getFlag (FLG_INCONDEFSLIB)
9422       && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9423     {
9424       mustConform = FALSE;
9425     }
9426   else
9427     {
9428       mustConform = TRUE;
9429     }
9430   
9431   llassert (uentry_isValid (old));
9432   llassert (uentry_isValid (unew));
9433   llassert (cstring_equal (old->uname, unew->uname));
9434
9435   if (uentry_isFunction (unew) && !uentry_isFunction (old))
9436     {
9437       if (uentry_isConstant (old))
9438         {
9439           llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9440           uentry_makeConstantFunction (old);
9441         }
9442       else
9443         {
9444           uentry_convertVarFunction (old);
9445         }
9446
9447       llassert (uentry_isFunction (old));
9448     }
9449
9450   DPRINTF (("uentry merge: %s / %s",
9451             uentry_unparseFull (old),
9452             uentry_unparseFull (unew)));
9453
9454   if (uentry_isExtern (unew))
9455     {
9456       uentry_setUsed (old, unewdef);
9457     }
9458
9459   /*
9460   ** should check old one was extern!
9461   */
9462
9463   if (uentry_isStatic (old))
9464     {
9465       if (!(uentry_isStatic (unew)))
9466         {
9467           if (optgenerror 
9468               (FLG_SHADOW,
9469                message ("%s %q shadows static declaration",
9470                         ekind_capName (unew->ukind),
9471                         uentry_getName (unew)),
9472                unewdef))
9473             {
9474               uentry_showWhereLast (old);
9475             }
9476         }
9477       else
9478         {
9479           uentry_setDeclDef (old, unewdef);
9480         }
9481     }
9482   else if (uentry_isStatic (unew))
9483     {
9484       uentry_setDeclDef (old, unewdef);
9485     }
9486   else if (uentry_isExtern (old))
9487     {
9488       uentry_setDeclared (old, unewdef);
9489     }
9490   else
9491     {
9492       if (!uentry_isExtern (unew) 
9493           && !uentry_isForward (old)
9494           && !fileloc_equal (olddef, unewdef)
9495           && !fileloc_isUndefined (olddef)
9496           && !fileloc_isUndefined (unewdef)
9497           && !fileloc_isBuiltin (olddef)
9498           && !fileloc_isBuiltin (unewdef)
9499           && !uentry_isYield (old)
9500           && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9501         {
9502           if (uentry_isVariable (old) || uentry_isVariable (unew))
9503             {
9504               ; /* will report redeclaration error later */
9505             }
9506           else
9507             {
9508               if (fileloc_isDefined (uentry_whereDefined (old)))
9509                 {
9510                   if (optgenerror
9511                       (FLG_REDEF,
9512                        message ("%s %q defined more than once", 
9513                                 ekind_capName (unew->ukind),
9514                                 uentry_getName (unew)),
9515                        uentry_whereLast (unew)))
9516                     {
9517                       llgenindentmsg
9518                         (message ("Previous definition of %q", 
9519                                   uentry_getName (old)),
9520                          uentry_whereLast (old));
9521                     }
9522                   /*
9523                   if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9524                     {
9525                       uentry_updateInto (old, unew);
9526                       old->sref = sRef_saveCopy (old->sref);
9527                     }
9528                     */
9529                 }
9530             }
9531         }
9532       else
9533         {
9534           if (fileloc_isLib (olddef)
9535               || fileloc_isUndefined (olddef)
9536               || fileloc_isImport (olddef))
9537             {
9538               if (uentry_isExtern (unew)) 
9539                 {
9540                   if (uentry_isExtern (old)
9541                       || (fileloc_isDefined (uentry_whereDeclared (old))
9542                           && (!fileloc_equal (uentry_whereDeclared (old),
9543                                               uentry_whereDefined (old)))))
9544                     {
9545                       if (optgenerror
9546                           (FLG_REDECL,
9547                            message ("%s %q declared more than once", 
9548                                     ekind_capName (unew->ukind),
9549                                     uentry_getName (unew)),
9550                            unew->whereDeclared))
9551                         {
9552                           llgenindentmsg
9553                             (message ("Previous declaration of %q", 
9554                                       uentry_getName (old)),
9555                              old->whereDeclared);
9556                         }
9557                     }
9558                   
9559                   uentry_setExtern (old);
9560                 }
9561               else
9562                 {
9563                   uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9564                 }
9565             }
9566         }
9567     }
9568
9569   DPRINTF (("uentry merge: %s / %s",
9570             uentry_unparseFull (old),
9571             uentry_unparseFull (unew)));
9572
9573   uentry_mergeConstraints (old, unew);
9574   DPRINTF (("uentry merge: %s / %s",
9575             uentry_unparseFull (old),
9576             uentry_unparseFull (unew)));
9577
9578   uentry_checkConformance (old, unew, mustConform, FALSE);
9579   DPRINTF (("uentry merge: %s / %s",
9580             uentry_unparseFull (old),
9581             uentry_unparseFull (unew)));
9582
9583   old->used = old->used || unew->used;
9584   old->uses = filelocList_append (old->uses, unew->uses);
9585   unew->uses = filelocList_undefined; 
9586
9587   sRef_storeState (old->sref); 
9588   sRef_storeState (unew->sref);
9589
9590   if (wasForward)
9591     {
9592       old->whereDefined = fileloc_update (old->whereDefined,
9593                                           fileloc_undefined);
9594     }
9595
9596   DPRINTF (("here: %s", uentry_unparseFull (old)));
9597
9598   /*
9599   ** No redeclaration errors for functions here, since we
9600   ** don't know if this is the definition of the function.
9601   */
9602
9603   if (fileloc_isUser (old->whereDeclared)
9604       && fileloc_isUser (unew->whereDeclared)
9605       && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9606       && !fileloc_isDefined (unew->whereDefined))
9607     {
9608       if (uentry_isFunction (old))
9609         {
9610           /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9611           posLoc = fileloc_update (posLoc, unew->whereDeclared);
9612         }
9613       else
9614         {
9615           if (optgenerror (FLG_REDECL,
9616                            message ("%s %q declared more than once", 
9617                                     ekind_capName (unew->ukind),
9618                                     uentry_getName (unew)),
9619                            unew->whereDeclared))
9620             {
9621               llgenindentmsg (message ("Previous declaration of %q", 
9622                                        uentry_getName (old)),
9623                               old->whereDeclared);
9624             }
9625         }
9626     }
9627
9628   if (fileloc_isUndefined (old->whereDefined))
9629     {
9630       old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9631     }
9632   else
9633     {
9634       if (!context_processingMacros ()
9635           && fileloc_isUser (old->whereDefined) 
9636           && fileloc_isUser (unew->whereDefined)
9637           && !fileloc_equal (old->whereDefined, unew->whereDefined))
9638         {
9639           if (uentry_isVariable (unew) || uentry_isFunction (unew))
9640             {
9641               if (uentry_isVariable (unew) 
9642                   && uentry_isExtern (unew))
9643                 {
9644                   if (optgenerror (FLG_REDECL,
9645                                    message ("%s %q declared after definition", 
9646                                             ekind_capName (unew->ukind),
9647                                             uentry_getName (unew)),
9648                                    unew->whereDeclared))
9649                     {
9650                       llgenindentmsg (message ("Definition of %q", 
9651                                                uentry_getName (old)),
9652                                       old->whereDefined);
9653                     }
9654                 }
9655               else
9656                 {
9657                   if (optgenerror (FLG_REDEF,
9658                                    message ("%s %q redefined", 
9659                                             ekind_capName (unew->ukind),
9660                                             uentry_getName (unew)),
9661                                    unew->whereDefined))
9662                     {
9663                       llgenindentmsg (message ("Previous definition of %q", 
9664                                                uentry_getName (old)),
9665                                       old->whereDefined);
9666                     }
9667                 }
9668             }
9669         }
9670     }
9671
9672   if (uentry_isExternal (unew))
9673     {
9674       old->whereDefined = fileloc_createExternal ();
9675     }
9676
9677   if (unew->hasNameError)
9678     {
9679       old->hasNameError = TRUE;
9680     }
9681
9682   uentry_free (unew);
9683
9684   if (!old->hasNameError)
9685     {
9686       uentry_checkName (old);
9687     }
9688
9689   DPRINTF (("After: %s", uentry_unparseFull (old)));
9690   llassert (!ctype_isUndefined (old->utype));
9691 }
9692
9693 void
9694 uentry_copyState (uentry res, uentry other)
9695 {
9696   llassert (uentry_isValid (res));
9697   llassert (uentry_isValid (other));
9698
9699   res->used = other->used;
9700
9701   res->info->var->kind = other->info->var->kind;
9702   res->info->var->defstate = other->info->var->defstate;
9703   res->info->var->nullstate = other->info->var->nullstate;
9704   res->info->var->checked = other->info->var->checked;
9705
9706   sRef_copyState (res->sref, other->sref);
9707 }
9708
9709 bool
9710 uentry_sameKind (uentry u1, uentry u2)
9711 {
9712   if (uentry_isValid (u1) && uentry_isValid (u2))
9713     {
9714       if (uentry_isVar (u1) && uentry_isVar (u2))
9715         {
9716           ctype c1 = u1->utype;
9717           ctype c2 = u2->utype;
9718
9719           if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9720
9721           /*
9722           ** both functions, or both not functions
9723           */
9724
9725           return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9726         }
9727       else
9728         {
9729           return ((u1->ukind == u2->ukind));
9730         }
9731     }
9732   
9733   return FALSE;
9734 }
9735    
9736 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9737 {
9738   ekind okind = unew->ukind;
9739   llassert (uentry_isValid (unew));
9740   llassert (uentry_isValid (old));
9741
9742   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9743
9744   unew->ukind = old->ukind;
9745   llassert (cstring_equal (unew->uname, old->uname));
9746   unew->utype = old->utype;
9747
9748   if (fileloc_isDefined (unew->whereSpecified) 
9749       && !fileloc_isDefined (old->whereSpecified))
9750     {
9751       ; /* Keep the old value */
9752     }
9753   else
9754     {
9755       fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9756       unew->whereSpecified = fileloc_copy (old->whereSpecified);
9757     }
9758
9759   if (fileloc_isDefined (unew->whereDefined) 
9760       && !fileloc_isDefined (old->whereDefined))
9761     {
9762       ; /* Keep the old value */
9763     }
9764   else
9765     {
9766       fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9767       unew->whereDefined = fileloc_copy (old->whereDefined);
9768     }
9769
9770   if (fileloc_isDefined (unew->whereDeclared) 
9771       && !fileloc_isDefined (old->whereDeclared))
9772     {
9773       ; /* Keep the old value */
9774     }
9775   else
9776     {
9777       fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9778       unew->whereDeclared = fileloc_copy (old->whereDeclared);
9779     }
9780
9781   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9782
9783   unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9784   unew->used = old->used;
9785   unew->lset = FALSE;
9786   unew->isPrivate = old->isPrivate;
9787   unew->hasNameError = old->hasNameError;
9788   unew->uses = filelocList_append (unew->uses, old->uses);
9789   old->uses = filelocList_undefined;
9790
9791   unew->storageclass = old->storageclass;
9792   uinfo_free (unew->info, okind);
9793   unew->info = uinfo_copy (old->info, old->ukind);
9794 }
9795
9796
9797 uentry
9798 uentry_copy (uentry e)
9799 {
9800   if (uentry_isValid (e))
9801     {
9802       uentry enew = uentry_alloc ();
9803       DPRINTF (("copy: %s", uentry_unparseFull (e)));
9804       enew->ukind = e->ukind;
9805       enew->uname = cstring_copy (e->uname);
9806       enew->utype = e->utype;
9807       
9808       enew->whereSpecified = fileloc_copy (e->whereSpecified);
9809       enew->whereDefined = fileloc_copy (e->whereDefined);
9810       enew->whereDeclared = fileloc_copy (e->whereDeclared);
9811       
9812       enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9813       enew->used = e->used;
9814       enew->lset = FALSE;
9815       enew->isPrivate = e->isPrivate;
9816       enew->hasNameError = e->hasNameError;
9817       enew->uses = filelocList_undefined;
9818       
9819       enew->storageclass = e->storageclass;
9820       enew->info = uinfo_copy (e->info, e->ukind);
9821       enew->warn = warnClause_copy (e->warn);
9822
9823       DPRINTF (("Here we are..."));
9824       DPRINTF (("original: %s", uentry_unparseFull (e)));
9825       DPRINTF (("copy: %s", uentry_unparse (enew)));
9826       DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9827       return enew;
9828     }
9829   else
9830     {
9831       return uentry_undefined;
9832     }
9833 }
9834
9835 void
9836 uentry_setState (uentry res, uentry other)
9837 {
9838   llassert (uentry_isValid (res));
9839   llassert (uentry_isValid (other));
9840
9841   llassert (res->ukind == other->ukind);
9842   llassert (res->ukind == KVAR);
9843
9844   res->sref = sRef_saveCopy (other->sref);
9845   res->used = other->used;
9846   filelocList_free (res->uses); 
9847   res->uses = other->uses; 
9848   other->uses = filelocList_undefined; 
9849   res->lset = other->lset;
9850 }
9851
9852 void
9853 uentry_mergeUses (uentry res, uentry other)
9854 {
9855   llassert (uentry_isValid (res));
9856   llassert (uentry_isValid (other));
9857
9858   res->used = other->used || res->used;
9859   res->lset = other->lset || res->lset;
9860   res->uses = filelocList_append (res->uses, other->uses);
9861   other->uses = filelocList_undefined;
9862 }
9863
9864
9865 /*
9866 ** This is a really ugly routine.
9867 **
9868 ** gack...fix this one day.
9869 */
9870
9871 /*
9872 ** flip == TRUE
9873 **   >> res is the false branch, other is the true branch (or continuation)
9874 ** flip == FALSE
9875 **   >> res is the true branch, other is the false branch (or continutation)
9876 **
9877 ** opt == TRUE if,
9878 **
9879 ** <other>
9880 ** if <res> ;
9881 **
9882 ** References not effected by res are propagated from other.
9883 */
9884
9885 static void
9886   branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
9887                     bool flip, clause cl, fileloc loc)
9888 {
9889   if (optgenerror 
9890       (FLG_BRANCHSTATE,
9891        message ("%s %q is %s %s, but %s %s.",
9892                 ekind_capName (res->ukind), uentry_getName (res),
9893                 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9894                 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9895        loc))
9896     {
9897       if (sRef_isDead (res->sref))
9898         {
9899           sRef_showStateInfo (res->sref);
9900         }
9901       else if (sRef_isKept (res->sref))
9902         {
9903           sRef_showAliasInfo (res->sref);
9904         }
9905       else /* dependent */
9906         {
9907           sRef_showAliasInfo (res->sref);
9908           sRef_showAliasInfo (other->sref);
9909         }
9910       
9911       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9912     }
9913 }
9914
9915 static bool incompatibleStates (sRef rs, sRef os)
9916 {
9917   alkind rk = sRef_getAliasKind (rs);
9918   alkind ok = sRef_getAliasKind (os);
9919
9920   if (alkind_isError (rk) || alkind_isError (ok))
9921     {
9922       return FALSE;
9923     }
9924   else
9925     {
9926       return ((sRef_isDead (rs)
9927                || (alkind_isKept (rk) && !alkind_isKept (ok))
9928                || (alkind_isDependent (rk) 
9929                    && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9930               && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9931     }
9932 }
9933
9934 static void
9935   branchStateAltError (/*@notnull@*/ uentry res,
9936                        /*@notnull@*/ uentry other, bool flip,
9937                        clause cl, fileloc loc)
9938 {
9939   if (optgenerror 
9940       (FLG_BRANCHSTATE,
9941        message ("%s %q is %s %s, but %s %s.",
9942                 ekind_capName (res->ukind), uentry_getName (res),
9943                 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
9944                 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
9945        loc))
9946     {
9947       if (sRef_isDead (other->sref))
9948         {
9949           sRef_showStateInfo (other->sref);
9950         }
9951       else /* kept */
9952         {
9953           sRef_showAliasInfo (other->sref);
9954         }
9955       
9956       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9957       sRef_setDefinedComplete (res->sref, fileloc_undefined);
9958       
9959       sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
9960       sRef_setDefinedComplete (other->sref, fileloc_undefined);
9961     }
9962 }
9963
9964 /*
9965 ** A reference is relevant for certain checks, only if it 
9966 ** is not definitely null on this path (but not declared
9967 ** to always be null.)
9968 */
9969
9970 static bool uentry_relevantReference (sRef sr, bool flip)
9971 {
9972   if (sRef_isKept (sr) || sRef_isDependent (sr))
9973     {
9974       return FALSE;
9975     }
9976   else
9977     {
9978       if (flip)
9979         {
9980           return !sRef_definitelyNullContext (sr);
9981         }
9982       else
9983         {
9984           return !sRef_definitelyNullAltContext (sr);
9985         }
9986     }
9987 }
9988
9989 static void
9990 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
9991                          bool mustReturn, bool flip, bool opt,
9992                          clause cl)    
9993 {
9994   DPRINTF (("Merge alias states: %s / %s",
9995             uentry_unparseFull (res),
9996             uentry_unparseFull (other)));
9997
9998   if (sRef_isValid (res->sref))
9999     {
10000       if (!mustReturn)
10001         {
10002           DPRINTF (("1"));
10003           if (incompatibleStates (res->sref, other->sref))
10004             {
10005               DPRINTF (("2"));
10006
10007               if (sRef_isThroughArrayFetch (res->sref)
10008                   && !context_getFlag (FLG_STRICTBRANCHSTATE))
10009                 {
10010                   if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
10011                     {
10012                       sRef_maybeKill (res->sref, loc);
10013                     }
10014                   else if (sRef_isPossiblyDead (other->sref))
10015                     {
10016                       sRef_maybeKill (res->sref, loc);
10017                     }
10018                   else
10019                     {
10020                       ;
10021                     }
10022                 }
10023               else
10024                 {
10025                   if (uentry_relevantReference (other->sref, flip))
10026                     {
10027                       DPRINTF (("4"));
10028                       if (sRef_isLocalParamVar (res->sref) 
10029                           && (sRef_isLocalState (other->sref) 
10030                               || sRef_isDependent (other->sref)))
10031                         {
10032                           if (sRef_isDependent (res->sref))
10033                             {
10034                               sRef_setDependent (other->sref, loc);
10035                             }
10036                           else
10037                             {
10038                               sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
10039                             }
10040                         }
10041                       else 
10042                         {
10043                           branchStateError (res, other, flip, cl, loc);
10044                         }
10045                     }
10046                 }
10047               
10048               if (sRef_isKept (res->sref))
10049                 {
10050                   sRef_setKept (other->sref, loc);
10051                 }
10052             }
10053           else
10054             {
10055               if (incompatibleStates (other->sref, res->sref))
10056                 {
10057                   if (uentry_relevantReference (res->sref, !flip))
10058                     {
10059                       if (sRef_isLocalParamVar (res->sref) 
10060                           && (sRef_isDependent (res->sref)
10061                               || sRef_isLocalState (res->sref)))
10062                         {
10063                           if (sRef_isDependent (other->sref))
10064                             {
10065                               sRef_setDependent (res->sref, loc);
10066                             }
10067                           else
10068                             {
10069                               sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
10070                             }
10071                         }
10072                       else
10073                         {
10074                           if (sRef_isParam (other->sref))
10075                             {
10076                               /* 
10077                               ** If the local variable associated
10078                               ** with the param has the correct state,
10079                               ** its okay.
10080                               ** (e.g., free (s); s = new(); ...
10081                               */
10082                               
10083                               uentry uvar = usymtab_lookupSafe (other->uname);
10084                               
10085                               if (uentry_isValid (uvar)
10086                                   && ((sRef_isDead (other->sref) 
10087                                        && sRef_isOnly (uvar->sref))
10088                                       || (sRef_isDependent (other->sref)
10089                                           && sRef_isOwned (uvar->sref))))
10090                                 {
10091                                   /* no error */
10092                                 }
10093                               else
10094                                 {
10095                                   branchStateAltError (res, other,
10096                                                        flip, cl, loc);
10097                                 }
10098                             }
10099                           else
10100                             {
10101                               DPRINTF (("Here: %s / %s",
10102                                         uentry_unparseFull (res),
10103                                         uentry_unparseFull (other)));
10104
10105                               branchStateAltError (res, other, 
10106                                                    flip, cl, loc);
10107                             }
10108                         }
10109                     }
10110                 }
10111               
10112               if (sRef_isKept (other->sref))
10113                 {
10114                   sRef_setKept (res->sref, loc);
10115                 }
10116             }
10117           
10118           if (opt)
10119             {
10120               DPRINTF (("Merge opt..."));
10121               sRef_mergeOptState (res->sref, other->sref, cl, loc);
10122               DPRINTF (("Done!"));
10123             }
10124           else
10125             {
10126               sRef_mergeState (res->sref, other->sref, cl, loc);
10127             }
10128         }
10129       else
10130         {
10131           if (sRef_isModified (other->sref))
10132             {
10133               sRef_setModified (res->sref);
10134             }
10135         }
10136     }
10137 }
10138
10139 static void
10140 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10141 {
10142   valueTable rvalues;
10143   valueTable ovalues;
10144
10145   DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10146   
10147   if (mustReturn)
10148     {
10149       return;
10150     }
10151   /* flip? */
10152
10153   rvalues = sRef_getValueTable (res->sref);
10154   ovalues = sRef_getValueTable (other->sref);
10155   
10156   if (valueTable_isUndefined (ovalues))
10157     {
10158       DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10159       ;
10160     }
10161   else if (valueTable_isUndefined (rvalues))
10162     {
10163       /*
10164       ** Copy values from other
10165       */
10166       
10167       /*@i$@#@*/
10168       DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10169       DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10170       ;
10171     }
10172   else
10173     {
10174       valueTable_elements (ovalues, fkey, fval) {
10175         stateValue tval;
10176         metaStateInfo minfo;
10177         stateCombinationTable sctable;
10178         cstring msg;
10179         int nval;
10180
10181         tval = valueTable_lookup (rvalues, fkey);
10182         
10183         DPRINTF (("Merge value: %s / %s X %s", fkey, 
10184                   stateValue_unparse (fval), stateValue_unparse (tval)));
10185
10186         minfo = context_lookupMetaStateInfo (fkey);
10187         llassert (stateValue_isDefined (tval));
10188         
10189         if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval)) 
10190           {
10191             DPRINTF (("Cannot find meta state for: %s", fkey));
10192             BADBRANCH;
10193           }
10194         else
10195           {
10196             llassert (metaStateInfo_isDefined (minfo));
10197
10198             if (stateValue_isError (fval)
10199                 || sRef_definitelyNullContext (res->sref))
10200               {
10201                 sRef_setMetaStateValueComplete (res->sref, 
10202                                                 fkey, stateValue_getValue (fval), 
10203                                                 stateValue_getLoc (fval));
10204                 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10205               }
10206             else if (stateValue_isError (tval)
10207                      || sRef_definitelyNullAltContext (other->sref))
10208               {
10209                 DPRINTF (("Other branch is definitely null!"));
10210               }
10211             else if (sRef_isStateUndefined (res->sref)
10212                      || sRef_isDead (res->sref))
10213               {
10214                 ; /* Combination state doesn't matter if it is undefined or dead */
10215               }
10216             else 
10217               {
10218                 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10219                           metaStateInfo_unparse (minfo),
10220                           stateValue_unparse (fval),
10221                           stateValue_unparse (tval)));
10222                 
10223                 DPRINTF (("state values: %d / %d",
10224                           stateValue_getValue (fval), stateValue_getValue (tval)));
10225                 
10226                 sctable = metaStateInfo_getMergeTable (minfo);
10227
10228                 DPRINTF (("Merge table: %s",
10229                           stateCombinationTable_unparse (sctable)));
10230                 
10231                 msg = cstring_undefined;
10232                 
10233                 nval = stateCombinationTable_lookup (sctable, 
10234                                                      stateValue_getValue (fval), 
10235                                                      stateValue_getValue (tval), 
10236                                                      &msg);
10237
10238                 DPRINTF (("nval: %d / %d / %d", nval,
10239                           stateValue_getValue (fval), stateValue_getValue (tval)));
10240
10241                 if (nval == stateValue_error)
10242                   {
10243                     /*@i32 print extra info for assignments@*/
10244
10245                     if (uentry_isGlobalMarker (res))
10246                       {
10247                         if (optgenerror 
10248                             (FLG_STATEMERGE,
10249                              message
10250                              ("Control branches merge with incompatible global states (%s and %s)%q",
10251                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10252                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10253                               cstring_isDefined (msg) 
10254                               ? message (": %s", msg) : cstring_undefined),
10255                              loc))
10256                           {
10257                             sRef_showMetaStateInfo (res->sref, fkey);
10258                             sRef_showMetaStateInfo (other->sref, fkey);
10259                           }
10260                       }
10261                     else
10262                       {
10263                         if (optgenerror 
10264                             (FLG_STATEMERGE,
10265                              message
10266                              ("Control branches merge with incompatible states for %q (%s and %s)%q",
10267                               uentry_getName (res),
10268                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10269                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10270                               cstring_isDefined (msg) 
10271                               ? message (": %s", msg) : cstring_undefined),
10272                              loc))
10273                           {
10274                             sRef_showMetaStateInfo (res->sref, fkey);
10275                             sRef_showMetaStateInfo (other->sref, fkey);
10276                             DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10277                             DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10278                             DPRINTF (("Null: %s / %s",
10279                                       bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10280                                       bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10281
10282                           }
10283                       }
10284                   }
10285
10286                 if (nval == stateValue_getValue (fval)
10287                     && nval != stateValue_getValue (tval))
10288                   {
10289                     loc = stateValue_getLoc (fval);
10290                   }
10291                 else if (nval == stateValue_getValue (tval)
10292                          && nval != stateValue_getValue (fval))
10293                   {
10294                     loc = stateValue_getLoc (tval);
10295                   }
10296                 else
10297                   {
10298                     ;
10299                   }
10300
10301                 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10302                     && nval == stateValue_getValue (fval)
10303                     && nval == stateValue_getValue (tval))
10304                   {
10305                     ;
10306                   }
10307                 else
10308                   {
10309                     sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10310                   }
10311               }
10312           }
10313       } end_valueTable_elements ;
10314     } 
10315 }
10316
10317
10318 static void
10319 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10320                        bool flip, clause cl)
10321 {
10322   if (cl == DOWHILECLAUSE)
10323     {
10324       res->used = other->used || res->used;
10325       res->lset = other->lset || res->lset;
10326       res->uses = filelocList_append (res->uses, other->uses);
10327       other->uses = filelocList_undefined;
10328     }
10329   else
10330     {
10331       if (sRef_isMacroParamRef (res->sref)
10332           && !uentry_isSefParam (other)
10333           && !uentry_isSefParam (res))
10334         {
10335           bool hasError = FALSE;
10336           
10337           if (bool_equal (res->used, other->used))
10338             {
10339               res->used = other->used;
10340             }
10341           else
10342             {
10343               if (other->used && !flip)
10344                 {
10345                   hasError = 
10346                     optgenerror 
10347                     (FLG_MACROPARAMS,
10348                      message ("Macro parameter %q used in true clause, "
10349                               "but not in false clause",
10350                               uentry_getName (res)),
10351                      uentry_whereDeclared (res));
10352                 }
10353               else
10354                 {       
10355                   hasError = 
10356                     optgenerror 
10357                     (FLG_MACROPARAMS,
10358                      message ("Macro parameter %q used in false clause, "
10359                               "but not in true clause",
10360                               uentry_getName (res)),
10361                      uentry_whereDeclared (res));
10362                 }
10363               res->used = TRUE;
10364               
10365               if (hasError)
10366                 {
10367                   /* make it sef now, prevent more errors */
10368                   res->info->var->kind = VKREFSEFPARAM;
10369                 }
10370             }
10371         }
10372       else
10373         {
10374           res->used = other->used || res->used;
10375           res->lset = other->lset || res->lset;
10376           res->uses = filelocList_append (res->uses, other->uses);
10377           other->uses = filelocList_undefined;
10378         }
10379     }
10380 }
10381
10382 void
10383 uentry_mergeState (uentry res, uentry other, fileloc loc,
10384                    bool mustReturn, bool flip, bool opt,
10385                    clause cl)
10386 {
10387   llassert (uentry_isValid (res));
10388   llassert (uentry_isValid (other));
10389
10390   llassert (res->ukind == other->ukind);
10391   llassert (res->ukind == KVAR);
10392
10393   DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10394             uentry_unparseFull (other)));
10395   
10396   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10397   uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10398   uentry_mergeSetStates (res, other, loc, flip, cl);
10399 }
10400
10401 void uentry_setUsed (uentry e, fileloc loc)
10402 {
10403   static bool firstTime = TRUE;
10404   static bool showUses = FALSE;
10405   static bool exportLocal = FALSE;
10406
10407   DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10408
10409   if (firstTime)
10410     {
10411       /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10412
10413       showUses = context_getFlag (FLG_SHOWUSES); 
10414       exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10415
10416       firstTime = FALSE;
10417     }
10418
10419   if (uentry_isValid (e))
10420     {
10421       int dp;
10422
10423       if (warnClause_isDefined (e->warn))
10424         {
10425           flagSpec flg = warnClause_getFlag (e->warn);
10426           cstring msg;
10427
10428           if (warnClause_hasMessage (e->warn))
10429             {
10430               msg = cstring_copy (warnClause_getMessage (e->warn));
10431             }
10432           else
10433             {
10434               msg = message ("Use of possibly dangerous %s",
10435                              uentry_ekindNameLC (e));
10436             }
10437
10438           vfsgenerror (flg, 
10439                        message ("%q: %q", msg, uentry_getName (e)),
10440                        loc);
10441         }
10442
10443       if (sRef_isMacroParamRef (e->sref))
10444         {
10445           if (uentry_isYield (e) || uentry_isSefParam (e))
10446             {
10447               ;
10448             }
10449           else 
10450             {
10451               if (context_inConditional ())
10452                 {
10453                   if (optgenerror
10454                       (FLG_MACROPARAMS,
10455                        message ("Macro parameter %q used in conditionally "
10456                                 "executed code (may or may not be "
10457                                 "evaluated exactly once)", 
10458                                 uentry_getName (e)),
10459                        loc))
10460                     {
10461                       e->info->var->kind = VKREFSEFPARAM;
10462                     }
10463                 }
10464               else
10465                 {
10466                   if ((e)->used)
10467                     {
10468                       if (optgenerror
10469                           (FLG_MACROPARAMS,
10470                            message ("Macro parameter %q used more than once", 
10471                                     uentry_getName (e)),
10472                            uentry_whereDeclared (e)))
10473                         {
10474                           e->info->var->kind = VKREFSEFPARAM;
10475                         }
10476                     }
10477                 }
10478             }
10479         }
10480       
10481       if ((dp = uentry_directParamNo (e)) >= 0)
10482         {
10483           uentry_setUsed (usymtab_getParam (dp), loc);
10484         }
10485       
10486       e->used = TRUE;
10487
10488       if (!sRef_isLocalVar (e->sref))
10489         {
10490           if (showUses)
10491             {
10492               e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10493             }
10494           else 
10495             {
10496               if (exportLocal)
10497                 {
10498                   if (context_inMacro ())
10499                     {
10500                       e->uses = filelocList_addUndefined (e->uses);
10501                     }
10502                   else 
10503                     {
10504                       e->uses = filelocList_addDifferentFile
10505                         (e->uses, 
10506                          uentry_whereDeclared (e),
10507                          loc);
10508                     }
10509                 }
10510             }
10511         }
10512     }
10513 }
10514
10515 bool uentry_isReturned (uentry u)
10516 {
10517   return (uentry_isValid (u) && uentry_isVar (u) 
10518           && (u->info->var->kind == VKRETPARAM
10519               || u->info->var->kind == VKSEFRETPARAM));
10520 }
10521
10522 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10523 {
10524   llassert (uentry_isRealFunction (u));
10525
10526   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10527     {
10528       stateClauseList clauses = uentry_getStateClauseList (u);
10529       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10530
10531       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10532       sRef_setAllocated (res, g_currentloc);
10533
10534       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10535                 stateClauseList_unparse (clauses)));
10536
10537       /*
10538       ** This should be in exprNode_reflectEnsuresClause
10539       */
10540
10541       stateClauseList_postElements (clauses, cl)
10542         {
10543           if (!stateClause_isGlobal (cl))
10544             {
10545               sRefSet refs = stateClause_getRefs (cl);
10546               sRefMod modf = stateClause_getEffectFunction (cl);
10547               
10548               sRefSet_elements (refs, el)
10549                 {
10550                   sRef base = sRef_getRootBase (el);
10551                   
10552                   if (sRef_isResult (base))
10553                     {
10554                       if (modf != NULL)
10555                         {
10556                           sRef sr = sRef_fixBase (el, res);
10557                           modf (sr, g_currentloc);
10558                         }
10559                     }
10560                   else
10561                     {
10562                       ;
10563                     }
10564                 } end_sRefSet_elements ;
10565             }
10566         } end_stateClauseList_postElements ;
10567         
10568       return res;
10569     }
10570   else
10571     {
10572       uentryList params;
10573       alkind ak;
10574       sRefSet prefs = sRefSet_new ();
10575       sRef res = sRef_undefined;
10576       int paramno = 0;
10577       
10578       params = uentry_getParams (u);
10579       
10580       uentryList_elements (params, current)
10581         {
10582           if (uentry_isReturned (current))
10583             {
10584               if (exprNodeList_size (args) >= paramno)
10585                 {
10586                   exprNode ecur = exprNodeList_nth (args, paramno);
10587                   sRef tref = exprNode_getSref (ecur);
10588                   
10589                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10590
10591                   if (sRef_isValid (tref))
10592                     {
10593                       sRef tcref = sRef_copy (tref);
10594                       
10595                       usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10596
10597                       if (sRef_isDead (tcref))
10598                         {
10599                           sRef_setDefined (tcref, g_currentloc);
10600                           sRef_setOnly (tcref, g_currentloc);
10601                         }
10602                       
10603                       if (sRef_isRefCounted (tcref))
10604                         {
10605                           /* could be a new ref now (but only if its returned) */
10606                           sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10607                         }
10608                       
10609                       sRef_makeSafe (tcref);
10610                       prefs = sRefSet_insert (prefs, tcref);
10611                     }
10612                 }
10613             }
10614           
10615           paramno++;
10616         } end_uentryList_elements ;
10617       
10618       if (sRefSet_size (prefs) > 0)
10619         {
10620           nstate n = sRef_getNullState (u->sref);
10621           
10622           if (sRefSet_size (prefs) == 1)
10623             {
10624               res = sRefSet_choose (prefs);
10625             }
10626           else
10627             {
10628               /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10629               res = sRefSet_mergeIntoOne (prefs);
10630             }
10631           
10632           if (nstate_isKnown (n))
10633             {
10634               sRef_setNullState (res, n, g_currentloc);
10635             }
10636         }
10637       else
10638         {
10639           if (ctype_isFunction (u->utype))
10640             {
10641               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10642               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10643             }
10644           else
10645             {
10646               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10647             }
10648           
10649           if (sRef_isRefCounted (res))
10650             {
10651               sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10652             }
10653         }
10654       
10655
10656       if (sRef_getNullState (res) == NS_ABSNULL)
10657         {
10658           ctype ct = ctype_realType (u->utype);
10659           
10660           if (ctype_isAbstract (ct))
10661             {
10662               sRef_setNotNull (res, g_currentloc);
10663             }
10664           else
10665             {
10666               if (ctype_isUser (ct))
10667                 {
10668                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10669                 }
10670               else
10671                 {
10672                   sRef_setNotNull (res, g_currentloc);
10673                 }
10674             }
10675         }
10676       
10677       if (sRef_isRefCounted (res))
10678         {
10679           sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10680         }
10681       else if (sRef_isKillRef (res))
10682         {
10683           sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10684         }
10685       else
10686         {
10687           ;
10688         }
10689       
10690       ak = sRef_getAliasKind (res);
10691       
10692       if (alkind_isImplicit (ak))
10693         {
10694           sRef_setAliasKind (res, 
10695                              alkind_fixImplicit (ak),
10696                              g_currentloc);
10697         }
10698       
10699       sRefSet_free (prefs);
10700       
10701       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10702       return res;
10703     }
10704 }
10705
10706 static bool uentry_isRefCounted (uentry ue)
10707 {
10708   ctype ct = uentry_getType (ue);
10709
10710   if (ctype_isFunction (ct))
10711     {
10712       return (ctype_isRefCounted (ctype_getReturnType (ct)));
10713     }
10714   else
10715     {
10716       return (ctype_isRefCounted (ct));
10717     }
10718 }
10719
10720 /*
10721 ** old was declared yield in the specification.  
10722 ** new is declared in the iter implementation.
10723 */
10724
10725 void uentry_checkYieldParam (uentry old, uentry unew)
10726 {
10727   cstring name;
10728
10729   llassert (uentry_isVariable (old));
10730   llassert (uentry_isVariable (unew));
10731
10732   unew->info->var->kind = VKYIELDPARAM;
10733   (void) checkTypeConformance (old, unew, TRUE);
10734   checkVarConformance (old, unew, TRUE, FALSE);
10735
10736   /* get rid of param marker */
10737
10738   name = uentry_getName (unew);
10739   cstring_free (unew->uname);
10740   unew->uname = name;
10741   unew->info->var->kind = VKREFYIELDPARAM;
10742
10743   uentry_setUsed (old, fileloc_undefined);
10744   uentry_setUsed (unew, fileloc_undefined);
10745 }
10746
10747 /*@observer@*/ cstring
10748 uentry_ekindName (uentry ue)
10749 {
10750   if (uentry_isValid (ue))
10751     {
10752       switch (ue->ukind)
10753         {
10754         case KINVALID:
10755           return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10756         case KDATATYPE: 
10757           return cstring_makeLiteralTemp ("Datatype");
10758         case KENUMCONST:
10759           return cstring_makeLiteralTemp ("Enum member");
10760         case KCONST:  
10761           return cstring_makeLiteralTemp ("Constant");
10762         case KVAR:      
10763           if (uentry_isParam (ue))
10764             {
10765               return cstring_makeLiteralTemp ("Parameter");
10766             }
10767           else if (uentry_isExpandedMacro (ue))
10768             {
10769               return cstring_makeLiteralTemp ("Expanded macro");
10770             }
10771           else
10772             {
10773               return cstring_makeLiteralTemp ("Variable");
10774             }
10775         case KFCN:   
10776           return cstring_makeLiteralTemp ("Function");
10777         case KITER: 
10778           return cstring_makeLiteralTemp ("Iterator");
10779         case KENDITER:
10780           return cstring_makeLiteralTemp ("Iterator finalizer");
10781         case KSTRUCTTAG:
10782           return cstring_makeLiteralTemp ("Struct tag");
10783         case KUNIONTAG:
10784           return cstring_makeLiteralTemp ("Union tag");
10785         case KENUMTAG: 
10786           return cstring_makeLiteralTemp ("Enum tag");
10787         case KELIPSMARKER: 
10788           return cstring_makeLiteralTemp ("Optional parameters");
10789         }
10790     }
10791   else
10792     {
10793       return cstring_makeLiteralTemp ("<Undefined>");
10794     }
10795
10796   BADEXIT;
10797 }
10798
10799 /*@observer@*/ cstring
10800 uentry_ekindNameLC (uentry ue)
10801 {
10802   if (uentry_isValid (ue))
10803     {
10804       switch (ue->ukind)
10805         {
10806         case KINVALID:
10807           return cstring_makeLiteralTemp ("<error: invalid uentry>");
10808         case KDATATYPE: 
10809           return cstring_makeLiteralTemp ("datatype");
10810         case KENUMCONST:
10811           return cstring_makeLiteralTemp ("enum member");
10812         case KCONST:  
10813           return cstring_makeLiteralTemp ("constant");
10814         case KVAR:      
10815           if (uentry_isParam (ue))
10816             {
10817               return cstring_makeLiteralTemp ("parameter");
10818             }
10819           else if (uentry_isExpandedMacro (ue))
10820             {
10821               return cstring_makeLiteralTemp ("expanded macro");
10822             }
10823           else
10824             {
10825               return cstring_makeLiteralTemp ("variable");
10826             }
10827         case KFCN:   
10828           return cstring_makeLiteralTemp ("function");
10829         case KITER: 
10830           return cstring_makeLiteralTemp ("iterator");
10831         case KENDITER:
10832           return cstring_makeLiteralTemp ("iterator finalizer");
10833         case KSTRUCTTAG:
10834           return cstring_makeLiteralTemp ("struct tag");
10835         case KUNIONTAG:
10836           return cstring_makeLiteralTemp ("union tag");
10837         case KENUMTAG: 
10838           return cstring_makeLiteralTemp ("enum tag");
10839         case KELIPSMARKER: 
10840           return cstring_makeLiteralTemp ("optional parameters");
10841         }
10842     }
10843   else
10844     {
10845       return cstring_makeLiteralTemp ("<Undefined>");
10846     }
10847
10848   BADEXIT;
10849 }
10850
10851 void uentry_setHasNameError (uentry ue)
10852 {
10853   llassert (uentry_isValid (ue));
10854
10855   ue->hasNameError = TRUE;
10856 }
10857
10858 void uentry_checkName (uentry ue)
10859 {
10860   DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10861             uentry_observeRealName (ue),
10862             bool_unparse (uentry_isVisibleExternally (ue))));
10863   
10864   if (uentry_isValid (ue) 
10865       && !context_inXHFile ()
10866       && uentry_hasName (ue)
10867       && !uentry_isElipsisMarker (ue)
10868       && context_getFlag (FLG_NAMECHECKS)
10869       && !ue->hasNameError 
10870       && !uentry_isEndIter (ue)
10871       && !fileloc_isBuiltin (uentry_whereLast (ue))
10872       && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10873     {      
10874       DPRINTF (("Here..."));
10875
10876       if (uentry_isPriv (ue))
10877         {
10878           ; /* any checks here? */
10879         }
10880       else if (fileloc_isExternal (uentry_whereDefined (ue)))
10881         {
10882           ; /* no errors for externals */
10883         }
10884       else
10885         {
10886           int scope;
10887           
10888           if (uentry_isExpandedMacro (ue))
10889             {
10890               scope = globScope;
10891             }
10892           else
10893             {
10894               if (uentry_isExpandedMacro (ue))
10895                 {
10896                   scope = fileScope;
10897                 }
10898               else if (uentry_isVariable (ue))
10899                 {
10900                   sRef sr = uentry_getSref (ue);
10901
10902                   if (sRef_isValid (sr))
10903                     {
10904                       scope = sRef_getScope (sr);
10905                     }
10906                   else
10907                     {
10908                       scope = fileScope; 
10909                     }
10910                 }
10911               else if (uentry_isFunction (ue)
10912                        || uentry_isIter (ue)
10913                        || uentry_isEndIter (ue)
10914                        || uentry_isConstant (ue))
10915                 {
10916                   scope = uentry_isStatic (ue) ? fileScope : globScope;
10917                 }
10918               else /* datatypes, etc. must be global */
10919                 {
10920                   scope = globScope;
10921                 }
10922               
10923               usymtab_checkDistinctName (ue, scope);
10924             }
10925         
10926           if (context_getFlag (FLG_CPPNAMES)) 
10927             {
10928               checkCppName (ue);
10929             }
10930
10931           if (scope == globScope)
10932             {
10933               checkExternalName (ue);
10934             }
10935           else if (scope == fileScope)
10936             {
10937               checkFileScopeName (ue);
10938             }
10939           else 
10940             {
10941               checkLocalName (ue);
10942             }
10943
10944           checkPrefix (ue);
10945           checkAnsiName (ue);
10946         }
10947     }
10948 }
10949
10950 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
10951 {
10952   uentry ue;
10953   fileloc tloc;
10954
10955   /*
10956   ** Can't but unrecognized ids in macros in global scope, because srefs will break! 
10957   */
10958
10959   if (!context_inMacro ())
10960     {
10961       sRef_setGlobalScopeSafe ();
10962     }
10963
10964   ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
10965   uentry_setUsed (ue, loc);               
10966   
10967   tloc = fileloc_createExternal ();
10968   uentry_setDefined (ue, tloc);
10969   fileloc_free (tloc);
10970   uentry_setHasNameError (ue);
10971   
10972   if (context_getFlag (FLG_REPEATUNRECOG))
10973     {
10974       uentry_markOwned (ue);
10975     }
10976   else
10977     {
10978       ue = usymtab_supReturnFileEntry (ue);
10979     }
10980   
10981   if (!context_inMacro ())
10982     {
10983       sRef_clearGlobalScopeSafe ();
10984     }
10985
10986   return ue;
10987 }
10988
10989 uentry uentry_makeGlobalMarker ()
10990 {
10991   uentry ue;
10992   fileloc tloc;
10993
10994   llassert (sRef_inGlobalScope ());
10995   
10996   ue = uentry_makeVariableAux
10997     (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined, 
10998      sRef_makeGlobalMarker (),
10999      FALSE, VKNORMAL);
11000
11001   tloc = fileloc_createExternal ();
11002   uentry_setUsed (ue, tloc);              
11003   uentry_setDefined (ue, tloc);
11004   fileloc_free (tloc);
11005   uentry_setHasNameError (ue);  
11006
11007   return ue;
11008 }
11009
11010
11011 bool uentry_isGlobalMarker (uentry ue)
11012 {
11013   return (uentry_isValid (ue)
11014           && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11015 }
11016
11017 /* new start modifications */
11018
11019 /* start modifications */
11020 /*
11021 requires: p_e is defined, is a ptr/array variable 
11022 modifies: p_e
11023 effects: sets the state of the variable
11024 */
11025
11026
11027 void uentry_setPossiblyNullTerminatedState (uentry p_e)  {
11028   /*@access sRef@*/ /*i523 shouldn't do this! */
11029   if( uentry_isValid(p_e) ) {
11030     if( p_e->info != NULL) {
11031       if( p_e->info->var != NULL) {
11032          p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11033          p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11034          return;
11035       }
11036     }
11037   }
11038   /*@noaccess sRef@*/
11039
11040   fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11041 }
11042
11043 /*
11044 requires: p_e is defined, is a ptr/array variable 
11045 modifies: p_e
11046 effects: sets the size of the buffer
11047 */
11048
11049 void uentry_setNullTerminatedState (uentry p_e)  {
11050   if( uentry_isValid(p_e) ) {
11051     if( p_e->info != NULL) {
11052       if( p_e->info->var != NULL) {
11053         p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11054         /*@access sRef@*/ /*@i523 bad!*/
11055         p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11056         /*@noaccess sRef@*/ 
11057         return;
11058       }
11059     }
11060   }
11061
11062   fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11063 }
11064
11065 /*
11066 requires: p_e is defined, is a ptr/array variable 
11067 modifies: p_e
11068 effects: sets the size of the buffer
11069 */
11070
11071 void uentry_setSize (uentry p_e, int size)  {
11072   if( uentry_isValid(p_e) ) {
11073     if( p_e->info != NULL) {
11074       if( p_e->info->var != NULL) {
11075         p_e->info->var->bufinfo->size = size;
11076         /*@access sRef@*/ /*@i523 bad!*/
11077         p_e->sref->bufinfo.size = size;
11078         /*@noaccess sRef@*/
11079         return;
11080       }
11081     }
11082   }
11083
11084   fprintf(stderr, "uentry:Error in setSize\n");
11085 }
11086
11087
11088 /*
11089 requires: p_e is defined, is a ptr/array variable 
11090 modifies: p_e
11091 effects: sets the length of the buffer
11092 */
11093
11094 void uentry_setLen (uentry p_e, int len)  {
11095   if( uentry_isValid(p_e) ) {
11096     if( p_e->info != NULL) {
11097       if( p_e->info->var != NULL) {
11098         p_e->info->var->bufinfo->len = len;
11099         /*@access sRef@*/ /*@i523 bad!*/
11100         p_e->sref->bufinfo.len = len;
11101         /*@noaccess sRef@*/
11102         return;
11103       }
11104     }
11105   }
11106   
11107   fprintf(stderr, "uentry:Error in setLen\n");
11108 }
11109
11110 /*@=type*/
11111
11112 bool uentry_hasMetaStateEnsures (uentry e)
11113 {
11114   if (uentry_isValid (e) && uentry_isFunction (e))
11115     {
11116       return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11117     }
11118   else
11119     {
11120       return FALSE;
11121     }
11122 }
11123
11124 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11125 {
11126   llassert (uentry_isValid (e) && uentry_isFunction (e));
11127   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11128 }
This page took 0.909846 seconds and 5 git commands to generate.