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