2 ** Copyright (c) Massachusetts Institute of Technology 1994-1998.
3 ** All Rights Reserved.
4 ** Unpublished rights reserved under the copyright laws of
7 ** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8 ** OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
10 ** This code is distributed freely and may be used freely under the
11 ** following conditions:
13 ** 1. This notice may not be removed or altered.
15 ** 2. Works derived from this code are not distributed for
16 ** commercial gain without explicit permission from MIT
17 ** (for permission contact lclint-request@sds.lcs.mit.edu).
22 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
23 ** (This is necessary becuase there is no other way in C to have a
24 ** hidden scope, besides at the file level.)
30 ** type definitions and forward declarations in ctbase.i
34 ctentry_free (/*@only@*/ ctentry c)
36 ctbase_free (c->ctbase);
37 cstring_free (c->unparse);
41 static void cttable_reset (void)
45 if (cttab.entries != NULL)
49 for (i = 0; i < cttab.size; i++)
51 ctentry_free (cttab.entries[i]);
55 sfree (cttab.entries);
66 ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
69 return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
72 static /*@only@*/ ctentry
73 ctentry_make (ctkind ctk,
74 /*@keep@*/ ctbase c, ctype base,
75 ctype ptr, ctype array,
76 /*@keep@*/ cstring unparse) /*@*/
78 ctentry cte = (ctentry) dmalloc (sizeof (*cte));
84 cte->unparse = unparse;
89 ctentry_unparse (ctentry c)
92 ("%20s [%d] [%d] [%d]",
93 (cstring_isDefined (c->unparse) ? c->unparse : cstring_makeLiteral ("<no name>")),
100 ctentry_isInteresting (ctentry c)
102 return (cstring_isNonEmpty (c->unparse));
105 static /*@only@*/ cstring
106 ctentry_dump (ctentry c)
108 DPRINTF (("Dumping: %s", ctentry_unparse (c)));
110 if (c->ptr == ctype_dne
111 && c->array == ctype_dne
112 && c->base == ctype_dne)
114 return (message ("%d %q&",
115 ctkind_toInt (c->kind),
116 ctbase_dump (c->ctbase)));
118 else if (c->base == ctype_undefined
119 && c->array == ctype_dne)
121 if (c->ptr == ctype_dne)
123 return (message ("%d %q!",
124 ctkind_toInt (c->kind),
125 ctbase_dump (c->ctbase)));
129 return (message ("%d %q^%d",
130 ctkind_toInt (c->kind),
131 ctbase_dump (c->ctbase),
135 else if (c->ptr == ctype_dne
136 && c->array == ctype_dne)
138 return (message ("%d %q%d&",
139 ctkind_toInt (c->kind),
140 ctbase_dump (c->ctbase),
145 return (message ("%d %q%d %d %d",
146 ctkind_toInt (c->kind),
147 ctbase_dump (c->ctbase),
148 c->base, c->ptr, c->array));
153 static /*@only@*/ ctentry
154 ctentry_undump (/*@dependent@*/ char *s)
156 int base, ptr, array;
160 kind = ctkind_fromInt (reader_getInt (&s));
161 ct = ctbase_undump (&s);
163 if (reader_optCheckChar (&s, '&'))
169 else if (reader_optCheckChar (&s, '!'))
171 base = ctype_undefined;
175 else if (reader_optCheckChar (&s, '^'))
177 base = ctype_undefined;
178 ptr = reader_getInt (&s);
183 base = reader_getInt (&s);
185 if (reader_optCheckChar (&s, '&'))
192 ptr = reader_getInt (&s);
193 array = reader_getInt (&s);
197 /* can't unparse w/o typeTable */
198 return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
201 static /*@observer@*/ cstring
202 ctentry_doUnparse (ctentry c) /*@modifies c@*/
204 if (cstring_isDefined (c->unparse))
210 cstring s = ctbase_unparse (c->ctbase);
212 if (!cstring_isEmpty (s) && !cstring_containsChar (s, '<'))
218 cstring_markOwned (s);
225 static /*@observer@*/ cstring
226 ctentry_doUnparseDeep (ctentry c)
228 if (cstring_isDefined (c->unparse))
234 c->unparse = ctbase_unparseDeep (c->ctbase);
240 ** cttable operations
243 static /*@only@*/ cstring
244 cttable_unparse (void)
247 cstring s = cstring_undefined;
250 for (i = 0; i < cttab.size; i++)
252 ctentry cte = cttab.entries[i];
253 if (ctentry_isInteresting (cte))
255 if (ctbase_isUA (cte->ctbase))
257 s = message ("%s%d\t%q [%d]\n", s, i, ctentry_unparse (cttab.entries[i]),
258 cte->ctbase->contents.tid);
262 s = message ("%s%d\t%q\n", s, i, ctentry_unparse (cttab.entries[i]));
266 /*@noaccess ctbase@*/
276 for (i = 0; i < cttab.size; i++)
278 ctentry cte = cttab.entries[i];
280 if (TRUE) /* ctentry_isInteresting (cte)) */
282 if (ctbase_isUA (cte->ctbase))
284 fprintf (g_msgstream, "%3d: %s [%d]\n", i,
285 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
286 cte->ctbase->contents.tid);
290 fprintf (g_msgstream, "%3d: %s\n", i,
291 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
296 /* fprintf (g_msgstream, "%3d: <no name>\n", i); */
299 /*@noaccess ctbase@*/
305 ** Output cttable for dump file
309 cttable_dump (FILE *fout)
311 bool showdots = FALSE;
312 int showdotstride = 0;
315 if (context_getFlag (FLG_SHOWSCAN) && cttab.size > 5000)
317 fprintf (g_msgstream, " >\n"); /* end dumping to */
318 fprintf (g_msgstream, "< Dumping type table (%d types) ", cttab.size);
319 showdotstride = cttab.size / 5;
324 DPRINTF (("Dumping cttable: "));
328 for (i = 0; i < cttab.size; i++)
332 s = ctentry_dump (cttab.entries[i]);
333 DPRINTF (("[%d] = %s", i, ctentry_unparse (cttab.entries[i])));
334 llassert (cstring_length (s) < MAX_DUMP_LINE_LENGTH);
335 fputline (fout, cstring_toCharsSafe (s));
338 if (showdots && (i != 0 && ((i - 1) % showdotstride == 0)))
340 (void) fflush (g_msgstream);
341 fprintf (stderr, ".");
342 (void) fflush (stderr);
348 fprintf (stderr, " >\n< Continuing dump ");
354 ** load cttable from init file
357 static void cttable_load (FILE *f)
359 /*@modifies cttab, f @*/
361 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
367 DPRINTF (("Loading cttable: "));
371 while (reader_readLine (f, s, MAX_DUMP_LINE_LENGTH) != NULL && *s == ';')
376 if (mstring_length (s) == (MAX_DUMP_LINE_LENGTH - 1))
378 llbug (message ("Library line too long: %s\n", cstring_fromChars (s)));
381 while (s != NULL && *s != ';' && *s != '\0')
385 cte = ctentry_undump (s);
386 ct = cttable_addFull (cte);
388 DPRINTF (("Type: %d: %s", ct, ctype_unparse (ct)));
390 if (ctbase_isConj (cte->ctbase)
391 && !(ctbase_isExplicitConj (cte->ctbase)))
393 ctype_recordConj (ct);
396 (void) reader_readLine (f, s, MAX_DUMP_LINE_LENGTH);
402 DPRINTF (("Done loading cttable: "));
410 ** fill up the cttable with basic types, and first order derivations.
411 ** this is done without using our constructors for efficiency reasons
417 static void cttable_init (void)
418 /*@globals cttab@*/ /*@modifies cttab@*/
422 ctbase ct = ctbase_undefined;
424 llassert (cttab.size == 0);
426 /* do for plain, pointer, arrayof */
427 for (i = CTK_PLAIN; i <= CTK_ARRAY; i++)
429 for (j = CTX_UNKNOWN; j <= CTX_LAST; j++)
435 ct = ctbase_createBool (); /* why different? */
437 else if (j == CTX_UNKNOWN)
439 ct = ctbase_createUnknown ();
443 ct = ctbase_createPrim ((cprim)j);
446 (void) cttable_addFull
447 (ctentry_make (CTK_PLAIN,
449 j + CTK_PREDEFINED, j + CTK_PREDEFINED2,
450 ctbase_unparse (ct)));
457 ct = ctbase_makePointer (j);
458 /*@switchbreak@*/ break;
460 ct = ctbase_makeArray (j);
461 /*@switchbreak@*/ break;
463 llbugexitlit ("cttable_init: base case");
466 (void) cttable_addDerived (i, ct, j);
471 /**** reserve a slot for userBool ****/
472 (void) cttable_addFull (ctentry_make (CTK_INVALID, ctbase_undefined,
473 ctype_undefined, ctype_dne, ctype_dne,
483 o_ctentry *newentries ;
485 cttab.nspace = CTK_BASESIZE;
486 newentries = (ctentry *) dmalloc (sizeof (*newentries) * (cttab.size + cttab.nspace));
488 if (newentries == NULL)
490 llfatalerror (message ("cttable_grow: out of memory. Size: %d",
494 for (i = 0; i < cttab.size; i++)
496 newentries[i] = cttab.entries[i];
500 sfree (cttab.entries);
503 cttab.entries = newentries;
508 cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
510 if (cttab.nspace == 0)
513 cttab.entries[cttab.size] =
514 ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
518 return (cttab.size++);
522 cttable_addComplex (/*@only@*/ ctbase cnew)
523 /*@modifies cttab; @*/
526 if (cnew->type != CT_FCN && cnew->type != CT_EXPFCN)
529 int ctstop = cttable_lastIndex () - DEFAULT_OPTLEVEL;
531 if (ctstop < LAST_PREDEFINED)
533 ctstop = LAST_PREDEFINED;
536 for (i = cttable_lastIndex (); i >= ctstop; i--) /* better to go from back... */
540 ctb = ctype_getCtbase (i);
542 /*@i32 is this optimization really worthwhile??? */
544 if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
546 DPRINTF (("EQUIV!! %s / %s",
547 ctbase_unparse (cnew),
548 ctbase_unparse (ctb)));
556 if (cttab.nspace == 0)
559 cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined,
560 ctype_dne, ctype_dne,
564 return (cttab.size++);
565 /*@noaccess ctbase@*/
569 cttable_addFull (ctentry cnew)
571 if (cttab.nspace == 0)
576 cttab.entries[cttab.size] = cnew;
579 return (cttab.size++);
583 cttable_addFullSafe (/*@only@*/ ctentry cnew)
586 ctbase cnewbase = cnew->ctbase;
588 llassert (ctbase_isDefined (cnewbase));
590 for (i = cttable_lastIndex (); i >= CT_FIRST; i--)
592 ctbase ctb = ctype_getCtbase (i);
594 if (ctbase_isDefined (ctb)
595 && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
602 if (cttab.nspace == 0)
605 cttab.entries[cttab.size] = cnew;
609 return (cttab.size++);