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