8ff43f183551df88f512313543b97d1ab7cc590a
[fw/sdcc] / src / SDCCsymt.c
1 /*-------------------------------------------------------------------------
2   SDCCsymt.c - Code file for Symbols table related structures and MACRO's.              
3               Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any
8    later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18    
19    In other words, you are welcome to use, share and improve this program.
20    You are forbidden to forbid anyone else to use, share and improve
21    what you give them.   Help stamp out software-hoarding!  
22 -------------------------------------------------------------------------*/
23
24 #include "common.h"
25
26 bucket   *SymbolTab [256]  ;  /* the symbol    table  */
27 bucket   *StructTab [256]  ;  /* the structure table  */
28 bucket   *TypedefTab[256]  ;  /* the typedef   table  */
29 bucket   *LabelTab  [256]  ;  /* the Label     table  */
30 bucket   *enumTab   [256]  ;  /* enumerated    table  */
31
32 /*------------------------------------------------------------------*/
33 /* initSymt () - initialises symbol table related stuff             */
34 /*------------------------------------------------------------------*/
35 void  initSymt ()
36 {
37    int i = 0 ;
38
39    for ( i = 0 ; i < 256 ; i++ )
40       SymbolTab[i] = StructTab[i] = (void *) NULL ;
41    
42    
43 }
44 /*-----------------------------------------------------------------*/
45 /* newBucket - allocates & returns a new bucket                    */
46 /*-----------------------------------------------------------------*/
47 bucket   *newBucket ()
48 {
49         bucket *bp ;
50               
51         ALLOC(bp,sizeof(bucket));
52         
53         return bp ;
54 }
55
56 /*-----------------------------------------------------------------*/
57 /* hashKey - computes the hashkey given a symbol name              */
58 /*-----------------------------------------------------------------*/
59 int hashKey (const char *s)
60 {
61     unsigned long key = 0;
62
63     while (*s)
64         key += *s++ ;
65     return key % 256 ;
66 }
67
68 /*-----------------------------------------------------------------*/
69 /* addSym - adds a symbol to the hash Table                        */
70 /*-----------------------------------------------------------------*/
71 void  addSym ( bucket **stab , 
72                void *sym     , 
73                char *sname   , 
74                int level     , 
75                int block)
76 {
77     int i ;       /* index into the hash Table */
78     bucket   *bp ; /* temp bucket    *         */
79     
80     /* the symbols are always added at the head of the list  */
81     i = hashKey(sname) ;      
82     /* get a free entry */
83     ALLOC(bp,sizeof(bucket));
84     
85     bp->sym = sym ;     /* update the symbol pointer  */
86     bp->level = level;   /* update the nest level      */   
87     bp->block = block;
88     strcpy(bp->name,sname);     /* copy the name into place     */
89     
90     /* if this is the first entry */
91     if (stab[i] == NULL) {
92         bp->prev = bp->next = (void *) NULL ;  /* point to nothing */
93         stab[i] = bp ;
94     }
95     /* not first entry then add @ head of list */
96     else {       
97         bp->prev      = NULL ;
98         stab[i]->prev = bp ;
99         bp->next      = stab[i] ;
100         stab[i]       = bp ;
101     }
102 }
103
104 /*-----------------------------------------------------------------*/
105 /* deleteSym - deletes a symbol from the hash Table  entry         */
106 /*-----------------------------------------------------------------*/
107 void  deleteSym ( bucket **stab, void *sym, char *sname)
108 {
109     int i = 0 ;
110     bucket *bp ;
111     
112     i = hashKey(sname) ;
113     
114     bp = stab[i] ;
115     /* find the symbol */
116     while (bp) {
117         if (bp->sym == sym)  /* found it then break out */
118             break ;        /* of the loop             */
119         bp = bp->next ;
120     }
121     
122     if (!bp)   /* did not find it */
123         return ;
124     /* if this is the first one in the chain */
125     if ( ! bp->prev ) {
126         stab[i] = bp->next ;
127         if ( stab[i] ) /* if chain ! empty */
128             stab[i]->prev = (void *) NULL ;
129     }
130     /* middle || end of chain */
131     else {
132         if ( bp->next ) /* if not end of chain */
133             bp->next->prev = bp->prev ;
134         
135         bp->prev->next = bp->next ;
136     }
137
138 }
139
140 /*-----------------------------------------------------------------*/
141 /* findSym - finds a symbol in a table                             */
142 /*-----------------------------------------------------------------*/
143 void  *findSym ( bucket **stab, void *sym, const char *sname)
144 {
145    bucket *bp ;
146
147    bp = stab[hashKey(sname)] ;
148    while (bp)
149    {
150       if ( bp->sym == sym || strcmp (bp->name,sname) == 0 )
151               break ;
152       bp = bp->next ;
153    }
154
155    return ( bp ? bp->sym : (void *) NULL ) ;
156 }
157
158 /*-----------------------------------------------------------------*/
159 /* findSymWithLevel - finds a symbol with a name & level           */
160 /*-----------------------------------------------------------------*/
161 void *findSymWithLevel ( bucket **stab, symbol *sym)
162 {
163   bucket *bp ;
164
165   bp = stab[hashKey(sym->name)];
166
167   /**
168    **  do the search from the head of the list since the 
169    **  elements are added at the head it is ensured that
170    ** we will find the deeper definitions before we find
171    ** the global ones. we need to check for symbols with 
172    ** level <= to the level given, if levels match then block
173    ** numbers need to match as well
174    **/
175   while (bp) {
176
177     if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) {
178       /* if this is parameter then nothing else need to be checked */
179       if (((symbol *)(bp->sym))->_isparm)
180         return (bp->sym) ;
181       /* if levels match then block numbers hsould also match */
182       if (bp->level && bp->level == sym->level && bp->block == sym->block )
183               return ( bp->sym );
184       /* if levels don't match then we are okay */
185       if (bp->level && bp->level != sym->level)
186               return ( bp->sym );
187       /* if this is a global variable then we are ok too */
188       if (bp->level == 0 )
189               return (bp->sym);
190     }
191     
192     bp = bp->next; 
193   }
194
195   return (void *) NULL ;
196 }
197
198 /*-----------------------------------------------------------------*/
199 /* findSymWithBlock - finds a symbol with name in with a block     */
200 /*-----------------------------------------------------------------*/
201 void  *findSymWithBlock ( bucket **stab, symbol *sym, int block)
202 {
203    bucket *bp ;
204
205    bp = stab[hashKey(sym->name)] ;
206    while (bp)
207    {
208       if ( strcmp (bp->name,sym->name) == 0 &&
209            bp->block <= block )
210               break ;
211       bp = bp->next ;
212    }
213
214    return ( bp ? bp->sym : (void *) NULL ) ;
215 }
216
217 /*------------------------------------------------------------------*/
218 /* newSymbol () - returns a new pointer to a symbol                 */
219 /*------------------------------------------------------------------*/
220 symbol *newSymbol (char *name, int scope )
221 {
222    symbol *sym ;
223    
224    ALLOC(sym,sizeof(symbol));   
225
226    strcpy(sym->name,name);             /* copy the name    */
227    sym->level = scope ;                /* set the level    */
228    sym->block = currBlockno ;
229    sym->lineDef = yylineno ;    /* set the line number */   
230    return sym ;
231 }
232
233 /*------------------------------------------------------------------*/
234 /* newLink - creates a new link (declarator,specifier)              */
235 /*------------------------------------------------------------------*/
236 sym_link  *newLink ()
237 {
238    sym_link *p ;
239
240    ALLOC(p,sizeof(sym_link));
241
242    return p;
243 }
244
245 /*------------------------------------------------------------------*/
246 /* newStruct - creats a new structdef from the free list            */
247 /*------------------------------------------------------------------*/
248 structdef   *newStruct  ( char   *tag   )
249 {
250    structdef  *s;
251
252    ALLOC(s,sizeof(structdef));
253    
254    strcpy(s->tag,tag) ;                     /* copy the tag            */
255    return s ;
256 }
257
258 /*------------------------------------------------------------------*/
259 /* pointerTypes - do the computation for the pointer types          */
260 /*------------------------------------------------------------------*/
261 void pointerTypes (sym_link *ptr, sym_link *type)
262 {    
263     if (IS_SPEC(ptr))
264         return ;
265     
266     /* find the first pointer type */
267     while (ptr && !IS_PTR(ptr)) 
268         ptr = ptr->next;
269
270     /* could not find it */
271     if (!ptr || IS_SPEC(ptr) ||
272         DCL_TYPE(ptr) != UPOINTER)
273         return ;
274         
275     /* change the pointer type depending on the 
276        storage class of the type */
277     if (IS_SPEC(type)) {
278         DCL_PTR_CONST(ptr) = SPEC_CONST(type);
279         DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type);
280         switch (SPEC_SCLS(type)) {
281         case S_XDATA:
282             DCL_TYPE(ptr) = FPOINTER;
283             break;
284         case S_IDATA:
285             DCL_TYPE(ptr) = IPOINTER ;
286             break;
287         case S_PDATA:
288             DCL_TYPE(ptr) = PPOINTER ;
289             break;
290         case S_DATA:
291             DCL_TYPE(ptr) = POINTER ;
292             break;
293         case S_CODE:
294             DCL_PTR_CONST(ptr) = port->mem.code_ro;
295             DCL_TYPE(ptr) = CPOINTER ;
296             break;
297         case S_EEPROM:
298             DCL_TYPE(ptr) = EEPPOINTER;
299             break;
300         default:
301             DCL_TYPE(ptr) = GPOINTER;
302             break;
303         }
304         /* the storage class of type ends here */
305         SPEC_SCLS(type) =
306             SPEC_CONST(type) =
307             SPEC_VOLATILE(type) = 0;
308     }    
309     
310     /* now change all the remaining unknown pointers
311        to generic pointers */
312     while (ptr) {
313         if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
314             DCL_TYPE(ptr) = GPOINTER;
315         ptr = ptr->next;
316     }
317
318     /* same for the type although it is highly unlikely that
319        type will have a pointer */
320     while (type) {
321         if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
322             DCL_TYPE(type) = GPOINTER;
323         type = type->next;
324     }
325
326 }
327
328 /*------------------------------------------------------------------*/
329 /* addDecl - adds a declarator @ the end of a chain                 */
330 /*------------------------------------------------------------------*/
331 void  addDecl ( symbol *sym, int type , sym_link *p )
332 {
333     sym_link    *head;
334     sym_link    *tail;
335     sym_link        *t ;
336     
337     /* if we are passed a link then set head & tail */
338     if ( p )  {
339         tail = head = p ;
340         while ( tail->next )
341             tail = tail->next ;
342     }
343     else {
344         head = tail = newLink() ;
345         DCL_TYPE(head) = type   ;
346     }
347     
348     /* if this is the first entry   */
349     if ( !sym->type )  {
350         sym->type = head ;
351         sym->etype = tail ;
352     }
353     else   {
354         if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
355             sym->etype = mergeSpec(sym->etype,head);
356         }
357         else {
358             if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
359                 t = sym->type ;
360                 while (t->next != sym->etype) t = t->next ;
361                 t->next = head ;
362                 tail->next = sym->etype;
363             } else {
364                 sym->etype->next = head;
365                 sym->etype   = tail;
366             }
367         }
368     }
369     
370     /* if the type is a unknown pointer and has
371        a tspec then take the storage class const & volatile
372        attribute from the tspec & make it those of this
373        symbol */
374     if (p &&
375         !IS_SPEC(p) && 
376         DCL_TYPE(p) == UPOINTER &&
377         DCL_TSPEC(p)) {
378         if (!IS_SPEC(sym->etype)) {
379             sym->etype = sym->etype->next = newLink();
380             sym->etype->class = SPECIFIER;
381         }
382         SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
383         SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
384         SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
385         DCL_TSPEC(p) = NULL;
386     }
387     return  ;
388 }
389
390 /*------------------------------------------------------------------*/
391 /* mergeSpec - merges two specifiers and returns the new one       */
392 /*------------------------------------------------------------------*/
393 sym_link  *mergeSpec ( sym_link *dest, sym_link *src )
394 {
395     /* if noun different then src overrides */
396     if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
397         SPEC_NOUN(dest) = SPEC_NOUN(src) ;
398     
399     if (! SPEC_SCLS(dest))  /* if destination has no storage class */
400         SPEC_SCLS(dest) = SPEC_SCLS(src) ;
401     
402     /* copy all the specifications  */
403     SPEC_LONG(dest) |= SPEC_LONG(src);
404     SPEC_SHORT(dest) |= SPEC_SHORT(src);
405     SPEC_USIGN(dest) |= SPEC_USIGN(src);
406     SPEC_STAT(dest) |= SPEC_STAT(src);
407     SPEC_EXTR(dest) |= SPEC_EXTR(src);
408     SPEC_ABSA(dest) |= SPEC_ABSA(src);
409     SPEC_RENT(dest) |= SPEC_RENT(src);
410     SPEC_INTN(dest) |= SPEC_INTN(src);
411     SPEC_BANK(dest) |= SPEC_BANK(src);
412     SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
413     SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
414     SPEC_ADDR(dest) |= SPEC_ADDR(src);
415     SPEC_OCLS(dest)  = SPEC_OCLS(src);
416     SPEC_BLEN(dest) |= SPEC_BLEN(src);
417     SPEC_BSTR(dest) |= SPEC_BSTR(src);
418     SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
419     SPEC_NONBANKED(dest) |= SPEC_NONBANKED(src);
420
421     if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
422         SPEC_STRUCT(dest) = SPEC_STRUCT(src);   
423     
424     return dest ;
425 }
426
427 /*------------------------------------------------------------------*/
428 /* cloneSpec - copies the entire spec and returns a new spec        */
429 /*------------------------------------------------------------------*/
430 sym_link  *cloneSpec ( sym_link *src )
431 {
432     sym_link  *spec ;
433     
434     /* go thru chain till we find the specifier */
435     while ( src && src->class != SPECIFIER )
436         src = src->next ;
437     
438     spec = newLink() ;
439     memcpy (spec,src,sizeof(sym_link));
440     return spec ;
441 }
442
443 /*------------------------------------------------------------------*/
444 /* genSymName - generates and returns a name used for anonymous vars*/
445 /*------------------------------------------------------------------*/
446 char  *genSymName ( int level )
447 {
448     static   int gCount = 0 ;
449     static   char gname[SDCC_NAME_MAX+1] ;
450     
451     sprintf (gname,"__%04d%04d",level,gCount++);
452     return gname ;
453 }
454
455 /*------------------------------------------------------------------*/
456 /* getSpec - returns the specifier part from a declaration chain    */
457 /*------------------------------------------------------------------*/
458 sym_link  *getSpec ( sym_link *p )
459 {
460     sym_link *loop ;
461     
462     loop = p ;
463     while ( p && ! (IS_SPEC(p)))
464         p = p->next ;
465     
466     return p ;
467 }
468
469 /*------------------------------------------------------------------*/
470 /* newCharLink() - creates an int type                              */
471 /*------------------------------------------------------------------*/
472 sym_link  *newCharLink()
473 {
474     sym_link *p;
475     
476     p = newLink();
477     p->class = SPECIFIER ;
478     SPEC_NOUN(p) = V_CHAR ;
479     
480     return p;
481 }
482
483 /*------------------------------------------------------------------*/
484 /* newFloatLink - a new Float type                                  */
485 /*------------------------------------------------------------------*/
486 sym_link *newFloatLink()
487 {
488     sym_link *p;
489     
490     p = newLink();
491     p->class = SPECIFIER ;
492     SPEC_NOUN(p) = V_FLOAT ;
493     
494     return p;
495 }
496
497 /*------------------------------------------------------------------*/
498 /* newLongLink() - new long type                                    */
499 /*------------------------------------------------------------------*/
500 sym_link *newLongLink()
501 {
502     sym_link *p;
503
504     p = newLink();
505     p->class = SPECIFIER ;
506     SPEC_NOUN(p) = V_INT ;
507     SPEC_LONG(p) = 1;
508     
509     return p;
510 }
511
512 /*------------------------------------------------------------------*/
513 /* newIntLink() - creates an int type                               */
514 /*------------------------------------------------------------------*/
515 sym_link  *newIntLink()
516 {
517     sym_link *p;
518     
519     p = newLink();
520     p->class = SPECIFIER ;
521     SPEC_NOUN(p) = V_INT ;
522     
523     return p;
524 }
525
526 /*------------------------------------------------------------------*/
527 /* getSize - returns size of a type chain in bits                   */
528 /*------------------------------------------------------------------*/
529 unsigned int   getSize ( sym_link *p )
530 {
531     /* if nothing return 0 */
532     if ( ! p )
533         return 0 ;
534     if ( IS_SPEC(p) ) { /* if this is the specifier then */
535         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
536         case V_INT:
537             return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
538         case V_FLOAT:
539             return FLOATSIZE ;
540         case V_CHAR:
541             return CHARSIZE ;
542         case V_VOID:
543             return   0 ;
544         case V_STRUCT:
545             return SPEC_STRUCT(p)->size ;
546         case V_LABEL:
547             return 0 ;
548         case V_SBIT:
549             return BITSIZE ;
550         case V_BIT:
551             return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
552         default  :
553             return 0 ;
554         }
555     }
556     
557     /* this is a specifier  */
558     switch (DCL_TYPE(p))  {
559     case FUNCTION:
560         return 2;
561     case ARRAY:
562         return DCL_ELEM(p) * getSize (p->next) ;
563     case IPOINTER:
564     case PPOINTER:
565     case POINTER:
566         return ( PTRSIZE ) ;
567     case EEPPOINTER:
568     case FPOINTER:
569     case CPOINTER:
570         return ( FPTRSIZE );
571     case GPOINTER:      
572         return ( GPTRSIZE );
573         
574     default     :
575         return  0 ;
576     }
577 }
578
579 /*------------------------------------------------------------------*/
580 /* bitsForType - returns # of bits required to store this type      */
581 /*------------------------------------------------------------------*/
582 unsigned int   bitsForType ( sym_link *p )
583 {
584     /* if nothing return 0 */
585     if ( ! p )
586         return 0 ;
587     
588     if ( IS_SPEC(p) ) { /* if this is the specifier then */
589         
590         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
591         case V_INT:
592             return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
593         case V_FLOAT:
594             return FLOATSIZE*8 ;
595         case V_CHAR:
596             return   CHARSIZE*8 ;
597         case V_VOID:
598             return   0 ;
599         case V_STRUCT:
600             return   SPEC_STRUCT(p)->size*8 ;
601         case V_LABEL:
602             return 0 ;
603         case V_SBIT:
604             return 1 ;
605         case V_BIT:
606             return SPEC_BLEN(p);
607         default  :
608             return 0 ;
609         }
610     }
611     
612     /* this is a specifier  */
613     switch (DCL_TYPE(p))  {
614     case FUNCTION:
615         return 2;
616     case ARRAY:
617         return DCL_ELEM(p) * getSize (p->next) *8 ;
618     case IPOINTER:
619     case PPOINTER:
620     case POINTER:
621         return ( PTRSIZE * 8) ;
622     case EEPPOINTER:
623     case FPOINTER:
624     case CPOINTER:
625         return ( FPTRSIZE * 8);
626     case GPOINTER:
627         return ( GPTRSIZE * 8);
628         
629     default     :
630         return  0 ;
631     }
632 }
633
634 /*------------------------------------------------------------------*/
635 /* copySymbolChain - copies a symbol chain                          */
636 /*------------------------------------------------------------------*/
637 symbol *copySymbolChain (symbol *src)
638 {
639         symbol *dest ;
640
641         if (!src)
642                 return NULL ;
643
644         dest = copySymbol(src);
645         dest->next = copySymbolChain(src->next);
646         return dest ;
647 }
648
649 /*------------------------------------------------------------------*/
650 /* copySymbol - makes a copy of a symbol                            */
651 /*------------------------------------------------------------------*/
652 symbol  *copySymbol     (symbol *src)
653 {
654         symbol *dest;
655
656         if (!src )
657                 return NULL ;
658
659         dest = newSymbol( src->name, src->level );
660         memcpy(dest,src,sizeof(symbol));
661         dest->level = src->level ;
662         dest->block = src->block ;
663         dest->ival = copyIlist(src->ival);
664         dest->type = copyLinkChain(src->type);
665         dest->etype= getSpec(dest->type);
666         dest->next = NULL ;
667         dest->args = copyValueChain (src->args);
668         dest->key = src->key;
669         dest->calleeSave = src->calleeSave;
670         dest->allocreq = src->allocreq;
671         return dest;
672 }
673
674 /*------------------------------------------------------------------*/
675 /* reverseSyms - reverses the links for a symbol chain      */
676 /*------------------------------------------------------------------*/
677 symbol   *reverseSyms ( symbol *sym)
678 {
679    symbol *prev  , *curr, *next ;
680
681    if (!sym)
682       return NULL ;
683
684    prev = sym ;
685    curr = sym->next ;
686
687    while (curr)
688    {
689       next = curr->next ;
690       curr->next = prev   ;
691       prev = curr ;
692       curr = next ;
693    }
694    sym->next = (void *) NULL ;
695    return prev ;
696 }
697
698 /*------------------------------------------------------------------*/
699 /* reverseLink - reverses the links for a type chain        */
700 /*------------------------------------------------------------------*/
701 sym_link     *reverseLink ( sym_link *type)
702 {
703    sym_link *prev  , *curr, *next ;
704
705    if (!type)
706       return NULL ;
707
708    prev = type ;
709    curr = type->next ;
710
711    while (curr)
712    {
713       next = curr->next ;
714       curr->next = prev   ;
715       prev = curr ;
716       curr = next ;
717    }
718    type->next = (void *) NULL ;
719    return prev ;
720 }
721
722 /*------------------------------------------------------------------*/
723 /* addSymChain - adds a symbol chain to the symboltable             */
724 /*------------------------------------------------------------------*/
725 void addSymChain ( symbol *symHead )
726 {
727   symbol *sym  = symHead ;
728   symbol *csym = NULL ;
729
730   for (;sym != NULL ; sym = sym->next ) {
731
732     /* if already exists in the symbol table then check if 
733        the previous was an extern definition if yes then   
734        then check if the type match, if the types match then 
735        delete the current entry and add the new entry      */   
736       if ((csym = findSymWithLevel (SymbolTab,sym)) &&
737         csym->level == sym->level) {
738       
739       /* previous definition extern ? */
740       if ( IS_EXTERN(csym->etype) ) {
741         /* do types match ? */
742         if (checkType ( csym->type,sym->type) != 1)
743           /* no then error */
744           werror (E_DUPLICATE,csym->name);
745
746         /* delete current entry */
747         deleteSym (SymbolTab, csym, csym->name );
748         /* add new entry */
749         addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
750       } else /* not extern */
751           werror(E_DUPLICATE,sym->name) ;
752       continue ;
753     }
754     
755     /* check if previously defined */
756     if (csym  && csym->level == sym->level  ) {
757       /* if the previous one was declared as extern */
758       /* then check the type with the current one         */
759       if ( IS_EXTERN(csym->etype) ) {
760         if ( checkType (csym->type, sym->type ) <= 0 )
761           werror (W_EXTERN_MISMATCH,csym->name);
762       }
763     }
764     
765     addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
766   }
767 }
768
769
770 /*------------------------------------------------------------------*/
771 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
772 /*------------------------------------------------------------------*/
773 int funcInChain (sym_link *lnk)
774 {
775     while (lnk) {
776         if (IS_FUNC(lnk))
777             return 1;
778         lnk = lnk->next;
779     }
780     return 0;
781 }
782
783 /*------------------------------------------------------------------*/
784 /* structElemType - returns the type info of a sturct member        */
785 /*------------------------------------------------------------------*/
786 sym_link *structElemType (sym_link *stype, value *id ,value **argsp)
787 {
788     symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
789     sym_link *type, *etype;
790     sym_link *petype = getSpec(stype);
791
792     if ( ! fields || ! id)
793         return NULL ;
794        
795     /* look for the id */
796     while (fields) {
797         if (strcmp(fields->rname,id->name) == 0) {
798             if (argsp) {
799                 *argsp = fields->args;
800             }
801             type = copyLinkChain (fields->type) ;
802             etype=getSpec(type);
803             SPEC_SCLS(etype) = (SPEC_SCLS(petype) == S_REGISTER ? 
804                                 SPEC_SCLS(etype) : SPEC_SCLS(petype));
805             return type;
806         }
807         fields = fields->next ;
808     }
809     werror(E_NOT_MEMBER,id->name);
810     
811     return NULL ;
812 }
813
814 /*------------------------------------------------------------------*/
815 /* getStructElement - returns element of a tructure definition      */
816 /*------------------------------------------------------------------*/
817 symbol *getStructElement ( structdef *sdef, symbol *sym)
818 {
819     symbol *field ;
820     
821     for ( field = sdef->fields ; field ; field = field->next )
822         if ( strcmp(field->name,sym->name) == 0)
823             return field ;
824     
825     werror(E_NOT_MEMBER,sym->name);
826     
827     return sdef->fields ;
828 }
829
830 /*------------------------------------------------------------------*/
831 /* compStructSize - computes the size of a structure                */
832 /*------------------------------------------------------------------*/
833 int   compStructSize (int su, structdef  *sdef )
834 {
835     int sum = 0 , usum =0;
836     int bitOffset = 0 ;
837     symbol   *loop ;
838     
839     /* for the identifiers  */
840     loop = sdef->fields ;
841     while ( loop ) {
842
843         /* create the internal name for this variable */
844         sprintf (loop->rname,"_%s",loop->name);
845         loop->offset = ( su == UNION ? sum = 0 : sum ) ;
846         SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
847
848         /* if this is a bit field  */
849         if (loop->bitVar)       {
850             
851             /* change it to a unsigned bit */
852             SPEC_NOUN(loop->etype) = V_BIT ;
853             SPEC_USIGN(loop->etype) = 1     ;
854             /* check if this fit into the remaining   */
855             /* bits of this byte else align it to the */
856             /* next byte boundary                     */
857             if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset))  {
858                 SPEC_BSTR(loop->etype) = bitOffset   ;
859                 if ((bitOffset += (loop->bitVar % 8)) == 8) sum++;
860             } 
861             else  /* does not fit */
862                 {
863                     bitOffset = 0 ;
864                     SPEC_BSTR(loop->etype) = bitOffset   ;
865                     sum += (loop->bitVar / 8)  ;
866                     bitOffset += (loop->bitVar % 8);
867                 }
868             /* if this is the last field then pad */
869             if (!loop->next && bitOffset && bitOffset != 8) {
870                 bitOffset = 0 ;
871                 sum++ ;
872             }
873         }
874         else {
875             checkDecl (loop);
876             sum += getSize (loop->type) ;
877         }
878
879         /* if function then do the arguments for it */
880         if (funcInChain(loop->type)) {
881             processFuncArgs (loop, 1);
882         }
883
884         loop = loop->next ;
885
886         /* if this is not a bitfield but the */
887         /* previous one was and did not take */
888         /* the whole byte then pad the rest  */
889         if ((loop && !loop->bitVar) && bitOffset) {
890             bitOffset = 0 ;
891             sum++ ;
892         }
893         
894         /* if union then size = sizeof larget field */
895         if (su == UNION)
896             usum = max(usum,sum);
897     
898     }
899     
900     return (su == UNION ? usum : sum);
901 }
902
903 /*------------------------------------------------------------------*/
904 /* checkSClass - check the storage class specification              */
905 /*------------------------------------------------------------------*/
906 static void  checkSClass ( symbol *sym )
907 {         
908     /* type is literal can happen foe enums change
909        to auto */
910     if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
911         SPEC_SCLS(sym->etype) = S_AUTO;
912
913     /* if sfr or sbit then must also be */
914     /* volatile the initial value will be xlated */
915     /* to an absolute address */
916     if (SPEC_SCLS(sym->etype) == S_SBIT ||
917         SPEC_SCLS(sym->etype) == S_SFR ) {
918         SPEC_VOLATILE(sym->etype) = 1;
919         /* if initial value given */
920         if (sym->ival) {
921             SPEC_ABSA(sym->etype) = 1;
922             SPEC_ADDR(sym->etype) =
923                 (int) list2int(sym->ival);
924             sym->ival = NULL;
925         }
926     }
927
928     /* if absolute address given then it mark it as
929        volatile */
930     if (IS_ABSOLUTE(sym->etype))
931         SPEC_VOLATILE(sym->etype) = 1;
932
933     /* global variables declared const put into code */
934     if (sym->level == 0 && 
935         SPEC_SCLS(sym->etype) == S_CONSTANT) {
936         SPEC_SCLS(sym->etype) = S_CODE ;
937         SPEC_CONST(sym->etype) = 1;
938     }
939
940     /* global variable in code space is a constant */
941     if (sym->level == 0 && 
942         SPEC_SCLS(sym->etype) == S_CODE &&
943         port->mem.code_ro )
944         SPEC_CONST(sym->etype) = 1;
945     
946
947     /* if bit variable then no storage class can be */
948     /* specified since bit is already a storage */
949     if ( IS_BITVAR(sym->etype)              && 
950          ( SPEC_SCLS(sym->etype) != S_FIXED &&   
951            SPEC_SCLS(sym->etype) != S_SBIT  &&
952            SPEC_SCLS(sym->etype) != S_BIT )
953          ) {
954         werror (E_BITVAR_STORAGE,sym->name);
955         SPEC_SCLS(sym->etype) = S_FIXED ;
956     }
957     
958     /* extern variables cannot be initialized */
959     if (IS_EXTERN(sym->etype) && sym->ival)     {
960         werror(E_EXTERN_INIT,sym->name);
961         sym->ival = NULL;
962     }    
963     
964     /* if this is an automatic symbol then */
965     /* storage class will be ignored and   */
966     /* symbol will be allocated on stack/  */
967     /* data depending on flag             */
968     if ( sym->level                             &&
969          (options.stackAuto || reentrant )      &&
970          ( SPEC_SCLS(sym->etype) != S_AUTO      &&
971            SPEC_SCLS(sym->etype) != S_FIXED     &&
972            SPEC_SCLS(sym->etype) != S_REGISTER  &&
973            SPEC_SCLS(sym->etype) != S_STACK     &&
974            SPEC_SCLS(sym->etype) != S_XSTACK    &&
975            SPEC_SCLS(sym->etype) != S_CONSTANT  )) {
976
977         werror(E_AUTO_ASSUMED,sym->name) ;
978         SPEC_SCLS(sym->etype) = S_AUTO   ;
979     }
980         
981     /* automatic symbols cannot be given   */
982     /* an absolute address ignore it      */
983     if ( sym->level  && 
984          SPEC_ABSA(sym->etype) &&
985          (options.stackAuto || reentrant) )  {
986         werror(E_AUTO_ABSA,sym->name);
987         SPEC_ABSA(sym->etype) = 0 ;
988     }
989         
990     /* arrays & pointers cannot be defined for bits   */
991     /* SBITS or SFRs or BIT                           */
992     if ((IS_ARRAY(sym->type) || IS_PTR(sym->type))  &&
993         ( SPEC_NOUN(sym->etype) == V_BIT          || 
994          SPEC_NOUN(sym->etype) == V_SBIT             ||
995          SPEC_SCLS(sym->etype) == S_SFR              ))
996         werror(E_BIT_ARRAY,sym->name);
997     
998     /* if this is a bit|sbit then set length & start  */
999     if (SPEC_NOUN(sym->etype) == V_BIT              ||
1000         SPEC_NOUN(sym->etype) == V_SBIT             )  {
1001         SPEC_BLEN(sym->etype) = 1 ;
1002         SPEC_BSTR(sym->etype) = 0 ;
1003     }    
1004     
1005     /* variables declared in CODE space must have */
1006     /* initializers if not an extern */
1007     if (SPEC_SCLS(sym->etype) == S_CODE && 
1008         sym->ival == NULL               &&
1009         !sym->level                     &&
1010         port->mem.code_ro               &&
1011         !IS_EXTERN(sym->etype)          &&
1012         !funcInChain(sym->type)) 
1013         werror(E_CODE_NO_INIT,sym->name);
1014     
1015     /* if parameter or local variable then change */
1016     /* the storage class to reflect where the var will go */
1017     if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1018         if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1019         {
1020             SPEC_SCLS(sym->etype) = (options.useXstack  ?
1021                                      S_XSTACK : S_STACK ) ;
1022         }
1023         else
1024         {
1025             /* hack-o-matic! I see no reason why the useXstack option should ever
1026              * control this allcoation, but the code was originally that way, and
1027              * changing it for non-390 ports breaks the compiler badly.
1028              */
1029             bool useXdata = IS_DS390_PORT ? options.model : options.useXstack;
1030             SPEC_SCLS(sym->etype) = (useXdata  ?
1031                                      S_XDATA : S_FIXED ) ;
1032         }
1033     }
1034 }
1035
1036 /*------------------------------------------------------------------*/
1037 /* changePointer - change pointer to functions                      */
1038 /*------------------------------------------------------------------*/
1039 void  changePointer  (symbol  *sym)
1040 {
1041     sym_link *p ;
1042     
1043     /* go thru the chain of declarations   */
1044     /* if we find a pointer to a function  */
1045     /* unconditionally change it to a ptr  */
1046     /* to code area                        */
1047     for ( p = sym->type ; p ; p = p->next) {
1048         if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1049             DCL_TYPE(p) = GPOINTER ;
1050         if ( IS_PTR(p) && IS_FUNC(p->next))
1051             DCL_TYPE(p) = CPOINTER ;
1052     }
1053 }
1054
1055 /*------------------------------------------------------------------*/
1056 /* checkDecl - does semantic validation of a declaration                   */
1057 /*------------------------------------------------------------------*/
1058 int checkDecl ( symbol *sym )
1059 {
1060     
1061     checkSClass  (sym); /* check the storage class      */
1062     changePointer(sym);  /* change pointers if required */
1063
1064     /* if this is an array without any dimension
1065        then update the dimension from the initial value */
1066     if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1067         DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);    
1068
1069     return 0 ;
1070 }
1071
1072 /*------------------------------------------------------------------*/
1073 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1074 /*------------------------------------------------------------------*/
1075 sym_link  *copyLinkChain ( sym_link *p)
1076 {
1077     sym_link  *head, *curr , *loop;
1078     
1079     curr = p ;
1080     head = loop = ( curr ? newLink() : (void *) NULL) ;
1081     while (curr)   {
1082         memcpy(loop,curr,sizeof(sym_link)) ; /* copy it */
1083         loop->next = (curr->next ? newLink() : (void *) NULL) ;
1084         loop = loop->next ;
1085         curr = curr->next ;
1086     }
1087     
1088     return head ;
1089 }
1090
1091
1092 /*------------------------------------------------------------------*/
1093 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1094 /*                symbols in the given block                        */
1095 /*------------------------------------------------------------------*/
1096 void cleanUpBlock ( bucket **table, int block)
1097 {    
1098     int i ;
1099     bucket  *chain;
1100     
1101     /* go thru the entire  table  */
1102     for ( i = 0 ; i < 256; i++ ) {
1103         for ( chain = table[i]; chain ; chain = chain->next ) {
1104             if (chain->block >= block) {
1105                 deleteSym (table,chain->sym,chain->name);                                 
1106             }   
1107         }
1108     }
1109 }
1110
1111 /*------------------------------------------------------------------*/
1112 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1113 /*                symbols in the given level                        */
1114 /*------------------------------------------------------------------*/
1115 void  cleanUpLevel   (bucket  **table, int level )
1116 {
1117     int i ;
1118     bucket  *chain;
1119     
1120     /* go thru the entire  table  */
1121     for ( i = 0 ; i < 256; i++ ) {
1122         for ( chain = table[i]; chain ; chain = chain->next ) {
1123             if (chain->level >= level) {
1124                 deleteSym (table,chain->sym,chain->name);                                 
1125             }   
1126         }
1127     }
1128 }
1129
1130 /*------------------------------------------------------------------*/
1131 /* computeType - computes the resultant type from two types         */
1132 /*------------------------------------------------------------------*/
1133 sym_link *computeType ( sym_link *type1, sym_link *type2)
1134 {
1135     sym_link *rType ;
1136     sym_link *reType;
1137     sym_link *etype1 = getSpec(type1);
1138     sym_link *etype2 = getSpec(type2);
1139     
1140     /* if one of them is a float then result is a float */
1141     /* here we assume that the types passed are okay */
1142     /* and can be cast to one another                */
1143     /* which ever is greater in size */
1144     if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1145         rType = newFloatLink();
1146     else
1147         /* if only one of them is a bit variable
1148            then the other one prevails */
1149         if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1150             rType = copyLinkChain(type2);
1151         else
1152             if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1153                 rType = copyLinkChain(type1);
1154             else
1155                 /* if one of them is a pointer then that
1156                    prevails */
1157                 if (IS_PTR(type1))
1158                     rType = copyLinkChain(type1);
1159                 else
1160                     if (IS_PTR(type2))
1161                         rType = copyLinkChain(type2);
1162                     else
1163                         if (getSize (type1) > getSize(type2) )
1164                             rType = copyLinkChain(type1);
1165                         else
1166                             rType = copyLinkChain(type2);
1167     
1168     reType = getSpec(rType);
1169     
1170     /* if either of them unsigned then make this unsigned */
1171     if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1172         SPEC_USIGN(reType) = 1;
1173     
1174     /* if result is a literal then make not so */
1175     if (IS_LITERAL(reType))
1176         SPEC_SCLS(reType) = S_REGISTER ;
1177     
1178     return rType;
1179 }
1180
1181 /*------------------------------------------------------------------*/
1182 /* checkType - will do type check return 1 if match                 */
1183 /*------------------------------------------------------------------*/
1184 int checkType ( sym_link *dest, sym_link *src )
1185 {
1186     if ( !dest && !src)
1187         return 1;
1188     
1189     if (dest && !src)
1190         return 0;
1191     
1192     if (src && !dest)
1193         return 0;
1194     
1195     /* if dest is a declarator then */
1196     if (IS_DECL(dest)) {
1197         if (IS_DECL(src)) {
1198             if (DCL_TYPE(src) == DCL_TYPE(dest))
1199                 return checkType(dest->next,src->next);
1200             else
1201                 if (IS_PTR(src) && IS_PTR(dest))
1202                     return -1;
1203                 else
1204                     if (IS_PTR(dest) && IS_ARRAY(src))
1205                         return -1;
1206                     else 
1207                         if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1208                             return -1 * checkType (dest->next,src) ;
1209                         else
1210                             return 0;
1211         }
1212         else
1213             if (IS_PTR(dest) && IS_INTEGRAL(src))
1214                 return -1;
1215             else
1216                 return 0;
1217     }
1218
1219     /* if one is a specifier and the other is not */
1220     if ((IS_SPEC(src) && !IS_SPEC(dest)) ||
1221         (IS_SPEC(dest) && !IS_SPEC(src))) return 0;
1222
1223     /* if one of them is a void then ok */
1224     if (SPEC_NOUN(dest) == V_VOID    &&
1225         SPEC_NOUN(src)  != V_VOID    )
1226         return -1 ;
1227     
1228     if (SPEC_NOUN(dest) != V_VOID &&
1229         SPEC_NOUN(src) == V_VOID )
1230         return -1;
1231     
1232     /* char === to short */
1233     if (SPEC_NOUN(dest) == V_CHAR &&
1234         SPEC_NOUN(src)  == V_INT  &&
1235         SPEC_SHORT(src)           )
1236         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1237
1238     if (SPEC_NOUN(src) == V_CHAR &&
1239         SPEC_NOUN(dest)  == V_INT  &&
1240         SPEC_SHORT(dest)           )
1241         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);    
1242
1243     /* if they are both bitfields then if the lengths
1244        and starts don't match */
1245     if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1246         (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1247          SPEC_BSTR(dest) != SPEC_BSTR(src)))
1248             return -1;
1249     
1250     /* it is a specifier */
1251     if (SPEC_NOUN(dest) != SPEC_NOUN(src))      {
1252         if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1253             IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1254             getSize(dest) == getSize(src))
1255             return 1;
1256         else
1257             if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1258                 return -1;
1259         else
1260             return 0;
1261     }
1262     else
1263         if (IS_STRUCT(dest)) {
1264             if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1265                 return 0 ;
1266             else 
1267                 return 1 ;
1268         }
1269     if (SPEC_LONG(dest) != SPEC_LONG(src))
1270         return -1;
1271     
1272     if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1273         return -1;
1274     
1275     if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1276         return -2;
1277     
1278     return 1;   
1279 }
1280
1281 /*------------------------------------------------------------------*/
1282 /* inCalleeSaveList - return 1 if found in calle save list          */
1283 /*------------------------------------------------------------------*/
1284 bool inCalleeSaveList ( char *s)
1285 {
1286     int i;
1287     
1288     for (i = 0 ; options.calleeSaves[i] ; i++ )
1289         if (strcmp(options.calleeSaves[i],s) == 0)
1290             return 1;
1291
1292     return 0;
1293 }
1294
1295 /*-----------------------------------------------------------------*/
1296 /* aggregateArgToPointer:  change an agggregate type function      */
1297 /*                         argument to a pointer to that type.     */
1298 /*-----------------------------------------------------------------*/
1299 void aggregateArgToPointer(value *val)
1300 {
1301         if ( IS_AGGREGATE(val->type)) {
1302             /* if this is a structure */
1303             /* then we need to add a new link */
1304             if (IS_STRUCT(val->type)) {
1305                                 /* first lets add DECLARATOR type */
1306                 sym_link *p = val->type ;
1307                 
1308                 werror(W_STRUCT_AS_ARG,val->name);
1309                 val->type = newLink();
1310                 val->type->next = p ;                           
1311             }
1312             
1313             /* change to a pointer depending on the */
1314             /* storage class specified                          */
1315             switch (SPEC_SCLS(val->etype)) {
1316             case S_IDATA:
1317                 DCL_TYPE(val->type) = IPOINTER;
1318                 break;
1319             case S_PDATA:
1320                 DCL_TYPE(val->type) = PPOINTER;
1321                 break;
1322             case S_FIXED:
1323                 if (IS_DS390_PORT)
1324                 {
1325                     /* The AUTO and REGISTER classes should probably
1326                      * also become generic pointers, but I haven't yet
1327                      * devised a test case for that.
1328                      */
1329                     DCL_TYPE(val->type) = GPOINTER;
1330                     break;
1331                 }
1332                 /* fall through! */
1333             case S_AUTO:
1334             case S_DATA:
1335             case S_REGISTER:
1336                 DCL_TYPE(val->type) = POINTER ;
1337                 break;
1338             case S_CODE:
1339                 DCL_TYPE(val->type) = CPOINTER;
1340                 break;
1341             case S_XDATA:
1342                 DCL_TYPE(val->type) = FPOINTER;
1343                 break;
1344             case S_EEPROM:
1345                 DCL_TYPE(val->type) = EEPPOINTER;
1346                 break;
1347             default :
1348                 DCL_TYPE(val->type) = GPOINTER;
1349             }
1350             
1351             /* is there is a symbol associated then */
1352             /* change the type of the symbol as well*/
1353             if ( val->sym ) {          
1354                 val->sym->type = copyLinkChain(val->type);
1355                 val->sym->etype = getSpec(val->sym->type);
1356             }
1357         }
1358 }
1359 /*------------------------------------------------------------------*/
1360 /* checkFunction - does all kinds of check on a function            */
1361 /*------------------------------------------------------------------*/
1362 int   checkFunction (symbol   *sym)
1363 {
1364     symbol *csym ;
1365     value  *exargs, *acargs ;
1366     int argCnt = 0 ;
1367     
1368     /* if not type then some kind of error */
1369     if ( !sym->type )
1370         return 0;
1371     
1372     /* if the function has no type then make it return int */
1373     if ( !sym->type->next )
1374         sym->type->next = sym->etype = newIntLink();
1375    
1376     /* function cannot return aggregate */
1377     if (IS_AGGREGATE(sym->type->next))   {
1378         werror(E_FUNC_AGGR,sym->name);
1379         return 0;      
1380     }
1381            
1382     /* function cannot return bit */
1383     if (IS_BITVAR(sym->type->next)) {
1384         werror(E_FUNC_BIT,sym->name);
1385         return 0;
1386     }
1387     
1388     /* check if this function is defined as calleeSaves
1389        then mark it as such */
1390     sym->calleeSave = inCalleeSaveList(sym->name); 
1391
1392     /* if interrupt service routine  */
1393     /* then it cannot have arguments */
1394     if ( sym->args  && IS_ISR(sym->etype) && !IS_VOID(sym->args->type))   {
1395         werror(E_INT_ARGS,sym->name);     
1396         sym->args = NULL ;
1397     }
1398     
1399     if (!(csym = findSym (SymbolTab, sym, sym->name )))
1400         return 1 ;  /* not defined nothing more to check  */
1401     
1402     /* check if body already present */
1403     if ( csym && csym->fbody )   {
1404         werror(E_FUNC_BODY,sym->name);
1405         return 0;
1406     }
1407     
1408     /* check the return value type   */
1409     if (checkType (csym->type,sym->type) <= 0) {
1410         werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1411         werror (E_CONTINUE,"previous defintion type ");
1412         printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1413         werror (E_CONTINUE,"current definition type ");
1414         printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1415         return 0;
1416     }
1417
1418     if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1419         werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1420         return 0;
1421     }
1422
1423     if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1424         werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1425         return 0;
1426     }
1427
1428     /* compare expected agrs with actual args */
1429     exargs = csym->args ;
1430     acargs = sym->args  ;
1431     
1432     /* for all the expected args do */
1433     for (argCnt =  1    ; 
1434          exargs && acargs ; 
1435          exargs = exargs->next, acargs = acargs->next, argCnt++ ) 
1436     {
1437         value *checkValue;
1438         /* If the actual argument is an array, any prototype
1439          * will have modified it to a pointer. Duplicate that
1440          * change here.
1441          */
1442         if ( IS_AGGREGATE(acargs->type)) 
1443         {
1444             checkValue = copyValue(acargs);
1445             aggregateArgToPointer(checkValue);
1446         } 
1447         else
1448         {
1449             checkValue = acargs;
1450         }
1451         
1452         if ( checkType(exargs->type,checkValue->type) <= 0) 
1453         {
1454             werror(E_ARG_TYPE,argCnt);
1455             return 0;
1456         }
1457     }
1458     
1459     /* if one them ended we have a problem */
1460     if ((exargs && !acargs && !IS_VOID(exargs->type)) || 
1461         (!exargs && acargs && !IS_VOID(acargs->type)))
1462         werror(E_ARG_COUNT);
1463     
1464     /* replace with this defition */
1465     sym->cdef = csym->cdef;
1466     deleteSym (SymbolTab,csym,csym->name);
1467     addSym    (SymbolTab,sym,sym->name,sym->level,sym->block);
1468     if (IS_EXTERN(csym->etype) && !
1469         IS_EXTERN(sym->etype)) {
1470         addSet(&publics,sym);
1471     }
1472     return 1 ;      
1473 }
1474
1475 /*-----------------------------------------------------------------*/
1476 /* processFuncArgs - does some processing with function args       */
1477 /*-----------------------------------------------------------------*/
1478 void  processFuncArgs   (symbol *func, int ignoreName)
1479 {
1480     value *val ;
1481     int pNum = 1;   
1482     
1483
1484     /* if this function has variable argument list */
1485     /* then make the function a reentrant one      */
1486     if (func->hasVargs)
1487         SPEC_RENT(func->etype) = 1;
1488
1489     /* check if this function is defined as calleeSaves
1490        then mark it as such */
1491     func->calleeSave = inCalleeSaveList(func->name); 
1492
1493     val = func->args; /* loop thru all the arguments   */
1494         
1495     /* if it is void then remove parameters */
1496     if (val && IS_VOID(val->type)) {     
1497         func->args = NULL ;
1498         return ;
1499     }
1500
1501     /* reset regparm for the port */
1502     (*port->reset_regparms)();
1503     /* if any of the arguments is an aggregate */
1504     /* change it to pointer to the same type */
1505     while (val) {
1506         /* mark it as a register parameter if
1507            the function does not have VA_ARG
1508            and as port dictates
1509            not inhibited by command line option or #pragma */
1510         if (!func->hasVargs       &&        
1511             !options.noregparms   &&
1512             !IS_RENT(func->etype) &&
1513             (*port->reg_parm)(val->type)) {
1514             SPEC_REGPARM(val->etype) = 1;
1515         }
1516         
1517         if ( IS_AGGREGATE(val->type)) {
1518             aggregateArgToPointer(val);
1519         }
1520         val = val->next ;
1521         pNum++;
1522     }
1523     
1524     /* if this function is reentrant or */
1525     /* automatics r 2b stacked then nothing */
1526     if (IS_RENT(func->etype) || options.stackAuto )
1527         return ;
1528     
1529     val = func->args;
1530     pNum = 1;
1531     while (val) {
1532         
1533         /* if a symbolname is not given  */
1534         /* synthesize a variable name */
1535         if (!val->sym) {
1536
1537             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1538             val->sym = newSymbol(val->name,1);
1539             SPEC_OCLS(val->etype) = port->mem.default_local_map;
1540             val->sym->type = copyLinkChain (val->type);
1541             val->sym->etype = getSpec (val->sym->type);
1542             val->sym->_isparm = 1;
1543             strcpy (val->sym->rname,val->name);  
1544             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1545                 SPEC_STAT(func->etype);
1546             addSymChain(val->sym);
1547    
1548         }
1549         else  /* symbol name given create synth name */      {
1550             
1551             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1552             strcpy (val->sym->rname,val->name);
1553             val->sym->_isparm = 1;
1554             SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) = 
1555                 (options.model != MODEL_SMALL ? xdata : data);
1556             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = 
1557                 SPEC_STAT(func->etype);
1558         }
1559         val = val->next ;
1560     }
1561 }
1562
1563 /*-----------------------------------------------------------------*/
1564 /* isSymbolEqual - compares two symbols return 1 if they match     */
1565 /*-----------------------------------------------------------------*/
1566 int isSymbolEqual (symbol *dest, symbol *src)
1567 {
1568     /* if pointers match then equal */
1569     if (dest == src)
1570         return 1;
1571
1572     /* if one of them is null then don't match */
1573     if (!dest || !src)
1574         return 0;
1575     
1576     /* if both of them have rname match on rname */
1577     if (dest->rname[0] && src->rname[0]) 
1578         return (!strcmp(dest->rname,src->rname));
1579     
1580     /* otherwise match on name */
1581     return (!strcmp(dest->name,src->name));
1582 }
1583
1584 /*-----------------------------------------------------------------*/ 
1585 /* printTypeChain - prints the type chain in human readable form   */
1586 /*-----------------------------------------------------------------*/ 
1587 void printTypeChain (sym_link *type, FILE *of)
1588 {
1589     int nlr = 0;
1590
1591     if (!of) {
1592         of = stdout;
1593         nlr = 1;
1594     }
1595
1596     while (type) {
1597         if (IS_DECL(type)) {
1598             switch (DCL_TYPE(type)) {
1599             case FUNCTION:
1600                 fprintf (of,"function ");
1601                 break;
1602             case GPOINTER:
1603                 fprintf (of,"_generic * ");
1604                 if (DCL_PTR_CONST(type))
1605                     fprintf(of,"const ");
1606                 break;          
1607             case CPOINTER:
1608                 fprintf (of,"_code * ");
1609                 if (DCL_PTR_CONST(type))
1610                     fprintf(of,"const ");
1611                 break;
1612             case FPOINTER:
1613                 fprintf (of,"_far * ");
1614                 if (DCL_PTR_CONST(type))
1615                     fprintf(of,"const ");
1616                 break;
1617             case EEPPOINTER:
1618                 fprintf (of,"_eeprom * ");
1619                 if (DCL_PTR_CONST(type))
1620                     fprintf(of,"const ");
1621                 break;
1622                 
1623             case POINTER:
1624                 fprintf (of,"_near * ");
1625                 if (DCL_PTR_CONST(type))
1626                     fprintf(of,"const ");       
1627                 break;
1628             case IPOINTER:
1629                 fprintf (of,"_idata *");
1630                 if (DCL_PTR_CONST(type))
1631                     fprintf(of,"const ");       
1632                 break; 
1633             case PPOINTER:
1634                 fprintf (of,"_pdata *");
1635                 if (DCL_PTR_CONST(type))
1636                     fprintf(of,"const ");       
1637                 break;
1638             case UPOINTER:
1639                 fprintf (of," _unkown *");
1640                 if (DCL_PTR_CONST(type))
1641                     fprintf(of,"const ");       
1642                 break;
1643                 
1644             case ARRAY :
1645                 fprintf (of,"array of ");
1646                 break;
1647             }
1648         } else { 
1649             if (SPEC_VOLATILE(type))
1650                 fprintf (of,"volatile "); 
1651             if (SPEC_USIGN(type))
1652                 fprintf (of,"unsigned ");
1653             
1654             switch (SPEC_NOUN(type)) {
1655             case V_INT:
1656                 if (IS_LONG(type))
1657                     fprintf (of,"long ");
1658                 else
1659                     if (IS_SHORT(type))
1660                         fprintf (of,"short ");
1661                     else
1662                         fprintf (of,"int ");
1663                 break;
1664
1665             case V_CHAR:
1666                 fprintf(of,"char ");
1667                 break;
1668
1669             case V_VOID:
1670                 fprintf(of,"void ");
1671                 break;
1672
1673             case V_FLOAT:
1674                 fprintf(of,"float ");
1675                 break;
1676
1677             case V_STRUCT:
1678                 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1679                 break;
1680                                   
1681             case V_SBIT:
1682                 fprintf(of,"sbit ");
1683                 break;
1684
1685             case V_BIT:
1686                 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1687                 break;
1688                 
1689             default:
1690                 break;
1691             }
1692         }
1693         type = type->next;
1694     }
1695     if (nlr)
1696         fprintf(of,"\n");
1697 }
1698
1699 /*-----------------------------------------------------------------*/ 
1700 /* cdbTypeInfo - print the type information for debugger           */
1701 /*-----------------------------------------------------------------*/
1702 void cdbTypeInfo (sym_link *type,FILE *of)
1703 {
1704     fprintf(of,"{%d}",getSize(type));
1705     while (type) {
1706         if (IS_DECL(type)) {
1707             switch (DCL_TYPE(type)) {
1708             case FUNCTION:
1709                 fprintf (of,"DF,");
1710                 break;
1711             case GPOINTER:
1712                 fprintf (of,"DG,");             
1713                 break;          
1714             case CPOINTER:
1715                 fprintf (of,"DC,");             
1716                 break;
1717             case FPOINTER:
1718                 fprintf (of,"DX,");             
1719                 break;
1720             case POINTER:
1721                 fprintf (of,"DD,");             
1722                 break;
1723             case IPOINTER:
1724                 fprintf (of,"DI,");
1725                 break;
1726             case PPOINTER:
1727                 fprintf (of,"DP,");
1728                 break;
1729             case EEPPOINTER:
1730                 fprintf (of,"DA,");
1731                 break;
1732             case ARRAY :
1733                 fprintf (of,"DA%d,",DCL_ELEM(type));
1734                 break;
1735             default:
1736                 break;
1737             }
1738         } else { 
1739             switch (SPEC_NOUN(type)) {
1740             case V_INT:
1741                 if (IS_LONG(type))
1742                     fprintf (of,"SL");
1743                 else
1744                     if (IS_SHORT(type))
1745                         fprintf (of,"SS");
1746                     else
1747                         fprintf (of,"SI");
1748                 break;
1749
1750             case V_CHAR:
1751                 fprintf(of,"SC");
1752                 break;
1753
1754             case V_VOID:
1755                 fprintf(of,"SV");
1756                 break;
1757
1758             case V_FLOAT:
1759                 fprintf(of,"SF");
1760                 break;
1761
1762             case V_STRUCT:
1763                 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1764                 break;
1765                                   
1766             case V_SBIT:
1767                 fprintf(of,"SX");
1768                 break;
1769
1770             case V_BIT:
1771                 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1772                 break;
1773
1774             default:
1775                 break;
1776             }
1777             fputs(":",of);
1778             if (SPEC_USIGN(type))
1779                 fputs("U",of);
1780             else
1781                 fputs("S",of);
1782         }
1783         type = type->next;
1784     }
1785 }
1786 /*-----------------------------------------------------------------*/ 
1787 /* cdbSymbol - prints a symbol & its type information for debugger */
1788 /*-----------------------------------------------------------------*/ 
1789 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1790 {
1791     memmap *map;
1792
1793     if (!sym)
1794         return ;
1795     if (!of)
1796         of = stdout;
1797     
1798     if (isFunc)
1799         fprintf(of,"F:");
1800     else
1801         fprintf(of,"S:"); /* symbol record */
1802     /* if this is not a structure symbol then
1803        we need to figure out the scope information */
1804     if (!isStructSym) {
1805         if (!sym->level) {
1806             /* global */
1807             if (IS_STATIC(sym->etype))
1808                 fprintf(of,"F%s$",moduleName); /* scope is file */
1809             else
1810                 fprintf(of,"G$"); /* scope is global */
1811         }
1812         else 
1813             /* symbol is local */
1814             fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1815     } else
1816         fprintf(of,"S$"); /* scope is structure */
1817     
1818     /* print the name, & mangled name */
1819     fprintf(of,"%s$%d$%d(",sym->name,
1820             sym->level,sym->block);
1821
1822     cdbTypeInfo(sym->type,of);
1823     fprintf(of,"),");
1824     
1825     /* print the address space */
1826     map = SPEC_OCLS(sym->etype);
1827     fprintf(of,"%c,%d,%d",
1828             (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1829     
1830     /* if assigned to registers then output register names */   
1831     /* if this is a function then print
1832        if is it an interrupt routine & interrupt number
1833        and the register bank it is using */
1834     if (isFunc)
1835         fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1836                 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1837     /* alternate location to find this symbol @ : eg registers
1838        or spillication */
1839    
1840     if (!isStructSym)
1841         fprintf(of,"\n");
1842 }                   
1843
1844 /*-----------------------------------------------------------------*/ 
1845 /* cdbStruct - print a structure for debugger                      */
1846 /*-----------------------------------------------------------------*/
1847 void cdbStruct ( structdef *sdef,int block,FILE *of,
1848                  int inStruct, char *tag)
1849 {
1850     symbol *sym;
1851
1852     fprintf(of,"T:");
1853     /* if block # then must have function scope */
1854     fprintf(of,"F%s$",moduleName);
1855     fprintf(of,"%s[",(tag ? tag : sdef->tag));
1856     for (sym=sdef->fields ; sym ; sym = sym->next) {
1857         fprintf(of,"({%d}",sym->offset);
1858             cdbSymbol(sym,of,TRUE,FALSE);
1859         fprintf(of,")");
1860     }
1861     fprintf(of,"]");
1862     if (!inStruct)
1863         fprintf(of,"\n");
1864 }
1865
1866 /*------------------------------------------------------------------*/
1867 /* cdbStructBlock - calls struct printing for a blcks               */
1868 /*------------------------------------------------------------------*/
1869 void cdbStructBlock (int block , FILE *of)
1870 {    
1871     int i ;
1872     bucket **table = StructTab;
1873     bucket  *chain;
1874     wassert(of);
1875
1876     /* go thru the entire  table  */
1877     for ( i = 0 ; i < 256; i++ ) {
1878         for ( chain = table[i]; chain ; chain = chain->next ) {
1879             if (chain->block >= block) {
1880                 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1881             }   
1882         }
1883     }
1884 }
1885                 
1886 /*-----------------------------------------------------------------*/ 
1887 /* powof2 - returns power of two for the number if number is pow 2 */
1888 /*-----------------------------------------------------------------*/ 
1889 int powof2 (unsigned long num)
1890 {
1891     int nshifts = 0;
1892     int n1s = 0 ;
1893     
1894     while (num) {
1895         if (num & 1) n1s++ ;
1896         num >>= 1 ;
1897         nshifts++ ;
1898     }
1899     
1900     if (n1s > 1 || nshifts == 0) return 0;
1901     return nshifts - 1 ;
1902 }
1903
1904 symbol *__fsadd ;
1905 symbol *__fssub ;
1906 symbol *__fsmul ;
1907 symbol *__fsdiv ;
1908 symbol *__fseq  ;
1909 symbol *__fsneq ;
1910 symbol *__fslt  ;
1911 symbol *__fslteq;
1912 symbol *__fsgt  ;
1913 symbol *__fsgteq;
1914
1915 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1916 symbol *__muldiv[3][3][2];
1917 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1918 sym_link *__multypes[3][2];
1919 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1920 symbol *__conv[2][3][2];
1921
1922 sym_link *floatType;
1923
1924 static void _makeRegParam(symbol *sym)
1925 {
1926     value *val ;
1927
1928     val = sym->args; /* loop thru all the arguments   */
1929
1930     /* reset regparm for the port */
1931     (*port->reset_regparms)();
1932     while (val) {
1933         SPEC_REGPARM(val->etype) = 1;
1934         sym->argStack -= getSize(val->type);
1935         val = val->next ;
1936     }
1937 }
1938
1939 /*-----------------------------------------------------------------*/ 
1940 /* initCSupport - create functions for C support routines          */
1941 /*-----------------------------------------------------------------*/ 
1942 void initCSupport ()
1943 {
1944     const char *smuldivmod[] = {
1945         "mul", "div", "mod"
1946     };
1947     const char *sbwd[] = {
1948         "char", "int", "long"
1949     };
1950     const char *ssu[] = {
1951         "s", "u"
1952     };
1953         
1954     int bwd, su, muldivmod, tofrom;
1955
1956     floatType= newFloatLink();
1957
1958     for (bwd = 0; bwd < 3; bwd++) {
1959         sym_link *l;
1960         switch (bwd) {
1961         case 0:
1962             l = newCharLink();
1963             break;
1964         case 1:
1965             l = newIntLink();
1966             break;
1967         case 2:
1968             l = newLongLink();
1969             break;
1970         default:
1971             assert(0);
1972         }
1973         __multypes[bwd][0] = l;
1974         __multypes[bwd][1] = copyLinkChain(l);
1975         SPEC_USIGN(__multypes[bwd][1]) = 1;
1976     }
1977
1978     __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1979     __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1980     __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1981     __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1982     __fseq  = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1983     __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1984     __fslt  = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1985     __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1986     __fsgt  = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1987     __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1988
1989     for (tofrom = 0; tofrom < 2; tofrom++) {
1990         for (bwd = 0; bwd < 3; bwd++) {
1991             for (su = 0; su < 2; su++) {
1992                 if (tofrom) {
1993                     sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1994                     __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1995                 }
1996                 else {
1997                     sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1998                     __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1999                 }
2000             }
2001         }
2002     }
2003
2004     for (muldivmod = 0; muldivmod < 3; muldivmod++) {
2005         for (bwd = 0; bwd < 3; bwd++) {
2006             for (su = 0; su < 2; su++) {
2007                 sprintf(buffer, "_%s%s%s", 
2008                         smuldivmod[muldivmod],
2009                         ssu[su],
2010                         sbwd[bwd]);
2011                 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2012                 SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1;
2013                 if (bwd < port->muldiv.force_reg_param_below) 
2014                     _makeRegParam(__muldiv[muldivmod][bwd][su]);
2015             }
2016         }
2017     }
2018 }