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