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