]> andersk Git - splint.git/blob - src/uentry.c
Added legacy flag for unix lib.
[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) /*@*/ ; 
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   llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3364
3365   /*
3366   ** expanded macro is marked used (until I write a pre-processor)
3367   */
3368
3369   ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3370
3371   ue->ukind = KFCN;
3372   ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3373   ue->info->fcn->exitCode = XK_UNKNOWN;
3374   ue->info->fcn->nullPred = qual_createUnknown ();
3375   ue->info->fcn->specialCode = SPC_NONE;
3376   ue->info->fcn->access = typeIdSet_undefined;
3377   ue->info->fcn->hasGlobs = FALSE;
3378   ue->info->fcn->globs = globSet_undefined;
3379   ue->info->fcn->hasMods = FALSE;
3380   ue->info->fcn->mods = sRefSet_undefined;
3381   ue->info->fcn->specclauses = NULL;
3382   ue->info->fcn->defparams = uentryList_undefined;
3383
3384   /*drl*/
3385   ue->info->fcn->preconditions = functionConstraint_undefined;
3386   /*end */
3387
3388   /*drl 12/28/2000*/
3389   ue->info->fcn->postconditions = functionConstraint_undefined; 
3390   /*end */
3391   
3392   if (ctype_isFunction (ue->utype))
3393     {
3394       ue->sref = sRef_makeType (ctype_getReturnType (ue->utype)); 
3395     }
3396   else
3397     {
3398       ue->sref = sRef_makeType (ctype_unknown); 
3399     }
3400
3401   if (sRef_isRefCounted (ue->sref))
3402     {
3403       ak = AK_NEWREF;
3404     }
3405   else
3406     {
3407       if (alkind_isUnknown (ak))
3408         {
3409           if (exkind_isKnown (ek))
3410             {
3411               DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3412               ak = AK_IMPDEPENDENT;
3413             }
3414           else 
3415             {
3416               if (context_getFlag (FLG_RETIMPONLY))
3417                 {
3418                   if (ctype_isFunction (ue->utype)
3419                       && ctype_isVisiblySharable 
3420                       (ctype_realType (ctype_getReturnType (ue->utype))))
3421                     {
3422                       if (uentryList_hasReturned (uentry_getParams (ue)))
3423                         {
3424                           ;
3425                         }
3426                       else
3427                         {
3428                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
3429                             {
3430                               ;
3431                             }
3432                           else 
3433                             {
3434                               ak = AK_IMPONLY;
3435                             }
3436                         }
3437                     }
3438                 }
3439             }
3440         }
3441     }
3442
3443   loc = ue->whereDeclared;
3444
3445   sRef_setAliasKind (ue->sref, ak, loc);
3446   sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3447   sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3448   sRef_setExKind (ue->sref, ek, loc);
3449
3450   if (oldInfo->kind == VKEXPMACRO)
3451     {
3452       ;
3453     }
3454   else
3455     {
3456       fileloc_free (ue->whereDefined);
3457       ue->whereDefined = fileloc_undefined;
3458     }
3459
3460   uvinfo_free (oldInfo);
3461 }
3462
3463 void uentry_makeConstantFunction (uentry ue)
3464 {
3465   alkind ak;
3466   exkind ek;
3467   ucinfo oldInfo;
3468   fileloc loc;
3469
3470   llassert (uentry_isValid (ue));
3471   llassert (!sRef_modInFunction ());
3472
3473   ak = sRef_getOrigAliasKind (ue->sref);
3474   ek = sRef_getOrigExKind (ue->sref);
3475
3476   llassert (uentry_isConstant (ue));
3477   oldInfo = ue->info->uconst;
3478
3479   llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3480
3481   /*
3482   ** expanded macro is marked used (until I write a pre-processor)
3483   */
3484
3485   ue->ukind = KFCN;
3486   ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3487   ue->info->fcn->exitCode = XK_UNKNOWN;
3488   ue->info->fcn->nullPred = qual_createUnknown ();
3489   ue->info->fcn->specialCode = SPC_NONE;
3490   ue->info->fcn->access = typeIdSet_undefined;
3491   ue->info->fcn->hasGlobs = FALSE;
3492   ue->info->fcn->globs = globSet_undefined;
3493   ue->info->fcn->hasMods = FALSE;
3494   ue->info->fcn->mods = sRefSet_undefined;
3495   ue->info->fcn->specclauses = NULL;
3496   ue->info->fcn->defparams = uentryList_undefined;
3497
3498   /*drl*/
3499   ue->info->fcn->preconditions = functionConstraint_undefined;
3500   /*end */
3501
3502   /*drl 12/28/2000*/
3503   ue->info->fcn->postconditions = functionConstraint_undefined;
3504   /*end */
3505
3506   
3507   if (ctype_isFunction (ue->utype))
3508     {
3509       ue->sref = sRef_makeType (ctype_getReturnType (ue->utype)); 
3510     }
3511   else
3512     {
3513       ue->sref = sRef_makeType (ctype_unknown); 
3514     }
3515
3516   if (sRef_isRefCounted (ue->sref))
3517     {
3518       ak = AK_NEWREF;
3519     }
3520   else
3521     {
3522       if (alkind_isUnknown (ak))
3523         {
3524           if (exkind_isKnown (ek))
3525             {
3526               DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3527               ak = AK_IMPDEPENDENT;
3528             }
3529           else 
3530             {
3531               if (context_getFlag (FLG_RETIMPONLY))
3532                 {
3533                   if (ctype_isFunction (ue->utype)
3534                       && ctype_isVisiblySharable 
3535                       (ctype_realType (ctype_getReturnType (ue->utype))))
3536                     {
3537                       if (uentryList_hasReturned (uentry_getParams (ue)))
3538                         {
3539                           ;
3540                         }
3541                       else
3542                         {
3543                           if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))) 
3544                             {
3545                               ;
3546                             }
3547                           else 
3548                             {
3549                               ak = AK_IMPONLY;
3550                             }
3551                         }
3552                     }
3553                 }
3554             }
3555         }
3556     }
3557
3558   loc = ue->whereDeclared;
3559
3560   sRef_setAliasKind (ue->sref, ak, loc);
3561   sRef_setExKind (ue->sref, ek, loc);
3562
3563   fileloc_free (ue->whereDefined);
3564   ue->whereDefined = fileloc_undefined;
3565   ucinfo_free (oldInfo);
3566 }
3567
3568 void
3569 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3570 {
3571   llassert (uentry_isValid (ue));
3572
3573   if (uentry_isIter (ue))
3574     {
3575       llassert (globSet_isUndefined (ue->info->iter->globs));
3576       ue->info->iter->globs = globs;
3577     }
3578   else
3579     {
3580       uentry_convertVarFunction (ue);
3581       
3582       llassert (uentry_isFunction (ue));
3583       llassert (!ue->info->fcn->hasGlobs 
3584                 && globSet_isUndefined (ue->info->fcn->globs));
3585       
3586       ue->info->fcn->hasGlobs = TRUE;
3587       globSet_markImmutable (globs);
3588       /*@-mustfree@*/ ue->info->fcn->globs = globs;
3589       /*@=mustfree@*/
3590     }
3591
3592   /*@i23*/
3593   /* ???  - evans 2001-09-09 not sure what's going on here...?
3594   if (globSet_hasStatic (globs))
3595     {
3596       context_recordFileGlobals (globs);
3597     }
3598   */
3599
3600   if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3601     {
3602       ue->info->fcn->hasMods = TRUE;
3603     }
3604 }
3605
3606 void uentry_addAccessType (uentry ue, typeId tid)
3607 {
3608   if (uentry_isFunction (ue))
3609     {
3610       ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3611     }
3612   else if (uentry_isEitherConstant (ue))
3613     {
3614       ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3615     }
3616   else if (uentry_isIter (ue))
3617     {
3618       ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3619     }
3620   else if (uentry_isEndIter (ue))
3621     {
3622       ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3623     }
3624   else
3625     {
3626       llbug (message ("no access for: %q", uentry_unparse (ue)));
3627     }
3628 }
3629
3630 /*@only@*/ /*@notnull@*/ uentry 
3631   uentry_makeFunction (cstring n, ctype t, 
3632                        typeId access, 
3633                        /*@only@*/ globSet globs, /*@only@*/ sRefSet mods, 
3634                        /*@only@*/ warnClause warn,
3635                        fileloc f)
3636 {
3637   llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3638   return (uentry_makeFunctionAux (n, t, 
3639                                   ((typeId_isInvalid (access)) ? typeIdSet_emptySet () 
3640                                    : typeIdSet_single (access)),
3641                                   globs, mods, warn,
3642                                   f,
3643                                   FALSE, FALSE));
3644 }
3645
3646 # ifndef NOLCL
3647 /*@notnull@*/ uentry 
3648   uentry_makePrivFunction2 (cstring n, ctype t, 
3649                             typeIdSet access, 
3650                             globSet globs, sRefSet mods, 
3651                             fileloc f)
3652 {
3653   return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3654                                   f, TRUE, FALSE));
3655 }
3656
3657
3658 /*@notnull@*/ uentry 
3659   uentry_makeSpecFunction (cstring n, ctype t, 
3660                            typeIdSet access,
3661                            /*@only@*/ globSet globs, 
3662                            /*@only@*/ sRefSet mods, 
3663                            fileloc f)
3664 {
3665   uentry ue = uentry_makeFunctionAux (n, t, access, 
3666                                       globs, mods, warnClause_undefined, 
3667                                       f, FALSE, FALSE);
3668
3669   uentry_setHasGlobs (ue);
3670   uentry_setHasMods (ue);
3671
3672   reflectImplicitFunctionQualifiers (ue, TRUE);
3673   return (ue);
3674 }
3675 # endif
3676
3677 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3678 {
3679   uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined, 
3680                                       sRef_undefined, FALSE, VKEXPMACRO);
3681
3682   uentry_setDefined (ue, f);
3683   return ue;
3684 }
3685
3686 /*@notnull@*/ /*@notnull@*/ uentry 
3687   uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3688 {
3689   uentry ue = uentry_makeFunctionAux (n, ctype_unknown, 
3690                                       typeIdSet_singleOpt (access),
3691                                       globSet_undefined, sRefSet_undefined, 
3692                                       warnClause_undefined,
3693                                       fileloc_undefined,
3694                                       FALSE, TRUE);
3695
3696   ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3697   return ue;
3698 }
3699
3700 bool uentry_isForward (uentry e)
3701 {
3702   if (uentry_isValid (e))
3703     {
3704       ctype ct = uentry_getType (e);
3705
3706       return (ctype_isUnknown (ct)
3707               || (ctype_isFunction (ct)
3708                   && ctype_isUnknown (ctype_getReturnType (ct))));
3709     }
3710
3711   return FALSE;
3712 }
3713
3714 # ifndef NOLCL
3715 /*@notnull@*/ uentry 
3716 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3717 {
3718   return (uentry_makeFunctionAux (n, ctype_unknown, access,
3719                                   globSet_undefined, sRefSet_undefined, warnClause_undefined,
3720                                   f,FALSE, TRUE));
3721 }
3722
3723 /*@notnull@*/ uentry 
3724 uentry_makeUnspecFunction (cstring n, ctype t, 
3725                            typeIdSet access, 
3726                            fileloc f)
3727 {
3728   uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3729                                       sRefSet_undefined, warnClause_undefined,
3730                                       f, FALSE, TRUE);
3731
3732   reflectImplicitFunctionQualifiers (ue, TRUE);
3733   return ue;
3734 }
3735 # endif
3736
3737 /*
3738 ** datatypes
3739 */
3740
3741 /* is exported for use by usymtab_interface */
3742
3743 /*@notnull@*/ uentry 
3744   uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract, 
3745                           fileloc f, bool priv)
3746 {
3747   uentry e = uentry_alloc ();
3748
3749   DPRINTF (("Make datatype: %s / %s",
3750             n, ctype_unparse (t)));
3751
3752   /* e->shallowCopy = FALSE; */
3753   e->ukind = KDATATYPE;
3754   e->uname = cstring_copy (n);
3755   e->utype = t;
3756   e->storageclass = SCNONE;
3757   e->sref  = sRef_makeUnknown ();
3758
3759   if (ctype_isUA (t))
3760     {
3761       sRef_setStateFromType (e->sref, t);
3762     }
3763
3764   uentry_setSpecDef (e, f);
3765
3766   e->warn = warnClause_undefined; /*@i634@*/ 
3767   e->uses = filelocList_new ();
3768   e->isPrivate = priv;
3769   e->hasNameError = FALSE;
3770
3771   e->used = FALSE;
3772   e->lset = FALSE;
3773
3774   e->info = (uinfo) dmalloc (sizeof (*e->info));
3775   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3776   e->info->datatype->abs = abstract;
3777   e->info->datatype->mut = mut;
3778   e->info->datatype->type = ctype_undefined;
3779
3780   if (uentry_isDeclared (e))
3781     {
3782       uentry_setDefined (e, f);
3783     }
3784
3785   if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3786     {
3787       sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3788     }
3789
3790   return (e);
3791 }
3792
3793 /*@notnull@*/ uentry
3794   uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3795 {
3796   return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3797 }
3798
3799 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3800 {
3801   uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3802                                        ctype_bool, NO, abstract, 
3803                                        fileloc_getBuiltin (),
3804                                        FALSE);
3805   
3806   ret->info->datatype->type = ctype_bool;
3807   return ret;
3808 }
3809
3810 /*
3811 ** iters
3812 */
3813
3814 static /*@only@*/ /*@notnull@*/ uentry 
3815   uentry_makeIterAux (cstring n, typeIdSet access, ctype ct, 
3816                       /*@only@*/ fileloc f)
3817 {
3818   uentry e = uentry_alloc ();
3819
3820   e->ukind = KITER;
3821   e->uname = cstring_copy (n);
3822   e->utype = ct;
3823   e->sref  = sRef_makeUnknown ();
3824   e->storageclass = SCNONE;
3825   e->used = FALSE;
3826   e->lset = FALSE;
3827
3828   uentry_setSpecDef (e, f);
3829
3830   e->warn = warnClause_undefined; /*@i452@*/
3831   e->uses = filelocList_new ();
3832   e->isPrivate = FALSE;
3833   e->hasNameError = FALSE;
3834
3835   e->info = (uinfo) dmalloc (sizeof (*e->info));
3836   e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3837   e->info->iter->access = access;
3838   e->info->iter->mods = sRefSet_undefined;
3839   e->info->iter->globs = globSet_undefined;
3840
3841   uentry_checkIterArgs (e);
3842   return (e);
3843 }
3844
3845 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3846 {
3847   return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3848 }
3849
3850 static /*@notnull@*/ uentry
3851 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3852 {
3853   uentry e = uentry_alloc ();
3854
3855   /* e->shallowCopy = FALSE; */
3856   e->ukind = KENDITER;
3857   e->storageclass = SCNONE;
3858   e->uname = message ("end_%s", n);
3859   e->utype = ctype_unknown;
3860   e->sref  = sRef_makeUnknown ();
3861
3862   uentry_setSpecDef (e, f);
3863
3864   e->used = FALSE;
3865   e->lset = FALSE;
3866
3867   e->uses = filelocList_new ();
3868   e->isPrivate = FALSE;
3869   e->hasNameError = FALSE;
3870
3871   e->info = (uinfo) dmalloc (sizeof (*e->info));
3872   e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3873
3874   e->info->enditer->access = access;
3875
3876   e->warn = warnClause_undefined; /*@i452@*/
3877   return (e);
3878 }
3879
3880 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3881 {
3882   return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3883 }
3884
3885 /*
3886 ** tags
3887 */
3888
3889 static /*@only@*/ /*@notnull@*/ uentry 
3890   uentry_makeTagAux (cstring n, ctype t, 
3891                      /*@only@*/ fileloc fl, 
3892                      bool priv, ekind kind)
3893 {
3894   uentry e = uentry_alloc ();
3895   
3896   if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3897     {
3898       llbuglit ("uentry_makeTagAux: not a tag type");
3899     }
3900   
3901   e->ukind = kind;
3902   /* e->shallowCopy = FALSE; */
3903   e->uname = cstring_copy (n);
3904
3905   e->utype = t;
3906   e->sref  = sRef_makeUnknown ();
3907   e->storageclass = SCNONE;
3908
3909   uentry_setSpecDef (e, fl);
3910   
3911   e->used = FALSE;
3912   e->lset = FALSE;
3913
3914   e->uses = filelocList_new ();
3915   e->isPrivate = priv;
3916   e->hasNameError = FALSE;
3917
3918   e->info = (uinfo) dmalloc (sizeof (*e->info));
3919   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3920   e->info->datatype->abs = NO;
3921   e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3922   e->info->datatype->type = t;
3923   e->warn = warnClause_undefined; /*@i452@*/
3924
3925   if (uentry_isDeclared (e))
3926     {
3927       uentry_setDefined (e, fl);
3928     }
3929
3930   return (e);  
3931 }
3932
3933 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3934 {
3935   cstring sname = makeStruct (n);
3936   uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3937
3938   cstring_free (sname);
3939   return (ret);
3940 }
3941
3942 /*@only@*/ uentry
3943 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3944 {
3945   cstring sname = makeStruct (n);
3946   uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3947
3948   cstring_free (sname);
3949   return ret;
3950 }
3951
3952 /*@only@*/ uentry
3953 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3954 {
3955   cstring uname = makeUnion (n);
3956   uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3957
3958   cstring_free (uname);
3959   return (ret);
3960 }
3961
3962 # ifndef NOLCL
3963 uentry
3964 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3965 {
3966   cstring ename = makeEnum (n);
3967   uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3968
3969   cstring_free (ename);
3970   return ret;
3971 }
3972 # endif
3973
3974 uentry
3975 uentry_makeUnionTagLoc (cstring n, ctype t)
3976 {
3977   cstring uname = makeUnion (n);
3978   uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3979
3980   cstring_free (uname);
3981   return ret;
3982 }
3983
3984 uentry
3985 uentry_makeEnumTagLoc (cstring n, ctype t)
3986 {
3987   cstring ename = makeEnum (n);
3988   uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3989
3990   cstring_free (ename);
3991   return ret;
3992 }
3993
3994 bool 
3995 uentry_isStructTag (uentry ue) 
3996 {
3997   return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3998 }
3999
4000 bool 
4001 uentry_isUnionTag (uentry ue) 
4002 {
4003   return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4004 }
4005
4006 bool 
4007 uentry_isEnumTag (uentry ue) 
4008 {
4009   return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4010 }
4011
4012 bool
4013 uentry_isAnyTag (uentry ue)
4014 {
4015   return (uentry_isStructTag (ue) 
4016           || uentry_isUnionTag (ue)
4017           || uentry_isEnumTag (ue));
4018 }
4019
4020 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4021
4022 extern void uentry_destroyMod (void)
4023    /*@globals killed emarker@*/ /*@modifies emarker@*/
4024 {
4025   static bool wasDestroyed = FALSE;
4026
4027   llassert (!wasDestroyed);
4028
4029   if (emarker != NULL)
4030     {
4031       uentry_reallyFree (emarker);
4032     }
4033
4034   wasDestroyed = TRUE;
4035 }
4036
4037 uentry
4038 uentry_makeElipsisMarker (void)
4039 {
4040   if (emarker == NULL)
4041     {
4042       emarker = uentry_alloc ();
4043
4044       emarker->ukind = KELIPSMARKER;
4045       emarker->uname = cstring_makeLiteral ("...");
4046       emarker->utype = ctype_elipsMarker;
4047       emarker->sref  = sRef_undefined;
4048       emarker->storageclass = SCNONE;
4049       emarker->used = FALSE;
4050       emarker->lset = FALSE;
4051       emarker->info = NULL;
4052
4053       uentry_setSpecDef (emarker, fileloc_undefined);
4054       emarker->uses = filelocList_new ();
4055       emarker->isPrivate = FALSE;
4056       emarker->hasNameError = FALSE;
4057     }
4058
4059   /*@ignore@*/ return (emarker); /*@end@*/
4060
4061
4062 /*
4063 ** comparisons
4064 */
4065
4066 bool
4067 uentry_equiv (uentry p1, uentry p2)
4068 {
4069   if (uentry_compare (p1, p2) != 0)
4070     {
4071       return FALSE;
4072     }
4073   else
4074     {
4075       return TRUE;
4076     }
4077 }
4078
4079 int
4080 uentry_xcomparealpha (uentry *p1, uentry *p2)
4081 {
4082   int res;
4083
4084   if ((res = uentry_compare (*p1, *p2)) == 0) {
4085     if ((*p1 != NULL) && (*p2 != NULL)) {
4086       res = cstring_compare ((*p1)->uname,
4087                              (*p2)->uname);
4088     }
4089   }
4090
4091   return res;
4092 }
4093
4094 int
4095 uentry_xcompareuses (uentry *p1, uentry *p2)
4096 {
4097   uentry u1 = *p1;
4098   uentry u2 = *p2;
4099
4100   if (uentry_isValid (u1))
4101     {
4102       if (uentry_isValid (u2))
4103         {
4104           return (-1 * int_compare (filelocList_size (u1->uses), 
4105                                     filelocList_size (u2->uses)));
4106         }
4107       else
4108         {
4109           return 1;
4110         }
4111     }
4112   else
4113     {
4114       if (uentry_isValid (u2))
4115         {
4116           return -1;
4117         }
4118       else
4119         {
4120           return 0;
4121         }
4122     }
4123 }
4124
4125 int 
4126 uentry_compareStrict (uentry v1, uentry v2)
4127 {
4128   COMPARERETURN (uentry_compare (v1, v2));
4129
4130   if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4131     {
4132       COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4133       COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4134       COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4135     }
4136
4137   return 0;
4138 }
4139
4140 int
4141 uentry_compare (uentry u1, uentry u2)
4142 {
4143   if (u1 == u2) return 0;
4144   
4145   if (uentry_isInvalid (u1)) return -1;
4146   if (uentry_isInvalid (u2)) return 1;
4147
4148   INTCOMPARERETURN (u1->ukind, u2->ukind);
4149   COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4150   COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4151   COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4152
4153   switch (u1->ukind)
4154     {
4155     case KINVALID:
4156     case KELIPSMARKER:
4157       /* bug detected by lclint:  
4158       ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE 
4159       */
4160       return 0;
4161     case KENUMCONST:
4162     case KCONST:
4163       return (multiVal_compare (uentry_getConstantValue (u1),
4164                                 uentry_getConstantValue (u2)));
4165     case KSTRUCTTAG: 
4166     case KUNIONTAG: 
4167     case KENUMTAG: 
4168       return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4169     case KITER:
4170       COMPARERETURN (typeIdSet_compare (uentry_accessType (u1), 
4171                                          uentry_accessType (u2)));
4172       return (uentryList_compareParams (uentry_getParams (u1), 
4173                                         uentry_getParams (u2)));
4174     case KENDITER:
4175       return (typeIdSet_compare (uentry_accessType (u1), 
4176                                   uentry_accessType (u2)));
4177     case KFCN:
4178       /*
4179       ** Functions are never equivalent
4180       */
4181       
4182       if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4183         {
4184           return -1;
4185         }
4186       else
4187         {
4188           return 1;
4189         }
4190     case KVAR:
4191       
4192       COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4193       COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4194                                       sRef_getOrigAliasKind (u2->sref)));
4195       COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4196                                       sRef_getOrigExKind (u2->sref)));
4197       COMPARERETURN (generic_compare (u1->info->var->checked,
4198                                       u2->info->var->checked));
4199       COMPARERETURN (generic_compare (u1->info->var->defstate, 
4200                                       u2->info->var->defstate));
4201       return        (generic_compare (u1->info->var->nullstate, 
4202                                       u2->info->var->nullstate));
4203     case KDATATYPE:
4204       COMPARERETURN (ctype_compare (u1->info->datatype->type,
4205                                     u2->info->datatype->type));
4206       COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4207                                   u2->info->datatype->mut));
4208       return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4209     }
4210   
4211   BADEXIT;
4212 }
4213
4214 /*
4215 ** library format:
4216 **
4217 ** all entries are: <type>[@<info>]*#<name>
4218 **
4219 ** info depends on kind:
4220 */
4221
4222 static void
4223 advanceField (char **s)
4224 {
4225   reader_checkChar (s, '@');
4226 }
4227
4228 static void
4229 advanceName (char **s)
4230 {
4231   reader_checkChar (s, '#');
4232 }
4233
4234 static vkind
4235 vkind_fromInt (int i)
4236 {
4237   if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4238     {
4239       llbuglit ("vkind_fromInt: out of range");
4240     }
4241
4242   return (vkind)i;
4243 }
4244
4245 static uentry  
4246   uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct, 
4247                            typeIdSet access, nstate nullstate,
4248                            /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4249 {
4250   uentry e = uentry_alloc ();
4251   
4252   e->ukind = KCONST;
4253   e->uname = name;
4254   e->utype = ct;
4255   e->sref  = sRef_makeConst (ct);
4256
4257   sRef_setNullState (e->sref, nullstate, loc);
4258   e->storageclass = SCNONE;
4259
4260   if (fileloc_isSpec (loc))
4261     {
4262       e->whereSpecified = loc;
4263       e->whereDeclared = fileloc_undefined;
4264     }
4265   else
4266     {
4267       e->whereSpecified = fileloc_undefined;
4268       e->whereDeclared = loc;
4269     }
4270
4271   e->whereDefined = fileloc_undefined;
4272   e->uses = filelocList_new ();
4273   e->isPrivate = FALSE;
4274   e->hasNameError = FALSE;
4275
4276   e->used = FALSE;
4277   e->lset = FALSE;
4278
4279   e->warn = warnClause_undefined; /*@i452@*/
4280
4281   e->info = (uinfo) dmalloc (sizeof (*e->info));
4282   e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4283   e->info->uconst->access = access;
4284
4285   uentry_setConstantValue (e, m);
4286   sRef_storeState (e->sref);
4287
4288   return (e);
4289 }
4290
4291 static /*@only@*/ uentry  
4292   uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind, 
4293                            sstate defstate, nstate isnull, alkind aliased,
4294                            exkind exp, chkind checked, 
4295                            /*@only@*/ fileloc loc)
4296 {
4297   uentry e = uentry_alloc ();
4298
4299   e->ukind = KVAR;
4300   e->uname = name;
4301   e->utype = ct;
4302   e->storageclass = SCNONE;
4303
4304   e->sref  = sRef_makeType (ct);
4305   sRef_setNullState (e->sref, isnull, loc);
4306
4307   e->whereDefined = fileloc_undefined;
4308
4309   if (fileloc_isSpec (loc))
4310     {
4311       e->whereSpecified = loc;
4312       e->whereDeclared = fileloc_undefined;
4313     }
4314   else
4315     {
4316       e->whereSpecified = fileloc_undefined;
4317       e->whereDeclared = loc;
4318     }
4319
4320   e->isPrivate = FALSE;
4321   e->hasNameError = FALSE;
4322
4323   e->used = FALSE;
4324   e->lset = FALSE;
4325
4326   e->uses = filelocList_new ();
4327   e->warn = warnClause_undefined; /*@i452@*/
4328
4329   e->info = (uinfo) dmalloc (sizeof (*e->info));
4330   e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4331   e->info->var->kind = kind;
4332   e->info->var->checked = checked;
4333   e->info->var->defstate = defstate;
4334
4335   sRef_setDefState (e->sref, defstate, loc);
4336
4337   e->info->var->nullstate = sRef_getNullState (e->sref);
4338
4339   sRef_setExKind (e->sref, exp, loc);
4340   sRef_setAliasKind (e->sref, aliased, loc);
4341
4342   sRef_storeState (e->sref);
4343
4344   /*DRL ADDED 9-1-2000 */
4345   e->info->var->bufinfo = NULL;
4346   
4347   return (e);
4348 }
4349
4350 static /*@only@*/ uentry  
4351 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract, 
4352                          ynm mut, ctype rtype, alkind ak, exkind exp, 
4353                          sstate defstate, nstate isnull,
4354                          /*@only@*/ fileloc loc)
4355 {
4356   uentry e = uentry_alloc ();
4357
4358   e->ukind = KDATATYPE;
4359   /* e->shallowCopy = FALSE; */
4360   e->uname = name;
4361   e->utype = ct;
4362   e->storageclass = SCNONE;
4363   e->sref  = sRef_makeUnknown ();
4364   DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4365
4366   /*
4367   ** This is only setting null state.  (I think?)
4368   */
4369
4370   if (ctype_isUA (ct))
4371     {
4372       uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4373
4374       if (uentry_isValid (te))
4375         {
4376           sRef_setStateFromUentry (e->sref, te);
4377         }
4378       else
4379         {
4380           /* problem for recursive type definitions */
4381         }
4382     }
4383   
4384   sRef_setAliasKind (e->sref, ak, loc);
4385   sRef_setExKind (e->sref, exp, loc);
4386
4387   sRef_setDefState (e->sref, defstate, loc);
4388
4389   if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4390     {
4391       isnull = NS_ABSNULL;
4392     }
4393
4394   DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4395   sRef_mergeNullState (e->sref, isnull);
4396
4397   e->whereDefined = fileloc_copy (loc); /*< bogus!  (but necessary for lexer) >*/
4398
4399   if (fileloc_isSpec (loc))
4400     {
4401       e->whereSpecified = loc;
4402       e->whereDeclared = fileloc_undefined;
4403     }
4404   else
4405     {
4406       e->whereSpecified = fileloc_undefined;
4407       e->whereDeclared = loc;
4408     }
4409   
4410   e->isPrivate = FALSE;
4411   e->hasNameError = FALSE;
4412
4413   e->warn = warnClause_undefined; /*@i452@*/
4414
4415   e->used = FALSE;
4416   e->lset = FALSE;
4417   e->uses = filelocList_new ();
4418
4419   e->info = (uinfo) dmalloc (sizeof (*e->info));
4420   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4421   e->info->datatype->abs = abstract;
4422   e->info->datatype->mut = mut;
4423   e->info->datatype->type = rtype;
4424
4425   DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4426   sRef_storeState (e->sref);
4427   DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4428
4429   return (e);
4430 }
4431
4432 # ifndef NOLCL
4433 static void uentry_setHasGlobs (uentry ue)
4434 {
4435   llassert (uentry_isFunction (ue));
4436
4437   ue->info->fcn->hasGlobs = TRUE;
4438 }
4439
4440 static void uentry_setHasMods (uentry ue)
4441 {
4442   llassert (uentry_isFunction (ue));
4443
4444   ue->info->fcn->hasMods = TRUE;
4445 }
4446 # endif
4447
4448 bool uentry_hasGlobs (uentry ue)
4449 {
4450   if (uentry_isFunction (ue))
4451     {
4452       return (ue->info->fcn->hasGlobs);
4453     }
4454
4455   return FALSE;
4456 }
4457
4458 bool uentry_hasStateClauseList (uentry ue)
4459 {
4460   return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4461 }
4462
4463 bool uentry_hasConditions (uentry ue)
4464 {
4465   return (uentry_isFunction (ue) 
4466           && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4467               || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4468 }
4469
4470 stateClauseList uentry_getStateClauseList (uentry ue)
4471 {
4472   if (!uentry_isFunction (ue))
4473     {
4474       llassert (uentry_isFunction (ue));
4475       return stateClauseList_undefined;
4476     }
4477
4478   DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4479   return ue->info->fcn->specclauses;
4480 }
4481
4482 bool uentry_hasMods (uentry ue)
4483 {
4484   if (uentry_isFunction (ue))
4485     {
4486       return (ue->info->fcn->hasMods);
4487     }
4488
4489   return FALSE;
4490 }
4491
4492 static uentry  
4493   uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct, 
4494                            typeIdSet access, 
4495                            bool hasGlobs, /*@only@*/ globSet globs, 
4496                            bool hasMods, /*@only@*/ sRefSet mods, 
4497                            alkind ak, exkind exp, 
4498                            sstate defstate, nstate isnull,
4499                            exitkind exitCode,
4500                            specCode sCode,
4501                            qual nullPred,
4502                            /*@only@*/ stateClauseList specclauses,
4503                            /*@only@*/ warnClause warnclause,
4504                            /*@only@*/ fileloc loc)
4505 {
4506   uentry e = uentry_alloc ();
4507   ctype ret;
4508
4509   /* e->shallowCopy = FALSE; */
4510   e->ukind = KFCN;
4511   e->uname = name;
4512   e->utype = ct;
4513   e->storageclass = SCNONE;
4514
4515   if (ctype_isFunction (ct))
4516     {
4517       ret = ctype_getReturnType (ct);
4518     }
4519   else
4520     {
4521       if (ctype_isKnown (ct))
4522         {
4523           llbug (message ("not function: %s", ctype_unparse (ct)));
4524         }
4525
4526       ret = ctype_unknown;
4527     }
4528
4529   e->sref  = sRef_makeType (ret);
4530
4531   if (ctype_isUA (ret))
4532     {
4533       sRef_setStateFromType (e->sref, ret);
4534     }
4535
4536   sRef_setDefined (e->sref, loc);
4537   sRef_setNullState (e->sref, isnull, loc);
4538
4539   sRef_setAliasKind (e->sref, ak, loc);
4540   sRef_setExKind (e->sref, exp, loc);
4541   sRef_setDefState (e->sref, defstate, loc);
4542
4543   e->whereSpecified = loc;
4544   e->whereDefined = fileloc_undefined;
4545
4546   e->isPrivate = FALSE;
4547   e->hasNameError = FALSE;
4548
4549   e->used = FALSE;
4550   e->lset = FALSE;
4551   e->uses = filelocList_new ();  
4552   e->warn = warnclause;
4553
4554   e->info = (uinfo) dmalloc (sizeof (*e->info));
4555   e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4556   
4557   e->info->fcn->exitCode = exitCode;
4558   e->info->fcn->specialCode = sCode;
4559   e->info->fcn->nullPred = nullPred;
4560   e->info->fcn->access = access;
4561
4562   e->info->fcn->specclauses = specclauses;
4563   e->info->fcn->hasGlobs = hasGlobs;
4564   e->info->fcn->globs = globs;
4565
4566   e->info->fcn->hasMods = hasMods;
4567   e->info->fcn->mods = mods;
4568
4569   e->info->fcn->defparams = uentryList_undefined; 
4570   e->whereDeclared = fileloc_undefined;
4571
4572   sRef_storeState (e->sref);
4573
4574   /*drl 111  30 2000*/
4575   e->info->fcn->preconditions = NULL;
4576     /* end drl */
4577
4578   /*drl 12  28 2000*/
4579   e->info->fcn->postconditions = NULL;
4580     /* end drl */
4581   
4582   return (e);
4583 }
4584
4585 static /*@only@*/ uentry  
4586   uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind, 
4587                       ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4588 {
4589   uentry e = uentry_alloc ();
4590   
4591   if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4592     {
4593       llbuglit ("uentry_makeTagBase: not a tag type");
4594     }
4595
4596   /* e->shallowCopy = FALSE; */
4597   e->ukind = tagkind;
4598   e->uname = name;
4599   e->utype = ct;
4600   e->sref  = sRef_makeUnknown ();
4601   e->storageclass = SCNONE;
4602
4603   if (fileloc_isSpec (loc))
4604     {
4605       e->whereSpecified = loc;
4606       e->whereDeclared = fileloc_undefined;
4607     }
4608   else
4609     {
4610       e->whereDeclared = loc;
4611       e->whereSpecified = fileloc_undefined;
4612     }
4613
4614   e->whereDefined = fileloc_undefined;
4615
4616   e->isPrivate = FALSE;
4617   e->hasNameError = FALSE;
4618
4619   e->used = FALSE;
4620   e->lset = FALSE;
4621   e->uses = filelocList_new ();
4622   e->warn = warnClause_undefined; /*@i452@*/
4623
4624   e->info = (uinfo) dmalloc (sizeof (*e->info));
4625   e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4626   e->info->datatype->abs  = NO;
4627   e->info->datatype->mut  = MAYBE;
4628   e->info->datatype->type = rtype;
4629
4630   sRef_storeState (e->sref);
4631
4632   return (e);  
4633 }
4634
4635 static uentry  
4636   uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access, 
4637                        ctype ct, /*@only@*/ fileloc loc)
4638 {
4639   uentry e = uentry_alloc ();
4640   
4641   /* e->shallowCopy = FALSE; */
4642   e->ukind = KITER;
4643   e->uname = name;
4644   e->utype = ct;
4645   e->sref  = sRef_makeUnknown ();
4646   e->storageclass = SCNONE;
4647
4648   if (fileloc_isSpec (loc))
4649     {
4650       e->whereSpecified = loc;
4651       e->whereDeclared = fileloc_undefined;
4652     }
4653   else
4654     {
4655       e->whereDeclared = loc;
4656       e->whereSpecified = fileloc_undefined;
4657     }
4658
4659   e->whereDefined = fileloc_undefined;
4660   
4661   e->isPrivate = FALSE;
4662   e->hasNameError = FALSE;
4663
4664   e->used = FALSE;
4665   e->lset = FALSE;
4666   e->uses = filelocList_new ();
4667   e->warn = warnClause_undefined; /*@i452@*/
4668
4669   e->info = (uinfo) dmalloc (sizeof (*e->info));
4670   e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4671   e->info->iter->access = access;
4672   e->info->iter->mods = sRefSet_undefined;
4673   e->info->iter->globs = globSet_undefined;
4674   
4675   sRef_storeState (e->sref);
4676   return (e);
4677 }
4678
4679 static uentry  
4680   uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access, 
4681                           /*@only@*/ fileloc loc)
4682 {
4683   uentry e = uentry_alloc ();
4684
4685   /* e->shallowCopy = FALSE; */
4686   e->ukind = KENDITER;
4687   e->storageclass = SCNONE;
4688   e->uname = name;
4689   e->utype = ctype_unknown;
4690   e->sref  = sRef_makeUnknown ();
4691   
4692   if (fileloc_isSpec (loc))
4693     {
4694       e->whereSpecified = loc;
4695       e->whereDeclared = fileloc_undefined;
4696     }
4697   else
4698     {
4699       e->whereDeclared = loc;
4700       e->whereSpecified = fileloc_undefined;
4701     }
4702
4703   e->whereDefined = fileloc_undefined;
4704
4705   e->isPrivate = FALSE;
4706   e->hasNameError = FALSE;
4707
4708   e->used = FALSE;
4709   e->lset = FALSE;
4710   e->uses = filelocList_new ();
4711   e->warn = warnClause_undefined; /*@i452@*/
4712
4713   e->info = (uinfo) dmalloc (sizeof (*e->info));
4714   e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4715   e->info->enditer->access = access;
4716   sRef_storeState (e->sref);
4717
4718   return (e);
4719 }
4720
4721 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4722 {
4723   /* should save u */
4724 /*@-mustfree@*/
4725 }
4726 /*@=mustfree@*/
4727
4728 /*@only@*/ uentry
4729 uentry_undump (ekind kind, fileloc loc, char **s)
4730 {
4731   uentry ue;
4732   
4733   DPRINTF (("Uentry undump: %s", *s));
4734
4735   if (**s == '!')
4736     {
4737       reader_checkChar (s, '!');
4738       reader_checkChar (s, '.');
4739       ue = uentry_makeElipsisMarker ();
4740     }
4741   else
4742     {
4743       ctype ct = ctype_undump (s);
4744       cstring name;
4745
4746       switch (kind)
4747         {
4748         case KVAR:
4749           {
4750             vkind  tkind;
4751             sstate defstate;
4752             nstate isnull;
4753             alkind aliased;
4754             exkind exp;
4755             chkind checked;
4756             
4757             reader_checkChar (s, '|');
4758
4759             if (reader_optCheckChar (s, '@'))
4760               {
4761                 tkind = vkind_fromInt (reader_getInt (s));
4762                 reader_checkChar (s, '|');
4763               }
4764             else
4765               {
4766                 tkind = VKPARAM;
4767               }
4768
4769             if (reader_optCheckChar (s, '$'))
4770               {
4771                 defstate = SS_UNKNOWN;
4772                 isnull = NS_UNKNOWN;
4773                 aliased = AK_IMPTEMP;
4774                 exp = XO_UNKNOWN;
4775                 checked = CH_UNKNOWN;
4776               }         
4777             else if (reader_optCheckChar (s, '&'))
4778               {
4779                 defstate = SS_DEFINED;
4780                 isnull = NS_UNKNOWN;
4781                 aliased = AK_IMPTEMP;
4782                 exp = XO_UNKNOWN;
4783                 checked = CH_UNKNOWN;
4784               }         
4785             else if (reader_optCheckChar (s, '^'))
4786               {
4787                 defstate = SS_UNKNOWN;
4788                 isnull = NS_UNKNOWN;
4789                 aliased = AK_IMPTEMP;
4790                 exp = XO_UNKNOWN;
4791                 checked = CH_UNKNOWN;
4792               }         
4793             else
4794               {
4795                 defstate = sstate_fromInt (reader_getInt (s));      
4796                 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));      
4797                 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));      
4798
4799                 if (reader_optCheckChar (s, '&'))
4800                   {
4801                     exp = XO_UNKNOWN;
4802                     checked = CH_UNKNOWN;
4803                   }
4804                 else
4805                   {
4806                     advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4807                     advanceField (s); checked = (chkind) (reader_getInt (s));      
4808                   }
4809               }
4810
4811             advanceName (s);
4812             name = reader_getStringWord (s);
4813             
4814             llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4815
4816             ue = uentry_makeVariableBase (name, ct, tkind, defstate, 
4817                                           isnull, aliased, exp, 
4818                                           checked, fileloc_copy (loc));
4819           }
4820           break;
4821         case KDATATYPE: 
4822           {
4823             ynm abstract;
4824             ynm mut;
4825             ctype rtype;
4826             sstate defstate;
4827             nstate isnull;
4828             alkind aliased;
4829             exkind exp;
4830
4831             advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4832             advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4833             advanceField (s); defstate = sstate_fromInt (reader_getInt (s));      
4834             advanceField (s); isnull = nstate_fromInt (reader_getInt (s));      
4835             advanceField (s); aliased = alkind_fromInt (reader_getInt (s));      
4836             advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4837             advanceField (s); rtype = ctype_undump (s);
4838             advanceName (s); 
4839             name = reader_getStringWord (s);
4840             DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4841             ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype, 
4842                                           aliased, exp, defstate, isnull, 
4843                                           fileloc_copy (loc));
4844           }
4845           break;
4846         case KFCN:
4847           {
4848             alkind     ak;
4849             exkind     exp;
4850             sstate     defstate;
4851             nstate     isnull;
4852             exitkind   exitCode;
4853             specCode   specc;
4854             qual       nullPred;
4855             typeIdSet access;
4856             bool       hasGlobs;
4857             globSet    globs;
4858             bool       hasMods;
4859             sRefSet    mods;
4860             stateClauseList specclauses = stateClauseList_undefined;
4861             warnClause warnclause = warnClause_undefined;
4862
4863             if (reader_optCheckChar (s, '$'))
4864               {
4865                 defstate = SS_DEFINED;
4866                 isnull = NS_UNKNOWN;
4867                 exitCode = XK_UNKNOWN;
4868                 specc = SPC_NONE;
4869                 nullPred = qual_createUnknown ();
4870               }
4871             else
4872               {
4873                 advanceField (s); defstate = sstate_fromInt (reader_getInt (s)); 
4874                 advanceField (s); isnull = nstate_fromInt (reader_getInt (s)); 
4875                 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s)); 
4876                 advanceField (s); specc = specCode_fromInt (reader_getInt (s)); 
4877                 advanceField (s); nullPred = qual_undump (s);
4878               }
4879
4880             if (reader_optCheckChar (s, '$'))
4881               {
4882                 hasGlobs = FALSE;
4883                 globs = globSet_undefined;
4884                 hasMods = FALSE;
4885                 mods = sRefSet_undefined;
4886               }
4887             else if (reader_optCheckChar (s, '^'))
4888               {
4889                 hasGlobs = TRUE;
4890                 globs = globSet_undefined;
4891                 hasMods = TRUE;
4892                 mods = sRefSet_undefined;
4893               }
4894             else
4895               {
4896                 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4897                 advanceField (s); globs  = globSet_undump (s);
4898                 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4899                 advanceField (s); mods   = sRefSet_undump (s);      
4900               }
4901
4902             if (reader_optCheckChar (s, '$'))
4903               {
4904                 ak = AK_UNKNOWN;
4905                 exp = XO_UNKNOWN;
4906               }
4907             else
4908               {
4909                 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4910                 advanceField (s); exp = exkind_fromInt (reader_getInt (s));      
4911               }
4912
4913             advanceField (s); access = typeIdSet_undump (s);
4914
4915             /*
4916             ** Optional clauses: Start with @<code>:
4917             */
4918
4919             while (reader_optCheckChar (s, '@'))
4920               {
4921                 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4922                   {
4923                     reader_checkChar (s, ':');
4924                     warnclause = warnClause_undump (s);
4925                   }
4926                 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4927                   {
4928                     reader_checkChar (s, ':');
4929                     specclauses = stateClauseList_undump (s);
4930                   }
4931                 else
4932                   {
4933                     BADBRANCH;
4934                   }
4935               }
4936
4937             advanceName (s);  name = reader_getStringWord (s);
4938
4939             ue = uentry_makeFunctionBase (name, ct, access, 
4940                                           hasGlobs, globs, 
4941                                           hasMods, mods, 
4942                                           ak, exp, defstate, isnull, 
4943                                           exitCode, specc, nullPred,
4944                                           specclauses,
4945                                           warnclause,
4946                                           fileloc_copy (loc));
4947             DPRINTF (("Undump: %s", uentry_unparse (ue)));
4948           }
4949           break;
4950         case KITER:
4951           {
4952             typeIdSet access;
4953             
4954             advanceField (s); access = typeIdSet_undump (s);
4955             advanceName (s);  name = reader_getStringWord (s);
4956             
4957             ue = uentry_makeIterBase (name, access, ct,
4958                                       fileloc_copy (loc));
4959           }
4960           break;
4961         case KENDITER:
4962           {
4963             typeIdSet access;
4964
4965             advanceField (s); access = typeIdSet_undump (s);
4966             advanceName (s);  name = reader_getStringWord (s);
4967             
4968             ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4969           }
4970           break;
4971         case KENUMCONST:  
4972         case KCONST:  
4973           {
4974             typeIdSet access;
4975             multiVal val;
4976             nstate nullstate;
4977
4978             if (reader_optCheckChar (s, '$'))
4979               {
4980                 val = multiVal_undefined;
4981                 access = typeIdSet_undefined;
4982                 nullstate = NS_UNKNOWN;
4983               }
4984             else
4985               {
4986                 advanceField (s); val = multiVal_undump (s);
4987                 advanceField (s); access = typeIdSet_undump (s);
4988                 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4989               }
4990
4991             advanceName (s);  name = reader_getStringWord (s);
4992             
4993             ue = uentry_makeConstantBase (name, ct, access,
4994                                           nullstate, fileloc_copy (loc), val);
4995             break;
4996           }
4997         case KSTRUCTTAG:
4998         case KUNIONTAG:
4999         case KENUMTAG:
5000           {
5001             ctype rtype;
5002             
5003             advanceField (s); rtype = ctype_undump (s);
5004             advanceName (s);  name = reader_getStringWord (s);
5005             ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5006           }
5007           break;
5008         case KINVALID:
5009           llcontbuglit ("uentry_undump: invalid");
5010           ue = uentry_undefined;
5011           break;
5012         case KELIPSMARKER:
5013           llcontbuglit ("uentry_undump: elips marker");
5014           ue = uentry_undefined;
5015           break;
5016         }
5017     }
5018   
5019   return (ue);
5020 }
5021
5022 cstring
5023 uentry_dump (uentry v)
5024 {
5025   return (uentry_dumpAux (v, FALSE));
5026 }
5027
5028 cstring
5029 uentry_dumpParam (uentry v)
5030 {
5031   llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5032                  ("dump: %s", uentry_unparseFull (v)));
5033
5034   return (uentry_dumpAux (v, TRUE));
5035 }
5036
5037 static cstring
5038 uentry_dumpAux (uentry v, bool isParam)
5039 {
5040   llassert (uentry_isValid (v));
5041   llassert (!uentry_isGlobalMarker (v));
5042
5043   DPRINTF (("Dump uentry: [%p]", v));
5044   DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5045   
5046   switch (v->ukind)
5047     {
5048     case KINVALID: 
5049       llcontbuglit ("uentry_dump: invalid entry"); 
5050       return cstring_undefined;
5051     case KELIPSMARKER: 
5052       return (message ("!."));
5053     case KVAR:     
5054       {
5055         cstring sdump;
5056         vkind vk  = v->info->var->kind;
5057         sstate dss = sRef_getDefState (v->sref);
5058         nstate nst = sRef_getNullState (v->sref);
5059         alkind alk = sRef_getAliasKind (v->sref);
5060         exkind exk = sRef_getExKind (v->sref);
5061         chkind chk = v->info->var->checked;
5062
5063         DPRINTF (("Dumping var"));
5064
5065         if (dss == SS_UNKNOWN
5066             && nst == NS_UNKNOWN
5067             && alk == AK_IMPTEMP
5068             && exk == XO_UNKNOWN
5069             && chk == CH_UNKNOWN)
5070           {
5071             sdump = cstring_makeLiteral ("$");
5072           }
5073         else if (dss == SS_DEFINED
5074                  && nst == NS_UNKNOWN
5075                  && alk == AK_IMPTEMP
5076                  && exk == XO_UNKNOWN
5077                  && chk == CH_UNKNOWN)
5078           {
5079             sdump = cstring_makeLiteral ("&");
5080           }
5081         else if (dss == SS_UNKNOWN
5082                  && nst == NS_UNKNOWN
5083                  && alk == AK_UNKNOWN
5084                  && exk == XO_UNKNOWN
5085                  && chk == CH_UNKNOWN)
5086           {
5087             sdump = cstring_makeLiteral ("^");
5088           }
5089         else if (exk == XO_UNKNOWN
5090                  && chk == CH_UNKNOWN)
5091           {
5092             sdump = message ("%d@%d@%d&",
5093                              (int) dss,
5094                              (int) nst,
5095                              (int) alk);
5096           }
5097         else
5098           {
5099             sdump = message ("%d@%d@%d@%d@%d",  
5100                      (int) dss,
5101                              (int) nst,
5102                              (int) alk,
5103                              (int) exk,
5104                              (int) chk);
5105           }
5106         
5107
5108         if (vk != VKPARAM)
5109           {
5110             return (message ("%q|@%d|%q#%s", 
5111                              ctype_dump (v->utype), 
5112                              (int) vk,
5113                              sdump,
5114                              isParam ? cstring_undefined : v->uname));
5115           }
5116         else
5117           {
5118             return (message ("%q|%q#%s", 
5119                              ctype_dump (v->utype), 
5120                              sdump,
5121                              isParam ? cstring_undefined : v->uname));
5122           }
5123
5124       }
5125     case KDATATYPE: 
5126       /*
5127       DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5128                 uentry_unparse (v), 
5129                 exkind_unparse (sRef_getExKind (v->sref)),
5130                 ctype_unparse (v->utype), (int) v->utype));
5131       */
5132
5133       return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s", 
5134                        ctype_dump (v->utype),
5135                        ynm_unparseCode (v->info->datatype->abs),
5136                        ynm_unparseCode (v->info->datatype->mut),
5137                        (int) sRef_getDefState (v->sref),
5138                        (int) sRef_getNullState (v->sref),
5139                        (int) sRef_getAliasKind (v->sref),
5140                        (int) sRef_getExKind (v->sref),
5141                        ctype_dump (v->info->datatype->type),
5142                        v->uname));
5143     case KFCN:
5144       {
5145         cstring sdump, gdump, adump, xdump;
5146         alkind alk = sRef_getAliasKind (v->sref);
5147         exkind exk = sRef_getExKind (v->sref);
5148
5149         if (sRef_getDefState (v->sref) == SS_DEFINED
5150             && !nstate_isKnown (sRef_getNullState (v->sref))
5151             && !exitkind_isKnown (v->info->fcn->exitCode)
5152             && v->info->fcn->specialCode == SPC_NONE
5153             && qual_isUnknown (v->info->fcn->nullPred))
5154           {
5155             sdump = cstring_makeLiteral ("$");
5156           }
5157         else
5158           {
5159             sdump = message ("@%d@%d@%d@%d@%x",
5160                              (int) sRef_getDefState (v->sref),
5161                              (int) sRef_getNullState (v->sref),
5162                              (int) v->info->fcn->exitCode,
5163                              (int) v->info->fcn->specialCode,
5164                              qual_dump (v->info->fcn->nullPred));
5165           }
5166
5167         if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5168           {
5169             gdump = cstring_makeLiteral ("$");
5170           }
5171         else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5172                  && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5173           {
5174             gdump = cstring_makeLiteral ("^");
5175           }
5176         else
5177           {
5178             gdump = message ("@%s@%q@%s@%q",
5179                              bool_dump (uentry_hasGlobs (v)),
5180                              globSet_dump (uentry_getGlobs (v)),
5181                              bool_dump (uentry_hasMods (v)),
5182                              sRefSet_dump (uentry_getMods (v)));
5183           }
5184
5185         if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5186           {
5187             adump = cstring_makeLiteral ("$");
5188           }
5189         else
5190           {
5191             adump = message ("@%d@%d", (int) alk, (int) exk);
5192           }
5193
5194         xdump = cstring_undefined;
5195
5196         if (uentry_hasWarning (v))
5197           {
5198             xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5199           }
5200
5201         if (uentry_hasStateClauseList (v))
5202           {
5203             xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5204           }
5205
5206         return (message ("%q%q%q%q@%q%q#%s",
5207                          ctype_dump (v->utype),
5208                          sdump,
5209                          gdump,
5210                          adump,
5211                          typeIdSet_dump (uentry_accessType (v)),
5212                          xdump,
5213                          v->uname));
5214       }
5215     case KITER:
5216       return (message ("%q@%q#%s",
5217                        ctype_dump (v->utype),
5218                        typeIdSet_dump (v->info->iter->access),
5219                        v->uname));
5220     case KENDITER:
5221       return (message ("%q@%q#%s",
5222                        ctype_dump (v->utype),
5223                        typeIdSet_dump (uentry_accessType (v)),
5224                        v->uname));
5225     case KENUMCONST:  
5226     case KCONST:  
5227       {
5228         cstring sdump;
5229
5230         if (multiVal_isUnknown (uentry_getConstantValue (v))
5231             && typeIdSet_isEmpty (uentry_accessType (v))
5232             && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5233           {
5234             sdump = cstring_makeLiteral ("$");
5235           }
5236         else
5237           {
5238             sdump = message ("@%q@%q@%d",
5239                              multiVal_dump (uentry_getConstantValue (v)),
5240                              typeIdSet_dump (uentry_accessType (v)),
5241                              (int) sRef_getNullState (v->sref));
5242           }
5243
5244         return (message ("%q%q#%s", 
5245                          ctype_dump (v->utype), 
5246                          sdump,
5247                          v->uname));
5248       }
5249     case KSTRUCTTAG:
5250     case KUNIONTAG:
5251     case KENUMTAG:
5252       return (message ("%q@%q#%s", 
5253                        ctype_dump (v->utype), 
5254                        ctype_dump (v->info->datatype->type), v->uname));
5255     }
5256
5257   BADEXIT;
5258 }
5259
5260 /*@only@*/ cstring
5261 uentry_unparseAbbrev (uentry v)
5262 {
5263   if (!uentry_isVariable (v))
5264     {
5265       llcontbuglit ("uentry_unparseAbbrev: not variable");
5266       return uentry_unparse (v);
5267     }
5268
5269   return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5270 }
5271
5272 /*@only@*/ cstring
5273 uentry_unparse (uentry v)
5274 {
5275   cstring st;
5276
5277     if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5278   if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5279
5280   st = uentry_getName (v);
5281
5282   if (cstring_isDefined (st))
5283     {
5284       return (ctype_unparseDeclaration (v->utype, st)); 
5285     }
5286   else
5287     {
5288       cstring_free (st);
5289       return (cstring_copy (ctype_unparse (v->utype)));
5290     }
5291 }
5292
5293 /*@only@*/ cstring
5294 uentry_unparseFull (uentry v)
5295 {
5296   if (uentry_isUndefined (v))
5297     {
5298       return (cstring_makeLiteral ("<undefined>"));
5299     }
5300   else
5301     {
5302       cstring res;
5303
5304       res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5305                      (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5306                      ctype_unparse (v->utype),
5307                      fileloc_unparse (uentry_whereSpecified (v)),
5308                      fileloc_unparse (uentry_whereDeclared (v)),
5309                      fileloc_unparse (uentry_whereDefined (v)));
5310
5311       DPRINTF (("uentry: %s", res));
5312
5313       if (uentry_isDatatype (v))
5314         {
5315           res = message ("%q / type: %s mut: %s abs: %s state: %q",
5316                          res,
5317                          ctype_unparse 
5318                          (ctype_isDefined (v->info->datatype->type) 
5319                           ? v->info->datatype->type : ctype_unknown),
5320                          ynm_unparse (v->info->datatype->mut),
5321                          ynm_unparse (v->info->datatype->abs),
5322                          sRef_unparseState (v->sref));
5323         }
5324       else if (uentry_isFunction (v))
5325         {
5326           res = message ("%q / sref: %q / mods: %q / "
5327                          "globs: %q / clauses: %q / pre: %q / post: %q",
5328                          res,
5329                          sRef_unparseFull (v->sref),
5330                          sRefSet_unparse (v->info->fcn->mods),
5331                          globSet_unparse  (v->info->fcn->globs),
5332                          stateClauseList_unparse (v->info->fcn->specclauses),
5333                          functionConstraint_unparse (v->info->fcn->preconditions),
5334                          functionConstraint_unparse (v->info->fcn->postconditions));
5335         }
5336       else if (uentry_isIter (v))
5337         {
5338           res = message ("%q / sref: %q",
5339                          res,
5340                          sRef_unparseFull (v->sref));
5341         }
5342       else if (uentry_isVariable (v))
5343         {
5344           res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5345                          res,
5346                          sRef_unparseFull (v->sref),
5347                          (int) v->info->var->kind,
5348                          (int) v->info->var->defstate,
5349                          (int) v->info->var->nullstate,
5350                          (int) v->used);
5351           DPRINTF (("sref: [%p]", v->sref));
5352           DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5353           /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref)));           */
5354         }
5355       else if (uentry_isConstant (v))
5356         {
5357           res = message ("%q = %q",
5358                          res, multiVal_unparse (uentry_getConstantValue (v)));
5359         }
5360       else
5361         {
5362           res = message ("%q :: %q", res, uentry_unparse (v));
5363         }
5364
5365       return res;
5366     }
5367 }
5368
5369 bool uentry_hasAccessType (uentry e)
5370 {
5371   if (uentry_isValid (e))
5372     {
5373       switch (e->ukind)
5374         {
5375         case KITER:
5376           return (!typeIdSet_isEmpty (e->info->iter->access));
5377         case KENDITER:
5378           return (!typeIdSet_isEmpty (e->info->enditer->access));
5379         case KFCN:
5380           return (!typeIdSet_isEmpty (e->info->fcn->access));
5381         case KENUMCONST:
5382         case KCONST:
5383           return (!typeIdSet_isEmpty (e->info->uconst->access));
5384         default:
5385           return FALSE;
5386         }
5387     }
5388
5389   return FALSE;
5390 }
5391   
5392 typeIdSet uentry_accessType (uentry e)
5393 {
5394   if (uentry_isValid (e))
5395     {
5396       switch (e->ukind)
5397         {
5398         case KITER:
5399           return (e->info->iter->access);
5400         case KENDITER:
5401           return (e->info->enditer->access);
5402         case KFCN:
5403           return (e->info->fcn->access);
5404         case KENUMCONST:
5405         case KCONST:
5406           return (e->info->uconst->access);
5407         default:
5408           break;
5409         }
5410     }
5411
5412   return typeIdSet_undefined;
5413 }
5414
5415 bool
5416 uentry_isVariable (uentry e)
5417 {
5418   return (uentry_isVar (e));
5419 }
5420
5421 bool
5422 uentry_isSpecified (uentry e)
5423 {
5424   return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5425 }
5426
5427 static bool
5428 uentry_isReallySpecified (uentry e)
5429 {
5430   return (uentry_isValid (e) 
5431           && fileloc_isRealSpec (e->whereSpecified));
5432 }
5433
5434 bool
5435 uentry_isVar (uentry e)
5436 {
5437   return (!uentry_isUndefined (e) && e->ukind == KVAR);
5438 }
5439
5440 bool 
5441 uentry_isFakeTag (uentry e)
5442 {
5443   return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5444 }
5445
5446 bool
5447 uentry_isDatatype (uentry e)
5448 {
5449   return (!uentry_isUndefined (e) &&
5450           (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5451            e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5452 }
5453
5454 void
5455 uentry_setAbstract (uentry e)
5456 {
5457   typeId oldid;
5458
5459   llassert (uentry_isDatatype (e) 
5460             && (ynm_isMaybe (e->info->datatype->abs)));
5461
5462   oldid = ctype_typeId (e->info->datatype->type);
5463   e->info->datatype->abs = YES;
5464   e->info->datatype->type = ctype_createAbstract (oldid);
5465 }
5466
5467 void
5468 uentry_setConcrete (uentry e)
5469 {
5470   llassert (uentry_isDatatype (e) 
5471             && (ynm_isMaybe (e->info->datatype->abs)));
5472
5473   e->info->datatype->abs = NO;
5474 }
5475
5476 bool
5477 uentry_isAbstractDatatype (uentry e)
5478 {
5479   return (uentry_isDatatype (e) 
5480           && (ynm_isOn (e->info->datatype->abs)));
5481 }
5482
5483 bool
5484 uentry_isMaybeAbstract (uentry e)
5485 {
5486   return (uentry_isDatatype (e) 
5487           && (ynm_isMaybe (e->info->datatype->abs)));
5488 }
5489
5490 bool
5491 uentry_isMutableDatatype (uentry e)
5492 {
5493   bool res = uentry_isDatatype (e) 
5494     && (ynm_toBoolRelaxed (e->info->datatype->mut));
5495   
5496   return res;
5497 }
5498
5499 bool
5500 uentry_isRefCountedDatatype (uentry e)
5501 {
5502   return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5503 }
5504
5505 bool
5506 uentry_isParam (uentry u)
5507 {
5508   return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5509                                     || u->info->var->kind == VKYIELDPARAM));
5510 }
5511
5512 bool
5513 uentry_isExpandedMacro (uentry u)
5514 {
5515   return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5516 }
5517
5518 bool
5519 uentry_isSefParam (uentry u)
5520 {
5521   return (uentry_isVariable (u) 
5522           && (u->info->var->kind == VKSEFPARAM
5523               || u->info->var->kind == VKREFSEFPARAM
5524               || u->info->var->kind == VKSEFRETPARAM
5525               || u->info->var->kind == VKREFSEFRETPARAM));
5526 }
5527
5528 bool
5529 uentry_isRefParam (uentry u)
5530 {
5531   return (uentry_isVariable (u) 
5532           && (u->info->var->kind == VKREFPARAM
5533               || u->info->var->kind == VKREFYIELDPARAM
5534               || u->info->var->kind == VKREFSEFPARAM
5535               || u->info->var->kind == VKREFSEFRETPARAM));
5536 }
5537
5538 bool
5539 uentry_isAnyParam (uentry u)
5540 {
5541   return (uentry_isVariable (u) 
5542           && ((u->info->var->kind == VKPARAM)
5543               || (u->info->var->kind == VKSEFPARAM)
5544               || (u->info->var->kind == VKYIELDPARAM)
5545               || (u->info->var->kind == VKRETPARAM)
5546               || (u->info->var->kind == VKSEFRETPARAM)));
5547 }
5548
5549 sstate 
5550 uentry_getDefState (uentry u)
5551 {
5552   if (uentry_isValid (u))
5553     {
5554       return (sRef_getDefState (u->sref));
5555     }
5556   else
5557     {
5558       return (SS_UNKNOWN);
5559     }
5560 }
5561
5562 bool
5563 uentry_isOut (uentry u)
5564 {
5565   return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5566           || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5567 }
5568
5569 bool
5570 uentry_isPartial (uentry u)
5571 {
5572   return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5573           || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5574 }
5575
5576 bool
5577 uentry_isStateSpecial (uentry u)
5578 {
5579   return ((uentry_isVariable (u) 
5580            && (u->info->var->defstate == SS_SPECIAL))
5581           || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5582 }
5583
5584 exitkind uentry_getExitCode (uentry ue) 
5585 {
5586   if (uentry_isFunction (ue))
5587     {
5588       return ue->info->fcn->exitCode;
5589     }
5590   else
5591     {
5592       return XK_UNKNOWN;
5593     }
5594 }
5595
5596 qual uentry_nullPred (uentry u)
5597 {
5598   llassert (uentry_isRealFunction (u));
5599
5600   if (uentry_isFunction (u))
5601     {
5602       return (u->info->fcn->nullPred);
5603     }
5604   else
5605     {
5606       return qual_createUnknown ();
5607     }
5608 }
5609
5610 /*
5611 ** Note for variables, this is checking the declared state, not the current state.
5612 */
5613
5614 bool
5615 uentry_possiblyNull (uentry u)
5616 {
5617   return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5618           || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5619 }
5620
5621 alkind 
5622 uentry_getAliasKind (uentry u)
5623 {
5624   if (uentry_isValid (u))
5625     {
5626       return (sRef_getAliasKind (uentry_getSref (u)));
5627     }
5628   else
5629     {
5630       return AK_UNKNOWN;
5631     }
5632 }
5633
5634 exkind 
5635 uentry_getExpKind (uentry u)
5636 {
5637   if (uentry_isValid (u))
5638     {
5639       return (sRef_getExKind (uentry_getSref (u)));
5640     }
5641   else
5642     {
5643       return XO_UNKNOWN;
5644     }
5645 }
5646
5647 bool
5648 uentry_isIter (uentry e)
5649 {
5650   return (!uentry_isUndefined (e) && e->ukind == KITER);
5651 }
5652
5653 bool
5654 uentry_isEndIter (uentry e)
5655 {
5656   return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5657 }
5658
5659 bool
5660 uentry_isRealFunction (uentry e)
5661 {
5662   return (uentry_isFunction (e) ||
5663           (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5664 }
5665
5666 bool
5667 uentry_hasName (uentry e)
5668 {
5669   if (uentry_isValid (e))
5670     {
5671       cstring s = e->uname;
5672       
5673       return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5674                 || uentry_isFakeTag (e)));
5675     }
5676   else
5677     {
5678       return FALSE;
5679     }
5680 }
5681
5682 /*
5683 ** Returns true for fake tags.
5684 ** This is used for dumping the library
5685 */
5686
5687 bool uentry_hasRealName (uentry e)
5688 {
5689   return (uentry_isValid (e) 
5690           && cstring_isNonEmpty (e->uname)
5691           && !uentry_isGlobalMarker (e));
5692 }
5693
5694
5695 /*@observer@*/ globSet
5696 uentry_getGlobs (uentry l)
5697 {
5698   if (uentry_isInvalid (l)) 
5699     {
5700       return globSet_undefined;
5701     }
5702
5703   if (l->ukind != KFCN)
5704     {
5705       if (l->ukind != KITER && l->ukind != KENDITER)
5706         {
5707           if (l->ukind == KVAR)
5708             {
5709               llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)", 
5710                               uentry_unparse (l), 
5711                               ekind_unparse (l->ukind)));
5712             }
5713           else
5714             {
5715               llbug (message ("Bad call to uentry_getGlobs: %q (%s)", 
5716                               uentry_unparse (l), 
5717                               ekind_unparse (l->ukind)));
5718             }
5719         }
5720       return globSet_undefined;
5721     }
5722
5723   return l->info->fcn->globs;
5724 }
5725
5726 /*@observer@*/ sRefSet
5727 uentry_getMods (uentry l)
5728 {
5729   llassert (uentry_isValid (l));
5730
5731   if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5732     {
5733       llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5734       return sRefSet_undefined; 
5735     }
5736
5737   return l->info->fcn->mods;
5738 }
5739
5740 ekind
5741 uentry_getKind (uentry e)
5742 {
5743   llassert (uentry_isValid (e));
5744
5745   return (e->ukind);
5746 }
5747
5748 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5749 {
5750   llassert (uentry_isEitherConstant (e)); 
5751   return (sRef_getValue (e->sref));
5752 }
5753
5754 /*@observer@*/ uentryList
5755 uentry_getParams (uentry l)
5756 {
5757   if (uentry_isInvalid (l)) return uentryList_undefined;
5758
5759   switch (l->ukind)
5760     {
5761     case KFCN:  
5762     case KITER:
5763       {
5764         ctype ct = l->utype;
5765
5766         if (ctype_isFunction (ct))
5767           {
5768             return (ctype_argsFunction (ct));
5769           }
5770         else
5771           {
5772             return uentryList_undefined;
5773           }
5774       }
5775     case KVAR:  
5776       {
5777         ctype ct = l->utype;
5778
5779         llassert (ctype_isFunction (ct));
5780         return (ctype_argsFunction (ct));
5781       }
5782     BADDEFAULT;
5783     }
5784   BADEXIT;
5785 }
5786
5787 /*@observer@*/ cstring
5788 uentry_rawName (uentry e)
5789 {
5790   if (uentry_isValid (e))
5791     {
5792       return (e->uname);
5793     }
5794   else
5795     {
5796       return cstring_undefined;
5797     }
5798 }
5799
5800 static cstring
5801 uentry_getOptName (uentry e)
5802 {
5803   cstring s = uentry_getName (e);
5804
5805   if (cstring_isDefined (s))
5806     {
5807       s = cstring_appendChar (s, ' ');
5808     }
5809   
5810   return s;
5811 }
5812
5813 /*@only@*/ cstring
5814 uentry_getName (uentry e)
5815 {
5816   cstring ret = cstring_undefined;
5817
5818   if (uentry_isValid (e))
5819     {
5820       if (uentry_isAnyTag (e))
5821         {
5822           ret = fixTagName (e->uname);  
5823         }
5824       else if (uentry_isAnyParam (e))
5825         {
5826           ret = cstring_copy (fixParamName (e->uname));
5827         }
5828       else
5829         {
5830           ret = cstring_copy (e->uname);
5831         }
5832     }
5833
5834   return ret;
5835 }
5836
5837 cstring uentry_observeRealName (uentry e)
5838 {
5839   cstring ret = cstring_undefined;
5840
5841   if (uentry_isValid (e))
5842     {      
5843       if (uentry_isAnyTag (e))
5844         {
5845           if (isFakeTag (e->uname))
5846             {
5847               ret = cstring_undefined;
5848             }
5849           else
5850             {
5851               ret = plainTagName (e->uname); 
5852             }
5853         }
5854       else if (uentry_isAnyParam (e))
5855         {
5856           ret = fixParamName (e->uname);
5857         }
5858       else
5859         {
5860           ret = e->uname;
5861         }
5862     }
5863
5864   return ret;
5865 }
5866
5867 cstring uentry_getRealName (uentry e)
5868 {
5869   if (uentry_isValid (e))
5870     {
5871       if (uentry_isAnyTag (e))
5872         {
5873           return (cstring_undefined);
5874         }
5875       else
5876         {
5877           return (e->uname);
5878         }
5879     }
5880   return cstring_undefined;
5881 }
5882
5883 ctype uentry_getType (uentry e)
5884 {
5885   if (uentry_isValid (e))
5886     {
5887       return e->utype;
5888     }
5889   else
5890     {
5891       return ctype_unknown;
5892     }
5893 }
5894
5895 fileloc uentry_whereLast (uentry e)
5896 {
5897   fileloc loc;
5898
5899   if (uentry_isInvalid (e)) 
5900     {
5901       return fileloc_undefined;
5902     }
5903   
5904   loc = e->whereDefined;
5905
5906   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5907     {
5908       return loc;
5909     }
5910
5911   loc = uentry_whereDeclared (e);
5912
5913   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5914     {
5915       return loc;
5916     }
5917
5918   loc = uentry_whereSpecified (e);
5919   return loc;
5920 }
5921
5922 fileloc uentry_whereEither (uentry e)
5923 {
5924   if (uentry_isInvalid (e)) return fileloc_undefined;
5925
5926   if (fileloc_isDefined (e->whereDefined) 
5927       && !fileloc_isExternal (e->whereDefined))
5928     {
5929       return e->whereDefined;
5930     }
5931   else if (fileloc_isDefined (e->whereDeclared))
5932     {
5933       return e->whereDeclared;
5934     }
5935   else
5936     {
5937       return e->whereSpecified;
5938     }
5939 }
5940
5941 fileloc uentry_whereSpecified (uentry e)
5942 {
5943   if (uentry_isInvalid (e)) return fileloc_undefined;
5944
5945   return (e->whereSpecified);
5946 }
5947
5948 fileloc uentry_whereDefined (uentry e)
5949 {
5950   if (uentry_isInvalid (e)) return fileloc_undefined;
5951
5952   return (e->whereDefined);
5953 }
5954
5955 fileloc uentry_whereDeclared (uentry e)
5956 {
5957   if (uentry_isInvalid (e)) return fileloc_undefined;
5958
5959   return (e->whereDeclared);
5960 }
5961
5962 /*@observer@*/ fileloc
5963 uentry_whereEarliest (uentry e)
5964 {
5965   if (uentry_isInvalid (e)) return fileloc_undefined;
5966   
5967   if (fileloc_isDefined (e->whereSpecified))
5968     {
5969       return (e->whereSpecified);
5970     }
5971   else if (fileloc_isDefined (e->whereDeclared))
5972     {
5973       return (e->whereDeclared);
5974     }
5975   else
5976     {
5977       return e->whereDefined;
5978     }
5979 }
5980
5981 void
5982 uentry_setFunctionDefined (uentry e, fileloc loc)
5983 {
5984   if (uentry_isValid (e))
5985     {
5986       llassert (uentry_isFunction (e));
5987
5988       if (fileloc_isUndefined (e->whereDeclared))
5989         {
5990           e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5991         }
5992       
5993       if (!fileloc_isDefined (e->whereDefined))
5994         {
5995           e->whereDefined = fileloc_update (e->whereDefined, loc);
5996         }
5997     }
5998 }
5999
6000 void
6001 uentry_setDeclDef (uentry e, fileloc f)
6002 {
6003   uentry_setDeclared (e, f);
6004   
6005   if (!uentry_isFunction (e)
6006       && !(uentry_isVariable (e) && uentry_isExtern (e)))
6007     {
6008       uentry_setDefined (e, f);
6009     }
6010 }
6011
6012 void
6013 uentry_setDeclaredForce (uentry e, fileloc f)
6014 {
6015   llassert (uentry_isValid (e));
6016   e->whereDeclared = fileloc_update (e->whereDeclared, f);
6017 }
6018
6019 void
6020 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6021 {
6022   llassert (uentry_isValid (e));
6023   fileloc_free (e->whereDeclared);
6024   e->whereDeclared = f;
6025 }
6026
6027 void
6028 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6029 {
6030   fileloc oldloc;
6031
6032   llassert (uentry_isValid (e));
6033   oldloc = e->whereDeclared;  
6034
6035   if (fileloc_isDefined (oldloc))
6036     {
6037       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6038         {
6039           e->whereDeclared = f;
6040           fileloc_free (oldloc);
6041         }
6042       else
6043         {
6044           fileloc_free (f);
6045         }
6046     }
6047   else
6048     {
6049       e->whereDeclared = f;
6050       fileloc_free (oldloc);
6051     }
6052 }
6053   
6054 void
6055 uentry_setDeclared (uentry e, fileloc f)
6056 {
6057   fileloc oldloc;
6058
6059   llassert (uentry_isValid (e));
6060   oldloc = e->whereDeclared;  
6061
6062   if (fileloc_isDefined (oldloc))
6063     {
6064       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6065         {
6066           e->whereDeclared = fileloc_update (e->whereDeclared, f);
6067         }
6068       else
6069         {
6070           ;
6071         }
6072     }
6073   else
6074     {
6075       e->whereDeclared = fileloc_update (e->whereDeclared, f);
6076     }
6077 }
6078
6079 void
6080 uentry_clearDefined (uentry e)
6081 {
6082   if (uentry_isValid (e))
6083     {
6084       e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6085     }
6086 }
6087
6088 void
6089 uentry_setDefined (uentry e, fileloc f)
6090 {
6091   fileloc oldloc;
6092
6093   llassert (uentry_isValid (e));
6094   oldloc = e->whereDefined;
6095
6096   if (fileloc_isDefined (oldloc))
6097     {
6098       if (fileloc_isLib (oldloc) 
6099           || fileloc_isImport (oldloc)
6100           || fileloc_isBuiltin (oldloc) 
6101           || fileloc_isPreproc (oldloc))
6102         {
6103           e->whereDefined = fileloc_update (e->whereDefined, f);
6104         }
6105       else
6106         {
6107           if (fileloc_equal (oldloc, f) || context_processingMacros ())
6108             {
6109               ; /* okay */
6110             }
6111           else
6112             {
6113               if (optgenerror (FLG_REDEF,
6114                                message ("%s %q redefined", 
6115                                         ekind_capName (e->ukind),
6116                                         uentry_getName (e)),
6117                                f))
6118                 {
6119                   llgenindentmsg (message ("Previous definition of %q", 
6120                                            uentry_getName (e)),
6121                                   e->whereDefined);
6122                 }
6123             }
6124         }
6125     }
6126   else
6127     {
6128       e->whereDefined = fileloc_update (e->whereDefined, f);
6129     }
6130 }
6131
6132 bool
6133 uentry_isCodeDefined (uentry e)
6134 {
6135   llassert (uentry_isValid (e));
6136
6137   return (fileloc_isDefined (e->whereDefined));
6138 }
6139
6140 bool
6141 uentry_isDeclared (uentry e)
6142 {
6143   if (uentry_isValid (e))
6144     {
6145       return (fileloc_isDefined (e->whereDeclared));
6146     }
6147
6148   return FALSE;
6149 }
6150
6151 sRef uentry_getSref (uentry e)
6152 {
6153   /* not true, used for functions too (but shouldn't be? */
6154   /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6155
6156   if (uentry_isInvalid (e)) return sRef_undefined;
6157   
6158   return (e->sref);
6159 }
6160
6161 sRef uentry_getOrigSref (uentry e)
6162 {
6163   /*@i523*/ /* evans 2001-09-09 - need to fix this 
6164   if (uentry_isValid (e))
6165     {
6166       if (uentry_isVariable (e))
6167         {
6168           return e->info->var->origsref;
6169         }
6170       else
6171         {
6172           sRef sr = sRef_copy (uentry_getSref (e));
6173           
6174           sRef_resetState (sr);
6175           sRef_clearDerived (sr);
6176           return (sr);
6177         }
6178     }
6179   else
6180     {
6181       return sRef_undefined;
6182     }
6183   */
6184
6185   if (uentry_isValid (e))
6186     {
6187       sRef sr = sRef_copy (uentry_getSref (e));
6188       
6189       sRef_resetState (sr);
6190       sRef_clearDerived (sr);
6191       
6192       if (uentry_isVariable (e))
6193         {
6194           sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6195           sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6196         }
6197       
6198       return (sr);
6199     }
6200   else
6201     {
6202       return sRef_undefined;
6203     }
6204 }
6205
6206 /*
6207 ** requires: uentry e is not in a hashed symbol table
6208 */
6209
6210 void 
6211 uentry_setName (uentry e, /*@only@*/ cstring n)
6212 {
6213   llassert (uentry_isValid (e));
6214
6215   cstring_free (e->uname);
6216   e->uname = n;
6217 }
6218
6219 void
6220 uentry_setType (uentry e, ctype t)
6221 {
6222   if (uentry_isValid (e)) 
6223     {
6224       e->utype = t;
6225       sRef_setType (e->sref, t);
6226     }
6227 }
6228
6229 void
6230 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6231 {
6232   ctype rct;
6233   ctype rettype = ctype_unknown;
6234   
6235   llassert (uentry_isValid (ue));
6236
6237   uentry_convertVarFunction (ue);
6238   llassert (uentry_isFunction (ue));
6239
6240   rct = ctype_realType (ue->utype);
6241
6242   if (ctype_isFunction (rct))
6243     {
6244       rettype = ctype_getReturnType (rct);
6245     }
6246
6247   ue->utype = ctype_makeNFParamsFunction (rettype, pn);      
6248 }
6249
6250 void
6251 uentry_setRefParam (uentry e)
6252 {
6253   if (!uentry_isVar (e))
6254     {
6255       llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6256     }
6257   else
6258     {
6259       if (e->info->var->kind == VKSEFPARAM)
6260         {
6261           e->info->var->kind = VKREFSEFPARAM;
6262         }
6263       else if (e->info->var->kind == VKSEFRETPARAM)
6264         {
6265           e->info->var->kind = VKREFSEFRETPARAM;
6266         }
6267       else if (e->info->var->kind == VKYIELDPARAM)
6268         {
6269           e->info->var->kind = VKREFYIELDPARAM;
6270         }
6271       else
6272         {
6273           e->info->var->kind = VKREFPARAM;
6274         }
6275     }
6276 }
6277
6278 void
6279 uentry_setParam (uentry e)
6280 {
6281   if (!uentry_isVar (e))
6282     {
6283       if (uentry_isElipsisMarker (e))
6284         {
6285
6286         }
6287       else
6288         {
6289           llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6290         }
6291     }
6292   else
6293     {
6294       cstring oldname;
6295
6296       if (e->info->var->kind == VKYIELDPARAM 
6297           || e->info->var->kind == VKSEFPARAM
6298           || e->info->var->kind == VKSEFRETPARAM)
6299         {
6300           ;
6301         }
6302       else
6303         {
6304           e->info->var->kind = VKPARAM;
6305         }
6306
6307       oldname = e->uname;
6308       e->uname = makeParam (e->uname);
6309       cstring_free (oldname);
6310     }
6311 }
6312
6313 void
6314 uentry_setSref (uentry e, sRef s)
6315 {
6316   if (uentry_isValid (e))
6317     {
6318       if (sRef_isValid (e->sref))
6319         {
6320           sRef_mergeStateQuietReverse (e->sref, s);
6321         }
6322       else
6323         {
6324           e->sref = sRef_saveCopy (s);
6325         }
6326     }
6327 }
6328
6329 ctype
6330 uentry_getAbstractType (uentry e)
6331 {
6332   llassert (uentry_isDatatype (e));
6333
6334   /*
6335   ** This assertion removed.
6336   ** Okay to have undefined type, for system types
6337   
6338   llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6339                     ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6340                     e->utype);
6341                     
6342   */
6343
6344   if (ctype_isUndefined (e->info->datatype->type))
6345     {
6346       return ctype_unknown;
6347     }
6348
6349   /*
6350   ** Sadly, a kludge...
6351   */
6352
6353   if (ctype_isUserBool (e->info->datatype->type)) {
6354     return ctype_bool;
6355   }
6356
6357   return e->info->datatype->type;
6358 }
6359
6360 ctype uentry_getRealType (uentry e)
6361 {
6362   ctype ct;
6363   typeId uid = USYMIDINVALID;
6364
6365   if (uentry_isInvalid (e))
6366     {
6367       return ctype_unknown;
6368     }
6369
6370   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6371
6372   if (uentry_isAnyTag (e))
6373     {
6374       return (e->utype);
6375     }
6376   
6377   if (uentry_isAbstractType (e))
6378     {
6379       ct = uentry_getAbstractType (e);      
6380
6381       if (ctype_isManifestBool (ct)) {
6382         return ct;
6383       }
6384
6385       llassert (ctype_isUA (ct));
6386       
6387       uid = ctype_typeId (ct);
6388       
6389       if (!context_hasAccess (uid))
6390         {
6391           return (ct);
6392         }
6393     }
6394
6395   ct = uentry_getType (e);
6396
6397   /* if (ctype_isUserBool (ct)) return ct; */
6398
6399   if (ctype_isManifestBool (ct)) {
6400     return ctype_bool;
6401   }
6402   
6403   if (ctype_isUA (ct))
6404     {
6405       usymId iid = ctype_typeId (ct);
6406       
6407       if (usymId_equal (iid, uid))
6408         {         
6409           llcontbug (message ("uentry_getRealType: recursive type! %s",
6410                               ctype_unparse (ct)));
6411           return ct;
6412         }
6413       else
6414         {
6415           /* evs 2000-07-25: possible infinite recursion ? */
6416           uentry ue2 = usymtab_getTypeEntry (iid);
6417
6418           if (ue2 == e)
6419             {
6420               llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6421               return ctype_unknown;
6422             }
6423
6424           return uentry_getRealType (ue2);
6425         }
6426     }
6427   else
6428     {
6429       return ct;
6430     }
6431 }
6432
6433 ctype uentry_getForceRealType (uentry e)
6434 {
6435   ctype   ct;
6436   typeId uid = USYMIDINVALID;
6437
6438   if (uentry_isInvalid (e))
6439     {
6440       return ctype_unknown;
6441     }
6442
6443   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6444   
6445   if (uentry_isAnyTag (e))
6446     {
6447       return (e->utype);
6448     }
6449   
6450   if (uentry_isAbstractType (e))
6451     {
6452       ct = uentry_getAbstractType (e);      
6453       llassert (ctype_isUA (ct));
6454       
6455       uid = ctype_typeId (ct);
6456       /* no check for access! */
6457     }
6458   
6459   ct = uentry_getType (e);
6460
6461   /* evs 2000-07-25 */
6462   /* if (ctype_isUserBool (ct)) return ct; */
6463
6464   if (ctype_isManifestBool (ct)) {
6465     return ctype_bool;
6466   }
6467   
6468   if (ctype_isUA (ct))
6469     {
6470       usymId iid = ctype_typeId (ct);
6471       
6472       if (usymId_equal (iid, uid))
6473         {         
6474           llcontbug (message ("uentry_getRealType: recursive type! %s",
6475                               ctype_unparse (ct)));
6476           return ct;
6477         }
6478       else
6479         {
6480           return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6481         }
6482     }
6483   else
6484     {
6485       return ct;
6486     }
6487 }
6488
6489 uentry uentry_nameCopy (cstring name, uentry e)
6490 {
6491   uentry enew = uentry_alloc ();
6492
6493   llassert (uentry_isValid (e));
6494
6495   /* enew->shallowCopy = FALSE; */
6496   enew->ukind = e->ukind;
6497   enew->uname = name;
6498   enew->utype = e->utype;
6499   enew->whereSpecified = fileloc_copy (e->whereSpecified);
6500   enew->whereDefined = fileloc_copy (e->whereDefined);
6501   enew->whereDeclared = fileloc_copy (e->whereDeclared);
6502   enew->sref = sRef_copy (e->sref); 
6503   enew->used = e->used;
6504   enew->lset = FALSE;
6505   enew->isPrivate = e->isPrivate;
6506   enew->hasNameError = FALSE;
6507
6508   enew->uses = filelocList_new ();
6509   enew->warn = warnClause_undefined; 
6510
6511   enew->storageclass = e->storageclass;
6512   enew->info = uinfo_copy (e->info, e->ukind);
6513
6514   return enew;
6515 }
6516
6517 void
6518 uentry_setDatatype (uentry e, usymId uid)
6519 {
6520   llassert (uentry_isDatatype (e));
6521
6522   if (uentry_isAbstractType (e))
6523     {
6524       e->info->datatype->type = ctype_createAbstract (uid);
6525     }
6526   else
6527     {
6528       e->info->datatype->type = ctype_createUser (uid);
6529     }
6530 }
6531
6532 static void 
6533 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6534    /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6535    /*@modifies e@*/
6536 {
6537   llassert (uentry_isValid (e));
6538
6539   if (fileloc_isSpec (f) || fileloc_isImport (f))
6540     {
6541       e->whereSpecified = f;
6542       e->whereDeclared  = fileloc_undefined;
6543       e->whereDefined  = fileloc_undefined;
6544     }
6545   else
6546     {
6547       e->whereSpecified = fileloc_undefined;
6548       e->whereDeclared  = f;
6549       e->whereDefined  = fileloc_undefined;
6550     }
6551
6552   llassert (fileloc_storable (f));
6553 }
6554
6555 static void
6556 ucinfo_free (/*@only@*/ ucinfo u)
6557 {
6558   sfree (u);
6559 }
6560
6561 static void
6562 uvinfo_free (/*@only@*/ uvinfo u)
6563 {
6564   /*drl7x added 6/29/01 */
6565   free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6566   sfree (u);
6567 }
6568
6569 static void
6570 udinfo_free (/*@only@*/ udinfo u)
6571 {
6572   sfree (u);
6573 }
6574
6575 static void
6576 ufinfo_free (/*@only@*/ ufinfo u)
6577 {
6578   globSet_free (u->globs);
6579   sRefSet_free (u->mods);
6580   stateClauseList_free (u->specclauses);
6581   sfree (u);
6582 }
6583
6584 static void
6585 uiinfo_free (/*@only@*/ uiinfo u)
6586 {
6587   sfree (u);
6588 }
6589
6590 static void
6591 ueinfo_free (/*@only@*/ ueinfo u)
6592 {
6593   sfree (u);
6594 }
6595
6596 static /*@only@*/ ucinfo
6597 ucinfo_copy (ucinfo u)
6598 {
6599   ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6600   ret->access = u->access;
6601   return ret;
6602 }
6603
6604 static /*@only@*/ uvinfo
6605 uvinfo_copy (uvinfo u)
6606 {
6607   uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6608   
6609   ret->kind = u->kind;
6610   ret->nullstate = u->nullstate;
6611   ret->defstate = u->defstate;
6612   ret->checked = u->checked;
6613
6614   /*@i523 ret->origsref = sRef_copy (u->origsref); */
6615
6616   /* drl added 07-02-001 */
6617   /* copy null terminated information */
6618
6619   if (u->bufinfo != NULL)
6620     {
6621       ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6622       ret->bufinfo->bufstate = u->bufinfo->bufstate;
6623       ret->bufinfo->size     = u->bufinfo->size;
6624       ret->bufinfo->len      = u->bufinfo->len;
6625       return ret;
6626     }
6627   else
6628     {
6629       ret->bufinfo = NULL;
6630       return ret;
6631     }
6632     
6633 }
6634
6635 static /*@only@*/ udinfo
6636 udinfo_copy (udinfo u)
6637 {
6638   udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6639
6640   ret->abs = u->abs;
6641   ret->mut = u->mut;
6642   ret->type = u->type;
6643
6644   return ret;
6645 }
6646
6647 static /*@only@*/ ufinfo
6648 ufinfo_copy (ufinfo u)
6649 {
6650   ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6651
6652   ret->hasGlobs = u->hasGlobs;
6653   ret->hasMods = u->hasMods;
6654   ret->exitCode = u->exitCode;
6655   ret->specialCode = u->specialCode;
6656   ret->nullPred = u->nullPred;
6657   ret->access = u->access;
6658   ret->globs = globSet_newCopy (u->globs);
6659   ret->mods = sRefSet_newCopy (u->mods);
6660   ret->defparams = u->defparams;
6661   ret->specclauses = stateClauseList_copy (u->specclauses);
6662
6663   ret->preconditions = functionConstraint_copy (u->preconditions);
6664   ret->postconditions = functionConstraint_copy (u->postconditions);
6665   
6666   return ret;
6667 }
6668
6669 static /*@only@*/ uiinfo
6670 uiinfo_copy (uiinfo u)
6671 {
6672   uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6673
6674   ret->access = u->access;
6675   ret->globs = globSet_newCopy (u->globs);
6676   ret->mods = sRefSet_newCopy (u->mods);
6677
6678   return (ret);
6679 }
6680
6681 static /*@only@*/ ueinfo
6682 ueinfo_copy (ueinfo u)
6683 {
6684   ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6685
6686   ret->access = u->access;
6687   return ret;
6688 }
6689
6690 static void
6691 uinfo_free (uinfo u, ekind kind)
6692 {
6693   switch (kind)
6694     {
6695     case KENUMCONST:
6696     case KCONST:       ucinfo_free (u->uconst); break;
6697     case KVAR:         uvinfo_free (u->var); break;
6698     case KSTRUCTTAG:
6699     case KUNIONTAG:
6700     case KENUMTAG:
6701     case KDATATYPE:    udinfo_free (u->datatype); break;
6702     case KFCN:         ufinfo_free (u->fcn); break;
6703     case KITER:        uiinfo_free (u->iter); break;
6704     case KENDITER:     ueinfo_free (u->enditer); break;
6705     case KELIPSMARKER: break;
6706     case KINVALID:     break;
6707     }
6708   
6709     sfree (u);
6710 }
6711
6712 static /*@only@*/ /*@null@*/ uinfo
6713 uinfo_copy (uinfo u, ekind kind)
6714 {
6715   if (kind == KELIPSMARKER || kind == KINVALID)
6716     {
6717       return NULL;
6718     }
6719   else
6720     {
6721       uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6722       
6723       switch (kind)
6724         {
6725         case KENUMCONST:
6726         case KCONST:    ret->uconst = ucinfo_copy (u->uconst); break;
6727         case KVAR:      ret->var = uvinfo_copy (u->var); break;
6728         case KSTRUCTTAG:
6729         case KUNIONTAG:
6730         case KENUMTAG:
6731         case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6732         case KFCN:      ret->fcn = ufinfo_copy (u->fcn); break;
6733         case KITER:     ret->iter = uiinfo_copy (u->iter); break;
6734         case KENDITER:  ret->enditer = ueinfo_copy (u->enditer); break;
6735         BADDEFAULT;
6736         }
6737       return ret;
6738     }
6739 }
6740
6741 static void
6742 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6743 {
6744   filelocList_free (e->uses);
6745   cstring_free (e->uname);
6746   
6747   uinfo_free (e->info, e->ukind);
6748   
6749   fileloc_free (e->whereSpecified); 
6750   fileloc_free (e->whereDefined); 
6751   fileloc_free (e->whereDeclared); 
6752
6753   warnClause_free (e->warn);
6754
6755   nuentries--;
6756   sfree (e);
6757   }
6758
6759 extern void uentry_markOwned (/*@owned@*/ uentry u)
6760 {
6761   sfreeEventually (u);
6762 }
6763
6764 void
6765 uentry_free (/*@only@*/ uentry e)
6766 {
6767   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6768     {
6769       uentry_reallyFree (e);
6770     }
6771 }
6772
6773 /*
6774 ** For uentry's in the global or file scope
6775 */
6776
6777 void
6778 uentry_freeComplete (/*@only@*/ uentry e)
6779 {
6780   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6781     {
6782       DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6783       /*@i@*/ sRef_free (e->sref);
6784       e->sref = sRef_undefined;
6785       uentry_reallyFree (e);
6786     }
6787 }
6788
6789 /*
6790 ** requires old->kind != new->kind, old->uname = new->uname
6791 */
6792
6793 static void
6794 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6795 {
6796   llassert (uentry_isValid (old));
6797   llassert (uentry_isValid (unew));
6798
6799   if (uentry_isEitherConstant (unew)
6800       && (fileloc_isPreproc (uentry_whereDeclared (old))
6801           || ctype_isUnknown (old->utype))
6802       && !uentry_isSpecified (old))
6803     {
6804       ; /* no error */
6805     }
6806   else 
6807     {
6808       if (mustConform)
6809         {
6810           if (!uentry_isDeclared (old))
6811             {
6812               if (uentry_isSpecified (old))
6813                 {
6814                   if (uentry_isSpecified (unew))
6815                     {
6816                       llbuglit ("Respecification!");
6817                     }
6818                   else if (uentry_isDeclared (unew))
6819                     {
6820                       if (optgenerror
6821                           (FLG_INCONDEFS,
6822                            message ("%s %q inconsistently declared as %s: %t",
6823                                     ekind_capName (old->ukind),
6824                                     uentry_getName (unew),
6825                                     ekind_unparseLong (unew->ukind),
6826                                     unew->utype),
6827                            uentry_whereLast (unew)))  /* evans 2001-12-30: was uentry_whereDeclared */
6828                         {
6829                           uentry_showWhereLastKind (old);
6830                         }
6831                     }
6832                   else
6833                     {
6834                       BADEXIT;
6835                     }
6836                 }
6837               else
6838                 {
6839                   if (optgenerror
6840                       (FLG_INCONDEFS,
6841                        message ("%s %q inconsistently declared as %s: %t",
6842                                 ekind_capName (old->ukind),
6843                                 uentry_getName (unew),
6844                                 ekind_unparseLong (unew->ukind),
6845                                 unew->utype),
6846                        uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6847                     {
6848                       uentry_showWhereLastKind (old);
6849                     }
6850                 }
6851             }
6852           else
6853             {
6854               llassert (uentry_isDeclared (unew));
6855
6856               DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6857               DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6858
6859               if (optgenerror
6860                   (FLG_INCONDEFS,
6861                    message ("%s %q inconsistently redeclared as %s",
6862                             ekind_capName (old->ukind),
6863                             uentry_getName (unew),
6864                             ekind_unparseLong (unew->ukind)),
6865                    uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6866                 {
6867                   uentry_showWhereLastKind (old);
6868                 }
6869             }
6870         }
6871     }
6872
6873   uentry_updateInto (old, unew);
6874 }
6875
6876 /*
6877 ** def is the definition of spec, modifies spec
6878 **
6879 ** reports any inconsistencies
6880 ** returns the summary of all available information
6881 ** if spec and def are inconsistent, def is returned
6882 */
6883
6884 void
6885 uentry_showWhereLast (uentry spec)
6886 {
6887   if (uentry_isValid (spec))
6888     {
6889       if (fileloc_isDefined (spec->whereDefined)
6890           && !fileloc_isLib (spec->whereDefined)
6891           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6892         {
6893           llgenindentmsg (message ("Previous definition of %q: %t", 
6894                                    uentry_getName (spec),
6895                                    uentry_getType (spec)),
6896                           uentry_whereDefined (spec));
6897         }
6898       else if (uentry_isDeclared (spec))
6899         {
6900           llgenindentmsg (message ("Previous declaration of %q: %t", 
6901                                    uentry_getName (spec),
6902                                    uentry_getType (spec)),
6903                           uentry_whereDeclared (spec));
6904         }
6905       else if (uentry_isSpecified (spec))
6906         {
6907           if (uentry_hasName (spec))
6908             {
6909               llgenindentmsg (message ("Specification of %q: %t", 
6910                                        uentry_getName (spec),
6911                                        uentry_getType (spec)),
6912                               uentry_whereSpecified (spec));
6913             }
6914           else
6915             {
6916               llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6917                               uentry_whereSpecified (spec));
6918             }
6919         }
6920       else
6921         {
6922           /* nothing to show */
6923         }
6924     }
6925 }
6926
6927 static void
6928 uentry_showWhereLastKind (uentry spec)
6929 {
6930   if (uentry_isValid (spec))
6931     {
6932       if (fileloc_isDefined (spec->whereDefined)
6933           && !fileloc_isLib (spec->whereDefined)
6934           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6935         {
6936           llgenindentmsg (message ("Previous definition of %q as %s: %t", 
6937                                    uentry_getName (spec),
6938                                    ekind_unparseLong (spec->ukind),
6939                                    uentry_getType (spec)),
6940                           uentry_whereDefined (spec));
6941         }
6942       else if (uentry_isDeclared (spec))
6943         {
6944           llgenindentmsg (message ("Previous declaration of %q as %s: %t", 
6945                                    uentry_getName (spec),
6946                                    ekind_unparseLong (spec->ukind),
6947                                    uentry_getType (spec)),
6948                           uentry_whereDeclared (spec));
6949         }
6950       else if (uentry_isSpecified (spec))
6951         {
6952           if (uentry_hasName (spec))
6953             {
6954               llgenindentmsg (message ("Specification of %q as %s: %t", 
6955                                        uentry_getName (spec),
6956                                        ekind_unparseLong (spec->ukind),
6957                                        uentry_getType (spec)),
6958                               uentry_whereSpecified (spec));
6959             }
6960           else
6961             {
6962               llgenindentmsg (message ("Specification as %s: %t",
6963                                        ekind_unparseLong (spec->ukind),
6964                                        uentry_getType (spec)),
6965                               uentry_whereSpecified (spec));
6966             }
6967         }
6968       else
6969         {
6970           /* nothing to show */
6971         }
6972     }
6973 }
6974
6975 void
6976 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6977 {
6978   fileloc loc = uentry_whereDefined (ce);
6979   
6980   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6981     {
6982       llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6983                       loc);
6984     }
6985
6986   loc = uentry_whereSpecified (ce);
6987   
6988   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6989     {
6990       llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6991                       loc);
6992     }
6993 }
6994
6995 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6996 {
6997   if (uentry_isDeclared (spec))
6998     {
6999       llgenindentmsg (message ("Previous declaration of %q: %q", 
7000                                uentry_getName (spec), extra),
7001                       uentry_whereDeclared (spec));
7002     }
7003   else if (uentry_isSpecified (spec))
7004     {
7005       llgenindentmsg (message ("Specification of %q: %q", 
7006                                uentry_getName (spec), extra),
7007                       uentry_whereSpecified (spec));
7008     }
7009   else
7010     {
7011       cstring_free (extra);
7012     }
7013 }
7014
7015 void
7016 uentry_showWhereDeclared (uentry spec)
7017 {
7018   if (uentry_isDeclared (spec))
7019     {
7020       if (uentry_hasName (spec))
7021         {
7022           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7023                           uentry_whereDeclared (spec));
7024         }
7025       else
7026         {
7027           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7028         }
7029     }
7030   else if (uentry_isSpecified (spec))
7031     {
7032       if (uentry_hasName (spec))
7033         {
7034           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7035                           uentry_whereSpecified (spec));
7036         }
7037       else
7038         {
7039           llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7040         }
7041     }
7042   else
7043     {
7044       /* nothing to show */
7045     }
7046     
7047 }
7048
7049 void
7050 uentry_showWhereAny (uentry spec)
7051 {
7052   if (uentry_isDeclared (spec))
7053     {
7054       if (uentry_hasName (spec))
7055         {
7056           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7057                           uentry_whereDeclared (spec));
7058         }
7059       else
7060         {
7061           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7062         }
7063     }
7064   else if (uentry_isSpecified (spec))
7065     {
7066       if (uentry_hasName (spec))
7067         {
7068           llgenindentmsg (message ("Specification of %q",
7069                                    uentry_getName (spec)),
7070                           uentry_whereSpecified (spec));
7071         }
7072       else
7073         {
7074           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7075                           uentry_whereSpecified (spec));
7076         }
7077     }
7078   else if (fileloc_isDefined (uentry_whereDefined (spec))) 
7079     {
7080       if (uentry_hasName (spec))
7081         {
7082           llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7083                           uentry_whereDefined (spec));
7084         }
7085       else
7086         {
7087           llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7088         }
7089     }
7090   else
7091     {
7092       /* nothing to show */
7093     }
7094 }
7095
7096 void
7097 uentry_showWhereDefined (uentry spec)
7098 {
7099   if (uentry_isCodeDefined (spec))
7100     {
7101       llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7102                       uentry_whereDefined (spec));
7103     }
7104 }
7105
7106 void
7107 uentry_showWhereLastPlain (uentry spec)
7108 {
7109   if (uentry_isDeclared (spec))
7110     {
7111       llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7112                       uentry_whereDeclared (spec));
7113     }
7114   else if (uentry_isSpecified (spec))
7115     {
7116       llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7117                       uentry_whereSpecified (spec));
7118     }
7119   else
7120     {
7121           }
7122 }
7123
7124 static void
7125 uentry_showWhereLastVal (uentry spec, cstring val)
7126 {
7127   if (uentry_isDeclared (spec))
7128     {
7129       llgenindentmsg (message ("Previous declaration of %q: %s", 
7130                                uentry_getName (spec), val),
7131                       uentry_whereDeclared (spec));
7132     }
7133   else if (uentry_isSpecified (spec))
7134     {
7135       llgenindentmsg (message ("Specification of %q: %s", 
7136                                uentry_getName (spec), val),
7137                       uentry_whereSpecified (spec));
7138     }
7139   else
7140     {
7141     }
7142 }
7143
7144 void
7145 uentry_showWhereSpecified (uentry spec)
7146 {
7147   if (uentry_isSpecified (spec))
7148     {
7149       if (uentry_hasName (spec))
7150         {
7151           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7152                           uentry_whereSpecified (spec));
7153         }
7154       else
7155         {
7156           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7157                           uentry_whereSpecified (spec));
7158         }
7159     }
7160   else if (uentry_isDeclared (spec))
7161     {
7162       llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7163                       uentry_whereDeclared (spec));
7164     }
7165   else
7166     {
7167       /* nothing to show */
7168     }
7169 }
7170
7171 void
7172 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7173 {
7174   if (uentry_isSpecified (spec))
7175     {
7176       if (uentry_hasName (spec))
7177         {
7178           llgenindentmsg (message ("Specification of %q: %q", 
7179                                    uentry_getName (spec), s),
7180                           uentry_whereSpecified (spec));
7181         }
7182       else
7183         {
7184           llgenindentmsg (message ("Specification: %q", s), 
7185                           uentry_whereSpecified (spec));
7186         }
7187     }
7188   else if (uentry_isDeclared (spec))
7189     {
7190       llgenindentmsg (message ("Declaration of %q: %q", 
7191                                uentry_getName (spec), s),
7192                       uentry_whereDeclared (spec));
7193     }
7194   else
7195     {
7196       llgenindentmsg (message ("Previous: %q", s),
7197                       uentry_whereLast (spec));
7198     }
7199 }
7200
7201 /*
7202 **
7203 */
7204
7205 static void
7206 checkStructConformance (uentry old, uentry unew)
7207 {
7208   ctype oldr, newr; 
7209   uentryList fold, fnew;
7210
7211   /*
7212   ** requires: types of old and new are structs or unions
7213   */
7214
7215   llassert (uentry_isValid (old));
7216   llassert (uentry_isValid (unew));
7217
7218   oldr = ctype_realType (old->utype);
7219   fold =  ctype_getFields (oldr);
7220
7221   newr = ctype_realType (unew->utype);
7222   fnew = ctype_getFields (newr);
7223
7224   if (!uentryList_matchFields (fold, fnew))
7225     {
7226       if (fileloc_equal (uentry_whereLast (old),
7227                          uentry_whereLast (unew)))
7228         {
7229           ; /* cheat! */
7230         }
7231       else 
7232         {
7233           if (optgenerror 
7234               (FLG_MATCHFIELDS,
7235                message ("%q %q %rdeclared with fields { %q }, %s "
7236                         "with fields { %q }",
7237                         cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7238                         uentry_getName (old), 
7239                         uentry_isDeclared (old),
7240                         uentryList_unparseAbbrev (fnew),
7241                         uentry_specOrDefName (old),
7242                         uentryList_unparseAbbrev (fold)),
7243                uentry_whereDeclared (unew)))
7244             {
7245               uentry_showWhereLastPlain (old);
7246               uentryList_showFieldDifference (fold, fnew);
7247             }
7248         }
7249
7250       old->utype = unew->utype;
7251     }
7252 }
7253
7254 static void
7255 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7256 {
7257   /*
7258   ** requires old and new are enums
7259   */
7260   
7261   ctype        rold = ctype_realType (old->utype);
7262   ctype        rnew = ctype_realType (unew->utype);
7263   enumNameList eold = ctype_elist (rold);
7264   enumNameList enew = ctype_elist (rnew);
7265   
7266   if (!enumNameList_match (eold, enew))
7267     {
7268       if (optgenerror 
7269           (FLG_MATCHFIELDS,
7270            message ("Enum %q declared with members { %q } but "
7271                     "specified with members { %q }",
7272                     uentry_getName (old), 
7273                     enumNameList_unparse (enew),
7274                     enumNameList_unparse (eold)),
7275            uentry_whereDeclared (unew)))
7276         {
7277           uentry_showWhereSpecified (old);
7278           old->utype = unew->utype;
7279         }
7280     }
7281 }
7282
7283 /*
7284 ** either oldCurrent or newCurrent may be undefined!
7285 */
7286
7287 static void
7288 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7289                 uentry unew, uentry newCurrent, ctype newType,
7290                 int paramno)
7291 {
7292   bool hasError = FALSE;
7293
7294   if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7295     {
7296       if (uentry_hasName (newCurrent))
7297         {
7298           hasError = optgenerror 
7299             (FLG_TYPE,
7300              message ("Parameter %d, %q, of function %q has inconsistent type: "
7301                       "declared %t, %s %t",
7302                       paramno + 1, uentry_getName (newCurrent), 
7303                       uentry_getName (unew),
7304                       newType, uentry_specOrDefName (old), oldType),
7305              uentry_whereDeclared (newCurrent));
7306         }
7307       else
7308         {
7309           hasError = optgenerror
7310             (FLG_TYPE,
7311              message ("Parameter %d of function %q has inconsistent type: "
7312                       "declared %t, %s %t",
7313                       paramno + 1, uentry_getName (unew),
7314                       newType, uentry_specOrDefName (old), oldType),
7315              uentry_whereDeclared (newCurrent));
7316
7317           DPRINTF (("type: %s / %s",
7318                     ctype_unparse (newType),
7319                     ctype_unparse (ctype_realType (newType))));
7320         }
7321     }
7322   else 
7323     {
7324       if (uentry_isDeclared (unew))
7325         {
7326           hasError = optgenerror 
7327             (FLG_TYPE,
7328              message ("Parameter %d of function %s has inconsistent type: "
7329                       "declared %t, %s %t",
7330                       paramno + 1, unew->uname, 
7331                       newType, uentry_specOrDefName (old), oldType),
7332              uentry_whereDeclared (unew));
7333         }
7334       else
7335         {
7336           hasError = optgenerror
7337             (FLG_TYPE,
7338              message ("Parameter %d of function %s has inconsistent type: "
7339                       "declared %t, %s %t",
7340                       paramno + 1, unew->uname, 
7341                       newType, uentry_specOrDefName (old), oldType),
7342              uentry_whereDeclared (unew));
7343         }
7344     }
7345   
7346   if (hasError)
7347     {
7348       DPRINTF (("Here: %s / %s",
7349                 uentry_unparseFull (oldCurrent),
7350                 uentry_unparseFull (newCurrent)));
7351
7352       if (!uentry_isUndefined (oldCurrent))
7353         {
7354           if (!uentry_isUndefined (newCurrent) 
7355               && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7356             {
7357               uentry_showWhereLast (oldCurrent);
7358             }
7359           else
7360             {
7361               uentry_showWhereLastPlain (old);
7362             }
7363           
7364           uentry_setType (oldCurrent, newType);
7365         }
7366       else
7367         {
7368           uentry_showWhereLastPlain (old);
7369         }
7370     }
7371 }
7372
7373 static void
7374 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7375 {
7376   if (optgenerror 
7377       (FLG_TYPE,
7378        message ("Function %s %rdeclared with %d arg%&, %s with %d",
7379                 unew->uname, 
7380                 uentry_isDeclared (old),
7381                 uentryList_size (uentry_getParams (unew)),
7382                 uentry_specOrDefName (old),
7383                 uentryList_size (uentry_getParams (old))),
7384        uentry_whereDeclared (unew)))
7385     {
7386       uentry_showWhereLastPlain (old);
7387     }
7388 }
7389
7390 static void
7391 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7392 {
7393   if (optgenerror
7394       (FLG_INCONDEFS,
7395        message ("Function %s inconsistently %rdeclared to return %t",
7396                 unew->uname,
7397                 uentry_isDeclared (old),
7398                 ctype_getReturnType (unew->utype)),
7399        uentry_whereDeclared (unew)))
7400     {
7401       uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7402     }
7403 }
7404
7405 static cstring paramStorageName (uentry ue)
7406 {
7407   return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7408 }
7409
7410 static cstring fcnErrName (uentry ue)
7411 {
7412   return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7413 }
7414
7415 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7416 {
7417   if (uentry_isVar (ue))
7418     {
7419       return (checkedName (ue->info->var->checked));
7420     }
7421   else
7422     {
7423       return (cstring_makeLiteralTemp ("<checked invalid>"));
7424     }
7425 }
7426
7427 static cstring checkedName (chkind checked)
7428 {
7429   switch (checked)
7430     {
7431     case CH_UNKNOWN:       return (cstring_makeLiteralTemp ("unknown"));
7432     case CH_UNCHECKED:     return (cstring_makeLiteralTemp ("unchecked"));
7433     case CH_CHECKED:       return (cstring_makeLiteralTemp ("checked"));
7434     case CH_CHECKMOD:      return (cstring_makeLiteralTemp ("checkmod"));
7435     case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7436     }
7437   BADEXIT;
7438 }
7439
7440 static
7441 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7442 {
7443   nstate oldState;
7444   nstate newState;
7445   
7446   if (uentry_isVar (unew))
7447     {
7448       llassert (uentry_isVar (old));
7449       
7450       oldState = old->info->var->nullstate;
7451       newState = unew->info->var->nullstate;
7452     }
7453   else
7454     {
7455       oldState = sRef_getNullState (old->sref);
7456       newState = sRef_getNullState (unew->sref);
7457     }
7458
7459   if (oldState == NS_ABSNULL)
7460     {
7461       if (uentry_isVar (old))
7462         {
7463           old->info->var->nullstate = newState;
7464         }
7465       
7466       sRef_mergeNullState (old->sref, newState);
7467     }
7468   else if (newState == NS_UNKNOWN)
7469     {
7470       if (completeConform && newState != oldState
7471           && uentry_isReallySpecified (old))
7472         {
7473           if (optgenerror 
7474               (FLG_NEEDSPEC,
7475                message ("%s %q specified as %s, but declared without %s qualifier",
7476                         ekind_capName (unew->ukind),
7477                         uentry_getName (unew),
7478                         nstate_unparse (oldState),
7479                         nstate_unparse (oldState)),
7480                uentry_whereDeclared (unew)))
7481             {
7482               uentry_showWhereSpecified (old);
7483             }
7484         }
7485       
7486       if (uentry_isVar (unew))
7487         {
7488           unew->info->var->nullstate = oldState;
7489         }
7490
7491       sRef_mergeNullState (unew->sref, oldState);
7492     }
7493   else if (newState == NS_POSNULL)
7494     {
7495       if (oldState == NS_MNOTNULL 
7496           && (ctype_isUA (unew->utype) 
7497               || (uentry_isFunction (unew)
7498                   && ctype_isUA (ctype_getReturnType (unew->utype)))))
7499         {
7500           if (uentry_isVar (unew))
7501             {
7502               unew->info->var->nullstate = oldState;
7503             }
7504
7505           sRef_mergeNullState (unew->sref, oldState);
7506         }
7507       else 
7508         {
7509           if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL 
7510               || oldState == NS_UNKNOWN)
7511             {
7512               if (mustConform)
7513                 {
7514                   if (optgenerror 
7515                       (FLG_INCONDEFS,
7516                        message 
7517                        ("%s %q inconsistently %rdeclared %s possibly null storage, "
7518                         "%s %q qualifier",
7519                         uentry_ekindName (unew),
7520                         uentry_getName (unew),
7521                         uentry_isDeclared (old),
7522                         fcnErrName (unew),
7523                         uentry_specOrDefName (old),
7524                         cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7525                        uentry_whereDeclared (unew)))
7526                     {
7527                       uentry_showWhereSpecified (old);
7528                     }
7529                 }
7530             }
7531           
7532           if (uentry_isVar (old))
7533             {
7534               old->info->var->nullstate = newState;
7535             }
7536
7537           sRef_mergeNullState (old->sref, newState);
7538         }
7539     }
7540   else if (newState == NS_MNOTNULL)
7541     {
7542       if (oldState != NS_MNOTNULL)
7543         {
7544           if (mustConform)
7545             {
7546               if (optgenerror 
7547                   (FLG_INCONDEFS,
7548                    message ("%s %q inconsistently %rdeclared %s notnull storage, "
7549                             "%s without notnull qualifier",
7550                             uentry_ekindName (unew),
7551                             uentry_getName (unew),
7552                             uentry_isDeclared (old),
7553                             fcnErrName (unew),
7554                             uentry_specOrDefName (old)),
7555                    uentry_whereDeclared (unew)))
7556                 {
7557                   uentry_showWhereSpecified (old);
7558                 }
7559             }
7560           
7561           if (uentry_isVar (old))
7562             {
7563               old->info->var->nullstate = newState;
7564             }
7565
7566           sRef_mergeNullState (old->sref, newState);
7567         }
7568     }
7569   else
7570     {
7571       if (uentry_isVar (unew)) 
7572         {
7573           unew->info->var->nullstate = oldState;
7574         }
7575
7576       sRef_mergeNullState (unew->sref, oldState);
7577     }
7578 }
7579
7580 static
7581 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7582                     bool mustConform, bool completeConform)
7583 {
7584   sstate oldState;
7585   sstate newState;
7586   bool vars = FALSE;
7587
7588   if (uentry_isVar (old) && uentry_isVar (unew))
7589     {
7590       oldState = old->info->var->defstate;
7591       newState = unew->info->var->defstate;
7592       vars = TRUE;
7593     }
7594   else
7595     {
7596       oldState = sRef_getDefState (old->sref);
7597       newState = sRef_getDefState (unew->sref);
7598     }
7599
7600   if (newState != oldState 
7601       && newState != SS_UNKNOWN 
7602       && newState != SS_DEFINED)
7603     {
7604       if (mustConform)
7605         {
7606           if (optgenerror 
7607               (FLG_INCONDEFS,
7608                message ("%s %q inconsistently %rdeclared %s %s %s, "
7609                         "%s %s %s %s",
7610                         uentry_ekindName (unew),
7611                         uentry_getName (unew),
7612                         uentry_isDeclared (old),
7613                         fcnErrName (unew),
7614                         sstate_unparse (newState),
7615                         paramStorageName (unew),
7616                         uentry_specOrDefName (old),
7617                         fcnErrName (unew),
7618                         sstate_unparse (oldState),
7619                         paramStorageName (unew)),
7620                uentry_whereDeclared (unew)))
7621             {
7622               uentry_showWhereSpecified (old);
7623             }
7624         }
7625
7626       if (vars) old->info->var->defstate = newState;
7627       sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7628     }
7629   else
7630     {
7631       if (completeConform
7632           && (newState != oldState) && (oldState != SS_DEFINED)
7633           && uentry_isReallySpecified (old))
7634         {
7635           if (optgenerror 
7636               (FLG_NEEDSPEC,
7637                message ("%s %q specified as %s, but declared without %s qualifier",
7638                         ekind_capName (unew->ukind),
7639                         uentry_getName (unew),
7640                         sstate_unparse (oldState),
7641                         sstate_unparse (oldState)),
7642                uentry_whereDeclared (unew)))
7643             {
7644               uentry_showWhereSpecified (old);
7645             }
7646         }
7647       
7648       if (vars) unew->info->var->defstate = oldState;
7649       sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7650     }
7651 }
7652
7653 static void 
7654   checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7655                    bool mustConform, bool completeConform)
7656 {
7657   alkind newKind;
7658   alkind oldKind;
7659
7660   oldKind = sRef_getAliasKind (old->sref);
7661   newKind = sRef_getAliasKind (unew->sref);
7662
7663   if (alkind_isImplicit (newKind) 
7664       || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7665     {
7666       if (completeConform && !alkind_equal (newKind, oldKind)
7667           && uentry_isReallySpecified (old))
7668         {
7669           if (optgenerror 
7670               (FLG_NEEDSPEC,
7671                message ("%s %q specified as %s, but declared without "
7672                         "explicit alias qualifier",
7673                         ekind_capName (unew->ukind),
7674                         uentry_getName (unew),
7675                         alkind_unparse (oldKind)),
7676                uentry_whereDeclared (unew)))
7677             {
7678               uentry_showWhereSpecified (old);
7679             }
7680         }
7681
7682       /*  
7683       ** This really shouldn't be necessary, but it is!
7684       ** Function params (?) use new here.
7685       */
7686
7687       sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7688       return;
7689     }
7690
7691   if (alkind_isKnown (newKind))
7692     {
7693       if (!alkind_equal (oldKind, newKind))
7694         {
7695           if (alkind_isKnown (oldKind))
7696             {
7697               if (mustConform && 
7698                   optgenerror 
7699                   (FLG_INCONDEFS,
7700                    message ("%s %q inconsistently %rdeclared %s %s storage, "
7701                             "%s as %s storage",
7702                             uentry_ekindName (unew),
7703                             uentry_getName (unew),
7704                             uentry_isDeclared (old),
7705                             fcnErrName (unew),
7706                             alkind_unparse (newKind),
7707                             uentry_specOrDefName (old),
7708                             alkind_unparse (oldKind)),
7709                    uentry_whereDeclared (unew)))
7710                 {
7711                   uentry_showWhereSpecified (old);
7712
7713                   DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7714                   DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7715                   sRef_setAliasKind (old->sref, AK_ERROR, 
7716                                      uentry_whereDeclared (unew));
7717                 }
7718               else
7719                 {
7720                   sRef_setAliasKind (old->sref, newKind, 
7721                                      uentry_whereDeclared (unew));
7722                 }
7723             }
7724           else
7725             {
7726               if (!(alkind_isImplicit (newKind)))
7727                 {
7728                   if (mustConform &&
7729                       !uentry_isFunction (unew) &&
7730                       optgenerror 
7731                       (FLG_INCONDEFS,
7732                        message ("%s %q inconsistently %rdeclared %s %s storage, "
7733                                 "implicitly %s as temp storage",
7734                                 uentry_ekindName (unew),
7735                                 uentry_getName (unew),
7736                                 uentry_isDeclared (old),
7737                                 fcnErrName (unew),
7738                                 alkind_unparse (newKind),
7739                                 uentry_specOrDefName (old)),
7740                        uentry_whereDeclared (unew)))
7741                     {
7742                       uentry_showWhereSpecified (old);
7743                       oldKind = AK_ERROR;
7744                     }
7745                   
7746                   sRef_setAliasKind (old->sref, newKind, 
7747                                      uentry_whereDeclared (unew));
7748                 }
7749               else /* newKind is temp or refcounted */
7750                 {
7751                   ;
7752                 }
7753             }
7754         }
7755     }
7756   else /* newKind unknown */
7757     {
7758       ;
7759     }
7760 }
7761
7762 static void 
7763   checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7764                 bool mustConform, bool completeConform)
7765 {
7766   exkind newKind;
7767   exkind oldKind;
7768   
7769   oldKind = sRef_getExKind (old->sref);
7770   newKind = sRef_getExKind (unew->sref);
7771
7772   if (exkind_isKnown (newKind))
7773     {
7774       if (oldKind != newKind)
7775         {
7776           if (exkind_isKnown (oldKind))
7777             {
7778               if (mustConform && 
7779                   optgenerror 
7780                   (FLG_INCONDEFS,
7781                    message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7782                             uentry_ekindName (unew),
7783                             uentry_getName (unew),
7784                             uentry_isDeclared (old),
7785                             fcnErrName (unew),
7786                             exkind_unparse (newKind),
7787                             uentry_specOrDefName (old),
7788                             exkind_unparse (oldKind)),
7789                    uentry_whereDeclared (unew)))
7790                 {
7791                   uentry_showWhereSpecified (old);
7792                 }
7793
7794               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7795             }
7796           else
7797             {
7798               if (mustConform &&
7799                   optgenerror 
7800                   (FLG_INCONDEFS,
7801                    message ("%s %q inconsistently %rdeclared %s %s, "
7802                             "implicitly %s without exposure qualifier",
7803                             uentry_ekindName (unew),
7804                             uentry_getName (unew),
7805                             uentry_isDeclared (old),
7806                             fcnErrName (unew),
7807                             exkind_unparse (newKind),
7808                             uentry_specOrDefName (old)),
7809                    uentry_whereDeclared (unew)))
7810                 {
7811                   uentry_showWhereSpecified (old);
7812                 }
7813
7814               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7815             }
7816         }
7817     }
7818   else
7819     {
7820       if (completeConform && exkind_isKnown (oldKind)
7821           && uentry_isReallySpecified (old))
7822         {
7823           if (optgenerror 
7824               (FLG_NEEDSPEC,
7825                message ("%s %q specified as %s, but declared without "
7826                         "exposure qualifier",
7827                         ekind_capName (unew->ukind),
7828                         uentry_getName (unew),
7829                         exkind_unparse (oldKind)),
7830                uentry_whereDeclared (unew)))
7831             {
7832               uentry_showWhereSpecified (old);
7833             }
7834         }
7835
7836       /* yes, this is necessary! (if its a param) */
7837       sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7838     }
7839 }
7840
7841 static void 
7842 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7843                 bool mustConform, /*@unused@*/ bool completeConform)
7844 {
7845   valueTable newvals = sRef_getValueTable (unew->sref);
7846
7847   if (valueTable_isDefined (newvals))
7848     {
7849       DPRINTF (("Check meta state: %s -> %s",
7850                 uentry_unparseFull (old),
7851                 uentry_unparseFull (unew)));
7852       
7853       DPRINTF (("Check meta state refs: %s -> %s",
7854                 sRef_unparseFull (old->sref),
7855                 sRef_unparseFull (unew->sref)));
7856       
7857       DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7858       
7859       /*
7860       ** Copy the new values into the old ref
7861       */
7862
7863       valueTable_elements (newvals, key, newval)
7864         {
7865           metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7866           stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7867             
7868           llassert (metaStateInfo_isDefined (msinfo));
7869
7870           if (stateValue_isUndefined (oldval))
7871             {
7872               sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7873             }
7874           else
7875             {
7876               if (stateValue_isError (oldval))
7877                 {
7878                   if (!stateValue_isError (newval))
7879                     {
7880                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7881                     }
7882                   else
7883                     {
7884                       ; /* No change necessary. */
7885                     }
7886                 }
7887               else
7888                 {
7889                   if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7890                     {
7891                       if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7892                         {
7893                           ;
7894                         }
7895                       else
7896                         {
7897                           if (!stateValue_isError (newval) 
7898                               && !stateValue_isImplicit (newval))
7899                             {
7900                               if (uentry_hasName (unew)
7901                                   || !sRef_isParam (uentry_getSref (unew)))
7902                                 {
7903                                   if (mustConform 
7904                                       && optgenerror 
7905                                       (FLG_INCONDEFS,
7906                                        message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7907                                                 uentry_ekindName (unew),
7908                                                 uentry_getName (unew),
7909                                                 uentry_isDeclared (old),
7910                                                 fcnErrName (unew),
7911                                                 stateValue_unparseValue (newval, msinfo),
7912                                                 uentry_specOrDefName (old),
7913                                                 stateValue_unparseValue (oldval, msinfo)),
7914                                        uentry_whereDeclared (unew)))
7915                                     {
7916                                       uentry_showWhereSpecified (old);
7917                                     }
7918                                 }
7919                               else
7920                                 {
7921                                   if (mustConform 
7922                                       && optgenerror 
7923                                       (FLG_INCONDEFS,
7924                                        message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7925                                                 uentry_ekindName (unew),
7926                                                 sRef_getParam (uentry_getSref (unew)),
7927                                                 uentry_isDeclared (old),
7928                                                 fcnErrName (unew),
7929                                                 stateValue_unparseValue (newval, msinfo),
7930                                                 uentry_specOrDefName (old),
7931                                                 stateValue_unparseValue (oldval, msinfo)),
7932                                        uentry_whereDeclared (unew)))
7933                                     {
7934                                       uentry_showWhereSpecified (old);
7935                                     }
7936                                 }
7937                             }
7938                         }
7939                       
7940                       DPRINTF (("Updating!"));
7941                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7942                     }
7943                   else
7944                     {
7945                       DPRINTF (("Values match"));
7946                     }
7947                 }
7948             }
7949         } end_valueTable_elements ;
7950     }
7951 }
7952
7953 static void
7954 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7955                               /*@notnull@*/ uentry unew,
7956                               bool mustConform, bool completeConform)
7957 {
7958   checkDefState (old, unew, mustConform, completeConform);
7959   checkNullState (old, unew, mustConform, completeConform);
7960   checkAliasState (old, unew, mustConform, completeConform);
7961   checkExpState (old, unew, mustConform, completeConform);
7962   checkMetaState (old, unew, mustConform, completeConform);
7963
7964   sRef_storeState (old->sref);
7965   sRef_storeState (unew->sref);
7966 }
7967
7968 static void
7969 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7970 {
7971   if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7972     {
7973       return;
7974     }
7975
7976   llassert (uentry_isVar (old));
7977   llassert (uentry_isVar (unew));
7978
7979   if (cstring_isEmpty (old->uname)) 
7980     {
7981       cstring_free (old->uname);
7982       old->uname = cstring_copy (unew->uname);
7983     }
7984
7985   if (unew->info->var->kind == VKRETPARAM
7986       || unew->info->var->kind == VKSEFRETPARAM)
7987     {
7988       if (old->info->var->kind != VKRETPARAM
7989           && old->info->var->kind != VKSEFRETPARAM)
7990         {
7991           if (optgenerror 
7992               (FLG_INCONDEFS,
7993                message ("Parameter %q inconsistently %rdeclared as "
7994                         "returned parameter",
7995                         uentry_getName (unew),
7996                         uentry_isDeclared (old)),
7997                uentry_whereDeclared (unew)))
7998             {
7999               uentry_showWhereSpecified (old);
8000               old->info->var->kind = unew->info->var->kind;
8001             }
8002         }
8003     }
8004
8005
8006   if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8007     {
8008       if (old->info->var->kind != VKSEFPARAM 
8009           && old->info->var->kind != VKSEFRETPARAM)
8010         {
8011           if (optgenerror 
8012               (FLG_INCONDEFS,
8013                message ("Parameter %qinconsistently %rdeclared as "
8014                         "sef parameter",
8015                         uentry_getOptName (unew),
8016                         uentry_isDeclared (old)),
8017                uentry_whereDeclared (unew)))
8018             {
8019               uentry_showWhereSpecified (old);
8020               old->info->var->kind = unew->info->var->kind;
8021             }
8022         }
8023     }
8024
8025   if (old->info->var->kind == VKSPEC)
8026     {
8027       old->info->var->kind = unew->info->var->kind;
8028     }
8029   else
8030     {
8031       unew->info->var->kind = old->info->var->kind;
8032     }
8033
8034   if (unew->info->var->checked != CH_UNKNOWN
8035       && unew->info->var->checked != old->info->var->checked)
8036     {
8037       if (old->info->var->checked == CH_UNKNOWN
8038           && !fileloc_isUser (uentry_whereLast (old)))
8039         {
8040           ; /* no error */
8041         }
8042       else
8043         {
8044           if (optgenerror 
8045               (FLG_INCONDEFS,
8046                message ("Variable %q inconsistently %rdeclared as "
8047                         "%s parameter (was %s)",
8048                         uentry_getName (unew),
8049                         uentry_isDeclared (old),
8050                         checkedName (unew->info->var->checked),
8051                         checkedName (old->info->var->checked)),
8052                uentry_whereDeclared (unew)))
8053             {
8054               uentry_showWhereSpecified (old);
8055             }
8056         }
8057       
8058       old->info->var->checked = unew->info->var->checked;
8059     }
8060   else
8061     {
8062       if (completeConform 
8063           && (old->info->var->checked != CH_UNKNOWN)
8064           && uentry_isReallySpecified (old))
8065         {
8066           if (optgenerror 
8067               (FLG_NEEDSPEC,
8068                message ("%s %q specified as %s, but declared without %s qualifier",
8069                         ekind_capName (unew->ukind),
8070                         uentry_getName (unew),
8071                         checkedName (old->info->var->checked),
8072                         checkedName (old->info->var->checked)),
8073                uentry_whereDeclared (unew)))
8074             {
8075               uentry_showWhereSpecified (old);
8076             }
8077         }
8078       
8079       unew->info->var->checked = old->info->var->checked;
8080     }
8081
8082   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8083 }
8084
8085 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8086 {
8087   if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8088     {
8089       return;
8090     }
8091
8092   llassert (uentry_isVar (u1));
8093   llassert (uentry_isVar (u2));
8094
8095   if (u1->info->var->kind != u2->info->var->kind) {
8096     if (u1->info->var->kind == VKSEFRETPARAM) {
8097       if (u2->info->var->kind == VKRETPARAM) {
8098         voptgenerror 
8099           (FLG_TYPE,
8100            message ("Function types are inconsistent. Parameter %d is "
8101                     "sef parameter, but non-sef parameter in "
8102                     "assigned function: %s",
8103                     paramno, exprNode_unparse (e)),
8104            exprNode_loc (e));
8105       } else if (u2->info->var->kind == VKSEFPARAM) {
8106         voptgenerror 
8107           (FLG_TYPE,
8108            message ("Function types are inconsistent. Parameter %d is "
8109                     "returns parameter, but non-returns parameter in "
8110                     "assigned function: %s",
8111                     paramno, exprNode_unparse (e)),
8112            exprNode_loc (e));
8113       } else {
8114         voptgenerror 
8115           (FLG_TYPE,
8116            message ("Function types are inconsistent. Parameter %d is "
8117                     "sef returns parameter, but non-sef returns parameter in "
8118                     "assigned function: %s",
8119                     paramno, exprNode_unparse (e)),
8120            exprNode_loc (e));
8121       }
8122     } else if (u1->info->var->kind == VKRETPARAM) {
8123       voptgenerror 
8124         (FLG_TYPE,
8125          message ("Function types are inconsistent. Parameter %d is "
8126                   "returns parameter, but non-returns parameter in "
8127                   "assigned function: %s",
8128                   paramno, exprNode_unparse (e)),
8129          exprNode_loc (e));
8130     } else if (u1->info->var->kind == VKSEFPARAM) {
8131       voptgenerror 
8132         (FLG_TYPE,
8133          message ("Function types are inconsistent. Parameter %d is "
8134                   "sef parameter, but non-sef parameter in "
8135                   "assigned function: %s",
8136                   paramno, exprNode_unparse (e)),
8137          exprNode_loc (e));
8138     } else {
8139       if (u2->info->var->kind == VKSEFRETPARAM) {
8140         voptgenerror 
8141           (FLG_TYPE,
8142            message ("Function types are inconsistent. Parameter %d is "
8143                     "normal parameter, but sef returns parameter in "
8144                     "assigned function: %s",
8145                     paramno, exprNode_unparse (e)),
8146            exprNode_loc (e));
8147       } else if (u2->info->var->kind == VKSEFPARAM) {
8148         voptgenerror 
8149           (FLG_TYPE,
8150            message ("Function types are inconsistent. Parameter %d is "
8151                     "normal parameter, but sef parameter in "
8152                     "assigned function: %s",
8153                     paramno, exprNode_unparse (e)),
8154            exprNode_loc (e));
8155       } else if (u2->info->var->kind == VKRETPARAM) {
8156         voptgenerror 
8157           (FLG_TYPE,
8158            message ("Function types are inconsistent. Parameter %d is "
8159                     "normal parameter, but returns parameter in "
8160                     "assigned function: %s",
8161                     paramno, exprNode_unparse (e)),
8162            exprNode_loc (e));
8163       } else {
8164         BADBRANCH;
8165       }
8166     }
8167   }
8168
8169   if (u1->info->var->defstate != u2->info->var->defstate) 
8170     {
8171       voptgenerror 
8172         (FLG_TYPE,
8173          message ("Function types are inconsistent. Parameter %d is "
8174                   "%s, but %s in assigned function: %s",
8175                   paramno, 
8176                   sstate_unparse (u1->info->var->defstate),
8177                   sstate_unparse (u2->info->var->defstate),
8178                   exprNode_unparse (e)),
8179          exprNode_loc (e));
8180     }
8181
8182   if (u1->info->var->nullstate != u2->info->var->nullstate) 
8183     {
8184       voptgenerror 
8185         (FLG_TYPE,
8186          message ("Function types are inconsistent. Parameter %d is "
8187                   "%s, but %s in assigned function: %s",
8188                   paramno, 
8189                   nstate_unparse (u1->info->var->nullstate),
8190                   nstate_unparse (u2->info->var->nullstate),
8191                   exprNode_unparse (e)),
8192          exprNode_loc (e));
8193     }
8194       
8195   if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8196     {
8197       voptgenerror 
8198         (FLG_TYPE,
8199          message ("Function types are inconsistent. Parameter %d is "
8200                   "%s, but %s in assigned function: %s",
8201                   paramno, 
8202                   alkind_unparse (sRef_getAliasKind (u1->sref)),
8203                   alkind_unparse (sRef_getAliasKind (u2->sref)),
8204                   exprNode_unparse (e)),
8205          exprNode_loc (e));
8206     }
8207
8208   if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8209     {
8210       voptgenerror 
8211         (FLG_TYPE,
8212          message ("Function types are inconsistent. Parameter %d is "
8213                   "%s, but %s in assigned function: %s",
8214                   paramno, 
8215                   exkind_unparse (sRef_getExKind (u1->sref)),
8216                   exkind_unparse (sRef_getExKind (u2->sref)),
8217                   exprNode_unparse (e)),
8218          exprNode_loc (e));
8219     }
8220 }
8221
8222 static void
8223 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8224                           /*@notnull@*/ uentry unew, 
8225                           bool mustConform, /*@unused@*/ bool completeConform)
8226 {
8227   uentryList oldParams  = uentry_getParams (old);
8228   uentryList newParams  = uentry_getParams (unew);
8229   ctype      newType    = unew->utype;
8230   ctype      oldType    = old->utype;
8231   ctype      oldRetType = ctype_unknown;
8232   ctype      newRetType = ctype_unknown;
8233
8234   DPRINTF (("Function conform: %s ==> %s",
8235             uentry_unparseFull (old),
8236             uentry_unparseFull (unew)));
8237
8238   if (uentry_isForward (old))
8239     {
8240       mustConform = FALSE;
8241       uentry_updateInto (old, unew);
8242       return;
8243     }
8244
8245   /*
8246   ** check return values
8247   */
8248   
8249   if (ctype_isKnown (oldType))
8250     {
8251       llassert (ctype_isFunction (oldType));
8252
8253       oldRetType = ctype_getReturnType (oldType);
8254     }
8255
8256   if (ctype_isKnown (newType))
8257     {
8258       llassert (ctype_isFunction (newType));
8259
8260       newRetType = ctype_getReturnType (newType);
8261     }
8262
8263   if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8264       && !ctype_matchDef (newRetType, oldRetType))
8265     {
8266       if (mustConform) returnValueError (old, unew);
8267     }
8268   else 
8269     {
8270       if (ctype_isConj (newRetType))
8271         {
8272           if (ctype_isConj (oldRetType))
8273             {
8274               if (!ctype_sameAltTypes (newRetType, oldRetType))
8275                 {
8276                   if (optgenerror 
8277                       (FLG_INCONDEFS,
8278                        message ("Function %q inconsistently %rdeclared to "
8279                                 "return alternate types %s "
8280                                 "(types match, but alternates are not identical, "
8281                                 "so checking may not be correct)",
8282                                 uentry_getName (unew),
8283                                 uentry_isDeclared (old),
8284                                 ctype_unparse (newRetType)),
8285                        uentry_whereDeclared (unew)))
8286                     {
8287                       uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8288                     }
8289                 }
8290             }
8291           else
8292             {
8293               old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8294             }
8295         }
8296     }
8297
8298   DPRINTF (("Before state: %s",
8299             uentry_unparseFull (old)));
8300   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8301   DPRINTF (("After state: %s",
8302             uentry_unparseFull (old)));
8303
8304   if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8305     {
8306       if (exitkind_isKnown (unew->info->fcn->exitCode))
8307         {
8308           if (optgenerror 
8309               (FLG_INCONDEFS,
8310                message ("Function %q inconsistently %rdeclared using %s",
8311                         uentry_getName (unew),
8312                         uentry_isDeclared (old),
8313                         exitkind_unparse (unew->info->fcn->exitCode)),
8314                uentry_whereDeclared (unew)))
8315             {
8316               uentry_showWhereSpecified (old);
8317             }
8318         }
8319       else
8320         {
8321           unew->info->fcn->exitCode = old->info->fcn->exitCode;
8322         }
8323     }
8324
8325   if (!qual_isUnknown (unew->info->fcn->nullPred))
8326     {
8327       if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8328         {
8329           if (optgenerror
8330               (FLG_INCONDEFS,
8331                message ("Function %q inconsistently %rdeclared using %s",
8332                         uentry_getName (unew),
8333                         uentry_isDeclared (old),
8334                         qual_unparse (unew->info->fcn->nullPred)),
8335                uentry_whereDeclared (unew)))
8336             {
8337               uentry_showWhereSpecified (old);
8338             }
8339         }
8340     }
8341   else
8342     {
8343       unew->info->fcn->nullPred = old->info->fcn->nullPred;
8344     }
8345
8346   if (unew->info->fcn->specialCode != SPC_NONE)
8347     {
8348       if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8349         {
8350           if (optgenerror
8351               (FLG_INCONDEFS,
8352                message ("Function %q inconsistently %rdeclared using %s",
8353                         uentry_getName (unew),
8354                         uentry_isDeclared (old),
8355                         specCode_unparse (unew->info->fcn->specialCode)),
8356                uentry_whereDeclared (unew)))
8357             {
8358               uentry_showWhereSpecified (old);
8359             }
8360         }
8361     }
8362   else
8363     {
8364       unew->info->fcn->specialCode = old->info->fcn->specialCode;
8365     }
8366           
8367   /*
8368   ** check parameters
8369   */
8370   
8371   if (!uentryList_sameObject (oldParams, newParams)
8372       && (!uentryList_isMissingParams (oldParams)))
8373     {
8374       if (!uentryList_isMissingParams (newParams))
8375         {
8376           int paramno = 0;
8377           int nparams = uentryList_size (oldParams);
8378           bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8379
8380           if (nparams != uentryList_size (newParams))
8381             {
8382               nargsError (old, unew);
8383             }
8384           
8385           if (uentryList_size (newParams) < nparams) 
8386             {
8387               nparams = uentryList_size (newParams);
8388             }
8389
8390           while (paramno < nparams)
8391             {
8392               uentry oldCurrent = uentryList_getN (oldParams, paramno);
8393               uentry newCurrent  = uentryList_getN (newParams, paramno);
8394               ctype  oldCurrentType = uentry_getType (oldCurrent);
8395               ctype  newCurrentType = uentry_getType (newCurrent);
8396
8397               llassert (uentry_isValid (oldCurrent)
8398                         && uentry_isValid (newCurrent));
8399               
8400               if (!uentry_isElipsisMarker (oldCurrent)
8401                   && !uentry_isElipsisMarker (newCurrent))
8402                 {
8403                   checkVarConformance (oldCurrent, newCurrent, 
8404                                        mustConform, completeConform);
8405                 }
8406
8407               if (checknames)
8408                 {
8409                   if (uentry_hasName (oldCurrent) 
8410                       && uentry_hasName (newCurrent))
8411                     {
8412                       cstring oldname = uentry_getName (oldCurrent);
8413                       cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8414                       cstring oname;
8415                       cstring nname = uentry_getName (newCurrent);
8416                       cstring nnamefix;
8417
8418                       if (cstring_isDefined (pfx)
8419                           && cstring_equalPrefix (oldname, pfx))
8420                         {
8421                           oname = cstring_suffix (oldname, cstring_length (pfx));
8422                         }
8423                       else
8424                         {
8425                           oname = oldname;
8426                         /*@-branchstate@*/ } /*@=branchstate@*/
8427
8428                       if (cstring_isDefined (pfx)
8429                           && cstring_equalPrefix (nname, pfx))
8430                         {
8431                           nnamefix = cstring_suffix (nname, cstring_length (pfx));
8432                         }
8433                       else
8434                         {
8435                           nnamefix = nname;
8436                         /*@-branchstate@*/ } /*@=branchstate@*/
8437
8438                       if (!cstring_equal (oname, nnamefix))
8439                         {
8440                           if (optgenerror
8441                               (FLG_DECLPARAMMATCH, 
8442                                message ("Definition parameter name %s does not match "
8443                                         "name of corresponding parameter in "
8444                                         "declaration: %s",
8445                                         nnamefix, oname),
8446                                uentry_whereLast (newCurrent)))
8447                             {
8448                               uentry_showWhereLastPlain (oldCurrent);
8449                             }
8450                         }
8451                       
8452                       cstring_free (oldname);
8453                       cstring_free (nname);
8454                     }
8455                 }
8456
8457               if (!ctype_match (oldCurrentType, newCurrentType))
8458                 {
8459                   paramTypeError (old, oldCurrent, oldCurrentType,
8460                                   unew, newCurrent, newCurrentType, paramno);
8461                 }
8462               else
8463                 {
8464                   if (ctype_isMissingParamsMarker (newCurrentType)
8465                       || ctype_isElips (newCurrentType)
8466                       || ctype_isMissingParamsMarker (oldCurrentType)
8467                       || ctype_isElips (oldCurrentType))
8468                     {
8469                       ;
8470                     }
8471                   else
8472                     {
8473                       if (ctype_isConj (newCurrentType))
8474                         {
8475                           if (ctype_isConj (oldCurrentType))
8476                             {
8477                               if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8478                                 {
8479                                   if (optgenerror 
8480                                       (FLG_INCONDEFS,
8481                                        message ("Parameter %q inconsistently %rdeclared with "
8482                                                 "alternate types %s "
8483                                                 "(types match, but alternates are not identical, "
8484                                                 "so checking may not be correct)",
8485                                                 uentry_getName (newCurrent),
8486                                                 uentry_isDeclared (oldCurrent),
8487                                                 ctype_unparse (newCurrentType)),
8488                                        uentry_whereDeclared (unew)))
8489                                     {
8490                                       uentry_showWhereLastVal (oldCurrent,
8491                                                                ctype_unparse (oldCurrentType));
8492                                     }
8493                                 }
8494                             }
8495                           else
8496                             {
8497                               if (optgenerror 
8498                                   (FLG_INCONDEFS,
8499                                    message ("Parameter %q inconsistently %rdeclared with "
8500                                             "alternate types %s",
8501                                             uentry_getName (newCurrent),
8502                                             uentry_isDeclared (oldCurrent),
8503                                             ctype_unparse (newCurrentType)),
8504                                    uentry_whereDeclared (unew)))
8505                                 {
8506                                   uentry_showWhereLastVal (oldCurrent,
8507                                                            ctype_unparse (oldCurrentType));
8508                                   
8509                                 }
8510                             }
8511                         }
8512                       else 
8513                         {
8514                           if (ctype_isConj (oldCurrentType))
8515                             {
8516                               uentry_setType (newCurrent, oldCurrentType);
8517                             }
8518                         }
8519                     }
8520                 }
8521
8522               paramno++;  
8523               /*
8524                ** Forgot this!  detected by lclint:
8525                ** uentry.c:1257,15: Suspected infinite loop
8526                */
8527             }
8528         }
8529     }
8530
8531   if (!uentryList_isMissingParams (newParams))
8532     {
8533       if (ctype_isConj (oldRetType))
8534         {
8535           old->utype = ctype_makeFunction (oldRetType, 
8536                                            uentryList_copy (newParams));
8537         }
8538       else
8539         {
8540           old->utype = unew->utype;
8541         }
8542     }
8543
8544   checkGlobalsConformance (old, unew, mustConform, completeConform);
8545   checkModifiesConformance (old, unew, mustConform, completeConform);
8546
8547   DPRINTF (("Before list: %s",
8548             uentry_unparseFull (old)));
8549
8550   if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8551     {
8552       if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8553         {
8554           /*
8555           if (optgenerror
8556               (FLG_INCONDEFS,
8557                message ("Function %q redeclared using special clauses (can only "
8558                         "be used in first declaration)",
8559                         uentry_getName (unew)),
8560                uentry_whereDeclared (unew)))
8561             {
8562               uentry_showWhereLast (old);
8563             }
8564           */
8565
8566           /*@i23 need checking @*/ 
8567
8568           old->info->fcn->specclauses = unew->info->fcn->specclauses;
8569         }
8570       else
8571         {
8572           /*@i43 should be able to append? @*/
8573
8574           stateClauseList_checkEqual (old, unew);
8575           stateClauseList_free (unew->info->fcn->specclauses);
8576           unew->info->fcn->specclauses = stateClauseList_undefined;
8577           /*@-branchstate@*/ 
8578         }
8579       /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8580     }
8581
8582   if (fileloc_isUndefined (old->whereDeclared))
8583     {
8584       old->whereDeclared = fileloc_copy (unew->whereDeclared);
8585     }
8586   else if (fileloc_isUndefined (unew->whereDeclared))
8587     {
8588       unew->whereDeclared = fileloc_copy (old->whereDeclared);
8589     }
8590   else
8591     {
8592       /* no change */
8593     }
8594 }
8595
8596 void
8597 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8598 {
8599   multiVal uval;
8600
8601   llassert (uentry_isValid (ue));
8602   llassert (uentry_isEitherConstant (ue));
8603
8604   DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8605   uval = uentry_getConstantValue (ue);
8606
8607   if (multiVal_isDefined (uval))
8608     {
8609       if (multiVal_isDefined (m))
8610         {
8611           if (!multiVal_equiv (uval, m))
8612             {
8613               if (optgenerror 
8614                   (FLG_INCONDEFS,
8615                    message ("%s %q defined with inconsistent value: %q",
8616                             ekind_capName (ue->ukind),
8617                             uentry_getName (ue), 
8618                             multiVal_unparse (m)),
8619                    g_currentloc))
8620                 {
8621                   uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8622                 }
8623             }
8624         }
8625       multiVal_free (m);
8626     }
8627   else
8628     {
8629       uentry_setConstantValue (ue, m);
8630     }
8631 }
8632
8633 static
8634 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
8635                            bool mustConform)
8636 {
8637   bool typeError = FALSE;
8638
8639   if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8640     {
8641       if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8642         {
8643           if (mustConform)
8644             {
8645               DPRINTF (("Check struct conformance: %s / %s",
8646                         uentry_unparseFull (old),
8647                         uentry_unparseFull (unew)));
8648               checkStructConformance (old, unew); 
8649             }
8650         }
8651       else
8652         {
8653           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8654             {
8655               llbug (message ("struct tags: bad types: %t / %t", 
8656                               old->utype, unew->utype));
8657             }
8658         }
8659     }
8660   else if (uentry_isEnumTag (old))
8661     {
8662       if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8663         {
8664           if (mustConform) checkEnumConformance (old, unew);
8665         }
8666       else 
8667         {
8668           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8669             {
8670               llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8671                               ctype_unparse (unew->utype)));
8672             }
8673         }
8674     }
8675   else if (!ctype_match (old->utype, unew->utype))
8676     {
8677       DPRINTF (("Type mismatch: %s / %s",
8678                 ctype_unparse (old->utype),
8679                 ctype_unparse (unew->utype)));
8680
8681       if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8682         {
8683           ctype realt = ctype_realType (unew->utype);
8684           
8685           if (ctype_isRealInt (realt) || ctype_isChar (realt))
8686             {
8687               unew->utype = ctype_bool;
8688             }
8689           else
8690             {
8691               if (mustConform)
8692                 {
8693                   typeError = optgenerror
8694                     (FLG_INCONDEFS,
8695                      message ("%q defined as %s", uentry_getName (old), 
8696                               ctype_unparse (realt)),
8697                      uentry_whereDeclared (unew));
8698                 }
8699             }
8700         } 
8701       else 
8702         {
8703           if (mustConform)
8704             {
8705               ctype oldr = ctype_realType (old->utype);
8706               ctype newr = ctype_realType (unew->utype);
8707               
8708               if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8709                 {
8710                   checkStructConformance (old, unew);
8711                 }
8712               else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8713                 {
8714                   checkStructConformance (old, unew);
8715                 }
8716               else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8717                 {
8718                   checkEnumConformance (old, unew);
8719                 }
8720               else if (uentry_isConstant (old) 
8721                        && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8722                 {
8723                   /* okay...for now! (should check the type is reset later... */
8724                 }
8725               else
8726                 {
8727                   DPRINTF (("YABA!"));
8728                   if (optgenerror 
8729                       (FLG_INCONDEFS,
8730                        message ("%s %q %rdeclared with inconsistent type: %t",
8731                                 ekind_capName (unew->ukind),
8732                                 uentry_getName (unew), 
8733                                 uentry_isDeclared (old),
8734                                 unew->utype),
8735                        uentry_whereDeclared (unew)))
8736                     {
8737                       uentry_showWhereLast (old);
8738                       typeError = TRUE;
8739                     }
8740                 }
8741             }
8742         }
8743     }
8744   else
8745     {
8746       /* no error */
8747     }
8748
8749   return typeError;
8750 }
8751
8752 static void
8753 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8754                                  /*@notnull@*/ uentry unew,
8755                                  bool mustConform, bool completeConform)
8756 {
8757   if (ctype_isDefined (unew->info->datatype->type))
8758     {
8759       /*
8760       ** bool is hard coded here, since it is built into LCL.
8761       ** For now, we're stuck with LCL's types.
8762       */
8763
8764       if (ctype_isDirectBool (old->utype) &&
8765           cstring_equalLit (unew->uname, "bool"))
8766         {
8767           /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8768              evs 2000-07-25: removed
8769           */
8770               unew->utype = ctype_bool;
8771         }
8772       
8773       if (ctype_isUnknown (old->info->datatype->type))
8774         {
8775           old->info->datatype->type = unew->info->datatype->type;
8776         }
8777       else
8778         {
8779           DPRINTF (("Old: %s / New: %s",
8780                     uentry_unparseFull (old),
8781                     uentry_unparseFull (unew)));
8782           DPRINTF (("Types: %s / %s",
8783                     ctype_unparse (old->info->datatype->type),
8784                     ctype_unparse (unew->info->datatype->type)));
8785
8786           if (ctype_matchDef (old->info->datatype->type,
8787                               unew->info->datatype->type))
8788             {
8789               ;
8790             }
8791           else
8792             {
8793               if (optgenerror 
8794                   (FLG_INCONDEFS,
8795                    message
8796                    ("Type %q %s with inconsistent type: %t",
8797                     uentry_getName (unew), 
8798                     uentry_reDefDecl (old, unew),
8799                     unew->info->datatype->type),
8800                    uentry_whereDeclared (unew)))
8801                 {
8802                   uentry_showWhereLastExtra 
8803                     (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8804                 }
8805
8806               old->info->datatype->type = unew->info->datatype->type;
8807             }
8808         }
8809     }
8810   
8811   if (unew->info->datatype->abs != MAYBE)
8812     {
8813       if (ynm_isOff (old->info->datatype->abs)
8814           && ynm_isOn (unew->info->datatype->abs))
8815         {
8816           if (!ctype_isDirectBool (old->utype))
8817             {
8818               if (optgenerror 
8819                   (FLG_INCONDEFS,
8820                    message 
8821                    ("Datatype %q inconsistently %rdeclared as abstract type",
8822                     uentry_getName (unew), 
8823                     uentry_isDeclared (old)),
8824                    uentry_whereDeclared (unew)))
8825                 {
8826                   uentry_showWhereLastPlain (old);
8827                 }
8828             }
8829         }
8830       else if (ynm_isOn (old->info->datatype->abs)
8831                && ynm_isOff (unew->info->datatype->abs))
8832         {
8833           if (!ctype_isDirectBool (old->utype))
8834             {
8835               if (optgenerror 
8836                   (FLG_INCONDEFS,
8837                    message 
8838                    ("Datatype %q inconsistently %rdeclared as concrete type",
8839                     uentry_getName (unew), 
8840                     uentry_isDeclared (old)),
8841                    uentry_whereDeclared (unew)))
8842                 {
8843                   uentry_showWhereLastPlain (old);
8844                 }
8845             }
8846         }
8847       else
8848         {
8849           ;
8850         }
8851     }
8852   else 
8853     {
8854       if (ynm_isOn (old->info->datatype->abs))
8855         {
8856           old->sref = unew->sref;
8857           unew->info->datatype->mut = old->info->datatype->mut;
8858           
8859           if (completeConform
8860               && uentry_isReallySpecified (old))
8861             {
8862               if (optgenerror 
8863                   (FLG_NEEDSPEC,
8864                    message 
8865                    ("Datatype %q specified as abstract, "
8866                     "but abstract annotation not used in declaration",
8867                     uentry_getName (unew)), 
8868                    uentry_whereDeclared (unew)))
8869                 {
8870                   uentry_showWhereLastPlain (old);
8871                 }
8872             }
8873         }
8874     }
8875   
8876   unew->info->datatype->abs = old->info->datatype->abs;   
8877   
8878   if (ynm_isMaybe (unew->info->datatype->mut))
8879     {
8880       if (completeConform && ynm_isOff (old->info->datatype->mut)
8881           && uentry_isReallySpecified (old))
8882         {
8883           if (optgenerror 
8884               (FLG_NEEDSPEC,
8885                message 
8886                ("Datatype %q specified as immutable, "
8887                 "but immutable annotation not used in declaration",
8888                 uentry_getName (unew)), 
8889                uentry_whereDeclared (unew)))
8890             {
8891               uentry_showWhereLastPlain (old);
8892             }
8893         }
8894       
8895       unew->info->datatype->mut = old->info->datatype->mut;
8896     }
8897   else if (ynm_isMaybe (old->info->datatype->mut))
8898     {
8899       old->info->datatype->mut = unew->info->datatype->mut;
8900     }
8901   else
8902     {
8903       if (ynm_isOn (old->info->datatype->abs))
8904         {
8905           if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8906             {
8907               if (optgenerror
8908                   (FLG_INCONDEFS,
8909                    message ("Datatype %q inconsistently %rdeclared as immutable",
8910                             uentry_getName (unew), 
8911                             uentry_isDeclared (old)),
8912                    uentry_whereDeclared (unew)))
8913                 {
8914                   uentry_showWhereLastPlain (old);
8915                 }
8916             }
8917           else 
8918             {
8919               if (ynm_isOff (old->info->datatype->mut)
8920                   && ynm_isOn (unew->info->datatype->mut))
8921                 {
8922                   if (optgenerror
8923                       (FLG_INCONDEFS,
8924                        message ("Datatype %q inconsistently %rdeclared as mutable",
8925                                 uentry_getName (unew), 
8926                                 uentry_isDeclared (old)),
8927                        uentry_whereDeclared (unew)))
8928                     {
8929                       uentry_showWhereLastPlain (old);
8930                     }
8931                 }
8932             }
8933         }
8934       old->info->datatype->mut = unew->info->datatype->mut;       
8935     }
8936
8937   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8938 }
8939
8940 static void
8941 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8942                                  /*@notnull@*/ uentry unew,
8943                                  bool mustConform, 
8944                                  /*@unused@*/ bool completeConform)
8945 {
8946   multiVal oldval = uentry_getConstantValue (old);
8947   multiVal newval = uentry_getConstantValue (unew);
8948   
8949   if (multiVal_isDefined (oldval))
8950     {
8951       if (multiVal_isDefined (newval))
8952         {
8953           if (!multiVal_equiv (oldval, newval))
8954             {
8955               if (mustConform
8956                   && optgenerror 
8957                   (FLG_INCONDEFS,
8958                    message ("%s %q %rdeclared with inconsistent value: %q",
8959                             ekind_capName (unew->ukind),
8960                             uentry_getName (unew), 
8961                             uentry_isDeclared (old),
8962                             multiVal_unparse (newval)),
8963                    uentry_whereDeclared (unew)))
8964                 {
8965                   uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8966                 }
8967             }
8968           
8969           uentry_setConstantValue (unew, multiVal_copy (oldval));
8970         }
8971       else
8972         {
8973           ;
8974         }
8975     }
8976   else
8977     {
8978       uentry_setConstantValue (old, multiVal_copy (newval));
8979     }
8980 }
8981
8982 static void 
8983 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old, 
8984                          /*@notnull@*/ uentry unew, bool mustConform,
8985                          bool completeConform)
8986 {
8987   bool typeError = FALSE;
8988   bool fcnConformance = FALSE;
8989
8990   if (!ekind_equal (unew->ukind, old->ukind))
8991     {
8992       /*
8993       ** okay, only if one is a function and the other is
8994       ** a variable of type function.
8995       */
8996
8997       if (unew->ukind == KENUMCONST
8998           && old->ukind == KCONST)
8999         {
9000           old->ukind = KENUMCONST;
9001           goto nokinderror;
9002         }
9003
9004       if (unew->ukind == KFCN 
9005           && old->ukind == KCONST
9006           && ctype_isUnknown (old->utype))
9007         {
9008           /*
9009           ** When a function is defined with an unparam macro
9010           */
9011
9012           uentry_updateInto (old, unew);
9013           return;
9014         }
9015
9016       if (uentry_isExpandedMacro (old) 
9017           && uentry_isEitherConstant (unew))
9018         {
9019           uentry_updateInto (old, unew);
9020           return;
9021         }
9022
9023       if (uentry_isEndIter (unew))
9024         {
9025           if (ctype_isUnknown (old->utype))
9026             {
9027               if (!uentry_isSpecified (old)
9028                   && uentry_isCodeDefined (unew))
9029                 {
9030                   if (!fileloc_withinLines (uentry_whereDefined (old),
9031                                             uentry_whereDeclared (unew), 2))
9032                     { /* bogus!  will give errors if there is too much whitespace */
9033                       voptgenerror
9034                         (FLG_SYNTAX,
9035                          message
9036                          ("Iterator finalized name %q does not match name in "
9037                           "previous iter declaration (should be end_%q).  This iter "
9038                           "is declared at %q", 
9039                           uentry_getName (unew),
9040                           uentry_getName (old),
9041                           fileloc_unparse (uentry_whereDefined (old))),
9042                          uentry_whereDeclared (old));
9043                     }
9044                 }
9045
9046               uentry_updateInto (old, unew);
9047               return;
9048             }
9049           else
9050             {
9051               KindConformanceError (old, unew, mustConform);
9052             }
9053         }
9054
9055       if (uentry_isFunction (unew))
9056         {
9057           if (uentry_isVariable (old))
9058             {
9059               if (!ctype_isUnknown (old->utype))
9060                 {
9061                   if (ctype_isFunction (old->utype))
9062                     {
9063                       uentry_makeVarFunction (old);
9064                       checkFunctionConformance (old, unew, mustConform,
9065                                                 completeConform);
9066                       fcnConformance = TRUE;
9067                     }
9068                   else
9069                     {
9070                       KindConformanceError (old, unew, mustConform);
9071                     }
9072                 }
9073               else
9074                 {
9075                   if (uentry_isExpandedMacro (old))
9076                     {
9077                       if (fileloc_isUndefined (unew->whereDefined))
9078                         {
9079                           unew->whereDefined = fileloc_update (unew->whereDefined, 
9080                                                               old->whereDefined);
9081                         }
9082
9083                       uentry_updateInto (old, unew);
9084                       old->used = unew->used = TRUE;
9085                       return;
9086                     }
9087                   else
9088                     {
9089                       /* undeclared identifier */
9090                       old->utype = unew->utype;
9091                       uentry_makeVarFunction (old);
9092                       checkFunctionConformance (old, unew, FALSE, FALSE);
9093                       fcnConformance = TRUE;
9094                     }
9095                 }
9096             }
9097           else
9098             {
9099               KindConformanceError (old, unew, mustConform);
9100             }
9101         }
9102       else if (uentry_isFunction (old) && uentry_isVariable (unew))
9103         {
9104           if (!ctype_isUnknown (unew->utype))
9105             {
9106               if (ctype_isFunction (unew->utype))
9107                 {
9108                   uentry_makeVarFunction (unew);
9109                   checkFunctionConformance (old, unew, mustConform, completeConform);
9110                   fcnConformance = TRUE;
9111                 }
9112               else
9113                 {
9114                   KindConformanceError (old, unew, mustConform);
9115                 }
9116             }
9117           else
9118             {
9119               KindConformanceError (old, unew, mustConform);
9120             }
9121         }
9122       else
9123         {
9124           KindConformanceError (old, unew, mustConform);
9125         }
9126     }
9127   else
9128     {
9129       /*
9130       ** check parameter lists for functions 
9131       ** (before type errors, to get better messages
9132       */
9133
9134       if (uentry_isFunction (old))
9135         {
9136           checkFunctionConformance (old, unew, mustConform, completeConform);
9137           fcnConformance = TRUE;
9138         }
9139       else 
9140         {
9141           if (!ctype_isUndefined (old->utype))
9142             {
9143               typeError = checkTypeConformance (old, unew, mustConform);
9144             }
9145         }
9146     }
9147
9148  nokinderror:
9149
9150   if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9151     {
9152       uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9153     }
9154
9155   if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9156     {
9157       DPRINTF (("Check datatype: %s / %s",
9158                 uentry_unparseFull (old),
9159                 uentry_unparseFull (unew)));
9160
9161       uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9162     }
9163
9164   if (uentry_isVariable (old) && uentry_isVariable (unew))
9165     {
9166       if (!typeError && 
9167           !ctype_matchDef (old->utype, unew->utype))
9168         {
9169           if (optgenerror 
9170               (FLG_INCONDEFS,
9171                message
9172                ("Variable %q %s with inconsistent type (arrays and pointers are "
9173                 "not identical in variable declarations): %t",
9174                 uentry_getName (unew), 
9175                 uentry_reDefDecl (old, unew),
9176                 unew->utype),
9177                uentry_whereDeclared (unew)))
9178             {
9179               uentry_showWhereLast (old);
9180               
9181               /*
9182               ** Avoid repeated errors.
9183               */
9184
9185               if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9186                 {
9187                   old->whereDefined = fileloc_update (old->whereDefined,
9188                                                       fileloc_undefined);
9189                 }
9190
9191               typeError = TRUE;
9192             }
9193         }
9194
9195       checkVarConformance (old, unew, mustConform, completeConform);
9196     }
9197
9198   if (fcnConformance)
9199     {
9200       /* old->utype = unew->utype; */
9201     }
9202   else
9203     {
9204       if (ctype_isConj (old->utype))
9205         {
9206           if (ctype_isConj (unew->utype))
9207             {
9208               if (!ctype_sameAltTypes (old->utype, unew->utype))
9209                 {
9210                   if (optgenerror 
9211                       (FLG_INCONDEFS,
9212                        message ("%s %q inconsistently %rdeclared with "
9213                                 "alternate types %s "
9214                                 "(types match, but alternates are not identical, "
9215                                 "so checking may not be correct)",
9216                                 ekind_capName (uentry_getKind (old)),
9217                                 uentry_getName (unew),
9218                                 uentry_isDeclared (old),
9219                                 ctype_unparse (unew->utype)),
9220                        uentry_whereDeclared (unew)))
9221                     {
9222                       uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9223                     }
9224                   else
9225                     {
9226                       old->utype = unew->utype;
9227                     }
9228                 }
9229             }
9230         }
9231       else
9232         {
9233           if (ctype_isUnknown (old->utype))
9234             {
9235               old->utype = unew->utype;
9236             }
9237         }
9238     }  
9239
9240   if (unew->ukind == old->ukind) 
9241     {
9242       sfree (unew->info);
9243       unew->info = uinfo_copy (old->info, old->ukind);
9244     }
9245
9246   sRef_storeState (old->sref);
9247   sRef_storeState (unew->sref);
9248 }
9249
9250 static void uentry_mergeConstraints (uentry spec, uentry def)
9251 {
9252   if (uentry_isFunction (def))
9253     {
9254       DPRINTF (("Here: %s / %s",
9255                 uentry_unparseFull (spec),
9256                 uentry_unparseFull (def)));
9257       /* evans 2001-07-21 */
9258       llassert (uentry_isFunction (spec));
9259
9260       if (functionConstraint_isDefined (def->info->fcn->preconditions))
9261         {
9262           if (fileloc_isXHFile (uentry_whereLast (def)))
9263             {
9264               llassert (uentry_isFunction (spec));
9265               spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9266                                                                            def->info->fcn->preconditions);
9267             }
9268           else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9269             {
9270               ;
9271             }
9272           else
9273             {
9274               /* Check if the constraints are identical */
9275
9276               if (optgenerror 
9277                   (FLG_INCONDEFS,
9278                    message
9279                    ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9280                     uentry_getName (spec),
9281                     functionConstraint_unparse (spec->info->fcn->preconditions)),
9282                    uentry_whereLast (def)))
9283                 {
9284                   uentry_showWhereSpecified (spec);
9285                 }
9286
9287               functionConstraint_free (spec->info->fcn->preconditions);
9288               spec->info->fcn->preconditions = def->info->fcn->preconditions;
9289             }
9290           
9291           def->info->fcn->preconditions = functionConstraint_undefined;
9292         }
9293
9294       if (functionConstraint_isDefined (def->info->fcn->postconditions))
9295         {
9296           if (fileloc_isXHFile (uentry_whereLast (def)))
9297             {
9298               llassert (uentry_isFunction (spec));
9299               DPRINTF (("Post: %s /++/ %s",
9300                         functionConstraint_unparse (spec->info->fcn->postconditions),
9301                         functionConstraint_unparse (def->info->fcn->postconditions)));
9302               spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9303                                                                             def->info->fcn->postconditions);
9304               def->info->fcn->postconditions = functionConstraint_undefined;
9305               DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9306             }
9307           else
9308             {
9309               if (optgenerror 
9310                   (FLG_INCONDEFS,
9311                    message
9312                    ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9313                     uentry_getName (spec),
9314                     functionConstraint_unparse (spec->info->fcn->postconditions)),
9315                    uentry_whereLast (def)))
9316                 {
9317                   uentry_showWhereSpecified (spec);
9318                 }
9319               
9320               functionConstraint_free (spec->info->fcn->postconditions);
9321               spec->info->fcn->postconditions = def->info->fcn->postconditions;
9322               def->info->fcn->postconditions = functionConstraint_undefined;
9323             }
9324         }
9325     }
9326 }
9327
9328 /*
9329 ** modifies spec to reflect def, reports any inconsistencies
9330 */
9331
9332 void
9333 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9334 {
9335   llassert (uentry_isValid (spec));
9336   llassert (uentry_isValid (def));
9337   llassert (cstring_equal (spec->uname, def->uname));
9338
9339   if (uentry_isFunction (def))
9340     {
9341       if (uentry_isConstant (spec))
9342         {
9343           llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9344           uentry_makeConstantFunction (spec);
9345         }
9346       else
9347         {
9348           uentry_convertVarFunction (spec);
9349         }
9350
9351       llassert (uentry_isFunction (spec));
9352     }
9353   
9354   DPRINTF (("Merge entries: %s / %s",
9355             uentry_unparseFull (spec),
9356             uentry_unparseFull (def)));
9357
9358   uentry_mergeConstraints (spec, def);
9359
9360   uentry_checkConformance (spec, def, TRUE, 
9361                            context_getFlag (FLG_NEEDSPEC));
9362
9363   DPRINTF (("Merge entries after conform: %s / %s",
9364             uentry_unparseFull (spec),
9365             uentry_unparseFull (def)));
9366
9367   /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9368
9369   /*
9370   ** okay, declarations conform.  Propagate extra information.
9371   */
9372
9373   uentry_setDefined (spec, uentry_whereDefined (def));
9374   uentry_setDeclared (spec, uentry_whereDeclared (def));
9375
9376   if (uentry_isStatic (def))
9377     {
9378       if (optgenerror 
9379           (FLG_INCONDEFS,
9380            message ("%s %q specified, but declared as static",
9381                     ekind_capName (def->ukind),
9382                     uentry_getName (def)),
9383            uentry_whereDeclared (def)))
9384         {
9385           uentry_showWhereSpecified (spec);
9386         }
9387     }
9388   else 
9389     {
9390       spec->storageclass = def->storageclass;
9391     }
9392
9393   sRef_storeState (spec->sref);
9394
9395   spec->used = def->used || spec->used;
9396   spec->hasNameError |= def->hasNameError;
9397
9398   uentry_free (def);
9399
9400   if (!spec->hasNameError)
9401     {
9402       uentry_checkName (spec);
9403     }
9404   else
9405     {
9406       ;
9407     }
9408 }
9409
9410 /*
9411 ** Can't generate function redeclaration errors when the 
9412 ** entries are merged, since we don't yet know if its the
9413 ** definition of the function.
9414 */
9415
9416 void
9417 uentry_clearDecl (void)
9418 {
9419   posRedeclared = uentry_undefined;
9420   fileloc_free (posLoc);
9421   posLoc = fileloc_undefined;
9422 }
9423
9424 void
9425 uentry_checkDecl (void)
9426 {
9427   if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9428     {
9429       llassert (fileloc_isDefined (posLoc));
9430
9431       if (uentry_isCodeDefined (posRedeclared))
9432         {
9433           if (optgenerror (FLG_REDECL,
9434                            message ("%s %q declared after definition", 
9435                                     ekind_capName (posRedeclared->ukind),
9436                                     uentry_getName (posRedeclared)),
9437                            posLoc))
9438             {
9439               llgenindentmsg (message ("Definition of %q", 
9440                                        uentry_getName (posRedeclared)),
9441                               posRedeclared->whereDeclared);
9442             }
9443         }
9444       else
9445         {
9446           if (optgenerror (FLG_REDECL,
9447                            message ("%s %q declared more than once", 
9448                                     ekind_capName (posRedeclared->ukind),
9449                                     uentry_getName (posRedeclared)),
9450                            posLoc))
9451             {
9452               llgenindentmsg (message ("Previous declaration of %q", 
9453                                        uentry_getName (posRedeclared)),
9454                               posRedeclared->whereDeclared);
9455             }
9456         }
9457     }
9458
9459   fileloc_free (posLoc);
9460   posLoc = fileloc_undefined;
9461   posRedeclared = uentry_undefined;
9462 }
9463
9464 /*
9465 ** Redefinition of old as unew.
9466 ** modifies old to reflect unew, reports any inconsistencies
9467 */
9468
9469 void
9470 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9471 {
9472   fileloc olddef = uentry_whereDeclared (old); 
9473   fileloc unewdef = uentry_whereDeclared (unew);
9474   bool mustConform;
9475   bool wasForward;
9476
9477   DPRINTF (("uentry merge: %s / %s",
9478             uentry_unparseFull (old),
9479             uentry_unparseFull (unew)));
9480  
9481   wasForward = 
9482     fileloc_isUndefined (olddef) 
9483     && fileloc_isDefined (uentry_whereDefined (old)) 
9484     && !uentry_isExpandedMacro (old);
9485   
9486   if (!context_getFlag (FLG_INCONDEFSLIB)
9487       && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9488     {
9489       mustConform = FALSE;
9490     }
9491   else
9492     {
9493       mustConform = TRUE;
9494     }
9495   
9496   llassert (uentry_isValid (old));
9497   llassert (uentry_isValid (unew));
9498   llassert (cstring_equal (old->uname, unew->uname));
9499
9500   if (uentry_isFunction (unew) && !uentry_isFunction (old))
9501     {
9502       if (uentry_isConstant (old))
9503         {
9504           llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9505           uentry_makeConstantFunction (old);
9506         }
9507       else
9508         {
9509           uentry_convertVarFunction (old);
9510         }
9511
9512       llassert (uentry_isFunction (old));
9513     }
9514
9515   DPRINTF (("uentry merge: %s / %s",
9516             uentry_unparseFull (old),
9517             uentry_unparseFull (unew)));
9518
9519   if (uentry_isExtern (unew))
9520     {
9521       uentry_setUsed (old, unewdef);
9522     }
9523
9524   /*
9525   ** should check old one was extern!
9526   */
9527
9528   if (uentry_isStatic (old))
9529     {
9530       if (!(uentry_isStatic (unew)))
9531         {
9532           if (optgenerror 
9533               (FLG_SHADOW,
9534                message ("%s %q shadows static declaration",
9535                         ekind_capName (unew->ukind),
9536                         uentry_getName (unew)),
9537                unewdef))
9538             {
9539               uentry_showWhereLast (old);
9540             }
9541         }
9542       else
9543         {
9544           uentry_setDeclDef (old, unewdef);
9545         }
9546     }
9547   else if (uentry_isStatic (unew))
9548     {
9549       uentry_setDeclDef (old, unewdef);
9550     }
9551   else if (uentry_isExtern (old))
9552     {
9553       uentry_setDeclared (old, unewdef);
9554     }
9555   else
9556     {
9557       if (!uentry_isExtern (unew) 
9558           && !uentry_isForward (old)
9559           && !fileloc_equal (olddef, unewdef)
9560           && !fileloc_isUndefined (olddef)
9561           && !fileloc_isUndefined (unewdef)
9562           && !fileloc_isBuiltin (olddef)
9563           && !fileloc_isBuiltin (unewdef)
9564           && !uentry_isYield (old)
9565           && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9566         {
9567           if (uentry_isVariable (old) || uentry_isVariable (unew))
9568             {
9569               ; /* will report redeclaration error later */
9570             }
9571           else
9572             {
9573               if (fileloc_isDefined (uentry_whereDefined (old)))
9574                 {
9575                   if (optgenerror
9576                       (FLG_REDEF,
9577                        message ("%s %q defined more than once", 
9578                                 ekind_capName (unew->ukind),
9579                                 uentry_getName (unew)),
9580                        uentry_whereLast (unew)))
9581                     {
9582                       llgenindentmsg
9583                         (message ("Previous definition of %q", 
9584                                   uentry_getName (old)),
9585                          uentry_whereLast (old));
9586                     }
9587                   /*
9588                   if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9589                     {
9590                       uentry_updateInto (old, unew);
9591                       old->sref = sRef_saveCopy (old->sref);
9592                     }
9593                     */
9594                 }
9595             }
9596         }
9597       else
9598         {
9599           if (fileloc_isLib (olddef)
9600               || fileloc_isUndefined (olddef)
9601               || fileloc_isImport (olddef))
9602             {
9603               if (uentry_isExtern (unew)) 
9604                 {
9605                   if (uentry_isExtern (old)
9606                       || (fileloc_isDefined (uentry_whereDeclared (old))
9607                           && (!fileloc_equal (uentry_whereDeclared (old),
9608                                               uentry_whereDefined (old)))))
9609                     {
9610                       if (optgenerror
9611                           (FLG_REDECL,
9612                            message ("%s %q declared more than once", 
9613                                     ekind_capName (unew->ukind),
9614                                     uentry_getName (unew)),
9615                            unew->whereDeclared))
9616                         {
9617                           llgenindentmsg
9618                             (message ("Previous declaration of %q", 
9619                                       uentry_getName (old)),
9620                              old->whereDeclared);
9621                         }
9622                     }
9623                   
9624                   uentry_setExtern (old);
9625                 }
9626               else
9627                 {
9628                   uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9629                 }
9630             }
9631         }
9632     }
9633
9634   DPRINTF (("uentry merge: %s / %s",
9635             uentry_unparseFull (old),
9636             uentry_unparseFull (unew)));
9637
9638   uentry_mergeConstraints (old, unew);
9639   DPRINTF (("uentry merge: %s / %s",
9640             uentry_unparseFull (old),
9641             uentry_unparseFull (unew)));
9642
9643   uentry_checkConformance (old, unew, mustConform, FALSE);
9644   DPRINTF (("uentry merge: %s / %s",
9645             uentry_unparseFull (old),
9646             uentry_unparseFull (unew)));
9647
9648   old->used = old->used || unew->used;
9649   old->uses = filelocList_append (old->uses, unew->uses);
9650   unew->uses = filelocList_undefined; 
9651
9652   sRef_storeState (old->sref); 
9653   sRef_storeState (unew->sref);
9654
9655   if (wasForward)
9656     {
9657       old->whereDefined = fileloc_update (old->whereDefined,
9658                                           fileloc_undefined);
9659     }
9660
9661   DPRINTF (("here: %s", uentry_unparseFull (old)));
9662
9663   /*
9664   ** No redeclaration errors for functions here, since we
9665   ** don't know if this is the definition of the function.
9666   */
9667
9668   if (fileloc_isUser (old->whereDeclared)
9669       && fileloc_isUser (unew->whereDeclared)
9670       && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9671       && !fileloc_isDefined (unew->whereDefined))
9672     {
9673       if (uentry_isFunction (old))
9674         {
9675           /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9676           posLoc = fileloc_update (posLoc, unew->whereDeclared);
9677         }
9678       else
9679         {
9680           if (optgenerror (FLG_REDECL,
9681                            message ("%s %q declared more than once", 
9682                                     ekind_capName (unew->ukind),
9683                                     uentry_getName (unew)),
9684                            unew->whereDeclared))
9685             {
9686               llgenindentmsg (message ("Previous declaration of %q", 
9687                                        uentry_getName (old)),
9688                               old->whereDeclared);
9689             }
9690         }
9691     }
9692
9693   if (fileloc_isUndefined (old->whereDefined))
9694     {
9695       old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9696     }
9697   else
9698     {
9699       if (!context_processingMacros ()
9700           && fileloc_isUser (old->whereDefined) 
9701           && fileloc_isUser (unew->whereDefined)
9702           && !fileloc_equal (old->whereDefined, unew->whereDefined))
9703         {
9704           if (uentry_isVariable (unew) || uentry_isFunction (unew))
9705             {
9706               if (uentry_isVariable (unew) 
9707                   && uentry_isExtern (unew))
9708                 {
9709                   if (optgenerror (FLG_REDECL,
9710                                    message ("%s %q declared after definition", 
9711                                             ekind_capName (unew->ukind),
9712                                             uentry_getName (unew)),
9713                                    unew->whereDeclared))
9714                     {
9715                       llgenindentmsg (message ("Definition of %q", 
9716                                                uentry_getName (old)),
9717                                       old->whereDefined);
9718                     }
9719                 }
9720               else
9721                 {
9722                   if (optgenerror (FLG_REDEF,
9723                                    message ("%s %q redefined", 
9724                                             ekind_capName (unew->ukind),
9725                                             uentry_getName (unew)),
9726                                    unew->whereDefined))
9727                     {
9728                       llgenindentmsg (message ("Previous definition of %q", 
9729                                                uentry_getName (old)),
9730                                       old->whereDefined);
9731                     }
9732                 }
9733             }
9734         }
9735     }
9736
9737   if (uentry_isExternal (unew))
9738     {
9739       old->whereDefined = fileloc_createExternal ();
9740     }
9741
9742   if (unew->hasNameError)
9743     {
9744       old->hasNameError = TRUE;
9745     }
9746
9747   uentry_free (unew);
9748
9749   if (!old->hasNameError)
9750     {
9751       uentry_checkName (old);
9752     }
9753
9754   DPRINTF (("After: %s", uentry_unparseFull (old)));
9755   llassert (!ctype_isUndefined (old->utype));
9756 }
9757
9758 void
9759 uentry_copyState (uentry res, uentry other)
9760 {
9761   llassert (uentry_isValid (res));
9762   llassert (uentry_isValid (other));
9763
9764   res->used = other->used;
9765
9766   res->info->var->kind = other->info->var->kind;
9767   res->info->var->defstate = other->info->var->defstate;
9768   res->info->var->nullstate = other->info->var->nullstate;
9769   res->info->var->checked = other->info->var->checked;
9770
9771   sRef_copyState (res->sref, other->sref);
9772 }
9773
9774 bool
9775 uentry_sameKind (uentry u1, uentry u2)
9776 {
9777   if (uentry_isValid (u1) && uentry_isValid (u2))
9778     {
9779       if (uentry_isVar (u1) && uentry_isVar (u2))
9780         {
9781           ctype c1 = u1->utype;
9782           ctype c2 = u2->utype;
9783
9784           if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9785
9786           /*
9787           ** both functions, or both not functions
9788           */
9789
9790           return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9791         }
9792       else
9793         {
9794           return ((u1->ukind == u2->ukind));
9795         }
9796     }
9797   
9798   return FALSE;
9799 }
9800    
9801 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9802 {
9803   ekind okind = unew->ukind;
9804   llassert (uentry_isValid (unew));
9805   llassert (uentry_isValid (old));
9806
9807   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9808
9809   unew->ukind = old->ukind;
9810   llassert (cstring_equal (unew->uname, old->uname));
9811   unew->utype = old->utype;
9812
9813   if (fileloc_isDefined (unew->whereSpecified) 
9814       && !fileloc_isDefined (old->whereSpecified))
9815     {
9816       ; /* Keep the old value */
9817     }
9818   else
9819     {
9820       fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9821       unew->whereSpecified = fileloc_copy (old->whereSpecified);
9822     }
9823
9824   if (fileloc_isDefined (unew->whereDefined) 
9825       && !fileloc_isDefined (old->whereDefined))
9826     {
9827       ; /* Keep the old value */
9828     }
9829   else
9830     {
9831       fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9832       unew->whereDefined = fileloc_copy (old->whereDefined);
9833     }
9834
9835   if (fileloc_isDefined (unew->whereDeclared) 
9836       && !fileloc_isDefined (old->whereDeclared))
9837     {
9838       ; /* Keep the old value */
9839     }
9840   else
9841     {
9842       fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9843       unew->whereDeclared = fileloc_copy (old->whereDeclared);
9844     }
9845
9846   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9847
9848   unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9849   unew->used = old->used;
9850   unew->lset = FALSE;
9851   unew->isPrivate = old->isPrivate;
9852   unew->hasNameError = old->hasNameError;
9853   unew->uses = filelocList_append (unew->uses, old->uses);
9854   old->uses = filelocList_undefined;
9855
9856   unew->storageclass = old->storageclass;
9857   uinfo_free (unew->info, okind);
9858   unew->info = uinfo_copy (old->info, old->ukind);
9859 }
9860
9861
9862 uentry
9863 uentry_copy (uentry e)
9864 {
9865   if (uentry_isValid (e))
9866     {
9867       uentry enew = uentry_alloc ();
9868       DPRINTF (("copy: %s", uentry_unparseFull (e)));
9869       enew->ukind = e->ukind;
9870       enew->uname = cstring_copy (e->uname);
9871       enew->utype = e->utype;
9872       
9873       enew->whereSpecified = fileloc_copy (e->whereSpecified);
9874       enew->whereDefined = fileloc_copy (e->whereDefined);
9875       enew->whereDeclared = fileloc_copy (e->whereDeclared);
9876       
9877       enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9878       enew->used = e->used;
9879       enew->lset = FALSE;
9880       enew->isPrivate = e->isPrivate;
9881       enew->hasNameError = e->hasNameError;
9882       enew->uses = filelocList_undefined;
9883       
9884       enew->storageclass = e->storageclass;
9885       enew->info = uinfo_copy (e->info, e->ukind);
9886       enew->warn = warnClause_copy (e->warn);
9887
9888       DPRINTF (("Here we are..."));
9889       DPRINTF (("original: %s", uentry_unparseFull (e)));
9890       DPRINTF (("copy: %s", uentry_unparse (enew)));
9891       DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9892       return enew;
9893     }
9894   else
9895     {
9896       return uentry_undefined;
9897     }
9898 }
9899
9900 void
9901 uentry_setState (uentry res, uentry other)
9902 {
9903   llassert (uentry_isValid (res));
9904   llassert (uentry_isValid (other));
9905
9906   llassert (res->ukind == other->ukind);
9907   llassert (res->ukind == KVAR);
9908
9909   res->sref = sRef_saveCopy (other->sref);
9910   res->used = other->used;
9911   filelocList_free (res->uses); 
9912   res->uses = other->uses; 
9913   other->uses = filelocList_undefined; 
9914   res->lset = other->lset;
9915 }
9916
9917 void
9918 uentry_mergeUses (uentry res, uentry other)
9919 {
9920   llassert (uentry_isValid (res));
9921   llassert (uentry_isValid (other));
9922
9923   res->used = other->used || res->used;
9924   res->lset = other->lset || res->lset;
9925   res->uses = filelocList_append (res->uses, other->uses);
9926   other->uses = filelocList_undefined;
9927 }
9928
9929
9930 /*
9931 ** This is a really ugly routine.
9932 **
9933 ** gack...fix this one day.
9934 */
9935
9936 /*
9937 ** flip == TRUE
9938 **   >> res is the false branch, other is the true branch (or continuation)
9939 ** flip == FALSE
9940 **   >> res is the true branch, other is the false branch (or continutation)
9941 **
9942 ** opt == TRUE if,
9943 **
9944 ** <other>
9945 ** if <res> ;
9946 **
9947 ** References not effected by res are propagated from other.
9948 */
9949
9950 static void
9951   branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
9952                     bool flip, clause cl, fileloc loc)
9953 {
9954   if (optgenerror 
9955       (FLG_BRANCHSTATE,
9956        message ("%s %q is %s %s, but %s %s.",
9957                 ekind_capName (res->ukind), uentry_getName (res),
9958                 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9959                 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9960        loc))
9961     {
9962       if (sRef_isDead (res->sref))
9963         {
9964           sRef_showStateInfo (res->sref);
9965         }
9966       else if (sRef_isKept (res->sref))
9967         {
9968           sRef_showAliasInfo (res->sref);
9969         }
9970       else /* dependent */
9971         {
9972           sRef_showAliasInfo (res->sref);
9973           sRef_showAliasInfo (other->sref);
9974         }
9975       
9976       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9977     }
9978 }
9979
9980 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
9981 {
9982   alkind rk = sRef_getAliasKind (rs);
9983   alkind ok = sRef_getAliasKind (os);
9984
9985   if (alkind_isError (rk) || alkind_isError (ok))
9986     {
9987       return FALSE;
9988     }
9989   else
9990     {
9991       return ((sRef_isDead (rs)
9992                || (alkind_isKept (rk) && !alkind_isKept (ok))
9993                || (alkind_isDependent (rk) 
9994                    && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9995               && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9996     }
9997 }
9998
9999 static void
10000   branchStateAltError (/*@notnull@*/ uentry res,
10001                        /*@notnull@*/ uentry other, bool flip,
10002                        clause cl, fileloc loc)
10003 {
10004   if (optgenerror 
10005       (FLG_BRANCHSTATE,
10006        message ("%s %q is %s %s, but %s %s.",
10007                 ekind_capName (res->ukind), uentry_getName (res),
10008                 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10009                 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10010        loc))
10011     {
10012       if (sRef_isDead (other->sref))
10013         {
10014           sRef_showStateInfo (other->sref);
10015         }
10016       else /* kept */
10017         {
10018           sRef_showAliasInfo (other->sref);
10019         }
10020       
10021       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10022       sRef_setDefinedComplete (res->sref, fileloc_undefined);
10023       
10024       sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10025       sRef_setDefinedComplete (other->sref, fileloc_undefined);
10026     }
10027 }
10028
10029 /*
10030 ** A reference is relevant for certain checks, only if it 
10031 ** is not definitely null on this path (but not declared
10032 ** to always be null.)
10033 */
10034
10035 static bool uentry_relevantReference (sRef sr, bool flip)
10036 {
10037   if (sRef_isKept (sr) || sRef_isDependent (sr))
10038     {
10039       return FALSE;
10040     }
10041   else
10042     {
10043       if (flip)
10044         {
10045           return !sRef_definitelyNullContext (sr);
10046         }
10047       else
10048         {
10049           return !sRef_definitelyNullAltContext (sr);
10050         }
10051     }
10052 }
10053
10054 static void
10055 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10056                          bool mustReturn, bool flip, bool opt,
10057                          clause cl)    
10058 {
10059   sRef rs = res->sref;
10060   sRef os = other->sref;
10061
10062   DPRINTF (("Merge alias states: %s / %s",
10063             uentry_unparseFull (res),
10064             uentry_unparseFull (other)));
10065
10066   if (sRef_isValid (rs))
10067     {
10068       if (!mustReturn)
10069         {
10070           if (uentry_incompatibleMemoryStates (rs, os))
10071             {
10072               DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10073                         sRef_unparseFull (rs), sRef_unparseFull (os)));
10074
10075               if (sRef_isThroughArrayFetch (rs)
10076                   && !context_getFlag (FLG_STRICTBRANCHSTATE))
10077                 {
10078                   if (sRef_isKept (rs) || sRef_isKept (os))
10079                     {
10080                       sRef_maybeKill (rs, loc);
10081                     }
10082                   else if (sRef_isPossiblyDead (os))
10083                     {
10084                       sRef_maybeKill (rs, loc);
10085                     }
10086                   else
10087                     {
10088                       ;
10089                     }
10090                 }
10091               else
10092                 {
10093                   if (uentry_relevantReference (os, flip))
10094                     {
10095                       if (sRef_isLocalParamVar (rs) 
10096                           && (sRef_isLocalState (os) 
10097                               || sRef_isDependent (os)))
10098                         {
10099                           if (sRef_isDependent (rs))
10100                             {
10101                               sRef_setDependent (os, loc);
10102                             }
10103                           else
10104                             {
10105                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10106                             }
10107                         }
10108                       else 
10109                         {
10110                           branchStateError (res, other, flip, cl, loc);
10111                         }
10112                     }
10113                 }
10114               
10115               if (sRef_isKept (rs))
10116                 {
10117                   DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10118                   sRef_setKept (os, loc);
10119                 }
10120             }
10121           else
10122             {
10123               if (uentry_incompatibleMemoryStates (os, rs))
10124                 {
10125                   if (uentry_relevantReference (rs, !flip))
10126                     {
10127                       if (sRef_isLocalParamVar (rs) 
10128                           && (sRef_isDependent (rs)
10129                               || sRef_isLocalState (rs)))
10130                         {
10131                           if (sRef_isDependent (os))
10132                             {
10133                               sRef_setDependent (rs, loc);
10134                             }
10135                           else
10136                             {
10137                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10138                             }
10139                         }
10140                       else
10141                         {
10142                           if (sRef_isParam (os))
10143                             {
10144                               /* 
10145                               ** If the local variable associated
10146                               ** with the param has the correct state,
10147                               ** its okay.
10148                               ** (e.g., free (s); s = new(); ...
10149                               */
10150                               
10151                               uentry uvar = usymtab_lookupSafe (other->uname);
10152                               
10153                               if (uentry_isValid (uvar)
10154                                   && ((sRef_isDead (os) 
10155                                        && sRef_isOnly (uvar->sref))
10156                                       || (sRef_isDependent (os)
10157                                           && sRef_isOwned (uvar->sref))))
10158                                 {
10159                                   /* no error */
10160                                 }
10161                               else
10162                                 {
10163                                   branchStateAltError (res, other,
10164                                                        flip, cl, loc);
10165                                 }
10166                             }
10167                           else
10168                             {
10169                               DPRINTF (("Here: %s / %s",
10170                                         uentry_unparseFull (res),
10171                                         uentry_unparseFull (other)));
10172
10173                               branchStateAltError (res, other, 
10174                                                    flip, cl, loc);
10175                             }
10176                         }
10177                     }
10178                 }
10179               
10180               if (sRef_isKept (os))
10181                 {
10182                   sRef_setKept (rs, loc);
10183                 }
10184             }
10185           
10186           if (opt)
10187             {
10188               DPRINTF (("Merge opt..."));
10189               sRef_mergeOptState (rs, os, cl, loc);
10190               DPRINTF (("Done!"));
10191             }
10192           else
10193             {
10194               DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10195               sRef_mergeState (rs, os, cl, loc);
10196               DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10197             }
10198         }
10199       else
10200         {
10201           if (sRef_isModified (os))
10202             {
10203               sRef_setModified (rs);
10204             }
10205         }
10206     }
10207
10208   DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10209 }
10210
10211 static void
10212 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10213 {
10214   valueTable rvalues;
10215   valueTable ovalues;
10216
10217   DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10218   
10219   if (mustReturn)
10220     {
10221       return;
10222     }
10223   /* flip? */
10224
10225   rvalues = sRef_getValueTable (res->sref);
10226   ovalues = sRef_getValueTable (other->sref);
10227   
10228   if (valueTable_isUndefined (ovalues))
10229     {
10230       DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10231       ;
10232     }
10233   else if (valueTable_isUndefined (rvalues))
10234     {
10235       /*
10236       ** Copy values from other
10237       */
10238       
10239       /*@i$@#@*/
10240       DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10241       DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10242       ;
10243     }
10244   else
10245     {
10246       valueTable_elements (ovalues, fkey, fval) {
10247         stateValue tval;
10248         metaStateInfo minfo;
10249         stateCombinationTable sctable;
10250         cstring msg;
10251         int nval;
10252
10253         tval = valueTable_lookup (rvalues, fkey);
10254         
10255         DPRINTF (("Merge value: %s / %s X %s", fkey, 
10256                   stateValue_unparse (fval), stateValue_unparse (tval)));
10257
10258         minfo = context_lookupMetaStateInfo (fkey);
10259         llassert (stateValue_isDefined (tval));
10260         
10261         if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval)) 
10262           {
10263             DPRINTF (("Cannot find meta state for: %s", fkey));
10264             BADBRANCH;
10265           }
10266         else
10267           {
10268             llassert (metaStateInfo_isDefined (minfo));
10269
10270             if (stateValue_isError (fval)
10271                 || sRef_definitelyNullContext (res->sref))
10272               {
10273                 sRef_setMetaStateValueComplete (res->sref, 
10274                                                 fkey, stateValue_getValue (fval), 
10275                                                 stateValue_getLoc (fval));
10276                 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10277               }
10278             else if (stateValue_isError (tval)
10279                      || sRef_definitelyNullAltContext (other->sref))
10280               {
10281                 DPRINTF (("Other branch is definitely null!"));
10282               }
10283             else if (sRef_isStateUndefined (res->sref)
10284                      || sRef_isDead (res->sref))
10285               {
10286                 ; /* Combination state doesn't matter if it is undefined or dead */
10287               }
10288             else 
10289               {
10290                 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10291                           metaStateInfo_unparse (minfo),
10292                           stateValue_unparse (fval),
10293                           stateValue_unparse (tval)));
10294                 
10295                 DPRINTF (("state values: %d / %d",
10296                           stateValue_getValue (fval), stateValue_getValue (tval)));
10297                 
10298                 sctable = metaStateInfo_getMergeTable (minfo);
10299
10300                 DPRINTF (("Merge table: %s",
10301                           stateCombinationTable_unparse (sctable)));
10302                 
10303                 msg = cstring_undefined;
10304                 
10305                 nval = stateCombinationTable_lookup (sctable, 
10306                                                      stateValue_getValue (fval), 
10307                                                      stateValue_getValue (tval), 
10308                                                      &msg);
10309
10310                 DPRINTF (("nval: %d / %d / %d", nval,
10311                           stateValue_getValue (fval), stateValue_getValue (tval)));
10312
10313                 if (nval == stateValue_error)
10314                   {
10315                     /*@i32 print extra info for assignments@*/
10316
10317                     if (uentry_isGlobalMarker (res))
10318                       {
10319                         if (optgenerror 
10320                             (FLG_STATEMERGE,
10321                              message
10322                              ("Control branches merge with incompatible global states (%s and %s)%q",
10323                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10324                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10325                               cstring_isDefined (msg) 
10326                               ? message (": %s", msg) : cstring_undefined),
10327                              loc))
10328                           {
10329                             sRef_showMetaStateInfo (res->sref, fkey);
10330                             sRef_showMetaStateInfo (other->sref, fkey);
10331                           }
10332                       }
10333                     else
10334                       {
10335                         if (optgenerror 
10336                             (FLG_STATEMERGE,
10337                              message
10338                              ("Control branches merge with incompatible states for %q (%s and %s)%q",
10339                               uentry_getName (res),
10340                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10341                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10342                               cstring_isDefined (msg) 
10343                               ? message (": %s", msg) : cstring_undefined),
10344                              loc))
10345                           {
10346                             sRef_showMetaStateInfo (res->sref, fkey);
10347                             sRef_showMetaStateInfo (other->sref, fkey);
10348                             DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10349                             DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10350                             DPRINTF (("Null: %s / %s",
10351                                       bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10352                                       bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10353
10354                           }
10355                       }
10356                   }
10357
10358                 if (nval == stateValue_getValue (fval)
10359                     && nval != stateValue_getValue (tval))
10360                   {
10361                     loc = stateValue_getLoc (fval);
10362                   }
10363                 else if (nval == stateValue_getValue (tval)
10364                          && nval != stateValue_getValue (fval))
10365                   {
10366                     loc = stateValue_getLoc (tval);
10367                   }
10368                 else
10369                   {
10370                     ;
10371                   }
10372
10373                 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10374                     && nval == stateValue_getValue (fval)
10375                     && nval == stateValue_getValue (tval))
10376                   {
10377                     ;
10378                   }
10379                 else
10380                   {
10381                     sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10382                   }
10383               }
10384           }
10385       } end_valueTable_elements ;
10386     } 
10387 }
10388
10389
10390 static void
10391 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10392                        bool flip, clause cl)
10393 {
10394   if (cl == DOWHILECLAUSE)
10395     {
10396       res->used = other->used || res->used;
10397       res->lset = other->lset || res->lset;
10398       res->uses = filelocList_append (res->uses, other->uses);
10399       other->uses = filelocList_undefined;
10400     }
10401   else
10402     {
10403       if (sRef_isMacroParamRef (res->sref)
10404           && !uentry_isSefParam (other)
10405           && !uentry_isSefParam (res))
10406         {
10407           bool hasError = FALSE;
10408           
10409           if (bool_equal (res->used, other->used))
10410             {
10411               res->used = other->used;
10412             }
10413           else
10414             {
10415               if (other->used && !flip)
10416                 {
10417                   hasError = 
10418                     optgenerror 
10419                     (FLG_MACROPARAMS,
10420                      message ("Macro parameter %q used in true clause, "
10421                               "but not in false clause",
10422                               uentry_getName (res)),
10423                      uentry_whereDeclared (res));
10424                 }
10425               else
10426                 {       
10427                   hasError = 
10428                     optgenerror 
10429                     (FLG_MACROPARAMS,
10430                      message ("Macro parameter %q used in false clause, "
10431                               "but not in true clause",
10432                               uentry_getName (res)),
10433                      uentry_whereDeclared (res));
10434                 }
10435               res->used = TRUE;
10436               
10437               if (hasError)
10438                 {
10439                   /* make it sef now, prevent more errors */
10440                   res->info->var->kind = VKREFSEFPARAM;
10441                 }
10442             }
10443         }
10444       else
10445         {
10446           res->used = other->used || res->used;
10447           res->lset = other->lset || res->lset;
10448           res->uses = filelocList_append (res->uses, other->uses);
10449           other->uses = filelocList_undefined;
10450         }
10451     }
10452 }
10453
10454 void
10455 uentry_mergeState (uentry res, uentry other, fileloc loc,
10456                    bool mustReturn, bool flip, bool opt,
10457                    clause cl)
10458 {
10459   llassert (uentry_isValid (res));
10460   llassert (uentry_isValid (other));
10461
10462   llassert (res->ukind == other->ukind);
10463   llassert (res->ukind == KVAR);
10464
10465   DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10466             uentry_unparseFull (other)));
10467   
10468   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10469   uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10470   uentry_mergeSetStates (res, other, loc, flip, cl);
10471 }
10472
10473 void uentry_setUsed (uentry e, fileloc loc)
10474 {
10475   static bool firstTime = TRUE;
10476   static bool showUses = FALSE;
10477   static bool exportLocal = FALSE;
10478
10479   DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10480
10481   if (firstTime)
10482     {
10483       /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10484
10485       showUses = context_getFlag (FLG_SHOWUSES); 
10486       exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10487
10488       firstTime = FALSE;
10489     }
10490
10491   if (uentry_isValid (e))
10492     {
10493       int dp;
10494
10495       if (warnClause_isDefined (e->warn))
10496         {
10497           flagSpec flg = warnClause_getFlag (e->warn);
10498           cstring msg;
10499
10500           if (warnClause_hasMessage (e->warn))
10501             {
10502               msg = cstring_copy (warnClause_getMessage (e->warn));
10503             }
10504           else
10505             {
10506               msg = message ("Use of possibly dangerous %s",
10507                              uentry_ekindNameLC (e));
10508             }
10509
10510           vfsgenerror (flg, 
10511                        message ("%q: %q", msg, uentry_getName (e)),
10512                        loc);
10513         }
10514
10515       if (sRef_isMacroParamRef (e->sref))
10516         {
10517           if (uentry_isYield (e) || uentry_isSefParam (e))
10518             {
10519               ;
10520             }
10521           else 
10522             {
10523               if (context_inConditional ())
10524                 {
10525                   if (optgenerror
10526                       (FLG_MACROPARAMS,
10527                        message ("Macro parameter %q used in conditionally "
10528                                 "executed code (may or may not be "
10529                                 "evaluated exactly once)", 
10530                                 uentry_getName (e)),
10531                        loc))
10532                     {
10533                       e->info->var->kind = VKREFSEFPARAM;
10534                     }
10535                 }
10536               else
10537                 {
10538                   if ((e)->used)
10539                     {
10540                       if (optgenerror
10541                           (FLG_MACROPARAMS,
10542                            message ("Macro parameter %q used more than once", 
10543                                     uentry_getName (e)),
10544                            uentry_whereDeclared (e)))
10545                         {
10546                           e->info->var->kind = VKREFSEFPARAM;
10547                         }
10548                     }
10549                 }
10550             }
10551         }
10552       
10553       if ((dp = uentry_directParamNo (e)) >= 0)
10554         {
10555           uentry_setUsed (usymtab_getParam (dp), loc);
10556         }
10557       
10558       e->used = TRUE;
10559
10560       if (!sRef_isLocalVar (e->sref))
10561         {
10562           if (showUses)
10563             {
10564               e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10565             }
10566           else 
10567             {
10568               if (exportLocal)
10569                 {
10570                   if (context_inMacro ())
10571                     {
10572                       e->uses = filelocList_addUndefined (e->uses);
10573                     }
10574                   else 
10575                     {
10576                       e->uses = filelocList_addDifferentFile
10577                         (e->uses, 
10578                          uentry_whereDeclared (e),
10579                          loc);
10580                     }
10581                 }
10582             }
10583         }
10584     }
10585 }
10586
10587 bool uentry_isReturned (uentry u)
10588 {
10589   return (uentry_isValid (u) && uentry_isVar (u) 
10590           && (u->info->var->kind == VKRETPARAM
10591               || u->info->var->kind == VKSEFRETPARAM));
10592 }
10593
10594 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10595 {
10596   llassert (uentry_isRealFunction (u));
10597
10598   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10599     {
10600       stateClauseList clauses = uentry_getStateClauseList (u);
10601       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10602
10603       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10604       sRef_setAllocated (res, g_currentloc);
10605
10606       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10607                 stateClauseList_unparse (clauses)));
10608
10609       /*
10610       ** This should be in exprNode_reflectEnsuresClause
10611       */
10612
10613       stateClauseList_postElements (clauses, cl)
10614         {
10615           if (!stateClause_isGlobal (cl))
10616             {
10617               sRefSet refs = stateClause_getRefs (cl);
10618               sRefMod modf = stateClause_getEffectFunction (cl);
10619               
10620               sRefSet_elements (refs, el)
10621                 {
10622                   sRef base = sRef_getRootBase (el);
10623                   
10624                   if (sRef_isResult (base))
10625                     {
10626                       if (modf != NULL)
10627                         {
10628                           sRef sr = sRef_fixBase (el, res);
10629                           modf (sr, g_currentloc);
10630                         }
10631                     }
10632                   else
10633                     {
10634                       ;
10635                     }
10636                 } end_sRefSet_elements ;
10637             }
10638         } end_stateClauseList_postElements ;
10639         
10640       return res;
10641     }
10642   else
10643     {
10644       uentryList params;
10645       alkind ak;
10646       sRefSet prefs = sRefSet_new ();
10647       sRef res = sRef_undefined;
10648       int paramno = 0;
10649       
10650       params = uentry_getParams (u);
10651       
10652       uentryList_elements (params, current)
10653         {
10654           if (uentry_isReturned (current))
10655             {
10656               if (exprNodeList_size (args) >= paramno)
10657                 {
10658                   exprNode ecur = exprNodeList_nth (args, paramno);
10659                   sRef tref = exprNode_getSref (ecur);
10660                   
10661                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10662
10663                   if (sRef_isValid (tref))
10664                     {
10665                       sRef tcref = sRef_copy (tref);
10666                       
10667                       usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10668
10669                       if (sRef_isDead (tcref))
10670                         {
10671                           sRef_setDefined (tcref, g_currentloc);
10672                           sRef_setOnly (tcref, g_currentloc);
10673                         }
10674                       
10675                       if (sRef_isRefCounted (tcref))
10676                         {
10677                           /* could be a new ref now (but only if its returned) */
10678                           sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10679                         }
10680                       
10681                       sRef_makeSafe (tcref);
10682                       prefs = sRefSet_insert (prefs, tcref);
10683                     }
10684                 }
10685             }
10686           
10687           paramno++;
10688         } end_uentryList_elements ;
10689       
10690       if (sRefSet_size (prefs) > 0)
10691         {
10692           nstate n = sRef_getNullState (u->sref);
10693           
10694           if (sRefSet_size (prefs) == 1)
10695             {
10696               res = sRefSet_choose (prefs);
10697             }
10698           else
10699             {
10700               /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10701               res = sRefSet_mergeIntoOne (prefs);
10702             }
10703           
10704           if (nstate_isKnown (n))
10705             {
10706               sRef_setNullState (res, n, g_currentloc);
10707             }
10708         }
10709       else
10710         {
10711           if (ctype_isFunction (u->utype))
10712             {
10713               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10714               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10715             }
10716           else
10717             {
10718               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10719             }
10720           
10721           if (sRef_isRefCounted (res))
10722             {
10723               sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10724             }
10725         }
10726       
10727
10728       if (sRef_getNullState (res) == NS_ABSNULL)
10729         {
10730           ctype ct = ctype_realType (u->utype);
10731           
10732           if (ctype_isAbstract (ct))
10733             {
10734               sRef_setNotNull (res, g_currentloc);
10735             }
10736           else
10737             {
10738               if (ctype_isUser (ct))
10739                 {
10740                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10741                 }
10742               else
10743                 {
10744                   sRef_setNotNull (res, g_currentloc);
10745                 }
10746             }
10747         }
10748       
10749       if (sRef_isRefCounted (res))
10750         {
10751           sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10752         }
10753       else if (sRef_isKillRef (res))
10754         {
10755           sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10756         }
10757       else
10758         {
10759           ;
10760         }
10761       
10762       ak = sRef_getAliasKind (res);
10763       
10764       if (alkind_isImplicit (ak))
10765         {
10766           sRef_setAliasKind (res, 
10767                              alkind_fixImplicit (ak),
10768                              g_currentloc);
10769         }
10770       
10771       sRefSet_free (prefs);
10772       
10773       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10774       return res;
10775     }
10776 }
10777
10778 static bool uentry_isRefCounted (uentry ue)
10779 {
10780   ctype ct = uentry_getType (ue);
10781
10782   if (ctype_isFunction (ct))
10783     {
10784       return (ctype_isRefCounted (ctype_getReturnType (ct)));
10785     }
10786   else
10787     {
10788       return (ctype_isRefCounted (ct));
10789     }
10790 }
10791
10792 /*
10793 ** old was declared yield in the specification.  
10794 ** new is declared in the iter implementation.
10795 */
10796
10797 void uentry_checkYieldParam (uentry old, uentry unew)
10798 {
10799   cstring name;
10800
10801   llassert (uentry_isVariable (old));
10802   llassert (uentry_isVariable (unew));
10803
10804   unew->info->var->kind = VKYIELDPARAM;
10805   (void) checkTypeConformance (old, unew, TRUE);
10806   checkVarConformance (old, unew, TRUE, FALSE);
10807
10808   /* get rid of param marker */
10809
10810   name = uentry_getName (unew);
10811   cstring_free (unew->uname);
10812   unew->uname = name;
10813   unew->info->var->kind = VKREFYIELDPARAM;
10814
10815   uentry_setUsed (old, fileloc_undefined);
10816   uentry_setUsed (unew, fileloc_undefined);
10817 }
10818
10819 /*@observer@*/ cstring
10820 uentry_ekindName (uentry ue)
10821 {
10822   if (uentry_isValid (ue))
10823     {
10824       switch (ue->ukind)
10825         {
10826         case KINVALID:
10827           return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10828         case KDATATYPE: 
10829           return cstring_makeLiteralTemp ("Datatype");
10830         case KENUMCONST:
10831           return cstring_makeLiteralTemp ("Enum member");
10832         case KCONST:  
10833           return cstring_makeLiteralTemp ("Constant");
10834         case KVAR:      
10835           if (uentry_isParam (ue))
10836             {
10837               return cstring_makeLiteralTemp ("Parameter");
10838             }
10839           else if (uentry_isExpandedMacro (ue))
10840             {
10841               return cstring_makeLiteralTemp ("Expanded macro");
10842             }
10843           else
10844             {
10845               return cstring_makeLiteralTemp ("Variable");
10846             }
10847         case KFCN:   
10848           return cstring_makeLiteralTemp ("Function");
10849         case KITER: 
10850           return cstring_makeLiteralTemp ("Iterator");
10851         case KENDITER:
10852           return cstring_makeLiteralTemp ("Iterator finalizer");
10853         case KSTRUCTTAG:
10854           return cstring_makeLiteralTemp ("Struct tag");
10855         case KUNIONTAG:
10856           return cstring_makeLiteralTemp ("Union tag");
10857         case KENUMTAG: 
10858           return cstring_makeLiteralTemp ("Enum tag");
10859         case KELIPSMARKER: 
10860           return cstring_makeLiteralTemp ("Optional parameters");
10861         }
10862     }
10863   else
10864     {
10865       return cstring_makeLiteralTemp ("<Undefined>");
10866     }
10867
10868   BADEXIT;
10869 }
10870
10871 /*@observer@*/ cstring
10872 uentry_ekindNameLC (uentry ue)
10873 {
10874   if (uentry_isValid (ue))
10875     {
10876       switch (ue->ukind)
10877         {
10878         case KINVALID:
10879           return cstring_makeLiteralTemp ("<error: invalid uentry>");
10880         case KDATATYPE: 
10881           return cstring_makeLiteralTemp ("datatype");
10882         case KENUMCONST:
10883           return cstring_makeLiteralTemp ("enum member");
10884         case KCONST:  
10885           return cstring_makeLiteralTemp ("constant");
10886         case KVAR:      
10887           if (uentry_isParam (ue))
10888             {
10889               return cstring_makeLiteralTemp ("parameter");
10890             }
10891           else if (uentry_isExpandedMacro (ue))
10892             {
10893               return cstring_makeLiteralTemp ("expanded macro");
10894             }
10895           else
10896             {
10897               return cstring_makeLiteralTemp ("variable");
10898             }
10899         case KFCN:   
10900           return cstring_makeLiteralTemp ("function");
10901         case KITER: 
10902           return cstring_makeLiteralTemp ("iterator");
10903         case KENDITER:
10904           return cstring_makeLiteralTemp ("iterator finalizer");
10905         case KSTRUCTTAG:
10906           return cstring_makeLiteralTemp ("struct tag");
10907         case KUNIONTAG:
10908           return cstring_makeLiteralTemp ("union tag");
10909         case KENUMTAG: 
10910           return cstring_makeLiteralTemp ("enum tag");
10911         case KELIPSMARKER: 
10912           return cstring_makeLiteralTemp ("optional parameters");
10913         }
10914     }
10915   else
10916     {
10917       return cstring_makeLiteralTemp ("<Undefined>");
10918     }
10919
10920   BADEXIT;
10921 }
10922
10923 void uentry_setHasNameError (uentry ue)
10924 {
10925   llassert (uentry_isValid (ue));
10926
10927   ue->hasNameError = TRUE;
10928 }
10929
10930 void uentry_checkName (uentry ue)
10931 {
10932   DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10933             uentry_observeRealName (ue),
10934             bool_unparse (uentry_isVisibleExternally (ue))));
10935   
10936   if (uentry_isValid (ue) 
10937       && !context_inXHFile ()
10938       && uentry_hasName (ue)
10939       && !uentry_isElipsisMarker (ue)
10940       && context_getFlag (FLG_NAMECHECKS)
10941       && !ue->hasNameError 
10942       && !uentry_isEndIter (ue)
10943       && !fileloc_isBuiltin (uentry_whereLast (ue))
10944       && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10945     {      
10946       DPRINTF (("Here..."));
10947
10948       if (uentry_isPriv (ue))
10949         {
10950           ; /* any checks here? */
10951         }
10952       else if (fileloc_isExternal (uentry_whereDefined (ue)))
10953         {
10954           ; /* no errors for externals */
10955         }
10956       else
10957         {
10958           int scope;
10959           
10960           if (uentry_isExpandedMacro (ue))
10961             {
10962               scope = globScope;
10963             }
10964           else
10965             {
10966               if (uentry_isExpandedMacro (ue))
10967                 {
10968                   scope = fileScope;
10969                 }
10970               else if (uentry_isVariable (ue))
10971                 {
10972                   sRef sr = uentry_getSref (ue);
10973
10974                   if (sRef_isValid (sr))
10975                     {
10976                       scope = sRef_getScope (sr);
10977                     }
10978                   else
10979                     {
10980                       scope = fileScope; 
10981                     }
10982                 }
10983               else if (uentry_isFunction (ue)
10984                        || uentry_isIter (ue)
10985                        || uentry_isEndIter (ue)
10986                        || uentry_isConstant (ue))
10987                 {
10988                   scope = uentry_isStatic (ue) ? fileScope : globScope;
10989                 }
10990               else /* datatypes, etc. must be global */
10991                 {
10992                   scope = globScope;
10993                 }
10994               
10995               usymtab_checkDistinctName (ue, scope);
10996             }
10997         
10998           if (context_getFlag (FLG_CPPNAMES)) 
10999             {
11000               checkCppName (ue);
11001             }
11002
11003           if (scope == globScope)
11004             {
11005               checkExternalName (ue);
11006             }
11007           else if (scope == fileScope)
11008             {
11009               checkFileScopeName (ue);
11010             }
11011           else 
11012             {
11013               checkLocalName (ue);
11014             }
11015
11016           checkPrefix (ue);
11017           checkAnsiName (ue);
11018         }
11019     }
11020 }
11021
11022 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11023 {
11024   uentry ue;
11025   fileloc tloc;
11026
11027   /*
11028   ** Can't but unrecognized ids in macros in global scope, because srefs will break! 
11029   */
11030
11031   if (!context_inMacro ())
11032     {
11033       sRef_setGlobalScopeSafe ();
11034     }
11035
11036   ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11037   uentry_setUsed (ue, loc);               
11038   
11039   tloc = fileloc_createExternal ();
11040   uentry_setDefined (ue, tloc);
11041   fileloc_free (tloc);
11042   uentry_setHasNameError (ue);
11043   
11044   if (context_getFlag (FLG_REPEATUNRECOG))
11045     {
11046       uentry_markOwned (ue);
11047     }
11048   else
11049     {
11050       ue = usymtab_supReturnFileEntry (ue);
11051     }
11052   
11053   if (!context_inMacro ())
11054     {
11055       sRef_clearGlobalScopeSafe ();
11056     }
11057
11058   return ue;
11059 }
11060
11061 uentry uentry_makeGlobalMarker ()
11062 {
11063   uentry ue;
11064   fileloc tloc;
11065
11066   llassert (sRef_inGlobalScope ());
11067   
11068   ue = uentry_makeVariableAux
11069     (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined, 
11070      sRef_makeGlobalMarker (),
11071      FALSE, VKNORMAL);
11072
11073   tloc = fileloc_createExternal ();
11074   uentry_setUsed (ue, tloc);              
11075   uentry_setDefined (ue, tloc);
11076   fileloc_free (tloc);
11077   uentry_setHasNameError (ue);  
11078
11079   return ue;
11080 }
11081
11082
11083 bool uentry_isGlobalMarker (uentry ue)
11084 {
11085   return (uentry_isValid (ue)
11086           && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11087 }
11088
11089 /* new start modifications */
11090
11091 /* start modifications */
11092 /*
11093 requires: p_e is defined, is a ptr/array variable 
11094 modifies: p_e
11095 effects: sets the state of the variable
11096 */
11097
11098
11099 void uentry_setPossiblyNullTerminatedState (uentry p_e)  {
11100   /*@access sRef@*/ /*i523 shouldn't do this! */
11101   if( uentry_isValid(p_e) ) {
11102     if( p_e->info != NULL) {
11103       if( p_e->info->var != NULL) {
11104          p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11105          p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11106          return;
11107       }
11108     }
11109   }
11110   /*@noaccess sRef@*/
11111
11112   fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11113 }
11114
11115 /*
11116 requires: p_e is defined, is a ptr/array variable 
11117 modifies: p_e
11118 effects: sets the size of the buffer
11119 */
11120
11121 void uentry_setNullTerminatedState (uentry p_e)  {
11122   if( uentry_isValid(p_e) ) {
11123     if( p_e->info != NULL) {
11124       if( p_e->info->var != NULL) {
11125         p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11126         /*@access sRef@*/ /*@i523 bad!*/
11127         p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11128         /*@noaccess sRef@*/ 
11129         return;
11130       }
11131     }
11132   }
11133
11134   fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11135 }
11136
11137 /*
11138 requires: p_e is defined, is a ptr/array variable 
11139 modifies: p_e
11140 effects: sets the size of the buffer
11141 */
11142
11143 void uentry_setSize (uentry p_e, int size)  {
11144   if( uentry_isValid(p_e) ) {
11145     if( p_e->info != NULL) {
11146       if( p_e->info->var != NULL) {
11147         p_e->info->var->bufinfo->size = size;
11148         /*@access sRef@*/ /*@i523 bad!*/
11149         p_e->sref->bufinfo.size = size;
11150         /*@noaccess sRef@*/
11151         return;
11152       }
11153     }
11154   }
11155
11156   fprintf(stderr, "uentry:Error in setSize\n");
11157 }
11158
11159
11160 /*
11161 requires: p_e is defined, is a ptr/array variable 
11162 modifies: p_e
11163 effects: sets the length of the buffer
11164 */
11165
11166 void uentry_setLen (uentry p_e, int len)  {
11167   if( uentry_isValid(p_e) ) {
11168     if( p_e->info != NULL) {
11169       if( p_e->info->var != NULL) {
11170         p_e->info->var->bufinfo->len = len;
11171         /*@access sRef@*/ /*@i523 bad!*/
11172         p_e->sref->bufinfo.len = len;
11173         /*@noaccess sRef@*/
11174         return;
11175       }
11176     }
11177   }
11178   
11179   fprintf(stderr, "uentry:Error in setLen\n");
11180 }
11181
11182 /*@=type*/
11183
11184 bool uentry_hasMetaStateEnsures (uentry e)
11185 {
11186   if (uentry_isValid (e) && uentry_isFunction (e))
11187     {
11188       return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11189     }
11190   else
11191     {
11192       return FALSE;
11193     }
11194 }
11195
11196 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11197 {
11198   llassert (uentry_isValid (e) && uentry_isFunction (e));
11199   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11200 }
This page took 0.949166 seconds and 5 git commands to generate.