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