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