]> andersk Git - splint.git/blob - src/cttable.i
Finshed basic merge. Still trying to get it through the test suit.
[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 if (c == CTK_ELIPS) 
130     llcontbuglit ("ctype_getCtentry: ctype elipsis");
131   else if (c == CTK_MISSINGPARAMS) 
132     llcontbuglit ("ctype_getCtentry: ctype missing params");
133   else
134     llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
135
136   return (cttab.entries[ctype_unknown]);
137   /*@=enumint@*/
138 }
139
140 static ctentry
141 ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
142 {
143   
144   return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
145 }
146
147 static /*@only@*/ ctentry
148 ctentry_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
163 static cstring
164 ctentry_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
174 static bool
175 ctentry_isInteresting (ctentry c)
176 {
177   return (cstring_isNonEmpty (c->unparse));
178 }
179
180 static /*@only@*/ cstring
181 ctentry_dump (ctentry c)
182 {
183   DPRINTF (("Dumping: %s", ctentry_unparse (c)));
184
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
228 static /*@only@*/ ctentry
229 ctentry_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
276 static /*@observer@*/ cstring
277 ctentry_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
300 static /*@observer@*/ cstring
301 ctentry_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
318 static /*@only@*/ cstring
319 cttable_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
345 void
346 cttable_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
383 static void
384 cttable_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   
420 }
421
422 /*
423 ** load cttable from init file
424 */
425
426 static 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@*/
474 static 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
536 static void
537 cttable_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
564 static ctype
565 cttable_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
578 static ctype
579 cttable_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           
596           ctb = ctype_getCtbase (i);
597
598           if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
599             {
600               DPRINTF (("EQUIV!! %s / %s",
601                         ctbase_unparse (cnew),
602                         ctbase_unparse (ctb)));
603               ctbase_free (cnew);
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
620 static ctype
621 cttable_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
634 static ctype
635 cttable_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.370533 seconds and 5 git commands to generate.