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