]> andersk Git - splint.git/blob - src/uentry.c
Fixed overly agressive assertions (from checking splint *.c in test/)
[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   if (!uentry_isDatatype (e))
6446     {
6447       /* This shouldn't happen, except when types are redeclared in strange ways */
6448       return ctype_unknown;
6449     }
6450
6451   if (uentry_isAnyTag (e))
6452     {
6453       return (e->utype);
6454     }
6455   
6456   if (uentry_isAbstractType (e))
6457     {
6458       ct = uentry_getAbstractType (e);      
6459
6460       if (ctype_isManifestBool (ct)) {
6461         return ct;
6462       }
6463
6464       llassert (ctype_isUA (ct));
6465       
6466       uid = ctype_typeId (ct);
6467       
6468       if (!context_hasAccess (uid))
6469         {
6470           return (ct);
6471         }
6472     }
6473
6474   ct = uentry_getType (e);
6475
6476   /* if (ctype_isUserBool (ct)) return ct; */
6477
6478   if (ctype_isManifestBool (ct)) {
6479     return ctype_bool;
6480   }
6481   
6482   if (ctype_isUA (ct))
6483     {
6484       typeId iid = ctype_typeId (ct);
6485       
6486       if (typeId_equal (iid, uid))
6487         {         
6488           llcontbug (message ("uentry_getRealType: recursive type! %s",
6489                               ctype_unparse (ct)));
6490           return ct;
6491         }
6492       else
6493         {
6494           /* evs 2000-07-25: possible infinite recursion ? */
6495           uentry ue2 = usymtab_getTypeEntry (iid);
6496
6497           if (ue2 == e)
6498             {
6499               llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6500               return ctype_unknown;
6501             }
6502
6503           return uentry_getRealType (ue2);
6504         }
6505     }
6506   else
6507     {
6508       return ct;
6509     }
6510 }
6511
6512 ctype uentry_getForceRealType (uentry e)
6513 {
6514   ctype   ct;
6515   typeId uid = typeId_invalid;
6516
6517   if (uentry_isInvalid (e))
6518     {
6519       return ctype_unknown;
6520     }
6521
6522   llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6523   
6524   if (uentry_isAnyTag (e))
6525     {
6526       return (e->utype);
6527     }
6528   
6529   if (uentry_isAbstractType (e))
6530     {
6531       ct = uentry_getAbstractType (e);      
6532       llassert (ctype_isUA (ct));
6533       
6534       uid = ctype_typeId (ct);
6535       /* no check for access! */
6536     }
6537   
6538   ct = uentry_getType (e);
6539
6540   /* evs 2000-07-25 */
6541   /* if (ctype_isUserBool (ct)) return ct; */
6542
6543   if (ctype_isManifestBool (ct)) {
6544     return ctype_bool;
6545   }
6546   
6547   if (ctype_isUA (ct))
6548     {
6549       typeId iid = ctype_typeId (ct);
6550       
6551       if (typeId_equal (iid, uid))
6552         {         
6553           llcontbug (message ("uentry_getRealType: recursive type! %s",
6554                               ctype_unparse (ct)));
6555           return ct;
6556         }
6557       else
6558         {
6559           return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6560         }
6561     }
6562   else
6563     {
6564       return ct;
6565     }
6566 }
6567
6568 uentry uentry_nameCopy (cstring name, uentry e)
6569 {
6570   uentry enew = uentry_alloc ();
6571
6572   llassert (uentry_isValid (e));
6573
6574   /* enew->shallowCopy = FALSE; */
6575   enew->ukind = e->ukind;
6576   enew->uname = name;
6577   enew->utype = e->utype;
6578   enew->whereSpecified = fileloc_copy (e->whereSpecified);
6579   enew->whereDefined = fileloc_copy (e->whereDefined);
6580   enew->whereDeclared = fileloc_copy (e->whereDeclared);
6581   enew->sref = sRef_copy (e->sref); 
6582   enew->used = e->used;
6583   enew->lset = FALSE;
6584   enew->isPrivate = e->isPrivate;
6585   enew->hasNameError = FALSE;
6586
6587   enew->uses = filelocList_new ();
6588   enew->warn = warnClause_undefined; 
6589
6590   enew->storageclass = e->storageclass;
6591   enew->info = uinfo_copy (e->info, e->ukind);
6592
6593   return enew;
6594 }
6595
6596 void
6597 uentry_setDatatype (uentry e, typeId uid)
6598 {
6599   llassert (uentry_isDatatype (e));
6600
6601   if (uentry_isAbstractType (e))
6602     {
6603       if (qual_isNumAbstract (e->info->datatype->abs)) 
6604         {
6605           e->info->datatype->type = ctype_createNumAbstract (uid);
6606         }
6607       else
6608         {
6609           llassert (qual_isAbstract (e->info->datatype->abs));
6610           e->info->datatype->type = ctype_createAbstract (uid);
6611         }
6612     }
6613   else
6614     {
6615       e->info->datatype->type = ctype_createUser (uid);
6616     }
6617 }
6618
6619 static void 
6620 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6621    /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6622    /*@modifies e@*/
6623 {
6624   llassert (uentry_isValid (e));
6625
6626   if (fileloc_isSpec (f) || fileloc_isImport (f))
6627     {
6628       e->whereSpecified = f;
6629       e->whereDeclared  = fileloc_undefined;
6630       e->whereDefined  = fileloc_undefined;
6631     }
6632   else
6633     {
6634       e->whereSpecified = fileloc_undefined;
6635       e->whereDeclared  = f;
6636       e->whereDefined  = fileloc_undefined;
6637     }
6638
6639   llassert (fileloc_storable (f));
6640 }
6641
6642 static void
6643 ucinfo_free (/*@only@*/ ucinfo u)
6644 {
6645   sfree (u);
6646 }
6647
6648 static void
6649 uvinfo_free (/*@only@*/ uvinfo u)
6650 {
6651   /*drl7x added 6/29/01 */
6652   free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6653   sfree (u);
6654 }
6655
6656 static void
6657 udinfo_free (/*@only@*/ udinfo u)
6658 {
6659   sfree (u);
6660 }
6661
6662 static void
6663 ufinfo_free (/*@only@*/ ufinfo u)
6664 {
6665   globSet_free (u->globs);
6666   sRefSet_free (u->mods);
6667   stateClauseList_free (u->specclauses);
6668   sfree (u);
6669 }
6670
6671 static void
6672 uiinfo_free (/*@only@*/ uiinfo u)
6673 {
6674   sfree (u);
6675 }
6676
6677 static void
6678 ueinfo_free (/*@only@*/ ueinfo u)
6679 {
6680   sfree (u);
6681 }
6682
6683 static /*@only@*/ ucinfo
6684 ucinfo_copy (ucinfo u)
6685 {
6686   ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6687   ret->access = u->access;
6688   ret->macro = u->macro;
6689   return ret;
6690 }
6691
6692 static /*@only@*/ uvinfo
6693 uvinfo_copy (uvinfo u)
6694 {
6695   uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6696   
6697   ret->kind = u->kind;
6698   ret->nullstate = u->nullstate;
6699   ret->defstate = u->defstate;
6700   ret->checked = u->checked;
6701
6702
6703   /* drl added 07-02-001 */
6704   /* copy null terminated information */
6705
6706   if (u->bufinfo != NULL)
6707     {
6708       ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6709       ret->bufinfo->bufstate = u->bufinfo->bufstate;
6710       ret->bufinfo->size     = u->bufinfo->size;
6711       ret->bufinfo->len      = u->bufinfo->len;
6712       return ret;
6713     }
6714   else
6715     {
6716       ret->bufinfo = NULL;
6717       return ret;
6718     }
6719     
6720 }
6721
6722 static /*@only@*/ udinfo
6723 udinfo_copy (udinfo u)
6724 {
6725   udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6726
6727   ret->abs = u->abs;
6728   ret->mut = u->mut;
6729   ret->type = u->type;
6730
6731   return ret;
6732 }
6733
6734 static /*@only@*/ ufinfo
6735 ufinfo_copy (ufinfo u)
6736 {
6737   ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6738
6739   ret->hasGlobs = u->hasGlobs;
6740   ret->hasMods = u->hasMods;
6741   ret->exitCode = u->exitCode;
6742   ret->specialCode = u->specialCode;
6743   ret->nullPred = u->nullPred;
6744   ret->access = u->access;
6745   ret->globs = globSet_newCopy (u->globs);
6746   ret->mods = sRefSet_newCopy (u->mods);
6747   ret->defparams = u->defparams;
6748   ret->specclauses = stateClauseList_copy (u->specclauses);
6749
6750   ret->preconditions = functionConstraint_copy (u->preconditions);
6751   ret->postconditions = functionConstraint_copy (u->postconditions);
6752   
6753   return ret;
6754 }
6755
6756 static /*@only@*/ uiinfo
6757 uiinfo_copy (uiinfo u)
6758 {
6759   uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6760
6761   ret->access = u->access;
6762   ret->globs = globSet_newCopy (u->globs);
6763   ret->mods = sRefSet_newCopy (u->mods);
6764
6765   return (ret);
6766 }
6767
6768 static /*@only@*/ ueinfo
6769 ueinfo_copy (ueinfo u)
6770 {
6771   ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6772
6773   ret->access = u->access;
6774   return ret;
6775 }
6776
6777 static void
6778 uinfo_free (uinfo u, ekind kind)
6779 {
6780   switch (kind)
6781     {
6782     case KENUMCONST:
6783     case KCONST:       ucinfo_free (u->uconst); break;
6784     case KVAR:         uvinfo_free (u->var); break;
6785     case KSTRUCTTAG:
6786     case KUNIONTAG:
6787     case KENUMTAG:
6788     case KDATATYPE:    udinfo_free (u->datatype); break;
6789     case KFCN:         ufinfo_free (u->fcn); break;
6790     case KITER:        uiinfo_free (u->iter); break;
6791     case KENDITER:     ueinfo_free (u->enditer); break;
6792     case KELIPSMARKER: break;
6793     case KINVALID:     break;
6794     }
6795   
6796     sfree (u);
6797 }
6798
6799 static /*@only@*/ /*@null@*/ uinfo
6800 uinfo_copy (uinfo u, ekind kind)
6801 {
6802   if (kind == KELIPSMARKER || kind == KINVALID)
6803     {
6804       return NULL;
6805     }
6806   else
6807     {
6808       uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6809       
6810       switch (kind)
6811         {
6812         case KENUMCONST:
6813         case KCONST:    ret->uconst = ucinfo_copy (u->uconst); break;
6814         case KVAR:      ret->var = uvinfo_copy (u->var); break;
6815         case KSTRUCTTAG:
6816         case KUNIONTAG:
6817         case KENUMTAG:
6818         case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6819         case KFCN:      ret->fcn = ufinfo_copy (u->fcn); break;
6820         case KITER:     ret->iter = uiinfo_copy (u->iter); break;
6821         case KENDITER:  ret->enditer = ueinfo_copy (u->enditer); break;
6822         BADDEFAULT;
6823         }
6824       return ret;
6825     }
6826 }
6827
6828 static void
6829 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6830 {
6831   filelocList_free (e->uses);
6832   cstring_free (e->uname);
6833   
6834   uinfo_free (e->info, e->ukind);
6835   
6836   fileloc_free (e->whereSpecified); 
6837   fileloc_free (e->whereDefined); 
6838   fileloc_free (e->whereDeclared); 
6839
6840   warnClause_free (e->warn);
6841
6842   nuentries--;
6843   sfree (e);
6844 }
6845
6846 extern void uentry_markOwned (/*@owned@*/ uentry u)
6847 {
6848   sfreeEventually (u);
6849 }
6850
6851 void
6852 uentry_free (/*@only@*/ uentry e)
6853 {
6854   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6855     {
6856       uentry_reallyFree (e);
6857     }
6858 }
6859
6860 /*
6861 ** For uentry's in the global or file scope
6862 */
6863
6864 void
6865 uentry_freeComplete (/*@only@*/ uentry e)
6866 {
6867   if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6868     {
6869       DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6870       /*@i@*/ sRef_free (e->sref);
6871       e->sref = sRef_undefined;
6872       uentry_reallyFree (e);
6873     }
6874 }
6875
6876 /*
6877 ** requires old->kind != new->kind, old->uname = new->uname
6878 */
6879
6880 static void
6881 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6882 {
6883   llassert (uentry_isValid (old));
6884   llassert (uentry_isValid (unew));
6885
6886   if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
6887       && (fileloc_isPreproc (uentry_whereDeclared (old))
6888           || ctype_isUnknown (old->utype))
6889       && !uentry_isSpecified (old))
6890     {
6891       ; /* no error */
6892     }
6893   else 
6894     {
6895       if (mustConform)
6896         {
6897           if (!uentry_isDeclared (old))
6898             {
6899               if (uentry_isSpecified (old))
6900                 {
6901                   if (uentry_isSpecified (unew))
6902                     {
6903                       llbuglit ("Respecification!");
6904                     }
6905                   else if (uentry_isDeclared (unew))
6906                     {
6907                       if (optgenerror
6908                           (FLG_INCONDEFS,
6909                            message ("%s %q inconsistently declared as %s: %t",
6910                                     ekind_capName (old->ukind),
6911                                     uentry_getName (unew),
6912                                     ekind_unparseLong (unew->ukind),
6913                                     unew->utype),
6914                            uentry_whereLast (unew)))  /* evans 2001-12-30: was uentry_whereDeclared */
6915                         {
6916                           uentry_showWhereLastKind (old);
6917                         }
6918                     }
6919                   else
6920                     {
6921                       BADEXIT;
6922                     }
6923                 }
6924               else
6925                 {
6926                   if (optgenerror
6927                       (FLG_INCONDEFS,
6928                        message ("%s %q inconsistently declared as %s: %t",
6929                                 ekind_capName (old->ukind),
6930                                 uentry_getName (unew),
6931                                 ekind_unparseLong (unew->ukind),
6932                                 unew->utype),
6933                        uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6934                     {
6935                       uentry_showWhereLastKind (old);
6936                     }
6937                 }
6938             }
6939           else
6940             {
6941               llassert (uentry_isDeclared (unew));
6942
6943               DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6944               DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6945
6946               if (optgenerror
6947                   (FLG_INCONDEFS,
6948                    message ("%s %q inconsistently redeclared as %s",
6949                             ekind_capName (old->ukind),
6950                             uentry_getName (unew),
6951                             ekind_unparseLong (unew->ukind)),
6952                    uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6953                 {
6954                   uentry_showWhereLastKind (old);
6955                 }
6956             }
6957         }
6958     }
6959
6960   uentry_updateInto (old, unew);
6961 }
6962
6963 /*
6964 ** def is the definition of spec, modifies spec
6965 **
6966 ** reports any inconsistencies
6967 ** returns the summary of all available information
6968 ** if spec and def are inconsistent, def is returned
6969 */
6970
6971 void
6972 uentry_showWhereLast (uentry spec)
6973 {
6974   if (uentry_isValid (spec))
6975     {
6976       if (fileloc_isDefined (spec->whereDefined)
6977           && !fileloc_isLib (spec->whereDefined)
6978           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6979         {
6980           llgenindentmsg (message ("Previous definition of %q: %t", 
6981                                    uentry_getName (spec),
6982                                    uentry_getType (spec)),
6983                           uentry_whereDefined (spec));
6984         }
6985       else if (uentry_isDeclared (spec))
6986         {
6987           llgenindentmsg (message ("Previous declaration of %q: %t", 
6988                                    uentry_getName (spec),
6989                                    uentry_getType (spec)),
6990                           uentry_whereDeclared (spec));
6991         }
6992       else if (uentry_isSpecified (spec))
6993         {
6994           if (uentry_hasName (spec))
6995             {
6996               llgenindentmsg (message ("Specification of %q: %t", 
6997                                        uentry_getName (spec),
6998                                        uentry_getType (spec)),
6999                               uentry_whereSpecified (spec));
7000             }
7001           else
7002             {
7003               llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
7004                               uentry_whereSpecified (spec));
7005             }
7006         }
7007       else
7008         {
7009           /* nothing to show */
7010         }
7011     }
7012 }
7013
7014 static void
7015 uentry_showWhereLastKind (uentry spec)
7016 {
7017   if (uentry_isValid (spec))
7018     {
7019       if (fileloc_isDefined (spec->whereDefined)
7020           && !fileloc_isLib (spec->whereDefined)
7021           /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
7022         {
7023           llgenindentmsg (message ("Previous definition of %q as %s: %t", 
7024                                    uentry_getName (spec),
7025                                    ekind_unparseLong (spec->ukind),
7026                                    uentry_getType (spec)),
7027                           uentry_whereDefined (spec));
7028         }
7029       else if (uentry_isDeclared (spec))
7030         {
7031           llgenindentmsg (message ("Previous declaration of %q as %s: %t", 
7032                                    uentry_getName (spec),
7033                                    ekind_unparseLong (spec->ukind),
7034                                    uentry_getType (spec)),
7035                           uentry_whereDeclared (spec));
7036         }
7037       else if (uentry_isSpecified (spec))
7038         {
7039           if (uentry_hasName (spec))
7040             {
7041               llgenindentmsg (message ("Specification of %q as %s: %t", 
7042                                        uentry_getName (spec),
7043                                        ekind_unparseLong (spec->ukind),
7044                                        uentry_getType (spec)),
7045                               uentry_whereSpecified (spec));
7046             }
7047           else
7048             {
7049               llgenindentmsg (message ("Specification as %s: %t",
7050                                        ekind_unparseLong (spec->ukind),
7051                                        uentry_getType (spec)),
7052                               uentry_whereSpecified (spec));
7053             }
7054         }
7055       else
7056         {
7057           /* nothing to show */
7058         }
7059     }
7060 }
7061
7062 void
7063 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7064 {
7065   fileloc loc = uentry_whereDefined (ce);
7066   
7067   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7068     {
7069       llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7070                       loc);
7071     }
7072
7073   loc = uentry_whereSpecified (ce);
7074   
7075   if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7076     {
7077       llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7078                       loc);
7079     }
7080 }
7081
7082 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7083 {
7084   if (uentry_isDeclared (spec))
7085     {
7086       llgenindentmsg (message ("Previous declaration of %q: %q", 
7087                                uentry_getName (spec), extra),
7088                       uentry_whereDeclared (spec));
7089     }
7090   else if (uentry_isSpecified (spec))
7091     {
7092       llgenindentmsg (message ("Specification of %q: %q", 
7093                                uentry_getName (spec), extra),
7094                       uentry_whereSpecified (spec));
7095     }
7096   else
7097     {
7098       cstring_free (extra);
7099     }
7100 }
7101
7102 void
7103 uentry_showWhereDeclared (uentry spec)
7104 {
7105   if (uentry_isDeclared (spec))
7106     {
7107       if (uentry_hasName (spec))
7108         {
7109           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7110                           uentry_whereDeclared (spec));
7111         }
7112       else
7113         {
7114           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7115         }
7116     }
7117   else if (uentry_isSpecified (spec))
7118     {
7119       if (uentry_hasName (spec))
7120         {
7121           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7122                           uentry_whereSpecified (spec));
7123         }
7124       else
7125         {
7126           llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7127         }
7128     }
7129   else
7130     {
7131       /* nothing to show */
7132     }
7133     
7134 }
7135
7136 void
7137 uentry_showWhereAny (uentry spec)
7138 {
7139   if (uentry_isDeclared (spec))
7140     {
7141       if (uentry_hasName (spec))
7142         {
7143           llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7144                           uentry_whereDeclared (spec));
7145         }
7146       else
7147         {
7148           llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7149         }
7150     }
7151   else if (uentry_isSpecified (spec))
7152     {
7153       if (uentry_hasName (spec))
7154         {
7155           llgenindentmsg (message ("Specification of %q",
7156                                    uentry_getName (spec)),
7157                           uentry_whereSpecified (spec));
7158         }
7159       else
7160         {
7161           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7162                           uentry_whereSpecified (spec));
7163         }
7164     }
7165   else if (fileloc_isDefined (uentry_whereDefined (spec))) 
7166     {
7167       if (uentry_hasName (spec))
7168         {
7169           llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7170                           uentry_whereDefined (spec));
7171         }
7172       else
7173         {
7174           llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7175         }
7176     }
7177   else
7178     {
7179       /* nothing to show */
7180     }
7181 }
7182
7183 void
7184 uentry_showWhereDefined (uentry spec)
7185 {
7186   if (uentry_isCodeDefined (spec))
7187     {
7188       llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7189                       uentry_whereDefined (spec));
7190     }
7191 }
7192
7193 void
7194 uentry_showWhereLastPlain (uentry spec)
7195 {
7196   if (uentry_isDeclared (spec))
7197     {
7198       llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7199                       uentry_whereDeclared (spec));
7200     }
7201   else if (uentry_isSpecified (spec))
7202     {
7203       llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7204                       uentry_whereSpecified (spec));
7205     }
7206   else
7207     {
7208           }
7209 }
7210
7211 static void
7212 uentry_showWhereLastVal (uentry spec, cstring val)
7213 {
7214   if (uentry_isDeclared (spec))
7215     {
7216       llgenindentmsg (message ("Previous declaration of %q: %s", 
7217                                uentry_getName (spec), val),
7218                       uentry_whereDeclared (spec));
7219     }
7220   else if (uentry_isSpecified (spec))
7221     {
7222       llgenindentmsg (message ("Specification of %q: %s", 
7223                                uentry_getName (spec), val),
7224                       uentry_whereSpecified (spec));
7225     }
7226   else
7227     {
7228     }
7229 }
7230
7231 void
7232 uentry_showWhereSpecified (uentry spec)
7233 {
7234   if (uentry_isSpecified (spec))
7235     {
7236       if (uentry_hasName (spec))
7237         {
7238           llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7239                           uentry_whereSpecified (spec));
7240         }
7241       else
7242         {
7243           llgenindentmsg (cstring_makeLiteral ("Specification"), 
7244                           uentry_whereSpecified (spec));
7245         }
7246     }
7247   else if (uentry_isDeclared (spec))
7248     {
7249       llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7250                       uentry_whereDeclared (spec));
7251     }
7252   else
7253     {
7254       /* nothing to show */
7255     }
7256 }
7257
7258 void
7259 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7260 {
7261   if (uentry_isSpecified (spec))
7262     {
7263       if (uentry_hasName (spec))
7264         {
7265           llgenindentmsg (message ("Specification of %q: %q", 
7266                                    uentry_getName (spec), s),
7267                           uentry_whereSpecified (spec));
7268         }
7269       else
7270         {
7271           llgenindentmsg (message ("Specification: %q", s), 
7272                           uentry_whereSpecified (spec));
7273         }
7274     }
7275   else if (uentry_isDeclared (spec))
7276     {
7277       llgenindentmsg (message ("Declaration of %q: %q", 
7278                                uentry_getName (spec), s),
7279                       uentry_whereDeclared (spec));
7280     }
7281   else
7282     {
7283       llgenindentmsg (message ("Previous: %q", s),
7284                       uentry_whereLast (spec));
7285     }
7286 }
7287
7288 /*
7289 **
7290 */
7291
7292 static void
7293 checkStructConformance (uentry old, uentry unew)
7294 {
7295   ctype oldr, newr; 
7296   uentryList fold, fnew;
7297
7298   /*
7299   ** requires: types of old and new are structs or unions
7300   */
7301
7302   llassert (uentry_isValid (old));
7303   llassert (uentry_isValid (unew));
7304
7305   oldr = ctype_realType (old->utype);
7306   fold =  ctype_getFields (oldr);
7307
7308   newr = ctype_realType (unew->utype);
7309   fnew = ctype_getFields (newr);
7310
7311   if (!uentryList_matchFields (fold, fnew))
7312     {
7313       if (fileloc_equal (uentry_whereLast (old),
7314                          uentry_whereLast (unew)))
7315         {
7316           ; /* cheat! */
7317         }
7318       else 
7319         {
7320           if (optgenerror 
7321               (FLG_MATCHFIELDS,
7322                message ("%q %q %rdeclared with fields { %q }, %s "
7323                         "with fields { %q }",
7324                         cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7325                         uentry_getName (old), 
7326                         uentry_isDeclared (old),
7327                         uentryList_unparseAbbrev (fnew),
7328                         uentry_specOrDefName (old),
7329                         uentryList_unparseAbbrev (fold)),
7330                uentry_whereDeclared (unew)))
7331             {
7332               uentry_showWhereLastPlain (old);
7333               uentryList_showFieldDifference (fold, fnew);
7334             }
7335         }
7336
7337       old->utype = unew->utype;
7338     }
7339 }
7340
7341 static void
7342 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7343 {
7344   /*
7345   ** requires old and new are enums
7346   */
7347   
7348   ctype        rold = ctype_realType (old->utype);
7349   ctype        rnew = ctype_realType (unew->utype);
7350   enumNameList eold = ctype_elist (rold);
7351   enumNameList enew = ctype_elist (rnew);
7352   
7353   if (!enumNameList_match (eold, enew))
7354     {
7355       if (optgenerror 
7356           (FLG_MATCHFIELDS,
7357            message ("Enum %q declared with members { %q } but "
7358                     "%s with members { %q }",
7359                     uentry_getName (old), 
7360                     enumNameList_unparse (enew),
7361                     uentry_specOrDefName (old),
7362                     enumNameList_unparse (eold)),
7363            uentry_whereDeclared (unew)))
7364         {
7365           uentry_showWhereSpecified (old);
7366           old->utype = unew->utype;
7367         }
7368     }
7369 }
7370
7371 /*
7372 ** either oldCurrent or newCurrent may be undefined!
7373 */
7374
7375 static void
7376 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7377                 uentry unew, uentry newCurrent, ctype newType,
7378                 int paramno)
7379 {
7380   bool hasError = FALSE;
7381
7382   if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7383     {
7384       if (uentry_hasName (newCurrent))
7385         {
7386           hasError = optgenerror 
7387             (FLG_TYPE,
7388              message ("Parameter %d, %q, of function %q has inconsistent type: "
7389                       "declared %t, %s %t",
7390                       paramno + 1, uentry_getName (newCurrent), 
7391                       uentry_getName (unew),
7392                       newType, uentry_specOrDefName (old), oldType),
7393              uentry_whereDeclared (newCurrent));
7394         }
7395       else
7396         {
7397           hasError = optgenerror
7398             (FLG_TYPE,
7399              message ("Parameter %d of function %q has inconsistent type: "
7400                       "declared %t, %s %t",
7401                       paramno + 1, uentry_getName (unew),
7402                       newType, uentry_specOrDefName (old), oldType),
7403              uentry_whereDeclared (newCurrent));
7404
7405           DPRINTF (("type: %s / %s",
7406                     ctype_unparse (newType),
7407                     ctype_unparse (ctype_realType (newType))));
7408         }
7409     }
7410   else 
7411     {
7412       if (uentry_isDeclared (unew))
7413         {
7414           hasError = optgenerror 
7415             (FLG_TYPE,
7416              message ("Parameter %d of function %s has inconsistent type: "
7417                       "declared %t, %s %t",
7418                       paramno + 1, unew->uname, 
7419                       newType, uentry_specOrDefName (old), oldType),
7420              uentry_whereDeclared (unew));
7421         }
7422       else
7423         {
7424           hasError = optgenerror
7425             (FLG_TYPE,
7426              message ("Parameter %d of function %s has inconsistent type: "
7427                       "declared %t, %s %t",
7428                       paramno + 1, unew->uname, 
7429                       newType, uentry_specOrDefName (old), oldType),
7430              uentry_whereDeclared (unew));
7431         }
7432     }
7433   
7434   if (hasError)
7435     {
7436       DPRINTF (("Here: %s / %s",
7437                 uentry_unparseFull (oldCurrent),
7438                 uentry_unparseFull (newCurrent)));
7439
7440       if (!uentry_isUndefined (oldCurrent))
7441         {
7442           if (!uentry_isUndefined (newCurrent) 
7443               && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7444             {
7445               uentry_showWhereLast (oldCurrent);
7446             }
7447           else
7448             {
7449               uentry_showWhereLastPlain (old);
7450             }
7451           
7452           uentry_setType (oldCurrent, newType);
7453         }
7454       else
7455         {
7456           uentry_showWhereLastPlain (old);
7457         }
7458     }
7459 }
7460
7461 static void
7462 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7463 {
7464   if (optgenerror 
7465       (FLG_TYPE,
7466        message ("Function %s %rdeclared with %d arg%&, %s with %d",
7467                 unew->uname, 
7468                 uentry_isDeclared (old),
7469                 uentryList_size (uentry_getParams (unew)),
7470                 uentry_specOrDefName (old),
7471                 uentryList_size (uentry_getParams (old))),
7472        uentry_whereDeclared (unew)))
7473     {
7474       uentry_showWhereLastPlain (old);
7475     }
7476 }
7477
7478 static void
7479 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7480 {
7481   if (optgenerror
7482       (FLG_INCONDEFS,
7483        message ("Function %s inconsistently %rdeclared to return %t",
7484                 unew->uname,
7485                 uentry_isDeclared (old),
7486                 ctype_getReturnType (unew->utype)),
7487        uentry_whereDeclared (unew)))
7488     {
7489       uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7490     }
7491 }
7492
7493 static cstring paramStorageName (uentry ue)
7494 {
7495   return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7496 }
7497
7498 static cstring fcnErrName (uentry ue)
7499 {
7500   return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7501 }
7502
7503 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7504 {
7505   if (uentry_isVar (ue))
7506     {
7507       return (checkedName (ue->info->var->checked));
7508     }
7509   else
7510     {
7511       return (cstring_makeLiteralTemp ("<checked invalid>"));
7512     }
7513 }
7514
7515 static cstring checkedName (chkind checked)
7516 {
7517   switch (checked)
7518     {
7519     case CH_UNKNOWN:       return (cstring_makeLiteralTemp ("unknown"));
7520     case CH_UNCHECKED:     return (cstring_makeLiteralTemp ("unchecked"));
7521     case CH_CHECKED:       return (cstring_makeLiteralTemp ("checked"));
7522     case CH_CHECKMOD:      return (cstring_makeLiteralTemp ("checkmod"));
7523     case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7524     }
7525   BADEXIT;
7526 }
7527
7528 static
7529 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7530 {
7531   nstate oldState;
7532   nstate newState;
7533   
7534   if (uentry_isVar (unew))
7535     {
7536       llassert (uentry_isVar (old));
7537       
7538       oldState = old->info->var->nullstate;
7539       newState = unew->info->var->nullstate;
7540     }
7541   else
7542     {
7543       oldState = sRef_getNullState (old->sref);
7544       newState = sRef_getNullState (unew->sref);
7545     }
7546
7547   if (oldState == NS_ABSNULL)
7548     {
7549       if (uentry_isVar (old))
7550         {
7551           old->info->var->nullstate = newState;
7552         }
7553       
7554       sRef_mergeNullState (old->sref, newState);
7555     }
7556   else if (newState == NS_UNKNOWN)
7557     {
7558       if (completeConform && newState != oldState
7559           && uentry_isReallySpecified (old))
7560         {
7561           if (optgenerror 
7562               (FLG_NEEDSPEC,
7563                message ("%s %q specified as %s, but declared without %s qualifier",
7564                         ekind_capName (unew->ukind),
7565                         uentry_getName (unew),
7566                         nstate_unparse (oldState),
7567                         nstate_unparse (oldState)),
7568                uentry_whereDeclared (unew)))
7569             {
7570               uentry_showWhereSpecified (old);
7571             }
7572         }
7573       
7574       if (uentry_isVar (unew))
7575         {
7576           unew->info->var->nullstate = oldState;
7577         }
7578
7579       sRef_mergeNullState (unew->sref, oldState);
7580     }
7581   else if (newState == NS_POSNULL)
7582     {
7583       if (oldState == NS_MNOTNULL 
7584           && (ctype_isUA (unew->utype) 
7585               || (uentry_isFunction (unew)
7586                   && ctype_isUA (ctype_getReturnType (unew->utype)))))
7587         {
7588           if (uentry_isVar (unew))
7589             {
7590               unew->info->var->nullstate = oldState;
7591             }
7592
7593           sRef_mergeNullState (unew->sref, oldState);
7594         }
7595       else 
7596         {
7597           if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL 
7598               || oldState == NS_UNKNOWN)
7599             {
7600               if (mustConform)
7601                 {
7602                   if (optgenerror 
7603                       (FLG_INCONDEFS,
7604                        message 
7605                        ("%s %q inconsistently %rdeclared %s possibly null storage, "
7606                         "%s %q qualifier",
7607                         uentry_ekindName (unew),
7608                         uentry_getName (unew),
7609                         uentry_isDeclared (old),
7610                         fcnErrName (unew),
7611                         uentry_specOrDefName (old),
7612                         cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7613                        uentry_whereDeclared (unew)))
7614                     {
7615                       uentry_showWhereSpecified (old);
7616                     }
7617                 }
7618             }
7619           
7620           if (uentry_isVar (old))
7621             {
7622               old->info->var->nullstate = newState;
7623             }
7624
7625           sRef_mergeNullState (old->sref, newState);
7626         }
7627     }
7628   else if (newState == NS_MNOTNULL)
7629     {
7630       if (oldState != NS_MNOTNULL)
7631         {
7632           if (mustConform)
7633             {
7634               if (optgenerror 
7635                   (FLG_INCONDEFS,
7636                    message ("%s %q inconsistently %rdeclared %s notnull storage, "
7637                             "%s without notnull qualifier",
7638                             uentry_ekindName (unew),
7639                             uentry_getName (unew),
7640                             uentry_isDeclared (old),
7641                             fcnErrName (unew),
7642                             uentry_specOrDefName (old)),
7643                    uentry_whereDeclared (unew)))
7644                 {
7645                   uentry_showWhereSpecified (old);
7646                 }
7647             }
7648           
7649           if (uentry_isVar (old))
7650             {
7651               old->info->var->nullstate = newState;
7652             }
7653
7654           sRef_mergeNullState (old->sref, newState);
7655         }
7656     }
7657   else
7658     {
7659       if (uentry_isVar (unew)) 
7660         {
7661           unew->info->var->nullstate = oldState;
7662         }
7663
7664       sRef_mergeNullState (unew->sref, oldState);
7665     }
7666 }
7667
7668 static
7669 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7670                     bool mustConform, bool completeConform)
7671 {
7672   sstate oldState;
7673   sstate newState;
7674   bool vars = FALSE;
7675
7676   if (uentry_isVar (old) && uentry_isVar (unew))
7677     {
7678       oldState = old->info->var->defstate;
7679       newState = unew->info->var->defstate;
7680       vars = TRUE;
7681     }
7682   else
7683     {
7684       oldState = sRef_getDefState (old->sref);
7685       newState = sRef_getDefState (unew->sref);
7686     }
7687
7688   if (newState != oldState 
7689       && newState != SS_UNKNOWN 
7690       && newState != SS_DEFINED)
7691     {
7692       if (mustConform)
7693         {
7694           if (optgenerror 
7695               (FLG_INCONDEFS,
7696                message ("%s %q inconsistently %rdeclared %s %s %s, "
7697                         "%s %s %s %s",
7698                         uentry_ekindName (unew),
7699                         uentry_getName (unew),
7700                         uentry_isDeclared (old),
7701                         fcnErrName (unew),
7702                         sstate_unparse (newState),
7703                         paramStorageName (unew),
7704                         uentry_specOrDefName (old),
7705                         fcnErrName (unew),
7706                         sstate_unparse (oldState),
7707                         paramStorageName (unew)),
7708                uentry_whereDeclared (unew)))
7709             {
7710               uentry_showWhereSpecified (old);
7711             }
7712         }
7713
7714       if (vars) old->info->var->defstate = newState;
7715       sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7716     }
7717   else
7718     {
7719       if (completeConform
7720           && (newState != oldState) && (oldState != SS_DEFINED)
7721           && uentry_isReallySpecified (old))
7722         {
7723           if (optgenerror 
7724               (FLG_NEEDSPEC,
7725                message ("%s %q specified as %s, but declared without %s qualifier",
7726                         ekind_capName (unew->ukind),
7727                         uentry_getName (unew),
7728                         sstate_unparse (oldState),
7729                         sstate_unparse (oldState)),
7730                uentry_whereDeclared (unew)))
7731             {
7732               uentry_showWhereSpecified (old);
7733             }
7734         }
7735       
7736       if (vars) unew->info->var->defstate = oldState;
7737       sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7738     }
7739 }
7740
7741 static void 
7742   checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7743                    bool mustConform, bool completeConform)
7744 {
7745   alkind newKind;
7746   alkind oldKind;
7747
7748   oldKind = sRef_getAliasKind (old->sref);
7749   newKind = sRef_getAliasKind (unew->sref);
7750
7751   if (alkind_isImplicit (newKind) 
7752       || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7753     {
7754       if (completeConform && !alkind_equal (newKind, oldKind)
7755           && uentry_isReallySpecified (old))
7756         {
7757           if (optgenerror 
7758               (FLG_NEEDSPEC,
7759                message ("%s %q specified as %s, but declared without "
7760                         "explicit alias qualifier",
7761                         ekind_capName (unew->ukind),
7762                         uentry_getName (unew),
7763                         alkind_unparse (oldKind)),
7764                uentry_whereDeclared (unew)))
7765             {
7766               uentry_showWhereSpecified (old);
7767             }
7768         }
7769
7770       /*  
7771       ** This really shouldn't be necessary, but it is!
7772       ** Function params (?) use new here.
7773       */
7774
7775       sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7776       return;
7777     }
7778
7779   if (alkind_isKnown (newKind))
7780     {
7781       if (!alkind_equal (oldKind, newKind))
7782         {
7783           if (alkind_isKnown (oldKind))
7784             {
7785               if (mustConform && 
7786                   optgenerror 
7787                   (FLG_INCONDEFS,
7788                    message ("%s %q inconsistently %rdeclared %s %s storage, "
7789                             "%s as %s storage",
7790                             uentry_ekindName (unew),
7791                             uentry_getName (unew),
7792                             uentry_isDeclared (old),
7793                             fcnErrName (unew),
7794                             alkind_unparse (newKind),
7795                             uentry_specOrDefName (old),
7796                             alkind_unparse (oldKind)),
7797                    uentry_whereDeclared (unew)))
7798                 {
7799                   uentry_showWhereSpecified (old);
7800
7801                   DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7802                   DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7803                   sRef_setAliasKind (old->sref, AK_ERROR, 
7804                                      uentry_whereDeclared (unew));
7805                 }
7806               else
7807                 {
7808                   sRef_setAliasKind (old->sref, newKind, 
7809                                      uentry_whereDeclared (unew));
7810                 }
7811             }
7812           else
7813             {
7814               if (!(alkind_isImplicit (newKind)))
7815                 {
7816                   if (mustConform &&
7817                       !uentry_isFunction (unew) &&
7818                       optgenerror 
7819                       (FLG_INCONDEFS,
7820                        message ("%s %q inconsistently %rdeclared %s %s storage, "
7821                                 "implicitly %s as temp storage",
7822                                 uentry_ekindName (unew),
7823                                 uentry_getName (unew),
7824                                 uentry_isDeclared (old),
7825                                 fcnErrName (unew),
7826                                 alkind_unparse (newKind),
7827                                 uentry_specOrDefName (old)),
7828                        uentry_whereDeclared (unew)))
7829                     {
7830                       uentry_showWhereSpecified (old);
7831                       oldKind = AK_ERROR;
7832                     }
7833                   
7834                   sRef_setAliasKind (old->sref, newKind, 
7835                                      uentry_whereDeclared (unew));
7836                 }
7837               else /* newKind is temp or refcounted */
7838                 {
7839                   ;
7840                 }
7841             }
7842         }
7843     }
7844   else /* newKind unknown */
7845     {
7846       ;
7847     }
7848 }
7849
7850 static void 
7851   checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7852                 bool mustConform, bool completeConform)
7853 {
7854   exkind newKind;
7855   exkind oldKind;
7856   
7857   oldKind = sRef_getExKind (old->sref);
7858   newKind = sRef_getExKind (unew->sref);
7859
7860   if (exkind_isKnown (newKind))
7861     {
7862       if (oldKind != newKind)
7863         {
7864           if (exkind_isKnown (oldKind))
7865             {
7866               if (mustConform && 
7867                   optgenerror 
7868                   (FLG_INCONDEFS,
7869                    message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7870                             uentry_ekindName (unew),
7871                             uentry_getName (unew),
7872                             uentry_isDeclared (old),
7873                             fcnErrName (unew),
7874                             exkind_unparse (newKind),
7875                             uentry_specOrDefName (old),
7876                             exkind_unparse (oldKind)),
7877                    uentry_whereDeclared (unew)))
7878                 {
7879                   uentry_showWhereSpecified (old);
7880                 }
7881
7882               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7883             }
7884           else
7885             {
7886               if (mustConform &&
7887                   optgenerror 
7888                   (FLG_INCONDEFS,
7889                    message ("%s %q inconsistently %rdeclared %s %s, "
7890                             "implicitly %s without exposure qualifier",
7891                             uentry_ekindName (unew),
7892                             uentry_getName (unew),
7893                             uentry_isDeclared (old),
7894                             fcnErrName (unew),
7895                             exkind_unparse (newKind),
7896                             uentry_specOrDefName (old)),
7897                    uentry_whereDeclared (unew)))
7898                 {
7899                   uentry_showWhereSpecified (old);
7900                 }
7901
7902               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7903             }
7904         }
7905     }
7906   else
7907     {
7908       if (completeConform && exkind_isKnown (oldKind)
7909           && uentry_isReallySpecified (old))
7910         {
7911           if (optgenerror 
7912               (FLG_NEEDSPEC,
7913                message ("%s %q specified as %s, but declared without "
7914                         "exposure qualifier",
7915                         ekind_capName (unew->ukind),
7916                         uentry_getName (unew),
7917                         exkind_unparse (oldKind)),
7918                uentry_whereDeclared (unew)))
7919             {
7920               uentry_showWhereSpecified (old);
7921             }
7922         }
7923
7924       /* yes, this is necessary! (if its a param) */
7925       sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7926     }
7927 }
7928
7929 static void 
7930 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7931                 bool mustConform, /*@unused@*/ bool completeConform)
7932 {
7933   valueTable newvals = sRef_getValueTable (unew->sref);
7934
7935   if (valueTable_isDefined (newvals))
7936     {
7937       DPRINTF (("Check meta state: %s -> %s",
7938                 uentry_unparseFull (old),
7939                 uentry_unparseFull (unew)));
7940       
7941       DPRINTF (("Check meta state refs: %s -> %s",
7942                 sRef_unparseFull (old->sref),
7943                 sRef_unparseFull (unew->sref)));
7944       
7945       DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7946       
7947       /*
7948       ** Copy the new values into the old ref
7949       */
7950
7951       valueTable_elements (newvals, key, newval)
7952         {
7953           metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7954           stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7955             
7956           llassert (metaStateInfo_isDefined (msinfo));
7957
7958           if (stateValue_isUndefined (oldval))
7959             {
7960               sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7961             }
7962           else
7963             {
7964               if (stateValue_isError (oldval))
7965                 {
7966                   if (!stateValue_isError (newval))
7967                     {
7968                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7969                     }
7970                   else
7971                     {
7972                       ; /* No change necessary. */
7973                     }
7974                 }
7975               else
7976                 {
7977                   if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7978                     {
7979                       if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7980                         {
7981                           ;
7982                         }
7983                       else
7984                         {
7985                           if (!stateValue_isError (newval) 
7986                               && !stateValue_isImplicit (newval))
7987                             {
7988                               if (uentry_hasName (unew)
7989                                   || !sRef_isParam (uentry_getSref (unew)))
7990                                 {
7991                                   if (mustConform 
7992                                       && optgenerror 
7993                                       (FLG_INCONDEFS,
7994                                        message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7995                                                 uentry_ekindName (unew),
7996                                                 uentry_getName (unew),
7997                                                 uentry_isDeclared (old),
7998                                                 fcnErrName (unew),
7999                                                 stateValue_unparseValue (newval, msinfo),
8000                                                 uentry_specOrDefName (old),
8001                                                 stateValue_unparseValue (oldval, msinfo)),
8002                                        uentry_whereDeclared (unew)))
8003                                     {
8004                                       uentry_showWhereSpecified (old);
8005                                     }
8006                                 }
8007                               else
8008                                 {
8009                                   if (mustConform 
8010                                       && optgenerror 
8011                                       (FLG_INCONDEFS,
8012                                        message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
8013                                                 uentry_ekindName (unew),
8014                                                 sRef_getParam (uentry_getSref (unew)),
8015                                                 uentry_isDeclared (old),
8016                                                 fcnErrName (unew),
8017                                                 stateValue_unparseValue (newval, msinfo),
8018                                                 uentry_specOrDefName (old),
8019                                                 stateValue_unparseValue (oldval, msinfo)),
8020                                        uentry_whereDeclared (unew)))
8021                                     {
8022                                       uentry_showWhereSpecified (old);
8023                                     }
8024                                 }
8025                             }
8026                         }
8027                       
8028                       DPRINTF (("Updating!"));
8029                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8030                     }
8031                   else
8032                     {
8033                       DPRINTF (("Values match"));
8034                     }
8035                 }
8036             }
8037         } end_valueTable_elements ;
8038     }
8039 }
8040
8041 static void
8042 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8043                               /*@notnull@*/ uentry unew,
8044                               bool mustConform, bool completeConform)
8045 {
8046   checkDefState (old, unew, mustConform, completeConform);
8047   checkNullState (old, unew, mustConform, completeConform);
8048   checkAliasState (old, unew, mustConform, completeConform);
8049   checkExpState (old, unew, mustConform, completeConform);
8050   checkMetaState (old, unew, mustConform, completeConform);
8051
8052   sRef_storeState (old->sref);
8053   sRef_storeState (unew->sref);
8054 }
8055
8056 static void
8057 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8058 {
8059   if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8060     {
8061       return;
8062     }
8063
8064   llassert (uentry_isVar (old));
8065   llassert (uentry_isVar (unew));
8066
8067   if (cstring_isEmpty (old->uname)) 
8068     {
8069       cstring_free (old->uname);
8070       old->uname = cstring_copy (unew->uname);
8071     }
8072
8073   if (unew->info->var->kind == VKRETPARAM
8074       || unew->info->var->kind == VKSEFRETPARAM)
8075     {
8076       if (old->info->var->kind != VKRETPARAM
8077           && old->info->var->kind != VKSEFRETPARAM)
8078         {
8079           if (optgenerror 
8080               (FLG_INCONDEFS,
8081                message ("Parameter %q inconsistently %rdeclared as "
8082                         "returned parameter",
8083                         uentry_getName (unew),
8084                         uentry_isDeclared (old)),
8085                uentry_whereDeclared (unew)))
8086             {
8087               uentry_showWhereSpecified (old);
8088               old->info->var->kind = unew->info->var->kind;
8089             }
8090         }
8091     }
8092
8093
8094   if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8095     {
8096       if (old->info->var->kind != VKSEFPARAM 
8097           && old->info->var->kind != VKSEFRETPARAM)
8098         {
8099           if (optgenerror 
8100               (FLG_INCONDEFS,
8101                message ("Parameter %qinconsistently %rdeclared as "
8102                         "sef parameter",
8103                         uentry_getOptName (unew),
8104                         uentry_isDeclared (old)),
8105                uentry_whereDeclared (unew)))
8106             {
8107               uentry_showWhereSpecified (old);
8108               old->info->var->kind = unew->info->var->kind;
8109             }
8110         }
8111     }
8112
8113   if (old->info->var->kind == VKSPEC)
8114     {
8115       old->info->var->kind = unew->info->var->kind;
8116     }
8117   else
8118     {
8119       unew->info->var->kind = old->info->var->kind;
8120     }
8121
8122   if (unew->info->var->checked != CH_UNKNOWN
8123       && unew->info->var->checked != old->info->var->checked)
8124     {
8125       if (old->info->var->checked == CH_UNKNOWN
8126           && !fileloc_isUser (uentry_whereLast (old)))
8127         {
8128           ; /* no error */
8129         }
8130       else
8131         {
8132           if (optgenerror 
8133               (FLG_INCONDEFS,
8134                message ("Variable %q inconsistently %rdeclared as "
8135                         "%s parameter (was %s)",
8136                         uentry_getName (unew),
8137                         uentry_isDeclared (old),
8138                         checkedName (unew->info->var->checked),
8139                         checkedName (old->info->var->checked)),
8140                uentry_whereDeclared (unew)))
8141             {
8142               uentry_showWhereSpecified (old);
8143             }
8144         }
8145       
8146       old->info->var->checked = unew->info->var->checked;
8147     }
8148   else
8149     {
8150       if (completeConform 
8151           && (old->info->var->checked != CH_UNKNOWN)
8152           && uentry_isReallySpecified (old))
8153         {
8154           if (optgenerror 
8155               (FLG_NEEDSPEC,
8156                message ("%s %q specified as %s, but declared without %s qualifier",
8157                         ekind_capName (unew->ukind),
8158                         uentry_getName (unew),
8159                         checkedName (old->info->var->checked),
8160                         checkedName (old->info->var->checked)),
8161                uentry_whereDeclared (unew)))
8162             {
8163               uentry_showWhereSpecified (old);
8164             }
8165         }
8166       
8167       unew->info->var->checked = old->info->var->checked;
8168     }
8169
8170   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8171 }
8172
8173 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8174 {
8175   if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8176     {
8177       return;
8178     }
8179
8180   llassert (uentry_isVar (u1));
8181   llassert (uentry_isVar (u2));
8182
8183   if (u1->info->var->kind != u2->info->var->kind) {
8184     if (u1->info->var->kind == VKSEFRETPARAM) {
8185       if (u2->info->var->kind == VKRETPARAM) {
8186         voptgenerror 
8187           (FLG_TYPE,
8188            message ("Function types are inconsistent. Parameter %d is "
8189                     "sef parameter, but non-sef parameter in "
8190                     "assigned function: %s",
8191                     paramno, exprNode_unparse (e)),
8192            exprNode_loc (e));
8193       } else if (u2->info->var->kind == VKSEFPARAM) {
8194         voptgenerror 
8195           (FLG_TYPE,
8196            message ("Function types are inconsistent. Parameter %d is "
8197                     "returns parameter, but non-returns parameter in "
8198                     "assigned function: %s",
8199                     paramno, exprNode_unparse (e)),
8200            exprNode_loc (e));
8201       } else {
8202         voptgenerror 
8203           (FLG_TYPE,
8204            message ("Function types are inconsistent. Parameter %d is "
8205                     "sef returns parameter, but non-sef returns parameter in "
8206                     "assigned function: %s",
8207                     paramno, exprNode_unparse (e)),
8208            exprNode_loc (e));
8209       }
8210     } else if (u1->info->var->kind == VKRETPARAM) {
8211       voptgenerror 
8212         (FLG_TYPE,
8213          message ("Function types are inconsistent. Parameter %d is "
8214                   "returns parameter, but non-returns parameter in "
8215                   "assigned function: %s",
8216                   paramno, exprNode_unparse (e)),
8217          exprNode_loc (e));
8218     } else if (u1->info->var->kind == VKSEFPARAM) {
8219       voptgenerror 
8220         (FLG_TYPE,
8221          message ("Function types are inconsistent. Parameter %d is "
8222                   "sef parameter, but non-sef parameter in "
8223                   "assigned function: %s",
8224                   paramno, exprNode_unparse (e)),
8225          exprNode_loc (e));
8226     } else {
8227       if (u2->info->var->kind == VKSEFRETPARAM) {
8228         voptgenerror 
8229           (FLG_TYPE,
8230            message ("Function types are inconsistent. Parameter %d is "
8231                     "normal parameter, but sef returns parameter in "
8232                     "assigned function: %s",
8233                     paramno, exprNode_unparse (e)),
8234            exprNode_loc (e));
8235       } else if (u2->info->var->kind == VKSEFPARAM) {
8236         voptgenerror 
8237           (FLG_TYPE,
8238            message ("Function types are inconsistent. Parameter %d is "
8239                     "normal parameter, but sef parameter in "
8240                     "assigned function: %s",
8241                     paramno, exprNode_unparse (e)),
8242            exprNode_loc (e));
8243       } else if (u2->info->var->kind == VKRETPARAM) {
8244         voptgenerror 
8245           (FLG_TYPE,
8246            message ("Function types are inconsistent. Parameter %d is "
8247                     "normal parameter, but returns parameter in "
8248                     "assigned function: %s",
8249                     paramno, exprNode_unparse (e)),
8250            exprNode_loc (e));
8251       } else {
8252         BADBRANCH;
8253       }
8254     }
8255   }
8256
8257   if (u1->info->var->defstate != u2->info->var->defstate) 
8258     {
8259       voptgenerror 
8260         (FLG_TYPE,
8261          message ("Function types are inconsistent. Parameter %d is "
8262                   "%s, but %s in assigned function: %s",
8263                   paramno, 
8264                   sstate_unparse (u1->info->var->defstate),
8265                   sstate_unparse (u2->info->var->defstate),
8266                   exprNode_unparse (e)),
8267          exprNode_loc (e));
8268     }
8269
8270   if (u1->info->var->nullstate != u2->info->var->nullstate) 
8271     {
8272       voptgenerror 
8273         (FLG_TYPE,
8274          message ("Function types are inconsistent. Parameter %d is "
8275                   "%s, but %s in assigned function: %s",
8276                   paramno, 
8277                   nstate_unparse (u1->info->var->nullstate),
8278                   nstate_unparse (u2->info->var->nullstate),
8279                   exprNode_unparse (e)),
8280          exprNode_loc (e));
8281     }
8282       
8283   if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8284     {
8285       voptgenerror 
8286         (FLG_TYPE,
8287          message ("Function types are inconsistent. Parameter %d is "
8288                   "%s, but %s in assigned function: %s",
8289                   paramno, 
8290                   alkind_unparse (sRef_getAliasKind (u1->sref)),
8291                   alkind_unparse (sRef_getAliasKind (u2->sref)),
8292                   exprNode_unparse (e)),
8293          exprNode_loc (e));
8294     }
8295
8296   if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8297     {
8298       voptgenerror 
8299         (FLG_TYPE,
8300          message ("Function types are inconsistent. Parameter %d is "
8301                   "%s, but %s in assigned function: %s",
8302                   paramno, 
8303                   exkind_unparse (sRef_getExKind (u1->sref)),
8304                   exkind_unparse (sRef_getExKind (u2->sref)),
8305                   exprNode_unparse (e)),
8306          exprNode_loc (e));
8307     }
8308 }
8309
8310 static void uentry_convertIntoFunction (/*@notnull@*/ uentry old)
8311 {
8312   /*
8313   ** Convert old into a function
8314   */
8315   
8316   old->ukind = KFCN;
8317   old->utype = ctype_unknown;
8318   old->info->fcn = (ufinfo) dmalloc (sizeof (*old->info->fcn));
8319   old->info->fcn->hasMods = FALSE;
8320   old->info->fcn->hasGlobs = FALSE;
8321   old->info->fcn->exitCode = XK_UNKNOWN;
8322   old->info->fcn->nullPred = qual_createUnknown ();
8323   old->info->fcn->specialCode = SPC_NONE;
8324   old->info->fcn->access = typeIdSet_undefined;
8325   old->info->fcn->globs = globSet_undefined;
8326   old->info->fcn->defparams = uentryList_undefined;
8327   old->info->fcn->mods = sRefSet_undefined;
8328   old->info->fcn->specclauses = NULL;
8329   old->info->fcn->preconditions = NULL;
8330   old->info->fcn->postconditions = NULL;
8331 }
8332
8333 static void
8334 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8335                           /*@notnull@*/ uentry unew, 
8336                           bool mustConform, /*@unused@*/ bool completeConform)
8337 {
8338   uentryList oldParams  = uentry_getParams (old);
8339   uentryList newParams  = uentry_getParams (unew);
8340   ctype      newType    = unew->utype;
8341   ctype      oldType    = ctype_realType (old->utype);
8342   ctype      oldRetType = ctype_unknown;
8343   ctype      newRetType = ctype_unknown;
8344
8345   DPRINTF (("Function conform: %s ==> %s",
8346             uentry_unparseFull (old),
8347             uentry_unparseFull (unew)));
8348
8349   if (uentry_isForward (old))
8350     {
8351       mustConform = FALSE;
8352       uentry_updateInto (old, unew);
8353       return;
8354     }
8355
8356   /*
8357   ** check return values
8358   */
8359   
8360   if (ctype_isKnown (oldType))
8361     {
8362       if (ctype_isFunction (oldType))
8363         {
8364           oldRetType = ctype_getReturnType (oldType);
8365         }
8366       else
8367         {
8368           if (optgenerror 
8369               (FLG_INCONDEFS,
8370                message ("%s %q declared as function, but previously declared as %s",
8371                         ekind_capName (unew->ukind),
8372                         uentry_getName (unew),
8373                         ekind_unparseLong (old->ukind)),
8374                uentry_whereDeclared (unew)))
8375             {
8376               uentry_showWhereLast (old);
8377             }
8378
8379           uentry_convertIntoFunction (old);
8380           return;
8381         }
8382     }
8383
8384   if (ctype_isKnown (newType))
8385     {
8386       llassert (ctype_isFunction (newType));
8387       newRetType = ctype_getReturnType (newType);
8388     }
8389
8390   if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8391       && !ctype_matchDef (newRetType, oldRetType))
8392     {
8393       if (mustConform) returnValueError (old, unew);
8394     }
8395   else 
8396     {
8397       if (ctype_isConj (newRetType))
8398         {
8399           if (ctype_isConj (oldRetType))
8400             {
8401               if (!ctype_sameAltTypes (newRetType, oldRetType))
8402                 {
8403                   if (optgenerror 
8404                       (FLG_INCONDEFS,
8405                        message ("Function %q inconsistently %rdeclared to "
8406                                 "return alternate types %s "
8407                                 "(types match, but alternates are not identical, "
8408                                 "so checking may not be correct)",
8409                                 uentry_getName (unew),
8410                                 uentry_isDeclared (old),
8411                                 ctype_unparse (newRetType)),
8412                        uentry_whereDeclared (unew)))
8413                     {
8414                       uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8415                     }
8416                 }
8417             }
8418           else
8419             {
8420               old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8421             }
8422         }
8423     }
8424
8425   DPRINTF (("Before state: %s",
8426             uentry_unparseFull (old)));
8427   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8428   DPRINTF (("After state: %s",
8429             uentry_unparseFull (old)));
8430
8431   if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8432     {
8433       if (exitkind_isKnown (unew->info->fcn->exitCode))
8434         {
8435           if (optgenerror 
8436               (FLG_INCONDEFS,
8437                message ("Function %q inconsistently %rdeclared using %s",
8438                         uentry_getName (unew),
8439                         uentry_isDeclared (old),
8440                         exitkind_unparse (unew->info->fcn->exitCode)),
8441                uentry_whereDeclared (unew)))
8442             {
8443               uentry_showWhereSpecified (old);
8444             }
8445         }
8446       else
8447         {
8448           unew->info->fcn->exitCode = old->info->fcn->exitCode;
8449         }
8450     }
8451
8452   if (!qual_isUnknown (unew->info->fcn->nullPred))
8453     {
8454       if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8455         {
8456           if (optgenerror
8457               (FLG_INCONDEFS,
8458                message ("Function %q inconsistently %rdeclared using %s",
8459                         uentry_getName (unew),
8460                         uentry_isDeclared (old),
8461                         qual_unparse (unew->info->fcn->nullPred)),
8462                uentry_whereDeclared (unew)))
8463             {
8464               uentry_showWhereSpecified (old);
8465             }
8466         }
8467     }
8468   else
8469     {
8470       unew->info->fcn->nullPred = old->info->fcn->nullPred;
8471     }
8472
8473   if (unew->info->fcn->specialCode != SPC_NONE)
8474     {
8475       if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8476         {
8477           if (optgenerror
8478               (FLG_INCONDEFS,
8479                message ("Function %q inconsistently %rdeclared using %s",
8480                         uentry_getName (unew),
8481                         uentry_isDeclared (old),
8482                         specCode_unparse (unew->info->fcn->specialCode)),
8483                uentry_whereDeclared (unew)))
8484             {
8485               uentry_showWhereSpecified (old);
8486             }
8487         }
8488     }
8489   else
8490     {
8491       unew->info->fcn->specialCode = old->info->fcn->specialCode;
8492     }
8493           
8494   /*
8495   ** check parameters
8496   */
8497   
8498   if (!uentryList_sameObject (oldParams, newParams)
8499       && (!uentryList_isMissingParams (oldParams)))
8500     {
8501       if (!uentryList_isMissingParams (newParams))
8502         {
8503           int paramno = 0;
8504           int nparams = uentryList_size (oldParams);
8505           bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8506
8507           if (nparams != uentryList_size (newParams))
8508             {
8509               nargsError (old, unew);
8510             }
8511           
8512           if (uentryList_size (newParams) < nparams) 
8513             {
8514               nparams = uentryList_size (newParams);
8515             }
8516
8517           while (paramno < nparams)
8518             {
8519               uentry oldCurrent = uentryList_getN (oldParams, paramno);
8520               uentry newCurrent  = uentryList_getN (newParams, paramno);
8521               ctype  oldCurrentType = uentry_getType (oldCurrent);
8522               ctype  newCurrentType = uentry_getType (newCurrent);
8523
8524               llassert (uentry_isValid (oldCurrent)
8525                         && uentry_isValid (newCurrent));
8526               
8527               if (!uentry_isElipsisMarker (oldCurrent)
8528                   && !uentry_isElipsisMarker (newCurrent))
8529                 {
8530                   checkVarConformance (oldCurrent, newCurrent, 
8531                                        mustConform, completeConform);
8532                 }
8533
8534               if (checknames)
8535                 {
8536                   if (uentry_hasName (oldCurrent) 
8537                       && uentry_hasName (newCurrent))
8538                     {
8539                       cstring oldname = uentry_getName (oldCurrent);
8540                       cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8541                       cstring oname;
8542                       cstring nname = uentry_getName (newCurrent);
8543                       cstring nnamefix;
8544
8545                       if (cstring_isDefined (pfx)
8546                           && cstring_equalPrefix (oldname, pfx))
8547                         {
8548                           oname = cstring_suffix (oldname, cstring_length (pfx));
8549                         }
8550                       else
8551                         {
8552                           oname = oldname;
8553                         /*@-branchstate@*/ } /*@=branchstate@*/
8554
8555                       if (cstring_isDefined (pfx)
8556                           && cstring_equalPrefix (nname, pfx))
8557                         {
8558                           nnamefix = cstring_suffix (nname, cstring_length (pfx));
8559                         }
8560                       else
8561                         {
8562                           nnamefix = nname;
8563                         /*@-branchstate@*/ } /*@=branchstate@*/
8564
8565                       if (!cstring_equal (oname, nnamefix))
8566                         {
8567                           if (optgenerror
8568                               (FLG_DECLPARAMMATCH, 
8569                                message ("Definition parameter name %s does not match "
8570                                         "name of corresponding parameter in "
8571                                         "declaration: %s",
8572                                         nnamefix, oname),
8573                                uentry_whereLast (newCurrent)))
8574                             {
8575                               uentry_showWhereLastPlain (oldCurrent);
8576                             }
8577                         }
8578                       
8579                       cstring_free (oldname);
8580                       cstring_free (nname);
8581                     }
8582                 }
8583
8584               if (!ctype_match (oldCurrentType, newCurrentType))
8585                 {
8586                   paramTypeError (old, oldCurrent, oldCurrentType,
8587                                   unew, newCurrent, newCurrentType, paramno);
8588                 }
8589               else
8590                 {
8591                   if (ctype_isMissingParamsMarker (newCurrentType)
8592                       || ctype_isElips (newCurrentType)
8593                       || ctype_isMissingParamsMarker (oldCurrentType)
8594                       || ctype_isElips (oldCurrentType))
8595                     {
8596                       ;
8597                     }
8598                   else
8599                     {
8600                       if (ctype_isConj (newCurrentType))
8601                         {
8602                           if (ctype_isConj (oldCurrentType))
8603                             {
8604                               if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8605                                 {
8606                                   if (optgenerror 
8607                                       (FLG_INCONDEFS,
8608                                        message ("Parameter %q inconsistently %rdeclared with "
8609                                                 "alternate types %s "
8610                                                 "(types match, but alternates are not identical, "
8611                                                 "so checking may not be correct)",
8612                                                 uentry_getName (newCurrent),
8613                                                 uentry_isDeclared (oldCurrent),
8614                                                 ctype_unparse (newCurrentType)),
8615                                        uentry_whereDeclared (unew)))
8616                                     {
8617                                       uentry_showWhereLastVal (oldCurrent,
8618                                                                ctype_unparse (oldCurrentType));
8619                                     }
8620                                 }
8621                             }
8622                           else
8623                             {
8624                               if (optgenerror 
8625                                   (FLG_INCONDEFS,
8626                                    message ("Parameter %q inconsistently %rdeclared with "
8627                                             "alternate types %s",
8628                                             uentry_getName (newCurrent),
8629                                             uentry_isDeclared (oldCurrent),
8630                                             ctype_unparse (newCurrentType)),
8631                                    uentry_whereDeclared (unew)))
8632                                 {
8633                                   uentry_showWhereLastVal (oldCurrent,
8634                                                            ctype_unparse (oldCurrentType));
8635                                   
8636                                 }
8637                             }
8638                         }
8639                       else 
8640                         {
8641                           if (ctype_isConj (oldCurrentType))
8642                             {
8643                               uentry_setType (newCurrent, oldCurrentType);
8644                             }
8645                         }
8646                     }
8647                 }
8648
8649               paramno++;  
8650               /*
8651                ** Forgot this!  detected by splint:
8652                ** uentry.c:1257,15: Suspected infinite loop
8653                */
8654             }
8655         }
8656     }
8657
8658   if (!uentryList_isMissingParams (newParams))
8659     {
8660       if (ctype_isConj (oldRetType))
8661         {
8662           old->utype = ctype_makeFunction (oldRetType, 
8663                                            uentryList_copy (newParams));
8664         }
8665       else
8666         {
8667           old->utype = unew->utype;
8668         }
8669     }
8670
8671   checkGlobalsConformance (old, unew, mustConform, completeConform);
8672   checkModifiesConformance (old, unew, mustConform, completeConform);
8673
8674   DPRINTF (("Before list: %s",
8675             uentry_unparseFull (old)));
8676
8677   if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8678     {
8679       if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8680         {
8681           /*
8682           if (optgenerror
8683               (FLG_INCONDEFS,
8684                message ("Function %q redeclared using special clauses (can only "
8685                         "be used in first declaration)",
8686                         uentry_getName (unew)),
8687                uentry_whereDeclared (unew)))
8688             {
8689               uentry_showWhereLast (old);
8690             }
8691           */
8692
8693           /* need to add some checking @*/ 
8694           old->info->fcn->specclauses = unew->info->fcn->specclauses;
8695         }
8696       else
8697         {
8698           /* should be able to append? */
8699
8700           stateClauseList_checkEqual (old, unew);
8701           stateClauseList_free (unew->info->fcn->specclauses);
8702           unew->info->fcn->specclauses = stateClauseList_undefined;
8703           /*@-branchstate@*/ 
8704         }
8705     }
8706   /*@=branchstate@*/ /* shouldn't need this */
8707
8708   if (fileloc_isUndefined (old->whereDeclared))
8709     {
8710       old->whereDeclared = fileloc_copy (unew->whereDeclared);
8711     }
8712   else if (fileloc_isUndefined (unew->whereDeclared))
8713     {
8714       unew->whereDeclared = fileloc_copy (old->whereDeclared);
8715     }
8716   else
8717     {
8718       /* no change */
8719     }
8720   /*@-compmempass@*/
8721 } /*@=compmempass@*/ /* I think this is a spurious warning */
8722
8723 void
8724 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8725 {
8726   multiVal uval;
8727
8728   llassert (uentry_isValid (ue));
8729   llassert (uentry_isEitherConstant (ue));
8730
8731   DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8732   uval = uentry_getConstantValue (ue);
8733
8734   if (multiVal_isDefined (uval))
8735     {
8736       if (multiVal_isDefined (m))
8737         {
8738           if (!multiVal_equiv (uval, m))
8739             {
8740               if (optgenerror 
8741                   (FLG_INCONDEFS,
8742                    message ("%s %q defined with inconsistent value: %q",
8743                             ekind_capName (ue->ukind),
8744                             uentry_getName (ue), 
8745                             multiVal_unparse (m)),
8746                    g_currentloc))
8747                 {
8748                   uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8749                 }
8750             }
8751         }
8752       multiVal_free (m);
8753     }
8754   else
8755     {
8756       uentry_setConstantValue (ue, m);
8757     }
8758 }
8759
8760 static
8761 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
8762                            bool mustConform)
8763 {
8764   bool typeError = FALSE;
8765
8766   if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8767     {
8768       if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8769         {
8770           if (mustConform)
8771             {
8772               DPRINTF (("Check struct conformance: %s / %s",
8773                         uentry_unparseFull (old),
8774                         uentry_unparseFull (unew)));
8775               checkStructConformance (old, unew); 
8776             }
8777         }
8778       else
8779         {
8780           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8781             {
8782               llbug (message ("struct tags: bad types: %t / %t", 
8783                               old->utype, unew->utype));
8784             }
8785         }
8786     }
8787   else if (uentry_isEnumTag (old))
8788     {
8789       if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8790         {
8791           if (mustConform) checkEnumConformance (old, unew);
8792         }
8793       else 
8794         {
8795           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8796             {
8797               llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8798                               ctype_unparse (unew->utype)));
8799             }
8800         }
8801     }
8802   else if (!ctype_match (old->utype, unew->utype))
8803     {
8804       DPRINTF (("Type mismatch: %s / %s",
8805                 ctype_unparse (old->utype),
8806                 ctype_unparse (unew->utype)));
8807
8808       if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8809         {
8810           ctype realt = ctype_realType (unew->utype);
8811           
8812           if (ctype_isRealInt (realt) || ctype_isChar (realt))
8813             {
8814               unew->utype = ctype_bool;
8815             }
8816           else
8817             {
8818               if (mustConform)
8819                 {
8820                   typeError = optgenerror
8821                     (FLG_INCONDEFS,
8822                      message ("%q defined as %s", uentry_getName (old), 
8823                               ctype_unparse (realt)),
8824                      uentry_whereDeclared (unew));
8825                 }
8826             }
8827         } 
8828       else 
8829         {
8830           if (mustConform)
8831             {
8832               ctype oldr = ctype_realType (old->utype);
8833               ctype newr = ctype_realType (unew->utype);
8834               
8835               if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8836                 {
8837                   checkStructConformance (old, unew);
8838                 }
8839               else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8840                 {
8841                   checkStructConformance (old, unew);
8842                 }
8843               else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8844                 {
8845                   checkEnumConformance (old, unew);
8846                 }
8847               else if (uentry_isConstant (old) 
8848                        && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8849                 {
8850                   /* okay...for now! (should check the type is reset later... */
8851                 }
8852               else
8853                 {
8854                   DPRINTF (("YABA!"));
8855                   if (optgenerror 
8856                       (FLG_INCONDEFS,
8857                        message ("%s %q %rdeclared with inconsistent type: %t",
8858                                 ekind_capName (unew->ukind),
8859                                 uentry_getName (unew), 
8860                                 uentry_isDeclared (old),
8861                                 unew->utype),
8862                        uentry_whereDeclared (unew)))
8863                     {
8864                       uentry_showWhereLast (old);
8865                       typeError = TRUE;
8866                     }
8867                 }
8868             }
8869         }
8870     }
8871   else
8872     {
8873       /* no error */
8874     }
8875
8876   return typeError;
8877 }
8878
8879 static void
8880 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8881                                  /*@notnull@*/ uentry unew,
8882                                  bool mustConform, bool completeConform)
8883 {
8884   if (ctype_isDefined (unew->info->datatype->type))
8885     {
8886       /*
8887       ** bool is hard coded here, since it is built into LCL.
8888       ** For now, we're stuck with LCL's types.
8889       */
8890
8891       if (ctype_isDirectBool (old->utype) &&
8892           cstring_equalLit (unew->uname, "bool"))
8893         {
8894           /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8895              evs 2000-07-25: removed
8896           */
8897               unew->utype = ctype_bool;
8898         }
8899       
8900       if (ctype_isUnknown (old->info->datatype->type))
8901         {
8902           old->info->datatype->type = unew->info->datatype->type;
8903         }
8904       else
8905         {
8906           DPRINTF (("Old: %s / New: %s",
8907                     uentry_unparseFull (old),
8908                     uentry_unparseFull (unew)));
8909           DPRINTF (("Types: %s / %s",
8910                     ctype_unparse (old->info->datatype->type),
8911                     ctype_unparse (unew->info->datatype->type)));
8912
8913           if (ctype_matchDef (old->info->datatype->type,
8914                               unew->info->datatype->type))
8915             {
8916               ;
8917             }
8918           else
8919             {
8920               if (optgenerror 
8921                   (FLG_INCONDEFS,
8922                    message
8923                    ("Type %q %s with inconsistent type: %t",
8924                     uentry_getName (unew), 
8925                     uentry_reDefDecl (old, unew),
8926                     unew->info->datatype->type),
8927                    uentry_whereDeclared (unew)))
8928                 {
8929                   uentry_showWhereLastExtra 
8930                     (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8931                 }
8932
8933               old->info->datatype->type = unew->info->datatype->type;
8934             }
8935         }
8936     }
8937   
8938   if (!qual_isUnknown (unew->info->datatype->abs))
8939     {
8940       if (qual_isConcrete (old->info->datatype->abs)
8941           && qual_isEitherAbstract (unew->info->datatype->abs))
8942         {
8943           if (!ctype_isDirectBool (old->utype))
8944             {
8945               if (optgenerror 
8946                   (FLG_INCONDEFS,
8947                    message 
8948                    ("Datatype %q inconsistently %rdeclared as abstract type",
8949                     uentry_getName (unew), 
8950                     uentry_isDeclared (old)),
8951                    uentry_whereDeclared (unew)))
8952                 {
8953                   uentry_showWhereLastPlain (old);
8954                 }
8955             }
8956         }
8957       else if (qual_isEitherAbstract (old->info->datatype->abs)
8958                && qual_isConcrete (unew->info->datatype->abs))
8959         {
8960           if (!ctype_isDirectBool (old->utype))
8961             {
8962               if (optgenerror 
8963                   (FLG_INCONDEFS,
8964                    message 
8965                    ("Datatype %q inconsistently %rdeclared as concrete type",
8966                     uentry_getName (unew), 
8967                     uentry_isDeclared (old)),
8968                    uentry_whereDeclared (unew)))
8969                 {
8970                   uentry_showWhereLastPlain (old);
8971                 }
8972             }
8973         }
8974       else
8975         {
8976           ;
8977         }
8978     }
8979   else 
8980     {
8981       if (qual_isEitherAbstract (old->info->datatype->abs))
8982         {
8983           old->sref = unew->sref;
8984           unew->info->datatype->mut = old->info->datatype->mut;
8985           
8986           if (completeConform
8987               && uentry_isReallySpecified (old))
8988             {
8989               if (optgenerror 
8990                   (FLG_NEEDSPEC,
8991                    message 
8992                    ("Datatype %q specified as abstract, "
8993                     "but abstract annotation not used in declaration",
8994                     uentry_getName (unew)), 
8995                    uentry_whereDeclared (unew)))
8996                 {
8997                   uentry_showWhereLastPlain (old);
8998                 }
8999             }
9000         }
9001     }
9002   
9003   unew->info->datatype->abs = old->info->datatype->abs;   
9004   
9005   if (ynm_isMaybe (unew->info->datatype->mut))
9006     {
9007       if (completeConform && ynm_isOff (old->info->datatype->mut)
9008           && uentry_isReallySpecified (old))
9009         {
9010           if (optgenerror 
9011               (FLG_NEEDSPEC,
9012                message 
9013                ("Datatype %q specified as immutable, "
9014                 "but immutable annotation not used in declaration",
9015                 uentry_getName (unew)), 
9016                uentry_whereDeclared (unew)))
9017             {
9018               uentry_showWhereLastPlain (old);
9019             }
9020         }
9021       
9022       unew->info->datatype->mut = old->info->datatype->mut;
9023     }
9024   else if (ynm_isMaybe (old->info->datatype->mut))
9025     {
9026       old->info->datatype->mut = unew->info->datatype->mut;
9027     }
9028   else
9029     {
9030       if (qual_isEitherAbstract (old->info->datatype->abs))
9031         {
9032           if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
9033             {
9034               if (optgenerror
9035                   (FLG_INCONDEFS,
9036                    message ("Datatype %q inconsistently %rdeclared as immutable",
9037                             uentry_getName (unew), 
9038                             uentry_isDeclared (old)),
9039                    uentry_whereDeclared (unew)))
9040                 {
9041                   uentry_showWhereLastPlain (old);
9042                 }
9043             }
9044           else 
9045             {
9046               if (ynm_isOff (old->info->datatype->mut)
9047                   && ynm_isOn (unew->info->datatype->mut))
9048                 {
9049                   if (optgenerror
9050                       (FLG_INCONDEFS,
9051                        message ("Datatype %q inconsistently %rdeclared as mutable",
9052                                 uentry_getName (unew), 
9053                                 uentry_isDeclared (old)),
9054                        uentry_whereDeclared (unew)))
9055                     {
9056                       uentry_showWhereLastPlain (old);
9057                     }
9058                 }
9059             }
9060         }
9061       old->info->datatype->mut = unew->info->datatype->mut;       
9062     }
9063
9064   uentry_checkStateConformance (old, unew, mustConform, completeConform);
9065 }
9066
9067 static void
9068 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
9069                                  /*@notnull@*/ uentry unew,
9070                                  bool mustConform, 
9071                                  /*@unused@*/ bool completeConform)
9072 {
9073   multiVal oldval = uentry_getConstantValue (old);
9074   multiVal newval = uentry_getConstantValue (unew);
9075   
9076   if (multiVal_isDefined (oldval))
9077     {
9078       if (multiVal_isDefined (newval))
9079         {
9080           if (!multiVal_equiv (oldval, newval))
9081             {
9082               if (mustConform
9083                   && optgenerror 
9084                   (FLG_INCONDEFS,
9085                    message ("%s %q %rdeclared with inconsistent value: %q",
9086                             ekind_capName (unew->ukind),
9087                             uentry_getName (unew), 
9088                             uentry_isDeclared (old),
9089                             multiVal_unparse (newval)),
9090                    uentry_whereDeclared (unew)))
9091                 {
9092                   uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9093                 }
9094             }
9095           
9096           uentry_setConstantValue (unew, multiVal_copy (oldval));
9097         }
9098       else
9099         {
9100           ;
9101         }
9102     }
9103   else
9104     {
9105       uentry_setConstantValue (old, multiVal_copy (newval));
9106     }
9107 }
9108
9109 static void 
9110 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old, 
9111                          /*@notnull@*/ uentry unew, bool mustConform,
9112                          bool completeConform)
9113 {
9114   bool typeError = FALSE;
9115   bool fcnConformance = FALSE;
9116
9117   if (!ekind_equal (unew->ukind, old->ukind))
9118     {
9119       /*
9120       ** okay, only if one is a function and the other is
9121       ** a variable of type function.
9122       */
9123
9124       if (unew->ukind == KENUMCONST
9125           && old->ukind == KCONST)
9126         {
9127           old->ukind = KENUMCONST;
9128           goto nokinderror;
9129         }
9130
9131       if (unew->ukind == KFCN 
9132           && old->ukind == KCONST
9133           && ctype_isUnknown (old->utype))
9134         {
9135           /*
9136           ** When a function is defined with an unparam macro
9137           */
9138
9139           uentry_updateInto (old, unew);
9140           return;
9141         }
9142
9143       if (uentry_isExpandedMacro (old) 
9144           && uentry_isEitherConstant (unew))
9145         {
9146           uentry_updateInto (old, unew);
9147           return;
9148         }
9149
9150       if (uentry_isEndIter (unew))
9151         {
9152           if (ctype_isUnknown (old->utype))
9153             {
9154               if (!uentry_isSpecified (old)
9155                   && uentry_isCodeDefined (unew))
9156                 {
9157                   if (!fileloc_withinLines (uentry_whereDefined (old),
9158                                             uentry_whereDeclared (unew), 2))
9159                     { /* bogus!  will give errors if there is too much whitespace */
9160                       voptgenerror
9161                         (FLG_SYNTAX,
9162                          message
9163                          ("Iterator finalized name %q does not match name in "
9164                           "previous iter declaration (should be end_%q).  This iter "
9165                           "is declared at %q", 
9166                           uentry_getName (unew),
9167                           uentry_getName (old),
9168                           fileloc_unparse (uentry_whereDefined (old))),
9169                          uentry_whereDeclared (old));
9170                     }
9171                 }
9172
9173               uentry_updateInto (old, unew);
9174               return;
9175             }
9176           else
9177             {
9178               KindConformanceError (old, unew, mustConform);
9179             }
9180         }
9181
9182       if (uentry_isFunction (unew))
9183         {
9184           if (uentry_isVariable (old))
9185             {
9186               if (!ctype_isUnknown (old->utype))
9187                 {
9188                   if (ctype_isFunction (old->utype))
9189                     {
9190                       uentry_makeVarFunction (old);
9191                       checkFunctionConformance (old, unew, mustConform,
9192                                                 completeConform);
9193                       fcnConformance = TRUE;
9194                     }
9195                   else
9196                     {
9197                       KindConformanceError (old, unew, mustConform);
9198                     }
9199                 }
9200               else
9201                 {
9202                   if (uentry_isExpandedMacro (old))
9203                     {
9204                       if (fileloc_isUndefined (unew->whereDefined))
9205                         {
9206                           unew->whereDefined = fileloc_update (unew->whereDefined, 
9207                                                               old->whereDefined);
9208                         }
9209
9210                       uentry_updateInto (old, unew);
9211                       old->used = unew->used = TRUE;
9212                       return;
9213                     }
9214                   else
9215                     {
9216                       /* undeclared identifier */
9217                       old->utype = unew->utype;
9218                       uentry_makeVarFunction (old);
9219                       checkFunctionConformance (old, unew, FALSE, FALSE);
9220                       fcnConformance = TRUE;
9221                     }
9222                 }
9223             }
9224           else
9225             {
9226               KindConformanceError (old, unew, mustConform);
9227             }
9228         }
9229       else if (uentry_isFunction (old) && uentry_isVariable (unew))
9230         {
9231           if (!ctype_isUnknown (unew->utype))
9232             {
9233               if (ctype_isFunction (unew->utype))
9234                 {
9235                   uentry_makeVarFunction (unew);
9236                   checkFunctionConformance (old, unew, mustConform, completeConform);
9237                   fcnConformance = TRUE;
9238                 }
9239               else
9240                 {
9241                   KindConformanceError (old, unew, mustConform);
9242                 }
9243             }
9244           else
9245             {
9246               KindConformanceError (old, unew, mustConform);
9247             }
9248         }
9249       else
9250         {
9251           KindConformanceError (old, unew, mustConform);
9252         }
9253     }
9254   else
9255     {
9256       /*
9257       ** check parameter lists for functions 
9258       ** (before type errors, to get better messages
9259       */
9260
9261       if (uentry_isFunction (old))
9262         {
9263           checkFunctionConformance (old, unew, mustConform, completeConform);
9264           fcnConformance = TRUE;
9265         }
9266       else 
9267         {
9268           if (!ctype_isUndefined (old->utype))
9269             {
9270               typeError = checkTypeConformance (old, unew, mustConform);
9271             }
9272         }
9273     }
9274
9275  nokinderror:
9276
9277   if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9278     {
9279       uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9280     }
9281
9282   if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9283     {
9284       DPRINTF (("Check datatype: %s / %s",
9285                 uentry_unparseFull (old),
9286                 uentry_unparseFull (unew)));
9287
9288       uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9289     }
9290
9291   if (uentry_isVariable (old) && uentry_isVariable (unew))
9292     {
9293       if (!typeError && 
9294           !ctype_matchDef (old->utype, unew->utype))
9295         {
9296           if (optgenerror 
9297               (FLG_INCONDEFS,
9298                message
9299                ("Variable %q %s with inconsistent type (arrays and pointers are "
9300                 "not identical in variable declarations): %t",
9301                 uentry_getName (unew), 
9302                 uentry_reDefDecl (old, unew),
9303                 unew->utype),
9304                uentry_whereDeclared (unew)))
9305             {
9306               uentry_showWhereLast (old);
9307               
9308               /*
9309               ** Avoid repeated errors.
9310               */
9311
9312               if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9313                 {
9314                   old->whereDefined = fileloc_update (old->whereDefined,
9315                                                       fileloc_undefined);
9316                 }
9317
9318               typeError = TRUE;
9319             }
9320         }
9321
9322       checkVarConformance (old, unew, mustConform, completeConform);
9323     }
9324
9325   if (fcnConformance)
9326     {
9327       /* old->utype = unew->utype; */
9328     }
9329   else
9330     {
9331       if (ctype_isConj (old->utype))
9332         {
9333           if (ctype_isConj (unew->utype))
9334             {
9335               if (!ctype_sameAltTypes (old->utype, unew->utype))
9336                 {
9337                   if (optgenerror 
9338                       (FLG_INCONDEFS,
9339                        message ("%s %q inconsistently %rdeclared with "
9340                                 "alternate types %s "
9341                                 "(types match, but alternates are not identical, "
9342                                 "so checking may not be correct)",
9343                                 ekind_capName (uentry_getKind (old)),
9344                                 uentry_getName (unew),
9345                                 uentry_isDeclared (old),
9346                                 ctype_unparse (unew->utype)),
9347                        uentry_whereDeclared (unew)))
9348                     {
9349                       uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9350                     }
9351                   else
9352                     {
9353                       old->utype = unew->utype;
9354                     }
9355                 }
9356             }
9357         }
9358       else
9359         {
9360           if (ctype_isUnknown (old->utype))
9361             {
9362               old->utype = unew->utype;
9363             }
9364         }
9365     }  
9366
9367   if (unew->ukind == old->ukind) 
9368     {
9369       sfree (unew->info);
9370       unew->info = uinfo_copy (old->info, old->ukind);
9371     }
9372
9373   sRef_storeState (old->sref);
9374   sRef_storeState (unew->sref);
9375 }
9376
9377 static void uentry_mergeConstraints (uentry spec, uentry def)
9378 {
9379   if (uentry_isFunction (def))
9380     {
9381       DPRINTF (("Here: %s / %s",
9382                 uentry_unparseFull (spec),
9383                 uentry_unparseFull (def)));
9384       /* evans 2001-07-21 */
9385       llassert (uentry_isFunction (spec));
9386
9387       if (functionConstraint_isDefined (def->info->fcn->preconditions))
9388         {
9389           if (fileloc_isXHFile (uentry_whereLast (def)))
9390             {
9391               llassert (uentry_isFunction (spec));
9392               spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9393                                                                            def->info->fcn->preconditions);
9394             }
9395           else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9396             {
9397               ;
9398             }
9399           else
9400             {
9401               /* Check if the constraints are identical */
9402
9403               if (optgenerror 
9404                   (FLG_INCONDEFS,
9405                    message
9406                    ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9407                     uentry_getName (spec),
9408                     functionConstraint_unparse (spec->info->fcn->preconditions)),
9409                    uentry_whereLast (def)))
9410                 {
9411                   uentry_showWhereSpecified (spec);
9412                 }
9413
9414               functionConstraint_free (spec->info->fcn->preconditions);
9415               spec->info->fcn->preconditions = def->info->fcn->preconditions;
9416             }
9417           
9418           def->info->fcn->preconditions = functionConstraint_undefined;
9419         }
9420
9421       if (functionConstraint_isDefined (def->info->fcn->postconditions))
9422         {
9423           if (fileloc_isXHFile (uentry_whereLast (def)))
9424             {
9425               llassert (uentry_isFunction (spec));
9426               DPRINTF (("Post: %s /++/ %s",
9427                         functionConstraint_unparse (spec->info->fcn->postconditions),
9428                         functionConstraint_unparse (def->info->fcn->postconditions)));
9429               spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9430                                                                             def->info->fcn->postconditions);
9431               def->info->fcn->postconditions = functionConstraint_undefined;
9432               DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9433             }
9434           else
9435             {
9436               if (optgenerror 
9437                   (FLG_INCONDEFS,
9438                    message
9439                    ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9440                     uentry_getName (spec),
9441                     functionConstraint_unparse (spec->info->fcn->postconditions)),
9442                    uentry_whereLast (def)))
9443                 {
9444                   uentry_showWhereSpecified (spec);
9445                 }
9446               
9447               functionConstraint_free (spec->info->fcn->postconditions);
9448               spec->info->fcn->postconditions = def->info->fcn->postconditions;
9449               def->info->fcn->postconditions = functionConstraint_undefined;
9450             }
9451         }
9452     }
9453 }
9454
9455 /*
9456 ** modifies spec to reflect def, reports any inconsistencies
9457 */
9458
9459 void
9460 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9461 {
9462   llassert (uentry_isValid (spec));
9463   llassert (uentry_isValid (def));
9464   llassert (cstring_equal (spec->uname, def->uname));
9465
9466   if (uentry_isFunction (def))
9467     {
9468       if (uentry_isConstant (spec))
9469         {
9470           llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9471           uentry_makeConstantFunction (spec);
9472         }
9473       else
9474         {
9475           uentry_convertVarFunction (spec);
9476         }
9477
9478       llassert (uentry_isFunction (spec));
9479     }
9480   
9481   DPRINTF (("Merge entries: %s / %s",
9482             uentry_unparseFull (spec),
9483             uentry_unparseFull (def)));
9484
9485   uentry_mergeConstraints (spec, def);
9486
9487   uentry_checkConformance (spec, def, TRUE, 
9488                            context_getFlag (FLG_NEEDSPEC));
9489
9490   DPRINTF (("Merge entries after conform: %s / %s",
9491             uentry_unparseFull (spec),
9492             uentry_unparseFull (def)));
9493
9494   /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9495
9496   /*
9497   ** okay, declarations conform.  Propagate extra information.
9498   */
9499
9500   uentry_setDefined (spec, uentry_whereDefined (def));
9501   uentry_setDeclared (spec, uentry_whereDeclared (def));
9502
9503   if (uentry_isStatic (def))
9504     {
9505       if (optgenerror 
9506           (FLG_INCONDEFS,
9507            message ("%s %q specified, but declared as static",
9508                     ekind_capName (def->ukind),
9509                     uentry_getName (def)),
9510            uentry_whereDeclared (def)))
9511         {
9512           uentry_showWhereSpecified (spec);
9513         }
9514     }
9515   else 
9516     {
9517       spec->storageclass = def->storageclass;
9518     }
9519
9520   sRef_storeState (spec->sref);
9521
9522   spec->used = def->used || spec->used;
9523   spec->hasNameError |= def->hasNameError;
9524
9525   uentry_free (def);
9526
9527   if (!spec->hasNameError)
9528     {
9529       uentry_checkName (spec);
9530     }
9531   else
9532     {
9533       ;
9534     }
9535 }
9536
9537 /*
9538 ** Can't generate function redeclaration errors when the 
9539 ** entries are merged, since we don't yet know if its the
9540 ** definition of the function.
9541 */
9542
9543 void
9544 uentry_clearDecl (void)
9545 {
9546   posRedeclared = uentry_undefined;
9547   fileloc_free (posLoc);
9548   posLoc = fileloc_undefined;
9549 }
9550
9551 void
9552 uentry_checkDecl (void)
9553 {
9554   if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9555     {
9556       llassert (fileloc_isDefined (posLoc));
9557
9558       if (uentry_isCodeDefined (posRedeclared))
9559         {
9560           if (optgenerror (FLG_REDECL,
9561                            message ("%s %q declared after definition", 
9562                                     ekind_capName (posRedeclared->ukind),
9563                                     uentry_getName (posRedeclared)),
9564                            posLoc))
9565             {
9566               llgenindentmsg (message ("Definition of %q", 
9567                                        uentry_getName (posRedeclared)),
9568                               posRedeclared->whereDeclared);
9569             }
9570         }
9571       else
9572         {
9573           if (optgenerror (FLG_REDECL,
9574                            message ("%s %q declared more than once", 
9575                                     ekind_capName (posRedeclared->ukind),
9576                                     uentry_getName (posRedeclared)),
9577                            posLoc))
9578             {
9579               llgenindentmsg (message ("Previous declaration of %q", 
9580                                        uentry_getName (posRedeclared)),
9581                               posRedeclared->whereDeclared);
9582             }
9583         }
9584     }
9585
9586   fileloc_free (posLoc);
9587   posLoc = fileloc_undefined;
9588   posRedeclared = uentry_undefined;
9589 }
9590
9591 /*
9592 ** Redefinition of old as unew.
9593 ** modifies old to reflect unew, reports any inconsistencies
9594 */
9595
9596 void
9597 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9598 {
9599   fileloc olddef = uentry_whereDeclared (old); 
9600   fileloc unewdef = uentry_whereDeclared (unew);
9601   bool mustConform;
9602   bool wasForward;
9603
9604   DPRINTF (("uentry merge: %s / %s",
9605             uentry_unparseFull (old),
9606             uentry_unparseFull (unew)));
9607  
9608   wasForward = 
9609     fileloc_isUndefined (olddef) 
9610     && fileloc_isDefined (uentry_whereDefined (old)) 
9611     && !uentry_isExpandedMacro (old);
9612   
9613   if (!context_getFlag (FLG_INCONDEFSLIB)
9614       && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9615     {
9616       mustConform = FALSE;
9617     }
9618   else
9619     {
9620       mustConform = TRUE;
9621     }
9622   
9623   llassert (uentry_isValid (old));
9624   llassert (uentry_isValid (unew));
9625   llassert (cstring_equal (old->uname, unew->uname));
9626
9627   if (uentry_isFunction (unew) && !uentry_isFunction (old))
9628     {
9629       if (uentry_isConstant (old))
9630         {
9631           llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9632           uentry_makeConstantFunction (old);
9633         }
9634       else
9635         {
9636           uentry_convertVarFunction (old);
9637         }
9638
9639       if (!uentry_isFunction (old))
9640         {
9641           if (optgenerror 
9642               (FLG_INCONDEFS,
9643                message ("%s %q declared as function, but previously declared as %s",
9644                         ekind_capName (unew->ukind),
9645                         uentry_getName (unew),
9646                         ekind_unparseLong (old->ukind)),
9647                uentry_whereDeclared (unew)))
9648             {
9649               uentry_showWhereLast (old);
9650             }
9651
9652           uentry_convertIntoFunction (old);
9653           return;
9654         }
9655     }
9656
9657   DPRINTF (("uentry merge: %s / %s",
9658             uentry_unparseFull (old),
9659             uentry_unparseFull (unew)));
9660
9661   if (uentry_isExtern (unew))
9662     {
9663       uentry_setUsed (old, unewdef);
9664     }
9665
9666   /*
9667   ** should check old one was extern!
9668   */
9669
9670   if (uentry_isStatic (old))
9671     {
9672       if (!(uentry_isStatic (unew)))
9673         {
9674           if (optgenerror 
9675               (FLG_SHADOW,
9676                message ("%s %q shadows static declaration",
9677                         ekind_capName (unew->ukind),
9678                         uentry_getName (unew)),
9679                unewdef))
9680             {
9681               uentry_showWhereLast (old);
9682             }
9683         }
9684       else
9685         {
9686           uentry_setDeclDef (old, unewdef);
9687         }
9688     }
9689   else if (uentry_isStatic (unew))
9690     {
9691       uentry_setDeclDef (old, unewdef);
9692     }
9693   else if (uentry_isExtern (old))
9694     {
9695       uentry_setDeclared (old, unewdef);
9696     }
9697   else
9698     {
9699       if (!uentry_isExtern (unew) 
9700           && !uentry_isForward (old)
9701           && !fileloc_equal (olddef, unewdef)
9702           && !fileloc_isUndefined (olddef)
9703           && !fileloc_isUndefined (unewdef)
9704           && !fileloc_isBuiltin (olddef)
9705           && !fileloc_isBuiltin (unewdef)
9706           && !uentry_isYield (old)
9707           && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9708         {
9709           if (uentry_isVariable (old) || uentry_isVariable (unew))
9710             {
9711               ; /* will report redeclaration error later */
9712             }
9713           else
9714             {
9715               if (fileloc_isDefined (uentry_whereDefined (old)))
9716                 {
9717                   if (optgenerror
9718                       (FLG_REDEF,
9719                        message ("%s %q defined more than once", 
9720                                 ekind_capName (unew->ukind),
9721                                 uentry_getName (unew)),
9722                        uentry_whereLast (unew)))
9723                     {
9724                       llgenindentmsg
9725                         (message ("Previous definition of %q", 
9726                                   uentry_getName (old)),
9727                          uentry_whereLast (old));
9728                     }
9729                   /*
9730                   if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9731                     {
9732                       uentry_updateInto (old, unew);
9733                       old->sref = sRef_saveCopy (old->sref);
9734                     }
9735                     */
9736                 }
9737             }
9738         }
9739       else
9740         {
9741           if (fileloc_isLib (olddef)
9742               || fileloc_isUndefined (olddef)
9743               || fileloc_isImport (olddef))
9744             {
9745               if (uentry_isExtern (unew)) 
9746                 {
9747                   if (uentry_isExtern (old)
9748                       || (fileloc_isDefined (uentry_whereDeclared (old))
9749                           && (!fileloc_equal (uentry_whereDeclared (old),
9750                                               uentry_whereDefined (old)))))
9751                     {
9752                       if (optgenerror
9753                           (FLG_REDECL,
9754                            message ("%s %q declared more than once", 
9755                                     ekind_capName (unew->ukind),
9756                                     uentry_getName (unew)),
9757                            unew->whereDeclared))
9758                         {
9759                           llgenindentmsg
9760                             (message ("Previous declaration of %q", 
9761                                       uentry_getName (old)),
9762                              old->whereDeclared);
9763                         }
9764                     }
9765                   
9766                   uentry_setExtern (old);
9767                 }
9768               else
9769                 {
9770                   uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9771                 }
9772             }
9773         }
9774     }
9775
9776   DPRINTF (("uentry merge: %s / %s",
9777             uentry_unparseFull (old),
9778             uentry_unparseFull (unew)));
9779
9780   uentry_mergeConstraints (old, unew);
9781   DPRINTF (("uentry merge: %s / %s",
9782             uentry_unparseFull (old),
9783             uentry_unparseFull (unew)));
9784
9785   uentry_checkConformance (old, unew, mustConform, FALSE);
9786   DPRINTF (("uentry merge: %s / %s",
9787             uentry_unparseFull (old),
9788             uentry_unparseFull (unew)));
9789
9790   old->used = old->used || unew->used;
9791   old->uses = filelocList_append (old->uses, unew->uses);
9792   unew->uses = filelocList_undefined; 
9793
9794   sRef_storeState (old->sref); 
9795   sRef_storeState (unew->sref);
9796
9797   if (wasForward)
9798     {
9799       old->whereDefined = fileloc_update (old->whereDefined,
9800                                           fileloc_undefined);
9801     }
9802
9803   DPRINTF (("here: %s", uentry_unparseFull (old)));
9804
9805   /*
9806   ** No redeclaration errors for functions here, since we
9807   ** don't know if this is the definition of the function.
9808   */
9809
9810   if (fileloc_isUser (old->whereDeclared)
9811       && fileloc_isUser (unew->whereDeclared)
9812       && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9813       && !fileloc_isDefined (unew->whereDefined))
9814     {
9815       if (uentry_isFunction (old))
9816         {
9817           /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9818           posLoc = fileloc_update (posLoc, unew->whereDeclared);
9819         }
9820       else
9821         {
9822           if (optgenerror (FLG_REDECL,
9823                            message ("%s %q declared more than once", 
9824                                     ekind_capName (unew->ukind),
9825                                     uentry_getName (unew)),
9826                            unew->whereDeclared))
9827             {
9828               llgenindentmsg (message ("Previous declaration of %q", 
9829                                        uentry_getName (old)),
9830                               old->whereDeclared);
9831             }
9832         }
9833     }
9834
9835   if (fileloc_isUndefined (old->whereDefined))
9836     {
9837       old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9838     }
9839   else
9840     {
9841       if (!context_processingMacros ()
9842           && fileloc_isUser (old->whereDefined) 
9843           && fileloc_isUser (unew->whereDefined)
9844           && !fileloc_equal (old->whereDefined, unew->whereDefined))
9845         {
9846           if (uentry_isVariable (unew) || uentry_isFunction (unew))
9847             {
9848               if (uentry_isVariable (unew) 
9849                   && uentry_isExtern (unew))
9850                 {
9851                   if (optgenerror (FLG_REDECL,
9852                                    message ("%s %q declared after definition", 
9853                                             ekind_capName (unew->ukind),
9854                                             uentry_getName (unew)),
9855                                    unew->whereDeclared))
9856                     {
9857                       llgenindentmsg (message ("Definition of %q", 
9858                                                uentry_getName (old)),
9859                                       old->whereDefined);
9860                     }
9861                 }
9862               else
9863                 {
9864                   if (optgenerror (FLG_REDEF,
9865                                    message ("%s %q redefined", 
9866                                             ekind_capName (unew->ukind),
9867                                             uentry_getName (unew)),
9868                                    unew->whereDefined))
9869                     {
9870                       llgenindentmsg (message ("Previous definition of %q", 
9871                                                uentry_getName (old)),
9872                                       old->whereDefined);
9873                     }
9874                 }
9875             }
9876         }
9877     }
9878
9879   if (uentry_isExternal (unew))
9880     {
9881       old->whereDefined = fileloc_createExternal ();
9882     }
9883
9884   if (unew->hasNameError)
9885     {
9886       old->hasNameError = TRUE;
9887     }
9888
9889   uentry_free (unew);
9890
9891   if (!old->hasNameError)
9892     {
9893       uentry_checkName (old);
9894     }
9895
9896   DPRINTF (("After: %s", uentry_unparseFull (old)));
9897   llassert (!ctype_isUndefined (old->utype));
9898 }
9899
9900 void
9901 uentry_copyState (uentry res, uentry other)
9902 {
9903   llassert (uentry_isValid (res));
9904   llassert (uentry_isValid (other));
9905
9906   res->used = other->used;
9907
9908   res->info->var->kind = other->info->var->kind;
9909   res->info->var->defstate = other->info->var->defstate;
9910   res->info->var->nullstate = other->info->var->nullstate;
9911   res->info->var->checked = other->info->var->checked;
9912
9913   sRef_copyState (res->sref, other->sref);
9914 }
9915
9916 bool
9917 uentry_sameKind (uentry u1, uentry u2)
9918 {
9919   if (uentry_isValid (u1) && uentry_isValid (u2))
9920     {
9921       if (uentry_isVar (u1) && uentry_isVar (u2))
9922         {
9923           ctype c1 = u1->utype;
9924           ctype c2 = u2->utype;
9925
9926           if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9927
9928           /*
9929           ** both functions, or both not functions
9930           */
9931
9932           return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9933         }
9934       else
9935         {
9936           return ((u1->ukind == u2->ukind));
9937         }
9938     }
9939   
9940   return FALSE;
9941 }
9942    
9943 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9944 {
9945   ekind okind;
9946   llassert (uentry_isValid (unew));
9947   llassert (uentry_isValid (old));
9948
9949   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9950   okind = unew->ukind;
9951   unew->ukind = old->ukind;
9952   llassert (cstring_equal (unew->uname, old->uname));
9953   unew->utype = old->utype;
9954
9955   if (fileloc_isDefined (unew->whereSpecified) 
9956       && !fileloc_isDefined (old->whereSpecified))
9957     {
9958       ; /* Keep the old value */
9959     }
9960   else
9961     {
9962       fileloc_free (unew->whereSpecified);
9963       unew->whereSpecified = fileloc_copy (old->whereSpecified);
9964     }
9965
9966   if (fileloc_isDefined (unew->whereDefined) 
9967       && !fileloc_isDefined (old->whereDefined))
9968     {
9969       ; /* Keep the old value */
9970     }
9971   else
9972     {
9973       fileloc_free (unew->whereDefined); 
9974       unew->whereDefined = fileloc_copy (old->whereDefined);
9975     }
9976
9977   if (fileloc_isDefined (unew->whereDeclared) 
9978       && !fileloc_isDefined (old->whereDeclared))
9979     {
9980       ; /* Keep the old value */
9981     }
9982   else
9983     {
9984       fileloc_free (unew->whereDeclared); 
9985       unew->whereDeclared = fileloc_copy (old->whereDeclared);
9986     }
9987
9988   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9989
9990   unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9991   unew->used = old->used;
9992   unew->lset = FALSE;
9993   unew->isPrivate = old->isPrivate;
9994   unew->hasNameError = old->hasNameError;
9995   unew->uses = filelocList_append (unew->uses, old->uses);
9996   old->uses = filelocList_undefined;
9997
9998   unew->storageclass = old->storageclass;
9999   uinfo_free (unew->info, okind);
10000   unew->info = uinfo_copy (old->info, old->ukind);
10001 }
10002
10003 static uentry
10004 uentry_copyAux (uentry e, bool saveCopy)
10005 {
10006   
10007   if (uentry_isValid (e))
10008     {
10009       uentry enew = uentry_alloc ();
10010       DPRINTF (("copy: %s", uentry_unparseFull (e)));
10011       enew->ukind = e->ukind;
10012       enew->uname = cstring_copy (e->uname);
10013       enew->utype = e->utype;
10014       
10015       enew->whereSpecified = fileloc_copy (e->whereSpecified);
10016       enew->whereDefined = fileloc_copy (e->whereDefined);
10017       enew->whereDeclared = fileloc_copy (e->whereDeclared);
10018       
10019       if (saveCopy)
10020         {
10021           enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
10022         }
10023       else
10024         {
10025           enew->sref = sRef_copy (e->sref);
10026         }
10027       
10028       enew->used = e->used;
10029       enew->lset = FALSE;
10030       enew->isPrivate = e->isPrivate;
10031       enew->hasNameError = e->hasNameError;
10032       enew->uses = filelocList_undefined;
10033       
10034       enew->storageclass = e->storageclass;
10035       enew->info = uinfo_copy (e->info, e->ukind);
10036       enew->warn = warnClause_copy (e->warn);
10037
10038       DPRINTF (("Here we are..."));
10039       DPRINTF (("original: %s", uentry_unparseFull (e)));
10040       DPRINTF (("copy: %s", uentry_unparse (enew)));
10041       DPRINTF (("copy: %s", uentry_unparseFull (enew)));
10042       return enew;
10043     }
10044   else
10045     {
10046       return uentry_undefined;
10047     }
10048 }
10049
10050 uentry
10051 uentry_copy (uentry e)
10052 {
10053   return uentry_copyAux (e, TRUE);
10054 }
10055
10056 uentry
10057 uentry_copyNoSave (uentry e)
10058 {
10059   return uentry_copyAux (e, FALSE);
10060 }
10061
10062 void
10063 uentry_setState (uentry res, uentry other)
10064 {
10065   llassert (uentry_isValid (res));
10066   llassert (uentry_isValid (other));
10067
10068   llassert (res->ukind == other->ukind);
10069   llassert (res->ukind == KVAR);
10070
10071   res->sref = sRef_saveCopy (other->sref);
10072   res->used = other->used;
10073   filelocList_free (res->uses); 
10074   res->uses = other->uses; 
10075   other->uses = filelocList_undefined; 
10076   res->lset = other->lset;
10077 }
10078
10079 void
10080 uentry_mergeUses (uentry res, uentry other)
10081 {
10082   llassert (uentry_isValid (res));
10083   llassert (uentry_isValid (other));
10084
10085   res->used = other->used || res->used;
10086   res->lset = other->lset || res->lset;
10087   res->uses = filelocList_append (res->uses, other->uses);
10088   other->uses = filelocList_undefined;
10089 }
10090
10091
10092 /*
10093 ** This is a really ugly routine.
10094 **
10095 ** gack...fix this one day.
10096 */
10097
10098 /*
10099 ** flip == TRUE
10100 **   >> res is the false branch, other is the true branch (or continuation)
10101 ** flip == FALSE
10102 **   >> res is the true branch, other is the false branch (or continutation)
10103 **
10104 ** opt == TRUE if,
10105 **
10106 ** <other>
10107 ** if <res> ;
10108 **
10109 ** References not effected by res are propagated from other.
10110 */
10111
10112 static void
10113 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10114                   bool flip, clause cl, fileloc loc)
10115 {
10116   if (optgenerror 
10117       (FLG_BRANCHSTATE,
10118        message ("%s %q is %s %s, but %s %s.",
10119                 ekind_capName (res->ukind), uentry_getName (res),
10120                 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10121                 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10122        loc))
10123     {
10124       DPRINTF (("Here: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10125
10126       if (sRef_isDead (res->sref))
10127         {
10128           if (sRef_hasStateInfoLoc (res->sref)) {
10129             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10130             sRef_showStateInfo (res->sref);
10131           }
10132
10133           if (sRef_hasStateInfoLoc (other->sref)) {
10134             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10135             sRef_showStateInfo (other->sref);
10136           }
10137         }
10138       else if (sRef_isKept (res->sref))
10139         {
10140           if (sRef_hasAliasInfoLoc (res->sref)) {
10141             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10142             sRef_showAliasInfo (res->sref);
10143           }
10144
10145           if (sRef_hasAliasInfoLoc (other->sref)) {
10146             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10147             sRef_showAliasInfo (other->sref);
10148           }
10149         }
10150       else /* dependent */
10151         {
10152           if (sRef_hasAliasInfoLoc (res->sref)) {
10153             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10154             sRef_showAliasInfo (res->sref);
10155           }
10156
10157           if (sRef_hasAliasInfoLoc (other->sref)) {
10158             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10159             sRef_showAliasInfo (other->sref);
10160           }
10161         }
10162       
10163       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10164     }
10165 }
10166
10167 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10168 {
10169   alkind rk = sRef_getAliasKind (rs);
10170   alkind ok = sRef_getAliasKind (os);
10171
10172   if (alkind_isError (rk) || alkind_isError (ok))
10173     {
10174       return FALSE;
10175     }
10176   else
10177     {
10178       return ((sRef_isDead (rs)
10179                || (alkind_isKept (rk) && !alkind_isKept (ok))
10180                || (alkind_isDependent (rk) 
10181                    && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10182               && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10183     }
10184 }
10185
10186 static void
10187   branchStateAltError (/*@notnull@*/ uentry res,
10188                        /*@notnull@*/ uentry other, bool flip,
10189                        clause cl, fileloc loc)
10190 {
10191   if (optgenerror 
10192       (FLG_BRANCHSTATE,
10193        message ("%s %q is %s %s, but %s %s.",
10194                 ekind_capName (res->ukind), uentry_getName (res),
10195                 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10196                 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10197        loc))
10198     {
10199       if (sRef_isDead (other->sref))
10200         {
10201           if (sRef_hasStateInfoLoc (other->sref)) {
10202             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10203             sRef_showStateInfo (other->sref);
10204           }
10205
10206           if (sRef_hasStateInfoLoc (res->sref)) {
10207             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10208             sRef_showStateInfo (res->sref);
10209           }
10210         }
10211       else /* kept */
10212         {
10213           if (sRef_hasAliasInfoLoc (other->sref)) {
10214             llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10215             sRef_showAliasInfo (other->sref);
10216           }
10217
10218           if (sRef_hasAliasInfoLoc (res->sref)) {
10219             llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10220             sRef_showAliasInfo (res->sref);
10221           }
10222         }
10223       
10224       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10225       sRef_setDefinedComplete (res->sref, fileloc_undefined);
10226       
10227       sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10228       sRef_setDefinedComplete (other->sref, fileloc_undefined);
10229     }
10230 }
10231
10232 /*
10233 ** A reference is relevant for certain checks, only if it 
10234 ** is not definitely null on this path (but not declared
10235 ** to always be null.)
10236 */
10237
10238 static bool uentry_relevantReference (sRef sr, bool flip)
10239 {
10240   if (sRef_isKept (sr) || sRef_isDependent (sr))
10241     {
10242       return FALSE;
10243     }
10244   else
10245     {
10246       if (flip)
10247         {
10248           return !sRef_definitelyNullContext (sr);
10249         }
10250       else
10251         {
10252           return !sRef_definitelyNullAltContext (sr);
10253         }
10254     }
10255 }
10256
10257 static void
10258 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10259                          fileloc loc, bool mustReturn, bool flip, bool opt,
10260                          clause cl)    
10261 {
10262   sRef rs = res->sref;
10263   sRef os = other->sref;
10264
10265   DPRINTF (("Merge alias states: %s / %s",
10266             uentry_unparseFull (res),
10267             uentry_unparseFull (other)));
10268
10269   if (sRef_isValid (rs))
10270     {
10271       if (!mustReturn)
10272         {
10273           if (uentry_incompatibleMemoryStates (rs, os))
10274             {
10275               DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10276                         sRef_unparseFull (rs), sRef_unparseFull (os)));
10277
10278               if (sRef_isThroughArrayFetch (rs)
10279                   && !context_getFlag (FLG_STRICTBRANCHSTATE))
10280                 {
10281                   if (sRef_isKept (rs) || sRef_isKept (os))
10282                     {
10283                       sRef_maybeKill (rs, loc);
10284                     }
10285                   else if (sRef_isPossiblyDead (os))
10286                     {
10287                       sRef_maybeKill (rs, loc);
10288                     }
10289                   else
10290                     {
10291                       ;
10292                     }
10293                 }
10294               else
10295                 {
10296                   if (uentry_relevantReference (os, flip))
10297                     {
10298                       if (sRef_isLocalParamVar (rs) 
10299                           && (sRef_isLocalState (os) 
10300                               || sRef_isDependent (os)))
10301                         {
10302                           if (sRef_isDependent (rs))
10303                             {
10304                               sRef_setDependent (os, loc);
10305                             }
10306                           else
10307                             {
10308                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10309                             }
10310                         }
10311                       else 
10312                         {
10313                           branchStateError (res, other, !flip, cl, loc); /* evans 2002-12-15: changed flip to !flip */
10314                         }
10315                     }
10316                 }
10317               
10318               if (sRef_isKept (rs))
10319                 {
10320                   DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10321                   sRef_setKept (os, loc);
10322                 }
10323             }
10324           else
10325             {
10326               if (uentry_incompatibleMemoryStates (os, rs))
10327                 {
10328                   if (uentry_relevantReference (rs, !flip))
10329                     {
10330                       if (sRef_isLocalParamVar (rs) 
10331                           && (sRef_isDependent (rs)
10332                               || sRef_isLocalState (rs)))
10333                         {
10334                           if (sRef_isDependent (os))
10335                             {
10336                               sRef_setDependent (rs, loc);
10337                             }
10338                           else
10339                             {
10340                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10341                             }
10342                         }
10343                       else
10344                         {
10345                           if (sRef_isParam (os))
10346                             {
10347                               /* 
10348                               ** If the local variable associated
10349                               ** with the param has the correct state,
10350                               ** its okay.
10351                               ** (e.g., free (s); s = new(); ...
10352                               */
10353                               
10354                               uentry uvar = usymtab_lookupSafe (other->uname);
10355                               
10356                               if (uentry_isValid (uvar)
10357                                   && ((sRef_isDead (os) 
10358                                        && sRef_isOnly (uvar->sref))
10359                                       || (sRef_isDependent (os)
10360                                           && sRef_isOwned (uvar->sref))))
10361                                 {
10362                                   /* no error */
10363                                 }
10364                               else
10365                                 {
10366                                   branchStateAltError (res, other,
10367                                                        flip, cl, loc);
10368                                 }
10369                             }
10370                           else
10371                             {
10372                               DPRINTF (("Here: %s / %s",
10373                                         uentry_unparseFull (res),
10374                                         uentry_unparseFull (other)));
10375
10376                               branchStateAltError (res, other, 
10377                                                    flip, cl, loc);
10378                             }
10379                         }
10380                     }
10381                 }
10382               
10383               if (sRef_isKept (os))
10384                 {
10385                   sRef_setKept (rs, loc);
10386                 }
10387             }
10388           
10389           if (opt)
10390             {
10391               DPRINTF (("Merge opt..."));
10392               sRef_mergeOptState (rs, os, cl, loc);
10393               DPRINTF (("Done!"));
10394             }
10395           else
10396             {
10397               DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10398               sRef_mergeState (rs, os, cl, loc);
10399               DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10400             }
10401         }
10402       else
10403         {
10404           if (sRef_isModified (os))
10405             {
10406               sRef_setModified (rs);
10407             }
10408         }
10409     }
10410
10411   DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10412 }
10413
10414 static void
10415 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10416                          fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10417 {
10418   valueTable rvalues;
10419   valueTable ovalues;
10420
10421   DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10422   
10423   if (mustReturn)
10424     {
10425       return;
10426     }
10427   /* flip? */
10428
10429   rvalues = sRef_getValueTable (res->sref);
10430   ovalues = sRef_getValueTable (other->sref);
10431   
10432   if (valueTable_isUndefined (ovalues))
10433     {
10434       DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10435       ;
10436     }
10437   else if (valueTable_isUndefined (rvalues))
10438     {
10439       /*
10440       ** Copy values from other
10441       */
10442       
10443       /* ??? */
10444     }
10445   else
10446     {
10447       valueTable_elements (ovalues, fkey, fval) {
10448         stateValue tval;
10449         metaStateInfo minfo;
10450         stateCombinationTable sctable;
10451         cstring msg;
10452         int nval;
10453
10454         tval = valueTable_lookup (rvalues, fkey);
10455         
10456         DPRINTF (("Merge value: %s / %s X %s", fkey, 
10457                   stateValue_unparse (fval), stateValue_unparse (tval)));
10458
10459         minfo = context_lookupMetaStateInfo (fkey);
10460         llassert (stateValue_isDefined (tval));
10461         
10462         if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval)) 
10463           {
10464             DPRINTF (("Cannot find meta state for: %s", fkey));
10465             BADBRANCH;
10466           }
10467         else
10468           {
10469             llassert (metaStateInfo_isDefined (minfo));
10470
10471             if (stateValue_isError (fval)
10472                 || sRef_definitelyNullContext (res->sref))
10473               {
10474                 sRef_setMetaStateValueComplete (res->sref, 
10475                                                 fkey, stateValue_getValue (fval), 
10476                                                 stateValue_getLoc (fval));
10477                 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10478               }
10479             else if (stateValue_isError (tval)
10480                      || sRef_definitelyNullAltContext (other->sref))
10481               {
10482                 DPRINTF (("Other branch is definitely null!"));
10483               }
10484             else if (sRef_isStateUndefined (res->sref)
10485                      || sRef_isDead (res->sref))
10486               {
10487                 ; /* Combination state doesn't matter if it is undefined or dead */
10488               }
10489             else 
10490               {
10491                 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10492                           metaStateInfo_unparse (minfo),
10493                           stateValue_unparse (fval),
10494                           stateValue_unparse (tval)));
10495                 
10496                 DPRINTF (("state values: %d / %d",
10497                           stateValue_getValue (fval), stateValue_getValue (tval)));
10498                 
10499                 sctable = metaStateInfo_getMergeTable (minfo);
10500
10501                 DPRINTF (("Merge table: %s",
10502                           stateCombinationTable_unparse (sctable)));
10503                 
10504                 msg = cstring_undefined;
10505                 
10506                 nval = stateCombinationTable_lookup (sctable, 
10507                                                      stateValue_getValue (fval), 
10508                                                      stateValue_getValue (tval), 
10509                                                      &msg);
10510
10511                 DPRINTF (("nval: %d / %d / %d", nval,
10512                           stateValue_getValue (fval), stateValue_getValue (tval)));
10513
10514                 if (nval == stateValue_error)
10515                   {
10516                     if (uentry_isGlobalMarker (res))
10517                       {
10518                         if (optgenerror 
10519                             (FLG_STATEMERGE,
10520                              message
10521                              ("Control branches merge with incompatible global states (%s and %s)%q",
10522                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10523                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10524                               cstring_isDefined (msg) 
10525                               ? message (": %s", msg) : cstring_undefined),
10526                              loc))
10527                           {
10528                             sRef_showMetaStateInfo (res->sref, fkey);
10529                             sRef_showMetaStateInfo (other->sref, fkey);
10530                           }
10531                       }
10532                     else
10533                       {
10534                         if (optgenerror 
10535                             (FLG_STATEMERGE,
10536                              message
10537                              ("Control branches merge with incompatible states for %q (%s and %s)%q",
10538                               uentry_getName (res),
10539                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10540                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10541                               cstring_isDefined (msg) 
10542                               ? message (": %s", msg) : cstring_undefined),
10543                              loc))
10544                           {
10545                             sRef_showMetaStateInfo (res->sref, fkey);
10546                             sRef_showMetaStateInfo (other->sref, fkey);
10547                             DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10548                             DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10549                             DPRINTF (("Null: %s / %s",
10550                                       bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10551                                       bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10552
10553                           }
10554                       }
10555                   }
10556
10557                 if (nval == stateValue_getValue (fval)
10558                     && nval != stateValue_getValue (tval))
10559                   {
10560                     loc = stateValue_getLoc (fval);
10561                   }
10562                 else if (nval == stateValue_getValue (tval)
10563                          && nval != stateValue_getValue (fval))
10564                   {
10565                     loc = stateValue_getLoc (tval);
10566                   }
10567                 else
10568                   {
10569                     ;
10570                   }
10571
10572                 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10573                     && nval == stateValue_getValue (fval)
10574                     && nval == stateValue_getValue (tval))
10575                   {
10576                     ;
10577                   }
10578                 else
10579                   {
10580                     sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10581                   }
10582               }
10583           }
10584       } end_valueTable_elements ;
10585     } 
10586 }
10587
10588
10589 static void
10590 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10591                        /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10592                        bool flip, clause cl)
10593 {
10594   if (cl == DOWHILECLAUSE)
10595     {
10596       res->used = other->used || res->used;
10597       res->lset = other->lset || res->lset;
10598       res->uses = filelocList_append (res->uses, other->uses);
10599       other->uses = filelocList_undefined;
10600     }
10601   else
10602     {
10603       if (sRef_isMacroParamRef (res->sref)
10604           && !uentry_isSefParam (other)
10605           && !uentry_isSefParam (res))
10606         {
10607           bool hasError = FALSE;
10608           
10609           if (bool_equal (res->used, other->used))
10610             {
10611               res->used = other->used;
10612             }
10613           else
10614             {
10615               if (other->used && !flip)
10616                 {
10617                   hasError = 
10618                     optgenerror 
10619                     (FLG_MACROPARAMS,
10620                      message ("Macro parameter %q used in true clause, "
10621                               "but not in false clause",
10622                               uentry_getName (res)),
10623                      uentry_whereDeclared (res));
10624                 }
10625               else
10626                 {       
10627                   hasError = 
10628                     optgenerror 
10629                     (FLG_MACROPARAMS,
10630                      message ("Macro parameter %q used in false clause, "
10631                               "but not in true clause",
10632                               uentry_getName (res)),
10633                      uentry_whereDeclared (res));
10634                 }
10635               res->used = TRUE;
10636               
10637               if (hasError)
10638                 {
10639                   /* make it sef now, prevent more errors */
10640                   res->info->var->kind = VKREFSEFPARAM;
10641                 }
10642             }
10643         }
10644       else
10645         {
10646           res->used = other->used || res->used;
10647           res->lset = other->lset || res->lset;
10648           res->uses = filelocList_append (res->uses, other->uses);
10649           other->uses = filelocList_undefined;
10650         }
10651     }
10652 }
10653
10654 void
10655 uentry_mergeState (uentry res, uentry other, fileloc loc,
10656                    bool mustReturn, bool flip, bool opt,
10657                    clause cl)
10658 {
10659   llassert (uentry_isValid (res));
10660   llassert (uentry_isValid (other));
10661
10662   llassert (res->ukind == other->ukind);
10663   llassert (res->ukind == KVAR);
10664
10665   DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10666             uentry_unparseFull (other)));
10667   
10668   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10669   uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10670   uentry_mergeSetStates (res, other, loc, flip, cl);
10671
10672   DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10673 }
10674
10675 void uentry_setUsed (uentry e, fileloc loc)
10676 {
10677   static bool firstTime = TRUE;
10678   static bool showUses = FALSE;
10679   static bool exportLocal = FALSE;
10680
10681   DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10682
10683   if (firstTime)
10684     {
10685       /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10686
10687       showUses = context_getFlag (FLG_SHOWUSES); 
10688       exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10689
10690       firstTime = FALSE;
10691     }
10692
10693   if (uentry_isValid (e))
10694     {
10695       if (warnClause_isDefined (e->warn))
10696         {
10697           flagSpec flg = warnClause_getFlag (e->warn);
10698           cstring msg;
10699
10700           if (warnClause_hasMessage (e->warn))
10701             {
10702               msg = cstring_copy (warnClause_getMessage (e->warn));
10703             }
10704           else
10705             {
10706               msg = message ("Use of possibly dangerous %s",
10707                              uentry_ekindNameLC (e));
10708             }
10709
10710           vfsgenerror (flg, 
10711                        message ("%q: %q", msg, uentry_getName (e)),
10712                        loc);
10713         }
10714
10715       if (sRef_isMacroParamRef (e->sref))
10716         {
10717           if (uentry_isYield (e) || uentry_isSefParam (e))
10718             {
10719               ;
10720             }
10721           else 
10722             {
10723               if (context_inConditional ())
10724                 {
10725                   if (optgenerror
10726                       (FLG_MACROPARAMS,
10727                        message ("Macro parameter %q used in conditionally "
10728                                 "executed code (may or may not be "
10729                                 "evaluated exactly once)", 
10730                                 uentry_getName (e)),
10731                        loc))
10732                     {
10733                       e->info->var->kind = VKREFSEFPARAM;
10734                     }
10735                 }
10736               else
10737                 {
10738                   if ((e)->used)
10739                     {
10740                       if (optgenerror
10741                           (FLG_MACROPARAMS,
10742                            message ("Macro parameter %q used more than once", 
10743                                     uentry_getName (e)),
10744                            uentry_whereDeclared (e)))
10745                         {
10746                           e->info->var->kind = VKREFSEFPARAM;
10747                         }
10748                     }
10749                 }
10750             }
10751         }
10752       
10753       if (usymId_isValid (usymtab_directParamNo (e)))
10754         {
10755           uentry_setUsed (usymtab_getParam (usymId_toInt (usymtab_directParamNo (e))), loc);
10756         }
10757       
10758       e->used = TRUE;
10759
10760       if (!sRef_isLocalVar (e->sref))
10761         {
10762           if (showUses)
10763             {
10764               e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10765             }
10766           else 
10767             {
10768               if (exportLocal)
10769                 {
10770                   if (context_inMacro ())
10771                     {
10772                       e->uses = filelocList_addUndefined (e->uses);
10773                     }
10774                   else 
10775                     {
10776                       e->uses = filelocList_addDifferentFile
10777                         (e->uses, 
10778                          uentry_whereDeclared (e),
10779                          loc);
10780                     }
10781                 }
10782             }
10783         }
10784     }
10785 }
10786
10787 bool uentry_isReturned (uentry u)
10788 {
10789   return (uentry_isValid (u) && uentry_isVar (u) 
10790           && (u->info->var->kind == VKRETPARAM
10791               || u->info->var->kind == VKSEFRETPARAM));
10792 }
10793
10794 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
10795 {
10796   llassert (uentry_isRealFunction (u));
10797
10798   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10799     {
10800       stateClauseList clauses = uentry_getStateClauseList (u);
10801       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10802
10803       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10804       sRef_setAllocated (res, loc);
10805
10806       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10807                 stateClauseList_unparse (clauses)));
10808
10809       /*
10810       ** This should be in exprNode_reflectEnsuresClause
10811       */
10812
10813       stateClauseList_postElements (clauses, cl)
10814         {
10815           if (!stateClause_isGlobal (cl))
10816             {
10817               sRefSet refs = stateClause_getRefs (cl);
10818               sRefMod modf = stateClause_getEffectFunction (cl);
10819               
10820               sRefSet_elements (refs, el)
10821                 {
10822                   sRef base = sRef_getRootBase (el);
10823                   
10824                   if (sRef_isResult (base))
10825                     {
10826                       if (modf != NULL)
10827                         {
10828                           sRef sr = sRef_fixBase (el, res);
10829                           modf (sr, loc);
10830                         }
10831                     }
10832                   else
10833                     {
10834                       ;
10835                     }
10836                 } end_sRefSet_elements ;
10837             }
10838         } end_stateClauseList_postElements ;
10839         
10840       return res;
10841     }
10842   else
10843     {
10844       uentryList params;
10845       alkind ak;
10846       sRefSet prefs = sRefSet_new ();
10847       sRef res = sRef_undefined;
10848       int paramno = 0;
10849       
10850       params = uentry_getParams (u);
10851       
10852       uentryList_elements (params, current)
10853         {
10854           if (uentry_isReturned (current))
10855             {
10856               if (exprNodeList_size (args) >= paramno)
10857                 {
10858                   exprNode ecur = exprNodeList_nth (args, paramno);
10859                   sRef tref = exprNode_getSref (ecur);
10860                   
10861                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10862
10863                   if (sRef_isValid (tref))
10864                     {
10865                       sRef tcref = sRef_copy (tref);
10866                       
10867                       usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10868
10869                       if (sRef_isNew (tcref))
10870                         {
10871                           /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
10872                         }
10873
10874                       if (sRef_isDead (tcref))
10875                         {
10876                           sRef_setDefined (tcref, loc);
10877                           sRef_setOnly (tcref, loc);
10878                         }
10879                       
10880                       if (sRef_isRefCounted (tcref))
10881                         {
10882                           /* could be a new ref now (but only if its returned) */
10883                           sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
10884                         }
10885                       
10886                       sRef_makeSafe (tcref);
10887                       DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
10888                       prefs = sRefSet_insert (prefs, tcref);
10889                     }
10890                 }
10891             }
10892           
10893           paramno++;
10894         } end_uentryList_elements ;
10895       
10896       if (sRefSet_size (prefs) > 0)
10897         {
10898           nstate n = sRef_getNullState (u->sref);
10899           
10900           if (sRefSet_size (prefs) == 1)
10901             {
10902               res = sRefSet_choose (prefs);
10903             }
10904           else
10905             {
10906               /* should this ever happen? */
10907               res = sRefSet_mergeIntoOne (prefs);
10908             }
10909           
10910           if (nstate_isKnown (n))
10911             {
10912               sRef_setNullState (res, n, loc);
10913             }
10914         }
10915       else
10916         {
10917           if (ctype_isFunction (u->utype))
10918             {
10919               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10920               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10921             }
10922           else
10923             {
10924               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10925             }
10926           
10927           if (sRef_isRefCounted (res))
10928             {
10929               sRef_setAliasKind (res, AK_NEWREF, loc);
10930             }
10931         }
10932       
10933
10934       if (sRef_getNullState (res) == NS_ABSNULL)
10935         {
10936           ctype ct = ctype_realType (u->utype);
10937           
10938           if (ctype_isAbstract (ct))
10939             {
10940               sRef_setNotNull (res, loc);
10941             }
10942           else
10943             {
10944               if (ctype_isUser (ct))
10945                 {
10946                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10947                 }
10948               else
10949                 {
10950                   sRef_setNotNull (res, loc);
10951                 }
10952             }
10953         }
10954       
10955       if (sRef_isRefCounted (res))
10956         {
10957           sRef_setAliasKind (res, AK_NEWREF, loc);
10958         }
10959       else if (sRef_isKillRef (res))
10960         {
10961           sRef_setAliasKind (res, AK_REFCOUNTED, loc);
10962         }
10963       else
10964         {
10965           ;
10966         }
10967       
10968       ak = sRef_getAliasKind (res);
10969       
10970       if (alkind_isImplicit (ak))
10971         {
10972           sRef_setAliasKind (res, 
10973                              alkind_fixImplicit (ak),
10974                              loc);
10975         }
10976       
10977       sRefSet_free (prefs);
10978
10979       /*
10980       if (sRef_isOnly (res))
10981         {
10982           sRef_setFresh (res, loc);
10983         }
10984       */
10985
10986       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10987       return res;
10988     }
10989 }
10990
10991 static bool uentry_isRefCounted (uentry ue)
10992 {
10993   ctype ct = uentry_getType (ue);
10994
10995   if (ctype_isFunction (ct))
10996     {
10997       return (ctype_isRefCounted (ctype_getReturnType (ct)));
10998     }
10999   else
11000     {
11001       return (ctype_isRefCounted (ct));
11002     }
11003 }
11004
11005 /*
11006 ** old was declared yield in the specification.  
11007 ** new is declared in the iter implementation.
11008 */
11009
11010 void uentry_checkYieldParam (uentry old, uentry unew)
11011 {
11012   cstring name;
11013
11014   llassert (uentry_isVariable (old));
11015   llassert (uentry_isVariable (unew));
11016
11017   unew->info->var->kind = VKYIELDPARAM;
11018   (void) checkTypeConformance (old, unew, TRUE);
11019   checkVarConformance (old, unew, TRUE, FALSE);
11020
11021   /* get rid of param marker */
11022
11023   name = uentry_getName (unew);
11024   cstring_free (unew->uname);
11025   unew->uname = name;
11026   unew->info->var->kind = VKREFYIELDPARAM;
11027
11028   uentry_setUsed (old, fileloc_undefined);
11029   uentry_setUsed (unew, fileloc_undefined);
11030 }
11031
11032 /*@observer@*/ cstring
11033 uentry_ekindName (uentry ue)
11034 {
11035   if (uentry_isValid (ue))
11036     {
11037       switch (ue->ukind)
11038         {
11039         case KINVALID:
11040           return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11041         case KDATATYPE: 
11042           return cstring_makeLiteralTemp ("Datatype");
11043         case KENUMCONST:
11044           return cstring_makeLiteralTemp ("Enum member");
11045         case KCONST:  
11046           return cstring_makeLiteralTemp ("Constant");
11047         case KVAR:      
11048           if (uentry_isParam (ue))
11049             {
11050               return cstring_makeLiteralTemp ("Parameter");
11051             }
11052           else if (uentry_isExpandedMacro (ue))
11053             {
11054               return cstring_makeLiteralTemp ("Expanded macro");
11055             }
11056           else
11057             {
11058               return cstring_makeLiteralTemp ("Variable");
11059             }
11060         case KFCN:   
11061           return cstring_makeLiteralTemp ("Function");
11062         case KITER: 
11063           return cstring_makeLiteralTemp ("Iterator");
11064         case KENDITER:
11065           return cstring_makeLiteralTemp ("Iterator finalizer");
11066         case KSTRUCTTAG:
11067           return cstring_makeLiteralTemp ("Struct tag");
11068         case KUNIONTAG:
11069           return cstring_makeLiteralTemp ("Union tag");
11070         case KENUMTAG: 
11071           return cstring_makeLiteralTemp ("Enum tag");
11072         case KELIPSMARKER: 
11073           return cstring_makeLiteralTemp ("Optional parameters");
11074         }
11075     }
11076   else
11077     {
11078       return cstring_makeLiteralTemp ("<Undefined>");
11079     }
11080
11081   BADEXIT;
11082 }
11083
11084 /*@observer@*/ cstring
11085 uentry_ekindNameLC (uentry ue)
11086 {
11087   if (uentry_isValid (ue))
11088     {
11089       switch (ue->ukind)
11090         {
11091         case KINVALID:
11092           return cstring_makeLiteralTemp ("<error: invalid uentry>");
11093         case KDATATYPE: 
11094           return cstring_makeLiteralTemp ("datatype");
11095         case KENUMCONST:
11096           return cstring_makeLiteralTemp ("enum member");
11097         case KCONST:  
11098           return cstring_makeLiteralTemp ("constant");
11099         case KVAR:      
11100           if (uentry_isParam (ue))
11101             {
11102               return cstring_makeLiteralTemp ("parameter");
11103             }
11104           else if (uentry_isExpandedMacro (ue))
11105             {
11106               return cstring_makeLiteralTemp ("expanded macro");
11107             }
11108           else
11109             {
11110               return cstring_makeLiteralTemp ("variable");
11111             }
11112         case KFCN:   
11113           return cstring_makeLiteralTemp ("function");
11114         case KITER: 
11115           return cstring_makeLiteralTemp ("iterator");
11116         case KENDITER:
11117           return cstring_makeLiteralTemp ("iterator finalizer");
11118         case KSTRUCTTAG:
11119           return cstring_makeLiteralTemp ("struct tag");
11120         case KUNIONTAG:
11121           return cstring_makeLiteralTemp ("union tag");
11122         case KENUMTAG: 
11123           return cstring_makeLiteralTemp ("enum tag");
11124         case KELIPSMARKER: 
11125           return cstring_makeLiteralTemp ("optional parameters");
11126         }
11127     }
11128   else
11129     {
11130       return cstring_makeLiteralTemp ("<Undefined>");
11131     }
11132
11133   BADEXIT;
11134 }
11135
11136 void uentry_setHasNameError (uentry ue)
11137 {
11138   llassert (uentry_isValid (ue));
11139
11140   ue->hasNameError = TRUE;
11141 }
11142
11143 void uentry_checkName (uentry ue)
11144 {
11145   DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11146             uentry_observeRealName (ue),
11147             bool_unparse (uentry_isVisibleExternally (ue))));
11148   
11149   if (uentry_isValid (ue) 
11150       && !context_inXHFile ()
11151       && uentry_hasName (ue)
11152       && !uentry_isElipsisMarker (ue)
11153       && context_getFlag (FLG_NAMECHECKS)
11154       && !ue->hasNameError 
11155       && !uentry_isEndIter (ue)
11156       && !fileloc_isBuiltin (uentry_whereLast (ue))
11157       && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11158     {      
11159       DPRINTF (("Here..."));
11160
11161       if (uentry_isPriv (ue))
11162         {
11163           ; /* any checks here? */
11164         }
11165       else if (fileloc_isExternal (uentry_whereDefined (ue)))
11166         {
11167           ; /* no errors for externals */
11168         }
11169       else
11170         {
11171           int scope;
11172           
11173           if (uentry_isExpandedMacro (ue))
11174             {
11175               scope = globScope;
11176             }
11177           else
11178             {
11179               if (uentry_isExpandedMacro (ue))
11180                 {
11181                   scope = fileScope;
11182                 }
11183               else if (uentry_isVariable (ue))
11184                 {
11185                   sRef sr = uentry_getSref (ue);
11186
11187                   if (sRef_isValid (sr))
11188                     {
11189                       scope = sRef_getScope (sr);
11190                     }
11191                   else
11192                     {
11193                       scope = fileScope; 
11194                     }
11195                 }
11196               else if (uentry_isFunction (ue)
11197                        || uentry_isIter (ue)
11198                        || uentry_isEndIter (ue)
11199                        || uentry_isConstant (ue))
11200                 {
11201                   scope = uentry_isStatic (ue) ? fileScope : globScope;
11202                 }
11203               else /* datatypes, etc. must be global */
11204                 {
11205                   scope = globScope;
11206                 }
11207               
11208               usymtab_checkDistinctName (ue, scope);
11209             }
11210         
11211           if (context_getFlag (FLG_CPPNAMES)) 
11212             {
11213               checkCppName (ue);
11214             }
11215
11216           if (scope == globScope)
11217             {
11218               checkExternalName (ue);
11219             }
11220           else if (scope == fileScope)
11221             {
11222               checkFileScopeName (ue);
11223             }
11224           else 
11225             {
11226               checkLocalName (ue);
11227             }
11228
11229           checkPrefix (ue);
11230           checkAnsiName (ue);
11231         }
11232     }
11233 }
11234
11235 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11236 {
11237   uentry ue;
11238   fileloc tloc;
11239
11240   /*
11241   ** Can't but unrecognized ids in macros in global scope, because srefs will break! 
11242   */
11243
11244   if (!context_inMacro ())
11245     {
11246       sRef_setGlobalScopeSafe ();
11247     }
11248
11249   ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11250   uentry_setUsed (ue, loc);               
11251   
11252   tloc = fileloc_createExternal ();
11253   uentry_setDefined (ue, tloc);
11254   fileloc_free (tloc);
11255   uentry_setHasNameError (ue);
11256   
11257   if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldStyleScope()))
11258     {
11259       uentry_markOwned (ue);
11260     }
11261   else
11262     {
11263       ue = usymtab_supReturnFileEntry (ue);
11264     }
11265   
11266   if (!context_inMacro ())
11267     {
11268       sRef_clearGlobalScopeSafe ();
11269     }
11270
11271   return ue;
11272 }
11273
11274 uentry uentry_makeGlobalMarker ()
11275 {
11276   uentry ue;
11277   fileloc tloc;
11278
11279   llassert (sRef_inGlobalScope ());
11280   
11281   ue = uentry_makeVariableAux
11282     (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined, 
11283      sRef_makeGlobalMarker (),
11284      FALSE, VKNORMAL);
11285
11286   tloc = fileloc_createExternal ();
11287   uentry_setUsed (ue, tloc);              
11288   uentry_setDefined (ue, tloc);
11289   fileloc_free (tloc);
11290   uentry_setHasNameError (ue);  
11291
11292   return ue;
11293 }
11294
11295
11296 bool uentry_isGlobalMarker (uentry ue)
11297 {
11298   return (uentry_isValid (ue)
11299           && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11300 }
11301
11302 /* new start modifications */
11303
11304 /* start modifications */
11305 /*
11306 requires: p_e is defined, is a ptr/array variable 
11307 modifies: p_e
11308 effects: sets the state of the variable
11309 */
11310
11311
11312 void uentry_setPossiblyNullTerminatedState (uentry p_e)  
11313 {
11314   llassert (uentry_isValid (p_e));
11315
11316   if (p_e->info != NULL)
11317     {
11318       if (p_e->info->var != NULL) 
11319         {
11320           llassert (p_e->info->var->bufinfo != NULL);
11321           p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11322           sRef_setPossiblyNullTerminatedState (p_e->sref);
11323         }
11324     }
11325 }
11326
11327 /*
11328 requires: p_e is defined, is a ptr/array variable 
11329 modifies: p_e
11330 effects: sets the size of the buffer
11331 */
11332
11333 void uentry_setNullTerminatedState (uentry p_e)  {
11334   llassert (uentry_isValid (p_e));
11335
11336   if (p_e->info != NULL)
11337     {
11338       if (p_e->info->var != NULL)
11339         {
11340           llassert (p_e->info->var->bufinfo != NULL);
11341           p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11342           sRef_setNullTerminatedState (p_e->sref);
11343         }
11344     }
11345 }
11346
11347 /*
11348 requires: p_e is defined, is a ptr/array variable 
11349 modifies: p_e
11350 effects: sets the size of the buffer
11351 */
11352
11353 void uentry_setSize (uentry p_e, int size)  
11354 {
11355   if (uentry_isValid (p_e))
11356     {
11357       if (p_e->info != NULL) 
11358         {
11359           if (p_e->info->var != NULL) 
11360             {
11361               llassert (p_e->info->var->bufinfo != NULL);
11362               p_e->info->var->bufinfo->size = size;
11363               sRef_setSize (p_e->sref, size);
11364             }
11365         }
11366     }
11367 }
11368
11369 /*
11370 requires: p_e is defined, is a ptr/array variable 
11371 modifies: p_e
11372 effects: sets the length of the buffer
11373 */
11374
11375 void uentry_setLen (uentry p_e, int len)  
11376 {
11377   if (uentry_isValid (p_e)) 
11378     {
11379       if (p_e->info != NULL
11380           && p_e->info->var != NULL) 
11381         {
11382           llassert (p_e->info->var->bufinfo != NULL);
11383           p_e->info->var->bufinfo->len = len;
11384           sRef_setLen (p_e->sref, len);
11385         }
11386     }
11387 }
11388
11389 /*@=type*/
11390
11391 bool uentry_hasMetaStateEnsures (uentry e)
11392 {
11393   if (uentry_isValid (e) && uentry_isFunction (e))
11394     {
11395       return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11396     }
11397   else
11398     {
11399       return FALSE;
11400     }
11401 }
11402
11403 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11404 {
11405   llassert (uentry_isValid (e) && uentry_isFunction (e));
11406   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11407 }
11408
11409
11410 bool uentry_hasBufStateInfo (uentry ue)
11411 {
11412   llassert (uentry_isValid (ue));
11413   return (ue->info->var->bufinfo != NULL);
11414 }
11415
11416 bool uentry_isNullTerminated (uentry ue)
11417 {
11418   llassert (uentry_hasBufStateInfo (ue));
11419   llassert (ue->info->var->bufinfo != NULL);
11420   return ue->info->var->bufinfo->bufstate == BB_NULLTERMINATED;
11421 }
11422
11423 bool uentry_isPossiblyNullTerminated (uentry ue)
11424 {
11425   llassert (uentry_hasBufStateInfo (ue));
11426   llassert (ue->info->var->bufinfo != NULL);
11427   return (ue->info->var->bufinfo->bufstate == BB_POSSIBLYNULLTERMINATED);
11428 }
11429
11430 bool uentry_isNotNullTerminated (uentry ue)
11431 {
11432   llassert (uentry_hasBufStateInfo (ue));
11433   llassert (ue->info->var->bufinfo != NULL);
11434   return (ue->info->var->bufinfo->bufstate == BB_NOTNULLTERMINATED);
11435 }
11436
11437 # ifdef DEBUGSPLINT
11438
11439 /*
11440 ** For debugging only
11441 */
11442
11443 void uentry_checkValid (uentry ue)
11444 {
11445   if (uentry_isValid (ue))
11446     {
11447       sRef_checkCompletelyReasonable (ue->sref);
11448     }
11449 }
11450
11451 # endif
This page took 1.280703 seconds and 5 git commands to generate.