]> andersk Git - splint.git/blob - src/uentry.c
Making fixes for Microsoft Visual C++ compiler.
[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 ekind
5809 uentry_getKind (uentry e)
5810 {
5811   llassert (uentry_isValid (e));
5812   return (e->ukind);
5813 }
5814
5815 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5816 {
5817   llassert (uentry_isEitherConstant (e)); 
5818   return (sRef_getValue (e->sref));
5819 }
5820
5821 /*@observer@*/ uentryList
5822 uentry_getParams (uentry l)
5823 {
5824   if (uentry_isInvalid (l)) return uentryList_undefined;
5825
5826   switch (l->ukind)
5827     {
5828     case KFCN:  
5829     case KITER:
5830       {
5831         ctype ct = l->utype;
5832
5833         if (ctype_isFunction (ct))
5834           {
5835             return (ctype_argsFunction (ct));
5836           }
5837         else
5838           {
5839             return uentryList_undefined;
5840           }
5841       }
5842     case KVAR:  
5843       {
5844         ctype ct = l->utype;
5845
5846         /*drl 12/10/2002 changed to fix bug involving multiple redefines of library functions in macros.  Bug was reported by  Malcolm Parsons
5847
5848         Old code was  simplly llassert (ctype_isFunction (ct) );
5849         */
5850         
5851         llassert (ctype_isFunction (ct) || context_inMacro() );
5852         
5853         return (ctype_argsFunction (ct));
5854       }
5855     BADDEFAULT;
5856     }
5857   BADEXIT;
5858 }
5859
5860 /*@observer@*/ cstring
5861 uentry_rawName (uentry e)
5862 {
5863   if (uentry_isValid (e))
5864     {
5865       return (e->uname);
5866     }
5867   else
5868     {
5869       return cstring_undefined;
5870     }
5871 }
5872
5873 static cstring
5874 uentry_getOptName (uentry e)
5875 {
5876   cstring s = uentry_getName (e);
5877
5878   if (cstring_isDefined (s))
5879     {
5880       s = cstring_appendChar (s, ' ');
5881     }
5882   
5883   return s;
5884 }
5885
5886 /*@only@*/ cstring
5887 uentry_getName (uentry e)
5888 {
5889   cstring ret = cstring_undefined;
5890
5891   if (uentry_isValid (e))
5892     {
5893       if (uentry_isAnyTag (e))
5894         {
5895           ret = fixTagName (e->uname);  
5896         }
5897       else if (uentry_isAnyParam (e))
5898         {
5899           ret = cstring_copy (fixParamName (e->uname));
5900         }
5901       else
5902         {
5903           ret = cstring_copy (e->uname);
5904         }
5905     }
5906
5907   return ret;
5908 }
5909
5910 cstring uentry_observeRealName (uentry e)
5911 {
5912   cstring ret = cstring_undefined;
5913
5914   if (uentry_isValid (e))
5915     {      
5916       if (uentry_isAnyTag (e))
5917         {
5918           if (isFakeTag (e->uname))
5919             {
5920               ret = cstring_undefined;
5921             }
5922           else
5923             {
5924               ret = plainTagName (e->uname); 
5925             }
5926         }
5927       else if (uentry_isAnyParam (e))
5928         {
5929           ret = fixParamName (e->uname);
5930         }
5931       else
5932         {
5933           ret = e->uname;
5934         }
5935     }
5936
5937   return ret;
5938 }
5939
5940 cstring uentry_getRealName (uentry e)
5941 {
5942   if (uentry_isValid (e))
5943     {
5944       if (uentry_isAnyTag (e))
5945         {
5946           return (cstring_undefined);
5947         }
5948       else
5949         {
5950           return (e->uname);
5951         }
5952     }
5953   return cstring_undefined;
5954 }
5955
5956 ctype uentry_getType (uentry e)
5957 {
5958   if (uentry_isValid (e))
5959     {
5960       return e->utype;
5961     }
5962   else
5963     {
5964       return ctype_unknown;
5965     }
5966 }
5967
5968 fileloc uentry_whereLast (uentry e)
5969 {
5970   fileloc loc;
5971
5972   if (uentry_isInvalid (e)) 
5973     {
5974       return fileloc_undefined;
5975     }
5976   
5977   loc = e->whereDefined;
5978
5979   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5980     {
5981       return loc;
5982     }
5983
5984   loc = uentry_whereDeclared (e);
5985
5986   if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5987     {
5988       return loc;
5989     }
5990
5991   loc = uentry_whereSpecified (e);
5992   return loc;
5993 }
5994
5995 fileloc uentry_whereEither (uentry e)
5996 {
5997   if (uentry_isInvalid (e)) return fileloc_undefined;
5998
5999   if (fileloc_isDefined (e->whereDefined) 
6000       && !fileloc_isExternal (e->whereDefined))
6001     {
6002       return e->whereDefined;
6003     }
6004   else if (fileloc_isDefined (e->whereDeclared))
6005     {
6006       return e->whereDeclared;
6007     }
6008   else
6009     {
6010       return e->whereSpecified;
6011     }
6012 }
6013
6014 fileloc uentry_whereSpecified (uentry e)
6015 {
6016   if (uentry_isInvalid (e)) return fileloc_undefined;
6017
6018   return (e->whereSpecified);
6019 }
6020
6021 fileloc uentry_whereDefined (uentry e)
6022 {
6023   if (uentry_isInvalid (e)) return fileloc_undefined;
6024
6025   return (e->whereDefined);
6026 }
6027
6028 fileloc uentry_whereDeclared (uentry e)
6029 {
6030   if (uentry_isInvalid (e)) return fileloc_undefined;
6031
6032   return (e->whereDeclared);
6033 }
6034
6035 /*@observer@*/ fileloc
6036 uentry_whereEarliest (uentry e)
6037 {
6038   if (uentry_isInvalid (e)) return fileloc_undefined;
6039   
6040   if (fileloc_isDefined (e->whereSpecified))
6041     {
6042       return (e->whereSpecified);
6043     }
6044   else if (fileloc_isDefined (e->whereDeclared))
6045     {
6046       return (e->whereDeclared);
6047     }
6048   else
6049     {
6050       return e->whereDefined;
6051     }
6052 }
6053
6054 void
6055 uentry_setFunctionDefined (uentry e, fileloc loc)
6056 {
6057   if (uentry_isValid (e))
6058     {
6059       llassert (uentry_isFunction (e));
6060
6061       if (fileloc_isUndefined (e->whereDeclared))
6062         {
6063           e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6064         }
6065       
6066       if (!fileloc_isDefined (e->whereDefined))
6067         {
6068           e->whereDefined = fileloc_update (e->whereDefined, loc);
6069         }
6070     }
6071 }
6072
6073 void
6074 uentry_setDeclDef (uentry e, fileloc f)
6075 {
6076   uentry_setDeclared (e, f);
6077   
6078   if (!uentry_isFunction (e)
6079       && !(uentry_isVariable (e) && uentry_isExtern (e)))
6080     {
6081       uentry_setDefined (e, f);
6082     }
6083 }
6084
6085 void
6086 uentry_setDeclaredForce (uentry e, fileloc f)
6087 {
6088   llassert (uentry_isValid (e));
6089   e->whereDeclared = fileloc_update (e->whereDeclared, f);
6090 }
6091
6092 void
6093 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6094 {
6095   llassert (uentry_isValid (e));
6096   fileloc_free (e->whereDeclared);
6097   e->whereDeclared = f;
6098 }
6099
6100 void
6101 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6102 {
6103   fileloc oldloc;
6104
6105   llassert (uentry_isValid (e));
6106   oldloc = e->whereDeclared;  
6107
6108   if (fileloc_isDefined (oldloc))
6109     {
6110       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6111         {
6112           e->whereDeclared = f;
6113           fileloc_free (oldloc);
6114         }
6115       else
6116         {
6117           fileloc_free (f);
6118         }
6119     }
6120   else
6121     {
6122       e->whereDeclared = f;
6123       fileloc_free (oldloc);
6124     }
6125 }
6126   
6127 void
6128 uentry_setDeclared (uentry e, fileloc f)
6129 {
6130   fileloc oldloc;
6131
6132   llassert (uentry_isValid (e));
6133   oldloc = e->whereDeclared;  
6134
6135   if (fileloc_isDefined (oldloc))
6136     {
6137       if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6138         {
6139           e->whereDeclared = fileloc_update (e->whereDeclared, f);
6140         }
6141       else
6142         {
6143           ;
6144         }
6145     }
6146   else
6147     {
6148       e->whereDeclared = fileloc_update (e->whereDeclared, f);
6149     }
6150 }
6151
6152 void
6153 uentry_clearDefined (uentry e)
6154 {
6155   if (uentry_isValid (e))
6156     {
6157       e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6158     }
6159 }
6160
6161 void
6162 uentry_setDefined (uentry e, fileloc f)
6163 {
6164   fileloc oldloc;
6165
6166   llassert (uentry_isValid (e));
6167   oldloc = e->whereDefined;
6168
6169   if (fileloc_isDefined (oldloc))
6170     {
6171       if (fileloc_isLib (oldloc) 
6172           || fileloc_isImport (oldloc)
6173           || fileloc_isBuiltin (oldloc) 
6174           || fileloc_isPreproc (oldloc))
6175         {
6176           e->whereDefined = fileloc_update (e->whereDefined, f);
6177         }
6178       else
6179         {
6180           if (fileloc_equal (oldloc, f) || context_processingMacros ())
6181             {
6182               ; /* okay */
6183             }
6184           else
6185             {
6186               if (optgenerror (FLG_REDEF,
6187                                message ("%s %q redefined", 
6188                                         ekind_capName (e->ukind),
6189                                         uentry_getName (e)),
6190                                f))
6191                 {
6192                   llgenindentmsg (message ("Previous definition of %q", 
6193                                            uentry_getName (e)),
6194                                   e->whereDefined);
6195                 }
6196             }
6197         }
6198     }
6199   else
6200     {
6201       e->whereDefined = fileloc_update (e->whereDefined, f);
6202     }
6203 }
6204
6205 bool
6206 uentry_isCodeDefined (uentry e)
6207 {
6208   llassert (uentry_isValid (e));
6209
6210   return (fileloc_isDefined (e->whereDefined));
6211 }
6212
6213 bool
6214 uentry_isDeclared (uentry e)
6215 {
6216   if (uentry_isValid (e))
6217     {
6218       return (fileloc_isDefined (e->whereDeclared));
6219     }
6220
6221   return FALSE;
6222 }
6223
6224 sRef uentry_getSref (uentry e)
6225 {
6226   /* not true, used for functions too (but shouldn't be? */
6227   /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6228
6229   if (uentry_isInvalid (e)) return sRef_undefined;
6230   
6231   return (e->sref);
6232 }
6233
6234 sRef uentry_getOrigSref (uentry e)
6235 {
6236   /* evans 2003-04-12 - removed for now */
6237   /* evans 2001-09-09 - need to fix this 
6238   if (uentry_isValid (e))
6239     {
6240       if (uentry_isVariable (e))
6241         {
6242           return e->info->var->origsref;
6243         }
6244       else
6245         {
6246           sRef sr = sRef_copy (uentry_getSref (e));
6247           
6248           sRef_resetState (sr);
6249           sRef_clearDerived (sr);
6250           return (sr);
6251         }
6252     }
6253   else
6254     {
6255       return sRef_undefined;
6256     }
6257   */
6258
6259   if (uentry_isValid (e))
6260     {
6261       sRef sr = sRef_copy (uentry_getSref (e));
6262       
6263       sRef_resetState (sr);
6264       sRef_clearDerived (sr);
6265       
6266       if (uentry_isVariable (e))
6267         {
6268           sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6269           sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6270         }
6271       
6272       return (sr);
6273     }
6274   else
6275     {
6276       return sRef_undefined;
6277     }
6278 }
6279
6280 /*
6281 ** requires: uentry e is not in a hashed symbol table
6282 */
6283
6284 void 
6285 uentry_setName (uentry e, /*@only@*/ cstring n)
6286 {
6287   llassert (uentry_isValid (e));
6288
6289   cstring_free (e->uname);
6290   e->uname = n;
6291 }
6292
6293 void
6294 uentry_setType (uentry e, ctype t)
6295 {
6296   if (uentry_isValid (e)) 
6297     {
6298       e->utype = t;
6299       sRef_setType (e->sref, t);
6300     }
6301 }
6302
6303 void
6304 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6305 {
6306   ctype rct;
6307   ctype rettype = ctype_unknown;
6308   
6309   llassert (uentry_isValid (ue));
6310
6311   uentry_convertVarFunction (ue);
6312   llassert (uentry_isFunction (ue));
6313
6314   rct = ctype_realType (ue->utype);
6315
6316   if (ctype_isFunction (rct))
6317     {
6318       rettype = ctype_getReturnType (rct);
6319     }
6320
6321   ue->utype = ctype_makeNFParamsFunction (rettype, pn);      
6322 }
6323
6324 void
6325 uentry_setRefParam (uentry e)
6326 {
6327   if (!uentry_isVar (e))
6328     {
6329       llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6330     }
6331   else
6332     {
6333       if (e->info->var->kind == VKSEFPARAM)
6334         {
6335           e->info->var->kind = VKREFSEFPARAM;
6336         }
6337       else if (e->info->var->kind == VKSEFRETPARAM)
6338         {
6339           e->info->var->kind = VKREFSEFRETPARAM;
6340         }
6341       else if (e->info->var->kind == VKYIELDPARAM)
6342         {
6343           e->info->var->kind = VKREFYIELDPARAM;
6344         }
6345       else
6346         {
6347           e->info->var->kind = VKREFPARAM;
6348         }
6349     }
6350 }
6351
6352 void
6353 uentry_setParam (uentry e)
6354 {
6355   if (!uentry_isVar (e))
6356     {
6357       if (uentry_isElipsisMarker (e))
6358         {
6359
6360         }
6361       else
6362         {
6363           llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6364         }
6365     }
6366   else
6367     {
6368       cstring oldname;
6369
6370       if (e->info->var->kind == VKYIELDPARAM 
6371           || e->info->var->kind == VKSEFPARAM
6372           || e->info->var->kind == VKSEFRETPARAM)
6373         {
6374           ;
6375         }
6376       else
6377         {
6378           e->info->var->kind = VKPARAM;
6379         }
6380
6381       oldname = e->uname;
6382       e->uname = makeParam (e->uname);
6383       cstring_free (oldname);
6384     }
6385 }
6386
6387 void
6388 uentry_setSref (uentry e, sRef s)
6389 {
6390   if (uentry_isValid (e))
6391     {
6392       if (sRef_isValid (e->sref))
6393         {
6394           sRef_mergeStateQuietReverse (e->sref, s);
6395         }
6396       else
6397         {
6398           e->sref = sRef_saveCopy (s);
6399         }
6400     }
6401 }
6402
6403 ctype
6404 uentry_getAbstractType (uentry e)
6405 {
6406   llassert (uentry_isDatatype (e));
6407
6408   /*
6409   ** This assertion removed.
6410   ** Okay to have undefined type, for system types
6411   
6412   llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6413                     ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6414                     e->utype);
6415                     
6416   */
6417
6418   if (ctype_isUndefined (e->info->datatype->type))
6419     {
6420       return ctype_unknown;
6421     }
6422
6423   /*
6424   ** Sadly, a kludge...
6425   */
6426
6427   if (ctype_isUserBool (e->info->datatype->type)) {
6428     return ctype_bool;
6429   }
6430
6431   return e->info->datatype->type;
6432 }
6433
6434 ctype uentry_getRealType (uentry e)
6435 {
6436   ctype ct;
6437   typeId uid = typeId_invalid;
6438
6439   if (uentry_isInvalid (e))
6440     {
6441       return ctype_unknown;
6442     }
6443
6444   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6445
6446   if (uentry_isAnyTag (e))
6447     {
6448       return (e->utype);
6449     }
6450   
6451   if (uentry_isAbstractType (e))
6452     {
6453       ct = uentry_getAbstractType (e);      
6454
6455       if (ctype_isManifestBool (ct)) {
6456         return ct;
6457       }
6458
6459       llassert (ctype_isUA (ct));
6460       
6461       uid = ctype_typeId (ct);
6462       
6463       if (!context_hasAccess (uid))
6464         {
6465           return (ct);
6466         }
6467     }
6468
6469   ct = uentry_getType (e);
6470
6471   /* if (ctype_isUserBool (ct)) return ct; */
6472
6473   if (ctype_isManifestBool (ct)) {
6474     return ctype_bool;
6475   }
6476   
6477   if (ctype_isUA (ct))
6478     {
6479       typeId iid = ctype_typeId (ct);
6480       
6481       if (typeId_equal (iid, uid))
6482         {         
6483           llcontbug (message ("uentry_getRealType: recursive type! %s",
6484                               ctype_unparse (ct)));
6485           return ct;
6486         }
6487       else
6488         {
6489           /* evs 2000-07-25: possible infinite recursion ? */
6490           uentry ue2 = usymtab_getTypeEntry (iid);
6491
6492           if (ue2 == e)
6493             {
6494               llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6495               return ctype_unknown;
6496             }
6497
6498           return uentry_getRealType (ue2);
6499         }
6500     }
6501   else
6502     {
6503       return ct;
6504     }
6505 }
6506
6507 ctype uentry_getForceRealType (uentry e)
6508 {
6509   ctype   ct;
6510   typeId uid = typeId_invalid;
6511
6512   if (uentry_isInvalid (e))
6513     {
6514       return ctype_unknown;
6515     }
6516
6517   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6518   
6519   if (uentry_isAnyTag (e))
6520     {
6521       return (e->utype);
6522     }
6523   
6524   if (uentry_isAbstractType (e))
6525     {
6526       ct = uentry_getAbstractType (e);      
6527       llassert (ctype_isUA (ct));
6528       
6529       uid = ctype_typeId (ct);
6530       /* no check for access! */
6531     }
6532   
6533   ct = uentry_getType (e);
6534
6535   /* evs 2000-07-25 */
6536   /* if (ctype_isUserBool (ct)) return ct; */
6537
6538   if (ctype_isManifestBool (ct)) {
6539     return ctype_bool;
6540   }
6541   
6542   if (ctype_isUA (ct))
6543     {
6544       typeId iid = ctype_typeId (ct);
6545       
6546       if (typeId_equal (iid, uid))
6547         {         
6548           llcontbug (message ("uentry_getRealType: recursive type! %s",
6549                               ctype_unparse (ct)));
6550           return ct;
6551         }
6552       else
6553         {
6554           return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6555         }
6556     }
6557   else
6558     {
6559       return ct;
6560     }
6561 }
6562
6563 uentry uentry_nameCopy (cstring name, uentry e)
6564 {
6565   uentry enew = uentry_alloc ();
6566
6567   llassert (uentry_isValid (e));
6568
6569   /* enew->shallowCopy = FALSE; */
6570   enew->ukind = e->ukind;
6571   enew->uname = name;
6572   enew->utype = e->utype;
6573   enew->whereSpecified = fileloc_copy (e->whereSpecified);
6574   enew->whereDefined = fileloc_copy (e->whereDefined);
6575   enew->whereDeclared = fileloc_copy (e->whereDeclared);
6576   enew->sref = sRef_copy (e->sref); 
6577   enew->used = e->used;
6578   enew->lset = FALSE;
6579   enew->isPrivate = e->isPrivate;
6580   enew->hasNameError = FALSE;
6581
6582   enew->uses = filelocList_new ();
6583   enew->warn = warnClause_undefined; 
6584
6585   enew->storageclass = e->storageclass;
6586   enew->info = uinfo_copy (e->info, e->ukind);
6587
6588   return enew;
6589 }
6590
6591 void
6592 uentry_setDatatype (uentry e, typeId uid)
6593 {
6594   llassert (uentry_isDatatype (e));
6595
6596   if (uentry_isAbstractType (e))
6597     {
6598       if (qual_isNumAbstract (e->info->datatype->abs)) 
6599         {
6600           e->info->datatype->type = ctype_createNumAbstract (uid);
6601         }
6602       else
6603         {
6604           llassert (qual_isAbstract (e->info->datatype->abs));
6605           e->info->datatype->type = ctype_createAbstract (uid);
6606         }
6607     }
6608   else
6609     {
6610       e->info->datatype->type = ctype_createUser (uid);
6611     }
6612 }
6613
6614 static void 
6615 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6616    /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6617    /*@modifies e@*/
6618 {
6619   llassert (uentry_isValid (e));
6620
6621   if (fileloc_isSpec (f) || fileloc_isImport (f))
6622     {
6623       e->whereSpecified = f;
6624       e->whereDeclared  = fileloc_undefined;
6625       e->whereDefined  = fileloc_undefined;
6626     }
6627   else
6628     {
6629       e->whereSpecified = fileloc_undefined;
6630       e->whereDeclared  = f;
6631       e->whereDefined  = fileloc_undefined;
6632     }
6633
6634   llassert (fileloc_storable (f));
6635 }
6636
6637 static void
6638 ucinfo_free (/*@only@*/ ucinfo u)
6639 {
6640   sfree (u);
6641 }
6642
6643 static void
6644 uvinfo_free (/*@only@*/ uvinfo u)
6645 {
6646   /*drl7x added 6/29/01 */
6647   free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6648   sfree (u);
6649 }
6650
6651 static void
6652 udinfo_free (/*@only@*/ udinfo u)
6653 {
6654   sfree (u);
6655 }
6656
6657 static void
6658 ufinfo_free (/*@only@*/ ufinfo u)
6659 {
6660   globSet_free (u->globs);
6661   sRefSet_free (u->mods);
6662   stateClauseList_free (u->specclauses);
6663   sfree (u);
6664 }
6665
6666 static void
6667 uiinfo_free (/*@only@*/ uiinfo u)
6668 {
6669   sfree (u);
6670 }
6671
6672 static void
6673 ueinfo_free (/*@only@*/ ueinfo u)
6674 {
6675   sfree (u);
6676 }
6677
6678 static /*@only@*/ ucinfo
6679 ucinfo_copy (ucinfo u)
6680 {
6681   ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6682   ret->access = u->access;
6683   ret->macro = u->macro;
6684   return ret;
6685 }
6686
6687 static /*@only@*/ uvinfo
6688 uvinfo_copy (uvinfo u)
6689 {
6690   uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6691   
6692   ret->kind = u->kind;
6693   ret->nullstate = u->nullstate;
6694   ret->defstate = u->defstate;
6695   ret->checked = u->checked;
6696
6697
6698   /* drl added 07-02-001 */
6699   /* copy null terminated information */
6700
6701   if (u->bufinfo != NULL)
6702     {
6703       ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6704       ret->bufinfo->bufstate = u->bufinfo->bufstate;
6705       ret->bufinfo->size     = u->bufinfo->size;
6706       ret->bufinfo->len      = u->bufinfo->len;
6707       return ret;
6708     }
6709   else
6710     {
6711       ret->bufinfo = NULL;
6712       return ret;
6713     }
6714     
6715 }
6716
6717 static /*@only@*/ udinfo
6718 udinfo_copy (udinfo u)
6719 {
6720   udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6721
6722   ret->abs = u->abs;
6723   ret->mut = u->mut;
6724   ret->type = u->type;
6725
6726   return ret;
6727 }
6728
6729 static /*@only@*/ ufinfo
6730 ufinfo_copy (ufinfo u)
6731 {
6732   ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6733
6734   ret->hasGlobs = u->hasGlobs;
6735   ret->hasMods = u->hasMods;
6736   ret->exitCode = u->exitCode;
6737   ret->specialCode = u->specialCode;
6738   ret->nullPred = u->nullPred;
6739   ret->access = u->access;
6740   ret->globs = globSet_newCopy (u->globs);
6741   ret->mods = sRefSet_newCopy (u->mods);
6742   ret->defparams = u->defparams;
6743   ret->specclauses = stateClauseList_copy (u->specclauses);
6744
6745   ret->preconditions = functionConstraint_copy (u->preconditions);
6746   ret->postconditions = functionConstraint_copy (u->postconditions);
6747   
6748   return ret;
6749 }
6750
6751 static /*@only@*/ uiinfo
6752 uiinfo_copy (uiinfo u)
6753 {
6754   uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6755
6756   ret->access = u->access;
6757   ret->globs = globSet_newCopy (u->globs);
6758   ret->mods = sRefSet_newCopy (u->mods);
6759
6760   return (ret);
6761 }
6762
6763 static /*@only@*/ ueinfo
6764 ueinfo_copy (ueinfo u)
6765 {
6766   ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6767
6768   ret->access = u->access;
6769   return ret;
6770 }
6771
6772 static void
6773 uinfo_free (uinfo u, ekind kind)
6774 {
6775   switch (kind)
6776     {
6777     case KENUMCONST:
6778     case KCONST:       ucinfo_free (u->uconst); break;
6779     case KVAR:         uvinfo_free (u->var); break;
6780     case KSTRUCTTAG:
6781     case KUNIONTAG:
6782     case KENUMTAG:
6783     case KDATATYPE:    udinfo_free (u->datatype); break;
6784     case KFCN:         ufinfo_free (u->fcn); break;
6785     case KITER:        uiinfo_free (u->iter); break;
6786     case KENDITER:     ueinfo_free (u->enditer); break;
6787     case KELIPSMARKER: break;
6788     case KINVALID:     break;
6789     }
6790   
6791     sfree (u);
6792 }
6793
6794 static /*@only@*/ /*@null@*/ uinfo
6795 uinfo_copy (uinfo u, ekind kind)
6796 {
6797   if (kind == KELIPSMARKER || kind == KINVALID)
6798     {
6799       return NULL;
6800     }
6801   else
6802     {
6803       uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6804       
6805       switch (kind)
6806         {
6807         case KENUMCONST:
6808         case KCONST:    ret->uconst = ucinfo_copy (u->uconst); break;
6809         case KVAR:      ret->var = uvinfo_copy (u->var); break;
6810         case KSTRUCTTAG:
6811         case KUNIONTAG:
6812         case KENUMTAG:
6813         case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6814         case KFCN:      ret->fcn = ufinfo_copy (u->fcn); break;
6815         case KITER:     ret->iter = uiinfo_copy (u->iter); break;
6816         case KENDITER:  ret->enditer = ueinfo_copy (u->enditer); break;
6817         BADDEFAULT;
6818         }
6819       return ret;
6820     }
6821 }
6822
6823 static void
6824 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6825 {
6826   filelocList_free (e->uses);
6827   cstring_free (e->uname);
6828   
6829   uinfo_free (e->info, e->ukind);
6830   
6831   fileloc_free (e->whereSpecified); 
6832   fileloc_free (e->whereDefined); 
6833   fileloc_free (e->whereDeclared); 
6834
6835   warnClause_free (e->warn);
6836
6837   nuentries--;
6838   sfree (e);
6839 }
6840
6841 extern void uentry_markOwned (/*@owned@*/ uentry u)
6842 {
6843   sfreeEventually (u);
6844 }
6845
6846 void
6847 uentry_free (/*@only@*/ uentry e)
6848 {
6849   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6850     {
6851       uentry_reallyFree (e);
6852     }
6853 }
6854
6855 /*
6856 ** For uentry's in the global or file scope
6857 */
6858
6859 void
6860 uentry_freeComplete (/*@only@*/ uentry e)
6861 {
6862   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6863     {
6864       DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6865       /*@i@*/ sRef_free (e->sref);
6866       e->sref = sRef_undefined;
6867       uentry_reallyFree (e);
6868     }
6869 }
6870
6871 /*
6872 ** requires old->kind != new->kind, old->uname = new->uname
6873 */
6874
6875 static void
6876 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6877 {
6878   llassert (uentry_isValid (old));
6879   llassert (uentry_isValid (unew));
6880
6881   if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
6882       && (fileloc_isPreproc (uentry_whereDeclared (old))
6883           || ctype_isUnknown (old->utype))
6884       && !uentry_isSpecified (old))
6885     {
6886       ; /* no error */
6887     }
6888   else 
6889     {
6890       if (mustConform)
6891         {
6892           if (!uentry_isDeclared (old))
6893             {
6894               if (uentry_isSpecified (old))
6895                 {
6896                   if (uentry_isSpecified (unew))
6897                     {
6898                       llbuglit ("Respecification!");
6899                     }
6900                   else if (uentry_isDeclared (unew))
6901                     {
6902                       if (optgenerror
6903                           (FLG_INCONDEFS,
6904                            message ("%s %q inconsistently declared as %s: %t",
6905                                     ekind_capName (old->ukind),
6906                                     uentry_getName (unew),
6907                                     ekind_unparseLong (unew->ukind),
6908                                     unew->utype),
6909                            uentry_whereLast (unew)))  /* evans 2001-12-30: was uentry_whereDeclared */
6910                         {
6911                           uentry_showWhereLastKind (old);
6912                         }
6913                     }
6914                   else
6915                     {
6916                       BADEXIT;
6917                     }
6918                 }
6919               else
6920                 {
6921                   if (optgenerror
6922                       (FLG_INCONDEFS,
6923                        message ("%s %q inconsistently declared as %s: %t",
6924                                 ekind_capName (old->ukind),
6925                                 uentry_getName (unew),
6926                                 ekind_unparseLong (unew->ukind),
6927                                 unew->utype),
6928                        uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6929                     {
6930                       uentry_showWhereLastKind (old);
6931                     }
6932                 }
6933             }
6934           else
6935             {
6936               llassert (uentry_isDeclared (unew));
6937
6938               DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6939               DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6940
6941               if (optgenerror
6942                   (FLG_INCONDEFS,
6943                    message ("%s %q inconsistently redeclared as %s",
6944                             ekind_capName (old->ukind),
6945                             uentry_getName (unew),
6946                             ekind_unparseLong (unew->ukind)),
6947                    uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6948                 {
6949                   uentry_showWhereLastKind (old);
6950                 }
6951             }
6952         }
6953     }
6954
6955   uentry_updateInto (old, unew);
6956 }
6957
6958 /*
6959 ** def is the definition of spec, modifies spec
6960 **
6961 ** reports any inconsistencies
6962 ** returns the summary of all available information
6963 ** if spec and def are inconsistent, def is returned
6964 */
6965
6966 void
6967 uentry_showWhereLast (uentry spec)
6968 {
6969   if (uentry_isValid (spec))
6970     {
6971       if (fileloc_isDefined (spec->whereDefined)
6972           && !fileloc_isLib (spec->whereDefined)
6973           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6974         {
6975           llgenindentmsg (message ("Previous definition of %q: %t", 
6976                                    uentry_getName (spec),
6977                                    uentry_getType (spec)),
6978                           uentry_whereDefined (spec));
6979         }
6980       else if (uentry_isDeclared (spec))
6981         {
6982           llgenindentmsg (message ("Previous declaration of %q: %t", 
6983                                    uentry_getName (spec),
6984                                    uentry_getType (spec)),
6985                           uentry_whereDeclared (spec));
6986         }
6987       else if (uentry_isSpecified (spec))
6988         {
6989           if (uentry_hasName (spec))
6990             {
6991               llgenindentmsg (message ("Specification of %q: %t", 
6992                                        uentry_getName (spec),
6993                                        uentry_getType (spec)),
6994                               uentry_whereSpecified (spec));
6995             }
6996           else
6997             {
6998               llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6999                               uentry_whereSpecified (spec));
7000             }
7001         }
7002       else
7003         {
7004           /* nothing to show */
7005         }
7006     }
7007 }
7008
7009 static void
7010 uentry_showWhereLastKind (uentry spec)
7011 {
7012   if (uentry_isValid (spec))
7013     {
7014       if (fileloc_isDefined (spec->whereDefined)
7015           && !fileloc_isLib (spec->whereDefined)
7016           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
7017         {
7018           llgenindentmsg (message ("Previous definition of %q as %s: %t", 
7019                                    uentry_getName (spec),
7020                                    ekind_unparseLong (spec->ukind),
7021                                    uentry_getType (spec)),
7022                           uentry_whereDefined (spec));
7023         }
7024       else if (uentry_isDeclared (spec))
7025         {
7026           llgenindentmsg (message ("Previous declaration of %q as %s: %t", 
7027                                    uentry_getName (spec),
7028                                    ekind_unparseLong (spec->ukind),
7029                                    uentry_getType (spec)),
7030                           uentry_whereDeclared (spec));
7031         }
7032       else if (uentry_isSpecified (spec))
7033         {
7034           if (uentry_hasName (spec))
7035             {
7036               llgenindentmsg (message ("Specification of %q as %s: %t", 
7037                                        uentry_getName (spec),
7038                                        ekind_unparseLong (spec->ukind),
7039                                        uentry_getType (spec)),
7040                               uentry_whereSpecified (spec));
7041             }
7042           else
7043             {
7044               llgenindentmsg (message ("Specification as %s: %t",
7045                                        ekind_unparseLong (spec->ukind),
7046                                        uentry_getType (spec)),
7047                               uentry_whereSpecified (spec));
7048             }
7049         }
7050       else
7051         {
7052           /* nothing to show */
7053         }
7054     }
7055 }
7056
7057 void
7058 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7059 {
7060   fileloc loc = uentry_whereDefined (ce);
7061   
7062   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7063     {
7064       llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7065                       loc);
7066     }
7067
7068   loc = uentry_whereSpecified (ce);
7069   
7070   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7071     {
7072       llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7073                       loc);
7074     }
7075 }
7076
7077 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7078 {
7079   if (uentry_isDeclared (spec))
7080     {
7081       llgenindentmsg (message ("Previous declaration of %q: %q", 
7082                                uentry_getName (spec), extra),
7083                       uentry_whereDeclared (spec));
7084     }
7085   else if (uentry_isSpecified (spec))
7086     {
7087       llgenindentmsg (message ("Specification of %q: %q", 
7088                                uentry_getName (spec), extra),
7089                       uentry_whereSpecified (spec));
7090     }
7091   else
7092     {
7093       cstring_free (extra);
7094     }
7095 }
7096
7097 void
7098 uentry_showWhereDeclared (uentry spec)
7099 {
7100   if (uentry_isDeclared (spec))
7101     {
7102       if (uentry_hasName (spec))
7103         {
7104           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7105                           uentry_whereDeclared (spec));
7106         }
7107       else
7108         {
7109           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7110         }
7111     }
7112   else if (uentry_isSpecified (spec))
7113     {
7114       if (uentry_hasName (spec))
7115         {
7116           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7117                           uentry_whereSpecified (spec));
7118         }
7119       else
7120         {
7121           llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7122         }
7123     }
7124   else
7125     {
7126       /* nothing to show */
7127     }
7128     
7129 }
7130
7131 void
7132 uentry_showWhereAny (uentry spec)
7133 {
7134   if (uentry_isDeclared (spec))
7135     {
7136       if (uentry_hasName (spec))
7137         {
7138           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7139                           uentry_whereDeclared (spec));
7140         }
7141       else
7142         {
7143           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7144         }
7145     }
7146   else if (uentry_isSpecified (spec))
7147     {
7148       if (uentry_hasName (spec))
7149         {
7150           llgenindentmsg (message ("Specification of %q",
7151                                    uentry_getName (spec)),
7152                           uentry_whereSpecified (spec));
7153         }
7154       else
7155         {
7156           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7157                           uentry_whereSpecified (spec));
7158         }
7159     }
7160   else if (fileloc_isDefined (uentry_whereDefined (spec))) 
7161     {
7162       if (uentry_hasName (spec))
7163         {
7164           llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7165                           uentry_whereDefined (spec));
7166         }
7167       else
7168         {
7169           llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7170         }
7171     }
7172   else
7173     {
7174       /* nothing to show */
7175     }
7176 }
7177
7178 void
7179 uentry_showWhereDefined (uentry spec)
7180 {
7181   if (uentry_isCodeDefined (spec))
7182     {
7183       llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7184                       uentry_whereDefined (spec));
7185     }
7186 }
7187
7188 void
7189 uentry_showWhereLastPlain (uentry spec)
7190 {
7191   if (uentry_isDeclared (spec))
7192     {
7193       llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7194                       uentry_whereDeclared (spec));
7195     }
7196   else if (uentry_isSpecified (spec))
7197     {
7198       llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7199                       uentry_whereSpecified (spec));
7200     }
7201   else
7202     {
7203           }
7204 }
7205
7206 static void
7207 uentry_showWhereLastVal (uentry spec, cstring val)
7208 {
7209   if (uentry_isDeclared (spec))
7210     {
7211       llgenindentmsg (message ("Previous declaration of %q: %s", 
7212                                uentry_getName (spec), val),
7213                       uentry_whereDeclared (spec));
7214     }
7215   else if (uentry_isSpecified (spec))
7216     {
7217       llgenindentmsg (message ("Specification of %q: %s", 
7218                                uentry_getName (spec), val),
7219                       uentry_whereSpecified (spec));
7220     }
7221   else
7222     {
7223     }
7224 }
7225
7226 void
7227 uentry_showWhereSpecified (uentry spec)
7228 {
7229   if (uentry_isSpecified (spec))
7230     {
7231       if (uentry_hasName (spec))
7232         {
7233           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7234                           uentry_whereSpecified (spec));
7235         }
7236       else
7237         {
7238           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7239                           uentry_whereSpecified (spec));
7240         }
7241     }
7242   else if (uentry_isDeclared (spec))
7243     {
7244       llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7245                       uentry_whereDeclared (spec));
7246     }
7247   else
7248     {
7249       /* nothing to show */
7250     }
7251 }
7252
7253 void
7254 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7255 {
7256   if (uentry_isSpecified (spec))
7257     {
7258       if (uentry_hasName (spec))
7259         {
7260           llgenindentmsg (message ("Specification of %q: %q", 
7261                                    uentry_getName (spec), s),
7262                           uentry_whereSpecified (spec));
7263         }
7264       else
7265         {
7266           llgenindentmsg (message ("Specification: %q", s), 
7267                           uentry_whereSpecified (spec));
7268         }
7269     }
7270   else if (uentry_isDeclared (spec))
7271     {
7272       llgenindentmsg (message ("Declaration of %q: %q", 
7273                                uentry_getName (spec), s),
7274                       uentry_whereDeclared (spec));
7275     }
7276   else
7277     {
7278       llgenindentmsg (message ("Previous: %q", s),
7279                       uentry_whereLast (spec));
7280     }
7281 }
7282
7283 /*
7284 **
7285 */
7286
7287 static void
7288 checkStructConformance (uentry old, uentry unew)
7289 {
7290   ctype oldr, newr; 
7291   uentryList fold, fnew;
7292
7293   /*
7294   ** requires: types of old and new are structs or unions
7295   */
7296
7297   llassert (uentry_isValid (old));
7298   llassert (uentry_isValid (unew));
7299
7300   oldr = ctype_realType (old->utype);
7301   fold =  ctype_getFields (oldr);
7302
7303   newr = ctype_realType (unew->utype);
7304   fnew = ctype_getFields (newr);
7305
7306   if (!uentryList_matchFields (fold, fnew))
7307     {
7308       if (fileloc_equal (uentry_whereLast (old),
7309                          uentry_whereLast (unew)))
7310         {
7311           ; /* cheat! */
7312         }
7313       else 
7314         {
7315           if (optgenerror 
7316               (FLG_MATCHFIELDS,
7317                message ("%q %q %rdeclared with fields { %q }, %s "
7318                         "with fields { %q }",
7319                         cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7320                         uentry_getName (old), 
7321                         uentry_isDeclared (old),
7322                         uentryList_unparseAbbrev (fnew),
7323                         uentry_specOrDefName (old),
7324                         uentryList_unparseAbbrev (fold)),
7325                uentry_whereDeclared (unew)))
7326             {
7327               uentry_showWhereLastPlain (old);
7328               uentryList_showFieldDifference (fold, fnew);
7329             }
7330         }
7331
7332       old->utype = unew->utype;
7333     }
7334 }
7335
7336 static void
7337 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7338 {
7339   /*
7340   ** requires old and new are enums
7341   */
7342   
7343   ctype        rold = ctype_realType (old->utype);
7344   ctype        rnew = ctype_realType (unew->utype);
7345   enumNameList eold = ctype_elist (rold);
7346   enumNameList enew = ctype_elist (rnew);
7347   
7348   if (!enumNameList_match (eold, enew))
7349     {
7350       if (optgenerror 
7351           (FLG_MATCHFIELDS,
7352            message ("Enum %q declared with members { %q } but "
7353                     "%s with members { %q }",
7354                     uentry_getName (old), 
7355                     enumNameList_unparse (enew),
7356                     uentry_specOrDefName (old),
7357                     enumNameList_unparse (eold)),
7358            uentry_whereDeclared (unew)))
7359         {
7360           uentry_showWhereSpecified (old);
7361           old->utype = unew->utype;
7362         }
7363     }
7364 }
7365
7366 /*
7367 ** either oldCurrent or newCurrent may be undefined!
7368 */
7369
7370 static void
7371 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7372                 uentry unew, uentry newCurrent, ctype newType,
7373                 int paramno)
7374 {
7375   bool hasError = FALSE;
7376
7377   if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7378     {
7379       if (uentry_hasName (newCurrent))
7380         {
7381           hasError = optgenerror 
7382             (FLG_TYPE,
7383              message ("Parameter %d, %q, of function %q has inconsistent type: "
7384                       "declared %t, %s %t",
7385                       paramno + 1, uentry_getName (newCurrent), 
7386                       uentry_getName (unew),
7387                       newType, uentry_specOrDefName (old), oldType),
7388              uentry_whereDeclared (newCurrent));
7389         }
7390       else
7391         {
7392           hasError = optgenerror
7393             (FLG_TYPE,
7394              message ("Parameter %d of function %q has inconsistent type: "
7395                       "declared %t, %s %t",
7396                       paramno + 1, uentry_getName (unew),
7397                       newType, uentry_specOrDefName (old), oldType),
7398              uentry_whereDeclared (newCurrent));
7399
7400           DPRINTF (("type: %s / %s",
7401                     ctype_unparse (newType),
7402                     ctype_unparse (ctype_realType (newType))));
7403         }
7404     }
7405   else 
7406     {
7407       if (uentry_isDeclared (unew))
7408         {
7409           hasError = optgenerror 
7410             (FLG_TYPE,
7411              message ("Parameter %d of function %s has inconsistent type: "
7412                       "declared %t, %s %t",
7413                       paramno + 1, unew->uname, 
7414                       newType, uentry_specOrDefName (old), oldType),
7415              uentry_whereDeclared (unew));
7416         }
7417       else
7418         {
7419           hasError = optgenerror
7420             (FLG_TYPE,
7421              message ("Parameter %d of function %s has inconsistent type: "
7422                       "declared %t, %s %t",
7423                       paramno + 1, unew->uname, 
7424                       newType, uentry_specOrDefName (old), oldType),
7425              uentry_whereDeclared (unew));
7426         }
7427     }
7428   
7429   if (hasError)
7430     {
7431       DPRINTF (("Here: %s / %s",
7432                 uentry_unparseFull (oldCurrent),
7433                 uentry_unparseFull (newCurrent)));
7434
7435       if (!uentry_isUndefined (oldCurrent))
7436         {
7437           if (!uentry_isUndefined (newCurrent) 
7438               && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7439             {
7440               uentry_showWhereLast (oldCurrent);
7441             }
7442           else
7443             {
7444               uentry_showWhereLastPlain (old);
7445             }
7446           
7447           uentry_setType (oldCurrent, newType);
7448         }
7449       else
7450         {
7451           uentry_showWhereLastPlain (old);
7452         }
7453     }
7454 }
7455
7456 static void
7457 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7458 {
7459   if (optgenerror 
7460       (FLG_TYPE,
7461        message ("Function %s %rdeclared with %d arg%&, %s with %d",
7462                 unew->uname, 
7463                 uentry_isDeclared (old),
7464                 uentryList_size (uentry_getParams (unew)),
7465                 uentry_specOrDefName (old),
7466                 uentryList_size (uentry_getParams (old))),
7467        uentry_whereDeclared (unew)))
7468     {
7469       uentry_showWhereLastPlain (old);
7470     }
7471 }
7472
7473 static void
7474 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7475 {
7476   if (optgenerror
7477       (FLG_INCONDEFS,
7478        message ("Function %s inconsistently %rdeclared to return %t",
7479                 unew->uname,
7480                 uentry_isDeclared (old),
7481                 ctype_getReturnType (unew->utype)),
7482        uentry_whereDeclared (unew)))
7483     {
7484       uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7485     }
7486 }
7487
7488 static cstring paramStorageName (uentry ue)
7489 {
7490   return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7491 }
7492
7493 static cstring fcnErrName (uentry ue)
7494 {
7495   return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7496 }
7497
7498 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7499 {
7500   if (uentry_isVar (ue))
7501     {
7502       return (checkedName (ue->info->var->checked));
7503     }
7504   else
7505     {
7506       return (cstring_makeLiteralTemp ("<checked invalid>"));
7507     }
7508 }
7509
7510 static cstring checkedName (chkind checked)
7511 {
7512   switch (checked)
7513     {
7514     case CH_UNKNOWN:       return (cstring_makeLiteralTemp ("unknown"));
7515     case CH_UNCHECKED:     return (cstring_makeLiteralTemp ("unchecked"));
7516     case CH_CHECKED:       return (cstring_makeLiteralTemp ("checked"));
7517     case CH_CHECKMOD:      return (cstring_makeLiteralTemp ("checkmod"));
7518     case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7519     }
7520   BADEXIT;
7521 }
7522
7523 static
7524 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7525 {
7526   nstate oldState;
7527   nstate newState;
7528   
7529   if (uentry_isVar (unew))
7530     {
7531       llassert (uentry_isVar (old));
7532       
7533       oldState = old->info->var->nullstate;
7534       newState = unew->info->var->nullstate;
7535     }
7536   else
7537     {
7538       oldState = sRef_getNullState (old->sref);
7539       newState = sRef_getNullState (unew->sref);
7540     }
7541
7542   if (oldState == NS_ABSNULL)
7543     {
7544       if (uentry_isVar (old))
7545         {
7546           old->info->var->nullstate = newState;
7547         }
7548       
7549       sRef_mergeNullState (old->sref, newState);
7550     }
7551   else if (newState == NS_UNKNOWN)
7552     {
7553       if (completeConform && newState != oldState
7554           && uentry_isReallySpecified (old))
7555         {
7556           if (optgenerror 
7557               (FLG_NEEDSPEC,
7558                message ("%s %q specified as %s, but declared without %s qualifier",
7559                         ekind_capName (unew->ukind),
7560                         uentry_getName (unew),
7561                         nstate_unparse (oldState),
7562                         nstate_unparse (oldState)),
7563                uentry_whereDeclared (unew)))
7564             {
7565               uentry_showWhereSpecified (old);
7566             }
7567         }
7568       
7569       if (uentry_isVar (unew))
7570         {
7571           unew->info->var->nullstate = oldState;
7572         }
7573
7574       sRef_mergeNullState (unew->sref, oldState);
7575     }
7576   else if (newState == NS_POSNULL)
7577     {
7578       if (oldState == NS_MNOTNULL 
7579           && (ctype_isUA (unew->utype) 
7580               || (uentry_isFunction (unew)
7581                   && ctype_isUA (ctype_getReturnType (unew->utype)))))
7582         {
7583           if (uentry_isVar (unew))
7584             {
7585               unew->info->var->nullstate = oldState;
7586             }
7587
7588           sRef_mergeNullState (unew->sref, oldState);
7589         }
7590       else 
7591         {
7592           if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL 
7593               || oldState == NS_UNKNOWN)
7594             {
7595               if (mustConform)
7596                 {
7597                   if (optgenerror 
7598                       (FLG_INCONDEFS,
7599                        message 
7600                        ("%s %q inconsistently %rdeclared %s possibly null storage, "
7601                         "%s %q qualifier",
7602                         uentry_ekindName (unew),
7603                         uentry_getName (unew),
7604                         uentry_isDeclared (old),
7605                         fcnErrName (unew),
7606                         uentry_specOrDefName (old),
7607                         cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7608                        uentry_whereDeclared (unew)))
7609                     {
7610                       uentry_showWhereSpecified (old);
7611                     }
7612                 }
7613             }
7614           
7615           if (uentry_isVar (old))
7616             {
7617               old->info->var->nullstate = newState;
7618             }
7619
7620           sRef_mergeNullState (old->sref, newState);
7621         }
7622     }
7623   else if (newState == NS_MNOTNULL)
7624     {
7625       if (oldState != NS_MNOTNULL)
7626         {
7627           if (mustConform)
7628             {
7629               if (optgenerror 
7630                   (FLG_INCONDEFS,
7631                    message ("%s %q inconsistently %rdeclared %s notnull storage, "
7632                             "%s without notnull qualifier",
7633                             uentry_ekindName (unew),
7634                             uentry_getName (unew),
7635                             uentry_isDeclared (old),
7636                             fcnErrName (unew),
7637                             uentry_specOrDefName (old)),
7638                    uentry_whereDeclared (unew)))
7639                 {
7640                   uentry_showWhereSpecified (old);
7641                 }
7642             }
7643           
7644           if (uentry_isVar (old))
7645             {
7646               old->info->var->nullstate = newState;
7647             }
7648
7649           sRef_mergeNullState (old->sref, newState);
7650         }
7651     }
7652   else
7653     {
7654       if (uentry_isVar (unew)) 
7655         {
7656           unew->info->var->nullstate = oldState;
7657         }
7658
7659       sRef_mergeNullState (unew->sref, oldState);
7660     }
7661 }
7662
7663 static
7664 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7665                     bool mustConform, bool completeConform)
7666 {
7667   sstate oldState;
7668   sstate newState;
7669   bool vars = FALSE;
7670
7671   if (uentry_isVar (old) && uentry_isVar (unew))
7672     {
7673       oldState = old->info->var->defstate;
7674       newState = unew->info->var->defstate;
7675       vars = TRUE;
7676     }
7677   else
7678     {
7679       oldState = sRef_getDefState (old->sref);
7680       newState = sRef_getDefState (unew->sref);
7681     }
7682
7683   if (newState != oldState 
7684       && newState != SS_UNKNOWN 
7685       && newState != SS_DEFINED)
7686     {
7687       if (mustConform)
7688         {
7689           if (optgenerror 
7690               (FLG_INCONDEFS,
7691                message ("%s %q inconsistently %rdeclared %s %s %s, "
7692                         "%s %s %s %s",
7693                         uentry_ekindName (unew),
7694                         uentry_getName (unew),
7695                         uentry_isDeclared (old),
7696                         fcnErrName (unew),
7697                         sstate_unparse (newState),
7698                         paramStorageName (unew),
7699                         uentry_specOrDefName (old),
7700                         fcnErrName (unew),
7701                         sstate_unparse (oldState),
7702                         paramStorageName (unew)),
7703                uentry_whereDeclared (unew)))
7704             {
7705               uentry_showWhereSpecified (old);
7706             }
7707         }
7708
7709       if (vars) old->info->var->defstate = newState;
7710       sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7711     }
7712   else
7713     {
7714       if (completeConform
7715           && (newState != oldState) && (oldState != SS_DEFINED)
7716           && uentry_isReallySpecified (old))
7717         {
7718           if (optgenerror 
7719               (FLG_NEEDSPEC,
7720                message ("%s %q specified as %s, but declared without %s qualifier",
7721                         ekind_capName (unew->ukind),
7722                         uentry_getName (unew),
7723                         sstate_unparse (oldState),
7724                         sstate_unparse (oldState)),
7725                uentry_whereDeclared (unew)))
7726             {
7727               uentry_showWhereSpecified (old);
7728             }
7729         }
7730       
7731       if (vars) unew->info->var->defstate = oldState;
7732       sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7733     }
7734 }
7735
7736 static void 
7737   checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7738                    bool mustConform, bool completeConform)
7739 {
7740   alkind newKind;
7741   alkind oldKind;
7742
7743   oldKind = sRef_getAliasKind (old->sref);
7744   newKind = sRef_getAliasKind (unew->sref);
7745
7746   if (alkind_isImplicit (newKind) 
7747       || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7748     {
7749       if (completeConform && !alkind_equal (newKind, oldKind)
7750           && uentry_isReallySpecified (old))
7751         {
7752           if (optgenerror 
7753               (FLG_NEEDSPEC,
7754                message ("%s %q specified as %s, but declared without "
7755                         "explicit alias qualifier",
7756                         ekind_capName (unew->ukind),
7757                         uentry_getName (unew),
7758                         alkind_unparse (oldKind)),
7759                uentry_whereDeclared (unew)))
7760             {
7761               uentry_showWhereSpecified (old);
7762             }
7763         }
7764
7765       /*  
7766       ** This really shouldn't be necessary, but it is!
7767       ** Function params (?) use new here.
7768       */
7769
7770       sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7771       return;
7772     }
7773
7774   if (alkind_isKnown (newKind))
7775     {
7776       if (!alkind_equal (oldKind, newKind))
7777         {
7778           if (alkind_isKnown (oldKind))
7779             {
7780               if (mustConform && 
7781                   optgenerror 
7782                   (FLG_INCONDEFS,
7783                    message ("%s %q inconsistently %rdeclared %s %s storage, "
7784                             "%s as %s storage",
7785                             uentry_ekindName (unew),
7786                             uentry_getName (unew),
7787                             uentry_isDeclared (old),
7788                             fcnErrName (unew),
7789                             alkind_unparse (newKind),
7790                             uentry_specOrDefName (old),
7791                             alkind_unparse (oldKind)),
7792                    uentry_whereDeclared (unew)))
7793                 {
7794                   uentry_showWhereSpecified (old);
7795
7796                   DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7797                   DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7798                   sRef_setAliasKind (old->sref, AK_ERROR, 
7799                                      uentry_whereDeclared (unew));
7800                 }
7801               else
7802                 {
7803                   sRef_setAliasKind (old->sref, newKind, 
7804                                      uentry_whereDeclared (unew));
7805                 }
7806             }
7807           else
7808             {
7809               if (!(alkind_isImplicit (newKind)))
7810                 {
7811                   if (mustConform &&
7812                       !uentry_isFunction (unew) &&
7813                       optgenerror 
7814                       (FLG_INCONDEFS,
7815                        message ("%s %q inconsistently %rdeclared %s %s storage, "
7816                                 "implicitly %s as temp storage",
7817                                 uentry_ekindName (unew),
7818                                 uentry_getName (unew),
7819                                 uentry_isDeclared (old),
7820                                 fcnErrName (unew),
7821                                 alkind_unparse (newKind),
7822                                 uentry_specOrDefName (old)),
7823                        uentry_whereDeclared (unew)))
7824                     {
7825                       uentry_showWhereSpecified (old);
7826                       oldKind = AK_ERROR;
7827                     }
7828                   
7829                   sRef_setAliasKind (old->sref, newKind, 
7830                                      uentry_whereDeclared (unew));
7831                 }
7832               else /* newKind is temp or refcounted */
7833                 {
7834                   ;
7835                 }
7836             }
7837         }
7838     }
7839   else /* newKind unknown */
7840     {
7841       ;
7842     }
7843 }
7844
7845 static void 
7846   checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7847                 bool mustConform, bool completeConform)
7848 {
7849   exkind newKind;
7850   exkind oldKind;
7851   
7852   oldKind = sRef_getExKind (old->sref);
7853   newKind = sRef_getExKind (unew->sref);
7854
7855   if (exkind_isKnown (newKind))
7856     {
7857       if (oldKind != newKind)
7858         {
7859           if (exkind_isKnown (oldKind))
7860             {
7861               if (mustConform && 
7862                   optgenerror 
7863                   (FLG_INCONDEFS,
7864                    message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7865                             uentry_ekindName (unew),
7866                             uentry_getName (unew),
7867                             uentry_isDeclared (old),
7868                             fcnErrName (unew),
7869                             exkind_unparse (newKind),
7870                             uentry_specOrDefName (old),
7871                             exkind_unparse (oldKind)),
7872                    uentry_whereDeclared (unew)))
7873                 {
7874                   uentry_showWhereSpecified (old);
7875                 }
7876
7877               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7878             }
7879           else
7880             {
7881               if (mustConform &&
7882                   optgenerror 
7883                   (FLG_INCONDEFS,
7884                    message ("%s %q inconsistently %rdeclared %s %s, "
7885                             "implicitly %s without exposure qualifier",
7886                             uentry_ekindName (unew),
7887                             uentry_getName (unew),
7888                             uentry_isDeclared (old),
7889                             fcnErrName (unew),
7890                             exkind_unparse (newKind),
7891                             uentry_specOrDefName (old)),
7892                    uentry_whereDeclared (unew)))
7893                 {
7894                   uentry_showWhereSpecified (old);
7895                 }
7896
7897               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7898             }
7899         }
7900     }
7901   else
7902     {
7903       if (completeConform && exkind_isKnown (oldKind)
7904           && uentry_isReallySpecified (old))
7905         {
7906           if (optgenerror 
7907               (FLG_NEEDSPEC,
7908                message ("%s %q specified as %s, but declared without "
7909                         "exposure qualifier",
7910                         ekind_capName (unew->ukind),
7911                         uentry_getName (unew),
7912                         exkind_unparse (oldKind)),
7913                uentry_whereDeclared (unew)))
7914             {
7915               uentry_showWhereSpecified (old);
7916             }
7917         }
7918
7919       /* yes, this is necessary! (if its a param) */
7920       sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7921     }
7922 }
7923
7924 static void 
7925 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7926                 bool mustConform, /*@unused@*/ bool completeConform)
7927 {
7928   valueTable newvals = sRef_getValueTable (unew->sref);
7929
7930   if (valueTable_isDefined (newvals))
7931     {
7932       DPRINTF (("Check meta state: %s -> %s",
7933                 uentry_unparseFull (old),
7934                 uentry_unparseFull (unew)));
7935       
7936       DPRINTF (("Check meta state refs: %s -> %s",
7937                 sRef_unparseFull (old->sref),
7938                 sRef_unparseFull (unew->sref)));
7939       
7940       DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7941       
7942       /*
7943       ** Copy the new values into the old ref
7944       */
7945
7946       valueTable_elements (newvals, key, newval)
7947         {
7948           metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7949           stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7950             
7951           llassert (metaStateInfo_isDefined (msinfo));
7952
7953           if (stateValue_isUndefined (oldval))
7954             {
7955               sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7956             }
7957           else
7958             {
7959               if (stateValue_isError (oldval))
7960                 {
7961                   if (!stateValue_isError (newval))
7962                     {
7963                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7964                     }
7965                   else
7966                     {
7967                       ; /* No change necessary. */
7968                     }
7969                 }
7970               else
7971                 {
7972                   if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7973                     {
7974                       if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7975                         {
7976                           ;
7977                         }
7978                       else
7979                         {
7980                           if (!stateValue_isError (newval) 
7981                               && !stateValue_isImplicit (newval))
7982                             {
7983                               if (uentry_hasName (unew)
7984                                   || !sRef_isParam (uentry_getSref (unew)))
7985                                 {
7986                                   if (mustConform 
7987                                       && optgenerror 
7988                                       (FLG_INCONDEFS,
7989                                        message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7990                                                 uentry_ekindName (unew),
7991                                                 uentry_getName (unew),
7992                                                 uentry_isDeclared (old),
7993                                                 fcnErrName (unew),
7994                                                 stateValue_unparseValue (newval, msinfo),
7995                                                 uentry_specOrDefName (old),
7996                                                 stateValue_unparseValue (oldval, msinfo)),
7997                                        uentry_whereDeclared (unew)))
7998                                     {
7999                                       uentry_showWhereSpecified (old);
8000                                     }
8001                                 }
8002                               else
8003                                 {
8004                                   if (mustConform 
8005                                       && optgenerror 
8006                                       (FLG_INCONDEFS,
8007                                        message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
8008                                                 uentry_ekindName (unew),
8009                                                 sRef_getParam (uentry_getSref (unew)),
8010                                                 uentry_isDeclared (old),
8011                                                 fcnErrName (unew),
8012                                                 stateValue_unparseValue (newval, msinfo),
8013                                                 uentry_specOrDefName (old),
8014                                                 stateValue_unparseValue (oldval, msinfo)),
8015                                        uentry_whereDeclared (unew)))
8016                                     {
8017                                       uentry_showWhereSpecified (old);
8018                                     }
8019                                 }
8020                             }
8021                         }
8022                       
8023                       DPRINTF (("Updating!"));
8024                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8025                     }
8026                   else
8027                     {
8028                       DPRINTF (("Values match"));
8029                     }
8030                 }
8031             }
8032         } end_valueTable_elements ;
8033     }
8034 }
8035
8036 static void
8037 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8038                               /*@notnull@*/ uentry unew,
8039                               bool mustConform, bool completeConform)
8040 {
8041   checkDefState (old, unew, mustConform, completeConform);
8042   checkNullState (old, unew, mustConform, completeConform);
8043   checkAliasState (old, unew, mustConform, completeConform);
8044   checkExpState (old, unew, mustConform, completeConform);
8045   checkMetaState (old, unew, mustConform, completeConform);
8046
8047   sRef_storeState (old->sref);
8048   sRef_storeState (unew->sref);
8049 }
8050
8051 static void
8052 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8053 {
8054   if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8055     {
8056       return;
8057     }
8058
8059   llassert (uentry_isVar (old));
8060   llassert (uentry_isVar (unew));
8061
8062   if (cstring_isEmpty (old->uname)) 
8063     {
8064       cstring_free (old->uname);
8065       old->uname = cstring_copy (unew->uname);
8066     }
8067
8068   if (unew->info->var->kind == VKRETPARAM
8069       || unew->info->var->kind == VKSEFRETPARAM)
8070     {
8071       if (old->info->var->kind != VKRETPARAM
8072           && old->info->var->kind != VKSEFRETPARAM)
8073         {
8074           if (optgenerror 
8075               (FLG_INCONDEFS,
8076                message ("Parameter %q inconsistently %rdeclared as "
8077                         "returned parameter",
8078                         uentry_getName (unew),
8079                         uentry_isDeclared (old)),
8080                uentry_whereDeclared (unew)))
8081             {
8082               uentry_showWhereSpecified (old);
8083               old->info->var->kind = unew->info->var->kind;
8084             }
8085         }
8086     }
8087
8088
8089   if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8090     {
8091       if (old->info->var->kind != VKSEFPARAM 
8092           && old->info->var->kind != VKSEFRETPARAM)
8093         {
8094           if (optgenerror 
8095               (FLG_INCONDEFS,
8096                message ("Parameter %qinconsistently %rdeclared as "
8097                         "sef parameter",
8098                         uentry_getOptName (unew),
8099                         uentry_isDeclared (old)),
8100                uentry_whereDeclared (unew)))
8101             {
8102               uentry_showWhereSpecified (old);
8103               old->info->var->kind = unew->info->var->kind;
8104             }
8105         }
8106     }
8107
8108   if (old->info->var->kind == VKSPEC)
8109     {
8110       old->info->var->kind = unew->info->var->kind;
8111     }
8112   else
8113     {
8114       unew->info->var->kind = old->info->var->kind;
8115     }
8116
8117   if (unew->info->var->checked != CH_UNKNOWN
8118       && unew->info->var->checked != old->info->var->checked)
8119     {
8120       if (old->info->var->checked == CH_UNKNOWN
8121           && !fileloc_isUser (uentry_whereLast (old)))
8122         {
8123           ; /* no error */
8124         }
8125       else
8126         {
8127           if (optgenerror 
8128               (FLG_INCONDEFS,
8129                message ("Variable %q inconsistently %rdeclared as "
8130                         "%s parameter (was %s)",
8131                         uentry_getName (unew),
8132                         uentry_isDeclared (old),
8133                         checkedName (unew->info->var->checked),
8134                         checkedName (old->info->var->checked)),
8135                uentry_whereDeclared (unew)))
8136             {
8137               uentry_showWhereSpecified (old);
8138             }
8139         }
8140       
8141       old->info->var->checked = unew->info->var->checked;
8142     }
8143   else
8144     {
8145       if (completeConform 
8146           && (old->info->var->checked != CH_UNKNOWN)
8147           && uentry_isReallySpecified (old))
8148         {
8149           if (optgenerror 
8150               (FLG_NEEDSPEC,
8151                message ("%s %q specified as %s, but declared without %s qualifier",
8152                         ekind_capName (unew->ukind),
8153                         uentry_getName (unew),
8154                         checkedName (old->info->var->checked),
8155                         checkedName (old->info->var->checked)),
8156                uentry_whereDeclared (unew)))
8157             {
8158               uentry_showWhereSpecified (old);
8159             }
8160         }
8161       
8162       unew->info->var->checked = old->info->var->checked;
8163     }
8164
8165   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8166 }
8167
8168 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8169 {
8170   if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8171     {
8172       return;
8173     }
8174
8175   llassert (uentry_isVar (u1));
8176   llassert (uentry_isVar (u2));
8177
8178   if (u1->info->var->kind != u2->info->var->kind) {
8179     if (u1->info->var->kind == VKSEFRETPARAM) {
8180       if (u2->info->var->kind == VKRETPARAM) {
8181         voptgenerror 
8182           (FLG_TYPE,
8183            message ("Function types are inconsistent. Parameter %d is "
8184                     "sef parameter, but non-sef parameter in "
8185                     "assigned function: %s",
8186                     paramno, exprNode_unparse (e)),
8187            exprNode_loc (e));
8188       } else if (u2->info->var->kind == VKSEFPARAM) {
8189         voptgenerror 
8190           (FLG_TYPE,
8191            message ("Function types are inconsistent. Parameter %d is "
8192                     "returns parameter, but non-returns parameter in "
8193                     "assigned function: %s",
8194                     paramno, exprNode_unparse (e)),
8195            exprNode_loc (e));
8196       } else {
8197         voptgenerror 
8198           (FLG_TYPE,
8199            message ("Function types are inconsistent. Parameter %d is "
8200                     "sef returns parameter, but non-sef returns parameter in "
8201                     "assigned function: %s",
8202                     paramno, exprNode_unparse (e)),
8203            exprNode_loc (e));
8204       }
8205     } else if (u1->info->var->kind == VKRETPARAM) {
8206       voptgenerror 
8207         (FLG_TYPE,
8208          message ("Function types are inconsistent. Parameter %d is "
8209                   "returns parameter, but non-returns parameter in "
8210                   "assigned function: %s",
8211                   paramno, exprNode_unparse (e)),
8212          exprNode_loc (e));
8213     } else if (u1->info->var->kind == VKSEFPARAM) {
8214       voptgenerror 
8215         (FLG_TYPE,
8216          message ("Function types are inconsistent. Parameter %d is "
8217                   "sef parameter, but non-sef parameter in "
8218                   "assigned function: %s",
8219                   paramno, exprNode_unparse (e)),
8220          exprNode_loc (e));
8221     } else {
8222       if (u2->info->var->kind == VKSEFRETPARAM) {
8223         voptgenerror 
8224           (FLG_TYPE,
8225            message ("Function types are inconsistent. Parameter %d is "
8226                     "normal parameter, but sef returns parameter in "
8227                     "assigned function: %s",
8228                     paramno, exprNode_unparse (e)),
8229            exprNode_loc (e));
8230       } else if (u2->info->var->kind == VKSEFPARAM) {
8231         voptgenerror 
8232           (FLG_TYPE,
8233            message ("Function types are inconsistent. Parameter %d is "
8234                     "normal parameter, but sef parameter in "
8235                     "assigned function: %s",
8236                     paramno, exprNode_unparse (e)),
8237            exprNode_loc (e));
8238       } else if (u2->info->var->kind == VKRETPARAM) {
8239         voptgenerror 
8240           (FLG_TYPE,
8241            message ("Function types are inconsistent. Parameter %d is "
8242                     "normal parameter, but returns parameter in "
8243                     "assigned function: %s",
8244                     paramno, exprNode_unparse (e)),
8245            exprNode_loc (e));
8246       } else {
8247         BADBRANCH;
8248       }
8249     }
8250   }
8251
8252   if (u1->info->var->defstate != u2->info->var->defstate) 
8253     {
8254       voptgenerror 
8255         (FLG_TYPE,
8256          message ("Function types are inconsistent. Parameter %d is "
8257                   "%s, but %s in assigned function: %s",
8258                   paramno, 
8259                   sstate_unparse (u1->info->var->defstate),
8260                   sstate_unparse (u2->info->var->defstate),
8261                   exprNode_unparse (e)),
8262          exprNode_loc (e));
8263     }
8264
8265   if (u1->info->var->nullstate != u2->info->var->nullstate) 
8266     {
8267       voptgenerror 
8268         (FLG_TYPE,
8269          message ("Function types are inconsistent. Parameter %d is "
8270                   "%s, but %s in assigned function: %s",
8271                   paramno, 
8272                   nstate_unparse (u1->info->var->nullstate),
8273                   nstate_unparse (u2->info->var->nullstate),
8274                   exprNode_unparse (e)),
8275          exprNode_loc (e));
8276     }
8277       
8278   if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8279     {
8280       voptgenerror 
8281         (FLG_TYPE,
8282          message ("Function types are inconsistent. Parameter %d is "
8283                   "%s, but %s in assigned function: %s",
8284                   paramno, 
8285                   alkind_unparse (sRef_getAliasKind (u1->sref)),
8286                   alkind_unparse (sRef_getAliasKind (u2->sref)),
8287                   exprNode_unparse (e)),
8288          exprNode_loc (e));
8289     }
8290
8291   if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8292     {
8293       voptgenerror 
8294         (FLG_TYPE,
8295          message ("Function types are inconsistent. Parameter %d is "
8296                   "%s, but %s in assigned function: %s",
8297                   paramno, 
8298                   exkind_unparse (sRef_getExKind (u1->sref)),
8299                   exkind_unparse (sRef_getExKind (u2->sref)),
8300                   exprNode_unparse (e)),
8301          exprNode_loc (e));
8302     }
8303 }
8304
8305 static void
8306 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8307                           /*@notnull@*/ uentry unew, 
8308                           bool mustConform, /*@unused@*/ bool completeConform)
8309 {
8310   uentryList oldParams  = uentry_getParams (old);
8311   uentryList newParams  = uentry_getParams (unew);
8312   ctype      newType    = unew->utype;
8313   ctype      oldType    = ctype_realType (old->utype);
8314   ctype      oldRetType = ctype_unknown;
8315   ctype      newRetType = ctype_unknown;
8316
8317   DPRINTF (("Function conform: %s ==> %s",
8318             uentry_unparseFull (old),
8319             uentry_unparseFull (unew)));
8320
8321   if (uentry_isForward (old))
8322     {
8323       mustConform = FALSE;
8324       uentry_updateInto (old, unew);
8325       return;
8326     }
8327
8328   /*
8329   ** check return values
8330   */
8331   
8332   if (ctype_isKnown (oldType))
8333     {
8334       llassert (ctype_isFunction (oldType));
8335       oldRetType = ctype_getReturnType (oldType);
8336     }
8337
8338   if (ctype_isKnown (newType))
8339     {
8340       llassert (ctype_isFunction (newType));
8341       newRetType = ctype_getReturnType (newType);
8342     }
8343
8344   if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8345       && !ctype_matchDef (newRetType, oldRetType))
8346     {
8347       if (mustConform) returnValueError (old, unew);
8348     }
8349   else 
8350     {
8351       if (ctype_isConj (newRetType))
8352         {
8353           if (ctype_isConj (oldRetType))
8354             {
8355               if (!ctype_sameAltTypes (newRetType, oldRetType))
8356                 {
8357                   if (optgenerror 
8358                       (FLG_INCONDEFS,
8359                        message ("Function %q inconsistently %rdeclared to "
8360                                 "return alternate types %s "
8361                                 "(types match, but alternates are not identical, "
8362                                 "so checking may not be correct)",
8363                                 uentry_getName (unew),
8364                                 uentry_isDeclared (old),
8365                                 ctype_unparse (newRetType)),
8366                        uentry_whereDeclared (unew)))
8367                     {
8368                       uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8369                     }
8370                 }
8371             }
8372           else
8373             {
8374               old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8375             }
8376         }
8377     }
8378
8379   DPRINTF (("Before state: %s",
8380             uentry_unparseFull (old)));
8381   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8382   DPRINTF (("After state: %s",
8383             uentry_unparseFull (old)));
8384
8385   if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8386     {
8387       if (exitkind_isKnown (unew->info->fcn->exitCode))
8388         {
8389           if (optgenerror 
8390               (FLG_INCONDEFS,
8391                message ("Function %q inconsistently %rdeclared using %s",
8392                         uentry_getName (unew),
8393                         uentry_isDeclared (old),
8394                         exitkind_unparse (unew->info->fcn->exitCode)),
8395                uentry_whereDeclared (unew)))
8396             {
8397               uentry_showWhereSpecified (old);
8398             }
8399         }
8400       else
8401         {
8402           unew->info->fcn->exitCode = old->info->fcn->exitCode;
8403         }
8404     }
8405
8406   if (!qual_isUnknown (unew->info->fcn->nullPred))
8407     {
8408       if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8409         {
8410           if (optgenerror
8411               (FLG_INCONDEFS,
8412                message ("Function %q inconsistently %rdeclared using %s",
8413                         uentry_getName (unew),
8414                         uentry_isDeclared (old),
8415                         qual_unparse (unew->info->fcn->nullPred)),
8416                uentry_whereDeclared (unew)))
8417             {
8418               uentry_showWhereSpecified (old);
8419             }
8420         }
8421     }
8422   else
8423     {
8424       unew->info->fcn->nullPred = old->info->fcn->nullPred;
8425     }
8426
8427   if (unew->info->fcn->specialCode != SPC_NONE)
8428     {
8429       if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8430         {
8431           if (optgenerror
8432               (FLG_INCONDEFS,
8433                message ("Function %q inconsistently %rdeclared using %s",
8434                         uentry_getName (unew),
8435                         uentry_isDeclared (old),
8436                         specCode_unparse (unew->info->fcn->specialCode)),
8437                uentry_whereDeclared (unew)))
8438             {
8439               uentry_showWhereSpecified (old);
8440             }
8441         }
8442     }
8443   else
8444     {
8445       unew->info->fcn->specialCode = old->info->fcn->specialCode;
8446     }
8447           
8448   /*
8449   ** check parameters
8450   */
8451   
8452   if (!uentryList_sameObject (oldParams, newParams)
8453       && (!uentryList_isMissingParams (oldParams)))
8454     {
8455       if (!uentryList_isMissingParams (newParams))
8456         {
8457           int paramno = 0;
8458           int nparams = uentryList_size (oldParams);
8459           bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8460
8461           if (nparams != uentryList_size (newParams))
8462             {
8463               nargsError (old, unew);
8464             }
8465           
8466           if (uentryList_size (newParams) < nparams) 
8467             {
8468               nparams = uentryList_size (newParams);
8469             }
8470
8471           while (paramno < nparams)
8472             {
8473               uentry oldCurrent = uentryList_getN (oldParams, paramno);
8474               uentry newCurrent  = uentryList_getN (newParams, paramno);
8475               ctype  oldCurrentType = uentry_getType (oldCurrent);
8476               ctype  newCurrentType = uentry_getType (newCurrent);
8477
8478               llassert (uentry_isValid (oldCurrent)
8479                         && uentry_isValid (newCurrent));
8480               
8481               if (!uentry_isElipsisMarker (oldCurrent)
8482                   && !uentry_isElipsisMarker (newCurrent))
8483                 {
8484                   checkVarConformance (oldCurrent, newCurrent, 
8485                                        mustConform, completeConform);
8486                 }
8487
8488               if (checknames)
8489                 {
8490                   if (uentry_hasName (oldCurrent) 
8491                       && uentry_hasName (newCurrent))
8492                     {
8493                       cstring oldname = uentry_getName (oldCurrent);
8494                       cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8495                       cstring oname;
8496                       cstring nname = uentry_getName (newCurrent);
8497                       cstring nnamefix;
8498
8499                       if (cstring_isDefined (pfx)
8500                           && cstring_equalPrefix (oldname, pfx))
8501                         {
8502                           oname = cstring_suffix (oldname, cstring_length (pfx));
8503                         }
8504                       else
8505                         {
8506                           oname = oldname;
8507                         /*@-branchstate@*/ } /*@=branchstate@*/
8508
8509                       if (cstring_isDefined (pfx)
8510                           && cstring_equalPrefix (nname, pfx))
8511                         {
8512                           nnamefix = cstring_suffix (nname, cstring_length (pfx));
8513                         }
8514                       else
8515                         {
8516                           nnamefix = nname;
8517                         /*@-branchstate@*/ } /*@=branchstate@*/
8518
8519                       if (!cstring_equal (oname, nnamefix))
8520                         {
8521                           if (optgenerror
8522                               (FLG_DECLPARAMMATCH, 
8523                                message ("Definition parameter name %s does not match "
8524                                         "name of corresponding parameter in "
8525                                         "declaration: %s",
8526                                         nnamefix, oname),
8527                                uentry_whereLast (newCurrent)))
8528                             {
8529                               uentry_showWhereLastPlain (oldCurrent);
8530                             }
8531                         }
8532                       
8533                       cstring_free (oldname);
8534                       cstring_free (nname);
8535                     }
8536                 }
8537
8538               if (!ctype_match (oldCurrentType, newCurrentType))
8539                 {
8540                   paramTypeError (old, oldCurrent, oldCurrentType,
8541                                   unew, newCurrent, newCurrentType, paramno);
8542                 }
8543               else
8544                 {
8545                   if (ctype_isMissingParamsMarker (newCurrentType)
8546                       || ctype_isElips (newCurrentType)
8547                       || ctype_isMissingParamsMarker (oldCurrentType)
8548                       || ctype_isElips (oldCurrentType))
8549                     {
8550                       ;
8551                     }
8552                   else
8553                     {
8554                       if (ctype_isConj (newCurrentType))
8555                         {
8556                           if (ctype_isConj (oldCurrentType))
8557                             {
8558                               if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8559                                 {
8560                                   if (optgenerror 
8561                                       (FLG_INCONDEFS,
8562                                        message ("Parameter %q inconsistently %rdeclared with "
8563                                                 "alternate types %s "
8564                                                 "(types match, but alternates are not identical, "
8565                                                 "so checking may not be correct)",
8566                                                 uentry_getName (newCurrent),
8567                                                 uentry_isDeclared (oldCurrent),
8568                                                 ctype_unparse (newCurrentType)),
8569                                        uentry_whereDeclared (unew)))
8570                                     {
8571                                       uentry_showWhereLastVal (oldCurrent,
8572                                                                ctype_unparse (oldCurrentType));
8573                                     }
8574                                 }
8575                             }
8576                           else
8577                             {
8578                               if (optgenerror 
8579                                   (FLG_INCONDEFS,
8580                                    message ("Parameter %q inconsistently %rdeclared with "
8581                                             "alternate types %s",
8582                                             uentry_getName (newCurrent),
8583                                             uentry_isDeclared (oldCurrent),
8584                                             ctype_unparse (newCurrentType)),
8585                                    uentry_whereDeclared (unew)))
8586                                 {
8587                                   uentry_showWhereLastVal (oldCurrent,
8588                                                            ctype_unparse (oldCurrentType));
8589                                   
8590                                 }
8591                             }
8592                         }
8593                       else 
8594                         {
8595                           if (ctype_isConj (oldCurrentType))
8596                             {
8597                               uentry_setType (newCurrent, oldCurrentType);
8598                             }
8599                         }
8600                     }
8601                 }
8602
8603               paramno++;  
8604               /*
8605                ** Forgot this!  detected by splint:
8606                ** uentry.c:1257,15: Suspected infinite loop
8607                */
8608             }
8609         }
8610     }
8611
8612   if (!uentryList_isMissingParams (newParams))
8613     {
8614       if (ctype_isConj (oldRetType))
8615         {
8616           old->utype = ctype_makeFunction (oldRetType, 
8617                                            uentryList_copy (newParams));
8618         }
8619       else
8620         {
8621           old->utype = unew->utype;
8622         }
8623     }
8624
8625   checkGlobalsConformance (old, unew, mustConform, completeConform);
8626   checkModifiesConformance (old, unew, mustConform, completeConform);
8627
8628   DPRINTF (("Before list: %s",
8629             uentry_unparseFull (old)));
8630
8631   if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8632     {
8633       if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8634         {
8635           /*
8636           if (optgenerror
8637               (FLG_INCONDEFS,
8638                message ("Function %q redeclared using special clauses (can only "
8639                         "be used in first declaration)",
8640                         uentry_getName (unew)),
8641                uentry_whereDeclared (unew)))
8642             {
8643               uentry_showWhereLast (old);
8644             }
8645           */
8646
8647           /* need to add some checking @*/ 
8648           old->info->fcn->specclauses = unew->info->fcn->specclauses;
8649         }
8650       else
8651         {
8652           /* should be able to append? */
8653
8654           stateClauseList_checkEqual (old, unew);
8655           stateClauseList_free (unew->info->fcn->specclauses);
8656           unew->info->fcn->specclauses = stateClauseList_undefined;
8657           /*@-branchstate@*/ 
8658         }
8659     }
8660   /*@=branchstate@*/ /* shouldn't need this */
8661
8662   if (fileloc_isUndefined (old->whereDeclared))
8663     {
8664       old->whereDeclared = fileloc_copy (unew->whereDeclared);
8665     }
8666   else if (fileloc_isUndefined (unew->whereDeclared))
8667     {
8668       unew->whereDeclared = fileloc_copy (old->whereDeclared);
8669     }
8670   else
8671     {
8672       /* no change */
8673     }
8674   /*@-compmempass@*/
8675 } /*@=compmempass@*/ /* I think this is a spurious warning */
8676
8677 void
8678 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8679 {
8680   multiVal uval;
8681
8682   llassert (uentry_isValid (ue));
8683   llassert (uentry_isEitherConstant (ue));
8684
8685   DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8686   uval = uentry_getConstantValue (ue);
8687
8688   if (multiVal_isDefined (uval))
8689     {
8690       if (multiVal_isDefined (m))
8691         {
8692           if (!multiVal_equiv (uval, m))
8693             {
8694               if (optgenerror 
8695                   (FLG_INCONDEFS,
8696                    message ("%s %q defined with inconsistent value: %q",
8697                             ekind_capName (ue->ukind),
8698                             uentry_getName (ue), 
8699                             multiVal_unparse (m)),
8700                    g_currentloc))
8701                 {
8702                   uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8703                 }
8704             }
8705         }
8706       multiVal_free (m);
8707     }
8708   else
8709     {
8710       uentry_setConstantValue (ue, m);
8711     }
8712 }
8713
8714 static
8715 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
8716                            bool mustConform)
8717 {
8718   bool typeError = FALSE;
8719
8720   if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8721     {
8722       if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8723         {
8724           if (mustConform)
8725             {
8726               DPRINTF (("Check struct conformance: %s / %s",
8727                         uentry_unparseFull (old),
8728                         uentry_unparseFull (unew)));
8729               checkStructConformance (old, unew); 
8730             }
8731         }
8732       else
8733         {
8734           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8735             {
8736               llbug (message ("struct tags: bad types: %t / %t", 
8737                               old->utype, unew->utype));
8738             }
8739         }
8740     }
8741   else if (uentry_isEnumTag (old))
8742     {
8743       if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8744         {
8745           if (mustConform) checkEnumConformance (old, unew);
8746         }
8747       else 
8748         {
8749           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8750             {
8751               llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8752                               ctype_unparse (unew->utype)));
8753             }
8754         }
8755     }
8756   else if (!ctype_match (old->utype, unew->utype))
8757     {
8758       DPRINTF (("Type mismatch: %s / %s",
8759                 ctype_unparse (old->utype),
8760                 ctype_unparse (unew->utype)));
8761
8762       if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8763         {
8764           ctype realt = ctype_realType (unew->utype);
8765           
8766           if (ctype_isRealInt (realt) || ctype_isChar (realt))
8767             {
8768               unew->utype = ctype_bool;
8769             }
8770           else
8771             {
8772               if (mustConform)
8773                 {
8774                   typeError = optgenerror
8775                     (FLG_INCONDEFS,
8776                      message ("%q defined as %s", uentry_getName (old), 
8777                               ctype_unparse (realt)),
8778                      uentry_whereDeclared (unew));
8779                 }
8780             }
8781         } 
8782       else 
8783         {
8784           if (mustConform)
8785             {
8786               ctype oldr = ctype_realType (old->utype);
8787               ctype newr = ctype_realType (unew->utype);
8788               
8789               if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8790                 {
8791                   checkStructConformance (old, unew);
8792                 }
8793               else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8794                 {
8795                   checkStructConformance (old, unew);
8796                 }
8797               else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8798                 {
8799                   checkEnumConformance (old, unew);
8800                 }
8801               else if (uentry_isConstant (old) 
8802                        && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8803                 {
8804                   /* okay...for now! (should check the type is reset later... */
8805                 }
8806               else
8807                 {
8808                   DPRINTF (("YABA!"));
8809                   if (optgenerror 
8810                       (FLG_INCONDEFS,
8811                        message ("%s %q %rdeclared with inconsistent type: %t",
8812                                 ekind_capName (unew->ukind),
8813                                 uentry_getName (unew), 
8814                                 uentry_isDeclared (old),
8815                                 unew->utype),
8816                        uentry_whereDeclared (unew)))
8817                     {
8818                       uentry_showWhereLast (old);
8819                       typeError = TRUE;
8820                     }
8821                 }
8822             }
8823         }
8824     }
8825   else
8826     {
8827       /* no error */
8828     }
8829
8830   return typeError;
8831 }
8832
8833 static void
8834 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8835                                  /*@notnull@*/ uentry unew,
8836                                  bool mustConform, bool completeConform)
8837 {
8838   if (ctype_isDefined (unew->info->datatype->type))
8839     {
8840       /*
8841       ** bool is hard coded here, since it is built into LCL.
8842       ** For now, we're stuck with LCL's types.
8843       */
8844
8845       if (ctype_isDirectBool (old->utype) &&
8846           cstring_equalLit (unew->uname, "bool"))
8847         {
8848           /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8849              evs 2000-07-25: removed
8850           */
8851               unew->utype = ctype_bool;
8852         }
8853       
8854       if (ctype_isUnknown (old->info->datatype->type))
8855         {
8856           old->info->datatype->type = unew->info->datatype->type;
8857         }
8858       else
8859         {
8860           DPRINTF (("Old: %s / New: %s",
8861                     uentry_unparseFull (old),
8862                     uentry_unparseFull (unew)));
8863           DPRINTF (("Types: %s / %s",
8864                     ctype_unparse (old->info->datatype->type),
8865                     ctype_unparse (unew->info->datatype->type)));
8866
8867           if (ctype_matchDef (old->info->datatype->type,
8868                               unew->info->datatype->type))
8869             {
8870               ;
8871             }
8872           else
8873             {
8874               if (optgenerror 
8875                   (FLG_INCONDEFS,
8876                    message
8877                    ("Type %q %s with inconsistent type: %t",
8878                     uentry_getName (unew), 
8879                     uentry_reDefDecl (old, unew),
8880                     unew->info->datatype->type),
8881                    uentry_whereDeclared (unew)))
8882                 {
8883                   uentry_showWhereLastExtra 
8884                     (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8885                 }
8886
8887               old->info->datatype->type = unew->info->datatype->type;
8888             }
8889         }
8890     }
8891   
8892   if (!qual_isUnknown (unew->info->datatype->abs))
8893     {
8894       if (qual_isConcrete (old->info->datatype->abs)
8895           && qual_isEitherAbstract (unew->info->datatype->abs))
8896         {
8897           if (!ctype_isDirectBool (old->utype))
8898             {
8899               if (optgenerror 
8900                   (FLG_INCONDEFS,
8901                    message 
8902                    ("Datatype %q inconsistently %rdeclared as abstract type",
8903                     uentry_getName (unew), 
8904                     uentry_isDeclared (old)),
8905                    uentry_whereDeclared (unew)))
8906                 {
8907                   uentry_showWhereLastPlain (old);
8908                 }
8909             }
8910         }
8911       else if (qual_isEitherAbstract (old->info->datatype->abs)
8912                && qual_isConcrete (unew->info->datatype->abs))
8913         {
8914           if (!ctype_isDirectBool (old->utype))
8915             {
8916               if (optgenerror 
8917                   (FLG_INCONDEFS,
8918                    message 
8919                    ("Datatype %q inconsistently %rdeclared as concrete type",
8920                     uentry_getName (unew), 
8921                     uentry_isDeclared (old)),
8922                    uentry_whereDeclared (unew)))
8923                 {
8924                   uentry_showWhereLastPlain (old);
8925                 }
8926             }
8927         }
8928       else
8929         {
8930           ;
8931         }
8932     }
8933   else 
8934     {
8935       if (qual_isEitherAbstract (old->info->datatype->abs))
8936         {
8937           old->sref = unew->sref;
8938           unew->info->datatype->mut = old->info->datatype->mut;
8939           
8940           if (completeConform
8941               && uentry_isReallySpecified (old))
8942             {
8943               if (optgenerror 
8944                   (FLG_NEEDSPEC,
8945                    message 
8946                    ("Datatype %q specified as abstract, "
8947                     "but abstract annotation not used in declaration",
8948                     uentry_getName (unew)), 
8949                    uentry_whereDeclared (unew)))
8950                 {
8951                   uentry_showWhereLastPlain (old);
8952                 }
8953             }
8954         }
8955     }
8956   
8957   unew->info->datatype->abs = old->info->datatype->abs;   
8958   
8959   if (ynm_isMaybe (unew->info->datatype->mut))
8960     {
8961       if (completeConform && ynm_isOff (old->info->datatype->mut)
8962           && uentry_isReallySpecified (old))
8963         {
8964           if (optgenerror 
8965               (FLG_NEEDSPEC,
8966                message 
8967                ("Datatype %q specified as immutable, "
8968                 "but immutable annotation not used in declaration",
8969                 uentry_getName (unew)), 
8970                uentry_whereDeclared (unew)))
8971             {
8972               uentry_showWhereLastPlain (old);
8973             }
8974         }
8975       
8976       unew->info->datatype->mut = old->info->datatype->mut;
8977     }
8978   else if (ynm_isMaybe (old->info->datatype->mut))
8979     {
8980       old->info->datatype->mut = unew->info->datatype->mut;
8981     }
8982   else
8983     {
8984       if (qual_isEitherAbstract (old->info->datatype->abs))
8985         {
8986           if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8987             {
8988               if (optgenerror
8989                   (FLG_INCONDEFS,
8990                    message ("Datatype %q inconsistently %rdeclared as immutable",
8991                             uentry_getName (unew), 
8992                             uentry_isDeclared (old)),
8993                    uentry_whereDeclared (unew)))
8994                 {
8995                   uentry_showWhereLastPlain (old);
8996                 }
8997             }
8998           else 
8999             {
9000               if (ynm_isOff (old->info->datatype->mut)
9001                   && ynm_isOn (unew->info->datatype->mut))
9002                 {
9003                   if (optgenerror
9004                       (FLG_INCONDEFS,
9005                        message ("Datatype %q inconsistently %rdeclared as mutable",
9006                                 uentry_getName (unew), 
9007                                 uentry_isDeclared (old)),
9008                        uentry_whereDeclared (unew)))
9009                     {
9010                       uentry_showWhereLastPlain (old);
9011                     }
9012                 }
9013             }
9014         }
9015       old->info->datatype->mut = unew->info->datatype->mut;       
9016     }
9017
9018   uentry_checkStateConformance (old, unew, mustConform, completeConform);
9019 }
9020
9021 static void
9022 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
9023                                  /*@notnull@*/ uentry unew,
9024                                  bool mustConform, 
9025                                  /*@unused@*/ bool completeConform)
9026 {
9027   multiVal oldval = uentry_getConstantValue (old);
9028   multiVal newval = uentry_getConstantValue (unew);
9029   
9030   if (multiVal_isDefined (oldval))
9031     {
9032       if (multiVal_isDefined (newval))
9033         {
9034           if (!multiVal_equiv (oldval, newval))
9035             {
9036               if (mustConform
9037                   && optgenerror 
9038                   (FLG_INCONDEFS,
9039                    message ("%s %q %rdeclared with inconsistent value: %q",
9040                             ekind_capName (unew->ukind),
9041                             uentry_getName (unew), 
9042                             uentry_isDeclared (old),
9043                             multiVal_unparse (newval)),
9044                    uentry_whereDeclared (unew)))
9045                 {
9046                   uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9047                 }
9048             }
9049           
9050           uentry_setConstantValue (unew, multiVal_copy (oldval));
9051         }
9052       else
9053         {
9054           ;
9055         }
9056     }
9057   else
9058     {
9059       uentry_setConstantValue (old, multiVal_copy (newval));
9060     }
9061 }
9062
9063 static void 
9064 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old, 
9065                          /*@notnull@*/ uentry unew, bool mustConform,
9066                          bool completeConform)
9067 {
9068   bool typeError = FALSE;
9069   bool fcnConformance = FALSE;
9070
9071   if (!ekind_equal (unew->ukind, old->ukind))
9072     {
9073       /*
9074       ** okay, only if one is a function and the other is
9075       ** a variable of type function.
9076       */
9077
9078       if (unew->ukind == KENUMCONST
9079           && old->ukind == KCONST)
9080         {
9081           old->ukind = KENUMCONST;
9082           goto nokinderror;
9083         }
9084
9085       if (unew->ukind == KFCN 
9086           && old->ukind == KCONST
9087           && ctype_isUnknown (old->utype))
9088         {
9089           /*
9090           ** When a function is defined with an unparam macro
9091           */
9092
9093           uentry_updateInto (old, unew);
9094           return;
9095         }
9096
9097       if (uentry_isExpandedMacro (old) 
9098           && uentry_isEitherConstant (unew))
9099         {
9100           uentry_updateInto (old, unew);
9101           return;
9102         }
9103
9104       if (uentry_isEndIter (unew))
9105         {
9106           if (ctype_isUnknown (old->utype))
9107             {
9108               if (!uentry_isSpecified (old)
9109                   && uentry_isCodeDefined (unew))
9110                 {
9111                   if (!fileloc_withinLines (uentry_whereDefined (old),
9112                                             uentry_whereDeclared (unew), 2))
9113                     { /* bogus!  will give errors if there is too much whitespace */
9114                       voptgenerror
9115                         (FLG_SYNTAX,
9116                          message
9117                          ("Iterator finalized name %q does not match name in "
9118                           "previous iter declaration (should be end_%q).  This iter "
9119                           "is declared at %q", 
9120                           uentry_getName (unew),
9121                           uentry_getName (old),
9122                           fileloc_unparse (uentry_whereDefined (old))),
9123                          uentry_whereDeclared (old));
9124                     }
9125                 }
9126
9127               uentry_updateInto (old, unew);
9128               return;
9129             }
9130           else
9131             {
9132               KindConformanceError (old, unew, mustConform);
9133             }
9134         }
9135
9136       if (uentry_isFunction (unew))
9137         {
9138           if (uentry_isVariable (old))
9139             {
9140               if (!ctype_isUnknown (old->utype))
9141                 {
9142                   if (ctype_isFunction (old->utype))
9143                     {
9144                       uentry_makeVarFunction (old);
9145                       checkFunctionConformance (old, unew, mustConform,
9146                                                 completeConform);
9147                       fcnConformance = TRUE;
9148                     }
9149                   else
9150                     {
9151                       KindConformanceError (old, unew, mustConform);
9152                     }
9153                 }
9154               else
9155                 {
9156                   if (uentry_isExpandedMacro (old))
9157                     {
9158                       if (fileloc_isUndefined (unew->whereDefined))
9159                         {
9160                           unew->whereDefined = fileloc_update (unew->whereDefined, 
9161                                                               old->whereDefined);
9162                         }
9163
9164                       uentry_updateInto (old, unew);
9165                       old->used = unew->used = TRUE;
9166                       return;
9167                     }
9168                   else
9169                     {
9170                       /* undeclared identifier */
9171                       old->utype = unew->utype;
9172                       uentry_makeVarFunction (old);
9173                       checkFunctionConformance (old, unew, FALSE, FALSE);
9174                       fcnConformance = TRUE;
9175                     }
9176                 }
9177             }
9178           else
9179             {
9180               KindConformanceError (old, unew, mustConform);
9181             }
9182         }
9183       else if (uentry_isFunction (old) && uentry_isVariable (unew))
9184         {
9185           if (!ctype_isUnknown (unew->utype))
9186             {
9187               if (ctype_isFunction (unew->utype))
9188                 {
9189                   uentry_makeVarFunction (unew);
9190                   checkFunctionConformance (old, unew, mustConform, completeConform);
9191                   fcnConformance = TRUE;
9192                 }
9193               else
9194                 {
9195                   KindConformanceError (old, unew, mustConform);
9196                 }
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       /*
9211       ** check parameter lists for functions 
9212       ** (before type errors, to get better messages
9213       */
9214
9215       if (uentry_isFunction (old))
9216         {
9217           checkFunctionConformance (old, unew, mustConform, completeConform);
9218           fcnConformance = TRUE;
9219         }
9220       else 
9221         {
9222           if (!ctype_isUndefined (old->utype))
9223             {
9224               typeError = checkTypeConformance (old, unew, mustConform);
9225             }
9226         }
9227     }
9228
9229  nokinderror:
9230
9231   if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9232     {
9233       uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9234     }
9235
9236   if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9237     {
9238       DPRINTF (("Check datatype: %s / %s",
9239                 uentry_unparseFull (old),
9240                 uentry_unparseFull (unew)));
9241
9242       uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9243     }
9244
9245   if (uentry_isVariable (old) && uentry_isVariable (unew))
9246     {
9247       if (!typeError && 
9248           !ctype_matchDef (old->utype, unew->utype))
9249         {
9250           if (optgenerror 
9251               (FLG_INCONDEFS,
9252                message
9253                ("Variable %q %s with inconsistent type (arrays and pointers are "
9254                 "not identical in variable declarations): %t",
9255                 uentry_getName (unew), 
9256                 uentry_reDefDecl (old, unew),
9257                 unew->utype),
9258                uentry_whereDeclared (unew)))
9259             {
9260               uentry_showWhereLast (old);
9261               
9262               /*
9263               ** Avoid repeated errors.
9264               */
9265
9266               if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9267                 {
9268                   old->whereDefined = fileloc_update (old->whereDefined,
9269                                                       fileloc_undefined);
9270                 }
9271
9272               typeError = TRUE;
9273             }
9274         }
9275
9276       checkVarConformance (old, unew, mustConform, completeConform);
9277     }
9278
9279   if (fcnConformance)
9280     {
9281       /* old->utype = unew->utype; */
9282     }
9283   else
9284     {
9285       if (ctype_isConj (old->utype))
9286         {
9287           if (ctype_isConj (unew->utype))
9288             {
9289               if (!ctype_sameAltTypes (old->utype, unew->utype))
9290                 {
9291                   if (optgenerror 
9292                       (FLG_INCONDEFS,
9293                        message ("%s %q inconsistently %rdeclared with "
9294                                 "alternate types %s "
9295                                 "(types match, but alternates are not identical, "
9296                                 "so checking may not be correct)",
9297                                 ekind_capName (uentry_getKind (old)),
9298                                 uentry_getName (unew),
9299                                 uentry_isDeclared (old),
9300                                 ctype_unparse (unew->utype)),
9301                        uentry_whereDeclared (unew)))
9302                     {
9303                       uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9304                     }
9305                   else
9306                     {
9307                       old->utype = unew->utype;
9308                     }
9309                 }
9310             }
9311         }
9312       else
9313         {
9314           if (ctype_isUnknown (old->utype))
9315             {
9316               old->utype = unew->utype;
9317             }
9318         }
9319     }  
9320
9321   if (unew->ukind == old->ukind) 
9322     {
9323       sfree (unew->info);
9324       unew->info = uinfo_copy (old->info, old->ukind);
9325     }
9326
9327   sRef_storeState (old->sref);
9328   sRef_storeState (unew->sref);
9329 }
9330
9331 static void uentry_mergeConstraints (uentry spec, uentry def)
9332 {
9333   if (uentry_isFunction (def))
9334     {
9335       DPRINTF (("Here: %s / %s",
9336                 uentry_unparseFull (spec),
9337                 uentry_unparseFull (def)));
9338       /* evans 2001-07-21 */
9339       llassert (uentry_isFunction (spec));
9340
9341       if (functionConstraint_isDefined (def->info->fcn->preconditions))
9342         {
9343           if (fileloc_isXHFile (uentry_whereLast (def)))
9344             {
9345               llassert (uentry_isFunction (spec));
9346               spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9347                                                                            def->info->fcn->preconditions);
9348             }
9349           else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9350             {
9351               ;
9352             }
9353           else
9354             {
9355               /* Check if the constraints are identical */
9356
9357               if (optgenerror 
9358                   (FLG_INCONDEFS,
9359                    message
9360                    ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9361                     uentry_getName (spec),
9362                     functionConstraint_unparse (spec->info->fcn->preconditions)),
9363                    uentry_whereLast (def)))
9364                 {
9365                   uentry_showWhereSpecified (spec);
9366                 }
9367
9368               functionConstraint_free (spec->info->fcn->preconditions);
9369               spec->info->fcn->preconditions = def->info->fcn->preconditions;
9370             }
9371           
9372           def->info->fcn->preconditions = functionConstraint_undefined;
9373         }
9374
9375       if (functionConstraint_isDefined (def->info->fcn->postconditions))
9376         {
9377           if (fileloc_isXHFile (uentry_whereLast (def)))
9378             {
9379               llassert (uentry_isFunction (spec));
9380               DPRINTF (("Post: %s /++/ %s",
9381                         functionConstraint_unparse (spec->info->fcn->postconditions),
9382                         functionConstraint_unparse (def->info->fcn->postconditions)));
9383               spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9384                                                                             def->info->fcn->postconditions);
9385               def->info->fcn->postconditions = functionConstraint_undefined;
9386               DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9387             }
9388           else
9389             {
9390               if (optgenerror 
9391                   (FLG_INCONDEFS,
9392                    message
9393                    ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9394                     uentry_getName (spec),
9395                     functionConstraint_unparse (spec->info->fcn->postconditions)),
9396                    uentry_whereLast (def)))
9397                 {
9398                   uentry_showWhereSpecified (spec);
9399                 }
9400               
9401               functionConstraint_free (spec->info->fcn->postconditions);
9402               spec->info->fcn->postconditions = def->info->fcn->postconditions;
9403               def->info->fcn->postconditions = functionConstraint_undefined;
9404             }
9405         }
9406     }
9407 }
9408
9409 /*
9410 ** modifies spec to reflect def, reports any inconsistencies
9411 */
9412
9413 void
9414 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9415 {
9416   llassert (uentry_isValid (spec));
9417   llassert (uentry_isValid (def));
9418   llassert (cstring_equal (spec->uname, def->uname));
9419
9420   if (uentry_isFunction (def))
9421     {
9422       if (uentry_isConstant (spec))
9423         {
9424           llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9425           uentry_makeConstantFunction (spec);
9426         }
9427       else
9428         {
9429           uentry_convertVarFunction (spec);
9430         }
9431
9432       llassert (uentry_isFunction (spec));
9433     }
9434   
9435   DPRINTF (("Merge entries: %s / %s",
9436             uentry_unparseFull (spec),
9437             uentry_unparseFull (def)));
9438
9439   uentry_mergeConstraints (spec, def);
9440
9441   uentry_checkConformance (spec, def, TRUE, 
9442                            context_getFlag (FLG_NEEDSPEC));
9443
9444   DPRINTF (("Merge entries after conform: %s / %s",
9445             uentry_unparseFull (spec),
9446             uentry_unparseFull (def)));
9447
9448   /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9449
9450   /*
9451   ** okay, declarations conform.  Propagate extra information.
9452   */
9453
9454   uentry_setDefined (spec, uentry_whereDefined (def));
9455   uentry_setDeclared (spec, uentry_whereDeclared (def));
9456
9457   if (uentry_isStatic (def))
9458     {
9459       if (optgenerror 
9460           (FLG_INCONDEFS,
9461            message ("%s %q specified, but declared as static",
9462                     ekind_capName (def->ukind),
9463                     uentry_getName (def)),
9464            uentry_whereDeclared (def)))
9465         {
9466           uentry_showWhereSpecified (spec);
9467         }
9468     }
9469   else 
9470     {
9471       spec->storageclass = def->storageclass;
9472     }
9473
9474   sRef_storeState (spec->sref);
9475
9476   spec->used = def->used || spec->used;
9477   spec->hasNameError |= def->hasNameError;
9478
9479   uentry_free (def);
9480
9481   if (!spec->hasNameError)
9482     {
9483       uentry_checkName (spec);
9484     }
9485   else
9486     {
9487       ;
9488     }
9489 }
9490
9491 /*
9492 ** Can't generate function redeclaration errors when the 
9493 ** entries are merged, since we don't yet know if its the
9494 ** definition of the function.
9495 */
9496
9497 void
9498 uentry_clearDecl (void)
9499 {
9500   posRedeclared = uentry_undefined;
9501   fileloc_free (posLoc);
9502   posLoc = fileloc_undefined;
9503 }
9504
9505 void
9506 uentry_checkDecl (void)
9507 {
9508   if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9509     {
9510       llassert (fileloc_isDefined (posLoc));
9511
9512       if (uentry_isCodeDefined (posRedeclared))
9513         {
9514           if (optgenerror (FLG_REDECL,
9515                            message ("%s %q declared after definition", 
9516                                     ekind_capName (posRedeclared->ukind),
9517                                     uentry_getName (posRedeclared)),
9518                            posLoc))
9519             {
9520               llgenindentmsg (message ("Definition of %q", 
9521                                        uentry_getName (posRedeclared)),
9522                               posRedeclared->whereDeclared);
9523             }
9524         }
9525       else
9526         {
9527           if (optgenerror (FLG_REDECL,
9528                            message ("%s %q declared more than once", 
9529                                     ekind_capName (posRedeclared->ukind),
9530                                     uentry_getName (posRedeclared)),
9531                            posLoc))
9532             {
9533               llgenindentmsg (message ("Previous declaration of %q", 
9534                                        uentry_getName (posRedeclared)),
9535                               posRedeclared->whereDeclared);
9536             }
9537         }
9538     }
9539
9540   fileloc_free (posLoc);
9541   posLoc = fileloc_undefined;
9542   posRedeclared = uentry_undefined;
9543 }
9544
9545 /*
9546 ** Redefinition of old as unew.
9547 ** modifies old to reflect unew, reports any inconsistencies
9548 */
9549
9550 void
9551 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9552 {
9553   fileloc olddef = uentry_whereDeclared (old); 
9554   fileloc unewdef = uentry_whereDeclared (unew);
9555   bool mustConform;
9556   bool wasForward;
9557
9558   DPRINTF (("uentry merge: %s / %s",
9559             uentry_unparseFull (old),
9560             uentry_unparseFull (unew)));
9561  
9562   wasForward = 
9563     fileloc_isUndefined (olddef) 
9564     && fileloc_isDefined (uentry_whereDefined (old)) 
9565     && !uentry_isExpandedMacro (old);
9566   
9567   if (!context_getFlag (FLG_INCONDEFSLIB)
9568       && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9569     {
9570       mustConform = FALSE;
9571     }
9572   else
9573     {
9574       mustConform = TRUE;
9575     }
9576   
9577   llassert (uentry_isValid (old));
9578   llassert (uentry_isValid (unew));
9579   llassert (cstring_equal (old->uname, unew->uname));
9580
9581   if (uentry_isFunction (unew) && !uentry_isFunction (old))
9582     {
9583       if (uentry_isConstant (old))
9584         {
9585           llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9586           uentry_makeConstantFunction (old);
9587         }
9588       else
9589         {
9590           uentry_convertVarFunction (old);
9591         }
9592
9593       llassert (uentry_isFunction (old));
9594     }
9595
9596   DPRINTF (("uentry merge: %s / %s",
9597             uentry_unparseFull (old),
9598             uentry_unparseFull (unew)));
9599
9600   if (uentry_isExtern (unew))
9601     {
9602       uentry_setUsed (old, unewdef);
9603     }
9604
9605   /*
9606   ** should check old one was extern!
9607   */
9608
9609   if (uentry_isStatic (old))
9610     {
9611       if (!(uentry_isStatic (unew)))
9612         {
9613           if (optgenerror 
9614               (FLG_SHADOW,
9615                message ("%s %q shadows static declaration",
9616                         ekind_capName (unew->ukind),
9617                         uentry_getName (unew)),
9618                unewdef))
9619             {
9620               uentry_showWhereLast (old);
9621             }
9622         }
9623       else
9624         {
9625           uentry_setDeclDef (old, unewdef);
9626         }
9627     }
9628   else if (uentry_isStatic (unew))
9629     {
9630       uentry_setDeclDef (old, unewdef);
9631     }
9632   else if (uentry_isExtern (old))
9633     {
9634       uentry_setDeclared (old, unewdef);
9635     }
9636   else
9637     {
9638       if (!uentry_isExtern (unew) 
9639           && !uentry_isForward (old)
9640           && !fileloc_equal (olddef, unewdef)
9641           && !fileloc_isUndefined (olddef)
9642           && !fileloc_isUndefined (unewdef)
9643           && !fileloc_isBuiltin (olddef)
9644           && !fileloc_isBuiltin (unewdef)
9645           && !uentry_isYield (old)
9646           && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9647         {
9648           if (uentry_isVariable (old) || uentry_isVariable (unew))
9649             {
9650               ; /* will report redeclaration error later */
9651             }
9652           else
9653             {
9654               if (fileloc_isDefined (uentry_whereDefined (old)))
9655                 {
9656                   if (optgenerror
9657                       (FLG_REDEF,
9658                        message ("%s %q defined more than once", 
9659                                 ekind_capName (unew->ukind),
9660                                 uentry_getName (unew)),
9661                        uentry_whereLast (unew)))
9662                     {
9663                       llgenindentmsg
9664                         (message ("Previous definition of %q", 
9665                                   uentry_getName (old)),
9666                          uentry_whereLast (old));
9667                     }
9668                   /*
9669                   if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9670                     {
9671                       uentry_updateInto (old, unew);
9672                       old->sref = sRef_saveCopy (old->sref);
9673                     }
9674                     */
9675                 }
9676             }
9677         }
9678       else
9679         {
9680           if (fileloc_isLib (olddef)
9681               || fileloc_isUndefined (olddef)
9682               || fileloc_isImport (olddef))
9683             {
9684               if (uentry_isExtern (unew)) 
9685                 {
9686                   if (uentry_isExtern (old)
9687                       || (fileloc_isDefined (uentry_whereDeclared (old))
9688                           && (!fileloc_equal (uentry_whereDeclared (old),
9689                                               uentry_whereDefined (old)))))
9690                     {
9691                       if (optgenerror
9692                           (FLG_REDECL,
9693                            message ("%s %q declared more than once", 
9694                                     ekind_capName (unew->ukind),
9695                                     uentry_getName (unew)),
9696                            unew->whereDeclared))
9697                         {
9698                           llgenindentmsg
9699                             (message ("Previous declaration of %q", 
9700                                       uentry_getName (old)),
9701                              old->whereDeclared);
9702                         }
9703                     }
9704                   
9705                   uentry_setExtern (old);
9706                 }
9707               else
9708                 {
9709                   uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9710                 }
9711             }
9712         }
9713     }
9714
9715   DPRINTF (("uentry merge: %s / %s",
9716             uentry_unparseFull (old),
9717             uentry_unparseFull (unew)));
9718
9719   uentry_mergeConstraints (old, unew);
9720   DPRINTF (("uentry merge: %s / %s",
9721             uentry_unparseFull (old),
9722             uentry_unparseFull (unew)));
9723
9724   uentry_checkConformance (old, unew, mustConform, FALSE);
9725   DPRINTF (("uentry merge: %s / %s",
9726             uentry_unparseFull (old),
9727             uentry_unparseFull (unew)));
9728
9729   old->used = old->used || unew->used;
9730   old->uses = filelocList_append (old->uses, unew->uses);
9731   unew->uses = filelocList_undefined; 
9732
9733   sRef_storeState (old->sref); 
9734   sRef_storeState (unew->sref);
9735
9736   if (wasForward)
9737     {
9738       old->whereDefined = fileloc_update (old->whereDefined,
9739                                           fileloc_undefined);
9740     }
9741
9742   DPRINTF (("here: %s", uentry_unparseFull (old)));
9743
9744   /*
9745   ** No redeclaration errors for functions here, since we
9746   ** don't know if this is the definition of the function.
9747   */
9748
9749   if (fileloc_isUser (old->whereDeclared)
9750       && fileloc_isUser (unew->whereDeclared)
9751       && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9752       && !fileloc_isDefined (unew->whereDefined))
9753     {
9754       if (uentry_isFunction (old))
9755         {
9756           /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9757           posLoc = fileloc_update (posLoc, unew->whereDeclared);
9758         }
9759       else
9760         {
9761           if (optgenerror (FLG_REDECL,
9762                            message ("%s %q declared more than once", 
9763                                     ekind_capName (unew->ukind),
9764                                     uentry_getName (unew)),
9765                            unew->whereDeclared))
9766             {
9767               llgenindentmsg (message ("Previous declaration of %q", 
9768                                        uentry_getName (old)),
9769                               old->whereDeclared);
9770             }
9771         }
9772     }
9773
9774   if (fileloc_isUndefined (old->whereDefined))
9775     {
9776       old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9777     }
9778   else
9779     {
9780       if (!context_processingMacros ()
9781           && fileloc_isUser (old->whereDefined) 
9782           && fileloc_isUser (unew->whereDefined)
9783           && !fileloc_equal (old->whereDefined, unew->whereDefined))
9784         {
9785           if (uentry_isVariable (unew) || uentry_isFunction (unew))
9786             {
9787               if (uentry_isVariable (unew) 
9788                   && uentry_isExtern (unew))
9789                 {
9790                   if (optgenerror (FLG_REDECL,
9791                                    message ("%s %q declared after definition", 
9792                                             ekind_capName (unew->ukind),
9793                                             uentry_getName (unew)),
9794                                    unew->whereDeclared))
9795                     {
9796                       llgenindentmsg (message ("Definition of %q", 
9797                                                uentry_getName (old)),
9798                                       old->whereDefined);
9799                     }
9800                 }
9801               else
9802                 {
9803                   if (optgenerror (FLG_REDEF,
9804                                    message ("%s %q redefined", 
9805                                             ekind_capName (unew->ukind),
9806                                             uentry_getName (unew)),
9807                                    unew->whereDefined))
9808                     {
9809                       llgenindentmsg (message ("Previous definition of %q", 
9810                                                uentry_getName (old)),
9811                                       old->whereDefined);
9812                     }
9813                 }
9814             }
9815         }
9816     }
9817
9818   if (uentry_isExternal (unew))
9819     {
9820       old->whereDefined = fileloc_createExternal ();
9821     }
9822
9823   if (unew->hasNameError)
9824     {
9825       old->hasNameError = TRUE;
9826     }
9827
9828   uentry_free (unew);
9829
9830   if (!old->hasNameError)
9831     {
9832       uentry_checkName (old);
9833     }
9834
9835   DPRINTF (("After: %s", uentry_unparseFull (old)));
9836   llassert (!ctype_isUndefined (old->utype));
9837 }
9838
9839 void
9840 uentry_copyState (uentry res, uentry other)
9841 {
9842   llassert (uentry_isValid (res));
9843   llassert (uentry_isValid (other));
9844
9845   res->used = other->used;
9846
9847   res->info->var->kind = other->info->var->kind;
9848   res->info->var->defstate = other->info->var->defstate;
9849   res->info->var->nullstate = other->info->var->nullstate;
9850   res->info->var->checked = other->info->var->checked;
9851
9852   sRef_copyState (res->sref, other->sref);
9853 }
9854
9855 bool
9856 uentry_sameKind (uentry u1, uentry u2)
9857 {
9858   if (uentry_isValid (u1) && uentry_isValid (u2))
9859     {
9860       if (uentry_isVar (u1) && uentry_isVar (u2))
9861         {
9862           ctype c1 = u1->utype;
9863           ctype c2 = u2->utype;
9864
9865           if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9866
9867           /*
9868           ** both functions, or both not functions
9869           */
9870
9871           return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9872         }
9873       else
9874         {
9875           return ((u1->ukind == u2->ukind));
9876         }
9877     }
9878   
9879   return FALSE;
9880 }
9881    
9882 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9883 {
9884   ekind okind;
9885   llassert (uentry_isValid (unew));
9886   llassert (uentry_isValid (old));
9887
9888   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9889   okind = unew->ukind;
9890   unew->ukind = old->ukind;
9891   llassert (cstring_equal (unew->uname, old->uname));
9892   unew->utype = old->utype;
9893
9894   if (fileloc_isDefined (unew->whereSpecified) 
9895       && !fileloc_isDefined (old->whereSpecified))
9896     {
9897       ; /* Keep the old value */
9898     }
9899   else
9900     {
9901       fileloc_free (unew->whereSpecified);
9902       unew->whereSpecified = fileloc_copy (old->whereSpecified);
9903     }
9904
9905   if (fileloc_isDefined (unew->whereDefined) 
9906       && !fileloc_isDefined (old->whereDefined))
9907     {
9908       ; /* Keep the old value */
9909     }
9910   else
9911     {
9912       fileloc_free (unew->whereDefined); 
9913       unew->whereDefined = fileloc_copy (old->whereDefined);
9914     }
9915
9916   if (fileloc_isDefined (unew->whereDeclared) 
9917       && !fileloc_isDefined (old->whereDeclared))
9918     {
9919       ; /* Keep the old value */
9920     }
9921   else
9922     {
9923       fileloc_free (unew->whereDeclared); 
9924       unew->whereDeclared = fileloc_copy (old->whereDeclared);
9925     }
9926
9927   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9928
9929   unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9930   unew->used = old->used;
9931   unew->lset = FALSE;
9932   unew->isPrivate = old->isPrivate;
9933   unew->hasNameError = old->hasNameError;
9934   unew->uses = filelocList_append (unew->uses, old->uses);
9935   old->uses = filelocList_undefined;
9936
9937   unew->storageclass = old->storageclass;
9938   uinfo_free (unew->info, okind);
9939   unew->info = uinfo_copy (old->info, old->ukind);
9940 }
9941
9942 static uentry
9943 uentry_copyAux (uentry e, bool saveCopy)
9944 {
9945   
9946   if (uentry_isValid (e))
9947     {
9948       uentry enew = uentry_alloc ();
9949       DPRINTF (("copy: %s", uentry_unparseFull (e)));
9950       enew->ukind = e->ukind;
9951       enew->uname = cstring_copy (e->uname);
9952       enew->utype = e->utype;
9953       
9954       enew->whereSpecified = fileloc_copy (e->whereSpecified);
9955       enew->whereDefined = fileloc_copy (e->whereDefined);
9956       enew->whereDeclared = fileloc_copy (e->whereDeclared);
9957       
9958       if (saveCopy)
9959         {
9960           enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9961         }
9962       else
9963         {
9964           enew->sref = sRef_copy (e->sref);
9965         }
9966       
9967       enew->used = e->used;
9968       enew->lset = FALSE;
9969       enew->isPrivate = e->isPrivate;
9970       enew->hasNameError = e->hasNameError;
9971       enew->uses = filelocList_undefined;
9972       
9973       enew->storageclass = e->storageclass;
9974       enew->info = uinfo_copy (e->info, e->ukind);
9975       enew->warn = warnClause_copy (e->warn);
9976
9977       DPRINTF (("Here we are..."));
9978       DPRINTF (("original: %s", uentry_unparseFull (e)));
9979       DPRINTF (("copy: %s", uentry_unparse (enew)));
9980       DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9981       return enew;
9982     }
9983   else
9984     {
9985       return uentry_undefined;
9986     }
9987 }
9988
9989 uentry
9990 uentry_copy (uentry e)
9991 {
9992   return uentry_copyAux (e, TRUE);
9993 }
9994
9995 uentry
9996 uentry_copyNoSave (uentry e)
9997 {
9998   return uentry_copyAux (e, FALSE);
9999 }
10000
10001 void
10002 uentry_setState (uentry res, uentry other)
10003 {
10004   llassert (uentry_isValid (res));
10005   llassert (uentry_isValid (other));
10006
10007   llassert (res->ukind == other->ukind);
10008   llassert (res->ukind == KVAR);
10009
10010   res->sref = sRef_saveCopy (other->sref);
10011   res->used = other->used;
10012   filelocList_free (res->uses); 
10013   res->uses = other->uses; 
10014   other->uses = filelocList_undefined; 
10015   res->lset = other->lset;
10016 }
10017
10018 void
10019 uentry_mergeUses (uentry res, uentry other)
10020 {
10021   llassert (uentry_isValid (res));
10022   llassert (uentry_isValid (other));
10023
10024   res->used = other->used || res->used;
10025   res->lset = other->lset || res->lset;
10026   res->uses = filelocList_append (res->uses, other->uses);
10027   other->uses = filelocList_undefined;
10028 }
10029
10030
10031 /*
10032 ** This is a really ugly routine.
10033 **
10034 ** gack...fix this one day.
10035 */
10036
10037 /*
10038 ** flip == TRUE
10039 **   >> res is the false branch, other is the true branch (or continuation)
10040 ** flip == FALSE
10041 **   >> res is the true branch, other is the false branch (or continutation)
10042 **
10043 ** opt == TRUE if,
10044 **
10045 ** <other>
10046 ** if <res> ;
10047 **
10048 ** References not effected by res are propagated from other.
10049 */
10050
10051 static void
10052 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10053                   bool flip, clause cl, fileloc loc)
10054 {
10055   if (optgenerror 
10056       (FLG_BRANCHSTATE,
10057        message ("%s %q is %s %s, but %s %s.",
10058                 ekind_capName (res->ukind), uentry_getName (res),
10059                 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10060                 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10061        loc))
10062     {
10063       DPRINTF (("Here: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10064
10065       if (sRef_isDead (res->sref))
10066         {
10067           if (sRef_hasStateInfoLoc (res->sref)) {
10068             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10069             sRef_showStateInfo (res->sref);
10070           }
10071
10072           if (sRef_hasStateInfoLoc (other->sref)) {
10073             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10074             sRef_showStateInfo (other->sref);
10075           }
10076         }
10077       else if (sRef_isKept (res->sref))
10078         {
10079           if (sRef_hasAliasInfoLoc (res->sref)) {
10080             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10081             sRef_showAliasInfo (res->sref);
10082           }
10083
10084           if (sRef_hasAliasInfoLoc (other->sref)) {
10085             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10086             sRef_showAliasInfo (other->sref);
10087           }
10088         }
10089       else /* dependent */
10090         {
10091           if (sRef_hasAliasInfoLoc (res->sref)) {
10092             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10093             sRef_showAliasInfo (res->sref);
10094           }
10095
10096           if (sRef_hasAliasInfoLoc (other->sref)) {
10097             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10098             sRef_showAliasInfo (other->sref);
10099           }
10100         }
10101       
10102       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10103     }
10104 }
10105
10106 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10107 {
10108   alkind rk = sRef_getAliasKind (rs);
10109   alkind ok = sRef_getAliasKind (os);
10110
10111   if (alkind_isError (rk) || alkind_isError (ok))
10112     {
10113       return FALSE;
10114     }
10115   else
10116     {
10117       return ((sRef_isDead (rs)
10118                || (alkind_isKept (rk) && !alkind_isKept (ok))
10119                || (alkind_isDependent (rk) 
10120                    && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10121               && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10122     }
10123 }
10124
10125 static void
10126   branchStateAltError (/*@notnull@*/ uentry res,
10127                        /*@notnull@*/ uentry other, bool flip,
10128                        clause cl, fileloc loc)
10129 {
10130   if (optgenerror 
10131       (FLG_BRANCHSTATE,
10132        message ("%s %q is %s %s, but %s %s.",
10133                 ekind_capName (res->ukind), uentry_getName (res),
10134                 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10135                 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10136        loc))
10137     {
10138       if (sRef_isDead (other->sref))
10139         {
10140           if (sRef_hasStateInfoLoc (other->sref)) {
10141             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10142             sRef_showStateInfo (other->sref);
10143           }
10144
10145           if (sRef_hasStateInfoLoc (res->sref)) {
10146             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10147             sRef_showStateInfo (res->sref);
10148           }
10149         }
10150       else /* kept */
10151         {
10152           if (sRef_hasAliasInfoLoc (other->sref)) {
10153             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10154             sRef_showAliasInfo (other->sref);
10155           }
10156
10157           if (sRef_hasAliasInfoLoc (res->sref)) {
10158             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10159             sRef_showAliasInfo (res->sref);
10160           }
10161         }
10162       
10163       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10164       sRef_setDefinedComplete (res->sref, fileloc_undefined);
10165       
10166       sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10167       sRef_setDefinedComplete (other->sref, fileloc_undefined);
10168     }
10169 }
10170
10171 /*
10172 ** A reference is relevant for certain checks, only if it 
10173 ** is not definitely null on this path (but not declared
10174 ** to always be null.)
10175 */
10176
10177 static bool uentry_relevantReference (sRef sr, bool flip)
10178 {
10179   if (sRef_isKept (sr) || sRef_isDependent (sr))
10180     {
10181       return FALSE;
10182     }
10183   else
10184     {
10185       if (flip)
10186         {
10187           return !sRef_definitelyNullContext (sr);
10188         }
10189       else
10190         {
10191           return !sRef_definitelyNullAltContext (sr);
10192         }
10193     }
10194 }
10195
10196 static void
10197 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10198                          fileloc loc, bool mustReturn, bool flip, bool opt,
10199                          clause cl)    
10200 {
10201   sRef rs = res->sref;
10202   sRef os = other->sref;
10203
10204   DPRINTF (("Merge alias states: %s / %s",
10205             uentry_unparseFull (res),
10206             uentry_unparseFull (other)));
10207
10208   if (sRef_isValid (rs))
10209     {
10210       if (!mustReturn)
10211         {
10212           if (uentry_incompatibleMemoryStates (rs, os))
10213             {
10214               DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10215                         sRef_unparseFull (rs), sRef_unparseFull (os)));
10216
10217               if (sRef_isThroughArrayFetch (rs)
10218                   && !context_getFlag (FLG_STRICTBRANCHSTATE))
10219                 {
10220                   if (sRef_isKept (rs) || sRef_isKept (os))
10221                     {
10222                       sRef_maybeKill (rs, loc);
10223                     }
10224                   else if (sRef_isPossiblyDead (os))
10225                     {
10226                       sRef_maybeKill (rs, loc);
10227                     }
10228                   else
10229                     {
10230                       ;
10231                     }
10232                 }
10233               else
10234                 {
10235                   if (uentry_relevantReference (os, flip))
10236                     {
10237                       if (sRef_isLocalParamVar (rs) 
10238                           && (sRef_isLocalState (os) 
10239                               || sRef_isDependent (os)))
10240                         {
10241                           if (sRef_isDependent (rs))
10242                             {
10243                               sRef_setDependent (os, loc);
10244                             }
10245                           else
10246                             {
10247                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10248                             }
10249                         }
10250                       else 
10251                         {
10252                           branchStateError (res, other, !flip, cl, loc); /* evans 2002-12-15: changed flip to !flip */
10253                         }
10254                     }
10255                 }
10256               
10257               if (sRef_isKept (rs))
10258                 {
10259                   DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10260                   sRef_setKept (os, loc);
10261                 }
10262             }
10263           else
10264             {
10265               if (uentry_incompatibleMemoryStates (os, rs))
10266                 {
10267                   if (uentry_relevantReference (rs, !flip))
10268                     {
10269                       if (sRef_isLocalParamVar (rs) 
10270                           && (sRef_isDependent (rs)
10271                               || sRef_isLocalState (rs)))
10272                         {
10273                           if (sRef_isDependent (os))
10274                             {
10275                               sRef_setDependent (rs, loc);
10276                             }
10277                           else
10278                             {
10279                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10280                             }
10281                         }
10282                       else
10283                         {
10284                           if (sRef_isParam (os))
10285                             {
10286                               /* 
10287                               ** If the local variable associated
10288                               ** with the param has the correct state,
10289                               ** its okay.
10290                               ** (e.g., free (s); s = new(); ...
10291                               */
10292                               
10293                               uentry uvar = usymtab_lookupSafe (other->uname);
10294                               
10295                               if (uentry_isValid (uvar)
10296                                   && ((sRef_isDead (os) 
10297                                        && sRef_isOnly (uvar->sref))
10298                                       || (sRef_isDependent (os)
10299                                           && sRef_isOwned (uvar->sref))))
10300                                 {
10301                                   /* no error */
10302                                 }
10303                               else
10304                                 {
10305                                   branchStateAltError (res, other,
10306                                                        flip, cl, loc);
10307                                 }
10308                             }
10309                           else
10310                             {
10311                               DPRINTF (("Here: %s / %s",
10312                                         uentry_unparseFull (res),
10313                                         uentry_unparseFull (other)));
10314
10315                               branchStateAltError (res, other, 
10316                                                    flip, cl, loc);
10317                             }
10318                         }
10319                     }
10320                 }
10321               
10322               if (sRef_isKept (os))
10323                 {
10324                   sRef_setKept (rs, loc);
10325                 }
10326             }
10327           
10328           if (opt)
10329             {
10330               DPRINTF (("Merge opt..."));
10331               sRef_mergeOptState (rs, os, cl, loc);
10332               DPRINTF (("Done!"));
10333             }
10334           else
10335             {
10336               DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10337               sRef_mergeState (rs, os, cl, loc);
10338               DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10339             }
10340         }
10341       else
10342         {
10343           if (sRef_isModified (os))
10344             {
10345               sRef_setModified (rs);
10346             }
10347         }
10348     }
10349
10350   DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10351 }
10352
10353 static void
10354 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10355                          fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10356 {
10357   valueTable rvalues;
10358   valueTable ovalues;
10359
10360   DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10361   
10362   if (mustReturn)
10363     {
10364       return;
10365     }
10366   /* flip? */
10367
10368   rvalues = sRef_getValueTable (res->sref);
10369   ovalues = sRef_getValueTable (other->sref);
10370   
10371   if (valueTable_isUndefined (ovalues))
10372     {
10373       DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10374       ;
10375     }
10376   else if (valueTable_isUndefined (rvalues))
10377     {
10378       /*
10379       ** Copy values from other
10380       */
10381       
10382       /*@i$@#@*/
10383       DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10384       DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10385       ;
10386     }
10387   else
10388     {
10389       valueTable_elements (ovalues, fkey, fval) {
10390         stateValue tval;
10391         metaStateInfo minfo;
10392         stateCombinationTable sctable;
10393         cstring msg;
10394         int nval;
10395
10396         tval = valueTable_lookup (rvalues, fkey);
10397         
10398         DPRINTF (("Merge value: %s / %s X %s", fkey, 
10399                   stateValue_unparse (fval), stateValue_unparse (tval)));
10400
10401         minfo = context_lookupMetaStateInfo (fkey);
10402         llassert (stateValue_isDefined (tval));
10403         
10404         if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval)) 
10405           {
10406             DPRINTF (("Cannot find meta state for: %s", fkey));
10407             BADBRANCH;
10408           }
10409         else
10410           {
10411             llassert (metaStateInfo_isDefined (minfo));
10412
10413             if (stateValue_isError (fval)
10414                 || sRef_definitelyNullContext (res->sref))
10415               {
10416                 sRef_setMetaStateValueComplete (res->sref, 
10417                                                 fkey, stateValue_getValue (fval), 
10418                                                 stateValue_getLoc (fval));
10419                 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10420               }
10421             else if (stateValue_isError (tval)
10422                      || sRef_definitelyNullAltContext (other->sref))
10423               {
10424                 DPRINTF (("Other branch is definitely null!"));
10425               }
10426             else if (sRef_isStateUndefined (res->sref)
10427                      || sRef_isDead (res->sref))
10428               {
10429                 ; /* Combination state doesn't matter if it is undefined or dead */
10430               }
10431             else 
10432               {
10433                 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10434                           metaStateInfo_unparse (minfo),
10435                           stateValue_unparse (fval),
10436                           stateValue_unparse (tval)));
10437                 
10438                 DPRINTF (("state values: %d / %d",
10439                           stateValue_getValue (fval), stateValue_getValue (tval)));
10440                 
10441                 sctable = metaStateInfo_getMergeTable (minfo);
10442
10443                 DPRINTF (("Merge table: %s",
10444                           stateCombinationTable_unparse (sctable)));
10445                 
10446                 msg = cstring_undefined;
10447                 
10448                 nval = stateCombinationTable_lookup (sctable, 
10449                                                      stateValue_getValue (fval), 
10450                                                      stateValue_getValue (tval), 
10451                                                      &msg);
10452
10453                 DPRINTF (("nval: %d / %d / %d", nval,
10454                           stateValue_getValue (fval), stateValue_getValue (tval)));
10455
10456                 if (nval == stateValue_error)
10457                   {
10458                     if (uentry_isGlobalMarker (res))
10459                       {
10460                         if (optgenerror 
10461                             (FLG_STATEMERGE,
10462                              message
10463                              ("Control branches merge with incompatible global states (%s and %s)%q",
10464                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10465                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10466                               cstring_isDefined (msg) 
10467                               ? message (": %s", msg) : cstring_undefined),
10468                              loc))
10469                           {
10470                             sRef_showMetaStateInfo (res->sref, fkey);
10471                             sRef_showMetaStateInfo (other->sref, fkey);
10472                           }
10473                       }
10474                     else
10475                       {
10476                         if (optgenerror 
10477                             (FLG_STATEMERGE,
10478                              message
10479                              ("Control branches merge with incompatible states for %q (%s and %s)%q",
10480                               uentry_getName (res),
10481                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10482                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10483                               cstring_isDefined (msg) 
10484                               ? message (": %s", msg) : cstring_undefined),
10485                              loc))
10486                           {
10487                             sRef_showMetaStateInfo (res->sref, fkey);
10488                             sRef_showMetaStateInfo (other->sref, fkey);
10489                             DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10490                             DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10491                             DPRINTF (("Null: %s / %s",
10492                                       bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10493                                       bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10494
10495                           }
10496                       }
10497                   }
10498
10499                 if (nval == stateValue_getValue (fval)
10500                     && nval != stateValue_getValue (tval))
10501                   {
10502                     loc = stateValue_getLoc (fval);
10503                   }
10504                 else if (nval == stateValue_getValue (tval)
10505                          && nval != stateValue_getValue (fval))
10506                   {
10507                     loc = stateValue_getLoc (tval);
10508                   }
10509                 else
10510                   {
10511                     ;
10512                   }
10513
10514                 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10515                     && nval == stateValue_getValue (fval)
10516                     && nval == stateValue_getValue (tval))
10517                   {
10518                     ;
10519                   }
10520                 else
10521                   {
10522                     sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10523                   }
10524               }
10525           }
10526       } end_valueTable_elements ;
10527     } 
10528 }
10529
10530
10531 static void
10532 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10533                        /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10534                        bool flip, clause cl)
10535 {
10536   if (cl == DOWHILECLAUSE)
10537     {
10538       res->used = other->used || res->used;
10539       res->lset = other->lset || res->lset;
10540       res->uses = filelocList_append (res->uses, other->uses);
10541       other->uses = filelocList_undefined;
10542     }
10543   else
10544     {
10545       if (sRef_isMacroParamRef (res->sref)
10546           && !uentry_isSefParam (other)
10547           && !uentry_isSefParam (res))
10548         {
10549           bool hasError = FALSE;
10550           
10551           if (bool_equal (res->used, other->used))
10552             {
10553               res->used = other->used;
10554             }
10555           else
10556             {
10557               if (other->used && !flip)
10558                 {
10559                   hasError = 
10560                     optgenerror 
10561                     (FLG_MACROPARAMS,
10562                      message ("Macro parameter %q used in true clause, "
10563                               "but not in false clause",
10564                               uentry_getName (res)),
10565                      uentry_whereDeclared (res));
10566                 }
10567               else
10568                 {       
10569                   hasError = 
10570                     optgenerror 
10571                     (FLG_MACROPARAMS,
10572                      message ("Macro parameter %q used in false clause, "
10573                               "but not in true clause",
10574                               uentry_getName (res)),
10575                      uentry_whereDeclared (res));
10576                 }
10577               res->used = TRUE;
10578               
10579               if (hasError)
10580                 {
10581                   /* make it sef now, prevent more errors */
10582                   res->info->var->kind = VKREFSEFPARAM;
10583                 }
10584             }
10585         }
10586       else
10587         {
10588           res->used = other->used || res->used;
10589           res->lset = other->lset || res->lset;
10590           res->uses = filelocList_append (res->uses, other->uses);
10591           other->uses = filelocList_undefined;
10592         }
10593     }
10594 }
10595
10596 void
10597 uentry_mergeState (uentry res, uentry other, fileloc loc,
10598                    bool mustReturn, bool flip, bool opt,
10599                    clause cl)
10600 {
10601   llassert (uentry_isValid (res));
10602   llassert (uentry_isValid (other));
10603
10604   llassert (res->ukind == other->ukind);
10605   llassert (res->ukind == KVAR);
10606
10607   DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10608             uentry_unparseFull (other)));
10609   
10610   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10611   uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10612   uentry_mergeSetStates (res, other, loc, flip, cl);
10613
10614   DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10615 }
10616
10617 void uentry_setUsed (uentry e, fileloc loc)
10618 {
10619   static bool firstTime = TRUE;
10620   static bool showUses = FALSE;
10621   static bool exportLocal = FALSE;
10622
10623   DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10624
10625   if (firstTime)
10626     {
10627       /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10628
10629       showUses = context_getFlag (FLG_SHOWUSES); 
10630       exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10631
10632       firstTime = FALSE;
10633     }
10634
10635   if (uentry_isValid (e))
10636     {
10637       if (warnClause_isDefined (e->warn))
10638         {
10639           flagSpec flg = warnClause_getFlag (e->warn);
10640           cstring msg;
10641
10642           if (warnClause_hasMessage (e->warn))
10643             {
10644               msg = cstring_copy (warnClause_getMessage (e->warn));
10645             }
10646           else
10647             {
10648               msg = message ("Use of possibly dangerous %s",
10649                              uentry_ekindNameLC (e));
10650             }
10651
10652           vfsgenerror (flg, 
10653                        message ("%q: %q", msg, uentry_getName (e)),
10654                        loc);
10655         }
10656
10657       if (sRef_isMacroParamRef (e->sref))
10658         {
10659           if (uentry_isYield (e) || uentry_isSefParam (e))
10660             {
10661               ;
10662             }
10663           else 
10664             {
10665               if (context_inConditional ())
10666                 {
10667                   if (optgenerror
10668                       (FLG_MACROPARAMS,
10669                        message ("Macro parameter %q used in conditionally "
10670                                 "executed code (may or may not be "
10671                                 "evaluated exactly once)", 
10672                                 uentry_getName (e)),
10673                        loc))
10674                     {
10675                       e->info->var->kind = VKREFSEFPARAM;
10676                     }
10677                 }
10678               else
10679                 {
10680                   if ((e)->used)
10681                     {
10682                       if (optgenerror
10683                           (FLG_MACROPARAMS,
10684                            message ("Macro parameter %q used more than once", 
10685                                     uentry_getName (e)),
10686                            uentry_whereDeclared (e)))
10687                         {
10688                           e->info->var->kind = VKREFSEFPARAM;
10689                         }
10690                     }
10691                 }
10692             }
10693         }
10694       
10695       if (usymId_isValid (usymtab_directParamNo (e)))
10696         {
10697           uentry_setUsed (usymtab_getParam (usymId_toInt (usymtab_directParamNo (e))), loc);
10698         }
10699       
10700       e->used = TRUE;
10701
10702       if (!sRef_isLocalVar (e->sref))
10703         {
10704           if (showUses)
10705             {
10706               e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10707             }
10708           else 
10709             {
10710               if (exportLocal)
10711                 {
10712                   if (context_inMacro ())
10713                     {
10714                       e->uses = filelocList_addUndefined (e->uses);
10715                     }
10716                   else 
10717                     {
10718                       e->uses = filelocList_addDifferentFile
10719                         (e->uses, 
10720                          uentry_whereDeclared (e),
10721                          loc);
10722                     }
10723                 }
10724             }
10725         }
10726     }
10727 }
10728
10729 bool uentry_isReturned (uentry u)
10730 {
10731   return (uentry_isValid (u) && uentry_isVar (u) 
10732           && (u->info->var->kind == VKRETPARAM
10733               || u->info->var->kind == VKSEFRETPARAM));
10734 }
10735
10736 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
10737 {
10738   llassert (uentry_isRealFunction (u));
10739
10740   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10741     {
10742       stateClauseList clauses = uentry_getStateClauseList (u);
10743       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10744
10745       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10746       sRef_setAllocated (res, loc);
10747
10748       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10749                 stateClauseList_unparse (clauses)));
10750
10751       /*
10752       ** This should be in exprNode_reflectEnsuresClause
10753       */
10754
10755       stateClauseList_postElements (clauses, cl)
10756         {
10757           if (!stateClause_isGlobal (cl))
10758             {
10759               sRefSet refs = stateClause_getRefs (cl);
10760               sRefMod modf = stateClause_getEffectFunction (cl);
10761               
10762               sRefSet_elements (refs, el)
10763                 {
10764                   sRef base = sRef_getRootBase (el);
10765                   
10766                   if (sRef_isResult (base))
10767                     {
10768                       if (modf != NULL)
10769                         {
10770                           sRef sr = sRef_fixBase (el, res);
10771                           modf (sr, loc);
10772                         }
10773                     }
10774                   else
10775                     {
10776                       ;
10777                     }
10778                 } end_sRefSet_elements ;
10779             }
10780         } end_stateClauseList_postElements ;
10781         
10782       return res;
10783     }
10784   else
10785     {
10786       uentryList params;
10787       alkind ak;
10788       sRefSet prefs = sRefSet_new ();
10789       sRef res = sRef_undefined;
10790       int paramno = 0;
10791       
10792       params = uentry_getParams (u);
10793       
10794       uentryList_elements (params, current)
10795         {
10796           if (uentry_isReturned (current))
10797             {
10798               if (exprNodeList_size (args) >= paramno)
10799                 {
10800                   exprNode ecur = exprNodeList_nth (args, paramno);
10801                   sRef tref = exprNode_getSref (ecur);
10802                   
10803                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10804
10805                   if (sRef_isValid (tref))
10806                     {
10807                       sRef tcref = sRef_copy (tref);
10808                       
10809                       usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10810
10811                       if (sRef_isNew (tcref))
10812                         {
10813                           /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
10814                         }
10815
10816                       if (sRef_isDead (tcref))
10817                         {
10818                           sRef_setDefined (tcref, loc);
10819                           sRef_setOnly (tcref, loc);
10820                         }
10821                       
10822                       if (sRef_isRefCounted (tcref))
10823                         {
10824                           /* could be a new ref now (but only if its returned) */
10825                           sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
10826                         }
10827                       
10828                       sRef_makeSafe (tcref);
10829                       DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
10830                       prefs = sRefSet_insert (prefs, tcref);
10831                     }
10832                 }
10833             }
10834           
10835           paramno++;
10836         } end_uentryList_elements ;
10837       
10838       if (sRefSet_size (prefs) > 0)
10839         {
10840           nstate n = sRef_getNullState (u->sref);
10841           
10842           if (sRefSet_size (prefs) == 1)
10843             {
10844               res = sRefSet_choose (prefs);
10845             }
10846           else
10847             {
10848               /* should this ever happen? */
10849               res = sRefSet_mergeIntoOne (prefs);
10850             }
10851           
10852           if (nstate_isKnown (n))
10853             {
10854               sRef_setNullState (res, n, loc);
10855             }
10856         }
10857       else
10858         {
10859           if (ctype_isFunction (u->utype))
10860             {
10861               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10862               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10863             }
10864           else
10865             {
10866               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10867             }
10868           
10869           if (sRef_isRefCounted (res))
10870             {
10871               sRef_setAliasKind (res, AK_NEWREF, loc);
10872             }
10873         }
10874       
10875
10876       if (sRef_getNullState (res) == NS_ABSNULL)
10877         {
10878           ctype ct = ctype_realType (u->utype);
10879           
10880           if (ctype_isAbstract (ct))
10881             {
10882               sRef_setNotNull (res, loc);
10883             }
10884           else
10885             {
10886               if (ctype_isUser (ct))
10887                 {
10888                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10889                 }
10890               else
10891                 {
10892                   sRef_setNotNull (res, loc);
10893                 }
10894             }
10895         }
10896       
10897       if (sRef_isRefCounted (res))
10898         {
10899           sRef_setAliasKind (res, AK_NEWREF, loc);
10900         }
10901       else if (sRef_isKillRef (res))
10902         {
10903           sRef_setAliasKind (res, AK_REFCOUNTED, loc);
10904         }
10905       else
10906         {
10907           ;
10908         }
10909       
10910       ak = sRef_getAliasKind (res);
10911       
10912       if (alkind_isImplicit (ak))
10913         {
10914           sRef_setAliasKind (res, 
10915                              alkind_fixImplicit (ak),
10916                              loc);
10917         }
10918       
10919       sRefSet_free (prefs);
10920
10921       /*
10922       if (sRef_isOnly (res))
10923         {
10924           sRef_setFresh (res, loc);
10925         }
10926       */
10927
10928       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10929       return res;
10930     }
10931 }
10932
10933 static bool uentry_isRefCounted (uentry ue)
10934 {
10935   ctype ct = uentry_getType (ue);
10936
10937   if (ctype_isFunction (ct))
10938     {
10939       return (ctype_isRefCounted (ctype_getReturnType (ct)));
10940     }
10941   else
10942     {
10943       return (ctype_isRefCounted (ct));
10944     }
10945 }
10946
10947 /*
10948 ** old was declared yield in the specification.  
10949 ** new is declared in the iter implementation.
10950 */
10951
10952 void uentry_checkYieldParam (uentry old, uentry unew)
10953 {
10954   cstring name;
10955
10956   llassert (uentry_isVariable (old));
10957   llassert (uentry_isVariable (unew));
10958
10959   unew->info->var->kind = VKYIELDPARAM;
10960   (void) checkTypeConformance (old, unew, TRUE);
10961   checkVarConformance (old, unew, TRUE, FALSE);
10962
10963   /* get rid of param marker */
10964
10965   name = uentry_getName (unew);
10966   cstring_free (unew->uname);
10967   unew->uname = name;
10968   unew->info->var->kind = VKREFYIELDPARAM;
10969
10970   uentry_setUsed (old, fileloc_undefined);
10971   uentry_setUsed (unew, fileloc_undefined);
10972 }
10973
10974 /*@observer@*/ cstring
10975 uentry_ekindName (uentry ue)
10976 {
10977   if (uentry_isValid (ue))
10978     {
10979       switch (ue->ukind)
10980         {
10981         case KINVALID:
10982           return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10983         case KDATATYPE: 
10984           return cstring_makeLiteralTemp ("Datatype");
10985         case KENUMCONST:
10986           return cstring_makeLiteralTemp ("Enum member");
10987         case KCONST:  
10988           return cstring_makeLiteralTemp ("Constant");
10989         case KVAR:      
10990           if (uentry_isParam (ue))
10991             {
10992               return cstring_makeLiteralTemp ("Parameter");
10993             }
10994           else if (uentry_isExpandedMacro (ue))
10995             {
10996               return cstring_makeLiteralTemp ("Expanded macro");
10997             }
10998           else
10999             {
11000               return cstring_makeLiteralTemp ("Variable");
11001             }
11002         case KFCN:   
11003           return cstring_makeLiteralTemp ("Function");
11004         case KITER: 
11005           return cstring_makeLiteralTemp ("Iterator");
11006         case KENDITER:
11007           return cstring_makeLiteralTemp ("Iterator finalizer");
11008         case KSTRUCTTAG:
11009           return cstring_makeLiteralTemp ("Struct tag");
11010         case KUNIONTAG:
11011           return cstring_makeLiteralTemp ("Union tag");
11012         case KENUMTAG: 
11013           return cstring_makeLiteralTemp ("Enum tag");
11014         case KELIPSMARKER: 
11015           return cstring_makeLiteralTemp ("Optional parameters");
11016         }
11017     }
11018   else
11019     {
11020       return cstring_makeLiteralTemp ("<Undefined>");
11021     }
11022
11023   BADEXIT;
11024 }
11025
11026 /*@observer@*/ cstring
11027 uentry_ekindNameLC (uentry ue)
11028 {
11029   if (uentry_isValid (ue))
11030     {
11031       switch (ue->ukind)
11032         {
11033         case KINVALID:
11034           return cstring_makeLiteralTemp ("<error: invalid uentry>");
11035         case KDATATYPE: 
11036           return cstring_makeLiteralTemp ("datatype");
11037         case KENUMCONST:
11038           return cstring_makeLiteralTemp ("enum member");
11039         case KCONST:  
11040           return cstring_makeLiteralTemp ("constant");
11041         case KVAR:      
11042           if (uentry_isParam (ue))
11043             {
11044               return cstring_makeLiteralTemp ("parameter");
11045             }
11046           else if (uentry_isExpandedMacro (ue))
11047             {
11048               return cstring_makeLiteralTemp ("expanded macro");
11049             }
11050           else
11051             {
11052               return cstring_makeLiteralTemp ("variable");
11053             }
11054         case KFCN:   
11055           return cstring_makeLiteralTemp ("function");
11056         case KITER: 
11057           return cstring_makeLiteralTemp ("iterator");
11058         case KENDITER:
11059           return cstring_makeLiteralTemp ("iterator finalizer");
11060         case KSTRUCTTAG:
11061           return cstring_makeLiteralTemp ("struct tag");
11062         case KUNIONTAG:
11063           return cstring_makeLiteralTemp ("union tag");
11064         case KENUMTAG: 
11065           return cstring_makeLiteralTemp ("enum tag");
11066         case KELIPSMARKER: 
11067           return cstring_makeLiteralTemp ("optional parameters");
11068         }
11069     }
11070   else
11071     {
11072       return cstring_makeLiteralTemp ("<Undefined>");
11073     }
11074
11075   BADEXIT;
11076 }
11077
11078 void uentry_setHasNameError (uentry ue)
11079 {
11080   llassert (uentry_isValid (ue));
11081
11082   ue->hasNameError = TRUE;
11083 }
11084
11085 void uentry_checkName (uentry ue)
11086 {
11087   DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11088             uentry_observeRealName (ue),
11089             bool_unparse (uentry_isVisibleExternally (ue))));
11090   
11091   if (uentry_isValid (ue) 
11092       && !context_inXHFile ()
11093       && uentry_hasName (ue)
11094       && !uentry_isElipsisMarker (ue)
11095       && context_getFlag (FLG_NAMECHECKS)
11096       && !ue->hasNameError 
11097       && !uentry_isEndIter (ue)
11098       && !fileloc_isBuiltin (uentry_whereLast (ue))
11099       && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11100     {      
11101       DPRINTF (("Here..."));
11102
11103       if (uentry_isPriv (ue))
11104         {
11105           ; /* any checks here? */
11106         }
11107       else if (fileloc_isExternal (uentry_whereDefined (ue)))
11108         {
11109           ; /* no errors for externals */
11110         }
11111       else
11112         {
11113           int scope;
11114           
11115           if (uentry_isExpandedMacro (ue))
11116             {
11117               scope = globScope;
11118             }
11119           else
11120             {
11121               if (uentry_isExpandedMacro (ue))
11122                 {
11123                   scope = fileScope;
11124                 }
11125               else if (uentry_isVariable (ue))
11126                 {
11127                   sRef sr = uentry_getSref (ue);
11128
11129                   if (sRef_isValid (sr))
11130                     {
11131                       scope = sRef_getScope (sr);
11132                     }
11133                   else
11134                     {
11135                       scope = fileScope; 
11136                     }
11137                 }
11138               else if (uentry_isFunction (ue)
11139                        || uentry_isIter (ue)
11140                        || uentry_isEndIter (ue)
11141                        || uentry_isConstant (ue))
11142                 {
11143                   scope = uentry_isStatic (ue) ? fileScope : globScope;
11144                 }
11145               else /* datatypes, etc. must be global */
11146                 {
11147                   scope = globScope;
11148                 }
11149               
11150               usymtab_checkDistinctName (ue, scope);
11151             }
11152         
11153           if (context_getFlag (FLG_CPPNAMES)) 
11154             {
11155               checkCppName (ue);
11156             }
11157
11158           if (scope == globScope)
11159             {
11160               checkExternalName (ue);
11161             }
11162           else if (scope == fileScope)
11163             {
11164               checkFileScopeName (ue);
11165             }
11166           else 
11167             {
11168               checkLocalName (ue);
11169             }
11170
11171           checkPrefix (ue);
11172           checkAnsiName (ue);
11173         }
11174     }
11175 }
11176
11177 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11178 {
11179   uentry ue;
11180   fileloc tloc;
11181
11182   /*
11183   ** Can't but unrecognized ids in macros in global scope, because srefs will break! 
11184   */
11185
11186   if (!context_inMacro ())
11187     {
11188       sRef_setGlobalScopeSafe ();
11189     }
11190
11191   ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11192   uentry_setUsed (ue, loc);               
11193   
11194   tloc = fileloc_createExternal ();
11195   uentry_setDefined (ue, tloc);
11196   fileloc_free (tloc);
11197   uentry_setHasNameError (ue);
11198   
11199   if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldStyleScope()))
11200     {
11201       uentry_markOwned (ue);
11202     }
11203   else
11204     {
11205       ue = usymtab_supReturnFileEntry (ue);
11206     }
11207   
11208   if (!context_inMacro ())
11209     {
11210       sRef_clearGlobalScopeSafe ();
11211     }
11212
11213   return ue;
11214 }
11215
11216 uentry uentry_makeGlobalMarker ()
11217 {
11218   uentry ue;
11219   fileloc tloc;
11220
11221   llassert (sRef_inGlobalScope ());
11222   
11223   ue = uentry_makeVariableAux
11224     (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined, 
11225      sRef_makeGlobalMarker (),
11226      FALSE, VKNORMAL);
11227
11228   tloc = fileloc_createExternal ();
11229   uentry_setUsed (ue, tloc);              
11230   uentry_setDefined (ue, tloc);
11231   fileloc_free (tloc);
11232   uentry_setHasNameError (ue);  
11233
11234   return ue;
11235 }
11236
11237
11238 bool uentry_isGlobalMarker (uentry ue)
11239 {
11240   return (uentry_isValid (ue)
11241           && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11242 }
11243
11244 /* new start modifications */
11245
11246 /* start modifications */
11247 /*
11248 requires: p_e is defined, is a ptr/array variable 
11249 modifies: p_e
11250 effects: sets the state of the variable
11251 */
11252
11253
11254 void uentry_setPossiblyNullTerminatedState (uentry p_e)  
11255 {
11256   llassert (uentry_isValid (p_e));
11257
11258   if (p_e->info != NULL)
11259     {
11260       if (p_e->info->var != NULL) 
11261         {
11262           llassert (p_e->info->var->bufinfo != NULL);
11263           p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11264           sRef_setPossiblyNullTerminatedState (p_e->sref);
11265         }
11266     }
11267 }
11268
11269 /*
11270 requires: p_e is defined, is a ptr/array variable 
11271 modifies: p_e
11272 effects: sets the size of the buffer
11273 */
11274
11275 void uentry_setNullTerminatedState (uentry p_e)  {
11276   llassert (uentry_isValid (p_e));
11277
11278   if (p_e->info != NULL)
11279     {
11280       if (p_e->info->var != NULL)
11281         {
11282           llassert (p_e->info->var->bufinfo != NULL);
11283           p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11284           sRef_setNullTerminatedState (p_e->sref);
11285         }
11286     }
11287 }
11288
11289 /*
11290 requires: p_e is defined, is a ptr/array variable 
11291 modifies: p_e
11292 effects: sets the size of the buffer
11293 */
11294
11295 void uentry_setSize (uentry p_e, int size)  
11296 {
11297   if (uentry_isValid (p_e))
11298     {
11299       if (p_e->info != NULL) 
11300         {
11301           if (p_e->info->var != NULL) 
11302             {
11303               llassert (p_e->info->var->bufinfo != NULL);
11304               p_e->info->var->bufinfo->size = size;
11305               sRef_setSize (p_e->sref, size);
11306             }
11307         }
11308     }
11309 }
11310
11311 /*
11312 requires: p_e is defined, is a ptr/array variable 
11313 modifies: p_e
11314 effects: sets the length of the buffer
11315 */
11316
11317 void uentry_setLen (uentry p_e, int len)  
11318 {
11319   if (uentry_isValid (p_e)) 
11320     {
11321       if (p_e->info != NULL
11322           && p_e->info->var != NULL) 
11323         {
11324           llassert (p_e->info->var->bufinfo != NULL);
11325           p_e->info->var->bufinfo->len = len;
11326           sRef_setLen (p_e->sref, len);
11327         }
11328     }
11329 }
11330
11331 /*@=type*/
11332
11333 bool uentry_hasMetaStateEnsures (uentry e)
11334 {
11335   if (uentry_isValid (e) && uentry_isFunction (e))
11336     {
11337       return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11338     }
11339   else
11340     {
11341       return FALSE;
11342     }
11343 }
11344
11345 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11346 {
11347   llassert (uentry_isValid (e) && uentry_isFunction (e));
11348   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11349 }
11350
11351
11352 bool uentry_hasBufStateInfo (uentry ue)
11353 {
11354   llassert (uentry_isValid (ue));
11355   return (ue->info->var->bufinfo != NULL);
11356 }
11357
11358 bool uentry_isNullTerminated (uentry ue)
11359 {
11360   llassert (uentry_hasBufStateInfo (ue));
11361   llassert (ue->info->var->bufinfo != NULL);
11362   return ue->info->var->bufinfo->bufstate == BB_NULLTERMINATED;
11363 }
11364
11365 bool uentry_isPossiblyNullTerminated (uentry ue)
11366 {
11367   llassert (uentry_hasBufStateInfo (ue));
11368   llassert (ue->info->var->bufinfo != NULL);
11369   return (ue->info->var->bufinfo->bufstate == BB_POSSIBLYNULLTERMINATED);
11370 }
11371
11372 bool uentry_isNotNullTerminated (uentry ue)
11373 {
11374   llassert (uentry_hasBufStateInfo (ue));
11375   llassert (ue->info->var->bufinfo != NULL);
11376   return (ue->info->var->bufinfo->bufstate == BB_NOTNULLTERMINATED);
11377 }
11378
11379 # ifdef DEBUGSPLINT
11380
11381 /*
11382 ** For debugging only
11383 */
11384
11385 void uentry_checkValid (uentry ue)
11386 {
11387   if (uentry_isValid (ue))
11388     {
11389       sRef_checkCompletelyReasonable (ue->sref);
11390     }
11391 }
11392
11393 # endif
This page took 0.961331 seconds and 5 git commands to generate.