fixed parms->ArgSym bug & type system bug
[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
917       /* create the internal name for this variable */
918       sprintf (loop->rname, "_%s", loop->name);
919       loop->offset = (su == UNION ? sum = 0 : sum);
920       SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
921
922       /* if this is a bit field  */
923       if (loop->bitVar)
924         {
925
926           /* change it to a unsigned bit */
927           SPEC_NOUN (loop->etype) = V_BIT;
928           SPEC_USIGN (loop->etype) = 1;
929           /* check if this fit into the remaining   */
930           /* bits of this byte else align it to the */
931           /* next byte boundary                     */
932           if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset))
933             {
934               SPEC_BSTR (loop->etype) = bitOffset;
935               if ((bitOffset += (loop->bitVar % 8)) == 8)
936                 sum++;
937             }
938           else
939             /* does not fit */
940             {
941               bitOffset = 0;
942               SPEC_BSTR (loop->etype) = bitOffset;
943               sum += (loop->bitVar / 8);
944               bitOffset += (loop->bitVar % 8);
945             }
946           /* if this is the last field then pad */
947           if (!loop->next && bitOffset && bitOffset != 8)
948             {
949               bitOffset = 0;
950               sum++;
951             }
952         }
953       else
954         {
955           checkDecl (loop);
956           sum += getSize (loop->type);
957         }
958
959       /* if function then do the arguments for it */
960       if (funcInChain (loop->type))
961         {
962           processFuncArgs (loop, 1);
963         }
964
965       loop = loop->next;
966
967       /* if this is not a bitfield but the */
968       /* previous one was and did not take */
969       /* the whole byte then pad the rest  */
970       if ((loop && !loop->bitVar) && bitOffset)
971         {
972           bitOffset = 0;
973           sum++;
974         }
975
976       /* if union then size = sizeof larget field */
977       if (su == UNION)
978         usum = max (usum, sum);
979
980     }
981
982   return (su == UNION ? usum : sum);
983 }
984
985 /*------------------------------------------------------------------*/
986 /* checkSClass - check the storage class specification              */
987 /*------------------------------------------------------------------*/
988 static void 
989 checkSClass (symbol * sym)
990 {
991   /* type is literal can happen foe enums change
992      to auto */
993   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
994     SPEC_SCLS (sym->etype) = S_AUTO;
995
996   /* if sfr or sbit then must also be */
997   /* volatile the initial value will be xlated */
998   /* to an absolute address */
999   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1000       SPEC_SCLS (sym->etype) == S_SFR)
1001     {
1002       SPEC_VOLATILE (sym->etype) = 1;
1003       /* if initial value given */
1004       if (sym->ival)
1005         {
1006           SPEC_ABSA (sym->etype) = 1;
1007           SPEC_ADDR (sym->etype) =
1008             (int) list2int (sym->ival);
1009           sym->ival = NULL;
1010         }
1011     }
1012
1013   /* if absolute address given then it mark it as
1014      volatile */
1015   if (IS_ABSOLUTE (sym->etype))
1016     SPEC_VOLATILE (sym->etype) = 1;
1017
1018   /* global variables declared const put into code */
1019   if (sym->level == 0 &&
1020       SPEC_SCLS (sym->etype) == S_CONSTANT)
1021     {
1022       SPEC_SCLS (sym->etype) = S_CODE;
1023       SPEC_CONST (sym->etype) = 1;
1024     }
1025
1026   /* global variable in code space is a constant */
1027   if (sym->level == 0 &&
1028       SPEC_SCLS (sym->etype) == S_CODE &&
1029       port->mem.code_ro)
1030     SPEC_CONST (sym->etype) = 1;
1031
1032
1033   /* if bit variable then no storage class can be */
1034   /* specified since bit is already a storage */
1035   if (IS_BITVAR (sym->etype) &&
1036       (SPEC_SCLS (sym->etype) != S_FIXED &&
1037        SPEC_SCLS (sym->etype) != S_SBIT &&
1038        SPEC_SCLS (sym->etype) != S_BIT)
1039     )
1040     {
1041       werror (E_BITVAR_STORAGE, sym->name);
1042       SPEC_SCLS (sym->etype) = S_FIXED;
1043     }
1044
1045   /* extern variables cannot be initialized */
1046   if (IS_EXTERN (sym->etype) && sym->ival)
1047     {
1048       werror (E_EXTERN_INIT, sym->name);
1049       sym->ival = NULL;
1050     }
1051
1052   /* if this is an automatic symbol then */
1053   /* storage class will be ignored and   */
1054   /* symbol will be allocated on stack/  */
1055   /* data depending on flag             */
1056   if (sym->level &&
1057       (options.stackAuto || reentrant) &&
1058       (SPEC_SCLS (sym->etype) != S_AUTO &&
1059        SPEC_SCLS (sym->etype) != S_FIXED &&
1060        SPEC_SCLS (sym->etype) != S_REGISTER &&
1061        SPEC_SCLS (sym->etype) != S_STACK &&
1062        SPEC_SCLS (sym->etype) != S_XSTACK &&
1063        SPEC_SCLS (sym->etype) != S_CONSTANT))
1064     {
1065
1066       werror (E_AUTO_ASSUMED, sym->name);
1067       SPEC_SCLS (sym->etype) = S_AUTO;
1068     }
1069
1070   /* automatic symbols cannot be given   */
1071   /* an absolute address ignore it      */
1072   if (sym->level &&
1073       SPEC_ABSA (sym->etype) &&
1074       (options.stackAuto || reentrant))
1075     {
1076       werror (E_AUTO_ABSA, sym->name);
1077       SPEC_ABSA (sym->etype) = 0;
1078     }
1079
1080   /* arrays & pointers cannot be defined for bits   */
1081   /* SBITS or SFRs or BIT                           */
1082   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1083       (SPEC_NOUN (sym->etype) == V_BIT ||
1084        SPEC_NOUN (sym->etype) == V_SBIT ||
1085        SPEC_SCLS (sym->etype) == S_SFR))
1086     werror (E_BIT_ARRAY, sym->name);
1087
1088   /* if this is a bit|sbit then set length & start  */
1089   if (SPEC_NOUN (sym->etype) == V_BIT ||
1090       SPEC_NOUN (sym->etype) == V_SBIT)
1091     {
1092       SPEC_BLEN (sym->etype) = 1;
1093       SPEC_BSTR (sym->etype) = 0;
1094     }
1095
1096   /* variables declared in CODE space must have */
1097   /* initializers if not an extern */
1098   if (SPEC_SCLS (sym->etype) == S_CODE &&
1099       sym->ival == NULL &&
1100       !sym->level &&
1101       port->mem.code_ro &&
1102       !IS_EXTERN (sym->etype) &&
1103       !funcInChain (sym->type))
1104     werror (E_CODE_NO_INIT, sym->name);
1105
1106   /* if parameter or local variable then change */
1107   /* the storage class to reflect where the var will go */
1108   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED)
1109     {
1110       if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1111         {
1112           SPEC_SCLS (sym->etype) = (options.useXstack ?
1113                                     S_XSTACK : S_STACK);
1114         }
1115       else
1116         {
1117           /* hack-o-matic! I see no reason why the useXstack option should ever
1118            * control this allcoation, but the code was originally that way, and
1119            * changing it for non-390 ports breaks the compiler badly.
1120            */
1121           bool useXdata = IS_DS390_PORT ? options.model : options.useXstack;
1122           SPEC_SCLS (sym->etype) = (useXdata ?
1123                                     S_XDATA : S_FIXED);
1124         }
1125     }
1126 }
1127
1128 /*------------------------------------------------------------------*/
1129 /* changePointer - change pointer to functions                      */
1130 /*------------------------------------------------------------------*/
1131 void 
1132 changePointer (symbol * sym)
1133 {
1134   sym_link *p;
1135
1136   /* go thru the chain of declarations   */
1137   /* if we find a pointer to a function  */
1138   /* unconditionally change it to a ptr  */
1139   /* to code area                        */
1140   for (p = sym->type; p; p = p->next)
1141     {
1142       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1143         DCL_TYPE (p) = GPOINTER;
1144       if (IS_PTR (p) && IS_FUNC (p->next))
1145         DCL_TYPE (p) = CPOINTER;
1146     }
1147 }
1148
1149 /*------------------------------------------------------------------*/
1150 /* checkDecl - does semantic validation of a declaration                   */
1151 /*------------------------------------------------------------------*/
1152 int 
1153 checkDecl (symbol * sym)
1154 {
1155
1156   checkSClass (sym);            /* check the storage class      */
1157   changePointer (sym);          /* change pointers if required */
1158
1159   /* if this is an array without any dimension
1160      then update the dimension from the initial value */
1161   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1162     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1163
1164   return 0;
1165 }
1166
1167 /*------------------------------------------------------------------*/
1168 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1169 /*------------------------------------------------------------------*/
1170 sym_link *
1171 copyLinkChain (sym_link * p)
1172 {
1173   sym_link *head, *curr, *loop;
1174
1175   curr = p;
1176   head = loop = (curr ? newLink () : (void *) NULL);
1177   while (curr)
1178     {
1179       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1180       loop->next = (curr->next ? newLink () : (void *) NULL);
1181       loop = loop->next;
1182       curr = curr->next;
1183     }
1184
1185   return head;
1186 }
1187
1188
1189 /*------------------------------------------------------------------*/
1190 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1191 /*                symbols in the given block                        */
1192 /*------------------------------------------------------------------*/
1193 void 
1194 cleanUpBlock (bucket ** table, int block)
1195 {
1196   int i;
1197   bucket *chain;
1198
1199   /* go thru the entire  table  */
1200   for (i = 0; i < 256; i++)
1201     {
1202       for (chain = table[i]; chain; chain = chain->next)
1203         {
1204           if (chain->block >= block)
1205             {
1206               deleteSym (table, chain->sym, chain->name);
1207             }
1208         }
1209     }
1210 }
1211
1212 /*------------------------------------------------------------------*/
1213 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1214 /*                symbols in the given level                        */
1215 /*------------------------------------------------------------------*/
1216 void 
1217 cleanUpLevel (bucket ** table, int level)
1218 {
1219   int i;
1220   bucket *chain;
1221
1222   /* go thru the entire  table  */
1223   for (i = 0; i < 256; i++)
1224     {
1225       for (chain = table[i]; chain; chain = chain->next)
1226         {
1227           if (chain->level >= level)
1228             {
1229               deleteSym (table, chain->sym, chain->name);
1230             }
1231         }
1232     }
1233 }
1234
1235 /*------------------------------------------------------------------*/
1236 /* computeType - computes the resultant type from two types         */
1237 /*------------------------------------------------------------------*/
1238 sym_link *
1239 computeType (sym_link * type1, sym_link * type2)
1240 {
1241   sym_link *rType;
1242   sym_link *reType;
1243   sym_link *etype1 = getSpec (type1);
1244   sym_link *etype2 = getSpec (type2);
1245
1246   /* if one of them is a float then result is a float */
1247   /* here we assume that the types passed are okay */
1248   /* and can be cast to one another                */
1249   /* which ever is greater in size */
1250   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1251     rType = newFloatLink ();
1252   else
1253     /* if only one of them is a bit variable
1254        then the other one prevails */
1255   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1256     rType = copyLinkChain (type2);
1257   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1258     rType = copyLinkChain (type1);
1259   else
1260     /* if one of them is a pointer then that
1261        prevails */
1262   if (IS_PTR (type1))
1263     rType = copyLinkChain (type1);
1264   else if (IS_PTR (type2))
1265     rType = copyLinkChain (type2);
1266   else if (getSize (type1) > getSize (type2))
1267     rType = copyLinkChain (type1);
1268   else
1269     rType = copyLinkChain (type2);
1270
1271   reType = getSpec (rType);
1272
1273   /* if either of them unsigned then make this unsigned */
1274   if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1275     SPEC_USIGN (reType) = 1;
1276
1277   /* if result is a literal then make not so */
1278   if (IS_LITERAL (reType))
1279     SPEC_SCLS (reType) = S_REGISTER;
1280
1281   return rType;
1282 }
1283
1284 /*------------------------------------------------------------------*/
1285 /* checkType - will do type check return 1 if match                 */
1286 /*------------------------------------------------------------------*/
1287 int 
1288 checkType (sym_link * dest, sym_link * src)
1289 {
1290   if (!dest && !src)
1291     return 1;
1292
1293   if (dest && !src)
1294     return 0;
1295
1296   if (src && !dest)
1297     return 0;
1298
1299   /* if dest is a declarator then */
1300   if (IS_DECL (dest))
1301     {
1302       if (IS_DECL (src))
1303         {
1304           if (DCL_TYPE (src) == DCL_TYPE (dest))
1305             return checkType (dest->next, src->next);
1306           else if (IS_PTR (src) && IS_PTR (dest))
1307             return -1;
1308           else if (IS_PTR (dest) && IS_ARRAY (src))
1309             return -1;
1310           else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1311             return -1 * checkType (dest->next, src);
1312           else
1313             return 0;
1314         }
1315       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1316         return -1;
1317       else
1318         return 0;
1319     }
1320
1321   /* if one is a specifier and the other is not */
1322   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1323       (IS_SPEC (dest) && !IS_SPEC (src)))
1324     return 0;
1325
1326   /* if one of them is a void then ok */
1327   if (SPEC_NOUN (dest) == V_VOID &&
1328       SPEC_NOUN (src) != V_VOID)
1329     return -1;
1330
1331   if (SPEC_NOUN (dest) != V_VOID &&
1332       SPEC_NOUN (src) == V_VOID)
1333     return -1;
1334
1335   /* char === to short */
1336   if (SPEC_NOUN (dest) == V_CHAR &&
1337       SPEC_NOUN (src) == V_INT &&
1338       SPEC_SHORT (src))
1339     return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1340
1341   if (SPEC_NOUN (src) == V_CHAR &&
1342       SPEC_NOUN (dest) == V_INT &&
1343       SPEC_SHORT (dest))
1344     return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1345
1346   /* if they are both bitfields then if the lengths
1347      and starts don't match */
1348   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1349       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1350        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1351     return -1;
1352
1353   /* it is a specifier */
1354   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1355     {
1356       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1357           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1358           getSize (dest) == getSize (src))
1359         return 1;
1360       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1361         return -1;
1362       else
1363         return 0;
1364     }
1365   else if (IS_STRUCT (dest))
1366     {
1367       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1368         return 0;
1369       else
1370         return 1;
1371     }
1372   if (SPEC_LONG (dest) != SPEC_LONG (src))
1373     return -1;
1374
1375   if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1376     return -1;
1377
1378   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1379     return -2;
1380
1381   return 1;
1382 }
1383
1384 /*------------------------------------------------------------------*/
1385 /* inCalleeSaveList - return 1 if found in calle save list          */
1386 /*------------------------------------------------------------------*/
1387 bool 
1388 inCalleeSaveList (char *s)
1389 {
1390   int i;
1391
1392   for (i = 0; options.calleeSaves[i]; i++)
1393     if (strcmp (options.calleeSaves[i], s) == 0)
1394       return 1;
1395
1396   return 0;
1397 }
1398
1399 /*-----------------------------------------------------------------*/
1400 /* aggregateArgToPointer:  change an agggregate type function      */
1401 /*         argument to a pointer to that type.     */
1402 /*-----------------------------------------------------------------*/
1403 void 
1404 aggregateArgToPointer (value * val)
1405 {
1406   if (IS_AGGREGATE (val->type))
1407     {
1408       /* if this is a structure */
1409       /* then we need to add a new link */
1410       if (IS_STRUCT (val->type))
1411         {
1412           /* first lets add DECLARATOR type */
1413           sym_link *p = val->type;
1414
1415           werror (W_STRUCT_AS_ARG, val->name);
1416           val->type = newLink ();
1417           val->type->next = p;
1418         }
1419
1420       /* change to a pointer depending on the */
1421       /* storage class specified        */
1422       switch (SPEC_SCLS (val->etype))
1423         {
1424         case S_IDATA:
1425           DCL_TYPE (val->type) = IPOINTER;
1426           break;
1427         case S_PDATA:
1428           DCL_TYPE (val->type) = PPOINTER;
1429           break;
1430         case S_FIXED:
1431           if (IS_DS390_PORT)
1432             {
1433               /* The AUTO and REGISTER classes should probably
1434                * also become generic pointers, but I haven't yet
1435                * devised a test case for that.
1436                */
1437               DCL_TYPE (val->type) = GPOINTER;
1438               break;
1439             }
1440           /* fall through! */
1441         case S_AUTO:
1442         case S_DATA:
1443         case S_REGISTER:
1444           DCL_TYPE (val->type) = POINTER;
1445           break;
1446         case S_CODE:
1447           DCL_TYPE (val->type) = CPOINTER;
1448           break;
1449         case S_XDATA:
1450           DCL_TYPE (val->type) = FPOINTER;
1451           break;
1452         case S_EEPROM:
1453           DCL_TYPE (val->type) = EEPPOINTER;
1454           break;
1455         default:
1456           DCL_TYPE (val->type) = GPOINTER;
1457         }
1458
1459       /* is there is a symbol associated then */
1460       /* change the type of the symbol as well */
1461       if (val->sym)
1462         {
1463           val->sym->type = copyLinkChain (val->type);
1464           val->sym->etype = getSpec (val->sym->type);
1465         }
1466     }
1467 }
1468 /*------------------------------------------------------------------*/
1469 /* checkFunction - does all kinds of check on a function            */
1470 /*------------------------------------------------------------------*/
1471 int 
1472 checkFunction (symbol * sym)
1473 {
1474   symbol *csym;
1475   value *exargs, *acargs;
1476   int argCnt = 0;
1477
1478   /* if not type then some kind of error */
1479   if (!sym->type)
1480     return 0;
1481
1482   /* if the function has no type then make it return int */
1483   if (!sym->type->next)
1484     sym->type->next = sym->etype = newIntLink ();
1485
1486   /* function cannot return aggregate */
1487   if (IS_AGGREGATE (sym->type->next))
1488     {
1489       werror (E_FUNC_AGGR, sym->name);
1490       return 0;
1491     }
1492
1493   /* function cannot return bit */
1494   if (IS_BITVAR (sym->type->next))
1495     {
1496       werror (E_FUNC_BIT, sym->name);
1497       return 0;
1498     }
1499
1500   /* check if this function is defined as calleeSaves
1501      then mark it as such */
1502   sym->calleeSave = inCalleeSaveList (sym->name);
1503
1504   /* if interrupt service routine  */
1505   /* then it cannot have arguments */
1506   if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1507     {
1508       werror (E_INT_ARGS, sym->name);
1509       sym->args = NULL;
1510     }
1511
1512   if (!(csym = findSym (SymbolTab, sym, sym->name)))
1513     return 1;                   /* not defined nothing more to check  */
1514
1515   /* check if body already present */
1516   if (csym && csym->fbody)
1517     {
1518       werror (E_FUNC_BODY, sym->name);
1519       return 0;
1520     }
1521
1522   /* check the return value type   */
1523   if (checkType (csym->type, sym->type) <= 0)
1524     {
1525       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1526       werror (E_CONTINUE, "previous defintion type ");
1527       printTypeChain (csym->type, stderr);
1528       fprintf (stderr, "\n");
1529       werror (E_CONTINUE, "current definition type ");
1530       printTypeChain (sym->type, stderr);
1531       fprintf (stderr, "\n");
1532       return 0;
1533     }
1534
1535   if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1536     {
1537       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1538       return 0;
1539     }
1540
1541   if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1542     {
1543       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1544       return 0;
1545     }
1546
1547   /* compare expected agrs with actual args */
1548   exargs = csym->args;
1549   acargs = sym->args;
1550
1551   /* for all the expected args do */
1552   for (argCnt = 1;
1553        exargs && acargs;
1554        exargs = exargs->next, acargs = acargs->next, argCnt++)
1555     {
1556       value *checkValue;
1557       /* If the actual argument is an array, any prototype
1558        * will have modified it to a pointer. Duplicate that
1559        * change here.
1560        */
1561       if (IS_AGGREGATE (acargs->type))
1562         {
1563           checkValue = copyValue (acargs);
1564           aggregateArgToPointer (checkValue);
1565         }
1566       else
1567         {
1568           checkValue = acargs;
1569         }
1570
1571       if (checkType (exargs->type, checkValue->type) <= 0)
1572         {
1573           werror (E_ARG_TYPE, argCnt);
1574           return 0;
1575         }
1576     }
1577
1578   /* if one them ended we have a problem */
1579   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1580       (!exargs && acargs && !IS_VOID (acargs->type)))
1581     werror (E_ARG_COUNT);
1582
1583   /* replace with this defition */
1584   sym->cdef = csym->cdef;
1585   deleteSym (SymbolTab, csym, csym->name);
1586   addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
1587   if (IS_EXTERN (csym->etype) && !
1588       IS_EXTERN (sym->etype))
1589     {
1590       addSet (&publics, sym);
1591     }
1592   return 1;
1593 }
1594
1595 /*-----------------------------------------------------------------*/
1596 /* processFuncArgs - does some processing with function args       */
1597 /*-----------------------------------------------------------------*/
1598 void 
1599 processFuncArgs (symbol * func, int ignoreName)
1600 {
1601   value *val;
1602   int pNum = 1;
1603
1604
1605   /* if this function has variable argument list */
1606   /* then make the function a reentrant one    */
1607   if (func->hasVargs)
1608     SPEC_RENT (func->etype) = 1;
1609
1610   /* check if this function is defined as calleeSaves
1611      then mark it as such */
1612   func->calleeSave = inCalleeSaveList (func->name);
1613
1614   val = func->args;             /* loop thru all the arguments   */
1615
1616   /* if it is void then remove parameters */
1617   if (val && IS_VOID (val->type))
1618     {
1619       func->args = NULL;
1620       return;
1621     }
1622
1623   /* reset regparm for the port */
1624   (*port->reset_regparms) ();
1625   /* if any of the arguments is an aggregate */
1626   /* change it to pointer to the same type */
1627   while (val)
1628     {
1629       /* mark it as a register parameter if
1630          the function does not have VA_ARG
1631          and as port dictates
1632          not inhibited by command line option or #pragma */
1633       if (!func->hasVargs &&
1634           !options.noregparms &&
1635           !IS_RENT (func->etype) &&
1636           (*port->reg_parm) (val->type))
1637         {
1638           SPEC_REGPARM (val->etype) = 1;
1639         }
1640
1641       if (IS_AGGREGATE (val->type))
1642         {
1643           aggregateArgToPointer (val);
1644         }
1645       val = val->next;
1646       pNum++;
1647     }
1648
1649   /* if this function is reentrant or */
1650   /* automatics r 2b stacked then nothing */
1651   if (IS_RENT (func->etype) || options.stackAuto)
1652     return;
1653
1654   val = func->args;
1655   pNum = 1;
1656   while (val)
1657     {
1658
1659       /* if a symbolname is not given  */
1660       /* synthesize a variable name */
1661       if (!val->sym)
1662         {
1663
1664           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1665           val->sym = newSymbol (val->name, 1);
1666           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1667           val->sym->type = copyLinkChain (val->type);
1668           val->sym->etype = getSpec (val->sym->type);
1669           val->sym->_isparm = 1;
1670           strcpy (val->sym->rname, val->name);
1671           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1672             SPEC_STAT (func->etype);
1673           addSymChain (val->sym);
1674
1675         }
1676       else                      /* symbol name given create synth name */
1677         {
1678
1679           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1680           strcpy (val->sym->rname, val->name);
1681           val->sym->_isparm = 1;
1682           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1683             (options.model != MODEL_SMALL ? xdata : data);
1684           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1685             SPEC_STAT (func->etype);
1686         }
1687       val = val->next;
1688     }
1689 }
1690
1691 /*-----------------------------------------------------------------*/
1692 /* isSymbolEqual - compares two symbols return 1 if they match     */
1693 /*-----------------------------------------------------------------*/
1694 int 
1695 isSymbolEqual (symbol * dest, symbol * src)
1696 {
1697   /* if pointers match then equal */
1698   if (dest == src)
1699     return 1;
1700
1701   /* if one of them is null then don't match */
1702   if (!dest || !src)
1703     return 0;
1704
1705   /* if both of them have rname match on rname */
1706   if (dest->rname[0] && src->rname[0])
1707     return (!strcmp (dest->rname, src->rname));
1708
1709   /* otherwise match on name */
1710   return (!strcmp (dest->name, src->name));
1711 }
1712
1713 void PT(sym_link *type)
1714 {
1715         printTypeChain(type,0);
1716 }
1717 /*-----------------------------------------------------------------*/
1718 /* printTypeChain - prints the type chain in human readable form   */
1719 /*-----------------------------------------------------------------*/
1720 void 
1721 printTypeChain (sym_link * type, FILE * of)
1722 {
1723   int nlr = 0;
1724
1725   if (!of)
1726     {
1727       of = stdout;
1728       nlr = 1;
1729     }
1730
1731   while (type)
1732     {
1733       if (IS_DECL (type))
1734         {
1735           switch (DCL_TYPE (type))
1736             {
1737             case FUNCTION:
1738               fprintf (of, "function ");
1739               break;
1740             case GPOINTER:
1741               fprintf (of, "_generic * ");
1742               if (DCL_PTR_CONST (type))
1743                 fprintf (of, "const ");
1744               break;
1745             case CPOINTER:
1746               fprintf (of, "_code * ");
1747               if (DCL_PTR_CONST (type))
1748                 fprintf (of, "const ");
1749               break;
1750             case FPOINTER:
1751               fprintf (of, "_far * ");
1752               if (DCL_PTR_CONST (type))
1753                 fprintf (of, "const ");
1754               break;
1755             case EEPPOINTER:
1756               fprintf (of, "_eeprom * ");
1757               if (DCL_PTR_CONST (type))
1758                 fprintf (of, "const ");
1759               break;
1760
1761             case POINTER:
1762               fprintf (of, "_near * ");
1763               if (DCL_PTR_CONST (type))
1764                 fprintf (of, "const ");
1765               break;
1766             case IPOINTER:
1767               fprintf (of, "_idata *");
1768               if (DCL_PTR_CONST (type))
1769                 fprintf (of, "const ");
1770               break;
1771             case PPOINTER:
1772               fprintf (of, "_pdata *");
1773               if (DCL_PTR_CONST (type))
1774                 fprintf (of, "const ");
1775               break;
1776             case UPOINTER:
1777               fprintf (of, " _unkown *");
1778               if (DCL_PTR_CONST (type))
1779                 fprintf (of, "const ");
1780               break;
1781
1782             case ARRAY:
1783               fprintf (of, "array of ");
1784               break;
1785             }
1786         }
1787       else
1788         {
1789           if (SPEC_VOLATILE (type))
1790             fprintf (of, "volatile ");
1791           if (SPEC_USIGN (type))
1792             fprintf (of, "unsigned ");
1793           if (SPEC_CONST (type))
1794             fprintf (of, "const ");
1795
1796           switch (SPEC_NOUN (type))
1797             {
1798             case V_INT:
1799               if (IS_LONG (type))
1800                 fprintf (of, "long ");
1801               else if (IS_SHORT (type))
1802                 fprintf (of, "short ");
1803               else
1804                 fprintf (of, "int ");
1805               break;
1806
1807             case V_CHAR:
1808               fprintf (of, "char ");
1809               break;
1810
1811             case V_VOID:
1812               fprintf (of, "void ");
1813               break;
1814
1815             case V_FLOAT:
1816               fprintf (of, "float ");
1817               break;
1818
1819             case V_STRUCT:
1820               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1821               break;
1822
1823             case V_SBIT:
1824               fprintf (of, "sbit ");
1825               break;
1826
1827             case V_BIT:
1828               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1829               break;
1830
1831             default:
1832               break;
1833             }
1834         }
1835       type = type->next;
1836     }
1837   if (nlr)
1838     fprintf (of, "\n");
1839 }
1840
1841 /*-----------------------------------------------------------------*/
1842 /* cdbTypeInfo - print the type information for debugger           */
1843 /*-----------------------------------------------------------------*/
1844 void 
1845 cdbTypeInfo (sym_link * type, FILE * of)
1846 {
1847   fprintf (of, "{%d}", getSize (type));
1848   while (type)
1849     {
1850       if (IS_DECL (type))
1851         {
1852           switch (DCL_TYPE (type))
1853             {
1854             case FUNCTION:
1855               fprintf (of, "DF,");
1856               break;
1857             case GPOINTER:
1858               fprintf (of, "DG,");
1859               break;
1860             case CPOINTER:
1861               fprintf (of, "DC,");
1862               break;
1863             case FPOINTER:
1864               fprintf (of, "DX,");
1865               break;
1866             case POINTER:
1867               fprintf (of, "DD,");
1868               break;
1869             case IPOINTER:
1870               fprintf (of, "DI,");
1871               break;
1872             case PPOINTER:
1873               fprintf (of, "DP,");
1874               break;
1875             case EEPPOINTER:
1876               fprintf (of, "DA,");
1877               break;
1878             case ARRAY:
1879               fprintf (of, "DA%d,", DCL_ELEM (type));
1880               break;
1881             default:
1882               break;
1883             }
1884         }
1885       else
1886         {
1887           switch (SPEC_NOUN (type))
1888             {
1889             case V_INT:
1890               if (IS_LONG (type))
1891                 fprintf (of, "SL");
1892               else if (IS_SHORT (type))
1893                 fprintf (of, "SS");
1894               else
1895                 fprintf (of, "SI");
1896               break;
1897
1898             case V_CHAR:
1899               fprintf (of, "SC");
1900               break;
1901
1902             case V_VOID:
1903               fprintf (of, "SV");
1904               break;
1905
1906             case V_FLOAT:
1907               fprintf (of, "SF");
1908               break;
1909
1910             case V_STRUCT:
1911               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1912               break;
1913
1914             case V_SBIT:
1915               fprintf (of, "SX");
1916               break;
1917
1918             case V_BIT:
1919               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1920               break;
1921
1922             default:
1923               break;
1924             }
1925           fputs (":", of);
1926           if (SPEC_USIGN (type))
1927             fputs ("U", of);
1928           else
1929             fputs ("S", of);
1930         }
1931       type = type->next;
1932     }
1933 }
1934 /*-----------------------------------------------------------------*/
1935 /* cdbSymbol - prints a symbol & its type information for debugger */
1936 /*-----------------------------------------------------------------*/
1937 void 
1938 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
1939 {
1940   memmap *map;
1941
1942   if (!sym)
1943     return;
1944   if (!of)
1945     of = stdout;
1946
1947   if (isFunc)
1948     fprintf (of, "F:");
1949   else
1950     fprintf (of, "S:");         /* symbol record */
1951   /* if this is not a structure symbol then
1952      we need to figure out the scope information */
1953   if (!isStructSym)
1954     {
1955       if (!sym->level)
1956         {
1957           /* global */
1958           if (IS_STATIC (sym->etype))
1959             fprintf (of, "F%s$", moduleName);   /* scope is file */
1960           else
1961             fprintf (of, "G$"); /* scope is global */
1962         }
1963       else
1964         /* symbol is local */
1965         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
1966     }
1967   else
1968     fprintf (of, "S$");         /* scope is structure */
1969
1970   /* print the name, & mangled name */
1971   fprintf (of, "%s$%d$%d(", sym->name,
1972            sym->level, sym->block);
1973
1974   cdbTypeInfo (sym->type, of);
1975   fprintf (of, "),");
1976
1977   /* print the address space */
1978   map = SPEC_OCLS (sym->etype);
1979   fprintf (of, "%c,%d,%d",
1980            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
1981
1982   /* if assigned to registers then output register names */
1983   /* if this is a function then print
1984      if is it an interrupt routine & interrupt number
1985      and the register bank it is using */
1986   if (isFunc)
1987     fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
1988              SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
1989   /* alternate location to find this symbol @ : eg registers
1990      or spillication */
1991
1992   if (!isStructSym)
1993     fprintf (of, "\n");
1994 }
1995
1996 /*-----------------------------------------------------------------*/
1997 /* cdbStruct - print a structure for debugger                      */
1998 /*-----------------------------------------------------------------*/
1999 void 
2000 cdbStruct (structdef * sdef, int block, FILE * of,
2001            int inStruct, char *tag)
2002 {
2003   symbol *sym;
2004
2005   fprintf (of, "T:");
2006   /* if block # then must have function scope */
2007   fprintf (of, "F%s$", moduleName);
2008   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2009   for (sym = sdef->fields; sym; sym = sym->next)
2010     {
2011       fprintf (of, "({%d}", sym->offset);
2012       cdbSymbol (sym, of, TRUE, FALSE);
2013       fprintf (of, ")");
2014     }
2015   fprintf (of, "]");
2016   if (!inStruct)
2017     fprintf (of, "\n");
2018 }
2019
2020 /*------------------------------------------------------------------*/
2021 /* cdbStructBlock - calls struct printing for a blcks               */
2022 /*------------------------------------------------------------------*/
2023 void 
2024 cdbStructBlock (int block, FILE * of)
2025 {
2026   int i;
2027   bucket **table = StructTab;
2028   bucket *chain;
2029   wassert (of);
2030
2031   /* go thru the entire  table  */
2032   for (i = 0; i < 256; i++)
2033     {
2034       for (chain = table[i]; chain; chain = chain->next)
2035         {
2036           if (chain->block >= block)
2037             {
2038               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2039             }
2040         }
2041     }
2042 }
2043
2044 /*-----------------------------------------------------------------*/
2045 /* powof2 - returns power of two for the number if number is pow 2 */
2046 /*-----------------------------------------------------------------*/
2047 int 
2048 powof2 (unsigned long num)
2049 {
2050   int nshifts = 0;
2051   int n1s = 0;
2052
2053   while (num)
2054     {
2055       if (num & 1)
2056         n1s++;
2057       num >>= 1;
2058       nshifts++;
2059     }
2060
2061   if (n1s > 1 || nshifts == 0)
2062     return 0;
2063   return nshifts - 1;
2064 }
2065
2066 symbol *__fsadd;
2067 symbol *__fssub;
2068 symbol *__fsmul;
2069 symbol *__fsdiv;
2070 symbol *__fseq;
2071 symbol *__fsneq;
2072 symbol *__fslt;
2073 symbol *__fslteq;
2074 symbol *__fsgt;
2075 symbol *__fsgteq;
2076
2077 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2078 symbol *__muldiv[3][3][2];
2079 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2080 sym_link *__multypes[3][2];
2081 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2082 symbol *__conv[2][3][2];
2083
2084 sym_link *floatType;
2085
2086 static void 
2087 _makeRegParam (symbol * sym)
2088 {
2089   value *val;
2090
2091   val = sym->args;              /* loop thru all the arguments   */
2092
2093   /* reset regparm for the port */
2094   (*port->reset_regparms) ();
2095   while (val)
2096     {
2097       SPEC_REGPARM (val->etype) = 1;
2098       sym->argStack -= getSize (val->type);
2099       val = val->next;
2100     }
2101 }
2102
2103 /*-----------------------------------------------------------------*/
2104 /* initCSupport - create functions for C support routines          */
2105 /*-----------------------------------------------------------------*/
2106 void 
2107 initCSupport ()
2108 {
2109   const char *smuldivmod[] =
2110   {
2111     "mul", "div", "mod"
2112   };
2113   const char *sbwd[] =
2114   {
2115     "char", "int", "long"
2116   };
2117   const char *ssu[] =
2118   {
2119     "s", "u"
2120   };
2121
2122   int bwd, su, muldivmod, tofrom;
2123
2124   floatType = newFloatLink ();
2125
2126   for (bwd = 0; bwd < 3; bwd++)
2127     {
2128       sym_link *l;
2129       switch (bwd)
2130         {
2131         case 0:
2132           l = newCharLink ();
2133           break;
2134         case 1:
2135           l = newIntLink ();
2136           break;
2137         case 2:
2138           l = newLongLink ();
2139           break;
2140         default:
2141           assert (0);
2142         }
2143       __multypes[bwd][0] = l;
2144       __multypes[bwd][1] = copyLinkChain (l);
2145       SPEC_USIGN (__multypes[bwd][1]) = 1;
2146     }
2147
2148   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2149   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2150   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2151   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2152   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2153   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2154   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2155   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2156   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2157   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2158
2159   for (tofrom = 0; tofrom < 2; tofrom++)
2160     {
2161       for (bwd = 0; bwd < 3; bwd++)
2162         {
2163           for (su = 0; su < 2; su++)
2164             {
2165               if (tofrom)
2166                 {
2167                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2168                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2169                 }
2170               else
2171                 {
2172                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2173                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2174                 }
2175             }
2176         }
2177     }
2178
2179   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2180     {
2181       for (bwd = 0; bwd < 3; bwd++)
2182         {
2183           for (su = 0; su < 2; su++)
2184             {
2185               sprintf (buffer, "_%s%s%s",
2186                        smuldivmod[muldivmod],
2187                        ssu[su],
2188                        sbwd[bwd]);
2189               __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2190               SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2191               if (bwd < port->muldiv.force_reg_param_below)
2192                 _makeRegParam (__muldiv[muldivmod][bwd][su]);
2193             }
2194         }
2195     }
2196 }