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