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