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