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