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