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