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