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