]> andersk Git - splint.git/blame - src/uentry.c
Temporarily set flags to splintme without warnings.
[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
146e25eb 46static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_msgstream@*/ ;
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,
89 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
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{
5e211f69 3155 return (uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ()));
3156}
3157
3e3ec469 3158/*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
5e211f69 3159{
3160 return (uentry_makeConstantAux (n, t, f, priv, FALSE, val));
3161}
3162
3163/*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3164{
3165 return (uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ()));
616915dd 3166}
3167
3168/*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3169{
3170 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3171 idDecl_getCtype (t),
3172 fileloc_undefined);
3173
3174 llassert (fileloc_isUndefined (ue->whereDeclared));
3175 ue->whereDeclared = setLocation ();
616915dd 3176 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3177
b9904f57 3178 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
7534721d 3179 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
616915dd 3180 return ue;
3181}
3182
3183/*
3184** variables
3185*/
3186
3187void uentry_setDefState (uentry ue, sstate defstate)
3188{
3189 if (uentry_isValid (ue))
3190 {
3191 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3192
3193 if (uentry_isVariable (ue))
3194 {
3195 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3196 }
3197 }
3198}
3199
3200bool uentry_isCheckedUnknown (uentry ue)
3201{
3202 return (uentry_isVar (ue)
3203 && (ue->info->var->checked == CH_UNKNOWN));
3204}
3205
3206bool uentry_isCheckMod (uentry ue)
3207{
3208 return (uentry_isVar (ue)
3209 && (ue->info->var->checked == CH_CHECKMOD));
3210}
3211
3212bool uentry_isUnchecked (uentry ue)
3213{
3214 return (uentry_isVar (ue)
3215 && (ue->info->var->checked == CH_UNCHECKED));
3216}
3217
3218bool uentry_isChecked (uentry ue)
3219{
3220 return (uentry_isVar (ue)
3221 && (ue->info->var->checked == CH_CHECKED));
3222}
3223
3224bool uentry_isCheckedModify (uentry ue)
3225{
3226 return (uentry_isVar (ue)
3227 && (ue->info->var->checked == CH_CHECKED
3228 || ue->info->var->checked == CH_CHECKMOD
3229 || ue->info->var->checked == CH_CHECKEDSTRICT));
3230}
3231
3232bool uentry_isCheckedStrict (uentry ue)
3233{
3234 return (uentry_isVar (ue)
3235 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3236}
3237
3238void uentry_setUnchecked (uentry ue)
3239{
3240 llassert (uentry_isVar (ue));
3241
3242 ue->info->var->checked = CH_UNCHECKED;
3243}
3244
3245void uentry_setChecked (uentry ue)
3246{
3247 llassert (uentry_isVar (ue));
3248
3249 ue->info->var->checked = CH_CHECKED;
3250}
3251
3252void uentry_setCheckMod (uentry ue)
3253{
3254 llassert (uentry_isVar (ue));
3255
3256 ue->info->var->checked = CH_CHECKMOD;
3257}
3258
3259void uentry_setCheckedStrict (uentry ue)
3260{
3261 llassert (uentry_isVar (ue));
3262
3263 ue->info->var->checked = CH_CHECKEDSTRICT;
3264}
3265
3266static /*@only@*/ /*@notnull@*/
abd7f895 3267uentry uentry_makeVariableAux (cstring n, ctype t,
3268 fileloc f,
3269 /*@exposed@*/ sRef s,
3270 bool priv, vkind kind)
616915dd 3271{
3272 uentry e = uentry_alloc ();
3273 ctype rt = t;
abd7f895 3274
616915dd 3275 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3276
3277 e->ukind = KVAR;
3278 e->uname = cstring_copy (n);
3279 e->utype = t;
3280
3281 e->storageclass = SCNONE;
3282
28bf4b0b 3283 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3284
616915dd 3285 e->sref = s;
3286
3287 e->used = FALSE;
3288 e->lset = FALSE;
3289
3290 e->uses = filelocList_new ();
3291 e->isPrivate = priv;
3292 e->hasNameError = FALSE;
3293
3294 e->info = (uinfo) dmalloc (sizeof (*e->info));
3295 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3296 e->info->var->kind = kind;
3297
b7e84605 3298 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
616915dd 3299 e->info->var->checked = CH_UNKNOWN;
3300
28bf4b0b 3301 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3302 uentry_setSpecDef (e, f);
28bf4b0b 3303 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3304
3305 if (ctype_isFunction (rt))
3306 {
28bf4b0b 3307 rt = ctype_getReturnType (rt);
616915dd 3308 }
3309
3310 if (ctype_isUA (rt))
3311 {
28bf4b0b 3312 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3313 sRef_setStateFromType (e->sref, rt);
3314 }
3315
28bf4b0b 3316 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3317 e->info->var->defstate = sRef_getDefState (e->sref);
3318 e->info->var->nullstate = sRef_getNullState (e->sref);
3319
6970c11b 3320 /* start modifications */
3321 /* This function sets the uentry for a pointer or array variable declaration,
3322 it allocates memory and sets the fields. We check if the type of the variable
3323 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3324
abd7f895 3325 if (ctype_isArray (t) || ctype_isPointer(t))
3326 {
3327 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3328 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3329 sRef_setNotNullTerminatedState (s);
3330 }
3331 else
3332 {
3333 e->info->var->bufinfo = NULL;
3334 }/* end else */
3335 /* end modification */
616915dd 3336
3337 return (e);
3338}
3339
3340bool
3341uentry_isYield (uentry ue)
3342{
3343 return (uentry_isVariable (ue)
3344 && (ue->info->var->kind == VKYIELDPARAM
3345 || ue->info->var->kind == VKREFYIELDPARAM));
3346}
3347
3348static bool
3349uentry_isRefsField (uentry ue)
3350{
3351 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3352}
3353
3354/*@only@*/ /*@notnull@*/
3355uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3356{
3357 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3358 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3359}
3360
3361/*
3362** functions
3363*/
3364
3365void uentry_makeVarFunction (uentry ue)
3366{
3367 alkind ak;
3368 exkind ek;
3369 uvinfo oldInfo;
3370 fileloc loc;
3371
3372 llassert (uentry_isValid (ue));
3373 llassert (!sRef_modInFunction ());
3374
3375 ak = sRef_getOrigAliasKind (ue->sref);
3376 ek = sRef_getOrigExKind (ue->sref);
3377
b072092f 3378 llassert (uentry_isVariable (ue));
616915dd 3379 oldInfo = ue->info->var;
3380
ac35a6ab 3381 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3382 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
616915dd 3383
3384 /*
ac35a6ab 3385 ** expanded macro is marked used
616915dd 3386 */
3387
efd360a3 3388 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
616915dd 3389
3390 ue->ukind = KFCN;
3391 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3392 ue->info->fcn->exitCode = XK_UNKNOWN;
28bf4b0b 3393 ue->info->fcn->nullPred = qual_createUnknown ();
616915dd 3394 ue->info->fcn->specialCode = SPC_NONE;
3395 ue->info->fcn->access = typeIdSet_undefined;
3396 ue->info->fcn->hasGlobs = FALSE;
3397 ue->info->fcn->globs = globSet_undefined;
3398 ue->info->fcn->hasMods = FALSE;
3399 ue->info->fcn->mods = sRefSet_undefined;
3400 ue->info->fcn->specclauses = NULL;
3401 ue->info->fcn->defparams = uentryList_undefined;
3402
3403 /*drl*/
3814599d 3404 ue->info->fcn->preconditions = functionConstraint_undefined;
616915dd 3405 /*end */
3406
3407 /*drl 12/28/2000*/
efd360a3 3408 ue->info->fcn->postconditions = functionConstraint_undefined;
616915dd 3409 /*end */
616915dd 3410
3411 if (ctype_isFunction (ue->utype))
3412 {
28bf4b0b 3413 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
616915dd 3414 }
3415 else
3416 {
3417 ue->sref = sRef_makeType (ctype_unknown);
3418 }
3419
3420 if (sRef_isRefCounted (ue->sref))
3421 {
3422 ak = AK_NEWREF;
3423 }
3424 else
3425 {
3426 if (alkind_isUnknown (ak))
3427 {
3428 if (exkind_isKnown (ek))
3429 {
28bf4b0b 3430 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
616915dd 3431 ak = AK_IMPDEPENDENT;
3432 }
3433 else
3434 {
3435 if (context_getFlag (FLG_RETIMPONLY))
3436 {
3437 if (ctype_isFunction (ue->utype)
3438 && ctype_isVisiblySharable
28bf4b0b 3439 (ctype_realType (ctype_getReturnType (ue->utype))))
616915dd 3440 {
3441 if (uentryList_hasReturned (uentry_getParams (ue)))
3442 {
3443 ;
3444 }
3445 else
3446 {
28bf4b0b 3447 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3448 {
3449 ;
3450 }
3451 else
3452 {
3453 ak = AK_IMPONLY;
3454 }
3455 }
616915dd 3456 }
3457 }
3458 }
3459 }
3460 }
3461
3462 loc = ue->whereDeclared;
3463
3464 sRef_setAliasKind (ue->sref, ak, loc);
3465 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3466 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3467 sRef_setExKind (ue->sref, ek, loc);
3468
3469 if (oldInfo->kind == VKEXPMACRO)
3470 {
efd360a3 3471 ;
616915dd 3472 }
3473 else
3474 {
3475 fileloc_free (ue->whereDefined);
3476 ue->whereDefined = fileloc_undefined;
3477 }
3478
3479 uvinfo_free (oldInfo);
3480}
3481
b072092f 3482void uentry_makeConstantFunction (uentry ue)
3483{
3484 alkind ak;
3485 exkind ek;
3486 ucinfo oldInfo;
3487 fileloc loc;
3488
3489 llassert (uentry_isValid (ue));
3490 llassert (!sRef_modInFunction ());
3491
3492 ak = sRef_getOrigAliasKind (ue->sref);
3493 ek = sRef_getOrigExKind (ue->sref);
3494
3495 llassert (uentry_isConstant (ue));
3496 oldInfo = ue->info->uconst;
3497
3498 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3499
3500 /*
3501 ** expanded macro is marked used (until I write a pre-processor)
3502 */
3503
3504 ue->ukind = KFCN;
3505 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3506 ue->info->fcn->exitCode = XK_UNKNOWN;
3507 ue->info->fcn->nullPred = qual_createUnknown ();
3508 ue->info->fcn->specialCode = SPC_NONE;
3509 ue->info->fcn->access = typeIdSet_undefined;
3510 ue->info->fcn->hasGlobs = FALSE;
3511 ue->info->fcn->globs = globSet_undefined;
3512 ue->info->fcn->hasMods = FALSE;
3513 ue->info->fcn->mods = sRefSet_undefined;
3514 ue->info->fcn->specclauses = NULL;
3515 ue->info->fcn->defparams = uentryList_undefined;
3516
3517 /*drl*/
3518 ue->info->fcn->preconditions = functionConstraint_undefined;
3519 /*end */
3520
3521 /*drl 12/28/2000*/
3522 ue->info->fcn->postconditions = functionConstraint_undefined;
3523 /*end */
3524
3525
3526 if (ctype_isFunction (ue->utype))
3527 {
3528 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3529 }
3530 else
3531 {
3532 ue->sref = sRef_makeType (ctype_unknown);
3533 }
3534
3535 if (sRef_isRefCounted (ue->sref))
3536 {
3537 ak = AK_NEWREF;
3538 }
3539 else
3540 {
3541 if (alkind_isUnknown (ak))
3542 {
3543 if (exkind_isKnown (ek))
3544 {
3545 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3546 ak = AK_IMPDEPENDENT;
3547 }
3548 else
3549 {
3550 if (context_getFlag (FLG_RETIMPONLY))
3551 {
3552 if (ctype_isFunction (ue->utype)
3553 && ctype_isVisiblySharable
3554 (ctype_realType (ctype_getReturnType (ue->utype))))
3555 {
3556 if (uentryList_hasReturned (uentry_getParams (ue)))
3557 {
3558 ;
3559 }
3560 else
3561 {
3562 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3563 {
3564 ;
3565 }
3566 else
3567 {
3568 ak = AK_IMPONLY;
3569 }
3570 }
3571 }
3572 }
3573 }
3574 }
3575 }
3576
3577 loc = ue->whereDeclared;
3578
3579 sRef_setAliasKind (ue->sref, ak, loc);
3580 sRef_setExKind (ue->sref, ek, loc);
3581
3582 fileloc_free (ue->whereDefined);
3583 ue->whereDefined = fileloc_undefined;
3584 ucinfo_free (oldInfo);
3585}
3586
616915dd 3587void
3588uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3589{
3590 llassert (uentry_isValid (ue));
3591
3592 if (uentry_isIter (ue))
3593 {
3594 llassert (globSet_isUndefined (ue->info->iter->globs));
3595 ue->info->iter->globs = globs;
3596 }
3597 else
3598 {
efd360a3 3599 uentry_convertVarFunction (ue);
616915dd 3600
3601 llassert (uentry_isFunction (ue));
3602 llassert (!ue->info->fcn->hasGlobs
3603 && globSet_isUndefined (ue->info->fcn->globs));
3604
3605 ue->info->fcn->hasGlobs = TRUE;
28bf4b0b 3606 globSet_markImmutable (globs);
616915dd 3607 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3608 /*@=mustfree@*/
3609 }
3610
68de3f33 3611 /*@i23*/
3612 /* ??? - evans 2001-09-09 not sure what's going on here...?
616915dd 3613 if (globSet_hasStatic (globs))
3614 {
3615 context_recordFileGlobals (globs);
3616 }
28bf4b0b 3617 */
616915dd 3618
3619 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3620 {
3621 ue->info->fcn->hasMods = TRUE;
3622 }
3623}
3624
3625void uentry_addAccessType (uentry ue, typeId tid)
3626{
3627 if (uentry_isFunction (ue))
3628 {
3629 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3630 }
3631 else if (uentry_isEitherConstant (ue))
3632 {
3633 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3634 }
3635 else if (uentry_isIter (ue))
3636 {
3637 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3638 }
3639 else if (uentry_isEndIter (ue))
3640 {
3641 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3642 }
3643 else
3644 {
3645 llbug (message ("no access for: %q", uentry_unparse (ue)));
3646 }
3647}
3648
3649/*@only@*/ /*@notnull@*/ uentry
3650 uentry_makeFunction (cstring n, ctype t,
3651 typeId access,
3652 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
28bf4b0b 3653 /*@only@*/ warnClause warn,
616915dd 3654 fileloc f)
3655{
28bf4b0b 3656 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
616915dd 3657 return (uentry_makeFunctionAux (n, t,
3658 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3659 : typeIdSet_single (access)),
28bf4b0b 3660 globs, mods, warn,
3661 f,
616915dd 3662 FALSE, FALSE));
3663}
3664
3665# ifndef NOLCL
3666/*@notnull@*/ uentry
3667 uentry_makePrivFunction2 (cstring n, ctype t,
3668 typeIdSet access,
3669 globSet globs, sRefSet mods,
3670 fileloc f)
3671{
28bf4b0b 3672 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3673 f, TRUE, FALSE));
616915dd 3674}
3675
3676
3677/*@notnull@*/ uentry
3678 uentry_makeSpecFunction (cstring n, ctype t,
3679 typeIdSet access,
3680 /*@only@*/ globSet globs,
3681 /*@only@*/ sRefSet mods,
3682 fileloc f)
3683{
3684 uentry ue = uentry_makeFunctionAux (n, t, access,
28bf4b0b 3685 globs, mods, warnClause_undefined,
3686 f, FALSE, FALSE);
616915dd 3687
3688 uentry_setHasGlobs (ue);
3689 uentry_setHasMods (ue);
3690
3691 reflectImplicitFunctionQualifiers (ue, TRUE);
3692 return (ue);
3693}
3694# endif
3695
3696uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3697{
3698 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3699 sRef_undefined, FALSE, VKEXPMACRO);
3700
3701 uentry_setDefined (ue, f);
3702 return ue;
3703}
3704
3705/*@notnull@*/ /*@notnull@*/ uentry
3706 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3707{
3708 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3709 typeIdSet_singleOpt (access),
3710 globSet_undefined, sRefSet_undefined,
28bf4b0b 3711 warnClause_undefined,
616915dd 3712 fileloc_undefined,
3713 FALSE, TRUE);
3714
3715 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3716 return ue;
3717}
3718
3719bool uentry_isForward (uentry e)
3720{
3721 if (uentry_isValid (e))
3722 {
3723 ctype ct = uentry_getType (e);
3724
3725 return (ctype_isUnknown (ct)
3726 || (ctype_isFunction (ct)
28bf4b0b 3727 && ctype_isUnknown (ctype_getReturnType (ct))));
616915dd 3728 }
3729
3730 return FALSE;
3731}
3732
3733# ifndef NOLCL
3734/*@notnull@*/ uentry
3735uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3736{
3737 return (uentry_makeFunctionAux (n, ctype_unknown, access,
28bf4b0b 3738 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3739 f,FALSE, TRUE));
616915dd 3740}
3741
3742/*@notnull@*/ uentry
3743uentry_makeUnspecFunction (cstring n, ctype t,
3744 typeIdSet access,
3745 fileloc f)
3746{
28bf4b0b 3747 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3748 sRefSet_undefined, warnClause_undefined,
3749 f, FALSE, TRUE);
616915dd 3750
3751 reflectImplicitFunctionQualifiers (ue, TRUE);
3752 return ue;
3753}
3754# endif
3755
3756/*
3757** datatypes
3758*/
3759
3760/* is exported for use by usymtab_interface */
3761
3762/*@notnull@*/ uentry
28bf4b0b 3763 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
616915dd 3764 fileloc f, bool priv)
3765{
3766 uentry e = uentry_alloc ();
3767
3768 DPRINTF (("Make datatype: %s / %s",
3769 n, ctype_unparse (t)));
3770
3771 /* e->shallowCopy = FALSE; */
3772 e->ukind = KDATATYPE;
3773 e->uname = cstring_copy (n);
3774 e->utype = t;
3775 e->storageclass = SCNONE;
3776 e->sref = sRef_makeUnknown ();
3777
3778 if (ctype_isUA (t))
3779 {
3780 sRef_setStateFromType (e->sref, t);
3781 }
3782
3783 uentry_setSpecDef (e, f);
3784
28bf4b0b 3785 e->warn = warnClause_undefined; /*@i634@*/
616915dd 3786 e->uses = filelocList_new ();
3787 e->isPrivate = priv;
3788 e->hasNameError = FALSE;
3789
3790 e->used = FALSE;
3791 e->lset = FALSE;
3792
3793 e->info = (uinfo) dmalloc (sizeof (*e->info));
3794 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
28bf4b0b 3795 e->info->datatype->abs = abstract;
616915dd 3796 e->info->datatype->mut = mut;
3797 e->info->datatype->type = ctype_undefined;
3798
3799 if (uentry_isDeclared (e))
3800 {
3801 uentry_setDefined (e, f);
3802 }
3803
28bf4b0b 3804 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
616915dd 3805 {
3806 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3807 }
3808
3809 return (e);
3810}
3811
3812/*@notnull@*/ uentry
28bf4b0b 3813 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
616915dd 3814{
28bf4b0b 3815 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
616915dd 3816}
3817
28bf4b0b 3818/*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
616915dd 3819{
3820 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
28bf4b0b 3821 ctype_bool, NO, abstract,
616915dd 3822 fileloc_getBuiltin (),
3823 FALSE);
3824
3825 ret->info->datatype->type = ctype_bool;
3826 return ret;
3827}
3828
3829/*
3830** iters
3831*/
3832
3833static /*@only@*/ /*@notnull@*/ uentry
3834 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3835 /*@only@*/ fileloc f)
3836{
3837 uentry e = uentry_alloc ();
3838
3839 e->ukind = KITER;
3840 e->uname = cstring_copy (n);
3841 e->utype = ct;
3842 e->sref = sRef_makeUnknown ();
3843 e->storageclass = SCNONE;
3844 e->used = FALSE;
3845 e->lset = FALSE;
3846
3847 uentry_setSpecDef (e, f);
3848
28bf4b0b 3849 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3850 e->uses = filelocList_new ();
3851 e->isPrivate = FALSE;
3852 e->hasNameError = FALSE;
3853
3854 e->info = (uinfo) dmalloc (sizeof (*e->info));
3855 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3856 e->info->iter->access = access;
3857 e->info->iter->mods = sRefSet_undefined;
3858 e->info->iter->globs = globSet_undefined;
3859
3860 uentry_checkIterArgs (e);
3861 return (e);
3862}
3863
3864/*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3865{
3866 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3867}
3868
3869static /*@notnull@*/ uentry
3870uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3871{
3872 uentry e = uentry_alloc ();
3873
3874 /* e->shallowCopy = FALSE; */
3875 e->ukind = KENDITER;
3876 e->storageclass = SCNONE;
3877 e->uname = message ("end_%s", n);
3878 e->utype = ctype_unknown;
3879 e->sref = sRef_makeUnknown ();
3880
3881 uentry_setSpecDef (e, f);
3882
3883 e->used = FALSE;
3884 e->lset = FALSE;
3885
3886 e->uses = filelocList_new ();
3887 e->isPrivate = FALSE;
3888 e->hasNameError = FALSE;
3889
3890 e->info = (uinfo) dmalloc (sizeof (*e->info));
3891 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3892
3893 e->info->enditer->access = access;
3894
28bf4b0b 3895 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3896 return (e);
3897}
3898
3899/*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3900{
3901 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3902}
3903
3904/*
3905** tags
3906*/
3907
3908static /*@only@*/ /*@notnull@*/ uentry
3909 uentry_makeTagAux (cstring n, ctype t,
3910 /*@only@*/ fileloc fl,
3911 bool priv, ekind kind)
3912{
3913 uentry e = uentry_alloc ();
3914
3915 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3916 {
3917 llbuglit ("uentry_makeTagAux: not a tag type");
3918 }
3919
3920 e->ukind = kind;
3921 /* e->shallowCopy = FALSE; */
3922 e->uname = cstring_copy (n);
3923
3924 e->utype = t;
3925 e->sref = sRef_makeUnknown ();
3926 e->storageclass = SCNONE;
3927
3928 uentry_setSpecDef (e, fl);
3929
3930 e->used = FALSE;
3931 e->lset = FALSE;
3932
3933 e->uses = filelocList_new ();
3934 e->isPrivate = priv;
3935 e->hasNameError = FALSE;
3936
3937 e->info = (uinfo) dmalloc (sizeof (*e->info));
3938 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3939 e->info->datatype->abs = NO;
3940 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3941 e->info->datatype->type = t;
28bf4b0b 3942 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3943
3944 if (uentry_isDeclared (e))
3945 {
3946 uentry_setDefined (e, fl);
3947 }
3948
3949 return (e);
3950}
3951
3952uentry uentry_makeStructTagLoc (cstring n, ctype t)
3953{
3954 cstring sname = makeStruct (n);
3955 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3956
3957 cstring_free (sname);
3958 return (ret);
3959}
3960
3961/*@only@*/ uentry
3962uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3963{
3964 cstring sname = makeStruct (n);
3965 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3966
3967 cstring_free (sname);
3968 return ret;
3969}
3970
3971/*@only@*/ uentry
3972uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3973{
3974 cstring uname = makeUnion (n);
3975 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3976
3977 cstring_free (uname);
3978 return (ret);
3979}
3980
3981# ifndef NOLCL
3982uentry
3983uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3984{
3985 cstring ename = makeEnum (n);
3986 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3987
3988 cstring_free (ename);
3989 return ret;
3990}
3991# endif
3992
3993uentry
3994uentry_makeUnionTagLoc (cstring n, ctype t)
3995{
3996 cstring uname = makeUnion (n);
3997 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3998
3999 cstring_free (uname);
4000 return ret;
4001}
4002
4003uentry
4004uentry_makeEnumTagLoc (cstring n, ctype t)
4005{
4006 cstring ename = makeEnum (n);
4007 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4008
4009 cstring_free (ename);
4010 return ret;
4011}
4012
4013bool
4014uentry_isStructTag (uentry ue)
4015{
4016 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4017}
4018
4019bool
4020uentry_isUnionTag (uentry ue)
4021{
4022 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4023}
4024
4025bool
4026uentry_isEnumTag (uentry ue)
4027{
4028 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4029}
4030
4031bool
4032uentry_isAnyTag (uentry ue)
4033{
4034 return (uentry_isStructTag (ue)
4035 || uentry_isUnionTag (ue)
4036 || uentry_isEnumTag (ue));
4037}
4038
4039static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4040
4041extern void uentry_destroyMod (void)
4042 /*@globals killed emarker@*/ /*@modifies emarker@*/
4043{
4044 static bool wasDestroyed = FALSE;
4045
4046 llassert (!wasDestroyed);
4047
4048 if (emarker != NULL)
4049 {
4050 uentry_reallyFree (emarker);
4051 }
4052
4053 wasDestroyed = TRUE;
4054}
4055
4056uentry
4057uentry_makeElipsisMarker (void)
4058{
4059 if (emarker == NULL)
4060 {
4061 emarker = uentry_alloc ();
4062
4063 emarker->ukind = KELIPSMARKER;
4064 emarker->uname = cstring_makeLiteral ("...");
4065 emarker->utype = ctype_elipsMarker;
4066 emarker->sref = sRef_undefined;
4067 emarker->storageclass = SCNONE;
4068 emarker->used = FALSE;
4069 emarker->lset = FALSE;
4070 emarker->info = NULL;
4071
4072 uentry_setSpecDef (emarker, fileloc_undefined);
4073 emarker->uses = filelocList_new ();
4074 emarker->isPrivate = FALSE;
4075 emarker->hasNameError = FALSE;
4076 }
4077
4078 /*@ignore@*/ return (emarker); /*@end@*/
4079}
4080
4081/*
4082** comparisons
4083*/
4084
4085bool
4086uentry_equiv (uentry p1, uentry p2)
4087{
4088 if (uentry_compare (p1, p2) != 0)
4089 {
4090 return FALSE;
4091 }
4092 else
4093 {
4094 return TRUE;
4095 }
4096}
4097
4098int
4099uentry_xcomparealpha (uentry *p1, uentry *p2)
4100{
4101 int res;
4102
4103 if ((res = uentry_compare (*p1, *p2)) == 0) {
4104 if ((*p1 != NULL) && (*p2 != NULL)) {
4105 res = cstring_compare ((*p1)->uname,
4106 (*p2)->uname);
4107 }
4108 }
4109
4110 return res;
4111}
4112
4113int
4114uentry_xcompareuses (uentry *p1, uentry *p2)
4115{
4116 uentry u1 = *p1;
4117 uentry u2 = *p2;
4118
4119 if (uentry_isValid (u1))
4120 {
4121 if (uentry_isValid (u2))
4122 {
4123 return (-1 * int_compare (filelocList_size (u1->uses),
4124 filelocList_size (u2->uses)));
4125 }
4126 else
4127 {
4128 return 1;
4129 }
4130 }
4131 else
4132 {
4133 if (uentry_isValid (u2))
4134 {
4135 return -1;
4136 }
4137 else
4138 {
4139 return 0;
4140 }
4141 }
4142}
4143
4144int
4145uentry_compareStrict (uentry v1, uentry v2)
4146{
4147 COMPARERETURN (uentry_compare (v1, v2));
4148
4149 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4150 {
4151 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4152 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4153 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4154 }
4155
4156 return 0;
4157}
4158
4159int
4160uentry_compare (uentry u1, uentry u2)
4161{
4162 if (u1 == u2) return 0;
4163
4164 if (uentry_isInvalid (u1)) return -1;
4165 if (uentry_isInvalid (u2)) return 1;
4166
4167 INTCOMPARERETURN (u1->ukind, u2->ukind);
4168 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4169 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
616915dd 4170 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4171
4172 switch (u1->ukind)
4173 {
4174 case KINVALID:
4175 case KELIPSMARKER:
1b8ae690 4176 /* bug detected by splint:
616915dd 4177 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4178 */
4179 return 0;
4180 case KENUMCONST:
4181 case KCONST:
b9904f57 4182 return (multiVal_compare (uentry_getConstantValue (u1),
4183 uentry_getConstantValue (u2)));
616915dd 4184 case KSTRUCTTAG:
4185 case KUNIONTAG:
4186 case KENUMTAG:
4187 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4188 case KITER:
4189 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4190 uentry_accessType (u2)));
4191 return (uentryList_compareParams (uentry_getParams (u1),
4192 uentry_getParams (u2)));
4193 case KENDITER:
4194 return (typeIdSet_compare (uentry_accessType (u1),
4195 uentry_accessType (u2)));
4196 case KFCN:
28bf4b0b 4197 /*
4198 ** Functions are never equivalent
4199 */
4200
b7e84605 4201 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
28bf4b0b 4202 {
4203 return -1;
4204 }
4205 else
4206 {
4207 return 1;
4208 }
4209 case KVAR:
4210
4211 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4212 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4213 sRef_getOrigAliasKind (u2->sref)));
4214 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4215 sRef_getOrigExKind (u2->sref)));
616915dd 4216 COMPARERETURN (generic_compare (u1->info->var->checked,
4217 u2->info->var->checked));
4218 COMPARERETURN (generic_compare (u1->info->var->defstate,
4219 u2->info->var->defstate));
4220 return (generic_compare (u1->info->var->nullstate,
4221 u2->info->var->nullstate));
4222 case KDATATYPE:
4223 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4224 u2->info->datatype->type));
4225 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4226 u2->info->datatype->mut));
4227 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4228 }
4229
4230 BADEXIT;
4231}
4232
4233/*
4234** library format:
4235**
4236** all entries are: <type>[@<info>]*#<name>
4237**
4238** info depends on kind:
4239*/
4240
4241static void
4242advanceField (char **s)
4243{
28bf4b0b 4244 reader_checkChar (s, '@');
616915dd 4245}
4246
4247static void
4248advanceName (char **s)
4249{
28bf4b0b 4250 reader_checkChar (s, '#');
616915dd 4251}
4252
4253static vkind
4254vkind_fromInt (int i)
4255{
4256 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4257 {
4258 llbuglit ("vkind_fromInt: out of range");
4259 }
4260
4261 return (vkind)i;
4262}
4263
4264static uentry
4265 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4266 typeIdSet access, nstate nullstate,
4267 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4268{
4269 uentry e = uentry_alloc ();
4270
4271 e->ukind = KCONST;
4272 e->uname = name;
4273 e->utype = ct;
4274 e->sref = sRef_makeConst (ct);
4275
4276 sRef_setNullState (e->sref, nullstate, loc);
4277 e->storageclass = SCNONE;
4278
4279 if (fileloc_isSpec (loc))
4280 {
4281 e->whereSpecified = loc;
4282 e->whereDeclared = fileloc_undefined;
4283 }
4284 else
4285 {
4286 e->whereSpecified = fileloc_undefined;
4287 e->whereDeclared = loc;
4288 }
4289
4290 e->whereDefined = fileloc_undefined;
4291 e->uses = filelocList_new ();
4292 e->isPrivate = FALSE;
4293 e->hasNameError = FALSE;
4294
4295 e->used = FALSE;
4296 e->lset = FALSE;
4297
28bf4b0b 4298 e->warn = warnClause_undefined; /*@i452@*/
4299
616915dd 4300 e->info = (uinfo) dmalloc (sizeof (*e->info));
4301 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
616915dd 4302 e->info->uconst->access = access;
3e3ec469 4303 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
b9904f57 4304 uentry_setConstantValue (e, m);
616915dd 4305 sRef_storeState (e->sref);
4306
4307 return (e);
4308}
4309
4310static /*@only@*/ uentry
4311 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4312 sstate defstate, nstate isnull, alkind aliased,
4313 exkind exp, chkind checked,
4314 /*@only@*/ fileloc loc)
4315{
4316 uentry e = uentry_alloc ();
4317
4318 e->ukind = KVAR;
4319 e->uname = name;
4320 e->utype = ct;
4321 e->storageclass = SCNONE;
4322
4323 e->sref = sRef_makeType (ct);
4324 sRef_setNullState (e->sref, isnull, loc);
4325
4326 e->whereDefined = fileloc_undefined;
4327
4328 if (fileloc_isSpec (loc))
4329 {
4330 e->whereSpecified = loc;
4331 e->whereDeclared = fileloc_undefined;
4332 }
4333 else
4334 {
4335 e->whereSpecified = fileloc_undefined;
4336 e->whereDeclared = loc;
4337 }
4338
4339 e->isPrivate = FALSE;
4340 e->hasNameError = FALSE;
4341
4342 e->used = FALSE;
4343 e->lset = FALSE;
4344
4345 e->uses = filelocList_new ();
28bf4b0b 4346 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4347
4348 e->info = (uinfo) dmalloc (sizeof (*e->info));
4349 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4350 e->info->var->kind = kind;
4351 e->info->var->checked = checked;
4352 e->info->var->defstate = defstate;
4353
4354 sRef_setDefState (e->sref, defstate, loc);
4355
4356 e->info->var->nullstate = sRef_getNullState (e->sref);
4357
4358 sRef_setExKind (e->sref, exp, loc);
4359 sRef_setAliasKind (e->sref, aliased, loc);
4360
4361 sRef_storeState (e->sref);
4362
4363 /*DRL ADDED 9-1-2000 */
4364 e->info->var->bufinfo = NULL;
4365
4366 return (e);
4367}
4368
4369static /*@only@*/ uentry
28bf4b0b 4370uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
616915dd 4371 ynm mut, ctype rtype, alkind ak, exkind exp,
4372 sstate defstate, nstate isnull,
4373 /*@only@*/ fileloc loc)
4374{
4375 uentry e = uentry_alloc ();
4376
4377 e->ukind = KDATATYPE;
4378 /* e->shallowCopy = FALSE; */
4379 e->uname = name;
4380 e->utype = ct;
4381 e->storageclass = SCNONE;
4382 e->sref = sRef_makeUnknown ();
28bf4b0b 4383 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
616915dd 4384
4385 /*
4386 ** This is only setting null state. (I think?)
4387 */
4388
4389 if (ctype_isUA (ct))
4390 {
4391 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4392
4393 if (uentry_isValid (te))
4394 {
4395 sRef_setStateFromUentry (e->sref, te);
4396 }
4397 else
4398 {
4399 /* problem for recursive type definitions */
4400 }
4401 }
4402
4403 sRef_setAliasKind (e->sref, ak, loc);
4404 sRef_setExKind (e->sref, exp, loc);
4405
4406 sRef_setDefState (e->sref, defstate, loc);
4407
28bf4b0b 4408 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
616915dd 4409 {
4410 isnull = NS_ABSNULL;
4411 }
4412
28bf4b0b 4413 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
616915dd 4414 sRef_mergeNullState (e->sref, isnull);
4415
4416 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4417
4418 if (fileloc_isSpec (loc))
4419 {
4420 e->whereSpecified = loc;
4421 e->whereDeclared = fileloc_undefined;
4422 }
4423 else
4424 {
4425 e->whereSpecified = fileloc_undefined;
4426 e->whereDeclared = loc;
4427 }
4428
4429 e->isPrivate = FALSE;
4430 e->hasNameError = FALSE;
4431
28bf4b0b 4432 e->warn = warnClause_undefined; /*@i452@*/
4433
616915dd 4434 e->used = FALSE;
4435 e->lset = FALSE;
4436 e->uses = filelocList_new ();
4437
4438 e->info = (uinfo) dmalloc (sizeof (*e->info));
4439 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
28bf4b0b 4440 e->info->datatype->abs = abstract;
616915dd 4441 e->info->datatype->mut = mut;
4442 e->info->datatype->type = rtype;
28bf4b0b 4443
4444 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
616915dd 4445 sRef_storeState (e->sref);
28bf4b0b 4446 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
616915dd 4447
4448 return (e);
4449}
4450
4451# ifndef NOLCL
4452static void uentry_setHasGlobs (uentry ue)
4453{
4454 llassert (uentry_isFunction (ue));
4455
4456 ue->info->fcn->hasGlobs = TRUE;
4457}
4458
4459static void uentry_setHasMods (uentry ue)
4460{
4461 llassert (uentry_isFunction (ue));
4462
4463 ue->info->fcn->hasMods = TRUE;
4464}
4465# endif
4466
4467bool uentry_hasGlobs (uentry ue)
4468{
4469 if (uentry_isFunction (ue))
4470 {
4471 return (ue->info->fcn->hasGlobs);
4472 }
4473
4474 return FALSE;
4475}
4476
28bf4b0b 4477bool uentry_hasStateClauseList (uentry ue)
616915dd 4478{
28bf4b0b 4479 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
616915dd 4480}
4481
ccf0a4a8 4482bool uentry_hasConditions (uentry ue)
4483{
4484 return (uentry_isFunction (ue)
4485 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4486 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4487}
4488
28bf4b0b 4489stateClauseList uentry_getStateClauseList (uentry ue)
616915dd 4490{
28bf4b0b 4491 if (!uentry_isFunction (ue))
4492 {
4493 llassert (uentry_isFunction (ue));
4494 return stateClauseList_undefined;
4495 }
4496
4497 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
616915dd 4498 return ue->info->fcn->specclauses;
4499}
4500
4501bool uentry_hasMods (uentry ue)
4502{
4503 if (uentry_isFunction (ue))
4504 {
4505 return (ue->info->fcn->hasMods);
4506 }
4507
4508 return FALSE;
4509}
4510
4511static uentry
4512 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4513 typeIdSet access,
4514 bool hasGlobs, /*@only@*/ globSet globs,
4515 bool hasMods, /*@only@*/ sRefSet mods,
4516 alkind ak, exkind exp,
4517 sstate defstate, nstate isnull,
4518 exitkind exitCode,
4519 specCode sCode,
4520 qual nullPred,
28bf4b0b 4521 /*@only@*/ stateClauseList specclauses,
4522 /*@only@*/ warnClause warnclause,
616915dd 4523 /*@only@*/ fileloc loc)
4524{
4525 uentry e = uentry_alloc ();
4526 ctype ret;
4527
4528 /* e->shallowCopy = FALSE; */
4529 e->ukind = KFCN;
4530 e->uname = name;
4531 e->utype = ct;
4532 e->storageclass = SCNONE;
4533
4534 if (ctype_isFunction (ct))
4535 {
28bf4b0b 4536 ret = ctype_getReturnType (ct);
616915dd 4537 }
4538 else
4539 {
4540 if (ctype_isKnown (ct))
4541 {
4542 llbug (message ("not function: %s", ctype_unparse (ct)));
4543 }
4544
4545 ret = ctype_unknown;
4546 }
4547
4548 e->sref = sRef_makeType (ret);
4549
4550 if (ctype_isUA (ret))
4551 {
4552 sRef_setStateFromType (e->sref, ret);
4553 }
4554
4555 sRef_setDefined (e->sref, loc);
4556 sRef_setNullState (e->sref, isnull, loc);
4557
4558 sRef_setAliasKind (e->sref, ak, loc);
4559 sRef_setExKind (e->sref, exp, loc);
4560 sRef_setDefState (e->sref, defstate, loc);
4561
4562 e->whereSpecified = loc;
4563 e->whereDefined = fileloc_undefined;
4564
4565 e->isPrivate = FALSE;
4566 e->hasNameError = FALSE;
4567
4568 e->used = FALSE;
4569 e->lset = FALSE;
4570 e->uses = filelocList_new ();
28bf4b0b 4571 e->warn = warnclause;
616915dd 4572
4573 e->info = (uinfo) dmalloc (sizeof (*e->info));
4574 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4575
4576 e->info->fcn->exitCode = exitCode;
4577 e->info->fcn->specialCode = sCode;
4578 e->info->fcn->nullPred = nullPred;
4579 e->info->fcn->access = access;
4580
4581 e->info->fcn->specclauses = specclauses;
4582 e->info->fcn->hasGlobs = hasGlobs;
4583 e->info->fcn->globs = globs;
4584
4585 e->info->fcn->hasMods = hasMods;
4586 e->info->fcn->mods = mods;
4587
4588 e->info->fcn->defparams = uentryList_undefined;
4589 e->whereDeclared = fileloc_undefined;
4590
4591 sRef_storeState (e->sref);
4592
4593 /*drl 111 30 2000*/
4594 e->info->fcn->preconditions = NULL;
4595 /* end drl */
4596
4597 /*drl 12 28 2000*/
4598 e->info->fcn->postconditions = NULL;
4599 /* end drl */
4600
4601 return (e);
4602}
4603
4604static /*@only@*/ uentry
4605 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4606 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4607{
4608 uentry e = uentry_alloc ();
4609
4610 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4611 {
4612 llbuglit ("uentry_makeTagBase: not a tag type");
4613 }
4614
4615 /* e->shallowCopy = FALSE; */
4616 e->ukind = tagkind;
4617 e->uname = name;
4618 e->utype = ct;
4619 e->sref = sRef_makeUnknown ();
4620 e->storageclass = SCNONE;
4621
4622 if (fileloc_isSpec (loc))
4623 {
4624 e->whereSpecified = loc;
4625 e->whereDeclared = fileloc_undefined;
4626 }
4627 else
4628 {
4629 e->whereDeclared = loc;
4630 e->whereSpecified = fileloc_undefined;
4631 }
4632
4633 e->whereDefined = fileloc_undefined;
4634
4635 e->isPrivate = FALSE;
4636 e->hasNameError = FALSE;
4637
4638 e->used = FALSE;
4639 e->lset = FALSE;
4640 e->uses = filelocList_new ();
28bf4b0b 4641 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4642
4643 e->info = (uinfo) dmalloc (sizeof (*e->info));
4644 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4645 e->info->datatype->abs = NO;
4646 e->info->datatype->mut = MAYBE;
4647 e->info->datatype->type = rtype;
4648
4649 sRef_storeState (e->sref);
4650
4651 return (e);
4652}
4653
4654static uentry
4655 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4656 ctype ct, /*@only@*/ fileloc loc)
4657{
4658 uentry e = uentry_alloc ();
4659
4660 /* e->shallowCopy = FALSE; */
4661 e->ukind = KITER;
4662 e->uname = name;
4663 e->utype = ct;
4664 e->sref = sRef_makeUnknown ();
4665 e->storageclass = SCNONE;
4666
4667 if (fileloc_isSpec (loc))
4668 {
4669 e->whereSpecified = loc;
4670 e->whereDeclared = fileloc_undefined;
4671 }
4672 else
4673 {
4674 e->whereDeclared = loc;
4675 e->whereSpecified = fileloc_undefined;
4676 }
4677
4678 e->whereDefined = fileloc_undefined;
4679
4680 e->isPrivate = FALSE;
4681 e->hasNameError = FALSE;
4682
4683 e->used = FALSE;
4684 e->lset = FALSE;
4685 e->uses = filelocList_new ();
28bf4b0b 4686 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4687
4688 e->info = (uinfo) dmalloc (sizeof (*e->info));
4689 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4690 e->info->iter->access = access;
4691 e->info->iter->mods = sRefSet_undefined;
4692 e->info->iter->globs = globSet_undefined;
4693
4694 sRef_storeState (e->sref);
4695 return (e);
4696}
4697
4698static uentry
4699 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4700 /*@only@*/ fileloc loc)
4701{
4702 uentry e = uentry_alloc ();
4703
4704 /* e->shallowCopy = FALSE; */
4705 e->ukind = KENDITER;
4706 e->storageclass = SCNONE;
4707 e->uname = name;
4708 e->utype = ctype_unknown;
4709 e->sref = sRef_makeUnknown ();
4710
4711 if (fileloc_isSpec (loc))
4712 {
4713 e->whereSpecified = loc;
4714 e->whereDeclared = fileloc_undefined;
4715 }
4716 else
4717 {
4718 e->whereDeclared = loc;
4719 e->whereSpecified = fileloc_undefined;
4720 }
4721
4722 e->whereDefined = fileloc_undefined;
4723
4724 e->isPrivate = FALSE;
4725 e->hasNameError = FALSE;
4726
4727 e->used = FALSE;
4728 e->lset = FALSE;
4729 e->uses = filelocList_new ();
28bf4b0b 4730 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4731
4732 e->info = (uinfo) dmalloc (sizeof (*e->info));
4733 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4734 e->info->enditer->access = access;
4735 sRef_storeState (e->sref);
4736
4737 return (e);
4738}
4739
4740void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4741{
4742 /* should save u */
4743/*@-mustfree@*/
4744}
4745/*@=mustfree@*/
4746
4747/*@only@*/ uentry
4748uentry_undump (ekind kind, fileloc loc, char **s)
4749{
4750 uentry ue;
4751
28bf4b0b 4752 DPRINTF (("Uentry undump: %s", *s));
4753
616915dd 4754 if (**s == '!')
4755 {
28bf4b0b 4756 reader_checkChar (s, '!');
4757 reader_checkChar (s, '.');
616915dd 4758 ue = uentry_makeElipsisMarker ();
4759 }
4760 else
4761 {
4762 ctype ct = ctype_undump (s);
4763 cstring name;
4764
4765 switch (kind)
4766 {
4767 case KVAR:
4768 {
4769 vkind tkind;
4770 sstate defstate;
4771 nstate isnull;
4772 alkind aliased;
4773 exkind exp;
4774 chkind checked;
4775
28bf4b0b 4776 reader_checkChar (s, '|');
616915dd 4777
28bf4b0b 4778 if (reader_optCheckChar (s, '@'))
616915dd 4779 {
28bf4b0b 4780 tkind = vkind_fromInt (reader_getInt (s));
4781 reader_checkChar (s, '|');
616915dd 4782 }
4783 else
4784 {
4785 tkind = VKPARAM;
4786 }
4787
28bf4b0b 4788 if (reader_optCheckChar (s, '$'))
616915dd 4789 {
4790 defstate = SS_UNKNOWN;
4791 isnull = NS_UNKNOWN;
4792 aliased = AK_IMPTEMP;
4793 exp = XO_UNKNOWN;
4794 checked = CH_UNKNOWN;
4795 }
28bf4b0b 4796 else if (reader_optCheckChar (s, '&'))
616915dd 4797 {
4798 defstate = SS_DEFINED;
4799 isnull = NS_UNKNOWN;
4800 aliased = AK_IMPTEMP;
4801 exp = XO_UNKNOWN;
4802 checked = CH_UNKNOWN;
4803 }
28bf4b0b 4804 else if (reader_optCheckChar (s, '^'))
616915dd 4805 {
4806 defstate = SS_UNKNOWN;
4807 isnull = NS_UNKNOWN;
4808 aliased = AK_IMPTEMP;
4809 exp = XO_UNKNOWN;
4810 checked = CH_UNKNOWN;
4811 }
4812 else
4813 {
28bf4b0b 4814 defstate = sstate_fromInt (reader_getInt (s));
4815 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4816 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
616915dd 4817
28bf4b0b 4818 if (reader_optCheckChar (s, '&'))
616915dd 4819 {
4820 exp = XO_UNKNOWN;
4821 checked = CH_UNKNOWN;
4822 }
4823 else
4824 {
28bf4b0b 4825 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4826 advanceField (s); checked = (chkind) (reader_getInt (s));
616915dd 4827 }
4828 }
4829
4830 advanceName (s);
28bf4b0b 4831 name = reader_getStringWord (s);
616915dd 4832
28bf4b0b 4833 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4834
616915dd 4835 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4836 isnull, aliased, exp,
4837 checked, fileloc_copy (loc));
4838 }
4839 break;
4840 case KDATATYPE:
4841 {
28bf4b0b 4842 ynm abstract;
616915dd 4843 ynm mut;
4844 ctype rtype;
4845 sstate defstate;
4846 nstate isnull;
4847 alkind aliased;
4848 exkind exp;
4849
28bf4b0b 4850 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4851 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4852 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4853 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4854 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4855 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
616915dd 4856 advanceField (s); rtype = ctype_undump (s);
4857 advanceName (s);
28bf4b0b 4858 name = reader_getStringWord (s);
4859 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4860 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
616915dd 4861 aliased, exp, defstate, isnull,
4862 fileloc_copy (loc));
4863 }
4864 break;
4865 case KFCN:
4866 {
4867 alkind ak;
4868 exkind exp;
4869 sstate defstate;
4870 nstate isnull;
4871 exitkind exitCode;
4872 specCode specc;
4873 qual nullPred;
4874 typeIdSet access;
4875 bool hasGlobs;
4876 globSet globs;
4877 bool hasMods;
4878 sRefSet mods;
28bf4b0b 4879 stateClauseList specclauses = stateClauseList_undefined;
4880 warnClause warnclause = warnClause_undefined;
616915dd 4881
28bf4b0b 4882 if (reader_optCheckChar (s, '$'))
616915dd 4883 {
4884 defstate = SS_DEFINED;
4885 isnull = NS_UNKNOWN;
4886 exitCode = XK_UNKNOWN;
4887 specc = SPC_NONE;
28bf4b0b 4888 nullPred = qual_createUnknown ();
616915dd 4889 }
4890 else
4891 {
28bf4b0b 4892 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4893 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4894 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4895 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4896 advanceField (s); nullPred = qual_undump (s);
616915dd 4897 }
4898
28bf4b0b 4899 if (reader_optCheckChar (s, '$'))
616915dd 4900 {
4901 hasGlobs = FALSE;
4902 globs = globSet_undefined;
4903 hasMods = FALSE;
4904 mods = sRefSet_undefined;
4905 }
28bf4b0b 4906 else if (reader_optCheckChar (s, '^'))
616915dd 4907 {
4908 hasGlobs = TRUE;
4909 globs = globSet_undefined;
4910 hasMods = TRUE;
4911 mods = sRefSet_undefined;
4912 }
4913 else
4914 {
28bf4b0b 4915 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
616915dd 4916 advanceField (s); globs = globSet_undump (s);
28bf4b0b 4917 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
616915dd 4918 advanceField (s); mods = sRefSet_undump (s);
4919 }
4920
28bf4b0b 4921 if (reader_optCheckChar (s, '$'))
616915dd 4922 {
4923 ak = AK_UNKNOWN;
4924 exp = XO_UNKNOWN;
4925 }
4926 else
4927 {
28bf4b0b 4928 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4929 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
616915dd 4930 }
4931
4932 advanceField (s); access = typeIdSet_undump (s);
4933
28bf4b0b 4934 /*
4935 ** Optional clauses: Start with @<code>:
4936 */
4937
4938 while (reader_optCheckChar (s, '@'))
616915dd 4939 {
28bf4b0b 4940 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4941 {
4942 reader_checkChar (s, ':');
4943 warnclause = warnClause_undump (s);
4944 }
4945 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4946 {
4947 reader_checkChar (s, ':');
4948 specclauses = stateClauseList_undump (s);
4949 }
4950 else
4951 {
4952 BADBRANCH;
4953 }
616915dd 4954 }
4955
28bf4b0b 4956 advanceName (s); name = reader_getStringWord (s);
616915dd 4957
4958 ue = uentry_makeFunctionBase (name, ct, access,
4959 hasGlobs, globs,
4960 hasMods, mods,
4961 ak, exp, defstate, isnull,
4962 exitCode, specc, nullPred,
4963 specclauses,
28bf4b0b 4964 warnclause,
616915dd 4965 fileloc_copy (loc));
4966 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4967 }
4968 break;
4969 case KITER:
4970 {
4971 typeIdSet access;
4972
4973 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4974 advanceName (s); name = reader_getStringWord (s);
616915dd 4975
4976 ue = uentry_makeIterBase (name, access, ct,
4977 fileloc_copy (loc));
4978 }
4979 break;
4980 case KENDITER:
4981 {
4982 typeIdSet access;
4983
4984 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4985 advanceName (s); name = reader_getStringWord (s);
616915dd 4986
4987 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4988 }
4989 break;
4990 case KENUMCONST:
4991 case KCONST:
4992 {
4993 typeIdSet access;
4994 multiVal val;
4995 nstate nullstate;
4996
28bf4b0b 4997 if (reader_optCheckChar (s, '$'))
616915dd 4998 {
4999 val = multiVal_undefined;
5000 access = typeIdSet_undefined;
5001 nullstate = NS_UNKNOWN;
5002 }
5003 else
5004 {
5005 advanceField (s); val = multiVal_undump (s);
5006 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 5007 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
616915dd 5008 }
5009
28bf4b0b 5010 advanceName (s); name = reader_getStringWord (s);
616915dd 5011
5012 ue = uentry_makeConstantBase (name, ct, access,
5013 nullstate, fileloc_copy (loc), val);
5014 break;
5015 }
5016 case KSTRUCTTAG:
5017 case KUNIONTAG:
5018 case KENUMTAG:
5019 {
5020 ctype rtype;
5021
5022 advanceField (s); rtype = ctype_undump (s);
28bf4b0b 5023 advanceName (s); name = reader_getStringWord (s);
616915dd 5024 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5025 }
5026 break;
5027 case KINVALID:
5028 llcontbuglit ("uentry_undump: invalid");
5029 ue = uentry_undefined;
5030 break;
5031 case KELIPSMARKER:
5032 llcontbuglit ("uentry_undump: elips marker");
5033 ue = uentry_undefined;
5034 break;
5035 }
5036 }
5037
5038 return (ue);
5039}
5040
5041cstring
5042uentry_dump (uentry v)
5043{
5044 return (uentry_dumpAux (v, FALSE));
5045}
5046
5047cstring
5048uentry_dumpParam (uentry v)
5049{
5050 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5051 ("dump: %s", uentry_unparseFull (v)));
5052
5053 return (uentry_dumpAux (v, TRUE));
5054}
5055
5056static cstring
5057uentry_dumpAux (uentry v, bool isParam)
5058{
5059 llassert (uentry_isValid (v));
28bf4b0b 5060 llassert (!uentry_isGlobalMarker (v));
616915dd 5061
28bf4b0b 5062 DPRINTF (("Dump uentry: [%p]", v));
616915dd 5063 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
28bf4b0b 5064
616915dd 5065 switch (v->ukind)
5066 {
5067 case KINVALID:
5068 llcontbuglit ("uentry_dump: invalid entry");
5069 return cstring_undefined;
5070 case KELIPSMARKER:
5071 return (message ("!."));
5072 case KVAR:
5073 {
5074 cstring sdump;
5075 vkind vk = v->info->var->kind;
5076 sstate dss = sRef_getDefState (v->sref);
5077 nstate nst = sRef_getNullState (v->sref);
5078 alkind alk = sRef_getAliasKind (v->sref);
5079 exkind exk = sRef_getExKind (v->sref);
5080 chkind chk = v->info->var->checked;
5081
5082 DPRINTF (("Dumping var"));
5083
5084 if (dss == SS_UNKNOWN
5085 && nst == NS_UNKNOWN
5086 && alk == AK_IMPTEMP
5087 && exk == XO_UNKNOWN
5088 && chk == CH_UNKNOWN)
5089 {
5090 sdump = cstring_makeLiteral ("$");
5091 }
5092 else if (dss == SS_DEFINED
5093 && nst == NS_UNKNOWN
5094 && alk == AK_IMPTEMP
5095 && exk == XO_UNKNOWN
5096 && chk == CH_UNKNOWN)
5097 {
5098 sdump = cstring_makeLiteral ("&");
5099 }
5100 else if (dss == SS_UNKNOWN
5101 && nst == NS_UNKNOWN
5102 && alk == AK_UNKNOWN
5103 && exk == XO_UNKNOWN
5104 && chk == CH_UNKNOWN)
5105 {
5106 sdump = cstring_makeLiteral ("^");
5107 }
5108 else if (exk == XO_UNKNOWN
5109 && chk == CH_UNKNOWN)
5110 {
5111 sdump = message ("%d@%d@%d&",
5112 (int) dss,
5113 (int) nst,
5114 (int) alk);
5115 }
5116 else
5117 {
5118 sdump = message ("%d@%d@%d@%d@%d",
5119 (int) dss,
5120 (int) nst,
5121 (int) alk,
5122 (int) exk,
5123 (int) chk);
5124 }
5125
5126
5127 if (vk != VKPARAM)
5128 {
5129 return (message ("%q|@%d|%q#%s",
5130 ctype_dump (v->utype),
5131 (int) vk,
5132 sdump,
5133 isParam ? cstring_undefined : v->uname));
5134 }
5135 else
5136 {
5137 return (message ("%q|%q#%s",
5138 ctype_dump (v->utype),
5139 sdump,
5140 isParam ? cstring_undefined : v->uname));
5141 }
5142
5143 }
5144 case KDATATYPE:
28bf4b0b 5145 /*
5146 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5147 uentry_unparse (v),
5148 exkind_unparse (sRef_getExKind (v->sref)),
5149 ctype_unparse (v->utype), (int) v->utype));
5150 */
5151
616915dd 5152 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5153 ctype_dump (v->utype),
5154 ynm_unparseCode (v->info->datatype->abs),
5155 ynm_unparseCode (v->info->datatype->mut),
5156 (int) sRef_getDefState (v->sref),
5157 (int) sRef_getNullState (v->sref),
5158 (int) sRef_getAliasKind (v->sref),
5159 (int) sRef_getExKind (v->sref),
5160 ctype_dump (v->info->datatype->type),
5161 v->uname));
5162 case KFCN:
5163 {
28bf4b0b 5164 cstring sdump, gdump, adump, xdump;
616915dd 5165 alkind alk = sRef_getAliasKind (v->sref);
5166 exkind exk = sRef_getExKind (v->sref);
5167
5168 if (sRef_getDefState (v->sref) == SS_DEFINED
5169 && !nstate_isKnown (sRef_getNullState (v->sref))
5170 && !exitkind_isKnown (v->info->fcn->exitCode)
5171 && v->info->fcn->specialCode == SPC_NONE
28bf4b0b 5172 && qual_isUnknown (v->info->fcn->nullPred))
616915dd 5173 {
5174 sdump = cstring_makeLiteral ("$");
5175 }
5176 else
5177 {
28bf4b0b 5178 sdump = message ("@%d@%d@%d@%d@%x",
616915dd 5179 (int) sRef_getDefState (v->sref),
5180 (int) sRef_getNullState (v->sref),
5181 (int) v->info->fcn->exitCode,
5182 (int) v->info->fcn->specialCode,
28bf4b0b 5183 qual_dump (v->info->fcn->nullPred));
616915dd 5184 }
5185
5186 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5187 {
5188 gdump = cstring_makeLiteral ("$");
5189 }
5190 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5191 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5192 {
5193 gdump = cstring_makeLiteral ("^");
5194 }
5195 else
5196 {
5197 gdump = message ("@%s@%q@%s@%q",
5198 bool_dump (uentry_hasGlobs (v)),
5199 globSet_dump (uentry_getGlobs (v)),
5200 bool_dump (uentry_hasMods (v)),
5201 sRefSet_dump (uentry_getMods (v)));
5202 }
5203
5204 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5205 {
5206 adump = cstring_makeLiteral ("$");
5207 }
5208 else
5209 {
5210 adump = message ("@%d@%d", (int) alk, (int) exk);
5211 }
5212
28bf4b0b 5213 xdump = cstring_undefined;
5214
5215 if (uentry_hasWarning (v))
616915dd 5216 {
28bf4b0b 5217 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
616915dd 5218 }
28bf4b0b 5219
5220 if (uentry_hasStateClauseList (v))
616915dd 5221 {
28bf4b0b 5222 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
616915dd 5223 }
28bf4b0b 5224
5225 return (message ("%q%q%q%q@%q%q#%s",
5226 ctype_dump (v->utype),
5227 sdump,
5228 gdump,
5229 adump,
5230 typeIdSet_dump (uentry_accessType (v)),
5231 xdump,
5232 v->uname));
616915dd 5233 }
5234 case KITER:
5235 return (message ("%q@%q#%s",
5236 ctype_dump (v->utype),
5237 typeIdSet_dump (v->info->iter->access),
5238 v->uname));
5239 case KENDITER:
5240 return (message ("%q@%q#%s",
5241 ctype_dump (v->utype),
5242 typeIdSet_dump (uentry_accessType (v)),
5243 v->uname));
5244 case KENUMCONST:
5245 case KCONST:
5246 {
5247 cstring sdump;
5248
b9904f57 5249 if (multiVal_isUnknown (uentry_getConstantValue (v))
616915dd 5250 && typeIdSet_isEmpty (uentry_accessType (v))
5251 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5252 {
5253 sdump = cstring_makeLiteral ("$");
5254 }
5255 else
5256 {
5257 sdump = message ("@%q@%q@%d",
b9904f57 5258 multiVal_dump (uentry_getConstantValue (v)),
616915dd 5259 typeIdSet_dump (uentry_accessType (v)),
5260 (int) sRef_getNullState (v->sref));
5261 }
5262
5263 return (message ("%q%q#%s",
5264 ctype_dump (v->utype),
5265 sdump,
5266 v->uname));
5267 }
5268 case KSTRUCTTAG:
5269 case KUNIONTAG:
5270 case KENUMTAG:
5271 return (message ("%q@%q#%s",
5272 ctype_dump (v->utype),
5273 ctype_dump (v->info->datatype->type), v->uname));
5274 }
5275
5276 BADEXIT;
5277}
5278
5279/*@only@*/ cstring
5280uentry_unparseAbbrev (uentry v)
5281{
5282 if (!uentry_isVariable (v))
5283 {
5284 llcontbuglit ("uentry_unparseAbbrev: not variable");
5285 return uentry_unparse (v);
5286 }
5287
5288 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5289}
5290
5291/*@only@*/ cstring
5292uentry_unparse (uentry v)
5293{
5294 cstring st;
5295
5296 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5297 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5298
5299 st = uentry_getName (v);
5300
5301 if (cstring_isDefined (st))
5302 {
5303 return (ctype_unparseDeclaration (v->utype, st));
5304 }
5305 else
5306 {
5307 cstring_free (st);
5308 return (cstring_copy (ctype_unparse (v->utype)));
5309 }
5310}
5311
5312/*@only@*/ cstring
5313uentry_unparseFull (uentry v)
5314{
5315 if (uentry_isUndefined (v))
5316 {
5317 return (cstring_makeLiteral ("<undefined>"));
5318 }
616915dd 5319 else
5320 {
28bf4b0b 5321 cstring res;
5322
5323 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5324 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5325 ctype_unparse (v->utype),
5326 fileloc_unparse (uentry_whereSpecified (v)),
5327 fileloc_unparse (uentry_whereDeclared (v)),
5328 fileloc_unparse (uentry_whereDefined (v)));
5329
5330 DPRINTF (("uentry: %s", res));
5331
5332 if (uentry_isDatatype (v))
5333 {
5334 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5335 res,
5336 ctype_unparse
5337 (ctype_isDefined (v->info->datatype->type)
5338 ? v->info->datatype->type : ctype_unknown),
5339 ynm_unparse (v->info->datatype->mut),
5340 ynm_unparse (v->info->datatype->abs),
5341 sRef_unparseState (v->sref));
5342 }
5343 else if (uentry_isFunction (v))
5344 {
5345 res = message ("%q / sref: %q / mods: %q / "
ba45e1e4 5346 "globs: %q / clauses: %q / pre: %q / post: %q",
28bf4b0b 5347 res,
5348 sRef_unparseFull (v->sref),
5349 sRefSet_unparse (v->info->fcn->mods),
5350 globSet_unparse (v->info->fcn->globs),
ba45e1e4 5351 stateClauseList_unparse (v->info->fcn->specclauses),
5352 functionConstraint_unparse (v->info->fcn->preconditions),
5353 functionConstraint_unparse (v->info->fcn->postconditions));
28bf4b0b 5354 }
5355 else if (uentry_isIter (v))
5356 {
5357 res = message ("%q / sref: %q",
5358 res,
5359 sRef_unparseFull (v->sref));
5360 }
5361 else if (uentry_isVariable (v))
5362 {
5363 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5364 res,
5365 sRef_unparseFull (v->sref),
5366 (int) v->info->var->kind,
5367 (int) v->info->var->defstate,
5368 (int) v->info->var->nullstate,
5369 (int) v->used);
5370 DPRINTF (("sref: [%p]", v->sref));
5371 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5372 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5373 }
b9904f57 5374 else if (uentry_isConstant (v))
5375 {
5376 res = message ("%q = %q",
5377 res, multiVal_unparse (uentry_getConstantValue (v)));
5378 }
28bf4b0b 5379 else
5380 {
5381 res = message ("%q :: %q", res, uentry_unparse (v));
5382 }
5383
5384 return res;
616915dd 5385 }
5386}
5387
5388bool uentry_hasAccessType (uentry e)
5389{
5390 if (uentry_isValid (e))
5391 {
5392 switch (e->ukind)
5393 {
5394 case KITER:
5395 return (!typeIdSet_isEmpty (e->info->iter->access));
5396 case KENDITER:
5397 return (!typeIdSet_isEmpty (e->info->enditer->access));
5398 case KFCN:
5399 return (!typeIdSet_isEmpty (e->info->fcn->access));
5400 case KENUMCONST:
5401 case KCONST:
5402 return (!typeIdSet_isEmpty (e->info->uconst->access));
5403 default:
5404 return FALSE;
5405 }
5406 }
5407
5408 return FALSE;
5409}
5410
5411typeIdSet uentry_accessType (uentry e)
5412{
5413 if (uentry_isValid (e))
5414 {
5415 switch (e->ukind)
5416 {
5417 case KITER:
5418 return (e->info->iter->access);
5419 case KENDITER:
5420 return (e->info->enditer->access);
5421 case KFCN:
5422 return (e->info->fcn->access);
5423 case KENUMCONST:
5424 case KCONST:
5425 return (e->info->uconst->access);
5426 default:
5427 break;
5428 }
5429 }
5430
5431 return typeIdSet_undefined;
5432}
5433
5434bool
5435uentry_isVariable (uentry e)
5436{
5437 return (uentry_isVar (e));
5438}
5439
5440bool
5441uentry_isSpecified (uentry e)
5442{
5443 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5444}
5445
5446static bool
5447uentry_isReallySpecified (uentry e)
5448{
5449 return (uentry_isValid (e)
5450 && fileloc_isRealSpec (e->whereSpecified));
5451}
5452
5453bool
5454uentry_isVar (uentry e)
5455{
5456 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5457}
5458
5459bool
5460uentry_isFakeTag (uentry e)
5461{
5462 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5463}
5464
5465bool
5466uentry_isDatatype (uentry e)
5467{
5468 return (!uentry_isUndefined (e) &&
5469 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5470 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5471}
5472
5473void
5474uentry_setAbstract (uentry e)
5475{
5476 typeId oldid;
5477
5478 llassert (uentry_isDatatype (e)
5479 && (ynm_isMaybe (e->info->datatype->abs)));
5480
5481 oldid = ctype_typeId (e->info->datatype->type);
5482 e->info->datatype->abs = YES;
5483 e->info->datatype->type = ctype_createAbstract (oldid);
5484}
5485
5486void
5487uentry_setConcrete (uentry e)
5488{
5489 llassert (uentry_isDatatype (e)
5490 && (ynm_isMaybe (e->info->datatype->abs)));
5491
5492 e->info->datatype->abs = NO;
5493}
5494
5495bool
5496uentry_isAbstractDatatype (uentry e)
5497{
5498 return (uentry_isDatatype (e)
5499 && (ynm_isOn (e->info->datatype->abs)));
5500}
5501
5502bool
5503uentry_isMaybeAbstract (uentry e)
5504{
5505 return (uentry_isDatatype (e)
5506 && (ynm_isMaybe (e->info->datatype->abs)));
5507}
5508
5509bool
5510uentry_isMutableDatatype (uentry e)
5511{
5512 bool res = uentry_isDatatype (e)
5513 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5514
5515 return res;
5516}
5517
5518bool
5519uentry_isRefCountedDatatype (uentry e)
5520{
5521 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5522}
5523
5524bool
5525uentry_isParam (uentry u)
5526{
5527 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5528 || u->info->var->kind == VKYIELDPARAM));
5529}
5530
5531bool
5532uentry_isExpandedMacro (uentry u)
5533{
5534 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5535}
5536
5537bool
5538uentry_isSefParam (uentry u)
5539{
5540 return (uentry_isVariable (u)
5541 && (u->info->var->kind == VKSEFPARAM
5542 || u->info->var->kind == VKREFSEFPARAM
5543 || u->info->var->kind == VKSEFRETPARAM
5544 || u->info->var->kind == VKREFSEFRETPARAM));
5545}
5546
5547bool
5548uentry_isRefParam (uentry u)
5549{
5550 return (uentry_isVariable (u)
5551 && (u->info->var->kind == VKREFPARAM
5552 || u->info->var->kind == VKREFYIELDPARAM
5553 || u->info->var->kind == VKREFSEFPARAM
5554 || u->info->var->kind == VKREFSEFRETPARAM));
5555}
5556
5557bool
5558uentry_isAnyParam (uentry u)
5559{
5560 return (uentry_isVariable (u)
5561 && ((u->info->var->kind == VKPARAM)
5562 || (u->info->var->kind == VKSEFPARAM)
5563 || (u->info->var->kind == VKYIELDPARAM)
5564 || (u->info->var->kind == VKRETPARAM)
5565 || (u->info->var->kind == VKSEFRETPARAM)));
5566}
5567
5568sstate
5569uentry_getDefState (uentry u)
5570{
5571 if (uentry_isValid (u))
5572 {
5573 return (sRef_getDefState (u->sref));
5574 }
5575 else
5576 {
5577 return (SS_UNKNOWN);
5578 }
5579}
5580
5581bool
5582uentry_isOut (uentry u)
5583{
5584 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5585 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5586}
5587
5588bool
5589uentry_isPartial (uentry u)
5590{
5591 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5592 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5593}
5594
5595bool
5596uentry_isStateSpecial (uentry u)
5597{
5598 return ((uentry_isVariable (u)
5599 && (u->info->var->defstate == SS_SPECIAL))
5600 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5601}
5602
5603exitkind uentry_getExitCode (uentry ue)
5604{
5605 if (uentry_isFunction (ue))
5606 {
5607 return ue->info->fcn->exitCode;
5608 }
5609 else
5610 {
5611 return XK_UNKNOWN;
5612 }
5613}
5614
28bf4b0b 5615qual uentry_nullPred (uentry u)
616915dd 5616{
5617 llassert (uentry_isRealFunction (u));
5618
5619 if (uentry_isFunction (u))
5620 {
5621 return (u->info->fcn->nullPred);
5622 }
5623 else
5624 {
28bf4b0b 5625 return qual_createUnknown ();
616915dd 5626 }
5627}
5628
28bf4b0b 5629/*
5630** Note for variables, this is checking the declared state, not the current state.
5631*/
5632
616915dd 5633bool
5634uentry_possiblyNull (uentry u)
5635{
5636 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5637 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5638}
5639
5640alkind
5641uentry_getAliasKind (uentry u)
5642{
5643 if (uentry_isValid (u))
5644 {
5645 return (sRef_getAliasKind (uentry_getSref (u)));
5646 }
5647 else
5648 {
5649 return AK_UNKNOWN;
5650 }
5651}
5652
5653exkind
5654uentry_getExpKind (uentry u)
5655{
5656 if (uentry_isValid (u))
5657 {
5658 return (sRef_getExKind (uentry_getSref (u)));
5659 }
5660 else
5661 {
5662 return XO_UNKNOWN;
5663 }
5664}
5665
5666bool
5667uentry_isIter (uentry e)
5668{
5669 return (!uentry_isUndefined (e) && e->ukind == KITER);
5670}
5671
5672bool
5673uentry_isEndIter (uentry e)
5674{
5675 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5676}
5677
5678bool
5679uentry_isRealFunction (uentry e)
5680{
5681 return (uentry_isFunction (e) ||
5682 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5683}
5684
5685bool
5686uentry_hasName (uentry e)
5687{
5688 if (uentry_isValid (e))
5689 {
5690 cstring s = e->uname;
5691
28bf4b0b 5692 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5693 || uentry_isFakeTag (e)));
616915dd 5694 }
5695 else
5696 {
5697 return FALSE;
5698 }
5699}
5700
28bf4b0b 5701/*
5702** Returns true for fake tags.
5703** This is used for dumping the library
5704*/
5705
616915dd 5706bool uentry_hasRealName (uentry e)
5707{
28bf4b0b 5708 return (uentry_isValid (e)
5709 && cstring_isNonEmpty (e->uname)
5710 && !uentry_isGlobalMarker (e));
616915dd 5711}
5712
5713
5714/*@observer@*/ globSet
5715uentry_getGlobs (uentry l)
5716{
5717 if (uentry_isInvalid (l))
5718 {
5719 return globSet_undefined;
5720 }
5721
5722 if (l->ukind != KFCN)
5723 {
5724 if (l->ukind != KITER && l->ukind != KENDITER)
5725 {
5726 if (l->ukind == KVAR)
5727 {
5728 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5729 uentry_unparse (l),
5730 ekind_unparse (l->ukind)));
5731 }
5732 else
5733 {
5734 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5735 uentry_unparse (l),
5736 ekind_unparse (l->ukind)));
5737 }
5738 }
5739 return globSet_undefined;
5740 }
5741
5742 return l->info->fcn->globs;
5743}
5744
5745/*@observer@*/ sRefSet
5746uentry_getMods (uentry l)
5747{
5748 llassert (uentry_isValid (l));
5749
5750 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5751 {
5752 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5753 return sRefSet_undefined;
5754 }
5755
5756 return l->info->fcn->mods;
5757}
5758
5759ekind
5760uentry_getKind (uentry e)
5761{
5762 llassert (uentry_isValid (e));
5763
5764 return (e->ukind);
5765}
5766
5767/*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5768{
b9904f57 5769 llassert (uentry_isEitherConstant (e));
5770 return (sRef_getValue (e->sref));
616915dd 5771}
5772
5773/*@observer@*/ uentryList
5774uentry_getParams (uentry l)
5775{
5776 if (uentry_isInvalid (l)) return uentryList_undefined;
5777
5778 switch (l->ukind)
5779 {
5780 case KFCN:
5781 case KITER:
5782 {
5783 ctype ct = l->utype;
5784
5785 if (ctype_isFunction (ct))
5786 {
5787 return (ctype_argsFunction (ct));
5788 }
5789 else
5790 {
5791 return uentryList_undefined;
5792 }
5793 }
5794 case KVAR:
5795 {
5796 ctype ct = l->utype;
5797
5798 llassert (ctype_isFunction (ct));
5799 return (ctype_argsFunction (ct));
5800 }
5801 BADDEFAULT;
5802 }
5803 BADEXIT;
5804}
5805
5806/*@observer@*/ cstring
5807uentry_rawName (uentry e)
5808{
5809 if (uentry_isValid (e))
5810 {
5811 return (e->uname);
5812 }
5813 else
5814 {
5815 return cstring_undefined;
5816 }
5817}
5818
5819static cstring
5820uentry_getOptName (uentry e)
5821{
5822 cstring s = uentry_getName (e);
5823
5824 if (cstring_isDefined (s))
5825 {
5826 s = cstring_appendChar (s, ' ');
5827 }
5828
5829 return s;
5830}
5831
5832/*@only@*/ cstring
5833uentry_getName (uentry e)
5834{
5835 cstring ret = cstring_undefined;
5836
5837 if (uentry_isValid (e))
5838 {
616915dd 5839 if (uentry_isAnyTag (e))
5840 {
28bf4b0b 5841 ret = fixTagName (e->uname);
616915dd 5842 }
5843 else if (uentry_isAnyParam (e))
5844 {
5845 ret = cstring_copy (fixParamName (e->uname));
5846 }
5847 else
5848 {
5849 ret = cstring_copy (e->uname);
5850 }
5851 }
5852
5853 return ret;
5854}
5855
28bf4b0b 5856cstring uentry_observeRealName (uentry e)
5857{
5858 cstring ret = cstring_undefined;
5859
5860 if (uentry_isValid (e))
5861 {
5862 if (uentry_isAnyTag (e))
5863 {
5864 if (isFakeTag (e->uname))
5865 {
5866 ret = cstring_undefined;
5867 }
5868 else
5869 {
5870 ret = plainTagName (e->uname);
5871 }
5872 }
5873 else if (uentry_isAnyParam (e))
5874 {
5875 ret = fixParamName (e->uname);
5876 }
5877 else
5878 {
5879 ret = e->uname;
5880 }
5881 }
5882
5883 return ret;
5884}
5885
616915dd 5886cstring uentry_getRealName (uentry e)
5887{
5888 if (uentry_isValid (e))
5889 {
5890 if (uentry_isAnyTag (e))
5891 {
5892 return (cstring_undefined);
5893 }
5894 else
5895 {
5896 return (e->uname);
5897 }
5898 }
5899 return cstring_undefined;
5900}
5901
5902ctype uentry_getType (uentry e)
5903{
5904 if (uentry_isValid (e))
5905 {
5906 return e->utype;
5907 }
5908 else
5909 {
5910 return ctype_unknown;
5911 }
5912}
5913
5914fileloc uentry_whereLast (uentry e)
5915{
5916 fileloc loc;
5917
5918 if (uentry_isInvalid (e))
5919 {
5920 return fileloc_undefined;
5921 }
5922
5923 loc = e->whereDefined;
5924
5925 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5926 {
5927 return loc;
5928 }
5929
5930 loc = uentry_whereDeclared (e);
5931
5932 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5933 {
5934 return loc;
5935 }
5936
5937 loc = uentry_whereSpecified (e);
5938 return loc;
5939}
5940
5941fileloc uentry_whereEither (uentry e)
5942{
5943 if (uentry_isInvalid (e)) return fileloc_undefined;
5944
5945 if (fileloc_isDefined (e->whereDefined)
5946 && !fileloc_isExternal (e->whereDefined))
5947 {
5948 return e->whereDefined;
5949 }
5950 else if (fileloc_isDefined (e->whereDeclared))
5951 {
5952 return e->whereDeclared;
5953 }
5954 else
5955 {
5956 return e->whereSpecified;
5957 }
5958}
5959
5960fileloc uentry_whereSpecified (uentry e)
5961{
5962 if (uentry_isInvalid (e)) return fileloc_undefined;
5963
5964 return (e->whereSpecified);
5965}
5966
5967fileloc uentry_whereDefined (uentry e)
5968{
5969 if (uentry_isInvalid (e)) return fileloc_undefined;
5970
5971 return (e->whereDefined);
5972}
5973
5974fileloc uentry_whereDeclared (uentry e)
5975{
5976 if (uentry_isInvalid (e)) return fileloc_undefined;
5977
5978 return (e->whereDeclared);
5979}
5980
5981/*@observer@*/ fileloc
5982uentry_whereEarliest (uentry e)
5983{
5984 if (uentry_isInvalid (e)) return fileloc_undefined;
5985
5986 if (fileloc_isDefined (e->whereSpecified))
5987 {
5988 return (e->whereSpecified);
5989 }
5990 else if (fileloc_isDefined (e->whereDeclared))
5991 {
5992 return (e->whereDeclared);
5993 }
5994 else
5995 {
5996 return e->whereDefined;
5997 }
5998}
5999
6000void
6001uentry_setFunctionDefined (uentry e, fileloc loc)
6002{
6003 if (uentry_isValid (e))
6004 {
6005 llassert (uentry_isFunction (e));
6006
6007 if (fileloc_isUndefined (e->whereDeclared))
6008 {
6009 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6010 }
6011
6012 if (!fileloc_isDefined (e->whereDefined))
6013 {
6014 e->whereDefined = fileloc_update (e->whereDefined, loc);
6015 }
6016 }
6017}
6018
6019void
6020uentry_setDeclDef (uentry e, fileloc f)
6021{
6022 uentry_setDeclared (e, f);
6023
6024 if (!uentry_isFunction (e)
6025 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6026 {
6027 uentry_setDefined (e, f);
6028 }
6029}
6030
6031void
6032uentry_setDeclaredForce (uentry e, fileloc f)
6033{
6034 llassert (uentry_isValid (e));
6035 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6036}
6037
6038void
6039uentry_setDeclaredForceOnly (uentry e, fileloc f)
6040{
6041 llassert (uentry_isValid (e));
6042 fileloc_free (e->whereDeclared);
6043 e->whereDeclared = f;
6044}
6045
6046void
6047uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6048{
6049 fileloc oldloc;
6050
6051 llassert (uentry_isValid (e));
6052 oldloc = e->whereDeclared;
6053
6054 if (fileloc_isDefined (oldloc))
6055 {
6056 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6057 {
6058 e->whereDeclared = f;
6059 fileloc_free (oldloc);
6060 }
6061 else
6062 {
6063 fileloc_free (f);
6064 }
6065 }
6066 else
6067 {
6068 e->whereDeclared = f;
6069 fileloc_free (oldloc);
6070 }
6071}
6072
6073void
6074uentry_setDeclared (uentry e, fileloc f)
6075{
6076 fileloc oldloc;
6077
6078 llassert (uentry_isValid (e));
6079 oldloc = e->whereDeclared;
6080
6081 if (fileloc_isDefined (oldloc))
6082 {
6083 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6084 {
6085 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6086 }
6087 else
6088 {
6089 ;
6090 }
6091 }
6092 else
6093 {
6094 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6095 }
6096}
6097
6098void
6099uentry_clearDefined (uentry e)
6100{
6101 if (uentry_isValid (e))
6102 {
6103 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6104 }
6105}
6106
6107void
6108uentry_setDefined (uentry e, fileloc f)
6109{
6110 fileloc oldloc;
6111
6112 llassert (uentry_isValid (e));
6113 oldloc = e->whereDefined;
6114
6115 if (fileloc_isDefined (oldloc))
6116 {
6117 if (fileloc_isLib (oldloc)
6118 || fileloc_isImport (oldloc)
6119 || fileloc_isBuiltin (oldloc)
6120 || fileloc_isPreproc (oldloc))
6121 {
6122 e->whereDefined = fileloc_update (e->whereDefined, f);
6123 }
6124 else
6125 {
6126 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6127 {
6128 ; /* okay */
6129 }
6130 else
6131 {
6132 if (optgenerror (FLG_REDEF,
6133 message ("%s %q redefined",
6134 ekind_capName (e->ukind),
6135 uentry_getName (e)),
6136 f))
6137 {
6138 llgenindentmsg (message ("Previous definition of %q",
6139 uentry_getName (e)),
6140 e->whereDefined);
6141 }
6142 }
6143 }
6144 }
6145 else
6146 {
6147 e->whereDefined = fileloc_update (e->whereDefined, f);
6148 }
6149}
6150
6151bool
6152uentry_isCodeDefined (uentry e)
6153{
efd360a3 6154 llassert (uentry_isValid (e));
6155
6156 return (fileloc_isDefined (e->whereDefined));
616915dd 6157}
6158
6159bool
6160uentry_isDeclared (uentry e)
6161{
6162 if (uentry_isValid (e))
6163 {
6164 return (fileloc_isDefined (e->whereDeclared));
6165 }
6166
6167 return FALSE;
6168}
6169
6170sRef uentry_getSref (uentry e)
6171{
6172 /* not true, used for functions too (but shouldn't be? */
6173 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6174
6175 if (uentry_isInvalid (e)) return sRef_undefined;
6176
6177 return (e->sref);
6178}
6179
6180sRef uentry_getOrigSref (uentry e)
6181{
68de3f33 6182 /*@i523*/ /* evans 2001-09-09 - need to fix this
b7e84605 6183 if (uentry_isValid (e))
6184 {
6185 if (uentry_isVariable (e))
6186 {
6187 return e->info->var->origsref;
6188 }
6189 else
6190 {
6191 sRef sr = sRef_copy (uentry_getSref (e));
6192
6193 sRef_resetState (sr);
6194 sRef_clearDerived (sr);
6195 return (sr);
6196 }
6197 }
6198 else
6199 {
6200 return sRef_undefined;
6201 }
6202 */
6203
616915dd 6204 if (uentry_isValid (e))
6205 {
6206 sRef sr = sRef_copy (uentry_getSref (e));
6207
6208 sRef_resetState (sr);
6209 sRef_clearDerived (sr);
6210
6211 if (uentry_isVariable (e))
6212 {
6213 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6214 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6215 }
6216
6217 return (sr);
6218 }
6219 else
6220 {
6221 return sRef_undefined;
6222 }
6223}
6224
6225/*
6226** requires: uentry e is not in a hashed symbol table
6227*/
6228
6229void
6230uentry_setName (uentry e, /*@only@*/ cstring n)
6231{
6232 llassert (uentry_isValid (e));
6233
6234 cstring_free (e->uname);
6235 e->uname = n;
6236}
6237
6238void
6239uentry_setType (uentry e, ctype t)
6240{
6241 if (uentry_isValid (e))
6242 {
6243 e->utype = t;
6244 sRef_setType (e->sref, t);
6245 }
6246}
6247
6248void
6249uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6250{
6251 ctype rct;
6252 ctype rettype = ctype_unknown;
6253
6254 llassert (uentry_isValid (ue));
6255
efd360a3 6256 uentry_convertVarFunction (ue);
616915dd 6257 llassert (uentry_isFunction (ue));
6258
efd360a3 6259 rct = ctype_realType (ue->utype);
6260
616915dd 6261 if (ctype_isFunction (rct))
6262 {
28bf4b0b 6263 rettype = ctype_getReturnType (rct);
616915dd 6264 }
6265
6266 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6267}
6268
6269void
6270uentry_setRefParam (uentry e)
6271{
616915dd 6272 if (!uentry_isVar (e))
6273 {
6274 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6275 }
6276 else
6277 {
6278 if (e->info->var->kind == VKSEFPARAM)
6279 {
6280 e->info->var->kind = VKREFSEFPARAM;
6281 }
6282 else if (e->info->var->kind == VKSEFRETPARAM)
6283 {
6284 e->info->var->kind = VKREFSEFRETPARAM;
6285 }
6286 else if (e->info->var->kind == VKYIELDPARAM)
6287 {
6288 e->info->var->kind = VKREFYIELDPARAM;
6289 }
6290 else
6291 {
6292 e->info->var->kind = VKREFPARAM;
6293 }
6294 }
6295}
6296
6297void
6298uentry_setParam (uentry e)
6299{
6300 if (!uentry_isVar (e))
6301 {
6302 if (uentry_isElipsisMarker (e))
6303 {
6304
6305 }
6306 else
6307 {
6308 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6309 }
6310 }
6311 else
6312 {
6313 cstring oldname;
6314
6315 if (e->info->var->kind == VKYIELDPARAM
6316 || e->info->var->kind == VKSEFPARAM
6317 || e->info->var->kind == VKSEFRETPARAM)
6318 {
6319 ;
6320 }
6321 else
6322 {
6323 e->info->var->kind = VKPARAM;
6324 }
6325
6326 oldname = e->uname;
6327 e->uname = makeParam (e->uname);
6328 cstring_free (oldname);
6329 }
6330}
6331
6332void
6333uentry_setSref (uentry e, sRef s)
6334{
6335 if (uentry_isValid (e))
6336 {
6337 if (sRef_isValid (e->sref))
6338 {
6339 sRef_mergeStateQuietReverse (e->sref, s);
6340 }
6341 else
6342 {
6343 e->sref = sRef_saveCopy (s);
6344 }
6345 }
6346}
6347
6348ctype
6349uentry_getAbstractType (uentry e)
6350{
6351 llassert (uentry_isDatatype (e));
6352
6353 /*
6354 ** This assertion removed.
6355 ** Okay to have undefined type, for system types
6356
6357 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6358 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6359 e->utype);
6360
6361 */
6362
6363 if (ctype_isUndefined (e->info->datatype->type))
6364 {
6365 return ctype_unknown;
6366 }
6367
6368 /*
6369 ** Sadly, a kludge...
6370 */
6371
6372 if (ctype_isUserBool (e->info->datatype->type)) {
6373 return ctype_bool;
6374 }
6375
6376 return e->info->datatype->type;
6377}
6378
6379ctype uentry_getRealType (uentry e)
6380{
6381 ctype ct;
6382 typeId uid = USYMIDINVALID;
6383
6384 if (uentry_isInvalid (e))
6385 {
6386 return ctype_unknown;
6387 }
6388
6389 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6390
6391 if (uentry_isAnyTag (e))
6392 {
6393 return (e->utype);
6394 }
6395
6396 if (uentry_isAbstractType (e))
6397 {
6398 ct = uentry_getAbstractType (e);
6399
6400 if (ctype_isManifestBool (ct)) {
6401 return ct;
6402 }
6403
6404 llassert (ctype_isUA (ct));
6405
6406 uid = ctype_typeId (ct);
6407
6408 if (!context_hasAccess (uid))
6409 {
6410 return (ct);
6411 }
6412 }
6413
6414 ct = uentry_getType (e);
6415
6416 /* if (ctype_isUserBool (ct)) return ct; */
6417
6418 if (ctype_isManifestBool (ct)) {
6419 return ctype_bool;
6420 }
6421
6422 if (ctype_isUA (ct))
6423 {
6424 usymId iid = ctype_typeId (ct);
6425
28bf4b0b 6426 if (usymId_equal (iid, uid))
616915dd 6427 {
6428 llcontbug (message ("uentry_getRealType: recursive type! %s",
6429 ctype_unparse (ct)));
6430 return ct;
6431 }
6432 else
6433 {
6434 /* evs 2000-07-25: possible infinite recursion ? */
6435 uentry ue2 = usymtab_getTypeEntry (iid);
28bf4b0b 6436
6437 if (ue2 == e)
6438 {
6439 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6440 return ctype_unknown;
6441 }
616915dd 6442
6443 return uentry_getRealType (ue2);
6444 }
6445 }
6446 else
6447 {
6448 return ct;
6449 }
6450}
6451
6452ctype uentry_getForceRealType (uentry e)
6453{
6454 ctype ct;
6455 typeId uid = USYMIDINVALID;
6456
6457 if (uentry_isInvalid (e))
6458 {
6459 return ctype_unknown;
6460 }
6461
6462 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6463
6464 if (uentry_isAnyTag (e))
6465 {
6466 return (e->utype);
6467 }
6468
6469 if (uentry_isAbstractType (e))
6470 {
6471 ct = uentry_getAbstractType (e);
6472 llassert (ctype_isUA (ct));
6473
6474 uid = ctype_typeId (ct);
6475 /* no check for access! */
6476 }
6477
6478 ct = uentry_getType (e);
6479
6480 /* evs 2000-07-25 */
6481 /* if (ctype_isUserBool (ct)) return ct; */
6482
6483 if (ctype_isManifestBool (ct)) {
6484 return ctype_bool;
6485 }
6486
6487 if (ctype_isUA (ct))
6488 {
6489 usymId iid = ctype_typeId (ct);
6490
28bf4b0b 6491 if (usymId_equal (iid, uid))
616915dd 6492 {
6493 llcontbug (message ("uentry_getRealType: recursive type! %s",
6494 ctype_unparse (ct)));
6495 return ct;
6496 }
6497 else
6498 {
6499 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6500 }
6501 }
6502 else
6503 {
6504 return ct;
6505 }
6506}
6507
6508uentry uentry_nameCopy (cstring name, uentry e)
6509{
6510 uentry enew = uentry_alloc ();
6511
6512 llassert (uentry_isValid (e));
6513
6514 /* enew->shallowCopy = FALSE; */
6515 enew->ukind = e->ukind;
6516 enew->uname = name;
6517 enew->utype = e->utype;
6518 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6519 enew->whereDefined = fileloc_copy (e->whereDefined);
6520 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6521 enew->sref = sRef_copy (e->sref);
6522 enew->used = e->used;
6523 enew->lset = FALSE;
6524 enew->isPrivate = e->isPrivate;
6525 enew->hasNameError = FALSE;
6526
6527 enew->uses = filelocList_new ();
28bf4b0b 6528 enew->warn = warnClause_undefined;
616915dd 6529
6530 enew->storageclass = e->storageclass;
6531 enew->info = uinfo_copy (e->info, e->ukind);
6532
6533 return enew;
6534}
6535
6536void
6537uentry_setDatatype (uentry e, usymId uid)
6538{
6539 llassert (uentry_isDatatype (e));
6540
6541 if (uentry_isAbstractType (e))
6542 {
6543 e->info->datatype->type = ctype_createAbstract (uid);
6544 }
6545 else
6546 {
6547 e->info->datatype->type = ctype_createUser (uid);
6548 }
6549}
6550
6551static void
6552uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6553 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6554 /*@modifies e@*/
6555{
6556 llassert (uentry_isValid (e));
6557
6558 if (fileloc_isSpec (f) || fileloc_isImport (f))
6559 {
6560 e->whereSpecified = f;
6561 e->whereDeclared = fileloc_undefined;
6562 e->whereDefined = fileloc_undefined;
6563 }
6564 else
6565 {
6566 e->whereSpecified = fileloc_undefined;
6567 e->whereDeclared = f;
6568 e->whereDefined = fileloc_undefined;
6569 }
7ebcc5bb 6570
6571 llassert (fileloc_storable (f));
616915dd 6572}
6573
6574static void
6575ucinfo_free (/*@only@*/ ucinfo u)
6576{
616915dd 6577 sfree (u);
6578}
6579
6580static void
6581uvinfo_free (/*@only@*/ uvinfo u)
6582{
28bf4b0b 6583 /*drl7x added 6/29/01 */
b072092f 6584 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
616915dd 6585 sfree (u);
6586}
6587
6588static void
6589udinfo_free (/*@only@*/ udinfo u)
6590{
6591 sfree (u);
6592}
6593
6594static void
6595ufinfo_free (/*@only@*/ ufinfo u)
6596{
6597 globSet_free (u->globs);
6598 sRefSet_free (u->mods);
28bf4b0b 6599 stateClauseList_free (u->specclauses);
616915dd 6600 sfree (u);
6601}
6602
6603static void
6604uiinfo_free (/*@only@*/ uiinfo u)
6605{
6606 sfree (u);
6607}
6608
6609static void
6610ueinfo_free (/*@only@*/ ueinfo u)
6611{
6612 sfree (u);
6613}
6614
6615static /*@only@*/ ucinfo
6616ucinfo_copy (ucinfo u)
6617{
6618 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
616915dd 6619 ret->access = u->access;
3e3ec469 6620 ret->macro = u->macro;
616915dd 6621 return ret;
6622}
6623
6624static /*@only@*/ uvinfo
6625uvinfo_copy (uvinfo u)
6626{
6627 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6628
6629 ret->kind = u->kind;
6630 ret->nullstate = u->nullstate;
6631 ret->defstate = u->defstate;
6632 ret->checked = u->checked;
28bf4b0b 6633
b7e84605 6634 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6635
28bf4b0b 6636 /* drl added 07-02-001 */
6637 /* copy null terminated information */
6638
6639 if (u->bufinfo != NULL)
6640 {
6641 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6642 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6643 ret->bufinfo->size = u->bufinfo->size;
6644 ret->bufinfo->len = u->bufinfo->len;
6645 return ret;
6646 }
6647 else
6648 {
6649 ret->bufinfo = NULL;
6650 return ret;
6651 }
6652
616915dd 6653}
6654
6655static /*@only@*/ udinfo
6656udinfo_copy (udinfo u)
6657{
6658 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6659
6660 ret->abs = u->abs;
6661 ret->mut = u->mut;
6662 ret->type = u->type;
6663
6664 return ret;
6665}
6666
6667static /*@only@*/ ufinfo
6668ufinfo_copy (ufinfo u)
6669{
6670 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6671
6672 ret->hasGlobs = u->hasGlobs;
6673 ret->hasMods = u->hasMods;
6674 ret->exitCode = u->exitCode;
6675 ret->specialCode = u->specialCode;
6676 ret->nullPred = u->nullPred;
6677 ret->access = u->access;
6678 ret->globs = globSet_newCopy (u->globs);
6679 ret->mods = sRefSet_newCopy (u->mods);
6680 ret->defparams = u->defparams;
28bf4b0b 6681 ret->specclauses = stateClauseList_copy (u->specclauses);
616915dd 6682
3814599d 6683 ret->preconditions = functionConstraint_copy (u->preconditions);
6684 ret->postconditions = functionConstraint_copy (u->postconditions);
616915dd 6685
6686 return ret;
6687}
6688
6689static /*@only@*/ uiinfo
6690uiinfo_copy (uiinfo u)
6691{
6692 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6693
6694 ret->access = u->access;
6695 ret->globs = globSet_newCopy (u->globs);
6696 ret->mods = sRefSet_newCopy (u->mods);
6697
6698 return (ret);
6699}
6700
6701static /*@only@*/ ueinfo
6702ueinfo_copy (ueinfo u)
6703{
6704 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6705
6706 ret->access = u->access;
6707 return ret;
6708}
6709
6710static void
6711uinfo_free (uinfo u, ekind kind)
6712{
6713 switch (kind)
6714 {
6715 case KENUMCONST:
6716 case KCONST: ucinfo_free (u->uconst); break;
6717 case KVAR: uvinfo_free (u->var); break;
6718 case KSTRUCTTAG:
6719 case KUNIONTAG:
6720 case KENUMTAG:
6721 case KDATATYPE: udinfo_free (u->datatype); break;
6722 case KFCN: ufinfo_free (u->fcn); break;
6723 case KITER: uiinfo_free (u->iter); break;
6724 case KENDITER: ueinfo_free (u->enditer); break;
6725 case KELIPSMARKER: break;
6726 case KINVALID: break;
6727 }
6728
6729 sfree (u);
6730}
6731
6732static /*@only@*/ /*@null@*/ uinfo
6733uinfo_copy (uinfo u, ekind kind)
6734{
6735 if (kind == KELIPSMARKER || kind == KINVALID)
6736 {
6737 return NULL;
6738 }
6739 else
6740 {
6741 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6742
6743 switch (kind)
6744 {
6745 case KENUMCONST:
6746 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6747 case KVAR: ret->var = uvinfo_copy (u->var); break;
6748 case KSTRUCTTAG:
6749 case KUNIONTAG:
6750 case KENUMTAG:
6751 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6752 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6753 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6754 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6755 BADDEFAULT;
6756 }
6757 return ret;
6758 }
6759}
6760
6761static void
6762uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6763{
6764 filelocList_free (e->uses);
6765 cstring_free (e->uname);
6766
6767 uinfo_free (e->info, e->ukind);
6768
6769 fileloc_free (e->whereSpecified);
6770 fileloc_free (e->whereDefined);
6771 fileloc_free (e->whereDeclared);
6772
28bf4b0b 6773 warnClause_free (e->warn);
6774
616915dd 6775 nuentries--;
6776 sfree (e);
6777 }
6778
6779extern void uentry_markOwned (/*@owned@*/ uentry u)
6780{
6781 sfreeEventually (u);
6782}
6783
6784void
6785uentry_free (/*@only@*/ uentry e)
6786{
6787 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6788 {
6789 uentry_reallyFree (e);
6790 }
6791}
6792
6793/*
6794** For uentry's in the global or file scope
6795*/
6796
6797void
6798uentry_freeComplete (/*@only@*/ uentry e)
6799{
6800 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6801 {
28bf4b0b 6802 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
616915dd 6803 /*@i@*/ sRef_free (e->sref);
6804 e->sref = sRef_undefined;
6805 uentry_reallyFree (e);
6806 }
6807}
6808
6809/*
6810** requires old->kind != new->kind, old->uname = new->uname
6811*/
6812
6813static void
6814KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6815{
6816 llassert (uentry_isValid (old));
6817 llassert (uentry_isValid (unew));
6818
6819 if (uentry_isEitherConstant (unew)
6820 && (fileloc_isPreproc (uentry_whereDeclared (old))
6821 || ctype_isUnknown (old->utype))
6822 && !uentry_isSpecified (old))
6823 {
6824 ; /* no error */
6825 }
6826 else
6827 {
6828 if (mustConform)
6829 {
6830 if (!uentry_isDeclared (old))
6831 {
6832 if (uentry_isSpecified (old))
6833 {
6834 if (uentry_isSpecified (unew))
6835 {
6836 llbuglit ("Respecification!");
6837 }
6838 else if (uentry_isDeclared (unew))
6839 {
6840 if (optgenerror
6841 (FLG_INCONDEFS,
6842 message ("%s %q inconsistently declared as %s: %t",
6843 ekind_capName (old->ukind),
6844 uentry_getName (unew),
6845 ekind_unparseLong (unew->ukind),
6846 unew->utype),
f2b6724f 6847 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6848 {
f2b6724f 6849 uentry_showWhereLastKind (old);
616915dd 6850 }
6851 }
6852 else
6853 {
6854 BADEXIT;
6855 }
6856 }
6857 else
6858 {
6859 if (optgenerror
6860 (FLG_INCONDEFS,
6861 message ("%s %q inconsistently declared as %s: %t",
6862 ekind_capName (old->ukind),
6863 uentry_getName (unew),
6864 ekind_unparseLong (unew->ukind),
6865 unew->utype),
f2b6724f 6866 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6867 {
f2b6724f 6868 uentry_showWhereLastKind (old);
616915dd 6869 }
6870 }
6871 }
6872 else
6873 {
6874 llassert (uentry_isDeclared (unew));
6875
f2b6724f 6876 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6877 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6878
616915dd 6879 if (optgenerror
6880 (FLG_INCONDEFS,
6881 message ("%s %q inconsistently redeclared as %s",
6882 ekind_capName (old->ukind),
6883 uentry_getName (unew),
6884 ekind_unparseLong (unew->ukind)),
f2b6724f 6885 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6886 {
f2b6724f 6887 uentry_showWhereLastKind (old);
616915dd 6888 }
6889 }
6890 }
6891 }
6892
efd360a3 6893 uentry_updateInto (old, unew);
616915dd 6894}
6895
6896/*
6897** def is the definition of spec, modifies spec
6898**
6899** reports any inconsistencies
6900** returns the summary of all available information
6901** if spec and def are inconsistent, def is returned
6902*/
6903
6904void
6905uentry_showWhereLast (uentry spec)
6906{
6907 if (uentry_isValid (spec))
6908 {
6909 if (fileloc_isDefined (spec->whereDefined)
6910 && !fileloc_isLib (spec->whereDefined)
f2b6724f 6911 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
616915dd 6912 {
6913 llgenindentmsg (message ("Previous definition of %q: %t",
6914 uentry_getName (spec),
6915 uentry_getType (spec)),
6916 uentry_whereDefined (spec));
6917 }
6918 else if (uentry_isDeclared (spec))
6919 {
6920 llgenindentmsg (message ("Previous declaration of %q: %t",
6921 uentry_getName (spec),
6922 uentry_getType (spec)),
6923 uentry_whereDeclared (spec));
6924 }
6925 else if (uentry_isSpecified (spec))
6926 {
6927 if (uentry_hasName (spec))
6928 {
6929 llgenindentmsg (message ("Specification of %q: %t",
6930 uentry_getName (spec),
6931 uentry_getType (spec)),
6932 uentry_whereSpecified (spec));
6933 }
6934 else
6935 {
6936 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6937 uentry_whereSpecified (spec));
6938 }
6939 }
6940 else
6941 {
6942 /* nothing to show */
6943 }
6944 }
6945}
6946
f2b6724f 6947static void
6948uentry_showWhereLastKind (uentry spec)
6949{
6950 if (uentry_isValid (spec))
6951 {
6952 if (fileloc_isDefined (spec->whereDefined)
6953 && !fileloc_isLib (spec->whereDefined)
6954 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6955 {
6956 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6957 uentry_getName (spec),
6958 ekind_unparseLong (spec->ukind),
6959 uentry_getType (spec)),
6960 uentry_whereDefined (spec));
6961 }
6962 else if (uentry_isDeclared (spec))
6963 {
6964 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6965 uentry_getName (spec),
6966 ekind_unparseLong (spec->ukind),
6967 uentry_getType (spec)),
6968 uentry_whereDeclared (spec));
6969 }
6970 else if (uentry_isSpecified (spec))
6971 {
6972 if (uentry_hasName (spec))
6973 {
6974 llgenindentmsg (message ("Specification of %q as %s: %t",
6975 uentry_getName (spec),
6976 ekind_unparseLong (spec->ukind),
6977 uentry_getType (spec)),
6978 uentry_whereSpecified (spec));
6979 }
6980 else
6981 {
6982 llgenindentmsg (message ("Specification as %s: %t",
6983 ekind_unparseLong (spec->ukind),
6984 uentry_getType (spec)),
6985 uentry_whereSpecified (spec));
6986 }
6987 }
6988 else
6989 {
6990 /* nothing to show */
6991 }
6992 }
6993}
6994
616915dd 6995void
6996uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6997{
6998 fileloc loc = uentry_whereDefined (ce);
6999
7000 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7001 {
7002 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7003 loc);
7004 }
7005
7006 loc = uentry_whereSpecified (ce);
7007
7008 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7009 {
7010 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7011 loc);
7012 }
7013}
7014
7015void uentry_showWhereLastExtra (uentry spec, cstring extra)
7016{
7017 if (uentry_isDeclared (spec))
7018 {
7019 llgenindentmsg (message ("Previous declaration of %q: %q",
7020 uentry_getName (spec), extra),
7021 uentry_whereDeclared (spec));
7022 }
7023 else if (uentry_isSpecified (spec))
7024 {
7025 llgenindentmsg (message ("Specification of %q: %q",
7026 uentry_getName (spec), extra),
7027 uentry_whereSpecified (spec));
7028 }
7029 else
7030 {
7031 cstring_free (extra);
7032 }
7033}
7034
7035void
7036uentry_showWhereDeclared (uentry spec)
7037{
7038 if (uentry_isDeclared (spec))
7039 {
7040 if (uentry_hasName (spec))
7041 {
7042 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7043 uentry_whereDeclared (spec));
7044 }
7045 else
7046 {
7047 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7048 }
7049 }
7050 else if (uentry_isSpecified (spec))
7051 {
7052 if (uentry_hasName (spec))
7053 {
7054 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7055 uentry_whereSpecified (spec));
7056 }
7057 else
7058 {
7059 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7060 }
7061 }
7062 else
7063 {
7064 /* nothing to show */
7065 }
7066
7067}
7068
7069void
7070uentry_showWhereAny (uentry spec)
7071{
7072 if (uentry_isDeclared (spec))
7073 {
7074 if (uentry_hasName (spec))
7075 {
7076 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7077 uentry_whereDeclared (spec));
7078 }
7079 else
7080 {
7081 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7082 }
7083 }
7084 else if (uentry_isSpecified (spec))
7085 {
7086 if (uentry_hasName (spec))
7087 {
7088 llgenindentmsg (message ("Specification of %q",
7089 uentry_getName (spec)),
7090 uentry_whereSpecified (spec));
7091 }
7092 else
7093 {
7094 llgenindentmsg (cstring_makeLiteral ("Specification"),
7095 uentry_whereSpecified (spec));
7096 }
7097 }
7098 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7099 {
7100 if (uentry_hasName (spec))
7101 {
7102 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7103 uentry_whereDefined (spec));
7104 }
7105 else
7106 {
7107 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7108 }
7109 }
7110 else
7111 {
7112 /* nothing to show */
7113 }
7114}
7115
7116void
7117uentry_showWhereDefined (uentry spec)
7118{
7119 if (uentry_isCodeDefined (spec))
7120 {
7121 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7122 uentry_whereDefined (spec));
7123 }
7124}
7125
7126void
7127uentry_showWhereLastPlain (uentry spec)
7128{
7129 if (uentry_isDeclared (spec))
7130 {
7131 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7132 uentry_whereDeclared (spec));
7133 }
7134 else if (uentry_isSpecified (spec))
7135 {
7136 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7137 uentry_whereSpecified (spec));
7138 }
7139 else
7140 {
7141 }
7142}
7143
7144static void
7145uentry_showWhereLastVal (uentry spec, cstring val)
7146{
7147 if (uentry_isDeclared (spec))
7148 {
7149 llgenindentmsg (message ("Previous declaration of %q: %s",
7150 uentry_getName (spec), val),
7151 uentry_whereDeclared (spec));
7152 }
7153 else if (uentry_isSpecified (spec))
7154 {
7155 llgenindentmsg (message ("Specification of %q: %s",
7156 uentry_getName (spec), val),
7157 uentry_whereSpecified (spec));
7158 }
7159 else
7160 {
7161 }
7162}
7163
7164void
7165uentry_showWhereSpecified (uentry spec)
7166{
7167 if (uentry_isSpecified (spec))
7168 {
7169 if (uentry_hasName (spec))
7170 {
7171 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7172 uentry_whereSpecified (spec));
7173 }
7174 else
7175 {
7176 llgenindentmsg (cstring_makeLiteral ("Specification"),
7177 uentry_whereSpecified (spec));
7178 }
7179 }
7180 else if (uentry_isDeclared (spec))
7181 {
7182 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7183 uentry_whereDeclared (spec));
7184 }
7185 else
7186 {
7187 /* nothing to show */
7188 }
7189}
7190
7191void
7192uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7193{
7194 if (uentry_isSpecified (spec))
7195 {
7196 if (uentry_hasName (spec))
7197 {
7198 llgenindentmsg (message ("Specification of %q: %q",
7199 uentry_getName (spec), s),
7200 uentry_whereSpecified (spec));
7201 }
7202 else
7203 {
7204 llgenindentmsg (message ("Specification: %q", s),
7205 uentry_whereSpecified (spec));
7206 }
7207 }
7208 else if (uentry_isDeclared (spec))
7209 {
7210 llgenindentmsg (message ("Declaration of %q: %q",
7211 uentry_getName (spec), s),
7212 uentry_whereDeclared (spec));
7213 }
7214 else
7215 {
7216 llgenindentmsg (message ("Previous: %q", s),
7217 uentry_whereLast (spec));
7218 }
7219}
7220
7221/*
7222**
7223*/
7224
7225static void
7226checkStructConformance (uentry old, uentry unew)
7227{
7228 ctype oldr, newr;
7229 uentryList fold, fnew;
7230
7231 /*
7232 ** requires: types of old and new are structs or unions
7233 */
7234
7235 llassert (uentry_isValid (old));
7236 llassert (uentry_isValid (unew));
7237
7238 oldr = ctype_realType (old->utype);
7239 fold = ctype_getFields (oldr);
7240
7241 newr = ctype_realType (unew->utype);
7242 fnew = ctype_getFields (newr);
7243
7244 if (!uentryList_matchFields (fold, fnew))
7245 {
7246 if (fileloc_equal (uentry_whereLast (old),
7247 uentry_whereLast (unew)))
7248 {
7249 ; /* cheat! */
7250 }
7251 else
7252 {
7253 if (optgenerror
7254 (FLG_MATCHFIELDS,
7255 message ("%q %q %rdeclared with fields { %q }, %s "
7256 "with fields { %q }",
7257 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7258 uentry_getName (old),
7259 uentry_isDeclared (old),
7260 uentryList_unparseAbbrev (fnew),
7261 uentry_specOrDefName (old),
7262 uentryList_unparseAbbrev (fold)),
7263 uentry_whereDeclared (unew)))
7264 {
7265 uentry_showWhereLastPlain (old);
7266 uentryList_showFieldDifference (fold, fnew);
7267 }
7268 }
7269
7270 old->utype = unew->utype;
7271 }
7272}
7273
7274static void
7275checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7276{
7277 /*
7278 ** requires old and new are enums
7279 */
7280
7281 ctype rold = ctype_realType (old->utype);
7282 ctype rnew = ctype_realType (unew->utype);
7283 enumNameList eold = ctype_elist (rold);
7284 enumNameList enew = ctype_elist (rnew);
7285
7286 if (!enumNameList_match (eold, enew))
7287 {
7288 if (optgenerror
7289 (FLG_MATCHFIELDS,
7290 message ("Enum %q declared with members { %q } but "
7291 "specified with members { %q }",
7292 uentry_getName (old),
7293 enumNameList_unparse (enew),
7294 enumNameList_unparse (eold)),
7295 uentry_whereDeclared (unew)))
7296 {
7297 uentry_showWhereSpecified (old);
7298 old->utype = unew->utype;
7299 }
7300 }
7301}
7302
7303/*
7304** either oldCurrent or newCurrent may be undefined!
7305*/
7306
7307static void
7308paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7309 uentry unew, uentry newCurrent, ctype newType,
7310 int paramno)
7311{
7312 bool hasError = FALSE;
7313
7314 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7315 {
7316 if (uentry_hasName (newCurrent))
7317 {
7318 hasError = optgenerror
7319 (FLG_TYPE,
7320 message ("Parameter %d, %q, of function %q has inconsistent type: "
7321 "declared %t, %s %t",
7322 paramno + 1, uentry_getName (newCurrent),
7323 uentry_getName (unew),
7324 newType, uentry_specOrDefName (old), oldType),
7325 uentry_whereDeclared (newCurrent));
7326 }
7327 else
7328 {
7329 hasError = optgenerror
7330 (FLG_TYPE,
7331 message ("Parameter %d of function %q has inconsistent type: "
7332 "declared %t, %s %t",
7333 paramno + 1, uentry_getName (unew),
7334 newType, uentry_specOrDefName (old), oldType),
7335 uentry_whereDeclared (newCurrent));
7336
7337 DPRINTF (("type: %s / %s",
7338 ctype_unparse (newType),
7339 ctype_unparse (ctype_realType (newType))));
7340 }
7341 }
7342 else
7343 {
7344 if (uentry_isDeclared (unew))
7345 {
7346 hasError = optgenerror
7347 (FLG_TYPE,
7348 message ("Parameter %d of function %s has inconsistent type: "
7349 "declared %t, %s %t",
7350 paramno + 1, unew->uname,
7351 newType, uentry_specOrDefName (old), oldType),
7352 uentry_whereDeclared (unew));
7353 }
7354 else
7355 {
7356 hasError = optgenerror
7357 (FLG_TYPE,
7358 message ("Parameter %d of function %s has inconsistent type: "
7359 "declared %t, %s %t",
7360 paramno + 1, unew->uname,
7361 newType, uentry_specOrDefName (old), oldType),
7362 uentry_whereDeclared (unew));
7363 }
7364 }
7365
7366 if (hasError)
7367 {
6970c11b 7368 DPRINTF (("Here: %s / %s",
7369 uentry_unparseFull (oldCurrent),
7370 uentry_unparseFull (newCurrent)));
7371
616915dd 7372 if (!uentry_isUndefined (oldCurrent))
7373 {
7374 if (!uentry_isUndefined (newCurrent)
7375 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7376 {
7377 uentry_showWhereLast (oldCurrent);
7378 }
7379 else
7380 {
7381 uentry_showWhereLastPlain (old);
7382 }
7383
7384 uentry_setType (oldCurrent, newType);
7385 }
7386 else
7387 {
7388 uentry_showWhereLastPlain (old);
7389 }
7390 }
7391}
7392
7393static void
7394nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7395{
7396 if (optgenerror
7397 (FLG_TYPE,
28bf4b0b 7398 message ("Function %s %rdeclared with %d arg%&, %s with %d",
616915dd 7399 unew->uname,
7400 uentry_isDeclared (old),
7401 uentryList_size (uentry_getParams (unew)),
7402 uentry_specOrDefName (old),
7403 uentryList_size (uentry_getParams (old))),
7404 uentry_whereDeclared (unew)))
7405 {
7406 uentry_showWhereLastPlain (old);
7407 }
7408}
7409
7410static void
7411returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7412{
7413 if (optgenerror
7414 (FLG_INCONDEFS,
7415 message ("Function %s inconsistently %rdeclared to return %t",
7416 unew->uname,
7417 uentry_isDeclared (old),
28bf4b0b 7418 ctype_getReturnType (unew->utype)),
616915dd 7419 uentry_whereDeclared (unew)))
7420 {
28bf4b0b 7421 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
616915dd 7422 }
7423}
7424
7425static cstring paramStorageName (uentry ue)
7426{
7427 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7428}
7429
7430static cstring fcnErrName (uentry ue)
7431{
7432 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7433}
7434
7435extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7436{
7437 if (uentry_isVar (ue))
7438 {
7439 return (checkedName (ue->info->var->checked));
7440 }
7441 else
7442 {
7443 return (cstring_makeLiteralTemp ("<checked invalid>"));
7444 }
7445}
7446
7447static cstring checkedName (chkind checked)
7448{
7449 switch (checked)
7450 {
7451 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7452 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7453 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7454 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7455 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7456 }
7457 BADEXIT;
7458}
7459
7460static
7461void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7462{
7463 nstate oldState;
7464 nstate newState;
7465
7466 if (uentry_isVar (unew))
7467 {
7468 llassert (uentry_isVar (old));
7469
7470 oldState = old->info->var->nullstate;
7471 newState = unew->info->var->nullstate;
7472 }
7473 else
7474 {
7475 oldState = sRef_getNullState (old->sref);
7476 newState = sRef_getNullState (unew->sref);
7477 }
7478
7479 if (oldState == NS_ABSNULL)
7480 {
7481 if (uentry_isVar (old))
7482 {
7483 old->info->var->nullstate = newState;
7484 }
7485
7486 sRef_mergeNullState (old->sref, newState);
7487 }
7488 else if (newState == NS_UNKNOWN)
7489 {
7490 if (completeConform && newState != oldState
7491 && uentry_isReallySpecified (old))
7492 {
7493 if (optgenerror
7494 (FLG_NEEDSPEC,
7495 message ("%s %q specified as %s, but declared without %s qualifier",
7496 ekind_capName (unew->ukind),
7497 uentry_getName (unew),
7498 nstate_unparse (oldState),
7499 nstate_unparse (oldState)),
7500 uentry_whereDeclared (unew)))
7501 {
7502 uentry_showWhereSpecified (old);
7503 }
7504 }
7505
7506 if (uentry_isVar (unew))
7507 {
7508 unew->info->var->nullstate = oldState;
7509 }
7510
7511 sRef_mergeNullState (unew->sref, oldState);
7512 }
7513 else if (newState == NS_POSNULL)
7514 {
7515 if (oldState == NS_MNOTNULL
7516 && (ctype_isUA (unew->utype)
7517 || (uentry_isFunction (unew)
28bf4b0b 7518 && ctype_isUA (ctype_getReturnType (unew->utype)))))
616915dd 7519 {
7520 if (uentry_isVar (unew))
7521 {
7522 unew->info->var->nullstate = oldState;
7523 }
7524
7525 sRef_mergeNullState (unew->sref, oldState);
7526 }
7527 else
7528 {
7529 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7530 || oldState == NS_UNKNOWN)
7531 {
7532 if (mustConform)
7533 {
7534 if (optgenerror
7535 (FLG_INCONDEFS,
7536 message
7537 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7538 "%s %q qualifier",
7539 uentry_ekindName (unew),
7540 uentry_getName (unew),
7541 uentry_isDeclared (old),
7542 fcnErrName (unew),
7543 uentry_specOrDefName (old),
7544 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7545 uentry_whereDeclared (unew)))
7546 {
7547 uentry_showWhereSpecified (old);
7548 }
7549 }
7550 }
7551
7552 if (uentry_isVar (old))
7553 {
7554 old->info->var->nullstate = newState;
7555 }
7556
7557 sRef_mergeNullState (old->sref, newState);
7558 }
7559 }
7560 else if (newState == NS_MNOTNULL)
7561 {
7562 if (oldState != NS_MNOTNULL)
7563 {
7564 if (mustConform)
7565 {
7566 if (optgenerror
7567 (FLG_INCONDEFS,
7568 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7569 "%s without notnull qualifier",
7570 uentry_ekindName (unew),
7571 uentry_getName (unew),
7572 uentry_isDeclared (old),
7573 fcnErrName (unew),
7574 uentry_specOrDefName (old)),
7575 uentry_whereDeclared (unew)))
7576 {
7577 uentry_showWhereSpecified (old);
7578 }
7579 }
7580
7581 if (uentry_isVar (old))
7582 {
7583 old->info->var->nullstate = newState;
7584 }
7585
7586 sRef_mergeNullState (old->sref, newState);
7587 }
7588 }
7589 else
7590 {
7591 if (uentry_isVar (unew))
7592 {
7593 unew->info->var->nullstate = oldState;
7594 }
7595
7596 sRef_mergeNullState (unew->sref, oldState);
7597 }
7598}
7599
7600static
7601void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7602 bool mustConform, bool completeConform)
7603{
7604 sstate oldState;
7605 sstate newState;
7606 bool vars = FALSE;
7607
7608 if (uentry_isVar (old) && uentry_isVar (unew))
7609 {
7610 oldState = old->info->var->defstate;
7611 newState = unew->info->var->defstate;
7612 vars = TRUE;
7613 }
7614 else
7615 {
7616 oldState = sRef_getDefState (old->sref);
7617 newState = sRef_getDefState (unew->sref);
7618 }
7619
28bf4b0b 7620 if (newState != oldState
7621 && newState != SS_UNKNOWN
7622 && newState != SS_DEFINED)
616915dd 7623 {
7624 if (mustConform)
7625 {
7626 if (optgenerror
7627 (FLG_INCONDEFS,
7628 message ("%s %q inconsistently %rdeclared %s %s %s, "
7629 "%s %s %s %s",
7630 uentry_ekindName (unew),
7631 uentry_getName (unew),
7632 uentry_isDeclared (old),
7633 fcnErrName (unew),
7634 sstate_unparse (newState),
7635 paramStorageName (unew),
7636 uentry_specOrDefName (old),
7637 fcnErrName (unew),
7638 sstate_unparse (oldState),
7639 paramStorageName (unew)),
7640 uentry_whereDeclared (unew)))
7641 {
7642 uentry_showWhereSpecified (old);
7643 }
7644 }
28bf4b0b 7645
616915dd 7646 if (vars) old->info->var->defstate = newState;
7647 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7648 }
7649 else
7650 {
7651 if (completeConform
7652 && (newState != oldState) && (oldState != SS_DEFINED)
7653 && uentry_isReallySpecified (old))
7654 {
7655 if (optgenerror
7656 (FLG_NEEDSPEC,
7657 message ("%s %q specified as %s, but declared without %s qualifier",
7658 ekind_capName (unew->ukind),
7659 uentry_getName (unew),
7660 sstate_unparse (oldState),
7661 sstate_unparse (oldState)),
7662 uentry_whereDeclared (unew)))
7663 {
7664 uentry_showWhereSpecified (old);
7665 }
7666 }
28bf4b0b 7667
616915dd 7668 if (vars) unew->info->var->defstate = oldState;
7669 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7670 }
7671}
7672
7673static void
7674 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7675 bool mustConform, bool completeConform)
7676{
7677 alkind newKind;
7678 alkind oldKind;
7679
7680 oldKind = sRef_getAliasKind (old->sref);
7681 newKind = sRef_getAliasKind (unew->sref);
7682
7683 if (alkind_isImplicit (newKind)
7684 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7685 {
7686 if (completeConform && !alkind_equal (newKind, oldKind)
7687 && uentry_isReallySpecified (old))
7688 {
7689 if (optgenerror
7690 (FLG_NEEDSPEC,
7691 message ("%s %q specified as %s, but declared without "
7692 "explicit alias qualifier",
7693 ekind_capName (unew->ukind),
7694 uentry_getName (unew),
7695 alkind_unparse (oldKind)),
7696 uentry_whereDeclared (unew)))
7697 {
7698 uentry_showWhereSpecified (old);
7699 }
7700 }
7701
7702 /*
7703 ** This really shouldn't be necessary, but it is!
7704 ** Function params (?) use new here.
7705 */
7706
7707 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7708 return;
7709 }
7710
7711 if (alkind_isKnown (newKind))
7712 {
7713 if (!alkind_equal (oldKind, newKind))
7714 {
7715 if (alkind_isKnown (oldKind))
7716 {
7717 if (mustConform &&
7718 optgenerror
7719 (FLG_INCONDEFS,
7720 message ("%s %q inconsistently %rdeclared %s %s storage, "
7721 "%s as %s storage",
7722 uentry_ekindName (unew),
7723 uentry_getName (unew),
7724 uentry_isDeclared (old),
7725 fcnErrName (unew),
7726 alkind_unparse (newKind),
7727 uentry_specOrDefName (old),
7728 alkind_unparse (oldKind)),
7729 uentry_whereDeclared (unew)))
7730 {
7731 uentry_showWhereSpecified (old);
7732
28bf4b0b 7733 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7734 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
616915dd 7735 sRef_setAliasKind (old->sref, AK_ERROR,
7736 uentry_whereDeclared (unew));
7737 }
7738 else
7739 {
7740 sRef_setAliasKind (old->sref, newKind,
7741 uentry_whereDeclared (unew));
7742 }
7743 }
7744 else
7745 {
7746 if (!(alkind_isImplicit (newKind)))
7747 {
7748 if (mustConform &&
7749 !uentry_isFunction (unew) &&
7750 optgenerror
7751 (FLG_INCONDEFS,
7752 message ("%s %q inconsistently %rdeclared %s %s storage, "
7753 "implicitly %s as temp storage",
7754 uentry_ekindName (unew),
7755 uentry_getName (unew),
7756 uentry_isDeclared (old),
7757 fcnErrName (unew),
7758 alkind_unparse (newKind),
7759 uentry_specOrDefName (old)),
7760 uentry_whereDeclared (unew)))
7761 {
7762 uentry_showWhereSpecified (old);
7763 oldKind = AK_ERROR;
7764 }
7765
7766 sRef_setAliasKind (old->sref, newKind,
7767 uentry_whereDeclared (unew));
7768 }
7769 else /* newKind is temp or refcounted */
7770 {
7771 ;
7772 }
7773 }
7774 }
7775 }
7776 else /* newKind unknown */
7777 {
7778 ;
7779 }
7780}
7781
7782static void
7783 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7784 bool mustConform, bool completeConform)
7785{
7786 exkind newKind;
7787 exkind oldKind;
7788
7789 oldKind = sRef_getExKind (old->sref);
7790 newKind = sRef_getExKind (unew->sref);
7791
7792 if (exkind_isKnown (newKind))
7793 {
7794 if (oldKind != newKind)
7795 {
7796 if (exkind_isKnown (oldKind))
7797 {
7798 if (mustConform &&
7799 optgenerror
7800 (FLG_INCONDEFS,
7801 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7802 uentry_ekindName (unew),
7803 uentry_getName (unew),
7804 uentry_isDeclared (old),
7805 fcnErrName (unew),
7806 exkind_unparse (newKind),
7807 uentry_specOrDefName (old),
7808 exkind_unparse (oldKind)),
7809 uentry_whereDeclared (unew)))
7810 {
7811 uentry_showWhereSpecified (old);
7812 }
7813
7814 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7815 }
7816 else
7817 {
7818 if (mustConform &&
7819 optgenerror
7820 (FLG_INCONDEFS,
7821 message ("%s %q inconsistently %rdeclared %s %s, "
7822 "implicitly %s without exposure qualifier",
7823 uentry_ekindName (unew),
7824 uentry_getName (unew),
7825 uentry_isDeclared (old),
7826 fcnErrName (unew),
7827 exkind_unparse (newKind),
7828 uentry_specOrDefName (old)),
7829 uentry_whereDeclared (unew)))
7830 {
7831 uentry_showWhereSpecified (old);
7832 }
7833
7834 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7835 }
7836 }
7837 }
7838 else
7839 {
7840 if (completeConform && exkind_isKnown (oldKind)
7841 && uentry_isReallySpecified (old))
7842 {
7843 if (optgenerror
7844 (FLG_NEEDSPEC,
7845 message ("%s %q specified as %s, but declared without "
7846 "exposure qualifier",
7847 ekind_capName (unew->ukind),
7848 uentry_getName (unew),
7849 exkind_unparse (oldKind)),
7850 uentry_whereDeclared (unew)))
7851 {
7852 uentry_showWhereSpecified (old);
7853 }
7854 }
7855
7856 /* yes, this is necessary! (if its a param) */
7857 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7858 }
7859}
7860
28bf4b0b 7861static void
7862checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7863 bool mustConform, /*@unused@*/ bool completeConform)
7864{
7865 valueTable newvals = sRef_getValueTable (unew->sref);
7866
7867 if (valueTable_isDefined (newvals))
7868 {
7869 DPRINTF (("Check meta state: %s -> %s",
7870 uentry_unparseFull (old),
7871 uentry_unparseFull (unew)));
7872
7873 DPRINTF (("Check meta state refs: %s -> %s",
7874 sRef_unparseFull (old->sref),
7875 sRef_unparseFull (unew->sref)));
7876
7877 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7878
7879 /*
7880 ** Copy the new values into the old ref
7881 */
7882
7883 valueTable_elements (newvals, key, newval)
7884 {
7885 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7886 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7887
7888 llassert (metaStateInfo_isDefined (msinfo));
7889
7890 if (stateValue_isUndefined (oldval))
7891 {
7892 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7893 }
7894 else
7895 {
7896 if (stateValue_isError (oldval))
7897 {
7898 if (!stateValue_isError (newval))
7899 {
7900 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7901 }
7902 else
7903 {
7904 ; /* No change necessary. */
7905 }
7906 }
7907 else
7908 {
7909 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7910 {
7911 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7912 {
7913 ;
7914 }
7915 else
7916 {
ccf0a4a8 7917 if (!stateValue_isError (newval)
7918 && !stateValue_isImplicit (newval))
28bf4b0b 7919 {
ccf0a4a8 7920 if (uentry_hasName (unew)
7921 || !sRef_isParam (uentry_getSref (unew)))
7922 {
7923 if (mustConform
7924 && optgenerror
7925 (FLG_INCONDEFS,
7926 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7927 uentry_ekindName (unew),
7928 uentry_getName (unew),
7929 uentry_isDeclared (old),
7930 fcnErrName (unew),
7931 stateValue_unparseValue (newval, msinfo),
7932 uentry_specOrDefName (old),
7933 stateValue_unparseValue (oldval, msinfo)),
7934 uentry_whereDeclared (unew)))
7935 {
7936 uentry_showWhereSpecified (old);
7937 }
7938 }
7939 else
abb1cb43 7940 {
ccf0a4a8 7941 if (mustConform
7942 && optgenerror
7943 (FLG_INCONDEFS,
7944 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7945 uentry_ekindName (unew),
7946 sRef_getParam (uentry_getSref (unew)),
7947 uentry_isDeclared (old),
7948 fcnErrName (unew),
7949 stateValue_unparseValue (newval, msinfo),
7950 uentry_specOrDefName (old),
7951 stateValue_unparseValue (oldval, msinfo)),
7952 uentry_whereDeclared (unew)))
7953 {
7954 uentry_showWhereSpecified (old);
7955 }
abb1cb43 7956 }
28bf4b0b 7957 }
7958 }
7959
7960 DPRINTF (("Updating!"));
7961 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7962 }
7963 else
7964 {
7965 DPRINTF (("Values match"));
7966 }
7967 }
7968 }
7969 } end_valueTable_elements ;
7970 }
7971}
7972
616915dd 7973static void
7974uentry_checkStateConformance (/*@notnull@*/ uentry old,
7975 /*@notnull@*/ uentry unew,
7976 bool mustConform, bool completeConform)
7977{
7978 checkDefState (old, unew, mustConform, completeConform);
7979 checkNullState (old, unew, mustConform, completeConform);
7980 checkAliasState (old, unew, mustConform, completeConform);
7981 checkExpState (old, unew, mustConform, completeConform);
28bf4b0b 7982 checkMetaState (old, unew, mustConform, completeConform);
616915dd 7983
7984 sRef_storeState (old->sref);
7985 sRef_storeState (unew->sref);
7986}
7987
7988static void
7989checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7990{
7991 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7992 {
7993 return;
7994 }
7995
7996 llassert (uentry_isVar (old));
7997 llassert (uentry_isVar (unew));
7998
7999 if (cstring_isEmpty (old->uname))
8000 {
8001 cstring_free (old->uname);
8002 old->uname = cstring_copy (unew->uname);
8003 }
8004
8005 if (unew->info->var->kind == VKRETPARAM
8006 || unew->info->var->kind == VKSEFRETPARAM)
8007 {
8008 if (old->info->var->kind != VKRETPARAM
8009 && old->info->var->kind != VKSEFRETPARAM)
8010 {
8011 if (optgenerror
8012 (FLG_INCONDEFS,
8013 message ("Parameter %q inconsistently %rdeclared as "
8014 "returned parameter",
8015 uentry_getName (unew),
8016 uentry_isDeclared (old)),
8017 uentry_whereDeclared (unew)))
8018 {
8019 uentry_showWhereSpecified (old);
8020 old->info->var->kind = unew->info->var->kind;
8021 }
8022 }
8023 }
8024
8025
8026 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8027 {
8028 if (old->info->var->kind != VKSEFPARAM
8029 && old->info->var->kind != VKSEFRETPARAM)
8030 {
8031 if (optgenerror
8032 (FLG_INCONDEFS,
8033 message ("Parameter %qinconsistently %rdeclared as "
8034 "sef parameter",
8035 uentry_getOptName (unew),
8036 uentry_isDeclared (old)),
8037 uentry_whereDeclared (unew)))
8038 {
8039 uentry_showWhereSpecified (old);
8040 old->info->var->kind = unew->info->var->kind;
8041 }
8042 }
8043 }
8044
8045 if (old->info->var->kind == VKSPEC)
8046 {
8047 old->info->var->kind = unew->info->var->kind;
8048 }
8049 else
8050 {
8051 unew->info->var->kind = old->info->var->kind;
8052 }
8053
8054 if (unew->info->var->checked != CH_UNKNOWN
8055 && unew->info->var->checked != old->info->var->checked)
8056 {
8057 if (old->info->var->checked == CH_UNKNOWN
8058 && !fileloc_isUser (uentry_whereLast (old)))
8059 {
8060 ; /* no error */
8061 }
8062 else
8063 {
8064 if (optgenerror
8065 (FLG_INCONDEFS,
8066 message ("Variable %q inconsistently %rdeclared as "
8067 "%s parameter (was %s)",
8068 uentry_getName (unew),
8069 uentry_isDeclared (old),
8070 checkedName (unew->info->var->checked),
8071 checkedName (old->info->var->checked)),
8072 uentry_whereDeclared (unew)))
8073 {
8074 uentry_showWhereSpecified (old);
8075 }
8076 }
8077
8078 old->info->var->checked = unew->info->var->checked;
8079 }
8080 else
8081 {
8082 if (completeConform
8083 && (old->info->var->checked != CH_UNKNOWN)
8084 && uentry_isReallySpecified (old))
8085 {
8086 if (optgenerror
8087 (FLG_NEEDSPEC,
8088 message ("%s %q specified as %s, but declared without %s qualifier",
8089 ekind_capName (unew->ukind),
8090 uentry_getName (unew),
8091 checkedName (old->info->var->checked),
8092 checkedName (old->info->var->checked)),
8093 uentry_whereDeclared (unew)))
8094 {
8095 uentry_showWhereSpecified (old);
8096 }
8097 }
8098
8099 unew->info->var->checked = old->info->var->checked;
8100 }
8101
8102 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8103}
8104
8105void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8106{
8107 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8108 {
8109 return;
8110 }
8111
8112 llassert (uentry_isVar (u1));
8113 llassert (uentry_isVar (u2));
8114
8115 if (u1->info->var->kind != u2->info->var->kind) {
8116 if (u1->info->var->kind == VKSEFRETPARAM) {
8117 if (u2->info->var->kind == VKRETPARAM) {
8118 voptgenerror
8119 (FLG_TYPE,
8120 message ("Function types are inconsistent. Parameter %d is "
8121 "sef parameter, but non-sef parameter in "
8122 "assigned function: %s",
8123 paramno, exprNode_unparse (e)),
8124 exprNode_loc (e));
8125 } else if (u2->info->var->kind == VKSEFPARAM) {
8126 voptgenerror
8127 (FLG_TYPE,
8128 message ("Function types are inconsistent. Parameter %d is "
8129 "returns parameter, but non-returns parameter in "
8130 "assigned function: %s",
8131 paramno, exprNode_unparse (e)),
8132 exprNode_loc (e));
8133 } else {
8134 voptgenerror
8135 (FLG_TYPE,
8136 message ("Function types are inconsistent. Parameter %d is "
8137 "sef returns parameter, but non-sef returns parameter in "
8138 "assigned function: %s",
8139 paramno, exprNode_unparse (e)),
8140 exprNode_loc (e));
8141 }
8142 } else if (u1->info->var->kind == VKRETPARAM) {
8143 voptgenerror
8144 (FLG_TYPE,
8145 message ("Function types are inconsistent. Parameter %d is "
8146 "returns parameter, but non-returns parameter in "
8147 "assigned function: %s",
8148 paramno, exprNode_unparse (e)),
8149 exprNode_loc (e));
8150 } else if (u1->info->var->kind == VKSEFPARAM) {
8151 voptgenerror
8152 (FLG_TYPE,
8153 message ("Function types are inconsistent. Parameter %d is "
8154 "sef parameter, but non-sef parameter in "
8155 "assigned function: %s",
8156 paramno, exprNode_unparse (e)),
8157 exprNode_loc (e));
8158 } else {
8159 if (u2->info->var->kind == VKSEFRETPARAM) {
8160 voptgenerror
8161 (FLG_TYPE,
8162 message ("Function types are inconsistent. Parameter %d is "
8163 "normal parameter, but sef returns parameter in "
8164 "assigned function: %s",
8165 paramno, exprNode_unparse (e)),
8166 exprNode_loc (e));
8167 } else if (u2->info->var->kind == VKSEFPARAM) {
8168 voptgenerror
8169 (FLG_TYPE,
8170 message ("Function types are inconsistent. Parameter %d is "
8171 "normal parameter, but sef parameter in "
8172 "assigned function: %s",
8173 paramno, exprNode_unparse (e)),
8174 exprNode_loc (e));
8175 } else if (u2->info->var->kind == VKRETPARAM) {
8176 voptgenerror
8177 (FLG_TYPE,
8178 message ("Function types are inconsistent. Parameter %d is "
8179 "normal parameter, but returns parameter in "
8180 "assigned function: %s",
8181 paramno, exprNode_unparse (e)),
8182 exprNode_loc (e));
8183 } else {
8184 BADBRANCH;
8185 }
8186 }
8187 }
8188
8189 if (u1->info->var->defstate != u2->info->var->defstate)
8190 {
8191 voptgenerror
8192 (FLG_TYPE,
8193 message ("Function types are inconsistent. Parameter %d is "
8194 "%s, but %s in assigned function: %s",
8195 paramno,
8196 sstate_unparse (u1->info->var->defstate),
8197 sstate_unparse (u2->info->var->defstate),
8198 exprNode_unparse (e)),
8199 exprNode_loc (e));
8200 }
8201
8202 if (u1->info->var->nullstate != u2->info->var->nullstate)
8203 {
8204 voptgenerror
8205 (FLG_TYPE,
8206 message ("Function types are inconsistent. Parameter %d is "
8207 "%s, but %s in assigned function: %s",
8208 paramno,
8209 nstate_unparse (u1->info->var->nullstate),
8210 nstate_unparse (u2->info->var->nullstate),
8211 exprNode_unparse (e)),
8212 exprNode_loc (e));
8213 }
8214
8215 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8216 {
8217 voptgenerror
8218 (FLG_TYPE,
8219 message ("Function types are inconsistent. Parameter %d is "
8220 "%s, but %s in assigned function: %s",
8221 paramno,
8222 alkind_unparse (sRef_getAliasKind (u1->sref)),
8223 alkind_unparse (sRef_getAliasKind (u2->sref)),
8224 exprNode_unparse (e)),
8225 exprNode_loc (e));
8226 }
8227
8228 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8229 {
8230 voptgenerror
8231 (FLG_TYPE,
8232 message ("Function types are inconsistent. Parameter %d is "
8233 "%s, but %s in assigned function: %s",
8234 paramno,
8235 exkind_unparse (sRef_getExKind (u1->sref)),
8236 exkind_unparse (sRef_getExKind (u2->sref)),
8237 exprNode_unparse (e)),
8238 exprNode_loc (e));
8239 }
8240}
8241
8242static void
8243checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8244 /*@notnull@*/ uentry unew,
8245 bool mustConform, /*@unused@*/ bool completeConform)
8246{
8247 uentryList oldParams = uentry_getParams (old);
8248 uentryList newParams = uentry_getParams (unew);
8249 ctype newType = unew->utype;
ac35a6ab 8250 ctype oldType = ctype_realType (old->utype);
616915dd 8251 ctype oldRetType = ctype_unknown;
8252 ctype newRetType = ctype_unknown;
8253
28bf4b0b 8254 DPRINTF (("Function conform: %s ==> %s",
8255 uentry_unparseFull (old),
8256 uentry_unparseFull (unew)));
8257
616915dd 8258 if (uentry_isForward (old))
8259 {
8260 mustConform = FALSE;
efd360a3 8261 uentry_updateInto (old, unew);
616915dd 8262 return;
8263 }
8264
8265 /*
8266 ** check return values
8267 */
8268
8269 if (ctype_isKnown (oldType))
8270 {
8271 llassert (ctype_isFunction (oldType));
28bf4b0b 8272 oldRetType = ctype_getReturnType (oldType);
616915dd 8273 }
8274
8275 if (ctype_isKnown (newType))
8276 {
8277 llassert (ctype_isFunction (newType));
28bf4b0b 8278 newRetType = ctype_getReturnType (newType);
616915dd 8279 }
8280
8281 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8282 && !ctype_matchDef (newRetType, oldRetType))
8283 {
8284 if (mustConform) returnValueError (old, unew);
8285 }
8286 else
8287 {
8288 if (ctype_isConj (newRetType))
8289 {
8290 if (ctype_isConj (oldRetType))
8291 {
8292 if (!ctype_sameAltTypes (newRetType, oldRetType))
8293 {
8294 if (optgenerror
8295 (FLG_INCONDEFS,
8296 message ("Function %q inconsistently %rdeclared to "
8297 "return alternate types %s "
8298 "(types match, but alternates are not identical, "
8299 "so checking may not be correct)",
8300 uentry_getName (unew),
8301 uentry_isDeclared (old),
8302 ctype_unparse (newRetType)),
8303 uentry_whereDeclared (unew)))
8304 {
8305 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8306 }
8307 }
8308 }
8309 else
8310 {
8311 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8312 }
8313 }
8314 }
8315
28bf4b0b 8316 DPRINTF (("Before state: %s",
8317 uentry_unparseFull (old)));
616915dd 8318 uentry_checkStateConformance (old, unew, mustConform, completeConform);
28bf4b0b 8319 DPRINTF (("After state: %s",
8320 uentry_unparseFull (old)));
616915dd 8321
8322 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8323 {
8324 if (exitkind_isKnown (unew->info->fcn->exitCode))
8325 {
8326 if (optgenerror
8327 (FLG_INCONDEFS,
8328 message ("Function %q inconsistently %rdeclared using %s",
8329 uentry_getName (unew),
8330 uentry_isDeclared (old),
8331 exitkind_unparse (unew->info->fcn->exitCode)),
8332 uentry_whereDeclared (unew)))
8333 {
8334 uentry_showWhereSpecified (old);
8335 }
8336 }
8337 else
8338 {
8339 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8340 }
8341 }
8342
8343 if (!qual_isUnknown (unew->info->fcn->nullPred))
8344 {
28bf4b0b 8345 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
616915dd 8346 {
8347 if (optgenerror
8348 (FLG_INCONDEFS,
8349 message ("Function %q inconsistently %rdeclared using %s",
8350 uentry_getName (unew),
8351 uentry_isDeclared (old),
8352 qual_unparse (unew->info->fcn->nullPred)),
8353 uentry_whereDeclared (unew)))
8354 {
8355 uentry_showWhereSpecified (old);
8356 }
8357 }
8358 }
8359 else
8360 {
8361 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8362 }
8363
8364 if (unew->info->fcn->specialCode != SPC_NONE)
8365 {
8366 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8367 {
8368 if (optgenerror
8369 (FLG_INCONDEFS,
8370 message ("Function %q inconsistently %rdeclared using %s",
8371 uentry_getName (unew),
8372 uentry_isDeclared (old),
8373 specCode_unparse (unew->info->fcn->specialCode)),
8374 uentry_whereDeclared (unew)))
8375 {
8376 uentry_showWhereSpecified (old);
8377 }
8378 }
8379 }
8380 else
8381 {
8382 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8383 }
8384
8385 /*
8386 ** check parameters
8387 */
8388
8389 if (!uentryList_sameObject (oldParams, newParams)
8390 && (!uentryList_isMissingParams (oldParams)))
8391 {
8392 if (!uentryList_isMissingParams (newParams))
8393 {
8394 int paramno = 0;
8395 int nparams = uentryList_size (oldParams);
8396 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8397
8398 if (nparams != uentryList_size (newParams))
8399 {
8400 nargsError (old, unew);
8401 }
8402
8403 if (uentryList_size (newParams) < nparams)
8404 {
8405 nparams = uentryList_size (newParams);
8406 }
8407
8408 while (paramno < nparams)
8409 {
8410 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8411 uentry newCurrent = uentryList_getN (newParams, paramno);
8412 ctype oldCurrentType = uentry_getType (oldCurrent);
8413 ctype newCurrentType = uentry_getType (newCurrent);
8414
8415 llassert (uentry_isValid (oldCurrent)
8416 && uentry_isValid (newCurrent));
8417
8418 if (!uentry_isElipsisMarker (oldCurrent)
8419 && !uentry_isElipsisMarker (newCurrent))
8420 {
8421 checkVarConformance (oldCurrent, newCurrent,
8422 mustConform, completeConform);
8423 }
8424
8425 if (checknames)
8426 {
8427 if (uentry_hasName (oldCurrent)
8428 && uentry_hasName (newCurrent))
8429 {
8430 cstring oldname = uentry_getName (oldCurrent);
8431 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8432 cstring oname;
8433 cstring nname = uentry_getName (newCurrent);
8434 cstring nnamefix;
8435
8436 if (cstring_isDefined (pfx)
68de3f33 8437 && cstring_equalPrefix (oldname, pfx))
616915dd 8438 {
8439 oname = cstring_suffix (oldname, cstring_length (pfx));
8440 }
8441 else
8442 {
8443 oname = oldname;
8444 /*@-branchstate@*/ } /*@=branchstate@*/
8445
8446 if (cstring_isDefined (pfx)
68de3f33 8447 && cstring_equalPrefix (nname, pfx))
616915dd 8448 {
8449 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8450 }
8451 else
8452 {
8453 nnamefix = nname;
8454 /*@-branchstate@*/ } /*@=branchstate@*/
8455
8456 if (!cstring_equal (oname, nnamefix))
8457 {
8458 if (optgenerror
8459 (FLG_DECLPARAMMATCH,
8460 message ("Definition parameter name %s does not match "
8461 "name of corresponding parameter in "
8462 "declaration: %s",
8463 nnamefix, oname),
8464 uentry_whereLast (newCurrent)))
8465 {
8466 uentry_showWhereLastPlain (oldCurrent);
8467 }
8468 }
8469
8470 cstring_free (oldname);
8471 cstring_free (nname);
8472 }
8473 }
8474
8475 if (!ctype_match (oldCurrentType, newCurrentType))
8476 {
8477 paramTypeError (old, oldCurrent, oldCurrentType,
8478 unew, newCurrent, newCurrentType, paramno);
8479 }
8480 else
8481 {
8482 if (ctype_isMissingParamsMarker (newCurrentType)
8483 || ctype_isElips (newCurrentType)
8484 || ctype_isMissingParamsMarker (oldCurrentType)
8485 || ctype_isElips (oldCurrentType))
8486 {
8487 ;
8488 }
8489 else
8490 {
8491 if (ctype_isConj (newCurrentType))
8492 {
8493 if (ctype_isConj (oldCurrentType))
8494 {
8495 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8496 {
8497 if (optgenerror
8498 (FLG_INCONDEFS,
8499 message ("Parameter %q inconsistently %rdeclared with "
8500 "alternate types %s "
8501 "(types match, but alternates are not identical, "
8502 "so checking may not be correct)",
8503 uentry_getName (newCurrent),
8504 uentry_isDeclared (oldCurrent),
8505 ctype_unparse (newCurrentType)),
8506 uentry_whereDeclared (unew)))
8507 {
8508 uentry_showWhereLastVal (oldCurrent,
8509 ctype_unparse (oldCurrentType));
8510 }
8511 }
8512 }
8513 else
8514 {
8515 if (optgenerror
8516 (FLG_INCONDEFS,
8517 message ("Parameter %q inconsistently %rdeclared with "
8518 "alternate types %s",
8519 uentry_getName (newCurrent),
8520 uentry_isDeclared (oldCurrent),
8521 ctype_unparse (newCurrentType)),
8522 uentry_whereDeclared (unew)))
8523 {
8524 uentry_showWhereLastVal (oldCurrent,
8525 ctype_unparse (oldCurrentType));
8526
8527 }
8528 }
8529 }
8530 else
8531 {
8532 if (ctype_isConj (oldCurrentType))
8533 {
8534 uentry_setType (newCurrent, oldCurrentType);
8535 }
8536 }
8537 }
8538 }
8539
8540 paramno++;
8541 /*
1b8ae690 8542 ** Forgot this! detected by splint:
616915dd 8543 ** uentry.c:1257,15: Suspected infinite loop
8544 */
8545 }
8546 }
8547 }
8548
8549 if (!uentryList_isMissingParams (newParams))
8550 {
8551 if (ctype_isConj (oldRetType))
8552 {
8553 old->utype = ctype_makeFunction (oldRetType,
8554 uentryList_copy (newParams));
8555 }
8556 else
8557 {
8558 old->utype = unew->utype;
8559 }
8560 }
8561
8562 checkGlobalsConformance (old, unew, mustConform, completeConform);
8563 checkModifiesConformance (old, unew, mustConform, completeConform);
8564
28bf4b0b 8565 DPRINTF (("Before list: %s",
8566 uentry_unparseFull (old)));
8567
8568 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
616915dd 8569 {
28bf4b0b 8570 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
616915dd 8571 {
28bf4b0b 8572 /*
616915dd 8573 if (optgenerror
8574 (FLG_INCONDEFS,
8575 message ("Function %q redeclared using special clauses (can only "
8576 "be used in first declaration)",
8577 uentry_getName (unew)),
8578 uentry_whereDeclared (unew)))
8579 {
8580 uentry_showWhereLast (old);
8581 }
28bf4b0b 8582 */
8583
8584 /*@i23 need checking @*/
8585
8586 old->info->fcn->specclauses = unew->info->fcn->specclauses;
616915dd 8587 }
8588 else
8589 {
28bf4b0b 8590 /*@i43 should be able to append? @*/
8591
8592 stateClauseList_checkEqual (old, unew);
8593 stateClauseList_free (unew->info->fcn->specclauses);
8594 unew->info->fcn->specclauses = stateClauseList_undefined;
8595 /*@-branchstate@*/
616915dd 8596 }
8597 }
146e25eb 8598 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
616915dd 8599
8600 if (fileloc_isUndefined (old->whereDeclared))
8601 {
8602 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8603 }
8604 else if (fileloc_isUndefined (unew->whereDeclared))
8605 {
8606 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8607 }
8608 else
8609 {
8610 /* no change */
8611 }
146e25eb 8612/*@i523 @*/ }
616915dd 8613
8614void
8615uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8616{
8617 multiVal uval;
8618
8619 llassert (uentry_isValid (ue));
8620 llassert (uentry_isEitherConstant (ue));
8621
b9904f57 8622 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8623 uval = uentry_getConstantValue (ue);
616915dd 8624
8625 if (multiVal_isDefined (uval))
8626 {
8627 if (multiVal_isDefined (m))
8628 {
8629 if (!multiVal_equiv (uval, m))
8630 {
8631 if (optgenerror
8632 (FLG_INCONDEFS,
8633 message ("%s %q defined with inconsistent value: %q",
8634 ekind_capName (ue->ukind),
8635 uentry_getName (ue),
8636 multiVal_unparse (m)),
8637 g_currentloc))
8638 {
8639 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8640 }
8641 }
8642 }
8643 multiVal_free (m);
8644 }
8645 else
8646 {
b9904f57 8647 uentry_setConstantValue (ue, m);
616915dd 8648 }
8649}
8650
8651static
8652bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8653 bool mustConform)
8654{
8655 bool typeError = FALSE;
8656
8657 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8658 {
8659 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8660 {
8661 if (mustConform)
8662 {
28bf4b0b 8663 DPRINTF (("Check struct conformance: %s / %s",
8664 uentry_unparseFull (old),
8665 uentry_unparseFull (unew)));
616915dd 8666 checkStructConformance (old, unew);
8667 }
8668 }
8669 else
8670 {
8671 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8672 {
8673 llbug (message ("struct tags: bad types: %t / %t",
8674 old->utype, unew->utype));
8675 }
8676 }
8677 }
8678 else if (uentry_isEnumTag (old))
8679 {
8680 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8681 {
8682 if (mustConform) checkEnumConformance (old, unew);
8683 }
8684 else
8685 {
8686 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8687 {
8688 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8689 ctype_unparse (unew->utype)));
8690 }
8691 }
8692 }
8693 else if (!ctype_match (old->utype, unew->utype))
8694 {
28bf4b0b 8695 DPRINTF (("Type mismatch: %s / %s",
8696 ctype_unparse (old->utype),
8697 ctype_unparse (unew->utype)));
8698
616915dd 8699 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8700 {
8701 ctype realt = ctype_realType (unew->utype);
8702
8703 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8704 {
8705 unew->utype = ctype_bool;
8706 }
8707 else
8708 {
8709 if (mustConform)
8710 {
8711 typeError = optgenerror
8712 (FLG_INCONDEFS,
8713 message ("%q defined as %s", uentry_getName (old),
8714 ctype_unparse (realt)),
8715 uentry_whereDeclared (unew));
8716 }
8717 }
8718 }
8719 else
8720 {
8721 if (mustConform)
8722 {
8723 ctype oldr = ctype_realType (old->utype);
8724 ctype newr = ctype_realType (unew->utype);
8725
8726 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8727 {
8728 checkStructConformance (old, unew);
8729 }
8730 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8731 {
8732 checkStructConformance (old, unew);
8733 }
8734 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8735 {
8736 checkEnumConformance (old, unew);
8737 }
8738 else if (uentry_isConstant (old)
8739 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8740 {
8741 /* okay...for now! (should check the type is reset later... */
8742 }
8743 else
8744 {
8745 DPRINTF (("YABA!"));
8746 if (optgenerror
8747 (FLG_INCONDEFS,
8748 message ("%s %q %rdeclared with inconsistent type: %t",
8749 ekind_capName (unew->ukind),
8750 uentry_getName (unew),
8751 uentry_isDeclared (old),
8752 unew->utype),
8753 uentry_whereDeclared (unew)))
8754 {
8755 uentry_showWhereLast (old);
8756 typeError = TRUE;
8757 }
8758 }
8759 }
8760 }
8761 }
8762 else
8763 {
8764 /* no error */
8765 }
8766
8767 return typeError;
8768}
8769
8770static void
8771uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8772 /*@notnull@*/ uentry unew,
8773 bool mustConform, bool completeConform)
8774{
8775 if (ctype_isDefined (unew->info->datatype->type))
8776 {
8777 /*
8778 ** bool is hard coded here, since it is built into LCL.
8779 ** For now, we're stuck with LCL's types.
8780 */
8781
8782 if (ctype_isDirectBool (old->utype) &&
8783 cstring_equalLit (unew->uname, "bool"))
8784 {
8785 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8786 evs 2000-07-25: removed
8787 */
8788 unew->utype = ctype_bool;
8789 }
8790
8791 if (ctype_isUnknown (old->info->datatype->type))
8792 {
8793 old->info->datatype->type = unew->info->datatype->type;
8794 }
8795 else
8796 {
8797 DPRINTF (("Old: %s / New: %s",
8798 uentry_unparseFull (old),
8799 uentry_unparseFull (unew)));
8800 DPRINTF (("Types: %s / %s",
8801 ctype_unparse (old->info->datatype->type),
8802 ctype_unparse (unew->info->datatype->type)));
8803
8804 if (ctype_matchDef (old->info->datatype->type,
8805 unew->info->datatype->type))
8806 {
8807 ;
8808 }
8809 else
8810 {
8811 if (optgenerror
8812 (FLG_INCONDEFS,
8813 message
8814 ("Type %q %s with inconsistent type: %t",
8815 uentry_getName (unew),
8816 uentry_reDefDecl (old, unew),
8817 unew->info->datatype->type),
8818 uentry_whereDeclared (unew)))
8819 {
8820 uentry_showWhereLastExtra
8821 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8822 }
8823
8824 old->info->datatype->type = unew->info->datatype->type;
8825 }
8826 }
8827 }
8828
8829 if (unew->info->datatype->abs != MAYBE)
8830 {
8831 if (ynm_isOff (old->info->datatype->abs)
8832 && ynm_isOn (unew->info->datatype->abs))
8833 {
8834 if (!ctype_isDirectBool (old->utype))
8835 {
8836 if (optgenerror
8837 (FLG_INCONDEFS,
8838 message
8839 ("Datatype %q inconsistently %rdeclared as abstract type",
8840 uentry_getName (unew),
8841 uentry_isDeclared (old)),
8842 uentry_whereDeclared (unew)))
8843 {
8844 uentry_showWhereLastPlain (old);
8845 }
8846 }
8847 }
8848 else if (ynm_isOn (old->info->datatype->abs)
8849 && ynm_isOff (unew->info->datatype->abs))
8850 {
8851 if (!ctype_isDirectBool (old->utype))
8852 {
8853 if (optgenerror
8854 (FLG_INCONDEFS,
8855 message
8856 ("Datatype %q inconsistently %rdeclared as concrete type",
8857 uentry_getName (unew),
8858 uentry_isDeclared (old)),
8859 uentry_whereDeclared (unew)))
8860 {
8861 uentry_showWhereLastPlain (old);
8862 }
8863 }
8864 }
8865 else
8866 {
8867 ;
8868 }
8869 }
8870 else
8871 {
8872 if (ynm_isOn (old->info->datatype->abs))
8873 {
8874 old->sref = unew->sref;
8875 unew->info->datatype->mut = old->info->datatype->mut;
8876
8877 if (completeConform
8878 && uentry_isReallySpecified (old))
8879 {
8880 if (optgenerror
8881 (FLG_NEEDSPEC,
8882 message
8883 ("Datatype %q specified as abstract, "
8884 "but abstract annotation not used in declaration",
8885 uentry_getName (unew)),
8886 uentry_whereDeclared (unew)))
8887 {
8888 uentry_showWhereLastPlain (old);
8889 }
8890 }
8891 }
8892 }
8893
8894 unew->info->datatype->abs = old->info->datatype->abs;
8895
8896 if (ynm_isMaybe (unew->info->datatype->mut))
8897 {
8898 if (completeConform && ynm_isOff (old->info->datatype->mut)
8899 && uentry_isReallySpecified (old))
8900 {
8901 if (optgenerror
8902 (FLG_NEEDSPEC,
8903 message
8904 ("Datatype %q specified as immutable, "
8905 "but immutable annotation not used in declaration",
8906 uentry_getName (unew)),
8907 uentry_whereDeclared (unew)))
8908 {
8909 uentry_showWhereLastPlain (old);
8910 }
8911 }
8912
8913 unew->info->datatype->mut = old->info->datatype->mut;
8914 }
8915 else if (ynm_isMaybe (old->info->datatype->mut))
8916 {
8917 old->info->datatype->mut = unew->info->datatype->mut;
8918 }
8919 else
8920 {
8921 if (ynm_isOn (old->info->datatype->abs))
8922 {
8923 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8924 {
8925 if (optgenerror
8926 (FLG_INCONDEFS,
8927 message ("Datatype %q inconsistently %rdeclared as immutable",
8928 uentry_getName (unew),
8929 uentry_isDeclared (old)),
8930 uentry_whereDeclared (unew)))
8931 {
8932 uentry_showWhereLastPlain (old);
8933 }
8934 }
8935 else
8936 {
8937 if (ynm_isOff (old->info->datatype->mut)
8938 && ynm_isOn (unew->info->datatype->mut))
8939 {
8940 if (optgenerror
8941 (FLG_INCONDEFS,
8942 message ("Datatype %q inconsistently %rdeclared as mutable",
8943 uentry_getName (unew),
8944 uentry_isDeclared (old)),
8945 uentry_whereDeclared (unew)))
8946 {
8947 uentry_showWhereLastPlain (old);
8948 }
8949 }
8950 }
8951 }
8952 old->info->datatype->mut = unew->info->datatype->mut;
8953 }
8954
8955 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8956}
8957
8958static void
8959uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8960 /*@notnull@*/ uentry unew,
8961 bool mustConform,
8962 /*@unused@*/ bool completeConform)
8963{
b9904f57 8964 multiVal oldval = uentry_getConstantValue (old);
8965 multiVal newval = uentry_getConstantValue (unew);
616915dd 8966
b9904f57 8967 if (multiVal_isDefined (oldval))
616915dd 8968 {
b9904f57 8969 if (multiVal_isDefined (newval))
616915dd 8970 {
b9904f57 8971 if (!multiVal_equiv (oldval, newval))
616915dd 8972 {
8973 if (mustConform
8974 && optgenerror
8975 (FLG_INCONDEFS,
8976 message ("%s %q %rdeclared with inconsistent value: %q",
8977 ekind_capName (unew->ukind),
8978 uentry_getName (unew),
8979 uentry_isDeclared (old),
b9904f57 8980 multiVal_unparse (newval)),
616915dd 8981 uentry_whereDeclared (unew)))
8982 {
b9904f57 8983 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
616915dd 8984 }
8985 }
8986
b9904f57 8987 uentry_setConstantValue (unew, multiVal_copy (oldval));
616915dd 8988 }
8989 else
8990 {
8991 ;
8992 }
8993 }
8994 else
8995 {
b9904f57 8996 uentry_setConstantValue (old, multiVal_copy (newval));
616915dd 8997 }
8998}
8999
9000static void
9001uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9002 /*@notnull@*/ uentry unew, bool mustConform,
9003 bool completeConform)
9004{
9005 bool typeError = FALSE;
9006 bool fcnConformance = FALSE;
9007
9008 if (!ekind_equal (unew->ukind, old->ukind))
9009 {
9010 /*
9011 ** okay, only if one is a function and the other is
9012 ** a variable of type function.
9013 */
9014
9015 if (unew->ukind == KENUMCONST
9016 && old->ukind == KCONST)
9017 {
9018 old->ukind = KENUMCONST;
9019 goto nokinderror;
9020 }
9021
9022 if (unew->ukind == KFCN
9023 && old->ukind == KCONST
9024 && ctype_isUnknown (old->utype))
9025 {
9026 /*
9027 ** When a function is defined with an unparam macro
9028 */
9029
efd360a3 9030 uentry_updateInto (old, unew);
616915dd 9031 return;
9032 }
9033
9034 if (uentry_isExpandedMacro (old)
9035 && uentry_isEitherConstant (unew))
9036 {
efd360a3 9037 uentry_updateInto (old, unew);
616915dd 9038 return;
9039 }
9040
9041 if (uentry_isEndIter (unew))
9042 {
9043 if (ctype_isUnknown (old->utype))
9044 {
9045 if (!uentry_isSpecified (old)
9046 && uentry_isCodeDefined (unew))
9047 {
9048 if (!fileloc_withinLines (uentry_whereDefined (old),
9049 uentry_whereDeclared (unew), 2))
9050 { /* bogus! will give errors if there is too much whitespace */
9051 voptgenerror
9052 (FLG_SYNTAX,
9053 message
9054 ("Iterator finalized name %q does not match name in "
9055 "previous iter declaration (should be end_%q). This iter "
9056 "is declared at %q",
9057 uentry_getName (unew),
9058 uentry_getName (old),
9059 fileloc_unparse (uentry_whereDefined (old))),
9060 uentry_whereDeclared (old));
9061 }
9062 }
9063
efd360a3 9064 uentry_updateInto (old, unew);
616915dd 9065 return;
9066 }
9067 else
9068 {
9069 KindConformanceError (old, unew, mustConform);
9070 }
9071 }
9072
9073 if (uentry_isFunction (unew))
9074 {
9075 if (uentry_isVariable (old))
9076 {
9077 if (!ctype_isUnknown (old->utype))
9078 {
9079 if (ctype_isFunction (old->utype))
9080 {
9081 uentry_makeVarFunction (old);
9082 checkFunctionConformance (old, unew, mustConform,
9083 completeConform);
9084 fcnConformance = TRUE;
9085 }
9086 else
9087 {
9088 KindConformanceError (old, unew, mustConform);
9089 }
9090 }
9091 else
9092 {
9093 if (uentry_isExpandedMacro (old))
9094 {
9095 if (fileloc_isUndefined (unew->whereDefined))
9096 {
9097 unew->whereDefined = fileloc_update (unew->whereDefined,
9098 old->whereDefined);
9099 }
9100
efd360a3 9101 uentry_updateInto (old, unew);
616915dd 9102 old->used = unew->used = TRUE;
9103 return;
9104 }
9105 else
9106 {
9107 /* undeclared identifier */
9108 old->utype = unew->utype;
9109 uentry_makeVarFunction (old);
9110 checkFunctionConformance (old, unew, FALSE, FALSE);
9111 fcnConformance = TRUE;
9112 }
9113 }
9114 }
9115 else
9116 {
9117 KindConformanceError (old, unew, mustConform);
9118 }
9119 }
9120 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9121 {
9122 if (!ctype_isUnknown (unew->utype))
9123 {
9124 if (ctype_isFunction (unew->utype))
9125 {
9126 uentry_makeVarFunction (unew);
9127 checkFunctionConformance (old, unew, mustConform, completeConform);
9128 fcnConformance = TRUE;
9129 }
9130 else
9131 {
9132 KindConformanceError (old, unew, mustConform);
9133 }
9134 }
9135 else
9136 {
9137 KindConformanceError (old, unew, mustConform);
9138 }
9139 }
9140 else
9141 {
9142 KindConformanceError (old, unew, mustConform);
9143 }
9144 }
9145 else
9146 {
9147 /*
9148 ** check parameter lists for functions
9149 ** (before type errors, to get better messages
9150 */
9151
9152 if (uentry_isFunction (old))
9153 {
9154 checkFunctionConformance (old, unew, mustConform, completeConform);
9155 fcnConformance = TRUE;
9156 }
9157 else
9158 {
9159 if (!ctype_isUndefined (old->utype))
9160 {
9161 typeError = checkTypeConformance (old, unew, mustConform);
9162 }
9163 }
9164 }
9165
9166 nokinderror:
9167
9168 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9169 {
9170 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9171 }
9172
9173 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9174 {
9175 DPRINTF (("Check datatype: %s / %s",
9176 uentry_unparseFull (old),
9177 uentry_unparseFull (unew)));
9178
9179 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9180 }
9181
9182 if (uentry_isVariable (old) && uentry_isVariable (unew))
9183 {
9184 if (!typeError &&
9185 !ctype_matchDef (old->utype, unew->utype))
9186 {
9187 if (optgenerror
9188 (FLG_INCONDEFS,
9189 message
9190 ("Variable %q %s with inconsistent type (arrays and pointers are "
9191 "not identical in variable declarations): %t",
9192 uentry_getName (unew),
9193 uentry_reDefDecl (old, unew),
9194 unew->utype),
9195 uentry_whereDeclared (unew)))
9196 {
9197 uentry_showWhereLast (old);
9198
9199 /*
9200 ** Avoid repeated errors.
9201 */
9202
9203 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9204 {
9205 old->whereDefined = fileloc_update (old->whereDefined,
9206 fileloc_undefined);
9207 }
9208
9209 typeError = TRUE;
9210 }
9211 }
9212
9213 checkVarConformance (old, unew, mustConform, completeConform);
9214 }
9215
9216 if (fcnConformance)
9217 {
9218 /* old->utype = unew->utype; */
9219 }
9220 else
9221 {
9222 if (ctype_isConj (old->utype))
9223 {
9224 if (ctype_isConj (unew->utype))
9225 {
9226 if (!ctype_sameAltTypes (old->utype, unew->utype))
9227 {
9228 if (optgenerror
9229 (FLG_INCONDEFS,
9230 message ("%s %q inconsistently %rdeclared with "
9231 "alternate types %s "
9232 "(types match, but alternates are not identical, "
9233 "so checking may not be correct)",
9234 ekind_capName (uentry_getKind (old)),
9235 uentry_getName (unew),
9236 uentry_isDeclared (old),
9237 ctype_unparse (unew->utype)),
9238 uentry_whereDeclared (unew)))
9239 {
9240 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9241 }
9242 else
9243 {
9244 old->utype = unew->utype;
9245 }
9246 }
9247 }
9248 }
9249 else
9250 {
9251 if (ctype_isUnknown (old->utype))
9252 {
9253 old->utype = unew->utype;
9254 }
9255 }
9256 }
9257
9258 if (unew->ukind == old->ukind)
9259 {
9260 sfree (unew->info);
9261 unew->info = uinfo_copy (old->info, old->ukind);
9262 }
9263
9264 sRef_storeState (old->sref);
9265 sRef_storeState (unew->sref);
9266}
9267
ba45e1e4 9268static void uentry_mergeConstraints (uentry spec, uentry def)
9269{
9270 if (uentry_isFunction (def))
9271 {
9272 DPRINTF (("Here: %s / %s",
9273 uentry_unparseFull (spec),
9274 uentry_unparseFull (def)));
efd360a3 9275 /* evans 2001-07-21 */
9276 llassert (uentry_isFunction (spec));
ba45e1e4 9277
9278 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9279 {
9280 if (fileloc_isXHFile (uentry_whereLast (def)))
9281 {
9282 llassert (uentry_isFunction (spec));
9283 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9284 def->info->fcn->preconditions);
ba45e1e4 9285 }
ccf0a4a8 9286 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9287 {
9288 ;
9289 }
ba45e1e4 9290 else
9291 {
ccf0a4a8 9292 /* Check if the constraints are identical */
9293
3120b462 9294 if (optgenerror
9295 (FLG_INCONDEFS,
9296 message
9297 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9298 uentry_getName (spec),
9299 functionConstraint_unparse (spec->info->fcn->preconditions)),
9300 uentry_whereLast (def)))
9301 {
9302 uentry_showWhereSpecified (spec);
9303 }
9304
9305 functionConstraint_free (spec->info->fcn->preconditions);
9306 spec->info->fcn->preconditions = def->info->fcn->preconditions;
ba45e1e4 9307 }
3120b462 9308
9309 def->info->fcn->preconditions = functionConstraint_undefined;
ba45e1e4 9310 }
9311
ba45e1e4 9312 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9313 {
9314 if (fileloc_isXHFile (uentry_whereLast (def)))
9315 {
9316 llassert (uentry_isFunction (spec));
9317 DPRINTF (("Post: %s /++/ %s",
9318 functionConstraint_unparse (spec->info->fcn->postconditions),
9319 functionConstraint_unparse (def->info->fcn->postconditions)));
9320 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9321 def->info->fcn->postconditions);
9322 def->info->fcn->postconditions = functionConstraint_undefined;
9323 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9324 }
9325 else
9326 {
3120b462 9327 if (optgenerror
9328 (FLG_INCONDEFS,
9329 message
9330 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9331 uentry_getName (spec),
9332 functionConstraint_unparse (spec->info->fcn->postconditions)),
9333 uentry_whereLast (def)))
9334 {
9335 uentry_showWhereSpecified (spec);
9336 }
9337
9338 functionConstraint_free (spec->info->fcn->postconditions);
9339 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9340 def->info->fcn->postconditions = functionConstraint_undefined;
ba45e1e4 9341 }
9342 }
9343 }
9344}
9345
616915dd 9346/*
9347** modifies spec to reflect def, reports any inconsistencies
9348*/
9349
9350void
9351uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9352{
9353 llassert (uentry_isValid (spec));
9354 llassert (uentry_isValid (def));
9355 llassert (cstring_equal (spec->uname, def->uname));
efd360a3 9356
9357 if (uentry_isFunction (def))
9358 {
9359 if (uentry_isConstant (spec))
9360 {
9361 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9362 uentry_makeConstantFunction (spec);
9363 }
9364 else
9365 {
9366 uentry_convertVarFunction (spec);
9367 }
9368
9369 llassert (uentry_isFunction (spec));
9370 }
28bf4b0b 9371
9372 DPRINTF (("Merge entries: %s / %s",
9373 uentry_unparseFull (spec),
9374 uentry_unparseFull (def)));
616915dd 9375
ba45e1e4 9376 uentry_mergeConstraints (spec, def);
9377
616915dd 9378 uentry_checkConformance (spec, def, TRUE,
9379 context_getFlag (FLG_NEEDSPEC));
9380
28bf4b0b 9381 DPRINTF (("Merge entries after conform: %s / %s",
9382 uentry_unparseFull (spec),
9383 uentry_unparseFull (def)));
9384
616915dd 9385 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9386
9387 /*
9388 ** okay, declarations conform. Propagate extra information.
9389 */
9390
9391 uentry_setDefined (spec, uentry_whereDefined (def));
9392 uentry_setDeclared (spec, uentry_whereDeclared (def));
9393
9394 if (uentry_isStatic (def))
9395 {
9396 if (optgenerror
9397 (FLG_INCONDEFS,
9398 message ("%s %q specified, but declared as static",
9399 ekind_capName (def->ukind),
9400 uentry_getName (def)),
9401 uentry_whereDeclared (def)))
9402 {
9403 uentry_showWhereSpecified (spec);
9404 }
9405 }
9406 else
9407 {
9408 spec->storageclass = def->storageclass;
9409 }
9410
9411 sRef_storeState (spec->sref);
9412
9413 spec->used = def->used || spec->used;
9414 spec->hasNameError |= def->hasNameError;
9415
9416 uentry_free (def);
9417
9418 if (!spec->hasNameError)
9419 {
9420 uentry_checkName (spec);
9421 }
9422 else
9423 {
9424 ;
9425 }
9426}
9427
9428/*
9429** Can't generate function redeclaration errors when the
9430** entries are merged, since we don't yet know if its the
9431** definition of the function.
9432*/
9433
9434void
9435uentry_clearDecl (void)
9436{
9437 posRedeclared = uentry_undefined;
9438 fileloc_free (posLoc);
9439 posLoc = fileloc_undefined;
9440}
9441
9442void
9443uentry_checkDecl (void)
9444{
f0171cff 9445 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
616915dd 9446 {
9447 llassert (fileloc_isDefined (posLoc));
9448
9449 if (uentry_isCodeDefined (posRedeclared))
9450 {
9451 if (optgenerror (FLG_REDECL,
9452 message ("%s %q declared after definition",
9453 ekind_capName (posRedeclared->ukind),
9454 uentry_getName (posRedeclared)),
9455 posLoc))
9456 {
9457 llgenindentmsg (message ("Definition of %q",
9458 uentry_getName (posRedeclared)),
9459 posRedeclared->whereDeclared);
9460 }
9461 }
9462 else
9463 {
9464 if (optgenerror (FLG_REDECL,
9465 message ("%s %q declared more than once",
9466 ekind_capName (posRedeclared->ukind),
9467 uentry_getName (posRedeclared)),
9468 posLoc))
9469 {
9470 llgenindentmsg (message ("Previous declaration of %q",
9471 uentry_getName (posRedeclared)),
9472 posRedeclared->whereDeclared);
9473 }
9474 }
9475 }
9476
9477 fileloc_free (posLoc);
9478 posLoc = fileloc_undefined;
9479 posRedeclared = uentry_undefined;
9480}
9481
9482/*
9483** Redefinition of old as unew.
9484** modifies old to reflect unew, reports any inconsistencies
9485*/
9486
9487void
9488uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9489{
d89a0c94 9490 fileloc olddef = uentry_whereDeclared (old);
616915dd 9491 fileloc unewdef = uentry_whereDeclared (unew);
9492 bool mustConform;
9493 bool wasForward;
28bf4b0b 9494
9495 DPRINTF (("uentry merge: %s / %s",
9496 uentry_unparseFull (old),
9497 uentry_unparseFull (unew)));
616915dd 9498
616915dd 9499 wasForward =
9500 fileloc_isUndefined (olddef)
efd360a3 9501 && fileloc_isDefined (uentry_whereDefined (old))
9502 && !uentry_isExpandedMacro (old);
616915dd 9503
9504 if (!context_getFlag (FLG_INCONDEFSLIB)
9505 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9506 {
9507 mustConform = FALSE;
9508 }
9509 else
9510 {
9511 mustConform = TRUE;
9512 }
9513
9514 llassert (uentry_isValid (old));
9515 llassert (uentry_isValid (unew));
9516 llassert (cstring_equal (old->uname, unew->uname));
9517
efd360a3 9518 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9519 {
9520 if (uentry_isConstant (old))
9521 {
9522 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9523 uentry_makeConstantFunction (old);
9524 }
9525 else
9526 {
9527 uentry_convertVarFunction (old);
9528 }
9529
9530 llassert (uentry_isFunction (old));
9531 }
9532
9533 DPRINTF (("uentry merge: %s / %s",
9534 uentry_unparseFull (old),
9535 uentry_unparseFull (unew)));
9536
9537 if (uentry_isExtern (unew))
9538 {
9539 uentry_setUsed (old, unewdef);
9540 }
9541
616915dd 9542 /*
9543 ** should check old one was extern!
9544 */
9545
9546 if (uentry_isStatic (old))
9547 {
9548 if (!(uentry_isStatic (unew)))
9549 {
9550 if (optgenerror
9551 (FLG_SHADOW,
9552 message ("%s %q shadows static declaration",
9553 ekind_capName (unew->ukind),
9554 uentry_getName (unew)),
9555 unewdef))
9556 {
9557 uentry_showWhereLast (old);
9558 }
9559 }
9560 else
9561 {
9562 uentry_setDeclDef (old, unewdef);
9563 }
9564 }
9565 else if (uentry_isStatic (unew))
9566 {
9567 uentry_setDeclDef (old, unewdef);
9568 }
9569 else if (uentry_isExtern (old))
9570 {
9571 uentry_setDeclared (old, unewdef);
9572 }
9573 else
9574 {
d89a0c94 9575 if (!uentry_isExtern (unew)
9576 && !uentry_isForward (old)
616915dd 9577 && !fileloc_equal (olddef, unewdef)
9578 && !fileloc_isUndefined (olddef)
9579 && !fileloc_isUndefined (unewdef)
9580 && !fileloc_isBuiltin (olddef)
9581 && !fileloc_isBuiltin (unewdef)
9582 && !uentry_isYield (old)
9583 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9584 {
9585 if (uentry_isVariable (old) || uentry_isVariable (unew))
9586 {
9587 ; /* will report redeclaration error later */
9588 }
9589 else
9590 {
9591 if (fileloc_isDefined (uentry_whereDefined (old)))
9592 {
9593 if (optgenerror
9594 (FLG_REDEF,
9595 message ("%s %q defined more than once",
9596 ekind_capName (unew->ukind),
9597 uentry_getName (unew)),
9598 uentry_whereLast (unew)))
9599 {
9600 llgenindentmsg
9601 (message ("Previous definition of %q",
9602 uentry_getName (old)),
9603 uentry_whereLast (old));
9604 }
9605 /*
9606 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9607 {
efd360a3 9608 uentry_updateInto (old, unew);
616915dd 9609 old->sref = sRef_saveCopy (old->sref);
9610 }
9611 */
9612 }
9613 }
9614 }
9615 else
9616 {
9617 if (fileloc_isLib (olddef)
9618 || fileloc_isUndefined (olddef)
9619 || fileloc_isImport (olddef))
9620 {
9621 if (uentry_isExtern (unew))
9622 {
9623 if (uentry_isExtern (old)
9624 || (fileloc_isDefined (uentry_whereDeclared (old))
9625 && (!fileloc_equal (uentry_whereDeclared (old),
9626 uentry_whereDefined (old)))))
9627 {
9628 if (optgenerror
9629 (FLG_REDECL,
9630 message ("%s %q declared more than once",
9631 ekind_capName (unew->ukind),
9632 uentry_getName (unew)),
9633 unew->whereDeclared))
9634 {
9635 llgenindentmsg
9636 (message ("Previous declaration of %q",
9637 uentry_getName (old)),
9638 old->whereDeclared);
9639 }
9640 }
9641
9642 uentry_setExtern (old);
9643 }
9644 else
9645 {
d89a0c94 9646 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
616915dd 9647 }
9648 }
9649 }
9650 }
9651
efd360a3 9652 DPRINTF (("uentry merge: %s / %s",
9653 uentry_unparseFull (old),
9654 uentry_unparseFull (unew)));
ba45e1e4 9655
efd360a3 9656 uentry_mergeConstraints (old, unew);
d89a0c94 9657 DPRINTF (("uentry merge: %s / %s",
9658 uentry_unparseFull (old),
9659 uentry_unparseFull (unew)));
9660
616915dd 9661 uentry_checkConformance (old, unew, mustConform, FALSE);
d89a0c94 9662 DPRINTF (("uentry merge: %s / %s",
9663 uentry_unparseFull (old),
9664 uentry_unparseFull (unew)));
616915dd 9665
9666 old->used = old->used || unew->used;
9667 old->uses = filelocList_append (old->uses, unew->uses);
9668 unew->uses = filelocList_undefined;
9669
9670 sRef_storeState (old->sref);
9671 sRef_storeState (unew->sref);
9672
9673 if (wasForward)
9674 {
9675 old->whereDefined = fileloc_update (old->whereDefined,
9676 fileloc_undefined);
9677 }
9678
d89a0c94 9679 DPRINTF (("here: %s", uentry_unparseFull (old)));
9680
616915dd 9681 /*
9682 ** No redeclaration errors for functions here, since we
9683 ** don't know if this is the definition of the function.
9684 */
9685
9686 if (fileloc_isUser (old->whereDeclared)
9687 && fileloc_isUser (unew->whereDeclared)
9688 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9689 && !fileloc_isDefined (unew->whereDefined))
9690 {
9691 if (uentry_isFunction (old))
9692 {
9693 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9694 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9695 }
9696 else
9697 {
9698 if (optgenerror (FLG_REDECL,
9699 message ("%s %q declared more than once",
9700 ekind_capName (unew->ukind),
9701 uentry_getName (unew)),
9702 unew->whereDeclared))
9703 {
9704 llgenindentmsg (message ("Previous declaration of %q",
9705 uentry_getName (old)),
9706 old->whereDeclared);
9707 }
9708 }
9709 }
9710
9711 if (fileloc_isUndefined (old->whereDefined))
9712 {
9713 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9714 }
9715 else
9716 {
9717 if (!context_processingMacros ()
9718 && fileloc_isUser (old->whereDefined)
9719 && fileloc_isUser (unew->whereDefined)
9720 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9721 {
9722 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9723 {
9724 if (uentry_isVariable (unew)
9725 && uentry_isExtern (unew))
9726 {
9727 if (optgenerror (FLG_REDECL,
9728 message ("%s %q declared after definition",
9729 ekind_capName (unew->ukind),
9730 uentry_getName (unew)),
9731 unew->whereDeclared))
9732 {
9733 llgenindentmsg (message ("Definition of %q",
9734 uentry_getName (old)),
9735 old->whereDefined);
9736 }
9737 }
9738 else
9739 {
9740 if (optgenerror (FLG_REDEF,
9741 message ("%s %q redefined",
9742 ekind_capName (unew->ukind),
9743 uentry_getName (unew)),
9744 unew->whereDefined))
9745 {
9746 llgenindentmsg (message ("Previous definition of %q",
9747 uentry_getName (old)),
9748 old->whereDefined);
9749 }
9750 }
9751 }
9752 }
9753 }
9754
9755 if (uentry_isExternal (unew))
9756 {
9757 old->whereDefined = fileloc_createExternal ();
9758 }
9759
9760 if (unew->hasNameError)
9761 {
9762 old->hasNameError = TRUE;
9763 }
9764
9765 uentry_free (unew);
9766
9767 if (!old->hasNameError)
9768 {
9769 uentry_checkName (old);
9770 }
9771
d89a0c94 9772 DPRINTF (("After: %s", uentry_unparseFull (old)));
616915dd 9773 llassert (!ctype_isUndefined (old->utype));
9774}
9775
9776void
9777uentry_copyState (uentry res, uentry other)
9778{
9779 llassert (uentry_isValid (res));
9780 llassert (uentry_isValid (other));
9781
9782 res->used = other->used;
9783
9784 res->info->var->kind = other->info->var->kind;
9785 res->info->var->defstate = other->info->var->defstate;
9786 res->info->var->nullstate = other->info->var->nullstate;
9787 res->info->var->checked = other->info->var->checked;
9788
9789 sRef_copyState (res->sref, other->sref);
9790}
9791
9792bool
9793uentry_sameKind (uentry u1, uentry u2)
9794{
9795 if (uentry_isValid (u1) && uentry_isValid (u2))
9796 {
9797 if (uentry_isVar (u1) && uentry_isVar (u2))
9798 {
9799 ctype c1 = u1->utype;
9800 ctype c2 = u2->utype;
9801
9802 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9803
9804 /*
9805 ** both functions, or both not functions
9806 */
9807
9808 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9809 }
9810 else
9811 {
9812 return ((u1->ukind == u2->ukind));
9813 }
9814 }
9815
9816 return FALSE;
9817}
9818
efd360a3 9819static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
616915dd 9820{
abd7f895 9821 ekind okind;
616915dd 9822 llassert (uentry_isValid (unew));
9823 llassert (uentry_isValid (old));
9824
d89a0c94 9825 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
abd7f895 9826 okind = unew->ukind;
616915dd 9827 unew->ukind = old->ukind;
efd360a3 9828 llassert (cstring_equal (unew->uname, old->uname));
616915dd 9829 unew->utype = old->utype;
9830
efd360a3 9831 if (fileloc_isDefined (unew->whereSpecified)
9832 && !fileloc_isDefined (old->whereSpecified))
9833 {
9834 ; /* Keep the old value */
9835 }
9836 else
9837 {
9838 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9839 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9840 }
9841
9842 if (fileloc_isDefined (unew->whereDefined)
9843 && !fileloc_isDefined (old->whereDefined))
9844 {
9845 ; /* Keep the old value */
9846 }
9847 else
9848 {
9849 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9850 unew->whereDefined = fileloc_copy (old->whereDefined);
9851 }
9852
9853 if (fileloc_isDefined (unew->whereDeclared)
9854 && !fileloc_isDefined (old->whereDeclared))
9855 {
9856 ; /* Keep the old value */
9857 }
9858 else
9859 {
9860 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9861 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9862 }
616915dd 9863
d89a0c94 9864 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9865
616915dd 9866 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9867 unew->used = old->used;
9868 unew->lset = FALSE;
9869 unew->isPrivate = old->isPrivate;
9870 unew->hasNameError = old->hasNameError;
efd360a3 9871 unew->uses = filelocList_append (unew->uses, old->uses);
9872 old->uses = filelocList_undefined;
616915dd 9873
9874 unew->storageclass = old->storageclass;
efd360a3 9875 uinfo_free (unew->info, okind);
616915dd 9876 unew->info = uinfo_copy (old->info, old->ukind);
9877}
9878
9879
9880uentry
9881uentry_copy (uentry e)
9882{
9883 if (uentry_isValid (e))
9884 {
9885 uentry enew = uentry_alloc ();
9886 DPRINTF (("copy: %s", uentry_unparseFull (e)));
efd360a3 9887 enew->ukind = e->ukind;
9888 enew->uname = cstring_copy (e->uname);
9889 enew->utype = e->utype;
9890
9891 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9892 enew->whereDefined = fileloc_copy (e->whereDefined);
9893 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9894
9895 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9896 enew->used = e->used;
9897 enew->lset = FALSE;
9898 enew->isPrivate = e->isPrivate;
9899 enew->hasNameError = e->hasNameError;
9900 enew->uses = filelocList_undefined;
9901
9902 enew->storageclass = e->storageclass;
9903 enew->info = uinfo_copy (e->info, e->ukind);
9904 enew->warn = warnClause_copy (e->warn);
9905
616915dd 9906 DPRINTF (("Here we are..."));
9907 DPRINTF (("original: %s", uentry_unparseFull (e)));
9908 DPRINTF (("copy: %s", uentry_unparse (enew)));
9909 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9910 return enew;
9911 }
9912 else
9913 {
9914 return uentry_undefined;
9915 }
9916}
9917
9918void
9919uentry_setState (uentry res, uentry other)
9920{
9921 llassert (uentry_isValid (res));
9922 llassert (uentry_isValid (other));
9923
9924 llassert (res->ukind == other->ukind);
9925 llassert (res->ukind == KVAR);
9926
9927 res->sref = sRef_saveCopy (other->sref);
9928 res->used = other->used;
9929 filelocList_free (res->uses);
9930 res->uses = other->uses;
9931 other->uses = filelocList_undefined;
9932 res->lset = other->lset;
9933}
9934
9935void
9936uentry_mergeUses (uentry res, uentry other)
9937{
9938 llassert (uentry_isValid (res));
9939 llassert (uentry_isValid (other));
9940
9941 res->used = other->used || res->used;
9942 res->lset = other->lset || res->lset;
9943 res->uses = filelocList_append (res->uses, other->uses);
9944 other->uses = filelocList_undefined;
9945}
9946
9947
9948/*
9949** This is a really ugly routine.
9950**
9951** gack...fix this one day.
9952*/
9953
9954/*
9955** flip == TRUE
9956** >> res is the false branch, other is the true branch (or continuation)
9957** flip == FALSE
9958** >> res is the true branch, other is the false branch (or continutation)
9959**
9960** opt == TRUE if,
9961**
9962** <other>
9963** if <res> ;
9964**
9965** References not effected by res are propagated from other.
9966*/
9967
9968static void
9969 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9970 bool flip, clause cl, fileloc loc)
9971{
9972 if (optgenerror
9973 (FLG_BRANCHSTATE,
9974 message ("%s %q is %s %s, but %s %s.",
9975 ekind_capName (res->ukind), uentry_getName (res),
9976 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9977 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9978 loc))
9979 {
9980 if (sRef_isDead (res->sref))
9981 {
9982 sRef_showStateInfo (res->sref);
9983 }
9984 else if (sRef_isKept (res->sref))
9985 {
9986 sRef_showAliasInfo (res->sref);
9987 }
9988 else /* dependent */
9989 {
9990 sRef_showAliasInfo (res->sref);
9991 sRef_showAliasInfo (other->sref);
9992 }
9993
9994 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9995 }
9996}
9997
60868d40 9998static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
616915dd 9999{
10000 alkind rk = sRef_getAliasKind (rs);
10001 alkind ok = sRef_getAliasKind (os);
10002
10003 if (alkind_isError (rk) || alkind_isError (ok))
10004 {
10005 return FALSE;
10006 }
10007 else
10008 {
10009 return ((sRef_isDead (rs)
10010 || (alkind_isKept (rk) && !alkind_isKept (ok))
10011 || (alkind_isDependent (rk)
10012 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10013 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10014 }
10015}
10016
10017static void
10018 branchStateAltError (/*@notnull@*/ uentry res,
10019 /*@notnull@*/ uentry other, bool flip,
10020 clause cl, fileloc loc)
10021{
10022 if (optgenerror
10023 (FLG_BRANCHSTATE,
10024 message ("%s %q is %s %s, but %s %s.",
10025 ekind_capName (res->ukind), uentry_getName (res),
10026 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10027 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10028 loc))
10029 {
10030 if (sRef_isDead (other->sref))
10031 {
10032 sRef_showStateInfo (other->sref);
10033 }
10034 else /* kept */
10035 {
10036 sRef_showAliasInfo (other->sref);
10037 }
10038
10039 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10040 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10041
10042 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10043 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10044 }
10045}
10046
28bf4b0b 10047/*
10048** A reference is relevant for certain checks, only if it
10049** is not definitely null on this path (but not declared
10050** to always be null.)
10051*/
10052
10053static bool uentry_relevantReference (sRef sr, bool flip)
616915dd 10054{
28bf4b0b 10055 if (sRef_isKept (sr) || sRef_isDependent (sr))
10056 {
10057 return FALSE;
10058 }
10059 else
10060 {
10061 if (flip)
10062 {
10063 return !sRef_definitelyNullContext (sr);
10064 }
10065 else
10066 {
10067 return !sRef_definitelyNullAltContext (sr);
10068 }
10069 }
616915dd 10070}
616915dd 10071
28bf4b0b 10072static void
abd7f895 10073uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10074 fileloc loc, bool mustReturn, bool flip, bool opt,
28bf4b0b 10075 clause cl)
10076{
60868d40 10077 sRef rs = res->sref;
10078 sRef os = other->sref;
10079
28bf4b0b 10080 DPRINTF (("Merge alias states: %s / %s",
10081 uentry_unparseFull (res),
10082 uentry_unparseFull (other)));
616915dd 10083
60868d40 10084 if (sRef_isValid (rs))
616915dd 10085 {
10086 if (!mustReturn)
10087 {
60868d40 10088 if (uentry_incompatibleMemoryStates (rs, os))
616915dd 10089 {
60868d40 10090 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10091 sRef_unparseFull (rs), sRef_unparseFull (os)));
28bf4b0b 10092
60868d40 10093 if (sRef_isThroughArrayFetch (rs)
616915dd 10094 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10095 {
60868d40 10096 if (sRef_isKept (rs) || sRef_isKept (os))
616915dd 10097 {
60868d40 10098 sRef_maybeKill (rs, loc);
616915dd 10099 }
60868d40 10100 else if (sRef_isPossiblyDead (os))
616915dd 10101 {
60868d40 10102 sRef_maybeKill (rs, loc);
616915dd 10103 }
10104 else
10105 {
10106 ;
10107 }
10108 }
10109 else
10110 {
60868d40 10111 if (uentry_relevantReference (os, flip))
616915dd 10112 {
60868d40 10113 if (sRef_isLocalParamVar (rs)
10114 && (sRef_isLocalState (os)
10115 || sRef_isDependent (os)))
616915dd 10116 {
60868d40 10117 if (sRef_isDependent (rs))
616915dd 10118 {
60868d40 10119 sRef_setDependent (os, loc);
616915dd 10120 }
10121 else
10122 {
60868d40 10123 sRef_setDefState (rs, SS_UNUSEABLE, loc);
616915dd 10124 }
10125 }
10126 else
10127 {
10128 branchStateError (res, other, flip, cl, loc);
10129 }
10130 }
10131 }
10132
60868d40 10133 if (sRef_isKept (rs))
616915dd 10134 {
60868d40 10135 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10136 sRef_setKept (os, loc);
616915dd 10137 }
10138 }
10139 else
10140 {
60868d40 10141 if (uentry_incompatibleMemoryStates (os, rs))
616915dd 10142 {
60868d40 10143 if (uentry_relevantReference (rs, !flip))
616915dd 10144 {
60868d40 10145 if (sRef_isLocalParamVar (rs)
10146 && (sRef_isDependent (rs)
10147 || sRef_isLocalState (rs)))
616915dd 10148 {
60868d40 10149 if (sRef_isDependent (os))
616915dd 10150 {
60868d40 10151 sRef_setDependent (rs, loc);
616915dd 10152 }
10153 else
10154 {
60868d40 10155 sRef_setDefState (rs, SS_UNUSEABLE, loc);
616915dd 10156 }
10157 }
10158 else
10159 {
60868d40 10160 if (sRef_isParam (os))
616915dd 10161 {
10162 /*
10163 ** If the local variable associated
10164 ** with the param has the correct state,
10165 ** its okay.
10166 ** (e.g., free (s); s = new(); ...
10167 */
28bf4b0b 10168
616915dd 10169 uentry uvar = usymtab_lookupSafe (other->uname);
28bf4b0b 10170
616915dd 10171 if (uentry_isValid (uvar)
60868d40 10172 && ((sRef_isDead (os)
616915dd 10173 && sRef_isOnly (uvar->sref))
60868d40 10174 || (sRef_isDependent (os)
616915dd 10175 && sRef_isOwned (uvar->sref))))
10176 {
10177 /* no error */
10178 }
10179 else
10180 {
10181 branchStateAltError (res, other,
10182 flip, cl, loc);
10183 }
10184 }
10185 else
10186 {
28bf4b0b 10187 DPRINTF (("Here: %s / %s",
10188 uentry_unparseFull (res),
10189 uentry_unparseFull (other)));
10190
616915dd 10191 branchStateAltError (res, other,
10192 flip, cl, loc);
10193 }
10194 }
10195 }
10196 }
28bf4b0b 10197
60868d40 10198 if (sRef_isKept (os))
616915dd 10199 {
60868d40 10200 sRef_setKept (rs, loc);
616915dd 10201 }
10202 }
10203
10204 if (opt)
10205 {
10206 DPRINTF (("Merge opt..."));
60868d40 10207 sRef_mergeOptState (rs, os, cl, loc);
616915dd 10208 DPRINTF (("Done!"));
10209 }
10210 else
10211 {
60868d40 10212 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10213 sRef_mergeState (rs, os, cl, loc);
10214 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
616915dd 10215 }
10216 }
10217 else
10218 {
60868d40 10219 if (sRef_isModified (os))
616915dd 10220 {
60868d40 10221 sRef_setModified (rs);
616915dd 10222 }
10223 }
28bf4b0b 10224 }
60868d40 10225
10226 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
28bf4b0b 10227}
616915dd 10228
28bf4b0b 10229static void
abd7f895 10230uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10231 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
28bf4b0b 10232{
10233 valueTable rvalues;
10234 valueTable ovalues;
10235
10236 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10237
b7e84605 10238 if (mustReturn)
10239 {
10240 return;
10241 }
10242 /* flip? */
10243
28bf4b0b 10244 rvalues = sRef_getValueTable (res->sref);
10245 ovalues = sRef_getValueTable (other->sref);
10246
10247 if (valueTable_isUndefined (ovalues))
10248 {
10249 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10250 ;
10251 }
10252 else if (valueTable_isUndefined (rvalues))
10253 {
10254 /*
10255 ** Copy values from other
10256 */
10257
10258 /*@i$@#@*/
10259 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10260 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10261 ;
10262 }
10263 else
10264 {
10265 valueTable_elements (ovalues, fkey, fval) {
10266 stateValue tval;
10267 metaStateInfo minfo;
10268 stateCombinationTable sctable;
10269 cstring msg;
10270 int nval;
10271
10272 tval = valueTable_lookup (rvalues, fkey);
10273
10274 DPRINTF (("Merge value: %s / %s X %s", fkey,
10275 stateValue_unparse (fval), stateValue_unparse (tval)));
10276
10277 minfo = context_lookupMetaStateInfo (fkey);
10278 llassert (stateValue_isDefined (tval));
10279
10280 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10281 {
10282 DPRINTF (("Cannot find meta state for: %s", fkey));
10283 BADBRANCH;
10284 }
10285 else
10286 {
10287 llassert (metaStateInfo_isDefined (minfo));
10288
10289 if (stateValue_isError (fval)
10290 || sRef_definitelyNullContext (res->sref))
10291 {
10292 sRef_setMetaStateValueComplete (res->sref,
10293 fkey, stateValue_getValue (fval),
b7e84605 10294 stateValue_getLoc (fval));
28bf4b0b 10295 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10296 }
10297 else if (stateValue_isError (tval)
10298 || sRef_definitelyNullAltContext (other->sref))
10299 {
10300 DPRINTF (("Other branch is definitely null!"));
10301 }
b7e84605 10302 else if (sRef_isStateUndefined (res->sref)
10303 || sRef_isDead (res->sref))
10304 {
10305 ; /* Combination state doesn't matter if it is undefined or dead */
10306 }
28bf4b0b 10307 else
10308 {
10309 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10310 metaStateInfo_unparse (minfo),
10311 stateValue_unparse (fval),
10312 stateValue_unparse (tval)));
10313
10314 DPRINTF (("state values: %d / %d",
10315 stateValue_getValue (fval), stateValue_getValue (tval)));
10316
10317 sctable = metaStateInfo_getMergeTable (minfo);
10318
10319 DPRINTF (("Merge table: %s",
10320 stateCombinationTable_unparse (sctable)));
10321
10322 msg = cstring_undefined;
10323
10324 nval = stateCombinationTable_lookup (sctable,
10325 stateValue_getValue (fval),
10326 stateValue_getValue (tval),
10327 &msg);
10328
10329 DPRINTF (("nval: %d / %d / %d", nval,
10330 stateValue_getValue (fval), stateValue_getValue (tval)));
10331
b7e84605 10332 if (nval == stateValue_error)
28bf4b0b 10333 {
10334 /*@i32 print extra info for assignments@*/
10335
10336 if (uentry_isGlobalMarker (res))
10337 {
10338 if (optgenerror
10339 (FLG_STATEMERGE,
10340 message
b7e84605 10341 ("Control branches merge with incompatible global states (%s and %s)%q",
28bf4b0b 10342 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10343 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
b7e84605 10344 cstring_isDefined (msg)
10345 ? message (": %s", msg) : cstring_undefined),
28bf4b0b 10346 loc))
10347 {
10348 sRef_showMetaStateInfo (res->sref, fkey);
10349 sRef_showMetaStateInfo (other->sref, fkey);
10350 }
10351 }
10352 else
10353 {
10354 if (optgenerror
10355 (FLG_STATEMERGE,
10356 message
b7e84605 10357 ("Control branches merge with incompatible states for %q (%s and %s)%q",
28bf4b0b 10358 uentry_getName (res),
10359 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10360 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
b7e84605 10361 cstring_isDefined (msg)
10362 ? message (": %s", msg) : cstring_undefined),
28bf4b0b 10363 loc))
10364 {
10365 sRef_showMetaStateInfo (res->sref, fkey);
10366 sRef_showMetaStateInfo (other->sref, fkey);
10367 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10368 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10369 DPRINTF (("Null: %s / %s",
10370 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10371 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10372
10373 }
10374 }
10375 }
10376
10377 if (nval == stateValue_getValue (fval)
10378 && nval != stateValue_getValue (tval))
10379 {
10380 loc = stateValue_getLoc (fval);
10381 }
10382 else if (nval == stateValue_getValue (tval)
10383 && nval != stateValue_getValue (fval))
10384 {
10385 loc = stateValue_getLoc (tval);
10386 }
10387 else
10388 {
10389 ;
10390 }
10391
10392 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10393 && nval == stateValue_getValue (fval)
10394 && nval == stateValue_getValue (tval))
10395 {
10396 ;
10397 }
10398 else
10399 {
10400 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10401 }
10402 }
10403 }
10404 } end_valueTable_elements ;
10405 }
10406}
10407
10408
10409static void
abd7f895 10410uentry_mergeSetStates (/*@notnull@*/ uentry res,
10411 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
28bf4b0b 10412 bool flip, clause cl)
10413{
10414 if (cl == DOWHILECLAUSE)
10415 {
10416 res->used = other->used || res->used;
10417 res->lset = other->lset || res->lset;
10418 res->uses = filelocList_append (res->uses, other->uses);
10419 other->uses = filelocList_undefined;
10420 }
10421 else
10422 {
10423 if (sRef_isMacroParamRef (res->sref)
10424 && !uentry_isSefParam (other)
10425 && !uentry_isSefParam (res))
616915dd 10426 {
28bf4b0b 10427 bool hasError = FALSE;
10428
10429 if (bool_equal (res->used, other->used))
616915dd 10430 {
28bf4b0b 10431 res->used = other->used;
10432 }
10433 else
10434 {
10435 if (other->used && !flip)
616915dd 10436 {
28bf4b0b 10437 hasError =
10438 optgenerror
10439 (FLG_MACROPARAMS,
10440 message ("Macro parameter %q used in true clause, "
10441 "but not in false clause",
10442 uentry_getName (res)),
10443 uentry_whereDeclared (res));
616915dd 10444 }
10445 else
28bf4b0b 10446 {
10447 hasError =
10448 optgenerror
10449 (FLG_MACROPARAMS,
10450 message ("Macro parameter %q used in false clause, "
10451 "but not in true clause",
10452 uentry_getName (res)),
10453 uentry_whereDeclared (res));
10454 }
10455 res->used = TRUE;
10456
10457 if (hasError)
616915dd 10458 {
28bf4b0b 10459 /* make it sef now, prevent more errors */
10460 res->info->var->kind = VKREFSEFPARAM;
616915dd 10461 }
10462 }
28bf4b0b 10463 }
10464 else
10465 {
10466 res->used = other->used || res->used;
10467 res->lset = other->lset || res->lset;
10468 res->uses = filelocList_append (res->uses, other->uses);
10469 other->uses = filelocList_undefined;
616915dd 10470 }
10471 }
10472}
10473
28bf4b0b 10474void
10475uentry_mergeState (uentry res, uentry other, fileloc loc,
10476 bool mustReturn, bool flip, bool opt,
10477 clause cl)
10478{
10479 llassert (uentry_isValid (res));
10480 llassert (uentry_isValid (other));
10481
10482 llassert (res->ukind == other->ukind);
10483 llassert (res->ukind == KVAR);
10484
10485 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10486 uentry_unparseFull (other)));
10487
10488 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
b7e84605 10489 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
28bf4b0b 10490 uentry_mergeSetStates (res, other, loc, flip, cl);
3e3ec469 10491
10492 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
28bf4b0b 10493}
10494
616915dd 10495void uentry_setUsed (uentry e, fileloc loc)
10496{
10497 static bool firstTime = TRUE;
10498 static bool showUses = FALSE;
10499 static bool exportLocal = FALSE;
10500
28bf4b0b 10501 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10502
616915dd 10503 if (firstTime)
10504 {
10505 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10506
10507 showUses = context_getFlag (FLG_SHOWUSES);
10508 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10509
10510 firstTime = FALSE;
10511 }
10512
10513 if (uentry_isValid (e))
10514 {
10515 int dp;
28bf4b0b 10516
10517 if (warnClause_isDefined (e->warn))
10518 {
10519 flagSpec flg = warnClause_getFlag (e->warn);
10520 cstring msg;
10521
10522 if (warnClause_hasMessage (e->warn))
10523 {
10524 msg = cstring_copy (warnClause_getMessage (e->warn));
10525 }
10526 else
10527 {
10528 msg = message ("Use of possibly dangerous %s",
10529 uentry_ekindNameLC (e));
10530 }
10531
10532 vfsgenerror (flg,
10533 message ("%q: %q", msg, uentry_getName (e)),
10534 loc);
10535 }
10536
616915dd 10537 if (sRef_isMacroParamRef (e->sref))
10538 {
10539 if (uentry_isYield (e) || uentry_isSefParam (e))
10540 {
10541 ;
10542 }
10543 else
10544 {
10545 if (context_inConditional ())
10546 {
10547 if (optgenerror
10548 (FLG_MACROPARAMS,
10549 message ("Macro parameter %q used in conditionally "
10550 "executed code (may or may not be "
10551 "evaluated exactly once)",
10552 uentry_getName (e)),
10553 loc))
10554 {
10555 e->info->var->kind = VKREFSEFPARAM;
10556 }
10557 }
10558 else
10559 {
10560 if ((e)->used)
10561 {
10562 if (optgenerror
10563 (FLG_MACROPARAMS,
10564 message ("Macro parameter %q used more than once",
10565 uentry_getName (e)),
10566 uentry_whereDeclared (e)))
10567 {
10568 e->info->var->kind = VKREFSEFPARAM;
10569 }
10570 }
10571 }
10572 }
10573 }
10574
10575 if ((dp = uentry_directParamNo (e)) >= 0)
10576 {
10577 uentry_setUsed (usymtab_getParam (dp), loc);
10578 }
10579
10580 e->used = TRUE;
28bf4b0b 10581
616915dd 10582 if (!sRef_isLocalVar (e->sref))
10583 {
10584 if (showUses)
10585 {
10586 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10587 }
10588 else
10589 {
10590 if (exportLocal)
10591 {
10592 if (context_inMacro ())
10593 {
10594 e->uses = filelocList_addUndefined (e->uses);
10595 }
10596 else
10597 {
10598 e->uses = filelocList_addDifferentFile
10599 (e->uses,
10600 uentry_whereDeclared (e),
10601 loc);
10602 }
10603 }
10604 }
10605 }
10606 }
10607}
10608
10609bool uentry_isReturned (uentry u)
10610{
10611 return (uentry_isValid (u) && uentry_isVar (u)
10612 && (u->info->var->kind == VKRETPARAM
10613 || u->info->var->kind == VKSEFRETPARAM));
10614}
10615
393e573f 10616/*@i52323@*/
10617# if 0
10618/*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10619{
10620 llassert (uentry_isRealFunction (u));
10621
10622 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10623 {
10624 stateClauseList clauses = uentry_getStateClauseList (u);
10625 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10626
10627 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10628 sRef_setAllocated (res, g_currentloc);
10629
10630 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10631 stateClauseList_unparse (clauses)));
10632
10633 /*
10634 ** This should be in exprNode_reflectEnsuresClause
10635 */
10636
10637 stateClauseList_postElements (clauses, cl)
10638 {
10639 if (!stateClause_isGlobal (cl))
10640 {
10641 sRefSet refs = stateClause_getRefs (cl);
10642 sRefMod modf = stateClause_getEffectFunction (cl);
10643
10644 sRefSet_elements (refs, el)
10645 {
10646 sRef base = sRef_getRootBase (el);
10647
10648 if (sRef_isResult (base))
10649 {
10650 if (modf != NULL)
10651 {
10652 sRef sr = sRef_fixBase (el, res);
10653 modf (sr, g_currentloc);
10654 }
10655 }
10656 else
10657 {
10658 ;
10659 }
10660 } end_sRefSet_elements ;
10661 }
10662 } end_stateClauseList_postElements ;
10663
10664 return res;
10665 }
10666 else
10667 {
10668 uentryList params;
10669 alkind ak;
10670 sRefSet prefs = sRefSet_new ();
10671 sRef res = sRef_undefined;
10672 sRef tcref = sRef_undefined;
10673 sRef tref = sRef_undefined;
10674 int paramno = 0;
10675
10676 params = uentry_getParams (u);
10677
10678 /*
10679 ** Setting up aliases has to happen *after* setting null state!
10680 */
10681
10682 uentryList_elements (params, current)
10683 {
10684 if (uentry_isReturned (current))
10685 {
10686 if (exprNodeList_size (args) >= paramno)
10687 {
10688 exprNode ecur = exprNodeList_nth (args, paramno);
10689 tref = exprNode_getSref (ecur);
10690
10691 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10692
10693 if (sRef_isValid (tref))
10694 {
10695 tcref = sRef_copy (tref);
10696
10697 if (sRef_isDead (tcref))
10698 {
10699 sRef_setDefined (tcref, g_currentloc);
10700 sRef_setOnly (tcref, g_currentloc);
10701 }
10702
10703 if (sRef_isRefCounted (tcref))
10704 {
10705 /* could be a new ref now (but only if its returned) */
10706 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10707 }
10708
10709 sRef_makeSafe (tcref);
10710 prefs = sRefSet_insert (prefs, tcref);
10711 }
10712 }
10713 }
10714
10715 paramno++;
10716 } end_uentryList_elements ;
10717
10718 if (sRefSet_size (prefs) > 0)
10719 {
10720 nstate n = sRef_getNullState (u->sref);
10721
10722 if (sRefSet_size (prefs) == 1)
10723 {
10724 sRef rref = sRefSet_choose (prefs);
10725 tref = rref;
10726 res = sRef_makeType (sRef_getType (rref));
10727 sRef_copyState (res, tref);
10728 }
10729 else
10730 {
10731 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10732 res = sRefSet_mergeIntoOne (prefs);
10733 }
10734
10735 if (nstate_isKnown (n))
10736 {
10737 sRef_setNullState (res, n, g_currentloc);
10738 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10739 }
10740 }
10741 else
10742 {
10743 if (ctype_isFunction (u->utype))
10744 {
10745 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10746 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10747 }
10748 else
10749 {
10750 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10751 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10752 }
10753
10754 if (sRef_isRefCounted (res))
10755 {
10756 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10757 }
10758 }
10759
10760 if (sRef_getNullState (res) == NS_ABSNULL)
10761 {
10762 ctype ct = ctype_realType (u->utype);
10763
10764 if (ctype_isAbstract (ct))
10765 {
10766 sRef_setNotNull (res, g_currentloc);
10767 }
10768 else
10769 {
10770 if (ctype_isUser (ct))
10771 {
10772 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10773 }
10774 else
10775 {
10776 sRef_setNotNull (res, g_currentloc);
10777 }
10778 }
10779 }
10780
10781 if (sRef_isRefCounted (res))
10782 {
10783 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10784 }
10785 else if (sRef_isKillRef (res))
10786 {
10787 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10788 }
10789 else
10790 {
10791 ;
10792 }
10793
10794 ak = sRef_getAliasKind (res);
10795
10796 if (alkind_isImplicit (ak))
10797 {
10798 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10799 }
10800
10801# if 0
10802 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10803 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10804
10805 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10806 usymtab_addReallyForceMustAlias (res, tref);
10807# endif
10808
10809 sRefSet_free (prefs);
10810
10811 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10812 return res;
10813 }
10814}
10815# endif
10816
616915dd 10817/*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10818{
10819 llassert (uentry_isRealFunction (u));
10820
28bf4b0b 10821 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
616915dd 10822 {
28bf4b0b 10823 stateClauseList clauses = uentry_getStateClauseList (u);
10824 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
616915dd 10825
28bf4b0b 10826 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
616915dd 10827 sRef_setAllocated (res, g_currentloc);
10828
28bf4b0b 10829 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10830 stateClauseList_unparse (clauses)));
616915dd 10831
ccf0a4a8 10832 /*
10833 ** This should be in exprNode_reflectEnsuresClause
10834 */
10835
28bf4b0b 10836 stateClauseList_postElements (clauses, cl)
10837 {
10838 if (!stateClause_isGlobal (cl))
616915dd 10839 {
28bf4b0b 10840 sRefSet refs = stateClause_getRefs (cl);
10841 sRefMod modf = stateClause_getEffectFunction (cl);
10842
10843 sRefSet_elements (refs, el)
616915dd 10844 {
28bf4b0b 10845 sRef base = sRef_getRootBase (el);
10846
10847 if (sRef_isResult (base))
616915dd 10848 {
28bf4b0b 10849 if (modf != NULL)
10850 {
10851 sRef sr = sRef_fixBase (el, res);
10852 modf (sr, g_currentloc);
10853 }
616915dd 10854 }
28bf4b0b 10855 else
10856 {
10857 ;
10858 }
10859 } end_sRefSet_elements ;
10860 }
10861 } end_stateClauseList_postElements ;
ccf0a4a8 10862
616915dd 10863 return res;
10864 }
10865 else
10866 {
10867 uentryList params;
10868 alkind ak;
10869 sRefSet prefs = sRefSet_new ();
10870 sRef res = sRef_undefined;
10871 int paramno = 0;
10872
10873 params = uentry_getParams (u);
10874
10875 uentryList_elements (params, current)
10876 {
10877 if (uentry_isReturned (current))
10878 {
10879 if (exprNodeList_size (args) >= paramno)
10880 {
10881 exprNode ecur = exprNodeList_nth (args, paramno);
10882 sRef tref = exprNode_getSref (ecur);
10883
28bf4b0b 10884 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10885
616915dd 10886 if (sRef_isValid (tref))
10887 {
10888 sRef tcref = sRef_copy (tref);
10889
28bf4b0b 10890 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10891
616915dd 10892 if (sRef_isDead (tcref))
10893 {
10894 sRef_setDefined (tcref, g_currentloc);
10895 sRef_setOnly (tcref, g_currentloc);
10896 }
10897
10898 if (sRef_isRefCounted (tcref))
10899 {
10900 /* could be a new ref now (but only if its returned) */
10901 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10902 }
10903
10904 sRef_makeSafe (tcref);
616915dd 10905 prefs = sRefSet_insert (prefs, tcref);
10906 }
10907 }
10908 }
10909
10910 paramno++;
10911 } end_uentryList_elements ;
10912
10913 if (sRefSet_size (prefs) > 0)
10914 {
10915 nstate n = sRef_getNullState (u->sref);
10916
10917 if (sRefSet_size (prefs) == 1)
10918 {
10919 res = sRefSet_choose (prefs);
10920 }
10921 else
10922 {
28bf4b0b 10923 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
616915dd 10924 res = sRefSet_mergeIntoOne (prefs);
10925 }
10926
10927 if (nstate_isKnown (n))
10928 {
10929 sRef_setNullState (res, n, g_currentloc);
10930 }
10931 }
10932 else
10933 {
10934 if (ctype_isFunction (u->utype))
10935 {
28bf4b0b 10936 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10937 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
616915dd 10938 }
10939 else
10940 {
10941 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10942 }
10943
10944 if (sRef_isRefCounted (res))
10945 {
10946 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10947 }
10948 }
10949
28bf4b0b 10950
616915dd 10951 if (sRef_getNullState (res) == NS_ABSNULL)
10952 {
10953 ctype ct = ctype_realType (u->utype);
10954
10955 if (ctype_isAbstract (ct))
10956 {
10957 sRef_setNotNull (res, g_currentloc);
10958 }
10959 else
10960 {
10961 if (ctype_isUser (ct))
10962 {
10963 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10964 }
10965 else
10966 {
10967 sRef_setNotNull (res, g_currentloc);
10968 }
10969 }
10970 }
10971
10972 if (sRef_isRefCounted (res))
10973 {
10974 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10975 }
10976 else if (sRef_isKillRef (res))
10977 {
10978 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10979 }
10980 else
10981 {
10982 ;
10983 }
10984
10985 ak = sRef_getAliasKind (res);
10986
10987 if (alkind_isImplicit (ak))
10988 {
10989 sRef_setAliasKind (res,
10990 alkind_fixImplicit (ak),
10991 g_currentloc);
10992 }
10993
10994 sRefSet_free (prefs);
10995
28bf4b0b 10996 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
616915dd 10997 return res;
10998 }
10999}
11000
11001static bool uentry_isRefCounted (uentry ue)
11002{
11003 ctype ct = uentry_getType (ue);
11004
11005 if (ctype_isFunction (ct))
11006 {
28bf4b0b 11007 return (ctype_isRefCounted (ctype_getReturnType (ct)));
616915dd 11008 }
11009 else
11010 {
11011 return (ctype_isRefCounted (ct));
11012 }
11013}
11014
11015/*
11016** old was declared yield in the specification.
11017** new is declared in the iter implementation.
11018*/
11019
11020void uentry_checkYieldParam (uentry old, uentry unew)
11021{
11022 cstring name;
11023
11024 llassert (uentry_isVariable (old));
11025 llassert (uentry_isVariable (unew));
11026
11027 unew->info->var->kind = VKYIELDPARAM;
11028 (void) checkTypeConformance (old, unew, TRUE);
11029 checkVarConformance (old, unew, TRUE, FALSE);
11030
11031 /* get rid of param marker */
11032
11033 name = uentry_getName (unew);
11034 cstring_free (unew->uname);
11035 unew->uname = name;
11036 unew->info->var->kind = VKREFYIELDPARAM;
11037
11038 uentry_setUsed (old, fileloc_undefined);
11039 uentry_setUsed (unew, fileloc_undefined);
11040}
11041
11042/*@observer@*/ cstring
11043uentry_ekindName (uentry ue)
11044{
11045 if (uentry_isValid (ue))
11046 {
11047 switch (ue->ukind)
11048 {
11049 case KINVALID:
11050 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11051 case KDATATYPE:
11052 return cstring_makeLiteralTemp ("Datatype");
11053 case KENUMCONST:
11054 return cstring_makeLiteralTemp ("Enum member");
11055 case KCONST:
11056 return cstring_makeLiteralTemp ("Constant");
11057 case KVAR:
11058 if (uentry_isParam (ue))
11059 {
11060 return cstring_makeLiteralTemp ("Parameter");
11061 }
11062 else if (uentry_isExpandedMacro (ue))
11063 {
11064 return cstring_makeLiteralTemp ("Expanded macro");
11065 }
11066 else
11067 {
11068 return cstring_makeLiteralTemp ("Variable");
11069 }
11070 case KFCN:
11071 return cstring_makeLiteralTemp ("Function");
11072 case KITER:
11073 return cstring_makeLiteralTemp ("Iterator");
11074 case KENDITER:
11075 return cstring_makeLiteralTemp ("Iterator finalizer");
11076 case KSTRUCTTAG:
11077 return cstring_makeLiteralTemp ("Struct tag");
11078 case KUNIONTAG:
11079 return cstring_makeLiteralTemp ("Union tag");
11080 case KENUMTAG:
11081 return cstring_makeLiteralTemp ("Enum tag");
11082 case KELIPSMARKER:
11083 return cstring_makeLiteralTemp ("Optional parameters");
11084 }
11085 }
11086 else
11087 {
11088 return cstring_makeLiteralTemp ("<Undefined>");
11089 }
11090
11091 BADEXIT;
11092}
11093
28bf4b0b 11094/*@observer@*/ cstring
11095uentry_ekindNameLC (uentry ue)
11096{
11097 if (uentry_isValid (ue))
11098 {
11099 switch (ue->ukind)
11100 {
11101 case KINVALID:
11102 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11103 case KDATATYPE:
11104 return cstring_makeLiteralTemp ("datatype");
11105 case KENUMCONST:
11106 return cstring_makeLiteralTemp ("enum member");
11107 case KCONST:
11108 return cstring_makeLiteralTemp ("constant");
11109 case KVAR:
11110 if (uentry_isParam (ue))
11111 {
11112 return cstring_makeLiteralTemp ("parameter");
11113 }
11114 else if (uentry_isExpandedMacro (ue))
11115 {
11116 return cstring_makeLiteralTemp ("expanded macro");
11117 }
11118 else
11119 {
11120 return cstring_makeLiteralTemp ("variable");
11121 }
11122 case KFCN:
11123 return cstring_makeLiteralTemp ("function");
11124 case KITER:
11125 return cstring_makeLiteralTemp ("iterator");
11126 case KENDITER:
11127 return cstring_makeLiteralTemp ("iterator finalizer");
11128 case KSTRUCTTAG:
11129 return cstring_makeLiteralTemp ("struct tag");
11130 case KUNIONTAG:
11131 return cstring_makeLiteralTemp ("union tag");
11132 case KENUMTAG:
11133 return cstring_makeLiteralTemp ("enum tag");
11134 case KELIPSMARKER:
11135 return cstring_makeLiteralTemp ("optional parameters");
11136 }
11137 }
11138 else
11139 {
11140 return cstring_makeLiteralTemp ("<Undefined>");
11141 }
11142
11143 BADEXIT;
11144}
11145
616915dd 11146void uentry_setHasNameError (uentry ue)
11147{
11148 llassert (uentry_isValid (ue));
11149
11150 ue->hasNameError = TRUE;
11151}
11152
11153void uentry_checkName (uentry ue)
11154{
28bf4b0b 11155 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11156 uentry_observeRealName (ue),
11157 bool_unparse (uentry_isVisibleExternally (ue))));
11158
616915dd 11159 if (uentry_isValid (ue)
28bf4b0b 11160 && !context_inXHFile ()
11161 && uentry_hasName (ue)
616915dd 11162 && !uentry_isElipsisMarker (ue)
11163 && context_getFlag (FLG_NAMECHECKS)
11164 && !ue->hasNameError
11165 && !uentry_isEndIter (ue)
11166 && !fileloc_isBuiltin (uentry_whereLast (ue))
11167 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
28bf4b0b 11168 {
11169 DPRINTF (("Here..."));
11170
616915dd 11171 if (uentry_isPriv (ue))
11172 {
11173 ; /* any checks here? */
11174 }
11175 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11176 {
11177 ; /* no errors for externals */
11178 }
11179 else
11180 {
11181 int scope;
11182
11183 if (uentry_isExpandedMacro (ue))
11184 {
11185 scope = globScope;
11186 }
11187 else
11188 {
11189 if (uentry_isExpandedMacro (ue))
11190 {
11191 scope = fileScope;
11192 }
11193 else if (uentry_isVariable (ue))
11194 {
11195 sRef sr = uentry_getSref (ue);
11196
11197 if (sRef_isValid (sr))
11198 {
11199 scope = sRef_getScope (sr);
11200 }
11201 else
11202 {
11203 scope = fileScope;
11204 }
11205 }
11206 else if (uentry_isFunction (ue)
11207 || uentry_isIter (ue)
11208 || uentry_isEndIter (ue)
11209 || uentry_isConstant (ue))
11210 {
11211 scope = uentry_isStatic (ue) ? fileScope : globScope;
11212 }
11213 else /* datatypes, etc. must be global */
11214 {
11215 scope = globScope;
11216 }
11217
11218 usymtab_checkDistinctName (ue, scope);
11219 }
28bf4b0b 11220
616915dd 11221 if (context_getFlag (FLG_CPPNAMES))
11222 {
28bf4b0b 11223 checkCppName (ue);
616915dd 11224 }
11225
11226 if (scope == globScope)
11227 {
28bf4b0b 11228 checkExternalName (ue);
616915dd 11229 }
28bf4b0b 11230 else if (scope == fileScope)
11231 {
11232 checkFileScopeName (ue);
11233 }
11234 else
616915dd 11235 {
11236 checkLocalName (ue);
616915dd 11237 }
11238
616915dd 11239 checkPrefix (ue);
28bf4b0b 11240 checkAnsiName (ue);
616915dd 11241 }
11242 }
11243}
11244
7ebcc5bb 11245/*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
616915dd 11246{
11247 uentry ue;
11248 fileloc tloc;
11249
11250 /*
7ebcc5bb 11251 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11252 */
11253
616915dd 11254 if (!context_inMacro ())
11255 {
11256 sRef_setGlobalScopeSafe ();
11257 }
11258
11259 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11260 uentry_setUsed (ue, loc);
11261
11262 tloc = fileloc_createExternal ();
11263 uentry_setDefined (ue, tloc);
11264 fileloc_free (tloc);
11265 uentry_setHasNameError (ue);
11266
c21b4c87 11267 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
616915dd 11268 {
11269 uentry_markOwned (ue);
11270 }
11271 else
11272 {
11273 ue = usymtab_supReturnFileEntry (ue);
11274 }
11275
11276 if (!context_inMacro ())
11277 {
11278 sRef_clearGlobalScopeSafe ();
11279 }
11280
11281 return ue;
11282}
11283
28bf4b0b 11284uentry uentry_makeGlobalMarker ()
11285{
11286 uentry ue;
11287 fileloc tloc;
11288
11289 llassert (sRef_inGlobalScope ());
11290
11291 ue = uentry_makeVariableAux
11292 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11293 sRef_makeGlobalMarker (),
11294 FALSE, VKNORMAL);
11295
11296 tloc = fileloc_createExternal ();
11297 uentry_setUsed (ue, tloc);
11298 uentry_setDefined (ue, tloc);
11299 fileloc_free (tloc);
11300 uentry_setHasNameError (ue);
11301
11302 return ue;
11303}
11304
11305
11306bool uentry_isGlobalMarker (uentry ue)
11307{
11308 return (uentry_isValid (ue)
11309 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11310}
11311
616915dd 11312/* new start modifications */
28bf4b0b 11313
616915dd 11314/* start modifications */
11315/*
11316requires: p_e is defined, is a ptr/array variable
11317modifies: p_e
11318effects: sets the state of the variable
11319*/
11320
28bf4b0b 11321
abd7f895 11322void uentry_setPossiblyNullTerminatedState (uentry p_e)
11323{
11324 llassert (uentry_isValid (p_e));
616915dd 11325
abd7f895 11326 if (p_e->info != NULL)
11327 {
11328 if (p_e->info->var != NULL)
11329 {
11330 llassert (p_e->info->var->bufinfo != NULL);
11331 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11332 sRef_setPossiblyNullTerminatedState (p_e->sref);
11333 }
11334 }
616915dd 11335}
11336
11337/*
11338requires: p_e is defined, is a ptr/array variable
11339modifies: p_e
11340effects: sets the size of the buffer
11341*/
11342
11343void uentry_setNullTerminatedState (uentry p_e) {
abd7f895 11344 llassert (uentry_isValid (p_e));
616915dd 11345
abd7f895 11346 if (p_e->info != NULL)
11347 {
11348 if (p_e->info->var != NULL)
11349 {
11350 llassert (p_e->info->var->bufinfo != NULL);
11351 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11352 sRef_setNullTerminatedState (p_e->sref);
11353 }
11354 }
616915dd 11355}
11356
616915dd 11357/*
11358requires: p_e is defined, is a ptr/array variable
11359modifies: p_e
11360effects: sets the size of the buffer
11361*/
11362
abd7f895 11363void uentry_setSize (uentry p_e, int size)
11364{
11365 if (uentry_isValid (p_e))
11366 {
11367 if (p_e->info != NULL)
11368 {
11369 if (p_e->info->var != NULL)
11370 {
11371 llassert (p_e->info->var->bufinfo != NULL);
11372 p_e->info->var->bufinfo->size = size;
11373 sRef_setSize (p_e->sref, size);
11374 }
11375 }
b7b694d6 11376 }
616915dd 11377}
11378
616915dd 11379/*
11380requires: p_e is defined, is a ptr/array variable
11381modifies: p_e
11382effects: sets the length of the buffer
11383*/
11384
abd7f895 11385void uentry_setLen (uentry p_e, int len)
11386{
11387 if (uentry_isValid (p_e))
11388 {
11389 if (p_e->info != NULL
11390 && p_e->info->var != NULL)
11391 {
11392 llassert (p_e->info->var->bufinfo != NULL);
11393 p_e->info->var->bufinfo->len = len;
11394 sRef_setLen (p_e->sref, len);
11395 }
b7b694d6 11396 }
616915dd 11397}
b7b694d6 11398
616915dd 11399/*@=type*/
ba45e1e4 11400
11401bool uentry_hasMetaStateEnsures (uentry e)
11402{
11403 if (uentry_isValid (e) && uentry_isFunction (e))
11404 {
11405 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11406 }
11407 else
11408 {
11409 return FALSE;
11410 }
11411}
11412
ccf0a4a8 11413metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
ba45e1e4 11414{
ccf0a4a8 11415 llassert (uentry_isValid (e) && uentry_isFunction (e));
11416 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
ba45e1e4 11417}
This page took 1.785502 seconds and 5 git commands to generate.