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