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