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