]> andersk Git - splint.git/blob - src/cttable.i
Merged code tree with Dave Evans's version. Many changes to numberous to list....
[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 ctentry
66 ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
67 {
68   
69   return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
70 }
71
72 static /*@only@*/ ctentry
73 ctentry_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
88 static cstring
89 ctentry_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
99 static bool
100 ctentry_isInteresting (ctentry c)
101 {
102   return (cstring_isNonEmpty (c->unparse));
103 }
104
105 static /*@only@*/ cstring
106 ctentry_dump (ctentry c)
107 {
108   DPRINTF (("Dumping: %s", ctentry_unparse (c)));
109
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
153 static /*@only@*/ ctentry
154 ctentry_undump (/*@dependent@*/ char *s)
155 {
156   int base, ptr, array;
157   ctkind kind;
158   ctbase ct;
159
160   kind = ctkind_fromInt (reader_getInt (&s));
161   ct = ctbase_undump (&s);
162
163   if (reader_optCheckChar (&s, '&'))
164     {
165       base = ctype_dne;
166       ptr = ctype_dne;
167       array = ctype_dne;
168     }
169   else if (reader_optCheckChar (&s, '!'))
170     {
171       base = ctype_undefined;
172       ptr = ctype_dne;
173       array = ctype_dne;
174     }
175   else if (reader_optCheckChar (&s, '^'))
176     {
177       base = ctype_undefined;
178       ptr = reader_getInt (&s);
179       array = ctype_dne;
180     }
181   else
182     {
183       base = reader_getInt (&s);
184       
185       if (reader_optCheckChar (&s, '&'))
186         {
187           ptr = ctype_dne;
188           array = ctype_dne;
189         }
190       else
191         {
192           ptr = reader_getInt (&s);
193           array = reader_getInt (&s);
194         }
195     }
196
197   /* can't unparse w/o typeTable */
198   return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
199 }
200
201 static /*@observer@*/ cstring
202 ctentry_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
225 static /*@observer@*/ cstring
226 ctentry_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
243 static /*@only@*/ cstring
244 cttable_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
270 void
271 cttable_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
280       if (TRUE) /* ctentry_isInteresting (cte)) */
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
308 static void
309 cttable_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
323   /*
324   DPRINTF (("Dumping cttable: "));
325   cttable_print ();
326   */
327
328   for (i = 0; i < cttab.size; i++)
329     {
330       cstring s;
331
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));
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   
351 }
352
353 /*
354 ** load cttable from init file
355 */
356
357 static 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
366   /*
367   DPRINTF (("Loading cttable: "));
368   cttable_print ();
369   */
370
371   while (reader_readLine (f, s, MAX_DUMP_LINE_LENGTH) != NULL && *s == ';')
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
388       DPRINTF (("Type: %d: %s", ct, ctype_unparse (ct)));
389
390       if (ctbase_isConj (cte->ctbase)
391           && !(ctbase_isExplicitConj (cte->ctbase)))
392         {
393           ctype_recordConj (ct);
394         }
395
396       (void) reader_readLine (f, s, MAX_DUMP_LINE_LENGTH);
397     }
398
399   sfree (s);
400
401   /*
402   DPRINTF (("Done loading cttable: "));
403   cttable_print ();
404   */
405 }
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@*/
417 static 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
479 static void
480 cttable_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
507 static ctype
508 cttable_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
521 static ctype
522 cttable_addComplex (/*@only@*/ ctbase cnew)
523    /*@modifies cttab; @*/
524 {
525   /*@access ctbase@*/
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           
540           ctb = ctype_getCtbase (i);
541           
542           /*@i32 is this optimization really worthwhile??? */
543
544           if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
545             {
546               DPRINTF (("EQUIV!! %s / %s",
547                         ctbase_unparse (cnew),
548                         ctbase_unparse (ctb)));
549
550               ctbase_free (cnew);
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++);
565   /*@noaccess ctbase@*/
566 }
567
568 static ctype
569 cttable_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
582 static ctype
583 cttable_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.082715 seconds and 5 git commands to generate.