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