]> andersk Git - splint.git/blob - src/uentry.c
Fixed pre-processing bug reported by Adam Clarke. Moved marking point
[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) || uentry_isDatatype (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                     "%s with members { %q }",
7315                     uentry_getName (old), 
7316                     enumNameList_unparse (enew),
7317                     uentry_specOrDefName (old),
7318                     enumNameList_unparse (eold)),
7319            uentry_whereDeclared (unew)))
7320         {
7321           uentry_showWhereSpecified (old);
7322           old->utype = unew->utype;
7323         }
7324     }
7325 }
7326
7327 /*
7328 ** either oldCurrent or newCurrent may be undefined!
7329 */
7330
7331 static void
7332 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7333                 uentry unew, uentry newCurrent, ctype newType,
7334                 int paramno)
7335 {
7336   bool hasError = FALSE;
7337
7338   if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7339     {
7340       if (uentry_hasName (newCurrent))
7341         {
7342           hasError = optgenerror 
7343             (FLG_TYPE,
7344              message ("Parameter %d, %q, of function %q has inconsistent type: "
7345                       "declared %t, %s %t",
7346                       paramno + 1, uentry_getName (newCurrent), 
7347                       uentry_getName (unew),
7348                       newType, uentry_specOrDefName (old), oldType),
7349              uentry_whereDeclared (newCurrent));
7350         }
7351       else
7352         {
7353           hasError = optgenerror
7354             (FLG_TYPE,
7355              message ("Parameter %d of function %q has inconsistent type: "
7356                       "declared %t, %s %t",
7357                       paramno + 1, uentry_getName (unew),
7358                       newType, uentry_specOrDefName (old), oldType),
7359              uentry_whereDeclared (newCurrent));
7360
7361           DPRINTF (("type: %s / %s",
7362                     ctype_unparse (newType),
7363                     ctype_unparse (ctype_realType (newType))));
7364         }
7365     }
7366   else 
7367     {
7368       if (uentry_isDeclared (unew))
7369         {
7370           hasError = optgenerror 
7371             (FLG_TYPE,
7372              message ("Parameter %d of function %s has inconsistent type: "
7373                       "declared %t, %s %t",
7374                       paramno + 1, unew->uname, 
7375                       newType, uentry_specOrDefName (old), oldType),
7376              uentry_whereDeclared (unew));
7377         }
7378       else
7379         {
7380           hasError = optgenerror
7381             (FLG_TYPE,
7382              message ("Parameter %d of function %s has inconsistent type: "
7383                       "declared %t, %s %t",
7384                       paramno + 1, unew->uname, 
7385                       newType, uentry_specOrDefName (old), oldType),
7386              uentry_whereDeclared (unew));
7387         }
7388     }
7389   
7390   if (hasError)
7391     {
7392       DPRINTF (("Here: %s / %s",
7393                 uentry_unparseFull (oldCurrent),
7394                 uentry_unparseFull (newCurrent)));
7395
7396       if (!uentry_isUndefined (oldCurrent))
7397         {
7398           if (!uentry_isUndefined (newCurrent) 
7399               && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7400             {
7401               uentry_showWhereLast (oldCurrent);
7402             }
7403           else
7404             {
7405               uentry_showWhereLastPlain (old);
7406             }
7407           
7408           uentry_setType (oldCurrent, newType);
7409         }
7410       else
7411         {
7412           uentry_showWhereLastPlain (old);
7413         }
7414     }
7415 }
7416
7417 static void
7418 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7419 {
7420   if (optgenerror 
7421       (FLG_TYPE,
7422        message ("Function %s %rdeclared with %d arg%&, %s with %d",
7423                 unew->uname, 
7424                 uentry_isDeclared (old),
7425                 uentryList_size (uentry_getParams (unew)),
7426                 uentry_specOrDefName (old),
7427                 uentryList_size (uentry_getParams (old))),
7428        uentry_whereDeclared (unew)))
7429     {
7430       uentry_showWhereLastPlain (old);
7431     }
7432 }
7433
7434 static void
7435 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7436 {
7437   if (optgenerror
7438       (FLG_INCONDEFS,
7439        message ("Function %s inconsistently %rdeclared to return %t",
7440                 unew->uname,
7441                 uentry_isDeclared (old),
7442                 ctype_getReturnType (unew->utype)),
7443        uentry_whereDeclared (unew)))
7444     {
7445       uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7446     }
7447 }
7448
7449 static cstring paramStorageName (uentry ue)
7450 {
7451   return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7452 }
7453
7454 static cstring fcnErrName (uentry ue)
7455 {
7456   return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7457 }
7458
7459 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7460 {
7461   if (uentry_isVar (ue))
7462     {
7463       return (checkedName (ue->info->var->checked));
7464     }
7465   else
7466     {
7467       return (cstring_makeLiteralTemp ("<checked invalid>"));
7468     }
7469 }
7470
7471 static cstring checkedName (chkind checked)
7472 {
7473   switch (checked)
7474     {
7475     case CH_UNKNOWN:       return (cstring_makeLiteralTemp ("unknown"));
7476     case CH_UNCHECKED:     return (cstring_makeLiteralTemp ("unchecked"));
7477     case CH_CHECKED:       return (cstring_makeLiteralTemp ("checked"));
7478     case CH_CHECKMOD:      return (cstring_makeLiteralTemp ("checkmod"));
7479     case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7480     }
7481   BADEXIT;
7482 }
7483
7484 static
7485 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7486 {
7487   nstate oldState;
7488   nstate newState;
7489   
7490   if (uentry_isVar (unew))
7491     {
7492       llassert (uentry_isVar (old));
7493       
7494       oldState = old->info->var->nullstate;
7495       newState = unew->info->var->nullstate;
7496     }
7497   else
7498     {
7499       oldState = sRef_getNullState (old->sref);
7500       newState = sRef_getNullState (unew->sref);
7501     }
7502
7503   if (oldState == NS_ABSNULL)
7504     {
7505       if (uentry_isVar (old))
7506         {
7507           old->info->var->nullstate = newState;
7508         }
7509       
7510       sRef_mergeNullState (old->sref, newState);
7511     }
7512   else if (newState == NS_UNKNOWN)
7513     {
7514       if (completeConform && newState != oldState
7515           && uentry_isReallySpecified (old))
7516         {
7517           if (optgenerror 
7518               (FLG_NEEDSPEC,
7519                message ("%s %q specified as %s, but declared without %s qualifier",
7520                         ekind_capName (unew->ukind),
7521                         uentry_getName (unew),
7522                         nstate_unparse (oldState),
7523                         nstate_unparse (oldState)),
7524                uentry_whereDeclared (unew)))
7525             {
7526               uentry_showWhereSpecified (old);
7527             }
7528         }
7529       
7530       if (uentry_isVar (unew))
7531         {
7532           unew->info->var->nullstate = oldState;
7533         }
7534
7535       sRef_mergeNullState (unew->sref, oldState);
7536     }
7537   else if (newState == NS_POSNULL)
7538     {
7539       if (oldState == NS_MNOTNULL 
7540           && (ctype_isUA (unew->utype) 
7541               || (uentry_isFunction (unew)
7542                   && ctype_isUA (ctype_getReturnType (unew->utype)))))
7543         {
7544           if (uentry_isVar (unew))
7545             {
7546               unew->info->var->nullstate = oldState;
7547             }
7548
7549           sRef_mergeNullState (unew->sref, oldState);
7550         }
7551       else 
7552         {
7553           if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL 
7554               || oldState == NS_UNKNOWN)
7555             {
7556               if (mustConform)
7557                 {
7558                   if (optgenerror 
7559                       (FLG_INCONDEFS,
7560                        message 
7561                        ("%s %q inconsistently %rdeclared %s possibly null storage, "
7562                         "%s %q qualifier",
7563                         uentry_ekindName (unew),
7564                         uentry_getName (unew),
7565                         uentry_isDeclared (old),
7566                         fcnErrName (unew),
7567                         uentry_specOrDefName (old),
7568                         cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7569                        uentry_whereDeclared (unew)))
7570                     {
7571                       uentry_showWhereSpecified (old);
7572                     }
7573                 }
7574             }
7575           
7576           if (uentry_isVar (old))
7577             {
7578               old->info->var->nullstate = newState;
7579             }
7580
7581           sRef_mergeNullState (old->sref, newState);
7582         }
7583     }
7584   else if (newState == NS_MNOTNULL)
7585     {
7586       if (oldState != NS_MNOTNULL)
7587         {
7588           if (mustConform)
7589             {
7590               if (optgenerror 
7591                   (FLG_INCONDEFS,
7592                    message ("%s %q inconsistently %rdeclared %s notnull storage, "
7593                             "%s without notnull qualifier",
7594                             uentry_ekindName (unew),
7595                             uentry_getName (unew),
7596                             uentry_isDeclared (old),
7597                             fcnErrName (unew),
7598                             uentry_specOrDefName (old)),
7599                    uentry_whereDeclared (unew)))
7600                 {
7601                   uentry_showWhereSpecified (old);
7602                 }
7603             }
7604           
7605           if (uentry_isVar (old))
7606             {
7607               old->info->var->nullstate = newState;
7608             }
7609
7610           sRef_mergeNullState (old->sref, newState);
7611         }
7612     }
7613   else
7614     {
7615       if (uentry_isVar (unew)) 
7616         {
7617           unew->info->var->nullstate = oldState;
7618         }
7619
7620       sRef_mergeNullState (unew->sref, oldState);
7621     }
7622 }
7623
7624 static
7625 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7626                     bool mustConform, bool completeConform)
7627 {
7628   sstate oldState;
7629   sstate newState;
7630   bool vars = FALSE;
7631
7632   if (uentry_isVar (old) && uentry_isVar (unew))
7633     {
7634       oldState = old->info->var->defstate;
7635       newState = unew->info->var->defstate;
7636       vars = TRUE;
7637     }
7638   else
7639     {
7640       oldState = sRef_getDefState (old->sref);
7641       newState = sRef_getDefState (unew->sref);
7642     }
7643
7644   if (newState != oldState 
7645       && newState != SS_UNKNOWN 
7646       && newState != SS_DEFINED)
7647     {
7648       if (mustConform)
7649         {
7650           if (optgenerror 
7651               (FLG_INCONDEFS,
7652                message ("%s %q inconsistently %rdeclared %s %s %s, "
7653                         "%s %s %s %s",
7654                         uentry_ekindName (unew),
7655                         uentry_getName (unew),
7656                         uentry_isDeclared (old),
7657                         fcnErrName (unew),
7658                         sstate_unparse (newState),
7659                         paramStorageName (unew),
7660                         uentry_specOrDefName (old),
7661                         fcnErrName (unew),
7662                         sstate_unparse (oldState),
7663                         paramStorageName (unew)),
7664                uentry_whereDeclared (unew)))
7665             {
7666               uentry_showWhereSpecified (old);
7667             }
7668         }
7669
7670       if (vars) old->info->var->defstate = newState;
7671       sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7672     }
7673   else
7674     {
7675       if (completeConform
7676           && (newState != oldState) && (oldState != SS_DEFINED)
7677           && uentry_isReallySpecified (old))
7678         {
7679           if (optgenerror 
7680               (FLG_NEEDSPEC,
7681                message ("%s %q specified as %s, but declared without %s qualifier",
7682                         ekind_capName (unew->ukind),
7683                         uentry_getName (unew),
7684                         sstate_unparse (oldState),
7685                         sstate_unparse (oldState)),
7686                uentry_whereDeclared (unew)))
7687             {
7688               uentry_showWhereSpecified (old);
7689             }
7690         }
7691       
7692       if (vars) unew->info->var->defstate = oldState;
7693       sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7694     }
7695 }
7696
7697 static void 
7698   checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7699                    bool mustConform, bool completeConform)
7700 {
7701   alkind newKind;
7702   alkind oldKind;
7703
7704   oldKind = sRef_getAliasKind (old->sref);
7705   newKind = sRef_getAliasKind (unew->sref);
7706
7707   if (alkind_isImplicit (newKind) 
7708       || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7709     {
7710       if (completeConform && !alkind_equal (newKind, oldKind)
7711           && uentry_isReallySpecified (old))
7712         {
7713           if (optgenerror 
7714               (FLG_NEEDSPEC,
7715                message ("%s %q specified as %s, but declared without "
7716                         "explicit alias qualifier",
7717                         ekind_capName (unew->ukind),
7718                         uentry_getName (unew),
7719                         alkind_unparse (oldKind)),
7720                uentry_whereDeclared (unew)))
7721             {
7722               uentry_showWhereSpecified (old);
7723             }
7724         }
7725
7726       /*  
7727       ** This really shouldn't be necessary, but it is!
7728       ** Function params (?) use new here.
7729       */
7730
7731       sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7732       return;
7733     }
7734
7735   if (alkind_isKnown (newKind))
7736     {
7737       if (!alkind_equal (oldKind, newKind))
7738         {
7739           if (alkind_isKnown (oldKind))
7740             {
7741               if (mustConform && 
7742                   optgenerror 
7743                   (FLG_INCONDEFS,
7744                    message ("%s %q inconsistently %rdeclared %s %s storage, "
7745                             "%s as %s storage",
7746                             uentry_ekindName (unew),
7747                             uentry_getName (unew),
7748                             uentry_isDeclared (old),
7749                             fcnErrName (unew),
7750                             alkind_unparse (newKind),
7751                             uentry_specOrDefName (old),
7752                             alkind_unparse (oldKind)),
7753                    uentry_whereDeclared (unew)))
7754                 {
7755                   uentry_showWhereSpecified (old);
7756
7757                   DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7758                   DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7759                   sRef_setAliasKind (old->sref, AK_ERROR, 
7760                                      uentry_whereDeclared (unew));
7761                 }
7762               else
7763                 {
7764                   sRef_setAliasKind (old->sref, newKind, 
7765                                      uentry_whereDeclared (unew));
7766                 }
7767             }
7768           else
7769             {
7770               if (!(alkind_isImplicit (newKind)))
7771                 {
7772                   if (mustConform &&
7773                       !uentry_isFunction (unew) &&
7774                       optgenerror 
7775                       (FLG_INCONDEFS,
7776                        message ("%s %q inconsistently %rdeclared %s %s storage, "
7777                                 "implicitly %s as temp storage",
7778                                 uentry_ekindName (unew),
7779                                 uentry_getName (unew),
7780                                 uentry_isDeclared (old),
7781                                 fcnErrName (unew),
7782                                 alkind_unparse (newKind),
7783                                 uentry_specOrDefName (old)),
7784                        uentry_whereDeclared (unew)))
7785                     {
7786                       uentry_showWhereSpecified (old);
7787                       oldKind = AK_ERROR;
7788                     }
7789                   
7790                   sRef_setAliasKind (old->sref, newKind, 
7791                                      uentry_whereDeclared (unew));
7792                 }
7793               else /* newKind is temp or refcounted */
7794                 {
7795                   ;
7796                 }
7797             }
7798         }
7799     }
7800   else /* newKind unknown */
7801     {
7802       ;
7803     }
7804 }
7805
7806 static void 
7807   checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7808                 bool mustConform, bool completeConform)
7809 {
7810   exkind newKind;
7811   exkind oldKind;
7812   
7813   oldKind = sRef_getExKind (old->sref);
7814   newKind = sRef_getExKind (unew->sref);
7815
7816   if (exkind_isKnown (newKind))
7817     {
7818       if (oldKind != newKind)
7819         {
7820           if (exkind_isKnown (oldKind))
7821             {
7822               if (mustConform && 
7823                   optgenerror 
7824                   (FLG_INCONDEFS,
7825                    message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7826                             uentry_ekindName (unew),
7827                             uentry_getName (unew),
7828                             uentry_isDeclared (old),
7829                             fcnErrName (unew),
7830                             exkind_unparse (newKind),
7831                             uentry_specOrDefName (old),
7832                             exkind_unparse (oldKind)),
7833                    uentry_whereDeclared (unew)))
7834                 {
7835                   uentry_showWhereSpecified (old);
7836                 }
7837
7838               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7839             }
7840           else
7841             {
7842               if (mustConform &&
7843                   optgenerror 
7844                   (FLG_INCONDEFS,
7845                    message ("%s %q inconsistently %rdeclared %s %s, "
7846                             "implicitly %s without exposure qualifier",
7847                             uentry_ekindName (unew),
7848                             uentry_getName (unew),
7849                             uentry_isDeclared (old),
7850                             fcnErrName (unew),
7851                             exkind_unparse (newKind),
7852                             uentry_specOrDefName (old)),
7853                    uentry_whereDeclared (unew)))
7854                 {
7855                   uentry_showWhereSpecified (old);
7856                 }
7857
7858               sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7859             }
7860         }
7861     }
7862   else
7863     {
7864       if (completeConform && exkind_isKnown (oldKind)
7865           && uentry_isReallySpecified (old))
7866         {
7867           if (optgenerror 
7868               (FLG_NEEDSPEC,
7869                message ("%s %q specified as %s, but declared without "
7870                         "exposure qualifier",
7871                         ekind_capName (unew->ukind),
7872                         uentry_getName (unew),
7873                         exkind_unparse (oldKind)),
7874                uentry_whereDeclared (unew)))
7875             {
7876               uentry_showWhereSpecified (old);
7877             }
7878         }
7879
7880       /* yes, this is necessary! (if its a param) */
7881       sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7882     }
7883 }
7884
7885 static void 
7886 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
7887                 bool mustConform, /*@unused@*/ bool completeConform)
7888 {
7889   valueTable newvals = sRef_getValueTable (unew->sref);
7890
7891   if (valueTable_isDefined (newvals))
7892     {
7893       DPRINTF (("Check meta state: %s -> %s",
7894                 uentry_unparseFull (old),
7895                 uentry_unparseFull (unew)));
7896       
7897       DPRINTF (("Check meta state refs: %s -> %s",
7898                 sRef_unparseFull (old->sref),
7899                 sRef_unparseFull (unew->sref)));
7900       
7901       DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7902       
7903       /*
7904       ** Copy the new values into the old ref
7905       */
7906
7907       valueTable_elements (newvals, key, newval)
7908         {
7909           metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7910           stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7911             
7912           llassert (metaStateInfo_isDefined (msinfo));
7913
7914           if (stateValue_isUndefined (oldval))
7915             {
7916               sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7917             }
7918           else
7919             {
7920               if (stateValue_isError (oldval))
7921                 {
7922                   if (!stateValue_isError (newval))
7923                     {
7924                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7925                     }
7926                   else
7927                     {
7928                       ; /* No change necessary. */
7929                     }
7930                 }
7931               else
7932                 {
7933                   if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7934                     {
7935                       if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7936                         {
7937                           ;
7938                         }
7939                       else
7940                         {
7941                           if (!stateValue_isError (newval) 
7942                               && !stateValue_isImplicit (newval))
7943                             {
7944                               if (uentry_hasName (unew)
7945                                   || !sRef_isParam (uentry_getSref (unew)))
7946                                 {
7947                                   if (mustConform 
7948                                       && optgenerror 
7949                                       (FLG_INCONDEFS,
7950                                        message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7951                                                 uentry_ekindName (unew),
7952                                                 uentry_getName (unew),
7953                                                 uentry_isDeclared (old),
7954                                                 fcnErrName (unew),
7955                                                 stateValue_unparseValue (newval, msinfo),
7956                                                 uentry_specOrDefName (old),
7957                                                 stateValue_unparseValue (oldval, msinfo)),
7958                                        uentry_whereDeclared (unew)))
7959                                     {
7960                                       uentry_showWhereSpecified (old);
7961                                     }
7962                                 }
7963                               else
7964                                 {
7965                                   if (mustConform 
7966                                       && optgenerror 
7967                                       (FLG_INCONDEFS,
7968                                        message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7969                                                 uentry_ekindName (unew),
7970                                                 sRef_getParam (uentry_getSref (unew)),
7971                                                 uentry_isDeclared (old),
7972                                                 fcnErrName (unew),
7973                                                 stateValue_unparseValue (newval, msinfo),
7974                                                 uentry_specOrDefName (old),
7975                                                 stateValue_unparseValue (oldval, msinfo)),
7976                                        uentry_whereDeclared (unew)))
7977                                     {
7978                                       uentry_showWhereSpecified (old);
7979                                     }
7980                                 }
7981                             }
7982                         }
7983                       
7984                       DPRINTF (("Updating!"));
7985                       sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7986                     }
7987                   else
7988                     {
7989                       DPRINTF (("Values match"));
7990                     }
7991                 }
7992             }
7993         } end_valueTable_elements ;
7994     }
7995 }
7996
7997 static void
7998 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7999                               /*@notnull@*/ uentry unew,
8000                               bool mustConform, bool completeConform)
8001 {
8002   checkDefState (old, unew, mustConform, completeConform);
8003   checkNullState (old, unew, mustConform, completeConform);
8004   checkAliasState (old, unew, mustConform, completeConform);
8005   checkExpState (old, unew, mustConform, completeConform);
8006   checkMetaState (old, unew, mustConform, completeConform);
8007
8008   sRef_storeState (old->sref);
8009   sRef_storeState (unew->sref);
8010 }
8011
8012 static void
8013 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8014 {
8015   if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8016     {
8017       return;
8018     }
8019
8020   llassert (uentry_isVar (old));
8021   llassert (uentry_isVar (unew));
8022
8023   if (cstring_isEmpty (old->uname)) 
8024     {
8025       cstring_free (old->uname);
8026       old->uname = cstring_copy (unew->uname);
8027     }
8028
8029   if (unew->info->var->kind == VKRETPARAM
8030       || unew->info->var->kind == VKSEFRETPARAM)
8031     {
8032       if (old->info->var->kind != VKRETPARAM
8033           && old->info->var->kind != VKSEFRETPARAM)
8034         {
8035           if (optgenerror 
8036               (FLG_INCONDEFS,
8037                message ("Parameter %q inconsistently %rdeclared as "
8038                         "returned parameter",
8039                         uentry_getName (unew),
8040                         uentry_isDeclared (old)),
8041                uentry_whereDeclared (unew)))
8042             {
8043               uentry_showWhereSpecified (old);
8044               old->info->var->kind = unew->info->var->kind;
8045             }
8046         }
8047     }
8048
8049
8050   if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8051     {
8052       if (old->info->var->kind != VKSEFPARAM 
8053           && old->info->var->kind != VKSEFRETPARAM)
8054         {
8055           if (optgenerror 
8056               (FLG_INCONDEFS,
8057                message ("Parameter %qinconsistently %rdeclared as "
8058                         "sef parameter",
8059                         uentry_getOptName (unew),
8060                         uentry_isDeclared (old)),
8061                uentry_whereDeclared (unew)))
8062             {
8063               uentry_showWhereSpecified (old);
8064               old->info->var->kind = unew->info->var->kind;
8065             }
8066         }
8067     }
8068
8069   if (old->info->var->kind == VKSPEC)
8070     {
8071       old->info->var->kind = unew->info->var->kind;
8072     }
8073   else
8074     {
8075       unew->info->var->kind = old->info->var->kind;
8076     }
8077
8078   if (unew->info->var->checked != CH_UNKNOWN
8079       && unew->info->var->checked != old->info->var->checked)
8080     {
8081       if (old->info->var->checked == CH_UNKNOWN
8082           && !fileloc_isUser (uentry_whereLast (old)))
8083         {
8084           ; /* no error */
8085         }
8086       else
8087         {
8088           if (optgenerror 
8089               (FLG_INCONDEFS,
8090                message ("Variable %q inconsistently %rdeclared as "
8091                         "%s parameter (was %s)",
8092                         uentry_getName (unew),
8093                         uentry_isDeclared (old),
8094                         checkedName (unew->info->var->checked),
8095                         checkedName (old->info->var->checked)),
8096                uentry_whereDeclared (unew)))
8097             {
8098               uentry_showWhereSpecified (old);
8099             }
8100         }
8101       
8102       old->info->var->checked = unew->info->var->checked;
8103     }
8104   else
8105     {
8106       if (completeConform 
8107           && (old->info->var->checked != CH_UNKNOWN)
8108           && uentry_isReallySpecified (old))
8109         {
8110           if (optgenerror 
8111               (FLG_NEEDSPEC,
8112                message ("%s %q specified as %s, but declared without %s qualifier",
8113                         ekind_capName (unew->ukind),
8114                         uentry_getName (unew),
8115                         checkedName (old->info->var->checked),
8116                         checkedName (old->info->var->checked)),
8117                uentry_whereDeclared (unew)))
8118             {
8119               uentry_showWhereSpecified (old);
8120             }
8121         }
8122       
8123       unew->info->var->checked = old->info->var->checked;
8124     }
8125
8126   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8127 }
8128
8129 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8130 {
8131   if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8132     {
8133       return;
8134     }
8135
8136   llassert (uentry_isVar (u1));
8137   llassert (uentry_isVar (u2));
8138
8139   if (u1->info->var->kind != u2->info->var->kind) {
8140     if (u1->info->var->kind == VKSEFRETPARAM) {
8141       if (u2->info->var->kind == VKRETPARAM) {
8142         voptgenerror 
8143           (FLG_TYPE,
8144            message ("Function types are inconsistent. Parameter %d is "
8145                     "sef parameter, but non-sef parameter in "
8146                     "assigned function: %s",
8147                     paramno, exprNode_unparse (e)),
8148            exprNode_loc (e));
8149       } else if (u2->info->var->kind == VKSEFPARAM) {
8150         voptgenerror 
8151           (FLG_TYPE,
8152            message ("Function types are inconsistent. Parameter %d is "
8153                     "returns parameter, but non-returns parameter in "
8154                     "assigned function: %s",
8155                     paramno, exprNode_unparse (e)),
8156            exprNode_loc (e));
8157       } else {
8158         voptgenerror 
8159           (FLG_TYPE,
8160            message ("Function types are inconsistent. Parameter %d is "
8161                     "sef returns parameter, but non-sef returns parameter in "
8162                     "assigned function: %s",
8163                     paramno, exprNode_unparse (e)),
8164            exprNode_loc (e));
8165       }
8166     } else if (u1->info->var->kind == VKRETPARAM) {
8167       voptgenerror 
8168         (FLG_TYPE,
8169          message ("Function types are inconsistent. Parameter %d is "
8170                   "returns parameter, but non-returns parameter in "
8171                   "assigned function: %s",
8172                   paramno, exprNode_unparse (e)),
8173          exprNode_loc (e));
8174     } else if (u1->info->var->kind == VKSEFPARAM) {
8175       voptgenerror 
8176         (FLG_TYPE,
8177          message ("Function types are inconsistent. Parameter %d is "
8178                   "sef parameter, but non-sef parameter in "
8179                   "assigned function: %s",
8180                   paramno, exprNode_unparse (e)),
8181          exprNode_loc (e));
8182     } else {
8183       if (u2->info->var->kind == VKSEFRETPARAM) {
8184         voptgenerror 
8185           (FLG_TYPE,
8186            message ("Function types are inconsistent. Parameter %d is "
8187                     "normal parameter, but sef returns parameter in "
8188                     "assigned function: %s",
8189                     paramno, exprNode_unparse (e)),
8190            exprNode_loc (e));
8191       } else if (u2->info->var->kind == VKSEFPARAM) {
8192         voptgenerror 
8193           (FLG_TYPE,
8194            message ("Function types are inconsistent. Parameter %d is "
8195                     "normal parameter, but sef parameter in "
8196                     "assigned function: %s",
8197                     paramno, exprNode_unparse (e)),
8198            exprNode_loc (e));
8199       } else if (u2->info->var->kind == VKRETPARAM) {
8200         voptgenerror 
8201           (FLG_TYPE,
8202            message ("Function types are inconsistent. Parameter %d is "
8203                     "normal parameter, but returns parameter in "
8204                     "assigned function: %s",
8205                     paramno, exprNode_unparse (e)),
8206            exprNode_loc (e));
8207       } else {
8208         BADBRANCH;
8209       }
8210     }
8211   }
8212
8213   if (u1->info->var->defstate != u2->info->var->defstate) 
8214     {
8215       voptgenerror 
8216         (FLG_TYPE,
8217          message ("Function types are inconsistent. Parameter %d is "
8218                   "%s, but %s in assigned function: %s",
8219                   paramno, 
8220                   sstate_unparse (u1->info->var->defstate),
8221                   sstate_unparse (u2->info->var->defstate),
8222                   exprNode_unparse (e)),
8223          exprNode_loc (e));
8224     }
8225
8226   if (u1->info->var->nullstate != u2->info->var->nullstate) 
8227     {
8228       voptgenerror 
8229         (FLG_TYPE,
8230          message ("Function types are inconsistent. Parameter %d is "
8231                   "%s, but %s in assigned function: %s",
8232                   paramno, 
8233                   nstate_unparse (u1->info->var->nullstate),
8234                   nstate_unparse (u2->info->var->nullstate),
8235                   exprNode_unparse (e)),
8236          exprNode_loc (e));
8237     }
8238       
8239   if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8240     {
8241       voptgenerror 
8242         (FLG_TYPE,
8243          message ("Function types are inconsistent. Parameter %d is "
8244                   "%s, but %s in assigned function: %s",
8245                   paramno, 
8246                   alkind_unparse (sRef_getAliasKind (u1->sref)),
8247                   alkind_unparse (sRef_getAliasKind (u2->sref)),
8248                   exprNode_unparse (e)),
8249          exprNode_loc (e));
8250     }
8251
8252   if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8253     {
8254       voptgenerror 
8255         (FLG_TYPE,
8256          message ("Function types are inconsistent. Parameter %d is "
8257                   "%s, but %s in assigned function: %s",
8258                   paramno, 
8259                   exkind_unparse (sRef_getExKind (u1->sref)),
8260                   exkind_unparse (sRef_getExKind (u2->sref)),
8261                   exprNode_unparse (e)),
8262          exprNode_loc (e));
8263     }
8264 }
8265
8266 static void
8267 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8268                           /*@notnull@*/ uentry unew, 
8269                           bool mustConform, /*@unused@*/ bool completeConform)
8270 {
8271   uentryList oldParams  = uentry_getParams (old);
8272   uentryList newParams  = uentry_getParams (unew);
8273   ctype      newType    = unew->utype;
8274   ctype      oldType    = ctype_realType (old->utype);
8275   ctype      oldRetType = ctype_unknown;
8276   ctype      newRetType = ctype_unknown;
8277
8278   DPRINTF (("Function conform: %s ==> %s",
8279             uentry_unparseFull (old),
8280             uentry_unparseFull (unew)));
8281
8282   if (uentry_isForward (old))
8283     {
8284       mustConform = FALSE;
8285       uentry_updateInto (old, unew);
8286       return;
8287     }
8288
8289   /*
8290   ** check return values
8291   */
8292   
8293   if (ctype_isKnown (oldType))
8294     {
8295       llassert (ctype_isFunction (oldType));
8296       oldRetType = ctype_getReturnType (oldType);
8297     }
8298
8299   if (ctype_isKnown (newType))
8300     {
8301       llassert (ctype_isFunction (newType));
8302       newRetType = ctype_getReturnType (newType);
8303     }
8304
8305   if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8306       && !ctype_matchDef (newRetType, oldRetType))
8307     {
8308       if (mustConform) returnValueError (old, unew);
8309     }
8310   else 
8311     {
8312       if (ctype_isConj (newRetType))
8313         {
8314           if (ctype_isConj (oldRetType))
8315             {
8316               if (!ctype_sameAltTypes (newRetType, oldRetType))
8317                 {
8318                   if (optgenerror 
8319                       (FLG_INCONDEFS,
8320                        message ("Function %q inconsistently %rdeclared to "
8321                                 "return alternate types %s "
8322                                 "(types match, but alternates are not identical, "
8323                                 "so checking may not be correct)",
8324                                 uentry_getName (unew),
8325                                 uentry_isDeclared (old),
8326                                 ctype_unparse (newRetType)),
8327                        uentry_whereDeclared (unew)))
8328                     {
8329                       uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8330                     }
8331                 }
8332             }
8333           else
8334             {
8335               old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8336             }
8337         }
8338     }
8339
8340   DPRINTF (("Before state: %s",
8341             uentry_unparseFull (old)));
8342   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8343   DPRINTF (("After state: %s",
8344             uentry_unparseFull (old)));
8345
8346   if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8347     {
8348       if (exitkind_isKnown (unew->info->fcn->exitCode))
8349         {
8350           if (optgenerror 
8351               (FLG_INCONDEFS,
8352                message ("Function %q inconsistently %rdeclared using %s",
8353                         uentry_getName (unew),
8354                         uentry_isDeclared (old),
8355                         exitkind_unparse (unew->info->fcn->exitCode)),
8356                uentry_whereDeclared (unew)))
8357             {
8358               uentry_showWhereSpecified (old);
8359             }
8360         }
8361       else
8362         {
8363           unew->info->fcn->exitCode = old->info->fcn->exitCode;
8364         }
8365     }
8366
8367   if (!qual_isUnknown (unew->info->fcn->nullPred))
8368     {
8369       if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8370         {
8371           if (optgenerror
8372               (FLG_INCONDEFS,
8373                message ("Function %q inconsistently %rdeclared using %s",
8374                         uentry_getName (unew),
8375                         uentry_isDeclared (old),
8376                         qual_unparse (unew->info->fcn->nullPred)),
8377                uentry_whereDeclared (unew)))
8378             {
8379               uentry_showWhereSpecified (old);
8380             }
8381         }
8382     }
8383   else
8384     {
8385       unew->info->fcn->nullPred = old->info->fcn->nullPred;
8386     }
8387
8388   if (unew->info->fcn->specialCode != SPC_NONE)
8389     {
8390       if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8391         {
8392           if (optgenerror
8393               (FLG_INCONDEFS,
8394                message ("Function %q inconsistently %rdeclared using %s",
8395                         uentry_getName (unew),
8396                         uentry_isDeclared (old),
8397                         specCode_unparse (unew->info->fcn->specialCode)),
8398                uentry_whereDeclared (unew)))
8399             {
8400               uentry_showWhereSpecified (old);
8401             }
8402         }
8403     }
8404   else
8405     {
8406       unew->info->fcn->specialCode = old->info->fcn->specialCode;
8407     }
8408           
8409   /*
8410   ** check parameters
8411   */
8412   
8413   if (!uentryList_sameObject (oldParams, newParams)
8414       && (!uentryList_isMissingParams (oldParams)))
8415     {
8416       if (!uentryList_isMissingParams (newParams))
8417         {
8418           int paramno = 0;
8419           int nparams = uentryList_size (oldParams);
8420           bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8421
8422           if (nparams != uentryList_size (newParams))
8423             {
8424               nargsError (old, unew);
8425             }
8426           
8427           if (uentryList_size (newParams) < nparams) 
8428             {
8429               nparams = uentryList_size (newParams);
8430             }
8431
8432           while (paramno < nparams)
8433             {
8434               uentry oldCurrent = uentryList_getN (oldParams, paramno);
8435               uentry newCurrent  = uentryList_getN (newParams, paramno);
8436               ctype  oldCurrentType = uentry_getType (oldCurrent);
8437               ctype  newCurrentType = uentry_getType (newCurrent);
8438
8439               llassert (uentry_isValid (oldCurrent)
8440                         && uentry_isValid (newCurrent));
8441               
8442               if (!uentry_isElipsisMarker (oldCurrent)
8443                   && !uentry_isElipsisMarker (newCurrent))
8444                 {
8445                   checkVarConformance (oldCurrent, newCurrent, 
8446                                        mustConform, completeConform);
8447                 }
8448
8449               if (checknames)
8450                 {
8451                   if (uentry_hasName (oldCurrent) 
8452                       && uentry_hasName (newCurrent))
8453                     {
8454                       cstring oldname = uentry_getName (oldCurrent);
8455                       cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8456                       cstring oname;
8457                       cstring nname = uentry_getName (newCurrent);
8458                       cstring nnamefix;
8459
8460                       if (cstring_isDefined (pfx)
8461                           && cstring_equalPrefix (oldname, pfx))
8462                         {
8463                           oname = cstring_suffix (oldname, cstring_length (pfx));
8464                         }
8465                       else
8466                         {
8467                           oname = oldname;
8468                         /*@-branchstate@*/ } /*@=branchstate@*/
8469
8470                       if (cstring_isDefined (pfx)
8471                           && cstring_equalPrefix (nname, pfx))
8472                         {
8473                           nnamefix = cstring_suffix (nname, cstring_length (pfx));
8474                         }
8475                       else
8476                         {
8477                           nnamefix = nname;
8478                         /*@-branchstate@*/ } /*@=branchstate@*/
8479
8480                       if (!cstring_equal (oname, nnamefix))
8481                         {
8482                           if (optgenerror
8483                               (FLG_DECLPARAMMATCH, 
8484                                message ("Definition parameter name %s does not match "
8485                                         "name of corresponding parameter in "
8486                                         "declaration: %s",
8487                                         nnamefix, oname),
8488                                uentry_whereLast (newCurrent)))
8489                             {
8490                               uentry_showWhereLastPlain (oldCurrent);
8491                             }
8492                         }
8493                       
8494                       cstring_free (oldname);
8495                       cstring_free (nname);
8496                     }
8497                 }
8498
8499               if (!ctype_match (oldCurrentType, newCurrentType))
8500                 {
8501                   paramTypeError (old, oldCurrent, oldCurrentType,
8502                                   unew, newCurrent, newCurrentType, paramno);
8503                 }
8504               else
8505                 {
8506                   if (ctype_isMissingParamsMarker (newCurrentType)
8507                       || ctype_isElips (newCurrentType)
8508                       || ctype_isMissingParamsMarker (oldCurrentType)
8509                       || ctype_isElips (oldCurrentType))
8510                     {
8511                       ;
8512                     }
8513                   else
8514                     {
8515                       if (ctype_isConj (newCurrentType))
8516                         {
8517                           if (ctype_isConj (oldCurrentType))
8518                             {
8519                               if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8520                                 {
8521                                   if (optgenerror 
8522                                       (FLG_INCONDEFS,
8523                                        message ("Parameter %q inconsistently %rdeclared with "
8524                                                 "alternate types %s "
8525                                                 "(types match, but alternates are not identical, "
8526                                                 "so checking may not be correct)",
8527                                                 uentry_getName (newCurrent),
8528                                                 uentry_isDeclared (oldCurrent),
8529                                                 ctype_unparse (newCurrentType)),
8530                                        uentry_whereDeclared (unew)))
8531                                     {
8532                                       uentry_showWhereLastVal (oldCurrent,
8533                                                                ctype_unparse (oldCurrentType));
8534                                     }
8535                                 }
8536                             }
8537                           else
8538                             {
8539                               if (optgenerror 
8540                                   (FLG_INCONDEFS,
8541                                    message ("Parameter %q inconsistently %rdeclared with "
8542                                             "alternate types %s",
8543                                             uentry_getName (newCurrent),
8544                                             uentry_isDeclared (oldCurrent),
8545                                             ctype_unparse (newCurrentType)),
8546                                    uentry_whereDeclared (unew)))
8547                                 {
8548                                   uentry_showWhereLastVal (oldCurrent,
8549                                                            ctype_unparse (oldCurrentType));
8550                                   
8551                                 }
8552                             }
8553                         }
8554                       else 
8555                         {
8556                           if (ctype_isConj (oldCurrentType))
8557                             {
8558                               uentry_setType (newCurrent, oldCurrentType);
8559                             }
8560                         }
8561                     }
8562                 }
8563
8564               paramno++;  
8565               /*
8566                ** Forgot this!  detected by splint:
8567                ** uentry.c:1257,15: Suspected infinite loop
8568                */
8569             }
8570         }
8571     }
8572
8573   if (!uentryList_isMissingParams (newParams))
8574     {
8575       if (ctype_isConj (oldRetType))
8576         {
8577           old->utype = ctype_makeFunction (oldRetType, 
8578                                            uentryList_copy (newParams));
8579         }
8580       else
8581         {
8582           old->utype = unew->utype;
8583         }
8584     }
8585
8586   checkGlobalsConformance (old, unew, mustConform, completeConform);
8587   checkModifiesConformance (old, unew, mustConform, completeConform);
8588
8589   DPRINTF (("Before list: %s",
8590             uentry_unparseFull (old)));
8591
8592   if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8593     {
8594       if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8595         {
8596           /*
8597           if (optgenerror
8598               (FLG_INCONDEFS,
8599                message ("Function %q redeclared using special clauses (can only "
8600                         "be used in first declaration)",
8601                         uentry_getName (unew)),
8602                uentry_whereDeclared (unew)))
8603             {
8604               uentry_showWhereLast (old);
8605             }
8606           */
8607
8608           /*@i23 need checking @*/ 
8609
8610           old->info->fcn->specclauses = unew->info->fcn->specclauses;
8611         }
8612       else
8613         {
8614           /*@i43 should be able to append? @*/
8615
8616           stateClauseList_checkEqual (old, unew);
8617           stateClauseList_free (unew->info->fcn->specclauses);
8618           unew->info->fcn->specclauses = stateClauseList_undefined;
8619           /*@-branchstate@*/ 
8620         }
8621     }
8622   /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8623
8624   if (fileloc_isUndefined (old->whereDeclared))
8625     {
8626       old->whereDeclared = fileloc_copy (unew->whereDeclared);
8627     }
8628   else if (fileloc_isUndefined (unew->whereDeclared))
8629     {
8630       unew->whereDeclared = fileloc_copy (old->whereDeclared);
8631     }
8632   else
8633     {
8634       /* no change */
8635     }
8636 /*@i523 @*/ }
8637
8638 void
8639 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8640 {
8641   multiVal uval;
8642
8643   llassert (uentry_isValid (ue));
8644   llassert (uentry_isEitherConstant (ue));
8645
8646   DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8647   uval = uentry_getConstantValue (ue);
8648
8649   if (multiVal_isDefined (uval))
8650     {
8651       if (multiVal_isDefined (m))
8652         {
8653           if (!multiVal_equiv (uval, m))
8654             {
8655               if (optgenerror 
8656                   (FLG_INCONDEFS,
8657                    message ("%s %q defined with inconsistent value: %q",
8658                             ekind_capName (ue->ukind),
8659                             uentry_getName (ue), 
8660                             multiVal_unparse (m)),
8661                    g_currentloc))
8662                 {
8663                   uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8664                 }
8665             }
8666         }
8667       multiVal_free (m);
8668     }
8669   else
8670     {
8671       uentry_setConstantValue (ue, m);
8672     }
8673 }
8674
8675 static
8676 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, 
8677                            bool mustConform)
8678 {
8679   bool typeError = FALSE;
8680
8681   if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8682     {
8683       if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8684         {
8685           if (mustConform)
8686             {
8687               DPRINTF (("Check struct conformance: %s / %s",
8688                         uentry_unparseFull (old),
8689                         uentry_unparseFull (unew)));
8690               checkStructConformance (old, unew); 
8691             }
8692         }
8693       else
8694         {
8695           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8696             {
8697               llbug (message ("struct tags: bad types: %t / %t", 
8698                               old->utype, unew->utype));
8699             }
8700         }
8701     }
8702   else if (uentry_isEnumTag (old))
8703     {
8704       if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8705         {
8706           if (mustConform) checkEnumConformance (old, unew);
8707         }
8708       else 
8709         {
8710           if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8711             {
8712               llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8713                               ctype_unparse (unew->utype)));
8714             }
8715         }
8716     }
8717   else if (!ctype_match (old->utype, unew->utype))
8718     {
8719       DPRINTF (("Type mismatch: %s / %s",
8720                 ctype_unparse (old->utype),
8721                 ctype_unparse (unew->utype)));
8722
8723       if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8724         {
8725           ctype realt = ctype_realType (unew->utype);
8726           
8727           if (ctype_isRealInt (realt) || ctype_isChar (realt))
8728             {
8729               unew->utype = ctype_bool;
8730             }
8731           else
8732             {
8733               if (mustConform)
8734                 {
8735                   typeError = optgenerror
8736                     (FLG_INCONDEFS,
8737                      message ("%q defined as %s", uentry_getName (old), 
8738                               ctype_unparse (realt)),
8739                      uentry_whereDeclared (unew));
8740                 }
8741             }
8742         } 
8743       else 
8744         {
8745           if (mustConform)
8746             {
8747               ctype oldr = ctype_realType (old->utype);
8748               ctype newr = ctype_realType (unew->utype);
8749               
8750               if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8751                 {
8752                   checkStructConformance (old, unew);
8753                 }
8754               else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8755                 {
8756                   checkStructConformance (old, unew);
8757                 }
8758               else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8759                 {
8760                   checkEnumConformance (old, unew);
8761                 }
8762               else if (uentry_isConstant (old) 
8763                        && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8764                 {
8765                   /* okay...for now! (should check the type is reset later... */
8766                 }
8767               else
8768                 {
8769                   DPRINTF (("YABA!"));
8770                   if (optgenerror 
8771                       (FLG_INCONDEFS,
8772                        message ("%s %q %rdeclared with inconsistent type: %t",
8773                                 ekind_capName (unew->ukind),
8774                                 uentry_getName (unew), 
8775                                 uentry_isDeclared (old),
8776                                 unew->utype),
8777                        uentry_whereDeclared (unew)))
8778                     {
8779                       uentry_showWhereLast (old);
8780                       typeError = TRUE;
8781                     }
8782                 }
8783             }
8784         }
8785     }
8786   else
8787     {
8788       /* no error */
8789     }
8790
8791   return typeError;
8792 }
8793
8794 static void
8795 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8796                                  /*@notnull@*/ uentry unew,
8797                                  bool mustConform, bool completeConform)
8798 {
8799   if (ctype_isDefined (unew->info->datatype->type))
8800     {
8801       /*
8802       ** bool is hard coded here, since it is built into LCL.
8803       ** For now, we're stuck with LCL's types.
8804       */
8805
8806       if (ctype_isDirectBool (old->utype) &&
8807           cstring_equalLit (unew->uname, "bool"))
8808         {
8809           /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8810              evs 2000-07-25: removed
8811           */
8812               unew->utype = ctype_bool;
8813         }
8814       
8815       if (ctype_isUnknown (old->info->datatype->type))
8816         {
8817           old->info->datatype->type = unew->info->datatype->type;
8818         }
8819       else
8820         {
8821           DPRINTF (("Old: %s / New: %s",
8822                     uentry_unparseFull (old),
8823                     uentry_unparseFull (unew)));
8824           DPRINTF (("Types: %s / %s",
8825                     ctype_unparse (old->info->datatype->type),
8826                     ctype_unparse (unew->info->datatype->type)));
8827
8828           if (ctype_matchDef (old->info->datatype->type,
8829                               unew->info->datatype->type))
8830             {
8831               ;
8832             }
8833           else
8834             {
8835               if (optgenerror 
8836                   (FLG_INCONDEFS,
8837                    message
8838                    ("Type %q %s with inconsistent type: %t",
8839                     uentry_getName (unew), 
8840                     uentry_reDefDecl (old, unew),
8841                     unew->info->datatype->type),
8842                    uentry_whereDeclared (unew)))
8843                 {
8844                   uentry_showWhereLastExtra 
8845                     (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8846                 }
8847
8848               old->info->datatype->type = unew->info->datatype->type;
8849             }
8850         }
8851     }
8852   
8853   if (unew->info->datatype->abs != MAYBE)
8854     {
8855       if (ynm_isOff (old->info->datatype->abs)
8856           && ynm_isOn (unew->info->datatype->abs))
8857         {
8858           if (!ctype_isDirectBool (old->utype))
8859             {
8860               if (optgenerror 
8861                   (FLG_INCONDEFS,
8862                    message 
8863                    ("Datatype %q inconsistently %rdeclared as abstract type",
8864                     uentry_getName (unew), 
8865                     uentry_isDeclared (old)),
8866                    uentry_whereDeclared (unew)))
8867                 {
8868                   uentry_showWhereLastPlain (old);
8869                 }
8870             }
8871         }
8872       else if (ynm_isOn (old->info->datatype->abs)
8873                && ynm_isOff (unew->info->datatype->abs))
8874         {
8875           if (!ctype_isDirectBool (old->utype))
8876             {
8877               if (optgenerror 
8878                   (FLG_INCONDEFS,
8879                    message 
8880                    ("Datatype %q inconsistently %rdeclared as concrete type",
8881                     uentry_getName (unew), 
8882                     uentry_isDeclared (old)),
8883                    uentry_whereDeclared (unew)))
8884                 {
8885                   uentry_showWhereLastPlain (old);
8886                 }
8887             }
8888         }
8889       else
8890         {
8891           ;
8892         }
8893     }
8894   else 
8895     {
8896       if (ynm_isOn (old->info->datatype->abs))
8897         {
8898           old->sref = unew->sref;
8899           unew->info->datatype->mut = old->info->datatype->mut;
8900           
8901           if (completeConform
8902               && uentry_isReallySpecified (old))
8903             {
8904               if (optgenerror 
8905                   (FLG_NEEDSPEC,
8906                    message 
8907                    ("Datatype %q specified as abstract, "
8908                     "but abstract annotation not used in declaration",
8909                     uentry_getName (unew)), 
8910                    uentry_whereDeclared (unew)))
8911                 {
8912                   uentry_showWhereLastPlain (old);
8913                 }
8914             }
8915         }
8916     }
8917   
8918   unew->info->datatype->abs = old->info->datatype->abs;   
8919   
8920   if (ynm_isMaybe (unew->info->datatype->mut))
8921     {
8922       if (completeConform && ynm_isOff (old->info->datatype->mut)
8923           && uentry_isReallySpecified (old))
8924         {
8925           if (optgenerror 
8926               (FLG_NEEDSPEC,
8927                message 
8928                ("Datatype %q specified as immutable, "
8929                 "but immutable annotation not used in declaration",
8930                 uentry_getName (unew)), 
8931                uentry_whereDeclared (unew)))
8932             {
8933               uentry_showWhereLastPlain (old);
8934             }
8935         }
8936       
8937       unew->info->datatype->mut = old->info->datatype->mut;
8938     }
8939   else if (ynm_isMaybe (old->info->datatype->mut))
8940     {
8941       old->info->datatype->mut = unew->info->datatype->mut;
8942     }
8943   else
8944     {
8945       if (ynm_isOn (old->info->datatype->abs))
8946         {
8947           if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8948             {
8949               if (optgenerror
8950                   (FLG_INCONDEFS,
8951                    message ("Datatype %q inconsistently %rdeclared as immutable",
8952                             uentry_getName (unew), 
8953                             uentry_isDeclared (old)),
8954                    uentry_whereDeclared (unew)))
8955                 {
8956                   uentry_showWhereLastPlain (old);
8957                 }
8958             }
8959           else 
8960             {
8961               if (ynm_isOff (old->info->datatype->mut)
8962                   && ynm_isOn (unew->info->datatype->mut))
8963                 {
8964                   if (optgenerror
8965                       (FLG_INCONDEFS,
8966                        message ("Datatype %q inconsistently %rdeclared as mutable",
8967                                 uentry_getName (unew), 
8968                                 uentry_isDeclared (old)),
8969                        uentry_whereDeclared (unew)))
8970                     {
8971                       uentry_showWhereLastPlain (old);
8972                     }
8973                 }
8974             }
8975         }
8976       old->info->datatype->mut = unew->info->datatype->mut;       
8977     }
8978
8979   uentry_checkStateConformance (old, unew, mustConform, completeConform);
8980 }
8981
8982 static void
8983 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8984                                  /*@notnull@*/ uentry unew,
8985                                  bool mustConform, 
8986                                  /*@unused@*/ bool completeConform)
8987 {
8988   multiVal oldval = uentry_getConstantValue (old);
8989   multiVal newval = uentry_getConstantValue (unew);
8990   
8991   if (multiVal_isDefined (oldval))
8992     {
8993       if (multiVal_isDefined (newval))
8994         {
8995           if (!multiVal_equiv (oldval, newval))
8996             {
8997               if (mustConform
8998                   && optgenerror 
8999                   (FLG_INCONDEFS,
9000                    message ("%s %q %rdeclared with inconsistent value: %q",
9001                             ekind_capName (unew->ukind),
9002                             uentry_getName (unew), 
9003                             uentry_isDeclared (old),
9004                             multiVal_unparse (newval)),
9005                    uentry_whereDeclared (unew)))
9006                 {
9007                   uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9008                 }
9009             }
9010           
9011           uentry_setConstantValue (unew, multiVal_copy (oldval));
9012         }
9013       else
9014         {
9015           ;
9016         }
9017     }
9018   else
9019     {
9020       uentry_setConstantValue (old, multiVal_copy (newval));
9021     }
9022 }
9023
9024 static void 
9025 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old, 
9026                          /*@notnull@*/ uentry unew, bool mustConform,
9027                          bool completeConform)
9028 {
9029   bool typeError = FALSE;
9030   bool fcnConformance = FALSE;
9031
9032   if (!ekind_equal (unew->ukind, old->ukind))
9033     {
9034       /*
9035       ** okay, only if one is a function and the other is
9036       ** a variable of type function.
9037       */
9038
9039       if (unew->ukind == KENUMCONST
9040           && old->ukind == KCONST)
9041         {
9042           old->ukind = KENUMCONST;
9043           goto nokinderror;
9044         }
9045
9046       if (unew->ukind == KFCN 
9047           && old->ukind == KCONST
9048           && ctype_isUnknown (old->utype))
9049         {
9050           /*
9051           ** When a function is defined with an unparam macro
9052           */
9053
9054           uentry_updateInto (old, unew);
9055           return;
9056         }
9057
9058       if (uentry_isExpandedMacro (old) 
9059           && uentry_isEitherConstant (unew))
9060         {
9061           uentry_updateInto (old, unew);
9062           return;
9063         }
9064
9065       if (uentry_isEndIter (unew))
9066         {
9067           if (ctype_isUnknown (old->utype))
9068             {
9069               if (!uentry_isSpecified (old)
9070                   && uentry_isCodeDefined (unew))
9071                 {
9072                   if (!fileloc_withinLines (uentry_whereDefined (old),
9073                                             uentry_whereDeclared (unew), 2))
9074                     { /* bogus!  will give errors if there is too much whitespace */
9075                       voptgenerror
9076                         (FLG_SYNTAX,
9077                          message
9078                          ("Iterator finalized name %q does not match name in "
9079                           "previous iter declaration (should be end_%q).  This iter "
9080                           "is declared at %q", 
9081                           uentry_getName (unew),
9082                           uentry_getName (old),
9083                           fileloc_unparse (uentry_whereDefined (old))),
9084                          uentry_whereDeclared (old));
9085                     }
9086                 }
9087
9088               uentry_updateInto (old, unew);
9089               return;
9090             }
9091           else
9092             {
9093               KindConformanceError (old, unew, mustConform);
9094             }
9095         }
9096
9097       if (uentry_isFunction (unew))
9098         {
9099           if (uentry_isVariable (old))
9100             {
9101               if (!ctype_isUnknown (old->utype))
9102                 {
9103                   if (ctype_isFunction (old->utype))
9104                     {
9105                       uentry_makeVarFunction (old);
9106                       checkFunctionConformance (old, unew, mustConform,
9107                                                 completeConform);
9108                       fcnConformance = TRUE;
9109                     }
9110                   else
9111                     {
9112                       KindConformanceError (old, unew, mustConform);
9113                     }
9114                 }
9115               else
9116                 {
9117                   if (uentry_isExpandedMacro (old))
9118                     {
9119                       if (fileloc_isUndefined (unew->whereDefined))
9120                         {
9121                           unew->whereDefined = fileloc_update (unew->whereDefined, 
9122                                                               old->whereDefined);
9123                         }
9124
9125                       uentry_updateInto (old, unew);
9126                       old->used = unew->used = TRUE;
9127                       return;
9128                     }
9129                   else
9130                     {
9131                       /* undeclared identifier */
9132                       old->utype = unew->utype;
9133                       uentry_makeVarFunction (old);
9134                       checkFunctionConformance (old, unew, FALSE, FALSE);
9135                       fcnConformance = TRUE;
9136                     }
9137                 }
9138             }
9139           else
9140             {
9141               KindConformanceError (old, unew, mustConform);
9142             }
9143         }
9144       else if (uentry_isFunction (old) && uentry_isVariable (unew))
9145         {
9146           if (!ctype_isUnknown (unew->utype))
9147             {
9148               if (ctype_isFunction (unew->utype))
9149                 {
9150                   uentry_makeVarFunction (unew);
9151                   checkFunctionConformance (old, unew, mustConform, completeConform);
9152                   fcnConformance = TRUE;
9153                 }
9154               else
9155                 {
9156                   KindConformanceError (old, unew, mustConform);
9157                 }
9158             }
9159           else
9160             {
9161               KindConformanceError (old, unew, mustConform);
9162             }
9163         }
9164       else
9165         {
9166           KindConformanceError (old, unew, mustConform);
9167         }
9168     }
9169   else
9170     {
9171       /*
9172       ** check parameter lists for functions 
9173       ** (before type errors, to get better messages
9174       */
9175
9176       if (uentry_isFunction (old))
9177         {
9178           checkFunctionConformance (old, unew, mustConform, completeConform);
9179           fcnConformance = TRUE;
9180         }
9181       else 
9182         {
9183           if (!ctype_isUndefined (old->utype))
9184             {
9185               typeError = checkTypeConformance (old, unew, mustConform);
9186             }
9187         }
9188     }
9189
9190  nokinderror:
9191
9192   if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9193     {
9194       uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9195     }
9196
9197   if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9198     {
9199       DPRINTF (("Check datatype: %s / %s",
9200                 uentry_unparseFull (old),
9201                 uentry_unparseFull (unew)));
9202
9203       uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9204     }
9205
9206   if (uentry_isVariable (old) && uentry_isVariable (unew))
9207     {
9208       if (!typeError && 
9209           !ctype_matchDef (old->utype, unew->utype))
9210         {
9211           if (optgenerror 
9212               (FLG_INCONDEFS,
9213                message
9214                ("Variable %q %s with inconsistent type (arrays and pointers are "
9215                 "not identical in variable declarations): %t",
9216                 uentry_getName (unew), 
9217                 uentry_reDefDecl (old, unew),
9218                 unew->utype),
9219                uentry_whereDeclared (unew)))
9220             {
9221               uentry_showWhereLast (old);
9222               
9223               /*
9224               ** Avoid repeated errors.
9225               */
9226
9227               if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9228                 {
9229                   old->whereDefined = fileloc_update (old->whereDefined,
9230                                                       fileloc_undefined);
9231                 }
9232
9233               typeError = TRUE;
9234             }
9235         }
9236
9237       checkVarConformance (old, unew, mustConform, completeConform);
9238     }
9239
9240   if (fcnConformance)
9241     {
9242       /* old->utype = unew->utype; */
9243     }
9244   else
9245     {
9246       if (ctype_isConj (old->utype))
9247         {
9248           if (ctype_isConj (unew->utype))
9249             {
9250               if (!ctype_sameAltTypes (old->utype, unew->utype))
9251                 {
9252                   if (optgenerror 
9253                       (FLG_INCONDEFS,
9254                        message ("%s %q inconsistently %rdeclared with "
9255                                 "alternate types %s "
9256                                 "(types match, but alternates are not identical, "
9257                                 "so checking may not be correct)",
9258                                 ekind_capName (uentry_getKind (old)),
9259                                 uentry_getName (unew),
9260                                 uentry_isDeclared (old),
9261                                 ctype_unparse (unew->utype)),
9262                        uentry_whereDeclared (unew)))
9263                     {
9264                       uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9265                     }
9266                   else
9267                     {
9268                       old->utype = unew->utype;
9269                     }
9270                 }
9271             }
9272         }
9273       else
9274         {
9275           if (ctype_isUnknown (old->utype))
9276             {
9277               old->utype = unew->utype;
9278             }
9279         }
9280     }  
9281
9282   if (unew->ukind == old->ukind) 
9283     {
9284       sfree (unew->info);
9285       unew->info = uinfo_copy (old->info, old->ukind);
9286     }
9287
9288   sRef_storeState (old->sref);
9289   sRef_storeState (unew->sref);
9290 }
9291
9292 static void uentry_mergeConstraints (uentry spec, uentry def)
9293 {
9294   if (uentry_isFunction (def))
9295     {
9296       DPRINTF (("Here: %s / %s",
9297                 uentry_unparseFull (spec),
9298                 uentry_unparseFull (def)));
9299       /* evans 2001-07-21 */
9300       llassert (uentry_isFunction (spec));
9301
9302       if (functionConstraint_isDefined (def->info->fcn->preconditions))
9303         {
9304           if (fileloc_isXHFile (uentry_whereLast (def)))
9305             {
9306               llassert (uentry_isFunction (spec));
9307               spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9308                                                                            def->info->fcn->preconditions);
9309             }
9310           else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9311             {
9312               ;
9313             }
9314           else
9315             {
9316               /* Check if the constraints are identical */
9317
9318               if (optgenerror 
9319                   (FLG_INCONDEFS,
9320                    message
9321                    ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9322                     uentry_getName (spec),
9323                     functionConstraint_unparse (spec->info->fcn->preconditions)),
9324                    uentry_whereLast (def)))
9325                 {
9326                   uentry_showWhereSpecified (spec);
9327                 }
9328
9329               functionConstraint_free (spec->info->fcn->preconditions);
9330               spec->info->fcn->preconditions = def->info->fcn->preconditions;
9331             }
9332           
9333           def->info->fcn->preconditions = functionConstraint_undefined;
9334         }
9335
9336       if (functionConstraint_isDefined (def->info->fcn->postconditions))
9337         {
9338           if (fileloc_isXHFile (uentry_whereLast (def)))
9339             {
9340               llassert (uentry_isFunction (spec));
9341               DPRINTF (("Post: %s /++/ %s",
9342                         functionConstraint_unparse (spec->info->fcn->postconditions),
9343                         functionConstraint_unparse (def->info->fcn->postconditions)));
9344               spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9345                                                                             def->info->fcn->postconditions);
9346               def->info->fcn->postconditions = functionConstraint_undefined;
9347               DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9348             }
9349           else
9350             {
9351               if (optgenerror 
9352                   (FLG_INCONDEFS,
9353                    message
9354                    ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9355                     uentry_getName (spec),
9356                     functionConstraint_unparse (spec->info->fcn->postconditions)),
9357                    uentry_whereLast (def)))
9358                 {
9359                   uentry_showWhereSpecified (spec);
9360                 }
9361               
9362               functionConstraint_free (spec->info->fcn->postconditions);
9363               spec->info->fcn->postconditions = def->info->fcn->postconditions;
9364               def->info->fcn->postconditions = functionConstraint_undefined;
9365             }
9366         }
9367     }
9368 }
9369
9370 /*
9371 ** modifies spec to reflect def, reports any inconsistencies
9372 */
9373
9374 void
9375 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9376 {
9377   llassert (uentry_isValid (spec));
9378   llassert (uentry_isValid (def));
9379   llassert (cstring_equal (spec->uname, def->uname));
9380
9381   if (uentry_isFunction (def))
9382     {
9383       if (uentry_isConstant (spec))
9384         {
9385           llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9386           uentry_makeConstantFunction (spec);
9387         }
9388       else
9389         {
9390           uentry_convertVarFunction (spec);
9391         }
9392
9393       llassert (uentry_isFunction (spec));
9394     }
9395   
9396   DPRINTF (("Merge entries: %s / %s",
9397             uentry_unparseFull (spec),
9398             uentry_unparseFull (def)));
9399
9400   uentry_mergeConstraints (spec, def);
9401
9402   uentry_checkConformance (spec, def, TRUE, 
9403                            context_getFlag (FLG_NEEDSPEC));
9404
9405   DPRINTF (("Merge entries after conform: %s / %s",
9406             uentry_unparseFull (spec),
9407             uentry_unparseFull (def)));
9408
9409   /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9410
9411   /*
9412   ** okay, declarations conform.  Propagate extra information.
9413   */
9414
9415   uentry_setDefined (spec, uentry_whereDefined (def));
9416   uentry_setDeclared (spec, uentry_whereDeclared (def));
9417
9418   if (uentry_isStatic (def))
9419     {
9420       if (optgenerror 
9421           (FLG_INCONDEFS,
9422            message ("%s %q specified, but declared as static",
9423                     ekind_capName (def->ukind),
9424                     uentry_getName (def)),
9425            uentry_whereDeclared (def)))
9426         {
9427           uentry_showWhereSpecified (spec);
9428         }
9429     }
9430   else 
9431     {
9432       spec->storageclass = def->storageclass;
9433     }
9434
9435   sRef_storeState (spec->sref);
9436
9437   spec->used = def->used || spec->used;
9438   spec->hasNameError |= def->hasNameError;
9439
9440   uentry_free (def);
9441
9442   if (!spec->hasNameError)
9443     {
9444       uentry_checkName (spec);
9445     }
9446   else
9447     {
9448       ;
9449     }
9450 }
9451
9452 /*
9453 ** Can't generate function redeclaration errors when the 
9454 ** entries are merged, since we don't yet know if its the
9455 ** definition of the function.
9456 */
9457
9458 void
9459 uentry_clearDecl (void)
9460 {
9461   posRedeclared = uentry_undefined;
9462   fileloc_free (posLoc);
9463   posLoc = fileloc_undefined;
9464 }
9465
9466 void
9467 uentry_checkDecl (void)
9468 {
9469   if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9470     {
9471       llassert (fileloc_isDefined (posLoc));
9472
9473       if (uentry_isCodeDefined (posRedeclared))
9474         {
9475           if (optgenerror (FLG_REDECL,
9476                            message ("%s %q declared after definition", 
9477                                     ekind_capName (posRedeclared->ukind),
9478                                     uentry_getName (posRedeclared)),
9479                            posLoc))
9480             {
9481               llgenindentmsg (message ("Definition of %q", 
9482                                        uentry_getName (posRedeclared)),
9483                               posRedeclared->whereDeclared);
9484             }
9485         }
9486       else
9487         {
9488           if (optgenerror (FLG_REDECL,
9489                            message ("%s %q declared more than once", 
9490                                     ekind_capName (posRedeclared->ukind),
9491                                     uentry_getName (posRedeclared)),
9492                            posLoc))
9493             {
9494               llgenindentmsg (message ("Previous declaration of %q", 
9495                                        uentry_getName (posRedeclared)),
9496                               posRedeclared->whereDeclared);
9497             }
9498         }
9499     }
9500
9501   fileloc_free (posLoc);
9502   posLoc = fileloc_undefined;
9503   posRedeclared = uentry_undefined;
9504 }
9505
9506 /*
9507 ** Redefinition of old as unew.
9508 ** modifies old to reflect unew, reports any inconsistencies
9509 */
9510
9511 void
9512 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9513 {
9514   fileloc olddef = uentry_whereDeclared (old); 
9515   fileloc unewdef = uentry_whereDeclared (unew);
9516   bool mustConform;
9517   bool wasForward;
9518
9519   DPRINTF (("uentry merge: %s / %s",
9520             uentry_unparseFull (old),
9521             uentry_unparseFull (unew)));
9522  
9523   wasForward = 
9524     fileloc_isUndefined (olddef) 
9525     && fileloc_isDefined (uentry_whereDefined (old)) 
9526     && !uentry_isExpandedMacro (old);
9527   
9528   if (!context_getFlag (FLG_INCONDEFSLIB)
9529       && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9530     {
9531       mustConform = FALSE;
9532     }
9533   else
9534     {
9535       mustConform = TRUE;
9536     }
9537   
9538   llassert (uentry_isValid (old));
9539   llassert (uentry_isValid (unew));
9540   llassert (cstring_equal (old->uname, unew->uname));
9541
9542   if (uentry_isFunction (unew) && !uentry_isFunction (old))
9543     {
9544       if (uentry_isConstant (old))
9545         {
9546           llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9547           uentry_makeConstantFunction (old);
9548         }
9549       else
9550         {
9551           uentry_convertVarFunction (old);
9552         }
9553
9554       llassert (uentry_isFunction (old));
9555     }
9556
9557   DPRINTF (("uentry merge: %s / %s",
9558             uentry_unparseFull (old),
9559             uentry_unparseFull (unew)));
9560
9561   if (uentry_isExtern (unew))
9562     {
9563       uentry_setUsed (old, unewdef);
9564     }
9565
9566   /*
9567   ** should check old one was extern!
9568   */
9569
9570   if (uentry_isStatic (old))
9571     {
9572       if (!(uentry_isStatic (unew)))
9573         {
9574           if (optgenerror 
9575               (FLG_SHADOW,
9576                message ("%s %q shadows static declaration",
9577                         ekind_capName (unew->ukind),
9578                         uentry_getName (unew)),
9579                unewdef))
9580             {
9581               uentry_showWhereLast (old);
9582             }
9583         }
9584       else
9585         {
9586           uentry_setDeclDef (old, unewdef);
9587         }
9588     }
9589   else if (uentry_isStatic (unew))
9590     {
9591       uentry_setDeclDef (old, unewdef);
9592     }
9593   else if (uentry_isExtern (old))
9594     {
9595       uentry_setDeclared (old, unewdef);
9596     }
9597   else
9598     {
9599       if (!uentry_isExtern (unew) 
9600           && !uentry_isForward (old)
9601           && !fileloc_equal (olddef, unewdef)
9602           && !fileloc_isUndefined (olddef)
9603           && !fileloc_isUndefined (unewdef)
9604           && !fileloc_isBuiltin (olddef)
9605           && !fileloc_isBuiltin (unewdef)
9606           && !uentry_isYield (old)
9607           && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9608         {
9609           if (uentry_isVariable (old) || uentry_isVariable (unew))
9610             {
9611               ; /* will report redeclaration error later */
9612             }
9613           else
9614             {
9615               if (fileloc_isDefined (uentry_whereDefined (old)))
9616                 {
9617                   if (optgenerror
9618                       (FLG_REDEF,
9619                        message ("%s %q defined more than once", 
9620                                 ekind_capName (unew->ukind),
9621                                 uentry_getName (unew)),
9622                        uentry_whereLast (unew)))
9623                     {
9624                       llgenindentmsg
9625                         (message ("Previous definition of %q", 
9626                                   uentry_getName (old)),
9627                          uentry_whereLast (old));
9628                     }
9629                   /*
9630                   if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9631                     {
9632                       uentry_updateInto (old, unew);
9633                       old->sref = sRef_saveCopy (old->sref);
9634                     }
9635                     */
9636                 }
9637             }
9638         }
9639       else
9640         {
9641           if (fileloc_isLib (olddef)
9642               || fileloc_isUndefined (olddef)
9643               || fileloc_isImport (olddef))
9644             {
9645               if (uentry_isExtern (unew)) 
9646                 {
9647                   if (uentry_isExtern (old)
9648                       || (fileloc_isDefined (uentry_whereDeclared (old))
9649                           && (!fileloc_equal (uentry_whereDeclared (old),
9650                                               uentry_whereDefined (old)))))
9651                     {
9652                       if (optgenerror
9653                           (FLG_REDECL,
9654                            message ("%s %q declared more than once", 
9655                                     ekind_capName (unew->ukind),
9656                                     uentry_getName (unew)),
9657                            unew->whereDeclared))
9658                         {
9659                           llgenindentmsg
9660                             (message ("Previous declaration of %q", 
9661                                       uentry_getName (old)),
9662                              old->whereDeclared);
9663                         }
9664                     }
9665                   
9666                   uentry_setExtern (old);
9667                 }
9668               else
9669                 {
9670                   uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9671                 }
9672             }
9673         }
9674     }
9675
9676   DPRINTF (("uentry merge: %s / %s",
9677             uentry_unparseFull (old),
9678             uentry_unparseFull (unew)));
9679
9680   uentry_mergeConstraints (old, unew);
9681   DPRINTF (("uentry merge: %s / %s",
9682             uentry_unparseFull (old),
9683             uentry_unparseFull (unew)));
9684
9685   uentry_checkConformance (old, unew, mustConform, FALSE);
9686   DPRINTF (("uentry merge: %s / %s",
9687             uentry_unparseFull (old),
9688             uentry_unparseFull (unew)));
9689
9690   old->used = old->used || unew->used;
9691   old->uses = filelocList_append (old->uses, unew->uses);
9692   unew->uses = filelocList_undefined; 
9693
9694   sRef_storeState (old->sref); 
9695   sRef_storeState (unew->sref);
9696
9697   if (wasForward)
9698     {
9699       old->whereDefined = fileloc_update (old->whereDefined,
9700                                           fileloc_undefined);
9701     }
9702
9703   DPRINTF (("here: %s", uentry_unparseFull (old)));
9704
9705   /*
9706   ** No redeclaration errors for functions here, since we
9707   ** don't know if this is the definition of the function.
9708   */
9709
9710   if (fileloc_isUser (old->whereDeclared)
9711       && fileloc_isUser (unew->whereDeclared)
9712       && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9713       && !fileloc_isDefined (unew->whereDefined))
9714     {
9715       if (uentry_isFunction (old))
9716         {
9717           /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9718           posLoc = fileloc_update (posLoc, unew->whereDeclared);
9719         }
9720       else
9721         {
9722           if (optgenerror (FLG_REDECL,
9723                            message ("%s %q declared more than once", 
9724                                     ekind_capName (unew->ukind),
9725                                     uentry_getName (unew)),
9726                            unew->whereDeclared))
9727             {
9728               llgenindentmsg (message ("Previous declaration of %q", 
9729                                        uentry_getName (old)),
9730                               old->whereDeclared);
9731             }
9732         }
9733     }
9734
9735   if (fileloc_isUndefined (old->whereDefined))
9736     {
9737       old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9738     }
9739   else
9740     {
9741       if (!context_processingMacros ()
9742           && fileloc_isUser (old->whereDefined) 
9743           && fileloc_isUser (unew->whereDefined)
9744           && !fileloc_equal (old->whereDefined, unew->whereDefined))
9745         {
9746           if (uentry_isVariable (unew) || uentry_isFunction (unew))
9747             {
9748               if (uentry_isVariable (unew) 
9749                   && uentry_isExtern (unew))
9750                 {
9751                   if (optgenerror (FLG_REDECL,
9752                                    message ("%s %q declared after definition", 
9753                                             ekind_capName (unew->ukind),
9754                                             uentry_getName (unew)),
9755                                    unew->whereDeclared))
9756                     {
9757                       llgenindentmsg (message ("Definition of %q", 
9758                                                uentry_getName (old)),
9759                                       old->whereDefined);
9760                     }
9761                 }
9762               else
9763                 {
9764                   if (optgenerror (FLG_REDEF,
9765                                    message ("%s %q redefined", 
9766                                             ekind_capName (unew->ukind),
9767                                             uentry_getName (unew)),
9768                                    unew->whereDefined))
9769                     {
9770                       llgenindentmsg (message ("Previous definition of %q", 
9771                                                uentry_getName (old)),
9772                                       old->whereDefined);
9773                     }
9774                 }
9775             }
9776         }
9777     }
9778
9779   if (uentry_isExternal (unew))
9780     {
9781       old->whereDefined = fileloc_createExternal ();
9782     }
9783
9784   if (unew->hasNameError)
9785     {
9786       old->hasNameError = TRUE;
9787     }
9788
9789   uentry_free (unew);
9790
9791   if (!old->hasNameError)
9792     {
9793       uentry_checkName (old);
9794     }
9795
9796   DPRINTF (("After: %s", uentry_unparseFull (old)));
9797   llassert (!ctype_isUndefined (old->utype));
9798 }
9799
9800 void
9801 uentry_copyState (uentry res, uentry other)
9802 {
9803   llassert (uentry_isValid (res));
9804   llassert (uentry_isValid (other));
9805
9806   res->used = other->used;
9807
9808   res->info->var->kind = other->info->var->kind;
9809   res->info->var->defstate = other->info->var->defstate;
9810   res->info->var->nullstate = other->info->var->nullstate;
9811   res->info->var->checked = other->info->var->checked;
9812
9813   sRef_copyState (res->sref, other->sref);
9814 }
9815
9816 bool
9817 uentry_sameKind (uentry u1, uentry u2)
9818 {
9819   if (uentry_isValid (u1) && uentry_isValid (u2))
9820     {
9821       if (uentry_isVar (u1) && uentry_isVar (u2))
9822         {
9823           ctype c1 = u1->utype;
9824           ctype c2 = u2->utype;
9825
9826           if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9827
9828           /*
9829           ** both functions, or both not functions
9830           */
9831
9832           return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9833         }
9834       else
9835         {
9836           return ((u1->ukind == u2->ukind));
9837         }
9838     }
9839   
9840   return FALSE;
9841 }
9842    
9843 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9844 {
9845   ekind okind;
9846   llassert (uentry_isValid (unew));
9847   llassert (uentry_isValid (old));
9848
9849   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9850   okind = unew->ukind;
9851   unew->ukind = old->ukind;
9852   llassert (cstring_equal (unew->uname, old->uname));
9853   unew->utype = old->utype;
9854
9855   if (fileloc_isDefined (unew->whereSpecified) 
9856       && !fileloc_isDefined (old->whereSpecified))
9857     {
9858       ; /* Keep the old value */
9859     }
9860   else
9861     {
9862       fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9863       unew->whereSpecified = fileloc_copy (old->whereSpecified);
9864     }
9865
9866   if (fileloc_isDefined (unew->whereDefined) 
9867       && !fileloc_isDefined (old->whereDefined))
9868     {
9869       ; /* Keep the old value */
9870     }
9871   else
9872     {
9873       fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9874       unew->whereDefined = fileloc_copy (old->whereDefined);
9875     }
9876
9877   if (fileloc_isDefined (unew->whereDeclared) 
9878       && !fileloc_isDefined (old->whereDeclared))
9879     {
9880       ; /* Keep the old value */
9881     }
9882   else
9883     {
9884       fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9885       unew->whereDeclared = fileloc_copy (old->whereDeclared);
9886     }
9887
9888   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9889
9890   unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9891   unew->used = old->used;
9892   unew->lset = FALSE;
9893   unew->isPrivate = old->isPrivate;
9894   unew->hasNameError = old->hasNameError;
9895   unew->uses = filelocList_append (unew->uses, old->uses);
9896   old->uses = filelocList_undefined;
9897
9898   unew->storageclass = old->storageclass;
9899   uinfo_free (unew->info, okind);
9900   unew->info = uinfo_copy (old->info, old->ukind);
9901 }
9902
9903
9904 uentry
9905 uentry_copy (uentry e)
9906 {
9907   if (uentry_isValid (e))
9908     {
9909       uentry enew = uentry_alloc ();
9910       DPRINTF (("copy: %s", uentry_unparseFull (e)));
9911       enew->ukind = e->ukind;
9912       enew->uname = cstring_copy (e->uname);
9913       enew->utype = e->utype;
9914       
9915       enew->whereSpecified = fileloc_copy (e->whereSpecified);
9916       enew->whereDefined = fileloc_copy (e->whereDefined);
9917       enew->whereDeclared = fileloc_copy (e->whereDeclared);
9918       
9919       enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9920       enew->used = e->used;
9921       enew->lset = FALSE;
9922       enew->isPrivate = e->isPrivate;
9923       enew->hasNameError = e->hasNameError;
9924       enew->uses = filelocList_undefined;
9925       
9926       enew->storageclass = e->storageclass;
9927       enew->info = uinfo_copy (e->info, e->ukind);
9928       enew->warn = warnClause_copy (e->warn);
9929
9930       DPRINTF (("Here we are..."));
9931       DPRINTF (("original: %s", uentry_unparseFull (e)));
9932       DPRINTF (("copy: %s", uentry_unparse (enew)));
9933       DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9934       return enew;
9935     }
9936   else
9937     {
9938       return uentry_undefined;
9939     }
9940 }
9941
9942 void
9943 uentry_setState (uentry res, uentry other)
9944 {
9945   llassert (uentry_isValid (res));
9946   llassert (uentry_isValid (other));
9947
9948   llassert (res->ukind == other->ukind);
9949   llassert (res->ukind == KVAR);
9950
9951   res->sref = sRef_saveCopy (other->sref);
9952   res->used = other->used;
9953   filelocList_free (res->uses); 
9954   res->uses = other->uses; 
9955   other->uses = filelocList_undefined; 
9956   res->lset = other->lset;
9957 }
9958
9959 void
9960 uentry_mergeUses (uentry res, uentry other)
9961 {
9962   llassert (uentry_isValid (res));
9963   llassert (uentry_isValid (other));
9964
9965   res->used = other->used || res->used;
9966   res->lset = other->lset || res->lset;
9967   res->uses = filelocList_append (res->uses, other->uses);
9968   other->uses = filelocList_undefined;
9969 }
9970
9971
9972 /*
9973 ** This is a really ugly routine.
9974 **
9975 ** gack...fix this one day.
9976 */
9977
9978 /*
9979 ** flip == TRUE
9980 **   >> res is the false branch, other is the true branch (or continuation)
9981 ** flip == FALSE
9982 **   >> res is the true branch, other is the false branch (or continutation)
9983 **
9984 ** opt == TRUE if,
9985 **
9986 ** <other>
9987 ** if <res> ;
9988 **
9989 ** References not effected by res are propagated from other.
9990 */
9991
9992 static void
9993 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
9994                   bool flip, clause cl, fileloc loc)
9995 {
9996   if (optgenerror 
9997       (FLG_BRANCHSTATE,
9998        message ("%s %q is %s %s, but %s %s.",
9999                 ekind_capName (res->ukind), uentry_getName (res),
10000                 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10001                 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10002        loc))
10003     {
10004       if (sRef_isDead (res->sref))
10005         {
10006           sRef_showStateInfo (res->sref);
10007           sRef_showStateInfo (other->sref);
10008         }
10009       else if (sRef_isKept (res->sref))
10010         {
10011           sRef_showAliasInfo (res->sref);
10012           sRef_showAliasInfo (other->sref);
10013         }
10014       else /* dependent */
10015         {
10016           sRef_showAliasInfo (res->sref);
10017           sRef_showAliasInfo (other->sref);
10018         }
10019       
10020       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10021     }
10022 }
10023
10024 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10025 {
10026   alkind rk = sRef_getAliasKind (rs);
10027   alkind ok = sRef_getAliasKind (os);
10028
10029   if (alkind_isError (rk) || alkind_isError (ok))
10030     {
10031       return FALSE;
10032     }
10033   else
10034     {
10035       return ((sRef_isDead (rs)
10036                || (alkind_isKept (rk) && !alkind_isKept (ok))
10037                || (alkind_isDependent (rk) 
10038                    && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10039               && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10040     }
10041 }
10042
10043 static void
10044   branchStateAltError (/*@notnull@*/ uentry res,
10045                        /*@notnull@*/ uentry other, bool flip,
10046                        clause cl, fileloc loc)
10047 {
10048   if (optgenerror 
10049       (FLG_BRANCHSTATE,
10050        message ("%s %q is %s %s, but %s %s.",
10051                 ekind_capName (res->ukind), uentry_getName (res),
10052                 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10053                 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10054        loc))
10055     {
10056       if (sRef_isDead (other->sref))
10057         {
10058           sRef_showStateInfo (other->sref);
10059         }
10060       else /* kept */
10061         {
10062           sRef_showAliasInfo (other->sref);
10063         }
10064       
10065       sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10066       sRef_setDefinedComplete (res->sref, fileloc_undefined);
10067       
10068       sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10069       sRef_setDefinedComplete (other->sref, fileloc_undefined);
10070     }
10071 }
10072
10073 /*
10074 ** A reference is relevant for certain checks, only if it 
10075 ** is not definitely null on this path (but not declared
10076 ** to always be null.)
10077 */
10078
10079 static bool uentry_relevantReference (sRef sr, bool flip)
10080 {
10081   if (sRef_isKept (sr) || sRef_isDependent (sr))
10082     {
10083       return FALSE;
10084     }
10085   else
10086     {
10087       if (flip)
10088         {
10089           return !sRef_definitelyNullContext (sr);
10090         }
10091       else
10092         {
10093           return !sRef_definitelyNullAltContext (sr);
10094         }
10095     }
10096 }
10097
10098 static void
10099 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
10100                          fileloc loc, bool mustReturn, bool flip, bool opt,
10101                          clause cl)    
10102 {
10103   sRef rs = res->sref;
10104   sRef os = other->sref;
10105
10106   DPRINTF (("Merge alias states: %s / %s",
10107             uentry_unparseFull (res),
10108             uentry_unparseFull (other)));
10109
10110   if (sRef_isValid (rs))
10111     {
10112       if (!mustReturn)
10113         {
10114           if (uentry_incompatibleMemoryStates (rs, os))
10115             {
10116               DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10117                         sRef_unparseFull (rs), sRef_unparseFull (os)));
10118
10119               if (sRef_isThroughArrayFetch (rs)
10120                   && !context_getFlag (FLG_STRICTBRANCHSTATE))
10121                 {
10122                   if (sRef_isKept (rs) || sRef_isKept (os))
10123                     {
10124                       sRef_maybeKill (rs, loc);
10125                     }
10126                   else if (sRef_isPossiblyDead (os))
10127                     {
10128                       sRef_maybeKill (rs, loc);
10129                     }
10130                   else
10131                     {
10132                       ;
10133                     }
10134                 }
10135               else
10136                 {
10137                   if (uentry_relevantReference (os, flip))
10138                     {
10139                       if (sRef_isLocalParamVar (rs) 
10140                           && (sRef_isLocalState (os) 
10141                               || sRef_isDependent (os)))
10142                         {
10143                           if (sRef_isDependent (rs))
10144                             {
10145                               sRef_setDependent (os, loc);
10146                             }
10147                           else
10148                             {
10149                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10150                             }
10151                         }
10152                       else 
10153                         {
10154                           branchStateError (res, other, flip, cl, loc);
10155                         }
10156                     }
10157                 }
10158               
10159               if (sRef_isKept (rs))
10160                 {
10161                   DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10162                   sRef_setKept (os, loc);
10163                 }
10164             }
10165           else
10166             {
10167               if (uentry_incompatibleMemoryStates (os, rs))
10168                 {
10169                   if (uentry_relevantReference (rs, !flip))
10170                     {
10171                       if (sRef_isLocalParamVar (rs) 
10172                           && (sRef_isDependent (rs)
10173                               || sRef_isLocalState (rs)))
10174                         {
10175                           if (sRef_isDependent (os))
10176                             {
10177                               sRef_setDependent (rs, loc);
10178                             }
10179                           else
10180                             {
10181                               sRef_setDefState (rs, SS_UNUSEABLE, loc);
10182                             }
10183                         }
10184                       else
10185                         {
10186                           if (sRef_isParam (os))
10187                             {
10188                               /* 
10189                               ** If the local variable associated
10190                               ** with the param has the correct state,
10191                               ** its okay.
10192                               ** (e.g., free (s); s = new(); ...
10193                               */
10194                               
10195                               uentry uvar = usymtab_lookupSafe (other->uname);
10196                               
10197                               if (uentry_isValid (uvar)
10198                                   && ((sRef_isDead (os) 
10199                                        && sRef_isOnly (uvar->sref))
10200                                       || (sRef_isDependent (os)
10201                                           && sRef_isOwned (uvar->sref))))
10202                                 {
10203                                   /* no error */
10204                                 }
10205                               else
10206                                 {
10207                                   branchStateAltError (res, other,
10208                                                        flip, cl, loc);
10209                                 }
10210                             }
10211                           else
10212                             {
10213                               DPRINTF (("Here: %s / %s",
10214                                         uentry_unparseFull (res),
10215                                         uentry_unparseFull (other)));
10216
10217                               branchStateAltError (res, other, 
10218                                                    flip, cl, loc);
10219                             }
10220                         }
10221                     }
10222                 }
10223               
10224               if (sRef_isKept (os))
10225                 {
10226                   sRef_setKept (rs, loc);
10227                 }
10228             }
10229           
10230           if (opt)
10231             {
10232               DPRINTF (("Merge opt..."));
10233               sRef_mergeOptState (rs, os, cl, loc);
10234               DPRINTF (("Done!"));
10235             }
10236           else
10237             {
10238               DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10239               sRef_mergeState (rs, os, cl, loc);
10240               DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10241             }
10242         }
10243       else
10244         {
10245           if (sRef_isModified (os))
10246             {
10247               sRef_setModified (rs);
10248             }
10249         }
10250     }
10251
10252   DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10253 }
10254
10255 static void
10256 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10257                          fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10258 {
10259   valueTable rvalues;
10260   valueTable ovalues;
10261
10262   DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10263   
10264   if (mustReturn)
10265     {
10266       return;
10267     }
10268   /* flip? */
10269
10270   rvalues = sRef_getValueTable (res->sref);
10271   ovalues = sRef_getValueTable (other->sref);
10272   
10273   if (valueTable_isUndefined (ovalues))
10274     {
10275       DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10276       ;
10277     }
10278   else if (valueTable_isUndefined (rvalues))
10279     {
10280       /*
10281       ** Copy values from other
10282       */
10283       
10284       /*@i$@#@*/
10285       DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10286       DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10287       ;
10288     }
10289   else
10290     {
10291       valueTable_elements (ovalues, fkey, fval) {
10292         stateValue tval;
10293         metaStateInfo minfo;
10294         stateCombinationTable sctable;
10295         cstring msg;
10296         int nval;
10297
10298         tval = valueTable_lookup (rvalues, fkey);
10299         
10300         DPRINTF (("Merge value: %s / %s X %s", fkey, 
10301                   stateValue_unparse (fval), stateValue_unparse (tval)));
10302
10303         minfo = context_lookupMetaStateInfo (fkey);
10304         llassert (stateValue_isDefined (tval));
10305         
10306         if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval)) 
10307           {
10308             DPRINTF (("Cannot find meta state for: %s", fkey));
10309             BADBRANCH;
10310           }
10311         else
10312           {
10313             llassert (metaStateInfo_isDefined (minfo));
10314
10315             if (stateValue_isError (fval)
10316                 || sRef_definitelyNullContext (res->sref))
10317               {
10318                 sRef_setMetaStateValueComplete (res->sref, 
10319                                                 fkey, stateValue_getValue (fval), 
10320                                                 stateValue_getLoc (fval));
10321                 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10322               }
10323             else if (stateValue_isError (tval)
10324                      || sRef_definitelyNullAltContext (other->sref))
10325               {
10326                 DPRINTF (("Other branch is definitely null!"));
10327               }
10328             else if (sRef_isStateUndefined (res->sref)
10329                      || sRef_isDead (res->sref))
10330               {
10331                 ; /* Combination state doesn't matter if it is undefined or dead */
10332               }
10333             else 
10334               {
10335                 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10336                           metaStateInfo_unparse (minfo),
10337                           stateValue_unparse (fval),
10338                           stateValue_unparse (tval)));
10339                 
10340                 DPRINTF (("state values: %d / %d",
10341                           stateValue_getValue (fval), stateValue_getValue (tval)));
10342                 
10343                 sctable = metaStateInfo_getMergeTable (minfo);
10344
10345                 DPRINTF (("Merge table: %s",
10346                           stateCombinationTable_unparse (sctable)));
10347                 
10348                 msg = cstring_undefined;
10349                 
10350                 nval = stateCombinationTable_lookup (sctable, 
10351                                                      stateValue_getValue (fval), 
10352                                                      stateValue_getValue (tval), 
10353                                                      &msg);
10354
10355                 DPRINTF (("nval: %d / %d / %d", nval,
10356                           stateValue_getValue (fval), stateValue_getValue (tval)));
10357
10358                 if (nval == stateValue_error)
10359                   {
10360                     /*@i32 print extra info for assignments@*/
10361
10362                     if (uentry_isGlobalMarker (res))
10363                       {
10364                         if (optgenerror 
10365                             (FLG_STATEMERGE,
10366                              message
10367                              ("Control branches merge with incompatible global states (%s and %s)%q",
10368                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10369                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10370                               cstring_isDefined (msg) 
10371                               ? message (": %s", msg) : cstring_undefined),
10372                              loc))
10373                           {
10374                             sRef_showMetaStateInfo (res->sref, fkey);
10375                             sRef_showMetaStateInfo (other->sref, fkey);
10376                           }
10377                       }
10378                     else
10379                       {
10380                         if (optgenerror 
10381                             (FLG_STATEMERGE,
10382                              message
10383                              ("Control branches merge with incompatible states for %q (%s and %s)%q",
10384                               uentry_getName (res),
10385                               metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10386                               metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10387                               cstring_isDefined (msg) 
10388                               ? message (": %s", msg) : cstring_undefined),
10389                              loc))
10390                           {
10391                             sRef_showMetaStateInfo (res->sref, fkey);
10392                             sRef_showMetaStateInfo (other->sref, fkey);
10393                             DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10394                             DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10395                             DPRINTF (("Null: %s / %s",
10396                                       bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10397                                       bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10398
10399                           }
10400                       }
10401                   }
10402
10403                 if (nval == stateValue_getValue (fval)
10404                     && nval != stateValue_getValue (tval))
10405                   {
10406                     loc = stateValue_getLoc (fval);
10407                   }
10408                 else if (nval == stateValue_getValue (tval)
10409                          && nval != stateValue_getValue (fval))
10410                   {
10411                     loc = stateValue_getLoc (tval);
10412                   }
10413                 else
10414                   {
10415                     ;
10416                   }
10417
10418                 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10419                     && nval == stateValue_getValue (fval)
10420                     && nval == stateValue_getValue (tval))
10421                   {
10422                     ;
10423                   }
10424                 else
10425                   {
10426                     sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10427                   }
10428               }
10429           }
10430       } end_valueTable_elements ;
10431     } 
10432 }
10433
10434
10435 static void
10436 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10437                        /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10438                        bool flip, clause cl)
10439 {
10440   if (cl == DOWHILECLAUSE)
10441     {
10442       res->used = other->used || res->used;
10443       res->lset = other->lset || res->lset;
10444       res->uses = filelocList_append (res->uses, other->uses);
10445       other->uses = filelocList_undefined;
10446     }
10447   else
10448     {
10449       if (sRef_isMacroParamRef (res->sref)
10450           && !uentry_isSefParam (other)
10451           && !uentry_isSefParam (res))
10452         {
10453           bool hasError = FALSE;
10454           
10455           if (bool_equal (res->used, other->used))
10456             {
10457               res->used = other->used;
10458             }
10459           else
10460             {
10461               if (other->used && !flip)
10462                 {
10463                   hasError = 
10464                     optgenerror 
10465                     (FLG_MACROPARAMS,
10466                      message ("Macro parameter %q used in true clause, "
10467                               "but not in false clause",
10468                               uentry_getName (res)),
10469                      uentry_whereDeclared (res));
10470                 }
10471               else
10472                 {       
10473                   hasError = 
10474                     optgenerror 
10475                     (FLG_MACROPARAMS,
10476                      message ("Macro parameter %q used in false clause, "
10477                               "but not in true clause",
10478                               uentry_getName (res)),
10479                      uentry_whereDeclared (res));
10480                 }
10481               res->used = TRUE;
10482               
10483               if (hasError)
10484                 {
10485                   /* make it sef now, prevent more errors */
10486                   res->info->var->kind = VKREFSEFPARAM;
10487                 }
10488             }
10489         }
10490       else
10491         {
10492           res->used = other->used || res->used;
10493           res->lset = other->lset || res->lset;
10494           res->uses = filelocList_append (res->uses, other->uses);
10495           other->uses = filelocList_undefined;
10496         }
10497     }
10498 }
10499
10500 void
10501 uentry_mergeState (uentry res, uentry other, fileloc loc,
10502                    bool mustReturn, bool flip, bool opt,
10503                    clause cl)
10504 {
10505   llassert (uentry_isValid (res));
10506   llassert (uentry_isValid (other));
10507
10508   llassert (res->ukind == other->ukind);
10509   llassert (res->ukind == KVAR);
10510
10511   DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10512             uentry_unparseFull (other)));
10513   
10514   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10515   uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10516   uentry_mergeSetStates (res, other, loc, flip, cl);
10517
10518   DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10519 }
10520
10521 void uentry_setUsed (uentry e, fileloc loc)
10522 {
10523   static bool firstTime = TRUE;
10524   static bool showUses = FALSE;
10525   static bool exportLocal = FALSE;
10526
10527   DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10528
10529   if (firstTime)
10530     {
10531       /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10532
10533       showUses = context_getFlag (FLG_SHOWUSES); 
10534       exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10535
10536       firstTime = FALSE;
10537     }
10538
10539   if (uentry_isValid (e))
10540     {
10541       int dp;
10542
10543       if (warnClause_isDefined (e->warn))
10544         {
10545           flagSpec flg = warnClause_getFlag (e->warn);
10546           cstring msg;
10547
10548           if (warnClause_hasMessage (e->warn))
10549             {
10550               msg = cstring_copy (warnClause_getMessage (e->warn));
10551             }
10552           else
10553             {
10554               msg = message ("Use of possibly dangerous %s",
10555                              uentry_ekindNameLC (e));
10556             }
10557
10558           vfsgenerror (flg, 
10559                        message ("%q: %q", msg, uentry_getName (e)),
10560                        loc);
10561         }
10562
10563       if (sRef_isMacroParamRef (e->sref))
10564         {
10565           if (uentry_isYield (e) || uentry_isSefParam (e))
10566             {
10567               ;
10568             }
10569           else 
10570             {
10571               if (context_inConditional ())
10572                 {
10573                   if (optgenerror
10574                       (FLG_MACROPARAMS,
10575                        message ("Macro parameter %q used in conditionally "
10576                                 "executed code (may or may not be "
10577                                 "evaluated exactly once)", 
10578                                 uentry_getName (e)),
10579                        loc))
10580                     {
10581                       e->info->var->kind = VKREFSEFPARAM;
10582                     }
10583                 }
10584               else
10585                 {
10586                   if ((e)->used)
10587                     {
10588                       if (optgenerror
10589                           (FLG_MACROPARAMS,
10590                            message ("Macro parameter %q used more than once", 
10591                                     uentry_getName (e)),
10592                            uentry_whereDeclared (e)))
10593                         {
10594                           e->info->var->kind = VKREFSEFPARAM;
10595                         }
10596                     }
10597                 }
10598             }
10599         }
10600       
10601       if ((dp = uentry_directParamNo (e)) >= 0)
10602         {
10603           uentry_setUsed (usymtab_getParam (dp), loc);
10604         }
10605       
10606       e->used = TRUE;
10607
10608       if (!sRef_isLocalVar (e->sref))
10609         {
10610           if (showUses)
10611             {
10612               e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10613             }
10614           else 
10615             {
10616               if (exportLocal)
10617                 {
10618                   if (context_inMacro ())
10619                     {
10620                       e->uses = filelocList_addUndefined (e->uses);
10621                     }
10622                   else 
10623                     {
10624                       e->uses = filelocList_addDifferentFile
10625                         (e->uses, 
10626                          uentry_whereDeclared (e),
10627                          loc);
10628                     }
10629                 }
10630             }
10631         }
10632     }
10633 }
10634
10635 bool uentry_isReturned (uentry u)
10636 {
10637   return (uentry_isValid (u) && uentry_isVar (u) 
10638           && (u->info->var->kind == VKRETPARAM
10639               || u->info->var->kind == VKSEFRETPARAM));
10640 }
10641
10642 /*@i52323@*/
10643 # if 0
10644 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10645 {
10646   llassert (uentry_isRealFunction (u));
10647
10648   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10649     {
10650       stateClauseList clauses = uentry_getStateClauseList (u);
10651       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10652
10653       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10654       sRef_setAllocated (res, g_currentloc);
10655
10656       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10657                 stateClauseList_unparse (clauses)));
10658
10659       /*
10660       ** This should be in exprNode_reflectEnsuresClause
10661       */
10662
10663       stateClauseList_postElements (clauses, cl)
10664         {
10665           if (!stateClause_isGlobal (cl))
10666             {
10667               sRefSet refs = stateClause_getRefs (cl);
10668               sRefMod modf = stateClause_getEffectFunction (cl);
10669               
10670               sRefSet_elements (refs, el)
10671                 {
10672                   sRef base = sRef_getRootBase (el);
10673                   
10674                   if (sRef_isResult (base))
10675                     {
10676                       if (modf != NULL)
10677                         {
10678                           sRef sr = sRef_fixBase (el, res);
10679                           modf (sr, g_currentloc);
10680                         }
10681                     }
10682                   else
10683                     {
10684                       ;
10685                     }
10686                 } end_sRefSet_elements ;
10687             }
10688         } end_stateClauseList_postElements ;
10689         
10690       return res;
10691     }
10692   else
10693     {
10694       uentryList params;
10695       alkind ak;
10696       sRefSet prefs = sRefSet_new ();
10697       sRef res = sRef_undefined;
10698       sRef tcref = sRef_undefined;
10699       sRef tref = sRef_undefined;
10700       int paramno = 0;
10701       
10702       params = uentry_getParams (u);
10703
10704       /*
10705       ** Setting up aliases has to happen *after* setting null state!
10706       */
10707
10708       uentryList_elements (params, current)
10709         {
10710           if (uentry_isReturned (current))
10711             {
10712               if (exprNodeList_size (args) >= paramno)
10713                 {
10714                   exprNode ecur = exprNodeList_nth (args, paramno);
10715                   tref = exprNode_getSref (ecur);
10716                   
10717                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10718
10719                   if (sRef_isValid (tref))
10720                     {
10721                       tcref = sRef_copy (tref);
10722                       
10723                       if (sRef_isDead (tcref))
10724                         {
10725                           sRef_setDefined (tcref, g_currentloc);
10726                           sRef_setOnly (tcref, g_currentloc);
10727                         }
10728                       
10729                       if (sRef_isRefCounted (tcref))
10730                         {
10731                           /* could be a new ref now (but only if its returned) */
10732                           sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10733                         }
10734                       
10735                       sRef_makeSafe (tcref);
10736                       prefs = sRefSet_insert (prefs, tcref);
10737                     }
10738                 }
10739             }
10740           
10741           paramno++;
10742         } end_uentryList_elements ;
10743
10744       if (sRefSet_size (prefs) > 0)
10745         {
10746           nstate n = sRef_getNullState (u->sref);
10747
10748           if (sRefSet_size (prefs) == 1)
10749             {
10750               sRef rref = sRefSet_choose (prefs);
10751               tref = rref;
10752               res = sRef_makeType (sRef_getType (rref));
10753               sRef_copyState (res, tref);
10754             }
10755           else
10756             {
10757               /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10758               res = sRefSet_mergeIntoOne (prefs);
10759             }
10760           
10761           if (nstate_isKnown (n))
10762             {
10763               sRef_setNullState (res, n, g_currentloc);
10764               DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10765             }
10766         }
10767       else
10768         {
10769           if (ctype_isFunction (u->utype))
10770             {
10771               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10772               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10773             }
10774           else
10775             {
10776               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10777               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10778             }
10779           
10780           if (sRef_isRefCounted (res))
10781             {
10782               sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10783             }
10784         }
10785       
10786       if (sRef_getNullState (res) == NS_ABSNULL)
10787         {
10788           ctype ct = ctype_realType (u->utype);
10789           
10790           if (ctype_isAbstract (ct))
10791             {
10792               sRef_setNotNull (res, g_currentloc);
10793             }
10794           else
10795             {
10796               if (ctype_isUser (ct))
10797                 {
10798                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10799                 }
10800               else
10801                 {
10802                   sRef_setNotNull (res, g_currentloc);
10803                 }
10804             }
10805         }
10806       
10807       if (sRef_isRefCounted (res))
10808         {
10809           sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10810         }
10811       else if (sRef_isKillRef (res))
10812         {
10813           sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10814         }
10815       else
10816         {
10817           ;
10818         }
10819       
10820       ak = sRef_getAliasKind (res);
10821       
10822       if (alkind_isImplicit (ak))
10823         {
10824           sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10825         }
10826
10827 # if 0
10828       DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10829       usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10830
10831       /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10832       usymtab_addReallyForceMustAlias (res, tref);
10833 # endif
10834
10835       sRefSet_free (prefs);
10836       
10837       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10838       return res;
10839     }
10840 }
10841 # endif
10842
10843 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10844 {
10845   llassert (uentry_isRealFunction (u));
10846
10847   if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10848     {
10849       stateClauseList clauses = uentry_getStateClauseList (u);
10850       sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10851
10852       DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10853       sRef_setAllocated (res, g_currentloc);
10854
10855       DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
10856                 stateClauseList_unparse (clauses)));
10857
10858       /*
10859       ** This should be in exprNode_reflectEnsuresClause
10860       */
10861
10862       stateClauseList_postElements (clauses, cl)
10863         {
10864           if (!stateClause_isGlobal (cl))
10865             {
10866               sRefSet refs = stateClause_getRefs (cl);
10867               sRefMod modf = stateClause_getEffectFunction (cl);
10868               
10869               sRefSet_elements (refs, el)
10870                 {
10871                   sRef base = sRef_getRootBase (el);
10872                   
10873                   if (sRef_isResult (base))
10874                     {
10875                       if (modf != NULL)
10876                         {
10877                           sRef sr = sRef_fixBase (el, res);
10878                           modf (sr, g_currentloc);
10879                         }
10880                     }
10881                   else
10882                     {
10883                       ;
10884                     }
10885                 } end_sRefSet_elements ;
10886             }
10887         } end_stateClauseList_postElements ;
10888         
10889       return res;
10890     }
10891   else
10892     {
10893       uentryList params;
10894       alkind ak;
10895       sRefSet prefs = sRefSet_new ();
10896       sRef res = sRef_undefined;
10897       int paramno = 0;
10898       
10899       params = uentry_getParams (u);
10900       
10901       uentryList_elements (params, current)
10902         {
10903           if (uentry_isReturned (current))
10904             {
10905               if (exprNodeList_size (args) >= paramno)
10906                 {
10907                   exprNode ecur = exprNodeList_nth (args, paramno);
10908                   sRef tref = exprNode_getSref (ecur);
10909                   
10910                   DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10911
10912                   if (sRef_isValid (tref))
10913                     {
10914                       sRef tcref = sRef_copy (tref);
10915                       
10916                       usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10917
10918                       if (sRef_isDead (tcref))
10919                         {
10920                           sRef_setDefined (tcref, g_currentloc);
10921                           sRef_setOnly (tcref, g_currentloc);
10922                         }
10923                       
10924                       if (sRef_isRefCounted (tcref))
10925                         {
10926                           /* could be a new ref now (but only if its returned) */
10927                           sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10928                         }
10929                       
10930                       sRef_makeSafe (tcref);
10931                       prefs = sRefSet_insert (prefs, tcref);
10932                     }
10933                 }
10934             }
10935           
10936           paramno++;
10937         } end_uentryList_elements ;
10938       
10939       if (sRefSet_size (prefs) > 0)
10940         {
10941           nstate n = sRef_getNullState (u->sref);
10942           
10943           if (sRefSet_size (prefs) == 1)
10944             {
10945               res = sRefSet_choose (prefs);
10946             }
10947           else
10948             {
10949               /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10950               res = sRefSet_mergeIntoOne (prefs);
10951             }
10952           
10953           if (nstate_isKnown (n))
10954             {
10955               sRef_setNullState (res, n, g_currentloc);
10956             }
10957         }
10958       else
10959         {
10960           if (ctype_isFunction (u->utype))
10961             {
10962               DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
10963               res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10964             }
10965           else
10966             {
10967               res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10968             }
10969           
10970           if (sRef_isRefCounted (res))
10971             {
10972               sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10973             }
10974         }
10975       
10976
10977       if (sRef_getNullState (res) == NS_ABSNULL)
10978         {
10979           ctype ct = ctype_realType (u->utype);
10980           
10981           if (ctype_isAbstract (ct))
10982             {
10983               sRef_setNotNull (res, g_currentloc);
10984             }
10985           else
10986             {
10987               if (ctype_isUser (ct))
10988                 {
10989                   sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10990                 }
10991               else
10992                 {
10993                   sRef_setNotNull (res, g_currentloc);
10994                 }
10995             }
10996         }
10997       
10998       if (sRef_isRefCounted (res))
10999         {
11000           sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
11001         }
11002       else if (sRef_isKillRef (res))
11003         {
11004           sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
11005         }
11006       else
11007         {
11008           ;
11009         }
11010       
11011       ak = sRef_getAliasKind (res);
11012       
11013       if (alkind_isImplicit (ak))
11014         {
11015           sRef_setAliasKind (res, 
11016                              alkind_fixImplicit (ak),
11017                              g_currentloc);
11018         }
11019       
11020       sRefSet_free (prefs);
11021       
11022       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11023       return res;
11024     }
11025 }
11026
11027 static bool uentry_isRefCounted (uentry ue)
11028 {
11029   ctype ct = uentry_getType (ue);
11030
11031   if (ctype_isFunction (ct))
11032     {
11033       return (ctype_isRefCounted (ctype_getReturnType (ct)));
11034     }
11035   else
11036     {
11037       return (ctype_isRefCounted (ct));
11038     }
11039 }
11040
11041 /*
11042 ** old was declared yield in the specification.  
11043 ** new is declared in the iter implementation.
11044 */
11045
11046 void uentry_checkYieldParam (uentry old, uentry unew)
11047 {
11048   cstring name;
11049
11050   llassert (uentry_isVariable (old));
11051   llassert (uentry_isVariable (unew));
11052
11053   unew->info->var->kind = VKYIELDPARAM;
11054   (void) checkTypeConformance (old, unew, TRUE);
11055   checkVarConformance (old, unew, TRUE, FALSE);
11056
11057   /* get rid of param marker */
11058
11059   name = uentry_getName (unew);
11060   cstring_free (unew->uname);
11061   unew->uname = name;
11062   unew->info->var->kind = VKREFYIELDPARAM;
11063
11064   uentry_setUsed (old, fileloc_undefined);
11065   uentry_setUsed (unew, fileloc_undefined);
11066 }
11067
11068 /*@observer@*/ cstring
11069 uentry_ekindName (uentry ue)
11070 {
11071   if (uentry_isValid (ue))
11072     {
11073       switch (ue->ukind)
11074         {
11075         case KINVALID:
11076           return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11077         case KDATATYPE: 
11078           return cstring_makeLiteralTemp ("Datatype");
11079         case KENUMCONST:
11080           return cstring_makeLiteralTemp ("Enum member");
11081         case KCONST:  
11082           return cstring_makeLiteralTemp ("Constant");
11083         case KVAR:      
11084           if (uentry_isParam (ue))
11085             {
11086               return cstring_makeLiteralTemp ("Parameter");
11087             }
11088           else if (uentry_isExpandedMacro (ue))
11089             {
11090               return cstring_makeLiteralTemp ("Expanded macro");
11091             }
11092           else
11093             {
11094               return cstring_makeLiteralTemp ("Variable");
11095             }
11096         case KFCN:   
11097           return cstring_makeLiteralTemp ("Function");
11098         case KITER: 
11099           return cstring_makeLiteralTemp ("Iterator");
11100         case KENDITER:
11101           return cstring_makeLiteralTemp ("Iterator finalizer");
11102         case KSTRUCTTAG:
11103           return cstring_makeLiteralTemp ("Struct tag");
11104         case KUNIONTAG:
11105           return cstring_makeLiteralTemp ("Union tag");
11106         case KENUMTAG: 
11107           return cstring_makeLiteralTemp ("Enum tag");
11108         case KELIPSMARKER: 
11109           return cstring_makeLiteralTemp ("Optional parameters");
11110         }
11111     }
11112   else
11113     {
11114       return cstring_makeLiteralTemp ("<Undefined>");
11115     }
11116
11117   BADEXIT;
11118 }
11119
11120 /*@observer@*/ cstring
11121 uentry_ekindNameLC (uentry ue)
11122 {
11123   if (uentry_isValid (ue))
11124     {
11125       switch (ue->ukind)
11126         {
11127         case KINVALID:
11128           return cstring_makeLiteralTemp ("<error: invalid uentry>");
11129         case KDATATYPE: 
11130           return cstring_makeLiteralTemp ("datatype");
11131         case KENUMCONST:
11132           return cstring_makeLiteralTemp ("enum member");
11133         case KCONST:  
11134           return cstring_makeLiteralTemp ("constant");
11135         case KVAR:      
11136           if (uentry_isParam (ue))
11137             {
11138               return cstring_makeLiteralTemp ("parameter");
11139             }
11140           else if (uentry_isExpandedMacro (ue))
11141             {
11142               return cstring_makeLiteralTemp ("expanded macro");
11143             }
11144           else
11145             {
11146               return cstring_makeLiteralTemp ("variable");
11147             }
11148         case KFCN:   
11149           return cstring_makeLiteralTemp ("function");
11150         case KITER: 
11151           return cstring_makeLiteralTemp ("iterator");
11152         case KENDITER:
11153           return cstring_makeLiteralTemp ("iterator finalizer");
11154         case KSTRUCTTAG:
11155           return cstring_makeLiteralTemp ("struct tag");
11156         case KUNIONTAG:
11157           return cstring_makeLiteralTemp ("union tag");
11158         case KENUMTAG: 
11159           return cstring_makeLiteralTemp ("enum tag");
11160         case KELIPSMARKER: 
11161           return cstring_makeLiteralTemp ("optional parameters");
11162         }
11163     }
11164   else
11165     {
11166       return cstring_makeLiteralTemp ("<Undefined>");
11167     }
11168
11169   BADEXIT;
11170 }
11171
11172 void uentry_setHasNameError (uentry ue)
11173 {
11174   llassert (uentry_isValid (ue));
11175
11176   ue->hasNameError = TRUE;
11177 }
11178
11179 void uentry_checkName (uentry ue)
11180 {
11181   DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11182             uentry_observeRealName (ue),
11183             bool_unparse (uentry_isVisibleExternally (ue))));
11184   
11185   if (uentry_isValid (ue) 
11186       && !context_inXHFile ()
11187       && uentry_hasName (ue)
11188       && !uentry_isElipsisMarker (ue)
11189       && context_getFlag (FLG_NAMECHECKS)
11190       && !ue->hasNameError 
11191       && !uentry_isEndIter (ue)
11192       && !fileloc_isBuiltin (uentry_whereLast (ue))
11193       && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11194     {      
11195       DPRINTF (("Here..."));
11196
11197       if (uentry_isPriv (ue))
11198         {
11199           ; /* any checks here? */
11200         }
11201       else if (fileloc_isExternal (uentry_whereDefined (ue)))
11202         {
11203           ; /* no errors for externals */
11204         }
11205       else
11206         {
11207           int scope;
11208           
11209           if (uentry_isExpandedMacro (ue))
11210             {
11211               scope = globScope;
11212             }
11213           else
11214             {
11215               if (uentry_isExpandedMacro (ue))
11216                 {
11217                   scope = fileScope;
11218                 }
11219               else if (uentry_isVariable (ue))
11220                 {
11221                   sRef sr = uentry_getSref (ue);
11222
11223                   if (sRef_isValid (sr))
11224                     {
11225                       scope = sRef_getScope (sr);
11226                     }
11227                   else
11228                     {
11229                       scope = fileScope; 
11230                     }
11231                 }
11232               else if (uentry_isFunction (ue)
11233                        || uentry_isIter (ue)
11234                        || uentry_isEndIter (ue)
11235                        || uentry_isConstant (ue))
11236                 {
11237                   scope = uentry_isStatic (ue) ? fileScope : globScope;
11238                 }
11239               else /* datatypes, etc. must be global */
11240                 {
11241                   scope = globScope;
11242                 }
11243               
11244               usymtab_checkDistinctName (ue, scope);
11245             }
11246         
11247           if (context_getFlag (FLG_CPPNAMES)) 
11248             {
11249               checkCppName (ue);
11250             }
11251
11252           if (scope == globScope)
11253             {
11254               checkExternalName (ue);
11255             }
11256           else if (scope == fileScope)
11257             {
11258               checkFileScopeName (ue);
11259             }
11260           else 
11261             {
11262               checkLocalName (ue);
11263             }
11264
11265           checkPrefix (ue);
11266           checkAnsiName (ue);
11267         }
11268     }
11269 }
11270
11271 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11272 {
11273   uentry ue;
11274   fileloc tloc;
11275
11276   /*
11277   ** Can't but unrecognized ids in macros in global scope, because srefs will break! 
11278   */
11279
11280   if (!context_inMacro ())
11281     {
11282       sRef_setGlobalScopeSafe ();
11283     }
11284
11285   ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11286   uentry_setUsed (ue, loc);               
11287   
11288   tloc = fileloc_createExternal ();
11289   uentry_setDefined (ue, tloc);
11290   fileloc_free (tloc);
11291   uentry_setHasNameError (ue);
11292   
11293   if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11294     {
11295       uentry_markOwned (ue);
11296     }
11297   else
11298     {
11299       ue = usymtab_supReturnFileEntry (ue);
11300     }
11301   
11302   if (!context_inMacro ())
11303     {
11304       sRef_clearGlobalScopeSafe ();
11305     }
11306
11307   return ue;
11308 }
11309
11310 uentry uentry_makeGlobalMarker ()
11311 {
11312   uentry ue;
11313   fileloc tloc;
11314
11315   llassert (sRef_inGlobalScope ());
11316   
11317   ue = uentry_makeVariableAux
11318     (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined, 
11319      sRef_makeGlobalMarker (),
11320      FALSE, VKNORMAL);
11321
11322   tloc = fileloc_createExternal ();
11323   uentry_setUsed (ue, tloc);              
11324   uentry_setDefined (ue, tloc);
11325   fileloc_free (tloc);
11326   uentry_setHasNameError (ue);  
11327
11328   return ue;
11329 }
11330
11331
11332 bool uentry_isGlobalMarker (uentry ue)
11333 {
11334   return (uentry_isValid (ue)
11335           && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11336 }
11337
11338 /* new start modifications */
11339
11340 /* start modifications */
11341 /*
11342 requires: p_e is defined, is a ptr/array variable 
11343 modifies: p_e
11344 effects: sets the state of the variable
11345 */
11346
11347
11348 void uentry_setPossiblyNullTerminatedState (uentry p_e)  
11349 {
11350   llassert (uentry_isValid (p_e));
11351
11352   if (p_e->info != NULL)
11353     {
11354       if (p_e->info->var != NULL) 
11355         {
11356           llassert (p_e->info->var->bufinfo != NULL);
11357           p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11358           sRef_setPossiblyNullTerminatedState (p_e->sref);
11359         }
11360     }
11361 }
11362
11363 /*
11364 requires: p_e is defined, is a ptr/array variable 
11365 modifies: p_e
11366 effects: sets the size of the buffer
11367 */
11368
11369 void uentry_setNullTerminatedState (uentry p_e)  {
11370   llassert (uentry_isValid (p_e));
11371
11372   if (p_e->info != NULL)
11373     {
11374       if (p_e->info->var != NULL)
11375         {
11376           llassert (p_e->info->var->bufinfo != NULL);
11377           p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11378           sRef_setNullTerminatedState (p_e->sref);
11379         }
11380     }
11381 }
11382
11383 /*
11384 requires: p_e is defined, is a ptr/array variable 
11385 modifies: p_e
11386 effects: sets the size of the buffer
11387 */
11388
11389 void uentry_setSize (uentry p_e, int size)  
11390 {
11391   if (uentry_isValid (p_e))
11392     {
11393       if (p_e->info != NULL) 
11394         {
11395           if (p_e->info->var != NULL) 
11396             {
11397               llassert (p_e->info->var->bufinfo != NULL);
11398               p_e->info->var->bufinfo->size = size;
11399               sRef_setSize (p_e->sref, size);
11400             }
11401         }
11402     }
11403 }
11404
11405 /*
11406 requires: p_e is defined, is a ptr/array variable 
11407 modifies: p_e
11408 effects: sets the length of the buffer
11409 */
11410
11411 void uentry_setLen (uentry p_e, int len)  
11412 {
11413   if (uentry_isValid (p_e)) 
11414     {
11415       if (p_e->info != NULL
11416           && p_e->info->var != NULL) 
11417         {
11418           llassert (p_e->info->var->bufinfo != NULL);
11419           p_e->info->var->bufinfo->len = len;
11420           sRef_setLen (p_e->sref, len);
11421         }
11422     }
11423 }
11424
11425 /*@=type*/
11426
11427 bool uentry_hasMetaStateEnsures (uentry e)
11428 {
11429   if (uentry_isValid (e) && uentry_isFunction (e))
11430     {
11431       return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11432     }
11433   else
11434     {
11435       return FALSE;
11436     }
11437 }
11438
11439 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11440 {
11441   llassert (uentry_isValid (e) && uentry_isFunction (e));
11442   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11443 }
11444
11445 # ifdef DEBUGSPLINT
11446
11447 /*
11448 ** For debugging only
11449 */
11450
11451 void uentry_checkValid (uentry ue)
11452 {
11453   if (uentry_isValid (ue))
11454     {
11455       sRef_checkCompletelyReasonable (ue->sref);
11456     }
11457 }
11458
11459 # endif
This page took 1.021641 seconds and 5 git commands to generate.