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