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