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