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