Add support for the --disable-boehm-gc flag for systems that lack -lgc.
[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 link  *newLink ()
237 {
238    link *p ;
239
240    ALLOC(p,sizeof(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 (link *ptr, 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 , link *p )
332 {
333     link    *head;
334     link    *tail;
335     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 link  *mergeSpec ( link *dest, 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 link  *cloneSpec ( link *src )
431 {
432     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(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 link  *getSpec ( link *p )
459 {
460     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 link  *newCharLink()
473 {
474     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 link *newFloatLink()
487 {
488     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 link *newLongLink()
501 {
502     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 link  *newIntLink()
516 {
517     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 ( 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 ( 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 link     *reverseLink ( link *type)
702 {
703    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 (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 link *structElemType (link *stype, value *id ,value **argsp)
787 {
788     symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
789     
790     if ( ! fields || ! id)
791         return NULL ;
792        
793     /* look for the id */
794     while (fields) {
795         if (strcmp(fields->rname,id->name) == 0) {
796             if (argsp) {
797                 *argsp = fields->args;
798             }
799             return copyLinkChain (fields->type) ;
800         }
801         fields = fields->next ;
802     }
803     werror(E_NOT_MEMBER,id->name);
804     
805     return NULL ;
806 }
807
808 /*------------------------------------------------------------------*/
809 /* getStructElement - returns element of a tructure definition      */
810 /*------------------------------------------------------------------*/
811 symbol *getStructElement ( structdef *sdef, symbol *sym)
812 {
813     symbol *field ;
814     
815     for ( field = sdef->fields ; field ; field = field->next )
816         if ( strcmp(field->name,sym->name) == 0)
817             return field ;
818     
819     werror(E_NOT_MEMBER,sym->name);
820     
821     return sdef->fields ;
822 }
823
824 /*------------------------------------------------------------------*/
825 /* compStructSize - computes the size of a structure                */
826 /*------------------------------------------------------------------*/
827 int   compStructSize (int su, structdef  *sdef )
828 {
829     int sum = 0 , usum =0;
830     int bitOffset = 0 ;
831     symbol   *loop ;
832     
833     /* for the identifiers  */
834     loop = sdef->fields ;
835     while ( loop ) {
836
837         /* create the internal name for this variable */
838         sprintf (loop->rname,"_%s",loop->name);
839         loop->offset = ( su == UNION ? sum = 0 : sum ) ;
840         SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
841
842         /* if this is a bit field  */
843         if (loop->bitVar)       {
844             
845             /* change it to a unsigned bit */
846             SPEC_NOUN(loop->etype) = V_BIT ;
847             SPEC_USIGN(loop->etype) = 1     ;
848             /* check if this fit into the remaining   */
849             /* bits of this byte else align it to the */
850             /* next byte boundary                     */
851             if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset))  {
852                 SPEC_BSTR(loop->etype) = bitOffset   ;
853                 sum += (loop->bitVar / 8)  ;
854                 bitOffset += (loop->bitVar % 8);
855             } 
856             else  /* does not fit */
857                 {
858                     bitOffset = 0 ;
859                     loop->offset++;   /* go to the next byte  */
860                     sum++         ;
861                     SPEC_BSTR(loop->etype) = bitOffset   ;
862                     sum += (loop->bitVar / 8)  ;
863                     bitOffset += (loop->bitVar % 8);
864                 }
865             /* if this is the last field then pad */
866             if (!loop->next && bitOffset) {
867                 bitOffset = 0 ;
868                 sum++ ;
869             }
870         }
871         else {
872             checkDecl (loop);
873             sum += getSize (loop->type) ;
874         }
875
876         /* if function then do the arguments for it */
877         if (funcInChain(loop->type)) {
878             processFuncArgs (loop, 1);
879         }
880
881         loop = loop->next ;
882
883         /* if this is not a bitfield but the */
884         /* previous one was and did not take */
885         /* the whole byte then pad the rest  */
886         if ((loop && !loop->bitVar) && bitOffset) {
887             bitOffset = 0 ;
888             sum++ ;
889         }
890         
891         /* if union then size = sizeof larget field */
892         if (su == UNION)
893             usum = max(usum,sum);
894     
895     }
896     
897     return (su == UNION ? usum : sum);
898 }
899
900 /*------------------------------------------------------------------*/
901 /* checkSClass - check the storage class specification              */
902 /*------------------------------------------------------------------*/
903 static void  checkSClass ( symbol *sym )
904 {         
905     /* type is literal can happen foe enums change
906        to auto */
907     if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
908         SPEC_SCLS(sym->etype) = S_AUTO;
909
910     /* if sfr or sbit then must also be */
911     /* volatile the initial value will be xlated */
912     /* to an absolute address */
913     if (SPEC_SCLS(sym->etype) == S_SBIT ||
914         SPEC_SCLS(sym->etype) == S_SFR ) {
915         SPEC_VOLATILE(sym->etype) = 1;
916         /* if initial value given */
917         if (sym->ival) {
918             SPEC_ABSA(sym->etype) = 1;
919             SPEC_ADDR(sym->etype) =
920                 (int) list2int(sym->ival);
921             sym->ival = NULL;
922         }
923     }
924
925     /* if absolute address given then it mark it as
926        volatile */
927     if (IS_ABSOLUTE(sym->etype))
928         SPEC_VOLATILE(sym->etype) = 1;
929
930     /* global variables declared const put into code */
931     if (sym->level == 0 && 
932         SPEC_SCLS(sym->etype) == S_CONSTANT) {
933         SPEC_SCLS(sym->etype) = S_CODE ;
934         SPEC_CONST(sym->etype) = 1;
935     }
936
937     /* global variable in code space is a constant */
938     if (sym->level == 0 && 
939         SPEC_SCLS(sym->etype) == S_CODE &&
940         port->mem.code_ro )
941         SPEC_CONST(sym->etype) = 1;
942     
943
944     /* if bit variable then no storage class can be */
945     /* specified since bit is already a storage */
946     if ( IS_BITVAR(sym->etype)              && 
947          ( SPEC_SCLS(sym->etype) != S_FIXED &&   
948            SPEC_SCLS(sym->etype) != S_SBIT  &&
949            SPEC_SCLS(sym->etype) != S_BIT )
950          ) {
951         werror (E_BITVAR_STORAGE,sym->name);
952         SPEC_SCLS(sym->etype) = S_FIXED ;
953     }
954     
955     /* extern variables cannot be initialized */
956     if (IS_EXTERN(sym->etype) && sym->ival)     {
957         werror(E_EXTERN_INIT,sym->name);
958         sym->ival = NULL;
959     }    
960     
961     /* if this is an automatic symbol then */
962     /* storage class will be ignored and   */
963     /* symbol will be allocated on stack/  */
964     /* data depending on flag             */
965     if ( sym->level                             &&
966          (options.stackAuto || reentrant )      &&
967          ( SPEC_SCLS(sym->etype) != S_AUTO      &&
968            SPEC_SCLS(sym->etype) != S_FIXED     &&
969            SPEC_SCLS(sym->etype) != S_REGISTER  &&
970            SPEC_SCLS(sym->etype) != S_STACK     &&
971            SPEC_SCLS(sym->etype) != S_XSTACK    &&
972            SPEC_SCLS(sym->etype) != S_CONSTANT  )) {
973
974         werror(E_AUTO_ASSUMED,sym->name) ;
975         SPEC_SCLS(sym->etype) = S_AUTO   ;
976     }
977         
978     /* automatic symbols cannot be given   */
979     /* an absolute address ignore it      */
980     if ( sym->level  && 
981          SPEC_ABSA(sym->etype) &&
982          (options.stackAuto || reentrant) )  {
983         werror(E_AUTO_ABSA,sym->name);
984         SPEC_ABSA(sym->etype) = 0 ;
985     }
986         
987     /* arrays & pointers cannot be defined for bits   */
988     /* SBITS or SFRs or BIT                           */
989     if ((IS_ARRAY(sym->type) || IS_PTR(sym->type))  &&
990         ( SPEC_NOUN(sym->etype) == V_BIT          || 
991          SPEC_NOUN(sym->etype) == V_SBIT             ||
992          SPEC_SCLS(sym->etype) == S_SFR              ))
993         werror(E_BIT_ARRAY,sym->name);
994     
995     /* if this is a bit|sbit then set length & start  */
996     if (SPEC_NOUN(sym->etype) == V_BIT              ||
997         SPEC_NOUN(sym->etype) == V_SBIT             )  {
998         SPEC_BLEN(sym->etype) = 1 ;
999         SPEC_BSTR(sym->etype) = 0 ;
1000     }    
1001     
1002     /* variables declared in CODE space must have */
1003     /* initializers if not an extern */
1004     if (SPEC_SCLS(sym->etype) == S_CODE && 
1005         sym->ival == NULL               &&
1006         !sym->level                     &&
1007         port->mem.code_ro               &&
1008         !IS_EXTERN(sym->etype)) 
1009         werror(E_CODE_NO_INIT,sym->name);
1010     
1011     /* if parameter or local variable then change */
1012     /* the storage class to reflect where the var will go */
1013     if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1014         if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1015         {
1016             SPEC_SCLS(sym->etype) = (options.useXstack  ?
1017                                      S_XSTACK : S_STACK ) ;
1018         }
1019         else
1020         {
1021             /* hack-o-matic! I see no reason why the useXstack option should ever
1022              * control this allcoation, but the code was originally that way, and
1023              * changing it for non-390 ports breaks the compiler badly.
1024              */
1025             bool useXdata = IS_DS390_PORT ? options.model : options.useXstack;
1026             SPEC_SCLS(sym->etype) = (useXdata  ?
1027                                      S_XDATA : S_FIXED ) ;
1028         }
1029     }
1030 }
1031
1032 /*------------------------------------------------------------------*/
1033 /* changePointer - change pointer to functions                      */
1034 /*------------------------------------------------------------------*/
1035 void  changePointer  (symbol  *sym)
1036 {
1037     link *p ;
1038     
1039     /* go thru the chain of declarations   */
1040     /* if we find a pointer to a function  */
1041     /* unconditionally change it to a ptr  */
1042     /* to code area                        */
1043     for ( p = sym->type ; p ; p = p->next) {
1044         if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1045             DCL_TYPE(p) = GPOINTER ;
1046         if ( IS_PTR(p) && IS_FUNC(p->next))
1047             DCL_TYPE(p) = CPOINTER ;
1048     }
1049 }
1050
1051 /*------------------------------------------------------------------*/
1052 /* checkDecl - does semantic validation of a declaration                   */
1053 /*------------------------------------------------------------------*/
1054 int checkDecl ( symbol *sym )
1055 {
1056     
1057     checkSClass  (sym); /* check the storage class      */
1058     changePointer(sym);  /* change pointers if required */
1059
1060     /* if this is an array without any dimension
1061        then update the dimension from the initial value */
1062     if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1063         DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);    
1064
1065     return 0 ;
1066 }
1067
1068 /*------------------------------------------------------------------*/
1069 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1070 /*------------------------------------------------------------------*/
1071 link  *copyLinkChain ( link *p)
1072 {
1073     link  *head, *curr , *loop;
1074     
1075     curr = p ;
1076     head = loop = ( curr ? newLink() : (void *) NULL) ;
1077     while (curr)   {
1078         memcpy(loop,curr,sizeof(link)) ; /* copy it */
1079         loop->next = (curr->next ? newLink() : (void *) NULL) ;
1080         loop = loop->next ;
1081         curr = curr->next ;
1082     }
1083     
1084     return head ;
1085 }
1086
1087
1088 /*------------------------------------------------------------------*/
1089 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1090 /*                symbols in the given block                        */
1091 /*------------------------------------------------------------------*/
1092 void cleanUpBlock ( bucket **table, int block)
1093 {    
1094     int i ;
1095     bucket  *chain;
1096     
1097     /* go thru the entire  table  */
1098     for ( i = 0 ; i < 256; i++ ) {
1099         for ( chain = table[i]; chain ; chain = chain->next ) {
1100             if (chain->block >= block) {
1101                 deleteSym (table,chain->sym,chain->name);                                 
1102             }   
1103         }
1104     }
1105 }
1106
1107 /*------------------------------------------------------------------*/
1108 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1109 /*                symbols in the given level                        */
1110 /*------------------------------------------------------------------*/
1111 void  cleanUpLevel   (bucket  **table, int level )
1112 {
1113     int i ;
1114     bucket  *chain;
1115     
1116     /* go thru the entire  table  */
1117     for ( i = 0 ; i < 256; i++ ) {
1118         for ( chain = table[i]; chain ; chain = chain->next ) {
1119             if (chain->level >= level) {
1120                 deleteSym (table,chain->sym,chain->name);                                 
1121             }   
1122         }
1123     }
1124 }
1125
1126 /*------------------------------------------------------------------*/
1127 /* computeType - computes the resultant type from two types         */
1128 /*------------------------------------------------------------------*/
1129 link *computeType ( link *type1, link *type2)
1130 {
1131     link *rType ;
1132     link *reType;
1133     link *etype1 = getSpec(type1);
1134     link *etype2 = getSpec(type2);
1135     
1136     /* if one of them is a float then result is a float */
1137     /* here we assume that the types passed are okay */
1138     /* and can be cast to one another                */
1139     /* which ever is greater in size */
1140     if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1141         rType = newFloatLink();
1142     else
1143         /* if only one of them is a bit variable
1144            then the other one prevails */
1145         if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1146             rType = copyLinkChain(type2);
1147         else
1148             if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1149                 rType = copyLinkChain(type1);
1150             else
1151                 /* if one of them is a pointer then that
1152                    prevails */
1153                 if (IS_PTR(type1))
1154                     rType = copyLinkChain(type1);
1155                 else
1156                     if (IS_PTR(type2))
1157                         rType = copyLinkChain(type2);
1158                     else
1159                         if (getSize (type1) > getSize(type2) )
1160                             rType = copyLinkChain(type1);
1161                         else
1162                             rType = copyLinkChain(type2);
1163     
1164     reType = getSpec(rType);
1165     
1166     /* if either of them unsigned then make this unsigned */
1167     if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1168         SPEC_USIGN(reType) = 1;
1169     
1170     /* if result is a literal then make not so */
1171     if (IS_LITERAL(reType))
1172         SPEC_SCLS(reType) = S_REGISTER ;
1173     
1174     return rType;
1175 }
1176
1177 /*------------------------------------------------------------------*/
1178 /* checkType - will do type check return 1 if match                 */
1179 /*------------------------------------------------------------------*/
1180 int checkType ( link *dest, link *src )
1181 {
1182     if ( !dest && !src)
1183         return 1;
1184     
1185     if (dest && !src)
1186         return 0;
1187     
1188     if (src && !dest)
1189         return 0;
1190     
1191     /* if dest is a declarator then */
1192     if (IS_DECL(dest)) {
1193         if (IS_DECL(src)) {
1194             if (DCL_TYPE(src) == DCL_TYPE(dest))
1195                 return checkType(dest->next,src->next);
1196             else
1197                 if (IS_PTR(src) && IS_PTR(dest))
1198                     return -1;
1199                 else
1200                     if (IS_PTR(dest) && IS_ARRAY(src))
1201                         return -1;
1202                     else 
1203                         if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1204                             return -1 * checkType (dest->next,src) ;
1205                         else
1206                             return 0;
1207         }
1208         else
1209             if (IS_PTR(dest) && IS_INTEGRAL(src))
1210                 return -1;
1211             else
1212                 return 0;
1213     }
1214
1215     /* if one is a specifier and the other is not */
1216     if ((IS_SPEC(src) && !IS_SPEC(dest)) ||
1217         (IS_SPEC(dest) && !IS_SPEC(src))) return 0;
1218
1219     /* if one of them is a void then ok */
1220     if (SPEC_NOUN(dest) == V_VOID    &&
1221         SPEC_NOUN(src)  != V_VOID    )
1222         return -1 ;
1223     
1224     if (SPEC_NOUN(dest) != V_VOID &&
1225         SPEC_NOUN(src) == V_VOID )
1226         return -1;
1227     
1228     /* char === to short */
1229     if (SPEC_NOUN(dest) == V_CHAR &&
1230         SPEC_NOUN(src)  == V_INT  &&
1231         SPEC_SHORT(src)           )
1232         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1233
1234     if (SPEC_NOUN(src) == V_CHAR &&
1235         SPEC_NOUN(dest)  == V_INT  &&
1236         SPEC_SHORT(dest)           )
1237         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);    
1238
1239     /* if they are both bitfields then if the lengths
1240        and starts don't match */
1241     if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1242         (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1243          SPEC_BSTR(dest) != SPEC_BSTR(src)))
1244             return -1;
1245     
1246     /* it is a specifier */
1247     if (SPEC_NOUN(dest) != SPEC_NOUN(src))      {
1248         if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1249             IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1250             getSize(dest) == getSize(src))
1251             return 1;
1252         else
1253             if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1254                 return -1;
1255         else
1256             return 0;
1257     }
1258     else
1259         if (IS_STRUCT(dest)) {
1260             if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1261                 return 0 ;
1262             else 
1263                 return 1 ;
1264         }
1265     if (SPEC_LONG(dest) != SPEC_LONG(src))
1266         return -1;
1267     
1268     if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1269         return -1;
1270     
1271     if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1272         return -2;
1273     
1274     return 1;   
1275 }
1276
1277 /*------------------------------------------------------------------*/
1278 /* inCalleeSaveList - return 1 if found in calle save list          */
1279 /*------------------------------------------------------------------*/
1280 bool inCalleeSaveList ( char *s)
1281 {
1282     int i;
1283     
1284     for (i = 0 ; options.calleeSaves[i] ; i++ )
1285         if (strcmp(options.calleeSaves[i],s) == 0)
1286             return 1;
1287
1288     return 0;
1289 }
1290
1291 /*------------------------------------------------------------------*/
1292 /* checkFunction - does all kinds of check on a function            */
1293 /*------------------------------------------------------------------*/
1294 int   checkFunction (symbol   *sym)
1295 {
1296     symbol *csym ;
1297     value  *exargs, *acargs ;
1298     int argCnt = 0 ;
1299     
1300     /* if not type then some kind of error */
1301     if ( !sym->type )
1302         return 0;
1303     
1304     /* if the function has no type then make it return int */
1305     if ( !sym->type->next )
1306         sym->type->next = sym->etype = newIntLink();
1307    
1308     /* function cannot return aggregate */
1309     if (IS_AGGREGATE(sym->type->next))   {
1310         werror(E_FUNC_AGGR,sym->name);
1311         return 0;      
1312     }
1313            
1314     /* function cannot return bit */
1315     if (IS_BITVAR(sym->type->next)) {
1316         werror(E_FUNC_BIT,sym->name);
1317         return 0;
1318     }
1319     
1320     /* check if this function is defined as calleeSaves
1321        then mark it as such */
1322     sym->calleeSave = inCalleeSaveList(sym->name); 
1323
1324     /* if interrupt service routine  */
1325     /* then it cannot have arguments */
1326     if ( sym->args  && IS_ISR(sym->etype) && !IS_VOID(sym->args->type))   {
1327         werror(E_INT_ARGS,sym->name);     
1328         sym->args = NULL ;
1329     }
1330     
1331     if (!(csym = findSym (SymbolTab, sym, sym->name )))
1332         return 1 ;  /* not defined nothing more to check  */
1333     
1334     /* check if body already present */
1335     if ( csym && csym->fbody )   {
1336         werror(E_FUNC_BODY,sym->name);
1337         return 0;
1338     }
1339     
1340     /* check the return value type   */
1341     if (checkType (csym->type,sym->type) <= 0) {
1342         werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1343         werror (E_CONTINUE,"previous defintion type ");
1344         printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1345         werror (E_CONTINUE,"current definition type ");
1346         printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1347         return 0;
1348     }
1349
1350     if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1351         werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1352         return 0;
1353     }
1354
1355     if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1356         werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1357         return 0;
1358     }
1359
1360     /* compare expected agrs with actual args */
1361     exargs = csym->args ;
1362     acargs = sym->args  ;
1363     
1364     /* for all the expected args do */
1365     for (argCnt =  1    ; 
1366          exargs && acargs ; 
1367          exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1368         if ( checkType(exargs->type,acargs->type) <= 0) {
1369             werror(E_ARG_TYPE,argCnt);
1370             return 0;
1371         }
1372     }
1373     
1374     /* if one them ended we have a problem */
1375     if ((exargs && !acargs && !IS_VOID(exargs->type)) || 
1376         (!exargs && acargs && !IS_VOID(acargs->type)))
1377         werror(E_ARG_COUNT);
1378     
1379     /* replace with this defition */
1380     sym->cdef = csym->cdef;
1381     deleteSym (SymbolTab,csym,csym->name);
1382     addSym    (SymbolTab,sym,sym->name,sym->level,sym->block);
1383     if (IS_EXTERN(csym->etype) && !
1384         IS_EXTERN(sym->etype)) {
1385         addSet(&publics,sym);
1386     }
1387     return 1 ;      
1388 }
1389
1390 /*-----------------------------------------------------------------*/
1391 /* processFuncArgs - does some processing with function args       */
1392 /*-----------------------------------------------------------------*/
1393 void  processFuncArgs   (symbol *func, int ignoreName)
1394 {
1395     value *val ;
1396     int pNum = 1;   
1397     
1398
1399     /* if this function has variable argument list */
1400     /* then make the function a reentrant one      */
1401     if (func->hasVargs)
1402         SPEC_RENT(func->etype) = 1;
1403
1404     /* check if this function is defined as calleeSaves
1405        then mark it as such */
1406     func->calleeSave = inCalleeSaveList(func->name); 
1407
1408     val = func->args; /* loop thru all the arguments   */
1409         
1410     /* if it is void then remove parameters */
1411     if (val && IS_VOID(val->type)) {     
1412         func->args = NULL ;
1413         return ;
1414     }
1415
1416     /* reset regparm for the port */
1417     (*port->reset_regparms)();
1418     /* if any of the arguments is an aggregate */
1419     /* change it to pointer to the same type */
1420     while (val) {
1421         /* mark it as a register parameter if
1422            the function does not have VA_ARG
1423            and as port dictates
1424            not inhibited by command line option or #pragma */
1425         if (!func->hasVargs       &&        
1426             !options.noregparms   &&
1427             !IS_RENT(func->etype) &&
1428             (*port->reg_parm)(val->type)) {
1429             SPEC_REGPARM(val->etype) = 1;
1430         }
1431         
1432         if ( IS_AGGREGATE(val->type)) {
1433             /* if this is a structure */
1434             /* then we need to add a new link */
1435             if (IS_STRUCT(val->type)) {
1436                                 /* first lets add DECLARATOR type */
1437                 link *p = val->type ;
1438                 
1439                 werror(W_STRUCT_AS_ARG,val->name);
1440                 val->type = newLink();
1441                 val->type->next = p ;                           
1442             }
1443             
1444             /* change to a pointer depending on the */
1445             /* storage class specified                          */
1446             switch (SPEC_SCLS(val->etype)) {
1447             case S_IDATA:
1448                 DCL_TYPE(val->type) = IPOINTER;
1449                 break;
1450             case S_PDATA:
1451                 DCL_TYPE(val->type) = PPOINTER;
1452                 break;
1453             case S_FIXED:
1454             case S_AUTO:
1455             case S_DATA:
1456             case S_REGISTER:
1457                 DCL_TYPE(val->type) = POINTER ;
1458                 break;
1459             case S_CODE:
1460                 DCL_TYPE(val->type) = CPOINTER;
1461                 break;
1462             case S_XDATA:
1463                 DCL_TYPE(val->type) = FPOINTER;
1464                 break;
1465             case S_EEPROM:
1466                 DCL_TYPE(val->type) = EEPPOINTER;
1467                 break;
1468             default :
1469                 DCL_TYPE(val->type) = GPOINTER;
1470             }
1471             
1472             /* is there is a symbol associated then */
1473             /* change the type of the symbol as well*/
1474             if ( val->sym ) {          
1475                 val->sym->type = copyLinkChain(val->type);
1476                 val->sym->etype = getSpec(val->sym->type);
1477             }
1478         }
1479         
1480         val = val->next ;
1481         pNum++;
1482     }
1483     
1484     /* if this function is reentrant or */
1485     /* automatics r 2b stacked then nothing */
1486     if (IS_RENT(func->etype) || options.stackAuto )
1487         return ;
1488     
1489     val = func->args;
1490     pNum = 1;
1491     while (val) {
1492         
1493         /* if a symbolname is not given  */
1494         /* synthesize a variable name */
1495         if (!val->sym) {
1496
1497             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1498             val->sym = newSymbol(val->name,1);
1499             SPEC_OCLS(val->etype) = port->mem.default_local_map;
1500             val->sym->type = copyLinkChain (val->type);
1501             val->sym->etype = getSpec (val->sym->type);
1502             val->sym->_isparm = 1;
1503             strcpy (val->sym->rname,val->name);  
1504             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1505                 SPEC_STAT(func->etype);
1506             addSymChain(val->sym);
1507    
1508         }
1509         else  /* symbol name given create synth name */      {
1510             
1511             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1512             strcpy (val->sym->rname,val->name);
1513             val->sym->_isparm = 1;
1514             SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) = 
1515                 (options.model != MODEL_SMALL ? xdata : data);
1516             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = 
1517                 SPEC_STAT(func->etype);
1518         }
1519         val = val->next ;
1520     }
1521 }
1522
1523 /*-----------------------------------------------------------------*/
1524 /* isSymbolEqual - compares two symbols return 1 if they match     */
1525 /*-----------------------------------------------------------------*/
1526 int isSymbolEqual (symbol *dest, symbol *src)
1527 {
1528     /* if pointers match then equal */
1529     if (dest == src)
1530         return 1;
1531
1532     /* if one of them is null then don't match */
1533     if (!dest || !src)
1534         return 0;
1535     
1536     /* if both of them have rname match on rname */
1537     if (dest->rname[0] && src->rname[0]) 
1538         return (!strcmp(dest->rname,src->rname));
1539     
1540     /* otherwise match on name */
1541     return (!strcmp(dest->name,src->name));
1542 }
1543
1544 /*-----------------------------------------------------------------*/ 
1545 /* printTypeChain - prints the type chain in human readable form   */
1546 /*-----------------------------------------------------------------*/ 
1547 void printTypeChain (link *type, FILE *of)
1548 {
1549     int nlr = 0;
1550
1551     if (!of) {
1552         of = stdout;
1553         nlr = 1;
1554     }
1555
1556     while (type) {
1557         if (IS_DECL(type)) {
1558             switch (DCL_TYPE(type)) {
1559             case FUNCTION:
1560                 fprintf (of,"function ");
1561                 break;
1562             case GPOINTER:
1563                 fprintf (of,"_generic * ");
1564                 if (DCL_PTR_CONST(type))
1565                     fprintf(of,"const ");
1566                 break;          
1567             case CPOINTER:
1568                 fprintf (of,"_code * ");
1569                 if (DCL_PTR_CONST(type))
1570                     fprintf(of,"const ");
1571                 break;
1572             case FPOINTER:
1573                 fprintf (of,"_far * ");
1574                 if (DCL_PTR_CONST(type))
1575                     fprintf(of,"const ");
1576                 break;
1577             case EEPPOINTER:
1578                 fprintf (of,"_eeprom * ");
1579                 if (DCL_PTR_CONST(type))
1580                     fprintf(of,"const ");
1581                 break;
1582                 
1583             case POINTER:
1584                 fprintf (of,"_near * ");
1585                 if (DCL_PTR_CONST(type))
1586                     fprintf(of,"const ");       
1587                 break;
1588             case IPOINTER:
1589                 fprintf (of,"_idata *");
1590                 if (DCL_PTR_CONST(type))
1591                     fprintf(of,"const ");       
1592                 break; 
1593             case PPOINTER:
1594                 fprintf (of,"_pdata *");
1595                 if (DCL_PTR_CONST(type))
1596                     fprintf(of,"const ");       
1597                 break;
1598             case UPOINTER:
1599                 fprintf (of," _unkown *");
1600                 if (DCL_PTR_CONST(type))
1601                     fprintf(of,"const ");       
1602                 break;
1603                 
1604             case ARRAY :
1605                 fprintf (of,"array of ");
1606                 break;
1607             }
1608         } else { 
1609             if (SPEC_VOLATILE(type))
1610                 fprintf (of,"volatile "); 
1611             if (SPEC_USIGN(type))
1612                 fprintf (of,"unsigned ");
1613             
1614             switch (SPEC_NOUN(type)) {
1615             case V_INT:
1616                 if (IS_LONG(type))
1617                     fprintf (of,"long ");
1618                 else
1619                     if (IS_SHORT(type))
1620                         fprintf (of,"short ");
1621                     else
1622                         fprintf (of,"int ");
1623                 break;
1624
1625             case V_CHAR:
1626                 fprintf(of,"char ");
1627                 break;
1628
1629             case V_VOID:
1630                 fprintf(of,"void ");
1631                 break;
1632
1633             case V_FLOAT:
1634                 fprintf(of,"float ");
1635                 break;
1636
1637             case V_STRUCT:
1638                 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1639                 break;
1640                                   
1641             case V_SBIT:
1642                 fprintf(of,"sbit ");
1643                 break;
1644
1645             case V_BIT:
1646                 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1647                 break;
1648                 
1649             default:
1650                 break;
1651             }
1652         }
1653         type = type->next;
1654     }
1655     if (nlr)
1656         fprintf(of,"\n");
1657 }
1658
1659 /*-----------------------------------------------------------------*/ 
1660 /* cdbTypeInfo - print the type information for debugger           */
1661 /*-----------------------------------------------------------------*/
1662 void cdbTypeInfo (link *type,FILE *of)
1663 {
1664     fprintf(of,"{%d}",getSize(type));
1665     while (type) {
1666         if (IS_DECL(type)) {
1667             switch (DCL_TYPE(type)) {
1668             case FUNCTION:
1669                 fprintf (of,"DF,");
1670                 break;
1671             case GPOINTER:
1672                 fprintf (of,"DG,");             
1673                 break;          
1674             case CPOINTER:
1675                 fprintf (of,"DC,");             
1676                 break;
1677             case FPOINTER:
1678                 fprintf (of,"DX,");             
1679                 break;
1680             case POINTER:
1681                 fprintf (of,"DD,");             
1682                 break;
1683             case IPOINTER:
1684                 fprintf (of,"DI,");
1685                 break;
1686             case PPOINTER:
1687                 fprintf (of,"DP,");
1688                 break;
1689             case EEPPOINTER:
1690                 fprintf (of,"DA,");
1691                 break;
1692             case ARRAY :
1693                 fprintf (of,"DA%d,",DCL_ELEM(type));
1694                 break;
1695             default:
1696                 break;
1697             }
1698         } else { 
1699             switch (SPEC_NOUN(type)) {
1700             case V_INT:
1701                 if (IS_LONG(type))
1702                     fprintf (of,"SL");
1703                 else
1704                     if (IS_SHORT(type))
1705                         fprintf (of,"SS");
1706                     else
1707                         fprintf (of,"SI");
1708                 break;
1709
1710             case V_CHAR:
1711                 fprintf(of,"SC");
1712                 break;
1713
1714             case V_VOID:
1715                 fprintf(of,"SV");
1716                 break;
1717
1718             case V_FLOAT:
1719                 fprintf(of,"SF");
1720                 break;
1721
1722             case V_STRUCT:
1723                 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1724                 break;
1725                                   
1726             case V_SBIT:
1727                 fprintf(of,"SX");
1728                 break;
1729
1730             case V_BIT:
1731                 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1732                 break;
1733
1734             default:
1735                 break;
1736             }
1737             fputs(":",of);
1738             if (SPEC_USIGN(type))
1739                 fputs("U",of);
1740             else
1741                 fputs("S",of);
1742         }
1743         type = type->next;
1744     }
1745 }
1746 /*-----------------------------------------------------------------*/ 
1747 /* cdbSymbol - prints a symbol & its type information for debugger */
1748 /*-----------------------------------------------------------------*/ 
1749 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1750 {
1751     memmap *map;
1752
1753     if (!sym)
1754         return ;
1755     if (!of)
1756         of = stdout;
1757     
1758     if (isFunc)
1759         fprintf(of,"F:");
1760     else
1761         fprintf(of,"S:"); /* symbol record */
1762     /* if this is not a structure symbol then
1763        we need to figure out the scope information */
1764     if (!isStructSym) {
1765         if (!sym->level) {
1766             /* global */
1767             if (IS_STATIC(sym->etype))
1768                 fprintf(of,"F%s$",moduleName); /* scope is file */
1769             else
1770                 fprintf(of,"G$"); /* scope is global */
1771         }
1772         else 
1773             /* symbol is local */
1774             fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1775     } else
1776         fprintf(of,"S$"); /* scope is structure */
1777     
1778     /* print the name, & mangled name */
1779     fprintf(of,"%s$%d$%d(",sym->name,
1780             sym->level,sym->block);
1781
1782     cdbTypeInfo(sym->type,of);
1783     fprintf(of,"),");
1784     
1785     /* print the address space */
1786     map = SPEC_OCLS(sym->etype);
1787     fprintf(of,"%c,%d,%d",
1788             (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1789     
1790     /* if assigned to registers then output register names */   
1791     /* if this is a function then print
1792        if is it an interrupt routine & interrupt number
1793        and the register bank it is using */
1794     if (isFunc)
1795         fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1796                 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1797     /* alternate location to find this symbol @ : eg registers
1798        or spillication */
1799    
1800     if (!isStructSym)
1801         fprintf(of,"\n");
1802 }                   
1803
1804 /*-----------------------------------------------------------------*/ 
1805 /* cdbStruct - print a structure for debugger                      */
1806 /*-----------------------------------------------------------------*/
1807 void cdbStruct ( structdef *sdef,int block,FILE *of,
1808                  int inStruct, char *tag)
1809 {
1810     symbol *sym;
1811
1812     fprintf(of,"T:");
1813     /* if block # then must have function scope */
1814     fprintf(of,"F%s$",moduleName);
1815     fprintf(of,"%s[",(tag ? tag : sdef->tag));
1816     for (sym=sdef->fields ; sym ; sym = sym->next) {
1817         fprintf(of,"({%d}",sym->offset);
1818             cdbSymbol(sym,of,TRUE,FALSE);
1819         fprintf(of,")");
1820     }
1821     fprintf(of,"]");
1822     if (!inStruct)
1823         fprintf(of,"\n");
1824 }
1825
1826 /*------------------------------------------------------------------*/
1827 /* cdbStructBlock - calls struct printing for a blcks               */
1828 /*------------------------------------------------------------------*/
1829 void cdbStructBlock (int block , FILE *of)
1830 {    
1831     int i ;
1832     bucket **table = StructTab;
1833     bucket  *chain;
1834     wassert(of);
1835
1836     /* go thru the entire  table  */
1837     for ( i = 0 ; i < 256; i++ ) {
1838         for ( chain = table[i]; chain ; chain = chain->next ) {
1839             if (chain->block >= block) {
1840                 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1841             }   
1842         }
1843     }
1844 }
1845                 
1846 /*-----------------------------------------------------------------*/ 
1847 /* powof2 - returns power of two for the number if number is pow 2 */
1848 /*-----------------------------------------------------------------*/ 
1849 int powof2 (unsigned long num)
1850 {
1851     int nshifts = 0;
1852     int n1s = 0 ;
1853     
1854     while (num) {
1855         if (num & 1) n1s++ ;
1856         num >>= 1 ;
1857         nshifts++ ;
1858     }
1859     
1860     if (n1s > 1 || nshifts == 0) return 0;
1861     return nshifts - 1 ;
1862 }
1863
1864 symbol *__fsadd ;
1865 symbol *__fssub ;
1866 symbol *__fsmul ;
1867 symbol *__fsdiv ;
1868 symbol *__fseq  ;
1869 symbol *__fsneq ;
1870 symbol *__fslt  ;
1871 symbol *__fslteq;
1872 symbol *__fsgt  ;
1873 symbol *__fsgteq;
1874
1875 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1876 symbol *__muldiv[3][3][2];
1877 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1878 link *__multypes[3][2];
1879 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1880 symbol *__conv[2][3][2];
1881
1882 link *floatType;
1883
1884 static void _makeRegParam(symbol *sym)
1885 {
1886     value *val ;
1887
1888     val = sym->args; /* loop thru all the arguments   */
1889
1890     /* reset regparm for the port */
1891     (*port->reset_regparms)();
1892     while (val) {
1893         SPEC_REGPARM(val->etype) = 1;
1894         sym->argStack -= getSize(val->type);
1895         val = val->next ;
1896     }
1897 }
1898
1899 /*-----------------------------------------------------------------*/ 
1900 /* initCSupport - create functions for C support routines          */
1901 /*-----------------------------------------------------------------*/ 
1902 void initCSupport ()
1903 {
1904     const char *smuldivmod[] = {
1905         "mul", "div", "mod"
1906     };
1907     const char *sbwd[] = {
1908         "char", "int", "long"
1909     };
1910     const char *ssu[] = {
1911         "s", "u"
1912     };
1913         
1914     int bwd, su, muldivmod, tofrom;
1915
1916     floatType= newFloatLink();
1917
1918     for (bwd = 0; bwd < 3; bwd++) {
1919         link *l;
1920         switch (bwd) {
1921         case 0:
1922             l = newCharLink();
1923             break;
1924         case 1:
1925             l = newIntLink();
1926             break;
1927         case 2:
1928             l = newLongLink();
1929             break;
1930         default:
1931             assert(0);
1932         }
1933         __multypes[bwd][0] = l;
1934         __multypes[bwd][1] = copyLinkChain(l);
1935         SPEC_USIGN(__multypes[bwd][1]) = 1;
1936     }
1937
1938     __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1939     __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1940     __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1941     __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1942     __fseq  = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1943     __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1944     __fslt  = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1945     __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1946     __fsgt  = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1947     __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1948
1949     for (tofrom = 0; tofrom < 2; tofrom++) {
1950         for (bwd = 0; bwd < 3; bwd++) {
1951             for (su = 0; su < 2; su++) {
1952                 if (tofrom) {
1953                     sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1954                     __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1955                 }
1956                 else {
1957                     sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1958                     __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1959                 }
1960             }
1961         }
1962     }
1963
1964     for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1965         for (bwd = 0; bwd < 3; bwd++) {
1966             for (su = 0; su < 2; su++) {
1967                 sprintf(buffer, "_%s%s%s", 
1968                         smuldivmod[muldivmod],
1969                         ssu[su],
1970                         sbwd[bwd]);
1971                 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
1972                 SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1;
1973                 if (bwd < port->muldiv.force_reg_param_below) 
1974                     _makeRegParam(__muldiv[muldivmod][bwd][su]);
1975             }
1976         }
1977     }
1978 }