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