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