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