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