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