Now the pointer_type information of a storeage
[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) = 1;
297             DCL_TYPE(ptr) = CPOINTER ;
298             break;
299         case S_FLASH:
300             DCL_TYPE(ptr) = FLPOINTER;
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     
536     if ( IS_SPEC(p) ) { /* if this is the specifier then */
537         
538         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
539         case V_INT:
540             return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
541         case V_FLOAT:
542             return FLOATSIZE ;
543         case V_CHAR:
544             return   CHARSIZE ;
545         case V_VOID:
546             return   0 ;
547         case V_STRUCT:
548             return   SPEC_STRUCT(p)->size ;
549         case V_LABEL:
550             return 0 ;
551         case V_SBIT:
552             return BITSIZE ;
553         case V_BIT:
554             return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
555         default  :
556             return 0 ;
557         }
558     }
559     
560     /* this is a specifier  */
561     switch (DCL_TYPE(p))  {
562     case FUNCTION:
563         return 2;
564     case ARRAY:
565         return DCL_ELEM(p) * getSize (p->next) ;
566     case IPOINTER:
567     case PPOINTER:
568     case POINTER:
569         return ( PTRSIZE ) ;
570     case FLPOINTER:
571     case FPOINTER:
572     case CPOINTER:
573         return ( FPTRSIZE );
574     case GPOINTER:      
575         return ( GPTRSIZE );
576         
577     default     :
578         return  0 ;
579     }
580 }
581
582 /*------------------------------------------------------------------*/
583 /* bitsForType - returns # of bits required to store this type      */
584 /*------------------------------------------------------------------*/
585 unsigned int   bitsForType ( link *p )
586 {
587     /* if nothing return 0 */
588     if ( ! p )
589         return 0 ;
590     
591     if ( IS_SPEC(p) ) { /* if this is the specifier then */
592         
593         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
594         case V_INT:
595             return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
596         case V_FLOAT:
597             return FLOATSIZE*8 ;
598         case V_CHAR:
599             return   CHARSIZE*8 ;
600         case V_VOID:
601             return   0 ;
602         case V_STRUCT:
603             return   SPEC_STRUCT(p)->size*8 ;
604         case V_LABEL:
605             return 0 ;
606         case V_SBIT:
607             return 1 ;
608         case V_BIT:
609             return SPEC_BLEN(p);
610         default  :
611             return 0 ;
612         }
613     }
614     
615     /* this is a specifier  */
616     switch (DCL_TYPE(p))  {
617     case FUNCTION:
618         return 2;
619     case ARRAY:
620         return DCL_ELEM(p) * getSize (p->next) *8 ;
621     case IPOINTER:
622     case PPOINTER:
623     case POINTER:
624         return ( PTRSIZE * 8) ;
625     case FLPOINTER:
626     case FPOINTER:
627     case CPOINTER:
628         return ( FPTRSIZE * 8);
629     case GPOINTER:
630         return ( GPTRSIZE * 8);
631         
632     default     :
633         return  0 ;
634     }
635 }
636
637 /*------------------------------------------------------------------*/
638 /* copySymbolChain - copies a symbol chain                          */
639 /*------------------------------------------------------------------*/
640 symbol *copySymbolChain (symbol *src)
641 {
642         symbol *dest ;
643
644         if (!src)
645                 return NULL ;
646
647         dest = copySymbol(src);
648         dest->next = copySymbolChain(src->next);
649         return dest ;
650 }
651
652 /*------------------------------------------------------------------*/
653 /* copySymbol - makes a copy of a symbol                            */
654 /*------------------------------------------------------------------*/
655 symbol  *copySymbol     (symbol *src)
656 {
657         symbol *dest;
658
659         if (!src )
660                 return NULL ;
661
662         dest = newSymbol( src->name, src->level );
663         memcpy(dest,src,sizeof(symbol));
664         dest->level = src->level ;
665         dest->block = src->block ;
666         dest->ival = copyIlist(src->ival);
667         dest->type = copyLinkChain(src->type);
668         dest->etype= getSpec(dest->type);
669         dest->next = NULL ;
670         dest->args = copyValueChain (src->args);
671         dest->key = src->key;
672         dest->calleeSave = src->calleeSave;
673         dest->allocreq = src->allocreq;
674         return dest;
675 }
676
677 /*------------------------------------------------------------------*/
678 /* reverseSyms - reverses the links for a symbol chain      */
679 /*------------------------------------------------------------------*/
680 symbol   *reverseSyms ( symbol *sym)
681 {
682    symbol *prev  , *curr, *next ;
683
684    if (!sym)
685       return NULL ;
686
687    prev = sym ;
688    curr = sym->next ;
689
690    while (curr)
691    {
692       next = curr->next ;
693       curr->next = prev   ;
694       prev = curr ;
695       curr = next ;
696    }
697    sym->next = (void *) NULL ;
698    return prev ;
699 }
700
701 /*------------------------------------------------------------------*/
702 /* reverseLink - reverses the links for a type chain        */
703 /*------------------------------------------------------------------*/
704 link     *reverseLink ( link *type)
705 {
706    link *prev  , *curr, *next ;
707
708    if (!type)
709       return NULL ;
710
711    prev = type ;
712    curr = type->next ;
713
714    while (curr)
715    {
716       next = curr->next ;
717       curr->next = prev   ;
718       prev = curr ;
719       curr = next ;
720    }
721    type->next = (void *) NULL ;
722    return prev ;
723 }
724
725 /*------------------------------------------------------------------*/
726 /* addSymChain - adds a symbol chain to the symboltable             */
727 /*------------------------------------------------------------------*/
728 void addSymChain ( symbol *symHead )
729 {
730   symbol *sym  = symHead ;
731   symbol *csym = NULL ;
732
733   for (;sym != NULL ; sym = sym->next ) {
734
735     /* if already exists in the symbol table then check if 
736        the previous was an extern definition if yes then   
737        then check if the type match, if the types match then 
738        delete the current entry and add the new entry      */   
739       if ((csym = findSymWithLevel (SymbolTab,sym)) &&
740         csym->level == sym->level) {
741       
742       /* previous definition extern ? */
743       if ( IS_EXTERN(csym->etype) ) {
744         /* do types match ? */
745         if (checkType ( csym->type,sym->type) != 1)
746           /* no then error */
747           werror (E_DUPLICATE,csym->name);
748
749         /* delete current entry */
750         deleteSym (SymbolTab, csym, csym->name );
751         /* add new entry */
752         addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
753       } else /* not extern */
754           werror(E_DUPLICATE,sym->name) ;
755       continue ;
756     }
757     
758     /* check if previously defined */
759     if (csym  && csym->level == sym->level  ) {
760       /* if the previous one was declared as extern */
761       /* then check the type with the current one         */
762       if ( IS_EXTERN(csym->etype) ) {
763         if ( checkType (csym->type, sym->type ) <= 0 )
764           werror (W_EXTERN_MISMATCH,csym->name);
765       }
766     }
767     
768     addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
769   }
770 }
771
772
773 /*------------------------------------------------------------------*/
774 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
775 /*------------------------------------------------------------------*/
776 int funcInChain (link *lnk)
777 {
778     while (lnk) {
779         if (IS_FUNC(lnk))
780             return 1;
781         lnk = lnk->next;
782     }
783     return 0;
784 }
785
786 /*------------------------------------------------------------------*/
787 /* structElemType - returns the type info of a sturct member        */
788 /*------------------------------------------------------------------*/
789 link *structElemType (link *stype, value *id ,value **argsp)
790 {
791     symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
792     
793     if ( ! fields || ! id)
794         return NULL ;
795        
796     /* look for the id */
797     while (fields) {
798         if (strcmp(fields->rname,id->name) == 0) {
799             if (argsp) {
800                 *argsp = fields->args;
801             }
802             return copyLinkChain (fields->type) ;
803         }
804         fields = fields->next ;
805     }
806     werror(E_NOT_MEMBER,id->name);
807     
808     return NULL ;
809 }
810
811 /*------------------------------------------------------------------*/
812 /* getStructElement - returns element of a tructure definition      */
813 /*------------------------------------------------------------------*/
814 symbol *getStructElement ( structdef *sdef, symbol *sym)
815 {
816     symbol *field ;
817     
818     for ( field = sdef->fields ; field ; field = field->next )
819         if ( strcmp(field->name,sym->name) == 0)
820             return field ;
821     
822     werror(E_NOT_MEMBER,sym->name);
823     
824     return sdef->fields ;
825 }
826
827 /*------------------------------------------------------------------*/
828 /* compStructSize - computes the size of a structure                */
829 /*------------------------------------------------------------------*/
830 int   compStructSize (int su, structdef  *sdef )
831 {
832     int sum = 0 , usum =0;
833     int bitOffset = 0 ;
834     symbol   *loop ;
835     
836     /* for the identifiers  */
837     loop = sdef->fields ;
838     while ( loop ) {
839
840         /* create the internal name for this variable */
841         sprintf (loop->rname,"_%s",loop->name);
842         loop->offset = ( su == UNION ? sum = 0 : sum ) ;
843         SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
844
845         /* if this is a bit field  */
846         if (loop->bitVar)       {
847             
848             /* change it to a unsigned bit */
849             SPEC_NOUN(loop->etype) = V_BIT ;
850             SPEC_USIGN(loop->etype) = 1     ;
851             /* check if this fit into the remaining   */
852             /* bits of this byte else align it to the */
853             /* next byte boundary                     */
854             if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset))  {
855                 SPEC_BSTR(loop->etype) = bitOffset   ;
856                 sum += (loop->bitVar / 8)  ;
857                 bitOffset += (loop->bitVar % 8);
858             } 
859             else  /* does not fit */
860                 {
861                     bitOffset = 0 ;
862                     loop->offset++;   /* go to the next byte  */
863                     sum++         ;
864                     SPEC_BSTR(loop->etype) = bitOffset   ;
865                     sum += (loop->bitVar / 8)  ;
866                     bitOffset += (loop->bitVar % 8);
867                 }
868             /* if this is the last field then pad */
869             if (!loop->next && bitOffset) {
870                 bitOffset = 0 ;
871                 sum++ ;
872             }
873         }
874         else {
875             checkDecl (loop);
876             sum += getSize (loop->type) ;
877         }
878
879         /* if function then do the arguments for it */
880         if (funcInChain(loop->type)) {
881             processFuncArgs (loop, 1);
882         }
883
884         loop = loop->next ;
885
886         /* if this is not a bitfield but the */
887         /* previous one was and did not take */
888         /* the whole byte then pad the rest  */
889         if ((loop && !loop->bitVar) && bitOffset) {
890             bitOffset = 0 ;
891             sum++ ;
892         }
893         
894         /* if union then size = sizeof larget field */
895         if (su == UNION)
896             usum = max(usum,sum);
897     
898     }
899     
900     return (su == UNION ? usum : sum);
901 }
902
903 /*------------------------------------------------------------------*/
904 /* checkSClass - check the storage class specification              */
905 /*------------------------------------------------------------------*/
906 static void  checkSClass ( symbol *sym )
907 {         
908     /* type is literal can happen foe enums change
909        to auto */
910     if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
911         SPEC_SCLS(sym->etype) = S_AUTO;
912
913     /* if sfr or sbit then must also be */
914     /* volatile the initial value will be xlated */
915     /* to an absolute address */
916     if (SPEC_SCLS(sym->etype) == S_SBIT ||
917         SPEC_SCLS(sym->etype) == S_SFR ) {
918         SPEC_VOLATILE(sym->etype) = 1;
919         /* if initial value given */
920         if (sym->ival) {
921             SPEC_ABSA(sym->etype) = 1;
922             SPEC_ADDR(sym->etype) =
923                 (int) list2int(sym->ival);
924             sym->ival = NULL;
925         }
926     }
927
928     /* if absolute address given then it mark it as
929        volatile */
930     if (IS_ABSOLUTE(sym->etype))
931         SPEC_VOLATILE(sym->etype) = 1;
932
933     /* global variables declared const put into code */
934     if (sym->level == 0 && 
935         SPEC_SCLS(sym->etype) == S_CONSTANT) 
936         SPEC_SCLS(sym->etype) = S_CODE ;
937     
938
939     /* global variable in code space is a constant */
940     if (sym->level == 0 && 
941         SPEC_SCLS(sym->etype) == S_CODE) 
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         !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             SPEC_SCLS(sym->etype) = (options.useXstack  ?
1016                                      S_XSTACK : S_STACK ) ;
1017         else
1018             SPEC_SCLS(sym->etype) = (options.useXstack  ?
1019                                      S_XDATA :S_DATA ) ;
1020     }
1021 }
1022
1023 /*------------------------------------------------------------------*/
1024 /* changePointer - change pointer to functions                      */
1025 /*------------------------------------------------------------------*/
1026 void  changePointer  (symbol  *sym)
1027 {
1028     link *p ;
1029     
1030     /* go thru the chain of declarations   */
1031     /* if we find a pointer to a function  */
1032     /* unconditionally change it to a ptr  */
1033     /* to code area                        */
1034     for ( p = sym->type ; p ; p = p->next) {
1035         if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1036             DCL_TYPE(p) = GPOINTER ;
1037         if ( IS_PTR(p) && IS_FUNC(p->next))
1038             DCL_TYPE(p) = CPOINTER ;
1039     }
1040 }
1041
1042 /*------------------------------------------------------------------*/
1043 /* checkDecl - does semantic validation of a declaration                   */
1044 /*------------------------------------------------------------------*/
1045 int checkDecl ( symbol *sym )
1046 {
1047     
1048     checkSClass  (sym); /* check the storage class      */
1049     changePointer(sym);  /* change pointers if required */
1050
1051     /* if this is an array without any dimension
1052        then update the dimension from the initial value */
1053     if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1054         DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);    
1055
1056     return 0 ;
1057 }
1058
1059 /*------------------------------------------------------------------*/
1060 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1061 /*------------------------------------------------------------------*/
1062 link  *copyLinkChain ( link *p)
1063 {
1064     link  *head, *curr , *loop;
1065     
1066     curr = p ;
1067     head = loop = ( curr ? newLink() : (void *) NULL) ;
1068     while (curr)   {
1069         memcpy(loop,curr,sizeof(link)) ; /* copy it */
1070         loop->next = (curr->next ? newLink() : (void *) NULL) ;
1071         loop = loop->next ;
1072         curr = curr->next ;
1073     }
1074     
1075     return head ;
1076 }
1077
1078
1079 /*------------------------------------------------------------------*/
1080 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1081 /*                symbols in the given block                        */
1082 /*------------------------------------------------------------------*/
1083 void cleanUpBlock ( bucket **table, int block)
1084 {    
1085     int i ;
1086     bucket  *chain;
1087     
1088     /* go thru the entire  table  */
1089     for ( i = 0 ; i < 256; i++ ) {
1090         for ( chain = table[i]; chain ; chain = chain->next ) {
1091             if (chain->block >= block) {
1092                 deleteSym (table,chain->sym,chain->name);                                 
1093             }   
1094         }
1095     }
1096 }
1097
1098 /*------------------------------------------------------------------*/
1099 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1100 /*                symbols in the given level                        */
1101 /*------------------------------------------------------------------*/
1102 void  cleanUpLevel   (bucket  **table, int level )
1103 {
1104     int i ;
1105     bucket  *chain;
1106     
1107     /* go thru the entire  table  */
1108     for ( i = 0 ; i < 256; i++ ) {
1109         for ( chain = table[i]; chain ; chain = chain->next ) {
1110             if (chain->level >= level) {
1111                 deleteSym (table,chain->sym,chain->name);                                 
1112             }   
1113         }
1114     }
1115 }
1116
1117 /*------------------------------------------------------------------*/
1118 /* computeType - computes the resultant type from two types         */
1119 /*------------------------------------------------------------------*/
1120 link *computeType ( link *type1, link *type2)
1121 {
1122     link *rType ;
1123     link *reType;
1124     link *etype1 = getSpec(type1);
1125     link *etype2 = getSpec(type2);
1126     
1127     /* if one of them is a float then result is a float */
1128     /* here we assume that the types passed are okay */
1129     /* and can be cast to one another                */
1130     /* which ever is greater in size */
1131     if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1132         rType = newFloatLink();
1133     else
1134         /* if only one of them is a bit variable
1135            then the other one prevails */
1136         if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1137             rType = copyLinkChain(type2);
1138         else
1139             if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1140                 rType = copyLinkChain(type1);
1141             else
1142                 /* if one of them is a pointer then that
1143                    prevails */
1144                 if (IS_PTR(type1))
1145                     rType = copyLinkChain(type1);
1146                 else
1147                     if (IS_PTR(type2))
1148                         rType = copyLinkChain(type2);
1149                     else
1150                         if (getSize (type1) > getSize(type2) )
1151                             rType = copyLinkChain(type1);
1152                         else
1153                             rType = copyLinkChain(type2);
1154     
1155     reType = getSpec(rType);
1156     
1157     /* if either of them unsigned then make this unsigned */
1158     if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1159         SPEC_USIGN(reType) = 1;
1160     
1161     /* if result is a literal then make not so */
1162     if (IS_LITERAL(reType))
1163         SPEC_SCLS(reType) = S_REGISTER ;
1164     
1165     return rType;
1166 }
1167
1168 /*------------------------------------------------------------------*/
1169 /* checkType - will do type check return 1 if match                 */
1170 /*------------------------------------------------------------------*/
1171 int checkType ( link *dest, link *src )
1172 {
1173     if ( !dest && !src)
1174         return 1;
1175     
1176     if (dest && !src)
1177         return 0;
1178     
1179     if (src && !dest)
1180         return 0;
1181     
1182     /* if dest is a declarator then */
1183     if (IS_DECL(dest)) {
1184         if (IS_DECL(src)) {
1185             if (DCL_TYPE(src) == DCL_TYPE(dest))
1186                 return checkType(dest->next,src->next);
1187             else
1188                 if (IS_PTR(src) && IS_PTR(dest))
1189                     return -1;
1190                 else
1191                     if (IS_PTR(dest) && IS_ARRAY(src))
1192                         return -1;
1193                     else 
1194                         if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1195                             return -1 * checkType (dest->next,src) ;
1196                         else
1197                             return 0;
1198         }
1199         else
1200             if (IS_PTR(dest) && IS_INTEGRAL(src))
1201                 return -1;
1202             else
1203                 return 0;
1204     }
1205     
1206     /* if one of them is a void then ok */
1207     if (SPEC_NOUN(dest) == V_VOID    &&
1208         SPEC_NOUN(src)  != V_VOID    )
1209         return -1 ;
1210     
1211     if (SPEC_NOUN(dest) != V_VOID &&
1212         SPEC_NOUN(src) == V_VOID )
1213         return -1;
1214     
1215     /* char === to short */
1216     if (SPEC_NOUN(dest) == V_CHAR &&
1217         SPEC_NOUN(src)  == V_INT  &&
1218         SPEC_SHORT(src)           )
1219         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1220
1221     if (SPEC_NOUN(src) == V_CHAR &&
1222         SPEC_NOUN(dest)  == V_INT  &&
1223         SPEC_SHORT(dest)           )
1224         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);    
1225
1226     /* if they are both bitfields then if the lengths
1227        and starts don't match */
1228     if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1229         (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1230          SPEC_BSTR(dest) != SPEC_BSTR(src)))
1231         return -1;
1232
1233     /* it is a specifier */
1234     if (SPEC_NOUN(dest) != SPEC_NOUN(src))      {
1235         if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1236             IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1237             getSize(dest) == getSize(src))
1238             return 1;
1239         else
1240             if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1241                 return -1;
1242         else
1243             return 0;
1244     }
1245     else
1246         if (IS_STRUCT(dest)) {
1247             if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1248                 return 0 ;
1249             else 
1250                 return 1 ;
1251         }
1252     if (SPEC_LONG(dest) != SPEC_LONG(src))
1253         return -1;
1254     
1255     if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1256         return -1;
1257     
1258     if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1259         return -2;
1260     
1261     return 1;   
1262 }
1263
1264 /*------------------------------------------------------------------*/
1265 /* inCalleeSaveList - return 1 if found in calle save list          */
1266 /*------------------------------------------------------------------*/
1267 bool inCalleeSaveList ( char *s)
1268 {
1269     int i;
1270     
1271     for (i = 0 ; options.calleeSaves[i] ; i++ )
1272         if (strcmp(options.calleeSaves[i],s) == 0)
1273             return 1;
1274
1275     return 0;
1276 }
1277
1278 /*------------------------------------------------------------------*/
1279 /* checkFunction - does all kinds of check on a function            */
1280 /*------------------------------------------------------------------*/
1281 int   checkFunction (symbol   *sym)
1282 {
1283     symbol *csym ;
1284     value  *exargs, *acargs ;
1285     int argCnt = 0 ;
1286     
1287     /* if not type then some kind of error */
1288     if ( !sym->type )
1289         return 0;
1290     
1291     /* if the function has no type then make it return int */
1292     if ( !sym->type->next )
1293         sym->type->next = sym->etype = newIntLink();
1294    
1295     /* function cannot return aggregate */
1296     if (IS_AGGREGATE(sym->type->next))   {
1297         werror(E_FUNC_AGGR,sym->name);
1298         return 0;      
1299     }
1300            
1301     /* function cannot return bit */
1302     if (IS_BITVAR(sym->type->next)) {
1303         werror(E_FUNC_BIT,sym->name);
1304         return 0;
1305     }
1306     
1307     /* check if this function is defined as calleeSaves
1308        then mark it as such */
1309     sym->calleeSave = inCalleeSaveList(sym->name); 
1310
1311     /* if interrupt service routine  */
1312     /* then it cannot have arguments */
1313     if ( sym->args  && IS_ISR(sym->etype) && !IS_VOID(sym->args->type))   {
1314         werror(E_INT_ARGS,sym->name);     
1315         sym->args = NULL ;
1316     }
1317     
1318     if (!(csym = findSym (SymbolTab, sym, sym->name )))
1319         return 1 ;  /* not defined nothing more to check  */
1320     
1321     /* check if body already present */
1322     if ( csym && csym->fbody )   {
1323         werror(E_FUNC_BODY,sym->name);
1324         return 0;
1325     }
1326     
1327     /* check the return value type   */
1328     if (checkType (csym->type,sym->type) <= 0) {
1329         werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1330         werror (E_CONTINUE,"previous defintion type ");
1331         printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1332         werror (E_CONTINUE,"current definition type ");
1333         printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1334         return 0;
1335     }
1336
1337     if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1338         werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1339         return 0;
1340     }
1341
1342     if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1343         werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1344         return 0;
1345     }
1346
1347     /* compare expected agrs with actual args */
1348     exargs = csym->args ;
1349     acargs = sym->args  ;
1350     
1351     /* for all the expected args do */
1352     for (argCnt =  1    ; 
1353          exargs && acargs ; 
1354          exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1355         if ( checkType(exargs->type,acargs->type) <= 0) {
1356             werror(E_ARG_TYPE,argCnt);
1357             return 0;
1358         }
1359     }
1360     
1361     /* if one them ended we have a problem */
1362     if ((exargs && !acargs && !IS_VOID(exargs->type)) || 
1363         (!exargs && acargs && !IS_VOID(acargs->type)))
1364         werror(E_ARG_COUNT);
1365     
1366     /* replace with this defition */
1367     sym->cdef = csym->cdef;
1368     deleteSym (SymbolTab,csym,csym->name);
1369     addSym    (SymbolTab,sym,sym->name,sym->level,sym->block);
1370     if (IS_EXTERN(csym->etype) && !
1371         IS_EXTERN(sym->etype))
1372         addSet(&publics,sym);
1373     return 1 ;      
1374 }
1375
1376 /*-----------------------------------------------------------------*/
1377 /* processFuncArgs - does some processing with function args       */
1378 /*-----------------------------------------------------------------*/
1379 void  processFuncArgs   (symbol *func, int ignoreName)
1380 {
1381     value *val ;
1382     int pNum = 1;   
1383     
1384     /* if this function has variable argument list */
1385     /* then make the function a reentrant one      */
1386     if (func->hasVargs)
1387         SPEC_RENT(func->etype) = 1;
1388
1389     /* check if this function is defined as calleeSaves
1390        then mark it as such */
1391     func->calleeSave = inCalleeSaveList(func->name); 
1392
1393     val = func->args; /* loop thru all the arguments   */
1394         
1395     /* if it is void then remove parameters */
1396     if (val && IS_VOID(val->type)) {     
1397         func->args = NULL ;
1398         return ;
1399     }
1400     
1401     /* if any of the arguments is an aggregate */
1402     /* change it to pointer to the same type */
1403     while (val) {
1404
1405         /* mark it as a register parameter if
1406            the function does nit have VA_ARG
1407            and MAX_REG_PARMS not exceeded &&
1408            not inhibited by command line option or #pragma */
1409         if (pNum <= MAX_REG_PARMS && 
1410             !options.noregparms   &&
1411             !func->hasVargs)
1412             SPEC_REGPARM(val->etype) = 1;
1413         
1414         if ( IS_AGGREGATE(val->type)) {
1415             /* if this is a structure */
1416             /* then we need to add a new link */
1417             if (IS_STRUCT(val->type)) {
1418                                 /* first lets add DECLARATOR type */
1419                 link *p = val->type ;
1420                 
1421                 werror(W_STRUCT_AS_ARG,val->name);
1422                 val->type = newLink();
1423                 val->type->next = p ;                           
1424             }
1425             
1426             /* change to a pointer depending on the */
1427             /* storage class specified                          */
1428             switch (SPEC_SCLS(val->etype)) {
1429             case S_IDATA:
1430                 DCL_TYPE(val->type) = IPOINTER;
1431                 break;
1432             case S_PDATA:
1433                 DCL_TYPE(val->type) = PPOINTER;
1434                 break;
1435             case S_FIXED:
1436             case S_AUTO:
1437             case S_DATA:
1438             case S_REGISTER:
1439                 DCL_TYPE(val->type) = POINTER ;
1440                 break;
1441             case S_CODE:
1442                 DCL_TYPE(val->type) = CPOINTER;
1443                 break;
1444             case S_XDATA:
1445                 DCL_TYPE(val->type) = FPOINTER;
1446                 break;
1447             case S_FLASH:
1448                 DCL_TYPE(val->type) = FLPOINTER;
1449                 break;
1450             default :
1451                 DCL_TYPE(val->type) = GPOINTER;
1452             }
1453             
1454             /* is there is a symbol associated then */
1455             /* change the type of the symbol as well*/
1456             if ( val->sym ) {          
1457                 val->sym->type = copyLinkChain(val->type);
1458                 val->sym->etype = getSpec(val->sym->type);
1459             }
1460         }
1461         
1462         val = val->next ;
1463         pNum++;
1464     }
1465     
1466     /* if this function is reentrant or */
1467     /* automatics r 2b stacked then nothing */
1468     if (IS_RENT(func->etype) || options.stackAuto )
1469         return ;
1470     
1471     val = func->args;
1472     pNum = 1;
1473     while (val) {
1474         
1475         /* if a symbolname is not given  */
1476         /* synthesize a variable name */
1477         if (!val->sym) {
1478
1479             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1480             val->sym = newSymbol(val->name,1);
1481             SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1482             val->sym->type = copyLinkChain (val->type);
1483             val->sym->etype = getSpec (val->sym->type);
1484             val->sym->_isparm = 1;
1485             strcpy (val->sym->rname,val->name);  
1486             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1487                 SPEC_STAT(func->etype);
1488             addSymChain(val->sym);
1489    
1490         }
1491         else  /* symbol name given create synth name */      {
1492             
1493             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1494             strcpy (val->sym->rname,val->name);
1495             val->sym->_isparm = 1;
1496             SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) = 
1497                 (options.model ? xdata : data);
1498             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = 
1499                 SPEC_STAT(func->etype);
1500         }
1501         val = val->next ;
1502     }
1503 }
1504
1505 /*-----------------------------------------------------------------*/
1506 /* isSymbolEqual - compares two symbols return 1 if they match     */
1507 /*-----------------------------------------------------------------*/
1508 int isSymbolEqual (symbol *dest, symbol *src)
1509 {
1510     /* if pointers match then equal */
1511     if (dest == src)
1512         return 1;
1513
1514     /* if one of them is null then don't match */
1515     if (!dest || !src)
1516         return 0;
1517     
1518     /* if both of them have rname match on rname */
1519     if (dest->rname[0] && src->rname[0]) 
1520         return (!strcmp(dest->rname,src->rname));
1521     
1522     /* otherwise match on name */
1523     return (!strcmp(dest->name,src->name));
1524 }
1525
1526 /*-----------------------------------------------------------------*/ 
1527 /* printTypeChain - prints the type chain in human readable form   */
1528 /*-----------------------------------------------------------------*/ 
1529 void printTypeChain (link *type, FILE *of)
1530 {
1531     int nlr = 0;
1532
1533     if (!of) {
1534         of = stdout;
1535         nlr = 1;
1536     }
1537
1538     while (type) {
1539         if (IS_DECL(type)) {
1540             switch (DCL_TYPE(type)) {
1541             case FUNCTION:
1542                 fprintf (of,"function ");
1543                 break;
1544             case GPOINTER:
1545                 fprintf (of,"_generic * ");
1546                 if (DCL_PTR_CONST(type))
1547                     fprintf(of,"const ");
1548                 break;          
1549             case CPOINTER:
1550                 fprintf (of,"_code * ");
1551                 if (DCL_PTR_CONST(type))
1552                     fprintf(of,"const ");
1553                 break;
1554             case FPOINTER:
1555                 fprintf (of,"_far * ");
1556                 if (DCL_PTR_CONST(type))
1557                     fprintf(of,"const ");
1558                 break;
1559             case FLPOINTER:
1560                 fprintf (of,"_flash * ");
1561                 if (DCL_PTR_CONST(type))
1562                     fprintf(of,"const ");
1563                 break;
1564                 
1565             case POINTER:
1566                 fprintf (of,"_near * ");
1567                 if (DCL_PTR_CONST(type))
1568                     fprintf(of,"const ");       
1569                 break;
1570             case IPOINTER:
1571                 fprintf (of,"_idata *");
1572                 if (DCL_PTR_CONST(type))
1573                     fprintf(of,"const ");       
1574                 break; 
1575             case PPOINTER:
1576                 fprintf (of,"_pdata *");
1577                 if (DCL_PTR_CONST(type))
1578                     fprintf(of,"const ");       
1579                 break;
1580             case UPOINTER:
1581                 fprintf (of," _unkown *");
1582                 if (DCL_PTR_CONST(type))
1583                     fprintf(of,"const ");       
1584                 break;
1585                 
1586             case ARRAY :
1587                 fprintf (of,"array of ");
1588                 break;
1589             }
1590         } else { 
1591             if (SPEC_VOLATILE(type))
1592                 fprintf (of,"volatile "); 
1593             if (SPEC_USIGN(type))
1594                 fprintf (of,"unsigned ");
1595             
1596             switch (SPEC_NOUN(type)) {
1597             case V_INT:
1598                 if (IS_LONG(type))
1599                     fprintf (of,"long ");
1600                 else
1601                     if (IS_SHORT(type))
1602                         fprintf (of,"short ");
1603                     else
1604                         fprintf (of,"int ");
1605                 break;
1606
1607             case V_CHAR:
1608                 fprintf(of,"char ");
1609                 break;
1610
1611             case V_VOID:
1612                 fprintf(of,"void ");
1613                 break;
1614
1615             case V_FLOAT:
1616                 fprintf(of,"float ");
1617                 break;
1618
1619             case V_STRUCT:
1620                 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1621                 break;
1622                                   
1623             case V_SBIT:
1624                 fprintf(of,"sbit ");
1625                 break;
1626
1627             case V_BIT:
1628                 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1629                 break;
1630             }
1631         }
1632         type = type->next;
1633     }
1634     if (nlr)
1635         fprintf(of,"\n");
1636 }
1637
1638 /*-----------------------------------------------------------------*/ 
1639 /* cdbTypeInfo - print the type information for debugger           */
1640 /*-----------------------------------------------------------------*/
1641 void cdbTypeInfo (link *type,FILE *of)
1642 {
1643     fprintf(of,"{%d}",getSize(type));
1644     while (type) {
1645         if (IS_DECL(type)) {
1646             switch (DCL_TYPE(type)) {
1647             case FUNCTION:
1648                 fprintf (of,"DF,");
1649                 break;
1650             case GPOINTER:
1651                 fprintf (of,"DG,");             
1652                 break;          
1653             case CPOINTER:
1654                 fprintf (of,"DC,");             
1655                 break;
1656             case FPOINTER:
1657                 fprintf (of,"DX,");             
1658                 break;
1659             case POINTER:
1660                 fprintf (of,"DD,");             
1661                 break;
1662             case IPOINTER:
1663                 fprintf (of,"DI,");
1664                 break;
1665             case PPOINTER:
1666                 fprintf (of,"DP,");
1667                 break;
1668             case FLPOINTER:
1669                 fprintf (of,"DA,");
1670                 break;
1671             case ARRAY :
1672                 fprintf (of,"DA%d,",DCL_ELEM(type));
1673                 break;
1674             }
1675         } else { 
1676             switch (SPEC_NOUN(type)) {
1677             case V_INT:
1678                 if (IS_LONG(type))
1679                     fprintf (of,"SL");
1680                 else
1681                     if (IS_SHORT(type))
1682                         fprintf (of,"SS");
1683                     else
1684                         fprintf (of,"SI");
1685                 break;
1686
1687             case V_CHAR:
1688                 fprintf(of,"SC");
1689                 break;
1690
1691             case V_VOID:
1692                 fprintf(of,"SV");
1693                 break;
1694
1695             case V_FLOAT:
1696                 fprintf(of,"SF");
1697                 break;
1698
1699             case V_STRUCT:
1700                 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1701                 break;
1702                                   
1703             case V_SBIT:
1704                 fprintf(of,"SX");
1705                 break;
1706
1707             case V_BIT:
1708                 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1709                 break;
1710             }
1711             fputs(":",of);
1712             if (SPEC_USIGN(type))
1713                 fputs("U",of);
1714             else
1715                 fputs("S",of);
1716         }
1717         type = type->next;
1718     }
1719 }
1720 /*-----------------------------------------------------------------*/ 
1721 /* cdbSymbol - prints a symbol & its type information for debugger */
1722 /*-----------------------------------------------------------------*/ 
1723 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1724 {
1725     memmap *map;
1726
1727     if (!sym)
1728         return ;
1729     if (!of)
1730         of = stdout;
1731     
1732     if (isFunc)
1733         fprintf(of,"F:");
1734     else
1735         fprintf(of,"S:"); /* symbol record */
1736     /* if this is not a structure symbol then
1737        we need to figure out the scope information */
1738     if (!isStructSym) {
1739         if (!sym->level) {
1740             /* global */
1741             if (IS_STATIC(sym->etype))
1742                 fprintf(of,"F%s$",moduleName); /* scope is file */
1743             else
1744                 fprintf(of,"G$"); /* scope is global */
1745         }
1746         else 
1747             /* symbol is local */
1748             fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1749     } else
1750         fprintf(of,"S$"); /* scope is structure */
1751     
1752     /* print the name, & mangled name */
1753     fprintf(of,"%s$%d$%d(",sym->name,
1754             sym->level,sym->block);
1755
1756     cdbTypeInfo(sym->type,of);
1757     fprintf(of,"),");
1758     
1759     /* print the address space */
1760     map = SPEC_OCLS(sym->etype);
1761     fprintf(of,"%c,%d,%d",
1762             (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1763     
1764     /* if assigned to registers then output register names */   
1765     /* if this is a function then print
1766        if is it an interrupt routine & interrupt number
1767        and the register bank it is using */
1768     if (isFunc)
1769         fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1770                 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1771     /* alternate location to find this symbol @ : eg registers
1772        or spillication */
1773    
1774     if (!isStructSym)
1775         fprintf(of,"\n");
1776 }                   
1777
1778 /*-----------------------------------------------------------------*/ 
1779 /* cdbStruct - print a structure for debugger                      */
1780 /*-----------------------------------------------------------------*/
1781 void cdbStruct ( structdef *sdef,int block,FILE *of,
1782                  int inStruct, char *tag)
1783 {
1784     symbol *sym;
1785
1786     fprintf(of,"T:");
1787     /* if block # then must have function scope */
1788     fprintf(of,"F%s$",moduleName);
1789     fprintf(of,"%s[",(tag ? tag : sdef->tag));
1790     for (sym=sdef->fields ; sym ; sym = sym->next) {
1791         fprintf(of,"({%d}",sym->offset);
1792             cdbSymbol(sym,of,TRUE,FALSE);
1793         fprintf(of,")");
1794     }
1795     fprintf(of,"]");
1796     if (!inStruct)
1797         fprintf(of,"\n");
1798 }
1799
1800 /*------------------------------------------------------------------*/
1801 /* cdbStructBlock - calls struct printing for a blcks               */
1802 /*------------------------------------------------------------------*/
1803 void cdbStructBlock (int block , FILE *of)
1804 {    
1805     int i ;
1806     bucket **table = StructTab;
1807     bucket  *chain;
1808     
1809     /* go thru the entire  table  */
1810     for ( i = 0 ; i < 256; i++ ) {
1811         for ( chain = table[i]; chain ; chain = chain->next ) {
1812             if (chain->block >= block) {
1813                 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1814             }   
1815         }
1816     }
1817 }
1818                 
1819 /*-----------------------------------------------------------------*/ 
1820 /* powof2 - returns power of two for the number if number is pow 2 */
1821 /*-----------------------------------------------------------------*/ 
1822 int powof2 (unsigned long num)
1823 {
1824     int nshifts = 0;
1825     int n1s = 0 ;
1826     
1827     while (num) {
1828         if (num & 1) n1s++ ;
1829         num >>= 1 ;
1830         nshifts++ ;
1831     }
1832     
1833     if (n1s > 1 || nshifts == 0) return 0;
1834     return nshifts - 1 ;
1835 }
1836
1837 symbol *__fsadd ;
1838 symbol *__fssub ;
1839 symbol *__fsmul ;
1840 symbol *__fsdiv ;
1841 symbol *__fseq  ;
1842 symbol *__fsneq ;
1843 symbol *__fslt  ;
1844 symbol *__fslteq;
1845 symbol *__fsgt  ;
1846 symbol *__fsgteq;
1847 symbol *__fs2uchar;
1848 symbol *__fs2uint ;
1849 symbol *__fs2ulong;
1850 symbol *__fs2char;
1851 symbol *__fs2int ;
1852 symbol *__fs2long;
1853 symbol *__long2fs;
1854 symbol *__ulong2fs;
1855 symbol *__int2fs;
1856 symbol *__uint2fs;
1857 symbol *__char2fs;
1858 symbol *__uchar2fs;
1859 symbol *__muluint;
1860 symbol *__mulsint;
1861 symbol *__divuint;
1862 symbol *__divsint;
1863 symbol *__mululong;
1864 symbol *__mulslong;
1865 symbol *__divulong;
1866 symbol *__divslong;
1867 symbol *__moduint;
1868 symbol *__modsint;
1869 symbol *__modulong;
1870 symbol *__modslong;
1871
1872 link *charType ;
1873 link *intType  ;
1874 link *floatType;
1875 link *longType ;
1876 link *ucharType ;
1877 link *uintType  ;
1878 link *ulongType ;
1879
1880 /*-----------------------------------------------------------------*/ 
1881 /* initCSupport - create functions for C support routines          */
1882 /*-----------------------------------------------------------------*/ 
1883 void initCSupport ()
1884 {
1885     charType = newCharLink();
1886     intType  = newIntLink();
1887     floatType= newFloatLink();
1888     longType = newLongLink();
1889     ucharType = copyLinkChain(charType);
1890     SPEC_USIGN(ucharType) = 1;
1891     ulongType = copyLinkChain(longType);
1892     SPEC_USIGN(ulongType) = 1;
1893     uintType = copyLinkChain(intType);
1894     SPEC_USIGN(uintType) = 1;
1895
1896
1897     __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1898     __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1899     __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1900     __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1901     __fseq  = funcOfType ("__fseq", charType, floatType, 2, options.float_rent);
1902     __fsneq = funcOfType ("__fsneq", charType, floatType, 2, options.float_rent);
1903     __fslt  = funcOfType ("__fslt", charType, floatType, 2, options.float_rent);
1904     __fslteq= funcOfType ("__fslteq", charType, floatType, 2, options.float_rent);
1905     __fsgt  = funcOfType ("__fsgt", charType, floatType, 2, options.float_rent);
1906     __fsgteq= funcOfType ("__fsgteq", charType, floatType, 2, options.float_rent);
1907     
1908     __fs2uchar = funcOfType ("__fs2uchar",ucharType,floatType,1, options.float_rent);
1909     __fs2uint  = funcOfType ("__fs2uint",uintType,floatType,1, options.float_rent);
1910     __fs2ulong = funcOfType ("__fs2ulong",ulongType,floatType,1, options.float_rent);
1911     __fs2char  = funcOfType ("__fs2char",charType,floatType,1, options.float_rent);
1912     __fs2int   = funcOfType ("__fs2int",intType,floatType,1, options.float_rent);
1913     __fs2long  = funcOfType ("__fs2long",longType,floatType,1, options.float_rent);
1914
1915     __long2fs  = funcOfType ("__long2fs",floatType,longType,1, options.float_rent);
1916     __ulong2fs = funcOfType ("__ulong2fs",floatType,ulongType,1, options.float_rent);
1917     __int2fs   = funcOfType ("__int2fs",floatType,intType,1, options.float_rent);
1918     __uint2fs  = funcOfType ("__uint2fs",floatType,uintType,1, options.float_rent);
1919     __char2fs  = funcOfType ("__char2fs",floatType,charType,1, options.float_rent);
1920     __uchar2fs = funcOfType ("__uchar2fs",floatType,ucharType,1, options.float_rent);
1921
1922     __muluint  = funcOfType ("_muluint",uintType,uintType,2,options.intlong_rent);
1923     __mulsint  = funcOfType ("_mulsint",intType,intType,2,options.intlong_rent);
1924     __divuint  = funcOfType ("_divuint",uintType,uintType,2,options.intlong_rent);
1925     __divsint  = funcOfType ("_divsint",intType,intType,2,options.intlong_rent);
1926     __moduint  = funcOfType ("_moduint",uintType,uintType,2,options.intlong_rent);
1927     __modsint  = funcOfType ("_modsint",intType,intType,2,options.intlong_rent);
1928   
1929     __mululong = funcOfType ("_mululong",ulongType,ulongType,2,options.intlong_rent);
1930     __mulslong = funcOfType ("_mulslong",longType,longType,2,options.intlong_rent);
1931     __divulong  = funcOfType ("_divulong",ulongType,ulongType,2,options.intlong_rent);
1932     __divslong  = funcOfType ("_divslong",longType,longType,2,options.intlong_rent);
1933     __modulong  = funcOfType ("_modulong",ulongType,ulongType,2,options.intlong_rent);
1934     __modslong  = funcOfType ("_modslong",longType,longType,2,options.intlong_rent);
1935  
1936 }