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