Minor strengthening of asserts.
[splint-patched.git] / src / cttable.i
blob1a7480aa0488959dd36a6e6a567cae70e985bee4
1 /* ;-*-C-*-;
2 ** vim: set syntax=c filetype=c shiftwidth=2 softtabstop=2 expandtab:
3 **
4 ** Splint - annotation-assisted static program checker
5 ** Copyright (C) 1994-2003 University of Virginia,
6 ** Massachusetts Institute of Technology
7 **
8 ** This program is free software; you can redistribute it and/or modify it
9 ** under the terms of the GNU General Public License as published by the
10 ** Free Software Foundation; either version 2 of the License, or (at your
11 ** option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful, but
14 ** WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
17 **
18 ** The GNU General Public License is available from http://www.gnu.org/ or
19 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 ** MA 02111-1307, USA.
22 ** For information on splint: info@splint.org
23 ** To report a bug: splint-bug@splint.org
24 ** For more information: http://www.splint.org
27 ** cttable.i
29 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
30 ** (This is necessary becuase there is no other way in C to have a
31 ** hidden scope, besides at the file level.)
34 /*@access ctype@*/
37 ** type definitions and forward declarations in ctbase.i
40 static void
41 ctentry_free (/*@only@*/ ctentry c)
43 ctbase_free (c->ctbase);
44 cstring_free (c->unparse);
45 sfree (c);
48 static void cttable_reset (void)
49 /*@globals cttab@*/
50 /*@modifies cttab@*/
52 if (cttab.entries != NULL)
54 int i;
56 for (i = 0; i < cttab.size; i++)
58 /*drl bee: si*/ ctentry_free (cttab.entries[i]);
61 /*@-compdestroy@*/
62 sfree (cttab.entries);
63 /*@=compdestroy@*/
65 cttab.entries = NULL;
68 cttab.size = 0 ;
69 cttab.nspace = 0 ;
72 static ctentry
73 ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
76 return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
79 static /*@only@*/ ctentry
80 ctentry_make (ctkind ctk,
81 /*@keep@*/ ctbase c, ctype base,
82 ctype ptr, ctype array,
83 /*@keep@*/ cstring unparse) /*@*/
85 ctentry cte = (ctentry) dmalloc (sizeof (*cte));
86 cte->kind = ctk;
87 cte->ctbase = c;
88 cte->base = base;
89 cte->ptr = ptr;
90 cte->array = array;
91 cte->unparse = unparse;
92 return cte;
95 static cstring
96 ctentry_unparse (ctentry c)
98 return (message
99 ("%20s [%d] [%d] [%d]",
100 (cstring_isDefined (c->unparse) ? c->unparse : cstring_makeLiteral ("<no name>")),
101 c->base,
102 c->ptr,
103 c->array));
106 static bool
107 ctentry_isInteresting (ctentry c)
109 return (cstring_isNonEmpty (c->unparse));
112 static /*@only@*/ cstring
113 ctentry_dump (ctentry c)
115 DPRINTF (("Dumping: %s", ctentry_unparse (c)));
117 if (c->ptr == ctype_dne
118 && c->array == ctype_dne
119 && c->base == ctype_dne)
121 return (message ("%d %q&",
122 ctkind_toInt (c->kind),
123 ctbase_dump (c->ctbase)));
125 else if (c->base == ctype_undefined
126 && c->array == ctype_dne)
128 if (c->ptr == ctype_dne)
130 return (message ("%d %q!",
131 ctkind_toInt (c->kind),
132 ctbase_dump (c->ctbase)));
134 else
136 return (message ("%d %q^%d",
137 ctkind_toInt (c->kind),
138 ctbase_dump (c->ctbase),
139 c->ptr));
142 else if (c->ptr == ctype_dne
143 && c->array == ctype_dne)
145 return (message ("%d %q%d&",
146 ctkind_toInt (c->kind),
147 ctbase_dump (c->ctbase),
148 c->base));
150 else
152 return (message ("%d %q%d %d %d",
153 ctkind_toInt (c->kind),
154 ctbase_dump (c->ctbase),
155 c->base, c->ptr, c->array));
160 static /*@only@*/ ctentry
161 ctentry_undump (/*@dependent@*/ char *s) /*@requires maxRead(s) >= 2 @*/
163 int base, ptr, array;
164 ctkind kind;
165 ctbase ct;
167 kind = ctkind_fromInt (reader_getInt (&s));
168 ct = ctbase_undump (&s);
170 if (reader_optCheckChar (&s, '&'))
172 base = ctype_dne;
173 ptr = ctype_dne;
174 array = ctype_dne;
176 else if (reader_optCheckChar (&s, '!'))
178 base = ctype_undefined;
179 ptr = ctype_dne;
180 array = ctype_dne;
182 else if (reader_optCheckChar (&s, '^'))
184 base = ctype_undefined;
185 ptr = reader_getInt (&s);
186 array = ctype_dne;
188 else
190 base = reader_getInt (&s);
192 if (reader_optCheckChar (&s, '&'))
194 ptr = ctype_dne;
195 array = ctype_dne;
197 else
199 ptr = reader_getInt (&s);
200 array = reader_getInt (&s);
204 /* can't unparse w/o typeTable */
205 return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
208 static /*@observer@*/ cstring
209 ctentry_doUnparse (ctentry c) /*@modifies c@*/
211 if (cstring_isDefined (c->unparse))
213 return (c->unparse);
215 else
217 cstring s = ctbase_unparse (c->ctbase);
219 if (!cstring_isEmpty (s) && !cstring_containsChar (s, '<'))
221 c->unparse = s;
223 else
225 cstring_markOwned (s);
228 return (s);
232 static /*@observer@*/ cstring
233 ctentry_doUnparseDeep (ctentry c)
235 if (cstring_isDefined (c->unparse))
237 return (c->unparse);
239 else
241 c->unparse = ctbase_unparseDeep (c->ctbase);
242 return (c->unparse);
247 ** cttable operations
250 static /*@only@*/ cstring
251 cttable_unparse (void)
253 int i;
254 cstring s = cstring_undefined;
256 /*@access ctbase@*/
257 for (i = 0; i < cttab.size; i++)
259 /*drl bee: si*/ ctentry cte = cttab.entries[i];
260 if (ctentry_isInteresting (cte))
262 if (ctbase_isUA (cte->ctbase))
264 s = message ("%s%d\t%q [%d]\n", s, i, ctentry_unparse (cttab.entries[i]),
265 cte->ctbase->contents.tid);
267 else
269 s = message ("%s%d\t%q\n", s, i, ctentry_unparse (cttab.entries[i]));
273 /*@noaccess ctbase@*/
274 return (s);
277 #if 0
278 void
279 cttable_print (void)
281 int i;
283 /*@access ctbase@*/
284 for (i = 0; i < cttab.size; i++)
286 /*drl bee: si*/ ctentry cte = cttab.entries[i];
288 if (TRUE) /* ctentry_isInteresting (cte)) */
290 if (ctbase_isUA (cte->ctbase))
292 fprintf (g_warningstream, "%3d: %s [%d]\n", i,
293 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
294 cte->ctbase->contents.tid);
296 else
298 fprintf (g_warningstream, "%3d: %s\n", i,
299 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
302 else
304 /* fprintf (g_warningstream, "%3d: <no name>\n", i); */
307 /*@noaccess ctbase@*/
309 #endif
312 ** cttable_dump
314 ** Output cttable for dump file
317 static void
318 cttable_dump (FILE *fout)
320 bool showdots = FALSE;
321 int showdotstride = 0;
322 int i;
324 if (context_getFlag (FLG_SHOWSCAN) && cttab.size > 5000)
326 displayScanClose ();
327 displayScanOpen (message ("Dumping type table (%d types)", cttab.size));
328 showdotstride = cttab.size / 5;
329 showdots = TRUE;
332 for (i = 0; i < cttab.size; i++)
334 cstring s;
336 /*drl bee: si*/ s = ctentry_dump (cttab.entries[i]);
337 DPRINTF (("[%d] = %s", i, ctentry_unparse (cttab.entries[i])));
338 llassert (cstring_length (s) < MAX_DUMP_LINE_LENGTH);
339 fputline (fout, cstring_toCharsSafe (s));
340 cstring_free (s);
342 if (showdots && (i != 0 && ((i - 1) % showdotstride == 0)))
344 (void) fflush (g_warningstream);
345 displayScanContinue (cstring_makeLiteralTemp ("."));
346 (void) fflush (stderr);
350 if (showdots)
352 displayScanClose ();
353 displayScanOpen (cstring_makeLiteral ("Continuing dump "));
359 ** load cttable from init file
362 static void cttable_load (FILE *f)
363 /*@globals cttab @*/
364 /*@modifies cttab, f @*/
366 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
367 char *os = s;
368 ctentry cte;
370 cttable_reset ();
373 DPRINTF (("Loading cttable: "));
374 cttable_print ();
377 while (reader_readLine (f, s, MAX_DUMP_LINE_LENGTH) != NULL && *s == ';')
382 if (mstring_length (s) == (MAX_DUMP_LINE_LENGTH - 1))
384 llbug (message ("Library line too long: %s\n", cstring_fromChars (s)));
387 while (s != NULL && *s != ';' && *s != '\0')
389 ctype ct;
391 /*drl bee: tcf*/ cte = ctentry_undump (s);
392 ct = cttable_addFull (cte);
394 DPRINTF (("Type: %d: %s", ct, ctype_unparse (ct)));
396 if (ctbase_isConj (cte->ctbase)
397 && !(ctbase_isExplicitConj (cte->ctbase)))
399 ctype_recordConj (ct);
402 s = reader_readLine (f, s, MAX_DUMP_LINE_LENGTH);
405 sfree (os);
408 DPRINTF (("Done loading cttable: "));
409 cttable_print ();
414 ** cttable_init
416 ** fill up the cttable with basic types, and first order derivations.
417 ** this is done without using our constructors for efficiency reasons
418 ** (probably bogus)
422 /*@access cprim@*/
423 static void cttable_init (void)
424 /*@globals cttab@*/ /*@modifies cttab@*/
426 ctkind i;
427 cprim j;
428 ctbase ct = ctbase_undefined;
430 llassert (cttab.size == 0);
432 /* do for plain, pointer, arrayof */
433 for (i = CTK_PLAIN; i <= CTK_ARRAY; i++)
435 for (j = CTX_UNKNOWN; j <= CTX_LAST; j++)
437 if (i == CTK_PLAIN)
439 if (j == CTX_BOOL)
441 ct = ctbase_createBool (); /* why different? */
443 else if (j == CTX_UNKNOWN)
445 ct = ctbase_createUnknown ();
447 else
449 ct = ctbase_createPrim ((cprim)j);
452 (void) cttable_addFull
453 (ctentry_make (CTK_PLAIN,
454 ct, ctype_undefined,
455 j + CTK_PREDEFINED, j + CTK_PREDEFINED2,
456 ctbase_unparse (ct)));
458 else
460 switch (i)
462 case CTK_PTR:
463 ct = ctbase_makePointer (j);
464 /*@switchbreak@*/ break;
465 case CTK_ARRAY:
466 ct = ctbase_makeArray (j);
467 /*@switchbreak@*/ break;
468 default:
469 llbugexitlit ("cttable_init: base case");
472 (void) cttable_addDerived (i, ct, j);
477 /**** reserve a slot for userBool ****/
478 (void) cttable_addFull (ctentry_make (CTK_INVALID, ctbase_undefined,
479 ctype_undefined, ctype_dne, ctype_dne,
480 cstring_undefined));
483 /*@noaccess cprim@*/
485 static void
486 cttable_grow (void)
488 int i;
489 o_ctentry *newentries ;
491 cttab.nspace = CTK_BASESIZE;
492 newentries = (ctentry *) dmalloc (sizeof (*newentries) * (cttab.size + cttab.nspace));
494 if (newentries == NULL)
496 llfatalerror (message ("cttable_grow: out of memory. Size: %d",
497 cttab.size));
500 for (i = 0; i < cttab.size; i++)
502 /*drl bee: dm*/ /*drl bee: si*/ newentries[i] = cttab.entries[i];
505 /*@-compdestroy@*/
506 sfree (cttab.entries);
507 /*@=compdestroy@*/
509 cttab.entries = newentries;
510 /*@-compdef@*/
511 } /*@=compdef@*/
513 static ctype
514 cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
516 if (cttab.nspace == 0)
517 cttable_grow ();
519 /*drl bee: si*/ cttab.entries[cttab.size] =
520 ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
522 cttab.nspace--;
524 return (cttab.size++);
527 static ctype
528 cttable_addComplex (/*@only@*/ ctbase cnew)
529 /*@modifies cttab; @*/
531 /*@access ctbase@*/
532 if (cnew->type != CT_FCN && cnew->type != CT_EXPFCN)
534 ctype i;
535 int ctstop = cttable_lastIndex () - DEFAULT_OPTLEVEL;
537 if (ctstop < LAST_PREDEFINED)
539 ctstop = LAST_PREDEFINED;
542 for (i = cttable_lastIndex (); i >= ctstop; i--) /* better to go from back... */
544 ctbase ctb;
546 ctb = ctype_getCtbase (i);
548 /* is this optimization really worthwhile? */
550 if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
552 DPRINTF (("EQUIV!! %s / %s",
553 ctbase_unparse (cnew),
554 ctbase_unparse (ctb)));
556 ctbase_free (cnew);
557 return i;
562 if (cttab.nspace == 0)
563 cttable_grow ();
565 /*drl bee: si*/ cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined,
566 ctype_dne, ctype_dne,
567 cstring_undefined);
568 cttab.nspace--;
570 return (cttab.size++);
571 /*@noaccess ctbase@*/
574 static ctype
575 cttable_addFull (ctentry cnew)
577 if (cttab.nspace == 0)
579 cttable_grow ();
582 /*drl bee: si*/ cttab.entries[cttab.size] = cnew;
583 cttab.nspace--;
585 return (cttab.size++);
588 static ctype
589 cttable_addFullSafe (/*@only@*/ ctentry cnew)
591 int i;
592 ctbase cnewbase = cnew->ctbase;
594 llassert (ctbase_isDefined (cnewbase));
596 for (i = cttable_lastIndex (); i >= CT_FIRST; i--)
598 ctbase ctb = ctype_getCtbase (i);
600 if (ctbase_isDefined (ctb)
601 && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
603 ctentry_free (cnew);
604 return i;
608 if (cttab.nspace == 0)
609 cttable_grow ();
611 /*drl bee: si*/ cttab.entries[cttab.size] = cnew;
613 cttab.nspace--;
615 return (cttab.size++);