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