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);
65 static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
68 if (c >= 0 && c < cttab.size)
70 return (cttab.entries[c]->ctbase);
75 llbuglit ("ctype_getCtbase: ctype unknown");
77 llbuglit ("ctype_getCtbase: ctype invalid");
79 llbuglit ("ctype_getCtbase: ctype dne");
81 llbuglit ("ctype_getCtbase: elips marker");
83 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
90 static /*@notnull@*/ /*@observer@*/ ctbase
91 ctype_getCtbaseSafe (ctype c)
93 ctbase res = ctype_getCtbase (c);
95 llassert (ctbase_isDefined (res));
104 ctype_getCtentry (ctype c)
106 static /*@only@*/ ctentry errorEntry = NULL;
110 if (errorEntry == NULL)
112 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
119 if (c >= CTK_PLAIN && c < cttab.size)
121 return (cttab.entries[c]);
123 else if (c == CTK_UNKNOWN)
124 llcontbuglit ("ctype_getCtentry: ctype unknown");
125 else if (c == CTK_INVALID)
126 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
127 else if (c == CTK_DNE)
128 llcontbuglit ("ctype_getCtentry: ctype dne");
129 else if (c == CTK_ELIPS)
130 llcontbuglit ("ctype_getCtentry: ctype elipsis");
131 else if (c == CTK_MISSINGPARAMS)
132 llcontbuglit ("ctype_getCtentry: ctype missing params");
134 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
136 return (cttab.entries[ctype_unknown]);
141 ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
144 return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
147 static /*@only@*/ ctentry
148 ctentry_make (ctkind ctk,
149 /*@keep@*/ ctbase c, ctype base,
150 ctype ptr, ctype array,
151 /*@keep@*/ cstring unparse) /*@*/
153 ctentry cte = (ctentry) dmalloc (sizeof (*cte));
159 cte->unparse = unparse;
164 ctentry_unparse (ctentry c)
167 ("%20s [%d] [%d] [%d]",
168 (cstring_isDefined (c->unparse) ? c->unparse : cstring_makeLiteral ("<no name>")),
175 ctentry_isInteresting (ctentry c)
177 return (cstring_isNonEmpty (c->unparse));
180 static /*@only@*/ cstring
181 ctentry_dump (ctentry c)
183 DPRINTF (("Dumping: %s", ctentry_unparse (c)));
185 if (c->ptr == ctype_dne
186 && c->array == ctype_dne
187 && c->base == ctype_dne)
189 return (message ("%d %q&",
190 ctkind_toInt (c->kind),
191 ctbase_dump (c->ctbase)));
193 else if (c->base == ctype_undefined
194 && c->array == ctype_dne)
196 if (c->ptr == ctype_dne)
198 return (message ("%d %q!",
199 ctkind_toInt (c->kind),
200 ctbase_dump (c->ctbase)));
204 return (message ("%d %q^%d",
205 ctkind_toInt (c->kind),
206 ctbase_dump (c->ctbase),
210 else if (c->ptr == ctype_dne
211 && c->array == ctype_dne)
213 return (message ("%d %q%d&",
214 ctkind_toInt (c->kind),
215 ctbase_dump (c->ctbase),
220 return (message ("%d %q%d %d %d",
221 ctkind_toInt (c->kind),
222 ctbase_dump (c->ctbase),
223 c->base, c->ptr, c->array));
228 static /*@only@*/ ctentry
229 ctentry_undump (/*@dependent@*/ char *s)
231 int base, ptr, array;
235 kind = ctkind_fromInt (getInt (&s));
236 ct = ctbase_undump (&s);
238 if (optCheckChar (&s, '&'))
244 else if (optCheckChar (&s, '!'))
246 base = ctype_undefined;
250 else if (optCheckChar (&s, '^'))
252 base = ctype_undefined;
260 if (optCheckChar (&s, '&'))
272 /* can't unparse w/o typeTable */
273 return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
276 static /*@observer@*/ cstring
277 ctentry_doUnparse (ctentry c) /*@modifies c@*/
279 if (cstring_isDefined (c->unparse))
285 cstring s = ctbase_unparse (c->ctbase);
287 if (!cstring_isEmpty (s) && !cstring_containsChar (s, '<'))
293 cstring_markOwned (s);
300 static /*@observer@*/ cstring
301 ctentry_doUnparseDeep (ctentry c)
303 if (cstring_isDefined (c->unparse))
309 c->unparse = ctbase_unparseDeep (c->ctbase);
315 ** cttable operations
318 static /*@only@*/ cstring
319 cttable_unparse (void)
322 cstring s = cstring_undefined;
325 for (i = 0; i < cttab.size; i++)
327 ctentry cte = cttab.entries[i];
328 if (ctentry_isInteresting (cte))
330 if (ctbase_isUA (cte->ctbase))
332 s = message ("%s%d\t%q [%d]\n", s, i, ctentry_unparse (cttab.entries[i]),
333 cte->ctbase->contents.tid);
337 s = message ("%s%d\t%q\n", s, i, ctentry_unparse (cttab.entries[i]));
341 /*@noaccess ctbase@*/
351 for (i = 0; i < cttab.size; i++)
353 ctentry cte = cttab.entries[i];
355 if (ctentry_isInteresting (cte))
357 if (ctbase_isUA (cte->ctbase))
359 fprintf (g_msgstream, "%3d: %s [%d]\n", i,
360 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
361 cte->ctbase->contents.tid);
365 fprintf (g_msgstream, "%3d: %s\n", i,
366 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
371 /* fprintf (g_msgstream, "%3d: <no name>\n", i); */
374 /*@noaccess ctbase@*/
380 ** Output cttable for dump file
384 cttable_dump (FILE *fout)
386 bool showdots = FALSE;
387 int showdotstride = 0;
390 if (context_getFlag (FLG_SHOWSCAN) && cttab.size > 5000)
392 fprintf (g_msgstream, " >\n"); /* end dumping to */
393 fprintf (g_msgstream, "< Dumping type table (%d types) ", cttab.size);
394 showdotstride = cttab.size / 5;
398 for (i = 0; i < cttab.size; i++)
402 s = ctentry_dump (cttab.entries[i]);
403 llassert (cstring_length (s) < MAX_DUMP_LINE_LENGTH);
404 fputline (fout, cstring_toCharsSafe (s));
407 if (showdots && (i != 0 && ((i - 1) % showdotstride == 0)))
409 (void) fflush (g_msgstream);
410 fprintf (stderr, ".");
411 (void) fflush (stderr);
417 fprintf (stderr, " >\n< Continuing dump ");
423 ** load cttable from init file
426 static void cttable_load (FILE *f)
428 /*@modifies cttab, f @*/
430 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
435 while (fgets (s, MAX_DUMP_LINE_LENGTH, f) != NULL && *s == ';')
440 if (mstring_length (s) == (MAX_DUMP_LINE_LENGTH - 1))
442 llbug (message ("Library line too long: %s\n", cstring_fromChars (s)));
445 while (s != NULL && *s != ';' && *s != '\0')
449 cte = ctentry_undump (s);
450 ct = cttable_addFull (cte);
452 if (ctbase_isConj (cte->ctbase)
453 && !(cte->ctbase->contents.conj->isExplicit))
455 ctype_recordConj (ct);
458 (void) fgets (s, MAX_DUMP_LINE_LENGTH, f);
467 ** fill up the cttable with basic types, and first order derivations.
468 ** this is done without using our constructors for efficiency reasons
474 static void cttable_init (void)
475 /*@globals cttab@*/ /*@modifies cttab@*/
479 ctbase ct = ctbase_undefined;
481 llassert (cttab.size == 0);
483 /* do for plain, pointer, arrayof */
484 for (i = CTK_PLAIN; i <= CTK_ARRAY; i++)
486 for (j = CTX_UNKNOWN; j <= CTX_LAST; j++)
492 ct = ctbase_createBool (); /* why different? */
494 else if (j == CTX_UNKNOWN)
496 ct = ctbase_createUnknown ();
500 ct = ctbase_createPrim ((cprim)j);
503 (void) cttable_addFull
504 (ctentry_make (CTK_PLAIN,
506 j + CTK_PREDEFINED, j + CTK_PREDEFINED2,
507 ctbase_unparse (ct)));
514 ct = ctbase_makePointer (j);
515 /*@switchbreak@*/ break;
517 ct = ctbase_makeArray (j);
518 /*@switchbreak@*/ break;
520 llbugexitlit ("cttable_init: base case");
523 (void) cttable_addDerived (i, ct, j);
528 /**** reserve a slot for userBool ****/
529 (void) cttable_addFull (ctentry_make (CTK_INVALID, ctbase_undefined,
530 ctype_undefined, ctype_dne, ctype_dne,
540 o_ctentry *newentries ;
542 cttab.nspace = CTK_BASESIZE;
543 newentries = (ctentry *) dmalloc (sizeof (*newentries) * (cttab.size + cttab.nspace));
545 if (newentries == NULL)
547 llfatalerror (message ("cttable_grow: out of memory. Size: %d",
551 for (i = 0; i < cttab.size; i++)
553 newentries[i] = cttab.entries[i];
557 sfree (cttab.entries);
560 cttab.entries = newentries;
565 cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
567 if (cttab.nspace == 0)
570 cttab.entries[cttab.size] =
571 ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
575 return (cttab.size++);
579 cttable_addComplex (/*@only@*/ /*@notnull@*/ ctbase cnew)
580 /*@modifies cttab; @*/
582 if (cnew->type != CT_FCN && cnew->type != CT_EXPFCN)
585 int ctstop = cttable_lastIndex () - DEFAULT_OPTLEVEL;
587 if (ctstop < LAST_PREDEFINED)
589 ctstop = LAST_PREDEFINED;
592 for (i = cttable_lastIndex (); i >= ctstop; i--) /* better to go from back... */
596 ctb = ctype_getCtbase (i);
598 if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
600 DPRINTF (("EQUIV!! %s / %s",
601 ctbase_unparse (cnew),
602 ctbase_unparse (ctb)));
609 if (cttab.nspace == 0)
612 cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined,
613 ctype_dne, ctype_dne,
617 return (cttab.size++);
621 cttable_addFull (ctentry cnew)
623 if (cttab.nspace == 0)
628 cttab.entries[cttab.size] = cnew;
631 return (cttab.size++);
635 cttable_addFullSafe (/*@only@*/ ctentry cnew)
638 ctbase cnewbase = cnew->ctbase;
640 llassert (ctbase_isDefined (cnewbase));
642 for (i = cttable_lastIndex (); i >= CT_FIRST; i--)
644 ctbase ctb = ctype_getCtbase (i);
646 if (ctbase_isDefined (ctb)
647 && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
654 if (cttab.nspace == 0)
657 cttab.entries[cttab.size] = cnew;
661 return (cttab.size++);