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