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