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