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