]> andersk Git - splint.git/blame - src/cttable.i
Added files
[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
65static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
66{
67 /*@+enumint@*/
68 if (c >= 0 && c < cttab.size)
69 {
70 return (cttab.entries[c]->ctbase);
71 }
72 else
73 {
74 if (c == CTK_UNKNOWN)
75 llbuglit ("ctype_getCtbase: ctype unknown");
76 if (c == CTK_INVALID)
77 llbuglit ("ctype_getCtbase: ctype invalid");
78 if (c == CTK_DNE)
79 llbuglit ("ctype_getCtbase: ctype dne");
80 if (c == CTK_ELIPS)
81 llbuglit ("ctype_getCtbase: elips marker");
82
83 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
84 BADEXIT;
85 }
86
87 /*@=enumint@*/
88}
89
90static /*@notnull@*/ /*@observer@*/ ctbase
91ctype_getCtbaseSafe (ctype c)
92{
93 ctbase res = ctype_getCtbase (c);
94
95 llassert (ctbase_isDefined (res));
96 return res;
97}
98
99/*
100** ctentry
101*/
102
103static ctentry
104ctype_getCtentry (ctype c)
105{
106 static /*@only@*/ ctentry errorEntry = NULL;
107
108 if (cttab.size == 0)
109 {
110 if (errorEntry == NULL)
111 {
112 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
113 }
114
115 return errorEntry;
116 }
117
118 /*@+enumint@*/
119 if (c >= CTK_PLAIN && c < cttab.size)
120 {
121 return (cttab.entries[c]);
122 }
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");
a0a162cd 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");
885824d3 133 else
134 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
135
136 return (cttab.entries[ctype_unknown]);
137 /*@=enumint@*/
138}
139
140static ctentry
141ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
142{
143
144 return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
145}
146
147static /*@only@*/ ctentry
148ctentry_make (ctkind ctk,
149 /*@keep@*/ ctbase c, ctype base,
150 ctype ptr, ctype array,
151 /*@keep@*/ cstring unparse) /*@*/
152{
153 ctentry cte = (ctentry) dmalloc (sizeof (*cte));
154 cte->kind = ctk;
155 cte->ctbase = c;
156 cte->base = base;
157 cte->ptr = ptr;
158 cte->array = array;
159 cte->unparse = unparse;
160 return cte;
161}
162
163static cstring
164ctentry_unparse (ctentry c)
165{
166 return (message
167 ("%20s [%d] [%d] [%d]",
168 (cstring_isDefined (c->unparse) ? c->unparse : cstring_makeLiteral ("<no name>")),
169 c->base,
170 c->ptr,
171 c->array));
172}
173
174static bool
175ctentry_isInteresting (ctentry c)
176{
177 return (cstring_isNonEmpty (c->unparse));
178}
179
180static /*@only@*/ cstring
181ctentry_dump (ctentry c)
182{
a0a162cd 183 DPRINTF (("Dumping: %s", ctentry_unparse (c)));
184
885824d3 185 if (c->ptr == ctype_dne
186 && c->array == ctype_dne
187 && c->base == ctype_dne)
188 {
189 return (message ("%d %q&",
190 ctkind_toInt (c->kind),
191 ctbase_dump (c->ctbase)));
192 }
193 else if (c->base == ctype_undefined
194 && c->array == ctype_dne)
195 {
196 if (c->ptr == ctype_dne)
197 {
198 return (message ("%d %q!",
199 ctkind_toInt (c->kind),
200 ctbase_dump (c->ctbase)));
201 }
202 else
203 {
204 return (message ("%d %q^%d",
205 ctkind_toInt (c->kind),
206 ctbase_dump (c->ctbase),
207 c->ptr));
208 }
209 }
210 else if (c->ptr == ctype_dne
211 && c->array == ctype_dne)
212 {
213 return (message ("%d %q%d&",
214 ctkind_toInt (c->kind),
215 ctbase_dump (c->ctbase),
216 c->base));
217 }
218 else
219 {
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));
224 }
225}
226
227
228static /*@only@*/ ctentry
229ctentry_undump (/*@dependent@*/ char *s)
230{
231 int base, ptr, array;
232 ctkind kind;
233 ctbase ct;
234
235 kind = ctkind_fromInt (getInt (&s));
236 ct = ctbase_undump (&s);
237
238 if (optCheckChar (&s, '&'))
239 {
240 base = ctype_dne;
241 ptr = ctype_dne;
242 array = ctype_dne;
243 }
244 else if (optCheckChar (&s, '!'))
245 {
246 base = ctype_undefined;
247 ptr = ctype_dne;
248 array = ctype_dne;
249 }
250 else if (optCheckChar (&s, '^'))
251 {
252 base = ctype_undefined;
253 ptr = getInt (&s);
254 array = ctype_dne;
255 }
256 else
257 {
258 base = getInt (&s);
259
260 if (optCheckChar (&s, '&'))
261 {
262 ptr = ctype_dne;
263 array = ctype_dne;
264 }
265 else
266 {
267 ptr = getInt (&s);
268 array = getInt (&s);
269 }
270 }
271
272 /* can't unparse w/o typeTable */
273 return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
274}
275
276static /*@observer@*/ cstring
277ctentry_doUnparse (ctentry c) /*@modifies c@*/
278{
279 if (cstring_isDefined (c->unparse))
280 {
281 return (c->unparse);
282 }
283 else
284 {
285 cstring s = ctbase_unparse (c->ctbase);
286
287 if (!cstring_isEmpty (s) && !cstring_containsChar (s, '<'))
288 {
289 c->unparse = s;
290 }
291 else
292 {
293 cstring_markOwned (s);
294 }
295
296 return (s);
297 }
298}
299
300static /*@observer@*/ cstring
301ctentry_doUnparseDeep (ctentry c)
302{
303 if (cstring_isDefined (c->unparse))
304 {
305 return (c->unparse);
306 }
307 else
308 {
309 c->unparse = ctbase_unparseDeep (c->ctbase);
310 return (c->unparse);
311 }
312}
313
314/*
315** cttable operations
316*/
317
318static /*@only@*/ cstring
319cttable_unparse (void)
320{
321 int i;
322 cstring s = cstring_undefined;
323
324 /*@access ctbase@*/
325 for (i = 0; i < cttab.size; i++)
326 {
327 ctentry cte = cttab.entries[i];
328 if (ctentry_isInteresting (cte))
329 {
330 if (ctbase_isUA (cte->ctbase))
331 {
332 s = message ("%s%d\t%q [%d]\n", s, i, ctentry_unparse (cttab.entries[i]),
333 cte->ctbase->contents.tid);
334 }
335 else
336 {
337 s = message ("%s%d\t%q\n", s, i, ctentry_unparse (cttab.entries[i]));
338 }
339 }
340 }
341 /*@noaccess ctbase@*/
342 return (s);
343}
344
345void
346cttable_print (void)
347{
348 int i;
349
350 /*@access ctbase@*/
351 for (i = 0; i < cttab.size; i++)
352 {
353 ctentry cte = cttab.entries[i];
354
355 if (ctentry_isInteresting (cte))
356 {
357 if (ctbase_isUA (cte->ctbase))
358 {
359 fprintf (g_msgstream, "%3d: %s [%d]\n", i,
360 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
361 cte->ctbase->contents.tid);
362 }
363 else
364 {
365 fprintf (g_msgstream, "%3d: %s\n", i,
366 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
367 }
368 }
369 else
370 {
371 /* fprintf (g_msgstream, "%3d: <no name>\n", i); */
372 }
373 }
374 /*@noaccess ctbase@*/
375}
376
377/*
378** cttable_dump
379**
380** Output cttable for dump file
381*/
382
383static void
384cttable_dump (FILE *fout)
385{
386 bool showdots = FALSE;
387 int showdotstride = 0;
388 int i;
389
390 if (context_getFlag (FLG_SHOWSCAN) && cttab.size > 5000)
391 {
392 fprintf (g_msgstream, " >\n"); /* end dumping to */
393 fprintf (g_msgstream, "< Dumping type table (%d types) ", cttab.size);
394 showdotstride = cttab.size / 5;
395 showdots = TRUE;
396 }
397
398 for (i = 0; i < cttab.size; i++)
399 {
400 cstring s;
401
402 s = ctentry_dump (cttab.entries[i]);
403 llassert (cstring_length (s) < MAX_DUMP_LINE_LENGTH);
404 fputline (fout, cstring_toCharsSafe (s));
405 cstring_free (s);
406
407 if (showdots && (i != 0 && ((i - 1) % showdotstride == 0)))
408 {
409 (void) fflush (g_msgstream);
410 fprintf (stderr, ".");
411 (void) fflush (stderr);
412 }
413 }
414
415 if (showdots)
416 {
417 fprintf (stderr, " >\n< Continuing dump ");
418 }
419
a0a162cd 420}
885824d3 421
422/*
423** load cttable from init file
424*/
425
426static void cttable_load (FILE *f)
427 /*@globals cttab @*/
428 /*@modifies cttab, f @*/
429{
430 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
431 ctentry cte;
432
433 cttable_reset ();
434
435 while (fgets (s, MAX_DUMP_LINE_LENGTH, f) != NULL && *s == ';')
436 {
437 ;
438 }
439
440 if (mstring_length (s) == (MAX_DUMP_LINE_LENGTH - 1))
441 {
442 llbug (message ("Library line too long: %s\n", cstring_fromChars (s)));
443 }
444
445 while (s != NULL && *s != ';' && *s != '\0')
446 {
447 ctype ct;
448
449 cte = ctentry_undump (s);
450 ct = cttable_addFull (cte);
451
452 if (ctbase_isConj (cte->ctbase)
453 && !(cte->ctbase->contents.conj->isExplicit))
454 {
455 ctype_recordConj (ct);
456 }
457
458 (void) fgets (s, MAX_DUMP_LINE_LENGTH, f);
459 }
460
461 sfree (s);
462 }
463
464/*
465** cttable_init
466**
467** fill up the cttable with basic types, and first order derivations.
468** this is done without using our constructors for efficiency reasons
469** (probably bogus)
470**
471*/
472
473/*@access cprim@*/
474static void cttable_init (void)
475 /*@globals cttab@*/ /*@modifies cttab@*/
476{
477 ctkind i;
478 cprim j;
479 ctbase ct = ctbase_undefined;
480
481 llassert (cttab.size == 0);
482
483 /* do for plain, pointer, arrayof */
484 for (i = CTK_PLAIN; i <= CTK_ARRAY; i++)
485 {
486 for (j = CTX_UNKNOWN; j <= CTX_LAST; j++)
487 {
488 if (i == CTK_PLAIN)
489 {
490 if (j == CTX_BOOL)
491 {
492 ct = ctbase_createBool (); /* why different? */
493 }
494 else if (j == CTX_UNKNOWN)
495 {
496 ct = ctbase_createUnknown ();
497 }
498 else
499 {
500 ct = ctbase_createPrim ((cprim)j);
501 }
502
503 (void) cttable_addFull
504 (ctentry_make (CTK_PLAIN,
505 ct, ctype_undefined,
506 j + CTK_PREDEFINED, j + CTK_PREDEFINED2,
507 ctbase_unparse (ct)));
508 }
509 else
510 {
511 switch (i)
512 {
513 case CTK_PTR:
514 ct = ctbase_makePointer (j);
515 /*@switchbreak@*/ break;
516 case CTK_ARRAY:
517 ct = ctbase_makeArray (j);
518 /*@switchbreak@*/ break;
519 default:
520 llbugexitlit ("cttable_init: base case");
521 }
522
523 (void) cttable_addDerived (i, ct, j);
524 }
525 }
526 }
527
528 /**** reserve a slot for userBool ****/
529 (void) cttable_addFull (ctentry_make (CTK_INVALID, ctbase_undefined,
530 ctype_undefined, ctype_dne, ctype_dne,
531 cstring_undefined));
532}
533
534/*@noaccess cprim@*/
535
536static void
537cttable_grow ()
538{
539 int i;
540 o_ctentry *newentries ;
541
542 cttab.nspace = CTK_BASESIZE;
543 newentries = (ctentry *) dmalloc (sizeof (*newentries) * (cttab.size + cttab.nspace));
544
545 if (newentries == NULL)
546 {
547 llfatalerror (message ("cttable_grow: out of memory. Size: %d",
548 cttab.size));
549 }
550
551 for (i = 0; i < cttab.size; i++)
552 {
553 newentries[i] = cttab.entries[i];
554 }
555
556 /*@-compdestroy@*/
557 sfree (cttab.entries);
558 /*@=compdestroy@*/
559
560 cttab.entries = newentries;
561/*@-compdef@*/
562} /*@=compdef@*/
563
564static ctype
565cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
566{
567 if (cttab.nspace == 0)
568 cttable_grow ();
569
570 cttab.entries[cttab.size] =
571 ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
572
573 cttab.nspace--;
574
575 return (cttab.size++);
576}
577
578static ctype
579cttable_addComplex (/*@only@*/ /*@notnull@*/ ctbase cnew)
580 /*@modifies cttab; @*/
581{
582 if (cnew->type != CT_FCN && cnew->type != CT_EXPFCN)
583 {
584 ctype i;
585 int ctstop = cttable_lastIndex () - DEFAULT_OPTLEVEL;
586
587 if (ctstop < LAST_PREDEFINED)
588 {
589 ctstop = LAST_PREDEFINED;
590 }
591
592 for (i = cttable_lastIndex (); i >= ctstop; i--) /* better to go from back... */
593 {
594 ctbase ctb;
595
885824d3 596 ctb = ctype_getCtbase (i);
597
598 if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
599 {
a0a162cd 600 DPRINTF (("EQUIV!! %s / %s",
601 ctbase_unparse (cnew),
602 ctbase_unparse (ctb)));
885824d3 603 ctbase_free (cnew);
885824d3 604 return i;
605 }
606 }
607 }
608
609 if (cttab.nspace == 0)
610 cttable_grow ();
611
612 cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined,
613 ctype_dne, ctype_dne,
614 cstring_undefined);
615 cttab.nspace--;
616
617 return (cttab.size++);
618}
619
620static ctype
621cttable_addFull (ctentry cnew)
622{
623 if (cttab.nspace == 0)
624 {
625 cttable_grow ();
626 }
627
628 cttab.entries[cttab.size] = cnew;
629 cttab.nspace--;
630
631 return (cttab.size++);
632}
633
634static ctype
635cttable_addFullSafe (/*@only@*/ ctentry cnew)
636{
637 int i;
638 ctbase cnewbase = cnew->ctbase;
639
640 llassert (ctbase_isDefined (cnewbase));
641
642 for (i = cttable_lastIndex (); i >= CT_FIRST; i--)
643 {
644 ctbase ctb = ctype_getCtbase (i);
645
646 if (ctbase_isDefined (ctb)
647 && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
648 {
649 ctentry_free (cnew);
650 return i;
651 }
652 }
653
654 if (cttab.nspace == 0)
655 cttable_grow ();
656
657 cttab.entries[cttab.size] = cnew;
658
659 cttab.nspace--;
660
661 return (cttab.size++);
662}
663
This page took 0.140436 seconds and 5 git commands to generate.