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