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