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