]> andersk Git - splint.git/blame - src/cttable.i
Cleaned up flags to generate manual help.
[splint.git] / src / cttable.i
CommitLineData
885824d3 1/* ;-*-C-*-;
2** Copyright (c) Massachusetts Institute of Technology 1994-1998.
3** All Rights Reserved.
4** Unpublished rights reserved under the copyright laws of
5** the United States.
6**
7** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8** OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
9**
10** This code is distributed freely and may be used freely under the
11** following conditions:
12**
13** 1. This notice may not be removed or altered.
14**
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).
18*/
19/*
20** cttable.i
21**
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.)
25*/
26
27/*@access ctype@*/
28
29/*
30** type definitions and forward declarations in ctbase.i
31*/
32
33static void
34ctentry_free (/*@only@*/ ctentry c)
35{
36 ctbase_free (c->ctbase);
37 cstring_free (c->unparse);
38 sfree (c);
39}
40
41static void cttable_reset (void)
42 /*@globals cttab@*/
43 /*@modifies cttab@*/
44{
45 if (cttab.entries != NULL)
46 {
47 int i;
48
49 for (i = 0; i < cttab.size; i++)
50 {
51 ctentry_free (cttab.entries[i]);
52 }
53
54 /*@-compdestroy@*/
55 sfree (cttab.entries);
56 /*@=compdestroy@*/
57
58 cttab.entries = NULL;
59 }
60
61 cttab.size = 0 ;
62 cttab.nspace = 0 ;
63}
64
885824d3 65static ctentry
66ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
67{
68
69 return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
70}
71
72static /*@only@*/ ctentry
73ctentry_make (ctkind ctk,
74 /*@keep@*/ ctbase c, ctype base,
75 ctype ptr, ctype array,
76 /*@keep@*/ cstring unparse) /*@*/
77{
78 ctentry cte = (ctentry) dmalloc (sizeof (*cte));
79 cte->kind = ctk;
80 cte->ctbase = c;
81 cte->base = base;
82 cte->ptr = ptr;
83 cte->array = array;
84 cte->unparse = unparse;
85 return cte;
86}
87
88static cstring
89ctentry_unparse (ctentry c)
90{
91 return (message
92 ("%20s [%d] [%d] [%d]",
93 (cstring_isDefined (c->unparse) ? c->unparse : cstring_makeLiteral ("<no name>")),
94 c->base,
95 c->ptr,
96 c->array));
97}
98
99static bool
100ctentry_isInteresting (ctentry c)
101{
102 return (cstring_isNonEmpty (c->unparse));
103}
104
105static /*@only@*/ cstring
106ctentry_dump (ctentry c)
107{
a0a162cd 108 DPRINTF (("Dumping: %s", ctentry_unparse (c)));
109
885824d3 110 if (c->ptr == ctype_dne
111 && c->array == ctype_dne
112 && c->base == ctype_dne)
113 {
114 return (message ("%d %q&",
115 ctkind_toInt (c->kind),
116 ctbase_dump (c->ctbase)));
117 }
118 else if (c->base == ctype_undefined
119 && c->array == ctype_dne)
120 {
121 if (c->ptr == ctype_dne)
122 {
123 return (message ("%d %q!",
124 ctkind_toInt (c->kind),
125 ctbase_dump (c->ctbase)));
126 }
127 else
128 {
129 return (message ("%d %q^%d",
130 ctkind_toInt (c->kind),
131 ctbase_dump (c->ctbase),
132 c->ptr));
133 }
134 }
135 else if (c->ptr == ctype_dne
136 && c->array == ctype_dne)
137 {
138 return (message ("%d %q%d&",
139 ctkind_toInt (c->kind),
140 ctbase_dump (c->ctbase),
141 c->base));
142 }
143 else
144 {
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));
149 }
150}
151
152
153static /*@only@*/ ctentry
154ctentry_undump (/*@dependent@*/ char *s)
155{
156 int base, ptr, array;
157 ctkind kind;
158 ctbase ct;
159
28bf4b0b 160 kind = ctkind_fromInt (reader_getInt (&s));
885824d3 161 ct = ctbase_undump (&s);
162
28bf4b0b 163 if (reader_optCheckChar (&s, '&'))
885824d3 164 {
165 base = ctype_dne;
166 ptr = ctype_dne;
167 array = ctype_dne;
168 }
28bf4b0b 169 else if (reader_optCheckChar (&s, '!'))
885824d3 170 {
171 base = ctype_undefined;
172 ptr = ctype_dne;
173 array = ctype_dne;
174 }
28bf4b0b 175 else if (reader_optCheckChar (&s, '^'))
885824d3 176 {
177 base = ctype_undefined;
28bf4b0b 178 ptr = reader_getInt (&s);
885824d3 179 array = ctype_dne;
180 }
181 else
182 {
28bf4b0b 183 base = reader_getInt (&s);
885824d3 184
28bf4b0b 185 if (reader_optCheckChar (&s, '&'))
885824d3 186 {
187 ptr = ctype_dne;
188 array = ctype_dne;
189 }
190 else
191 {
28bf4b0b 192 ptr = reader_getInt (&s);
193 array = reader_getInt (&s);
885824d3 194 }
195 }
196
197 /* can't unparse w/o typeTable */
198 return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
199}
200
201static /*@observer@*/ cstring
202ctentry_doUnparse (ctentry c) /*@modifies c@*/
203{
204 if (cstring_isDefined (c->unparse))
205 {
206 return (c->unparse);
207 }
208 else
209 {
210 cstring s = ctbase_unparse (c->ctbase);
211
212 if (!cstring_isEmpty (s) && !cstring_containsChar (s, '<'))
213 {
214 c->unparse = s;
215 }
216 else
217 {
218 cstring_markOwned (s);
219 }
220
221 return (s);
222 }
223}
224
225static /*@observer@*/ cstring
226ctentry_doUnparseDeep (ctentry c)
227{
228 if (cstring_isDefined (c->unparse))
229 {
230 return (c->unparse);
231 }
232 else
233 {
234 c->unparse = ctbase_unparseDeep (c->ctbase);
235 return (c->unparse);
236 }
237}
238
239/*
240** cttable operations
241*/
242
243static /*@only@*/ cstring
244cttable_unparse (void)
245{
246 int i;
247 cstring s = cstring_undefined;
248
249 /*@access ctbase@*/
250 for (i = 0; i < cttab.size; i++)
251 {
252 ctentry cte = cttab.entries[i];
253 if (ctentry_isInteresting (cte))
254 {
255 if (ctbase_isUA (cte->ctbase))
256 {
257 s = message ("%s%d\t%q [%d]\n", s, i, ctentry_unparse (cttab.entries[i]),
258 cte->ctbase->contents.tid);
259 }
260 else
261 {
262 s = message ("%s%d\t%q\n", s, i, ctentry_unparse (cttab.entries[i]));
263 }
264 }
265 }
266 /*@noaccess ctbase@*/
267 return (s);
268}
269
270void
271cttable_print (void)
272{
273 int i;
274
275 /*@access ctbase@*/
276 for (i = 0; i < cttab.size; i++)
277 {
278 ctentry cte = cttab.entries[i];
279
28bf4b0b 280 if (TRUE) /* ctentry_isInteresting (cte)) */
885824d3 281 {
282 if (ctbase_isUA (cte->ctbase))
283 {
284 fprintf (g_msgstream, "%3d: %s [%d]\n", i,
285 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
286 cte->ctbase->contents.tid);
287 }
288 else
289 {
290 fprintf (g_msgstream, "%3d: %s\n", i,
291 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
292 }
293 }
294 else
295 {
296 /* fprintf (g_msgstream, "%3d: <no name>\n", i); */
297 }
298 }
299 /*@noaccess ctbase@*/
300}
301
302/*
303** cttable_dump
304**
305** Output cttable for dump file
306*/
307
308static void
309cttable_dump (FILE *fout)
310{
311 bool showdots = FALSE;
312 int showdotstride = 0;
313 int i;
314
315 if (context_getFlag (FLG_SHOWSCAN) && cttab.size > 5000)
316 {
317 fprintf (g_msgstream, " >\n"); /* end dumping to */
318 fprintf (g_msgstream, "< Dumping type table (%d types) ", cttab.size);
319 showdotstride = cttab.size / 5;
320 showdots = TRUE;
321 }
322
28bf4b0b 323 /*
324 DPRINTF (("Dumping cttable: "));
325 cttable_print ();
326 */
327
885824d3 328 for (i = 0; i < cttab.size; i++)
329 {
330 cstring s;
331
332 s = ctentry_dump (cttab.entries[i]);
28bf4b0b 333 DPRINTF (("[%d] = %s", i, ctentry_unparse (cttab.entries[i])));
885824d3 334 llassert (cstring_length (s) < MAX_DUMP_LINE_LENGTH);
335 fputline (fout, cstring_toCharsSafe (s));
336 cstring_free (s);
337
338 if (showdots && (i != 0 && ((i - 1) % showdotstride == 0)))
339 {
340 (void) fflush (g_msgstream);
341 fprintf (stderr, ".");
342 (void) fflush (stderr);
343 }
344 }
345
346 if (showdots)
347 {
348 fprintf (stderr, " >\n< Continuing dump ");
349 }
350
a0a162cd 351}
885824d3 352
353/*
354** load cttable from init file
355*/
356
357static void cttable_load (FILE *f)
358 /*@globals cttab @*/
359 /*@modifies cttab, f @*/
360{
361 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
362 ctentry cte;
363
364 cttable_reset ();
365
28bf4b0b 366 /*
367 DPRINTF (("Loading cttable: "));
368 cttable_print ();
369 */
370
371 while (reader_readLine (f, s, MAX_DUMP_LINE_LENGTH) != NULL && *s == ';')
885824d3 372 {
373 ;
374 }
375
376 if (mstring_length (s) == (MAX_DUMP_LINE_LENGTH - 1))
377 {
378 llbug (message ("Library line too long: %s\n", cstring_fromChars (s)));
379 }
380
381 while (s != NULL && *s != ';' && *s != '\0')
382 {
383 ctype ct;
384
385 cte = ctentry_undump (s);
386 ct = cttable_addFull (cte);
387
28bf4b0b 388 DPRINTF (("Type: %d: %s", ct, ctype_unparse (ct)));
389
885824d3 390 if (ctbase_isConj (cte->ctbase)
28bf4b0b 391 && !(ctbase_isExplicitConj (cte->ctbase)))
885824d3 392 {
393 ctype_recordConj (ct);
394 }
395
28bf4b0b 396 (void) reader_readLine (f, s, MAX_DUMP_LINE_LENGTH);
885824d3 397 }
398
399 sfree (s);
28bf4b0b 400
401 /*
402 DPRINTF (("Done loading cttable: "));
403 cttable_print ();
404 */
405}
885824d3 406
407/*
408** cttable_init
409**
410** fill up the cttable with basic types, and first order derivations.
411** this is done without using our constructors for efficiency reasons
412** (probably bogus)
413**
414*/
415
416/*@access cprim@*/
417static void cttable_init (void)
418 /*@globals cttab@*/ /*@modifies cttab@*/
419{
420 ctkind i;
421 cprim j;
422 ctbase ct = ctbase_undefined;
423
424 llassert (cttab.size == 0);
425
426 /* do for plain, pointer, arrayof */
427 for (i = CTK_PLAIN; i <= CTK_ARRAY; i++)
428 {
429 for (j = CTX_UNKNOWN; j <= CTX_LAST; j++)
430 {
431 if (i == CTK_PLAIN)
432 {
433 if (j == CTX_BOOL)
434 {
435 ct = ctbase_createBool (); /* why different? */
436 }
437 else if (j == CTX_UNKNOWN)
438 {
439 ct = ctbase_createUnknown ();
440 }
441 else
442 {
443 ct = ctbase_createPrim ((cprim)j);
444 }
445
446 (void) cttable_addFull
447 (ctentry_make (CTK_PLAIN,
448 ct, ctype_undefined,
449 j + CTK_PREDEFINED, j + CTK_PREDEFINED2,
450 ctbase_unparse (ct)));
451 }
452 else
453 {
454 switch (i)
455 {
456 case CTK_PTR:
457 ct = ctbase_makePointer (j);
458 /*@switchbreak@*/ break;
459 case CTK_ARRAY:
460 ct = ctbase_makeArray (j);
461 /*@switchbreak@*/ break;
462 default:
463 llbugexitlit ("cttable_init: base case");
464 }
465
466 (void) cttable_addDerived (i, ct, j);
467 }
468 }
469 }
470
471 /**** reserve a slot for userBool ****/
472 (void) cttable_addFull (ctentry_make (CTK_INVALID, ctbase_undefined,
473 ctype_undefined, ctype_dne, ctype_dne,
474 cstring_undefined));
475}
476
477/*@noaccess cprim@*/
478
479static void
480cttable_grow ()
481{
482 int i;
483 o_ctentry *newentries ;
484
485 cttab.nspace = CTK_BASESIZE;
486 newentries = (ctentry *) dmalloc (sizeof (*newentries) * (cttab.size + cttab.nspace));
487
488 if (newentries == NULL)
489 {
490 llfatalerror (message ("cttable_grow: out of memory. Size: %d",
491 cttab.size));
492 }
493
494 for (i = 0; i < cttab.size; i++)
495 {
496 newentries[i] = cttab.entries[i];
497 }
498
499 /*@-compdestroy@*/
500 sfree (cttab.entries);
501 /*@=compdestroy@*/
502
503 cttab.entries = newentries;
504/*@-compdef@*/
505} /*@=compdef@*/
506
507static ctype
508cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
509{
510 if (cttab.nspace == 0)
511 cttable_grow ();
512
513 cttab.entries[cttab.size] =
514 ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
515
516 cttab.nspace--;
517
518 return (cttab.size++);
519}
520
521static ctype
28bf4b0b 522cttable_addComplex (/*@only@*/ ctbase cnew)
885824d3 523 /*@modifies cttab; @*/
524{
28bf4b0b 525 /*@access ctbase@*/
885824d3 526 if (cnew->type != CT_FCN && cnew->type != CT_EXPFCN)
527 {
528 ctype i;
529 int ctstop = cttable_lastIndex () - DEFAULT_OPTLEVEL;
530
531 if (ctstop < LAST_PREDEFINED)
532 {
533 ctstop = LAST_PREDEFINED;
534 }
535
536 for (i = cttable_lastIndex (); i >= ctstop; i--) /* better to go from back... */
537 {
538 ctbase ctb;
539
885824d3 540 ctb = ctype_getCtbase (i);
28bf4b0b 541
542 /*@i32 is this optimization really worthwhile??? */
885824d3 543
544 if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
545 {
a0a162cd 546 DPRINTF (("EQUIV!! %s / %s",
547 ctbase_unparse (cnew),
548 ctbase_unparse (ctb)));
28bf4b0b 549
885824d3 550 ctbase_free (cnew);
885824d3 551 return i;
552 }
553 }
554 }
555
556 if (cttab.nspace == 0)
557 cttable_grow ();
558
559 cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined,
560 ctype_dne, ctype_dne,
561 cstring_undefined);
562 cttab.nspace--;
563
564 return (cttab.size++);
28bf4b0b 565 /*@noaccess ctbase@*/
885824d3 566}
567
568static ctype
569cttable_addFull (ctentry cnew)
570{
571 if (cttab.nspace == 0)
572 {
573 cttable_grow ();
574 }
575
576 cttab.entries[cttab.size] = cnew;
577 cttab.nspace--;
578
579 return (cttab.size++);
580}
581
582static ctype
583cttable_addFullSafe (/*@only@*/ ctentry cnew)
584{
585 int i;
586 ctbase cnewbase = cnew->ctbase;
587
588 llassert (ctbase_isDefined (cnewbase));
589
590 for (i = cttable_lastIndex (); i >= CT_FIRST; i--)
591 {
592 ctbase ctb = ctype_getCtbase (i);
593
594 if (ctbase_isDefined (ctb)
595 && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
596 {
597 ctentry_free (cnew);
598 return i;
599 }
600 }
601
602 if (cttab.nspace == 0)
603 cttable_grow ();
604
605 cttab.entries[cttab.size] = cnew;
606
607 cttab.nspace--;
608
609 return (cttab.size++);
610}
611
This page took 0.131377 seconds and 5 git commands to generate.