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