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