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