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