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