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