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