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