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