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