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