Beautified (indented) compiler source tree
[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)
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
1789           switch (SPEC_NOUN (type))
1790             {
1791             case V_INT:
1792               if (IS_LONG (type))
1793                 fprintf (of, "long ");
1794               else if (IS_SHORT (type))
1795                 fprintf (of, "short ");
1796               else
1797                 fprintf (of, "int ");
1798               break;
1799
1800             case V_CHAR:
1801               fprintf (of, "char ");
1802               break;
1803
1804             case V_VOID:
1805               fprintf (of, "void ");
1806               break;
1807
1808             case V_FLOAT:
1809               fprintf (of, "float ");
1810               break;
1811
1812             case V_STRUCT:
1813               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1814               break;
1815
1816             case V_SBIT:
1817               fprintf (of, "sbit ");
1818               break;
1819
1820             case V_BIT:
1821               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1822               break;
1823
1824             default:
1825               break;
1826             }
1827         }
1828       type = type->next;
1829     }
1830   if (nlr)
1831     fprintf (of, "\n");
1832 }
1833
1834 /*-----------------------------------------------------------------*/
1835 /* cdbTypeInfo - print the type information for debugger           */
1836 /*-----------------------------------------------------------------*/
1837 void 
1838 cdbTypeInfo (sym_link * type, FILE * of)
1839 {
1840   fprintf (of, "{%d}", getSize (type));
1841   while (type)
1842     {
1843       if (IS_DECL (type))
1844         {
1845           switch (DCL_TYPE (type))
1846             {
1847             case FUNCTION:
1848               fprintf (of, "DF,");
1849               break;
1850             case GPOINTER:
1851               fprintf (of, "DG,");
1852               break;
1853             case CPOINTER:
1854               fprintf (of, "DC,");
1855               break;
1856             case FPOINTER:
1857               fprintf (of, "DX,");
1858               break;
1859             case POINTER:
1860               fprintf (of, "DD,");
1861               break;
1862             case IPOINTER:
1863               fprintf (of, "DI,");
1864               break;
1865             case PPOINTER:
1866               fprintf (of, "DP,");
1867               break;
1868             case EEPPOINTER:
1869               fprintf (of, "DA,");
1870               break;
1871             case ARRAY:
1872               fprintf (of, "DA%d,", DCL_ELEM (type));
1873               break;
1874             default:
1875               break;
1876             }
1877         }
1878       else
1879         {
1880           switch (SPEC_NOUN (type))
1881             {
1882             case V_INT:
1883               if (IS_LONG (type))
1884                 fprintf (of, "SL");
1885               else if (IS_SHORT (type))
1886                 fprintf (of, "SS");
1887               else
1888                 fprintf (of, "SI");
1889               break;
1890
1891             case V_CHAR:
1892               fprintf (of, "SC");
1893               break;
1894
1895             case V_VOID:
1896               fprintf (of, "SV");
1897               break;
1898
1899             case V_FLOAT:
1900               fprintf (of, "SF");
1901               break;
1902
1903             case V_STRUCT:
1904               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1905               break;
1906
1907             case V_SBIT:
1908               fprintf (of, "SX");
1909               break;
1910
1911             case V_BIT:
1912               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1913               break;
1914
1915             default:
1916               break;
1917             }
1918           fputs (":", of);
1919           if (SPEC_USIGN (type))
1920             fputs ("U", of);
1921           else
1922             fputs ("S", of);
1923         }
1924       type = type->next;
1925     }
1926 }
1927 /*-----------------------------------------------------------------*/
1928 /* cdbSymbol - prints a symbol & its type information for debugger */
1929 /*-----------------------------------------------------------------*/
1930 void 
1931 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
1932 {
1933   memmap *map;
1934
1935   if (!sym)
1936     return;
1937   if (!of)
1938     of = stdout;
1939
1940   if (isFunc)
1941     fprintf (of, "F:");
1942   else
1943     fprintf (of, "S:");         /* symbol record */
1944   /* if this is not a structure symbol then
1945      we need to figure out the scope information */
1946   if (!isStructSym)
1947     {
1948       if (!sym->level)
1949         {
1950           /* global */
1951           if (IS_STATIC (sym->etype))
1952             fprintf (of, "F%s$", moduleName);   /* scope is file */
1953           else
1954             fprintf (of, "G$"); /* scope is global */
1955         }
1956       else
1957         /* symbol is local */
1958         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
1959     }
1960   else
1961     fprintf (of, "S$");         /* scope is structure */
1962
1963   /* print the name, & mangled name */
1964   fprintf (of, "%s$%d$%d(", sym->name,
1965            sym->level, sym->block);
1966
1967   cdbTypeInfo (sym->type, of);
1968   fprintf (of, "),");
1969
1970   /* print the address space */
1971   map = SPEC_OCLS (sym->etype);
1972   fprintf (of, "%c,%d,%d",
1973            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
1974
1975   /* if assigned to registers then output register names */
1976   /* if this is a function then print
1977      if is it an interrupt routine & interrupt number
1978      and the register bank it is using */
1979   if (isFunc)
1980     fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
1981              SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
1982   /* alternate location to find this symbol @ : eg registers
1983      or spillication */
1984
1985   if (!isStructSym)
1986     fprintf (of, "\n");
1987 }
1988
1989 /*-----------------------------------------------------------------*/
1990 /* cdbStruct - print a structure for debugger                      */
1991 /*-----------------------------------------------------------------*/
1992 void 
1993 cdbStruct (structdef * sdef, int block, FILE * of,
1994            int inStruct, char *tag)
1995 {
1996   symbol *sym;
1997
1998   fprintf (of, "T:");
1999   /* if block # then must have function scope */
2000   fprintf (of, "F%s$", moduleName);
2001   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2002   for (sym = sdef->fields; sym; sym = sym->next)
2003     {
2004       fprintf (of, "({%d}", sym->offset);
2005       cdbSymbol (sym, of, TRUE, FALSE);
2006       fprintf (of, ")");
2007     }
2008   fprintf (of, "]");
2009   if (!inStruct)
2010     fprintf (of, "\n");
2011 }
2012
2013 /*------------------------------------------------------------------*/
2014 /* cdbStructBlock - calls struct printing for a blcks               */
2015 /*------------------------------------------------------------------*/
2016 void 
2017 cdbStructBlock (int block, FILE * of)
2018 {
2019   int i;
2020   bucket **table = StructTab;
2021   bucket *chain;
2022   wassert (of);
2023
2024   /* go thru the entire  table  */
2025   for (i = 0; i < 256; i++)
2026     {
2027       for (chain = table[i]; chain; chain = chain->next)
2028         {
2029           if (chain->block >= block)
2030             {
2031               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2032             }
2033         }
2034     }
2035 }
2036
2037 /*-----------------------------------------------------------------*/
2038 /* powof2 - returns power of two for the number if number is pow 2 */
2039 /*-----------------------------------------------------------------*/
2040 int 
2041 powof2 (unsigned long num)
2042 {
2043   int nshifts = 0;
2044   int n1s = 0;
2045
2046   while (num)
2047     {
2048       if (num & 1)
2049         n1s++;
2050       num >>= 1;
2051       nshifts++;
2052     }
2053
2054   if (n1s > 1 || nshifts == 0)
2055     return 0;
2056   return nshifts - 1;
2057 }
2058
2059 symbol *__fsadd;
2060 symbol *__fssub;
2061 symbol *__fsmul;
2062 symbol *__fsdiv;
2063 symbol *__fseq;
2064 symbol *__fsneq;
2065 symbol *__fslt;
2066 symbol *__fslteq;
2067 symbol *__fsgt;
2068 symbol *__fsgteq;
2069
2070 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2071 symbol *__muldiv[3][3][2];
2072 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2073 sym_link *__multypes[3][2];
2074 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2075 symbol *__conv[2][3][2];
2076
2077 sym_link *floatType;
2078
2079 static void 
2080 _makeRegParam (symbol * sym)
2081 {
2082   value *val;
2083
2084   val = sym->args;              /* loop thru all the arguments   */
2085
2086   /* reset regparm for the port */
2087   (*port->reset_regparms) ();
2088   while (val)
2089     {
2090       SPEC_REGPARM (val->etype) = 1;
2091       sym->argStack -= getSize (val->type);
2092       val = val->next;
2093     }
2094 }
2095
2096 /*-----------------------------------------------------------------*/
2097 /* initCSupport - create functions for C support routines          */
2098 /*-----------------------------------------------------------------*/
2099 void 
2100 initCSupport ()
2101 {
2102   const char *smuldivmod[] =
2103   {
2104     "mul", "div", "mod"
2105   };
2106   const char *sbwd[] =
2107   {
2108     "char", "int", "long"
2109   };
2110   const char *ssu[] =
2111   {
2112     "s", "u"
2113   };
2114
2115   int bwd, su, muldivmod, tofrom;
2116
2117   floatType = newFloatLink ();
2118
2119   for (bwd = 0; bwd < 3; bwd++)
2120     {
2121       sym_link *l;
2122       switch (bwd)
2123         {
2124         case 0:
2125           l = newCharLink ();
2126           break;
2127         case 1:
2128           l = newIntLink ();
2129           break;
2130         case 2:
2131           l = newLongLink ();
2132           break;
2133         default:
2134           assert (0);
2135         }
2136       __multypes[bwd][0] = l;
2137       __multypes[bwd][1] = copyLinkChain (l);
2138       SPEC_USIGN (__multypes[bwd][1]) = 1;
2139     }
2140
2141   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2142   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2143   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2144   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2145   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2146   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2147   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2148   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2149   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2150   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2151
2152   for (tofrom = 0; tofrom < 2; tofrom++)
2153     {
2154       for (bwd = 0; bwd < 3; bwd++)
2155         {
2156           for (su = 0; su < 2; su++)
2157             {
2158               if (tofrom)
2159                 {
2160                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2161                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2162                 }
2163               else
2164                 {
2165                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2166                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2167                 }
2168             }
2169         }
2170     }
2171
2172   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2173     {
2174       for (bwd = 0; bwd < 3; bwd++)
2175         {
2176           for (su = 0; su < 2; su++)
2177             {
2178               sprintf (buffer, "_%s%s%s",
2179                        smuldivmod[muldivmod],
2180                        ssu[su],
2181                        sbwd[bwd]);
2182               __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2183               SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2184               if (bwd < port->muldiv.force_reg_param_below)
2185                 _makeRegParam (__muldiv[muldivmod][bwd][su]);
2186             }
2187         }
2188     }
2189 }