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