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