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