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