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