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