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