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