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