Move the sources to trunk
[opencv] / apps / Hawk / CVEiCL / EiC / src / symbol.c
1 /* symbol.c
2  *
3  *      (C) Copyright Apr 15 1995, Edmond J. Breen.
4  *                 ALL RIGHTS RESERVED.
5  * This code may be copied for personal, non-profit use only.
6  *
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "typemod.h"
14 #include "MachSet.h"
15 #include  "global.h"
16 #include "lexer.h"
17 #include "xalloc.h"
18 #include "preproc.h"
19 #include "symbol.h"
20 #include "parser.h"
21
22
23
24 int EiC_iskeyword(keyword_t *keywords,char*id,int n)
25 {
26     int i;
27     for(i=0;i<n;i++)
28         if(strcmp(keywords[i].id,id) == 0)
29             return keywords[i].token;
30     return 0;
31 }
32
33 #define MoD 2
34 void EiC_eicpush(eicstack_t *s, val_t v)
35 {
36     if(!(s->n%MoD)) {
37         if(!s->n)
38             s->val = (val_t*)xcalloc(sizeof(val_t),MoD);
39         else
40             s->val = (val_t*)xrealloc(s->val,(s->n+MoD)*sizeof(val_t));
41     }
42     s->val[s->n] = v;
43     s->n++;
44 }
45
46 int EiC_eicpop(eicstack_t *s, val_t *pop)
47 {
48     if(s->n == 0)
49         return 0;
50     s->n--;
51     *pop = s->val[s->n];
52     if(!(s->n%MoD)) {           
53         if(!s->n)
54             xfree(s->val);
55         else
56             s->val = (val_t*)xrealloc(s->val,s->n*sizeof(val_t));
57     }
58     return 1;
59 }
60
61
62 /* LOOK UP TABLE ROUTINES
63    --------------------------*/
64
65 static size_t _EnTrY_No = 0;
66 int hashsmc(char * s,int mod);
67 symentry_t *EiC_HTAB[HSIZE];
68
69
70 /* code for generating tempories */
71 unsigned int NumTemps=0, CurTemp =0;
72
73 symentry_t * EiC_nxtTemp(int obj, int level)
74 {
75     symentry_t *sym;
76     char tmpName[50];
77     sprintf(tmpName,"%s%d","__TeMp",NumTemps);
78
79     /* There should be no need to watch out for change of level !!!!
80      * It will be assumed that the compound statement routine will
81      * handle it.
82      */
83
84
85     sym = EiC_insertLUT(EiC_work_tab,tmpName,obj);
86     NumTemps++;
87
88     CurTemp++;
89
90     if(sym->val.ival == -1) /* needs a home */ 
91         EiC_stackit(sym,level);
92
93     /* Setting up the token information is left
94      * to the caller of this routine.
95      */
96
97     sym->level = level;
98     return sym;
99 }    
100
101
102
103 size_t EiC_lut_NextEntryNum(void)
104 {
105     return _EnTrY_No;
106 }
107                              /*CUT EiChashFunc*/
108 int hashsmc(char * s,int mod)
109 {
110     register unsigned int h, c;
111     h = 0;
112     while(  (c = (int) *s++) > 0)
113         h =   (h << 1) + c;
114     return ( h % mod);
115 }
116                            /*END CUT*/
117
118                             /*CUT lutLookUp*/
119 int Pclash;
120
121 char *EiC_getClashedfname(char nspace,char *id)
122 {
123     symentry_t *sym;
124     for(sym = EiC_HTAB[hashsmc(id,HSIZE)]; sym != NULL; sym = sym->next)
125         if(sym->nspace == nspace && strcmp(id,sym->id) == 0)
126             if((sym->sclass & c_private) &&
127                sym->fname != CurrentFileName()) {
128                 return sym->fname;
129             }
130     return NULL;
131 }
132
133 symentry_t * EiC_lookup(char nspace, char *id)
134 {
135     symentry_t *sym;
136     Pclash = 0;
137     for(sym = EiC_HTAB[hashsmc(id,HSIZE)]; sym != NULL; sym = sym->next)
138         if(sym->nspace == nspace && strcmp(id,sym->id) == 0) {
139             if((sym->sclass & c_private) &&
140                sym->fname != CurrentFileName()) {
141                 Pclash = 1;
142                 continue;
143             }
144             else
145                 break;
146         }
147
148     return(sym);
149 }
150                              /*END CUT*/
151
152                            /*CUT lutInsert*/
153 symentry_t * EiC_insertLUT(char nspace,char *id,int type)
154 {
155     symentry_t *sym;
156     auto int  hashval;
157
158     sym = (symentry_t *) xcalloc(1,sizeof(symentry_t));
159     if(sym == NULL)
160         return(NULL);
161     if( (sym->id = EiC_strsave(id)) == NULL) {
162         xfree(sym);
163         return(NULL);
164     }
165     sym->entry = _EnTrY_No++;
166     hashval = hashsmc(sym->id,HSIZE);
167     sym->next = EiC_HTAB[hashval];
168     EiC_HTAB[hashval] = sym;
169     sym->nspace = nspace;
170     sym->val.ival = -1;         /* indicates  unused */
171     sym->type = EiC_addtype(type,NULL);
172     sym->fname =  CurrentFileName();
173     return(sym);
174 }
175                            /*END CUT*/
176
177 void delete(symentry_t *sym)
178 {
179     auto symentry_t * this;
180     auto int idx;
181     
182     idx = hashsmc(sym->id,HSIZE);
183     this = EiC_HTAB[idx];
184     if(this == sym)
185         EiC_HTAB[idx] = sym->next;
186     else {                      /* find and unlink  */
187         while(this && this->next != sym)
188             this = this->next;
189         this->next = sym->next;
190     }
191 }
192
193 void EiC_UpdateSymPos(symentry_t * sym)
194 {
195
196     if(sym->next && sym->next->level > sym->level) {
197         symentry_t * p = EiC_HTAB[hashsmc(sym->id,HSIZE)];
198         delete(sym);
199         while(p->next != sym)
200             if(p->next) {
201                 if(p->next->level > sym->level)
202                     p=p->next;
203                 else {
204                     sym->next = p->next;
205                     p->next = sym;
206                 }
207             } else {
208                 p->next = sym;
209                 sym->next = NULL;
210             }
211     }
212 }
213
214 void EiC_remsym(symentry_t *sym)
215 {
216
217   delete(sym);
218   free_sym(sym);
219
220 }
221 /*END CUT*/
222
223 #if 1
224 void remBuiltin(symentry_t *sym)
225 {
226     /* removes the prototype of the builtin function only */
227     EiC_freetype(sym->type);
228     sym->type = EiC_addtype(t_builtin,NULL);
229     sym->fname = "::EiC::";
230 }
231 #endif
232
233
234 /*CUT lutRemLevel*/
235 void EiC_remlevel(int level)
236 {
237   int i;
238   symentry_t * sym, *symh;
239
240   for(i=0;i<HSIZE;i++) {
241     sym = EiC_HTAB[i];
242     while(sym && sym->level >= level) {
243       symh = sym->next;
244       free_sym(sym);
245       sym = symh;
246     }
247     EiC_HTAB[i] = sym;
248   }
249 }
250 /*END CUT*/
251 /*CUT lutRemTempories*/
252 void EiC_remTempories(void)
253 {
254   int i;
255   symentry_t * sym, *symh;
256
257   for(i=0;i<HSIZE;i++) {
258     sym = EiC_HTAB[i];
259     while(sym && IsTemp(sym->type)) {
260       symh = sym->next;
261       free_sym(sym);
262       sym = symh;
263     }
264     EiC_HTAB[i] = sym;
265   }
266 }
267 /*END CUT*/
268
269
270
271 int  EiC_lutClearFileEntries(char *FileName)
272 {
273
274     int i;
275     symentry_t * sym, *p, *t;
276
277     for(i=0;i<HSIZE;i++) {
278         t = sym = EiC_HTAB[i];
279         p = NULL;
280         while(sym){
281             if(strcmp(sym->fname,FileName) == 0) {
282                 if(p)
283                     p->next = sym->next;
284                 else
285                     t = sym->next;
286                 free_sym(sym);
287                 if(!p) {
288                     sym = t;
289                     continue;
290                 }
291             } else
292                 p = sym;
293             sym=p->next;
294         }
295         EiC_HTAB[i] = t;
296     }
297     return 1;
298
299 }
300                     /*END CUT*/
301                      /*CUT lutCleanUp*/
302
303 void EiC_lut_CleanUp(size_t bot)
304 {
305
306     int i;
307     symentry_t * sym, *p, *t;
308     for(i=0;i<HSIZE;i++) {
309         t = sym = EiC_HTAB[i];
310         p = NULL;
311         while(sym){
312             if(sym->entry >= bot) {
313                 if(EiC_gettype(sym->type) == t_builtin) {
314                     remBuiltin(sym);
315                     p = sym;
316                 } else {
317                     if(p)
318                         p->next = sym->next;
319                     else
320                         t = sym->next;
321                     free_sym(sym);
322                     if(!p) {
323                         sym = t;
324                         continue;
325                     }
326                 }
327             } else
328                 p = sym;
329             sym=p->next;
330         }
331         EiC_HTAB[i] = t;
332     }
333
334 }
335                      /*END CUT*/
336                      /*CUT lutFreeSym*/
337
338 #define freeAg(X)   do {\
339                             symentry_t *x = X; \
340                             if(!isconst(x->type)) \
341                                  xfree(EiC_ENV->AR[x->val.ival].v.p.p);\
342                             else xfree(x->val.p.p);\
343                     } while (0)
344
345
346 #define freeAg1(X)  xfree(EiC_ENV->AR[X->val.ival].v.p.p)
347
348
349 static void free_sym(symentry_t *sym)
350 {
351
352 #if 0    
353       printf("Freeing [%s] %d  %d [%d]\n",
354         sym->id, sym->entry, sym->val.ival,EiC_gettype(sym->type));
355     
356 #endif    
357     
358     if(EiC_gettype(sym->type) == t_func) {
359         EiC_killcode(sym);
360     } else if(sym->level == 1)  { /* global value */
361         int t;
362         if((t=EiC_gettype(sym->type)) == t_array && sym->val.ival >=0) 
363             freeAg(sym);
364         else if ((t== t_union || t == t_struct) && sym->val.ival >=0 ) 
365             freeAg(sym);
366                 
367     }
368
369
370     /*
371      * the conditions for pushing  onto the ARgar stack
372      * must be the same as those for stacking as found in
373      * function establish_id
374      * Except for ParseError
375      */
376     if( sym->val.ival >=0
377        && sym->level == 1
378        && EiC_gettype(sym->type) != t_builtin ) {
379         if(! isconst(sym->type)
380            && sym->nspace == stand_tab
381            && sym->sclass != c_typedef) {
382             EiC_eicpush(&EiC_ENV->ARgar,sym->val);
383         }
384     }
385     EiC_freetype(sym->type);
386     xfree(sym->id);
387     xfree(sym);
388 }
389                         /*END CUT*/
390
391 void EiC_UpdateEntry(symentry_t *sym)
392 {
393     int t = EiC_gettype(sym->type);
394     if(CurrentFileName() != sym->fname &&
395        t != t_func &&
396        t != t_funcdec &&
397        t != t_builtin)
398         return;
399     sym->entry =  _EnTrY_No++;
400     sym->pname = sym->fname;
401     sym->fname = CurrentFileName();
402 }
403
404 void EiC_addoffsettolevel(char nspace,int level,int off)
405 {
406     int i;
407     symentry_t * sym;
408
409     for(i=0;i<HSIZE;i++) {
410         sym = EiC_HTAB[i];
411         while(sym && sym->level == level && sym->nspace == nspace) {
412             sym->val.ival = -(sym->val.ival + off);
413             sym = sym->next;
414         }
415     }
416 }
417
418 void EiC_marktype(type_expr *type, char mark)
419 {
420     int i;
421     struct_t *s;
422     void EiC_markFunc(type_expr *t,int mark);
423     
424     while(type) {
425         xmark(type,mark);
426         switch(EiC_gettype(type)) {
427           case t_builtin:
428             if(EiC_getInf(type) == NULL)
429                 break;
430           case t_funcdec:
431           case t_func:
432             EiC_markFunc(type,mark);
433             break;
434           case t_union:
435           case t_struct:
436             if(type->alias)
437                 break;
438             s = EiC_getInf(type);
439             /*
440              * REM must allow for incomplete
441              * types.
442              */
443             if(!s)
444                 break;
445             xmark(s,mark);
446             if(!s->cl)
447                 break;
448             xmark(s->offset,mark);
449             xmark(s->id,mark);
450             xmark(s->type,mark);
451             for(i=0;i<s->n;i++) {
452                 xmark(s->id[i],mark);
453                 EiC_marktype(s->type[i],mark);
454             }
455             if(s->ntags) {
456                 xmark(s->tag,mark);
457                 for(i=0;i<s->ntags;++i)
458                     EiC_marktype(s->tag[i],mark);
459             }
460             break;
461         }
462         type = nextType(type);
463     }
464 }
465
466 static void marklabel(Label_t *l,char mark) 
467 {
468     while(l) {
469         xmark(l,mark);
470         xmark(l->name,mark);
471         l = l->nxt;
472     }
473 }
474
475 static void markcode(symentry_t *sym,char mark)
476 {
477     int i;
478     InsT_t *inst;
479     code_t * code;
480     code = EiC_ENV->AR[sym->val.ival].v.p.p;
481     xmark(code,mark);
482     xmark(code->inst,mark);
483     marklabel(code->labels,mark);
484     marklabel(code->gotos,mark);
485
486     inst = code->inst;
487     for(i=0;i<code->nextinst;i++,inst++)
488         if(inst->opcode == jmptab) {
489             eicstack_t * s;
490             s = inst->val.p.p;
491             xmark(s->val,mark);
492             xmark(s,mark);
493         } else if(inst->opcode == assigntype)
494             EiC_marktype(inst->val.p.p,mark);
495 }
496
497
498 void EiC_marksyms(char mark)
499 {
500     void EiC_markmacros(char);
501     void EiC_markENV(char);
502     
503     int i;
504     symentry_t * sym;
505
506     EiC_markmacros(mark);
507     
508     if(EiC_ENV->AR)
509         xmark(EiC_ENV->AR,mark);
510     if(EiC_ENV->ARgar.n) 
511         xmark(EiC_ENV->ARgar.val,mark);
512     if(EiC_ENV->LAR)
513         xmark(EiC_ENV->LAR,mark);
514     if(EiC_ENV->CODE.nextinst)
515         xmark(EiC_ENV->CODE.inst,mark);
516     xmark(EiC_ENV,mark);
517
518     EiC_markENV(mark);
519     
520     for(i=0;i<HSIZE;i++) {
521         sym = EiC_HTAB[i];
522         while(sym) {
523             /*printf("marking %s\n",sym->id);*/
524             if(strcmp(sym->id,"p") == 0)
525               sym->id = sym->id;
526             xmark(sym,mark);
527             xmark(sym->id,mark);
528             EiC_marktype(sym->type,mark);           
529             if(sym->nspace != tag_tab)
530                 switch(EiC_gettype(sym->type)) {
531                   case t_func: markcode(sym,mark); break;
532                   case t_array:
533                   case t_union:
534                   case t_struct:
535                     if(isconst(sym->type))
536                        xmark(sym->val.p.p,mark);
537                     else
538                         if(sym->sclass != c_typedef && sym->val.ival >= 0)
539                             xmark(EiC_ENV->AR[sym->val.ival].v.p.p,mark);
540                     break;
541                 }
542             sym = sym->next;
543         }
544     }
545 }
546
547
548 char * EiC_strsave(char *s)
549 {
550     char *p;
551     int n;
552
553     for(n = 0,p =s; *p != '\0';++p,++n)
554         ;
555     n++;
556     p = xcalloc(n,sizeof(char));
557     if(p) 
558         while((*p++ = *s++));
559     return p - n;
560 }
561
562 void EiC_newsymtype(symentry_t *sym, type_expr *t)
563 {
564     if(sym) {
565         if(sym->type && sym->type != t)
566             EiC_freetype(sym->type);
567         sym->type = t;
568     }
569 }
570
571 int nextstackitem(int level)
572 {
573     if(level == 1) {            /* static variables */
574         val_t v;
575         if(!EiC_eicpop(&EiC_ENV->ARgar,&v))  { /* check for spare slots */
576             if(EiC_ENV->sp == EiC_ENV->ARsize) {
577                 if(!EiC_ENV->ARsize)
578                     EiC_ENV->AR = (AR_t*)xcalloc(sizeof(AR_t),1);
579                 else
580                     EiC_ENV->AR = (AR_t*)xrealloc(EiC_ENV->AR,
581                                               (EiC_ENV->sp+1)*sizeof(AR_t));
582                 EiC_ENV->ARsize++;
583             }
584             v.ival = EiC_ENV->sp;
585             EiC_ENV->sp++;
586         }
587         return v.ival;
588     } else {                    /* automatic variables */
589         if(EiC_ENV->lsp == EiC_ENV->LARsize) {
590             if(!EiC_ENV->LARsize)
591                 EiC_ENV->LAR = (AR_t*)xcalloc(sizeof(AR_t),1);
592             else
593                 EiC_ENV->LAR = (AR_t*)xrealloc(EiC_ENV->LAR,(EiC_ENV->lsp+1)*
594                                            sizeof(AR_t));
595             EiC_ENV->LARsize++;
596         }
597         EiC_ENV->lsp++;
598         return EiC_ENV->lsp - 1;
599     }
600 }
601
602 int EiC_stackit(symentry_t * sym,int level)
603 {
604     int i;
605     AR_t * ar;
606     
607     i = nextstackitem(level);
608     if(level == 1)              /* static variables */
609         ar = EiC_ENV->AR;
610     else                        /* local variable */    
611         ar = EiC_ENV->LAR;
612
613     sym->val.ival = i;
614
615     ar[i].v.dval = 0; /* NULL it */
616     ar[i].type = sym->type;
617     return i;
618 }
619
620
621 /*------------------------------------------------*/
622 void EiC_inittoken(token_t * e1)
623 {
624     e1->Pflag = 0;
625     e1->Code.binst = e1->Code.nextinst = 0;
626     e1->Code.labels = e1->Code.gotos = NULL;
627     e1->Typequal = e1->Sclass = 0;
628     e1->Sym = NULL;
629     e1->Val.sym = NULL;
630     e1->Type = NULL;
631 }
632 void EiC_freetoken(token_t * e1)
633 {
634     EiC_freetype(e1->Type);
635     e1->Type = NULL;
636 }
637 void initcode(code_t * code)
638 {
639     code->binst = code->nextinst = 0;
640 }
641
642
643 void EiC_cleancode(code_t * code)
644 {
645     unsigned int i;
646     InsT_t *inst;
647
648     if(!code)
649         return;
650     inst = code->inst;
651     /* printf("Next instr: %d\n", code->nextinst); */
652     /* rem free up other info also */
653     for(i=0;i<code->nextinst;i++,inst++)
654         if(inst->opcode == jmptab) {
655             eicstack_t *s;
656             s = inst->val.p.p;
657             xfree(s->val);
658             xfree(s);
659         } else if(inst->opcode == assigntype)
660             EiC_freetype(inst->val.p.p);
661
662 }    
663
664 static void freeCodeLabels(code_t *code)
665 {
666     void EiCp_freeLabels(Label_t *lab);
667     if(code->labels) {
668         EiCp_freeLabels(code->labels);
669         code->labels = NULL;
670     }
671     if(code->gotos) {
672         EiCp_freeLabels(code->gotos);
673         code->gotos = NULL;
674     }
675 }
676
677 void EiC_killcode(symentry_t *sym)
678 {
679     code_t * code;
680     code = EiC_ENV->AR[sym->val.ival].v.p.p;
681     if(!code)
682         return;
683     EiC_cleancode(code);
684     freeCodeLabels(code);
685     xfree(code->inst);
686     xfree(code);
687 }
688 void EiC_freecode(code_t * code)
689 {
690
691     if(code && code->binst > 0) {
692         xfree(code->inst);
693         code->nextinst = code->binst = 0;
694         freeCodeLabels(code);
695     }
696 }
697
698 #define ModSize 5
699
700 void EiC_generate(code_t * code, int opcode,val_t *val,int ext)
701 {
702     InsT_t * inst;
703     inst = code->inst;
704     if(code->nextinst == code->binst)
705         if(!(code->binst%ModSize)) {
706             if(!code->binst)
707                 inst = (InsT_t*)xcalloc(1,sizeof(InsT_t)*ModSize);
708             else
709                 inst = (InsT_t*)
710                     xrealloc(inst,(code->binst+ModSize)*sizeof(InsT_t));
711             code->binst += ModSize;
712         }
713     code->inst = inst;
714     inst[code->nextinst].opcode = opcode;
715     inst[code->nextinst].val = *val;
716     inst[code->nextinst].ext = ext;
717     inst[code->nextinst].line = CurrentLineNo();
718     code->nextinst++;
719 }
720
721 #if 0
722 void copycode(code_t * c1, code_t * c2)
723 {
724     /* this function needs to handle label and gotos */
725     unsigned int i;
726     InsT_t *inst;
727     inst = c2->inst;
728     for(i=0;i<c2->nextinst;++i,++inst) {
729         EiC_generate(c1,inst->opcode,&inst->val,inst->ext);
730         c1->inst[c1->nextinst-1].line = inst->line;
731     }
732 }
733 #else
734 void copycode(code_t * c1, code_t * c2)
735 {
736     Label_t * EiCp_addLabel(Label_t *, char *, int, int);
737     InsT_t *inst;
738     int h, Tsize;
739     Label_t *lab;
740
741     if(!c2->nextinst)
742         return;
743     /* concatenate labels*/
744     if(c2->labels) {
745         lab = c2->labels;
746         while(lab) {
747             c1->labels = EiCp_addLabel(c1->labels,lab->name,lab->loc+c1->nextinst,1);
748             lab = lab->nxt;
749         }
750     }
751     /* conatenate gotos */
752     if(c2->gotos) {
753         lab = c2->gotos;
754         while(lab) {
755             c1->gotos = EiCp_addLabel(c1->gotos,lab->name,lab->loc+c1->nextinst,0);
756             lab = lab->nxt;
757         }
758     }
759
760     Tsize = c1->nextinst + c2->nextinst;
761     /* make memory size a multiple of ModSize */
762     h = Tsize;
763     if(Tsize%ModSize) 
764         Tsize += ModSize - (Tsize%ModSize);
765     if(c1->binst)
766         c1->inst = xrealloc(c1->inst,Tsize*sizeof(InsT_t));
767     else
768         c1->inst = xcalloc(Tsize,sizeof(InsT_t));
769     inst = c1->inst;
770     memcpy(&inst[c1->nextinst], c2->inst, c2->nextinst * sizeof(InsT_t));
771     c1->binst = Tsize;
772     c1->nextinst = h;
773 }
774
775 #endif
776
777 void EiC_concode(code_t * c1, code_t * c2)
778 {
779     copycode(c1,c2);
780     EiC_freecode(c2);
781 }
782 void EiC_contoken(token_t * e1, token_t * e2)
783 {
784     EiC_concode(&e1->Code,&e2->Code);
785     e1->Type = EiC_getcontype(e1->Type,e2->Type);
786     EiC_freetoken(e2);
787 }
788
789 void EiC_swaptokens(token_t *e1, token_t * e2)
790 {
791     token_t e3;
792     e3 = *e2;
793     *e2 = *e1;
794     *e1 = e3;
795 }
796     
797
798 #if 0
799
800 typedef struct list_t {
801     char * fname;
802     struct list_t *nxt;
803 }list_t;
804
805
806 typdef struct llist_t {
807     list_t **list;
808     int n;
809 } llist_t;
810
811 static llist_t ** includes = NULL, ** included = NULL;
812
813 static int inllist(llist_t **list, char *fname)
814 {
815     /* returns -1 if not in list */
816     int i;
817     for(i=0;i<list->n,++i) {
818         if(fname == list->list[i]->fname == 0)
819             return i;
820     }
821     return -1;
822 }
823
824 static list_t * add2list(list_t *list, char *fname)
825 {
826    list_t n = calloc(sizeof(list_t),1);
827    n->fname = fname;
828    n->nxt = list;
829    return n;
830 }
831
832
833 static void add2includes(char *file, char * includes)
834 {
835     int i = inlist(includes,file);
836
837     if(i < 0) {
838         i = includes->n;
839         includes->list = realloc(includes->list, 
840                                  (includes->n + 1) * sizeof(*includes->list));
841         
842         includes->list = 
843         includes
844
845
846
847
848
849 #endif
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866