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