work on avr port start by defining the new
[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 static void  checkSClass ( symbol *sym )
902 {         
903     /* type is literal can happen foe enums change
904        to auto */
905     if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
906         SPEC_SCLS(sym->etype) = S_AUTO;
907
908     /* if sfr or sbit then must also be */
909     /* volatile the initial value will be xlated */
910     /* to an absolute address */
911     if (SPEC_SCLS(sym->etype) == S_SBIT ||
912         SPEC_SCLS(sym->etype) == S_SFR ) {
913         SPEC_VOLATILE(sym->etype) = 1;
914         /* if initial value given */
915         if (sym->ival) {
916             SPEC_ABSA(sym->etype) = 1;
917             SPEC_ADDR(sym->etype) =
918                 (int) list2int(sym->ival);
919             sym->ival = NULL;
920         }
921     }
922
923     /* if absolute address given then it mark it as
924        volatile */
925     if (IS_ABSOLUTE(sym->etype))
926         SPEC_VOLATILE(sym->etype) = 1;
927
928     /* global variables declared const put into code */
929     if (sym->level == 0 && 
930         SPEC_SCLS(sym->etype) == S_CONSTANT) 
931         SPEC_SCLS(sym->etype) = S_CODE ;
932     
933
934     /* global variable in code space is a constant */
935     if (sym->level == 0 && 
936         SPEC_SCLS(sym->etype) == S_CODE) 
937         SPEC_CONST(sym->etype) = 1;
938     
939
940     /* if bit variable then no storage class can be */
941     /* specified since bit is already a storage */
942     if ( IS_BITVAR(sym->etype)              && 
943          ( SPEC_SCLS(sym->etype) != S_FIXED &&   
944            SPEC_SCLS(sym->etype) != S_SBIT  &&
945            SPEC_SCLS(sym->etype) != S_BIT )
946          ) {
947         werror (E_BITVAR_STORAGE,sym->name);
948         SPEC_SCLS(sym->etype) = S_FIXED ;
949     }
950     
951     /* extern variables cannot be initialized */
952     if (IS_EXTERN(sym->etype) && sym->ival)     {
953         werror(E_EXTERN_INIT,sym->name);
954         sym->ival = NULL;
955     }    
956     
957     /* if this is an automatic symbol then */
958     /* storage class will be ignored and   */
959     /* symbol will be allocated on stack/  */
960     /* data depending on flag             */
961     if ( sym->level                             &&
962          (options.stackAuto || reentrant )      &&
963          ( SPEC_SCLS(sym->etype) != S_AUTO      &&
964            SPEC_SCLS(sym->etype) != S_FIXED     &&
965            SPEC_SCLS(sym->etype) != S_REGISTER  &&
966            SPEC_SCLS(sym->etype) != S_STACK     &&
967            SPEC_SCLS(sym->etype) != S_XSTACK    &&
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.useXstack  ?
1011                                      S_XSTACK : S_STACK ) ;
1012         else
1013             SPEC_SCLS(sym->etype) = (options.useXstack  ?
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 }