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