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