* src/Makefile.in (dep): include SLIBOBJS in dependency check
[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 value *aggregateToPointer (value *val);
28 void printTypeChainRaw (sym_link * start, FILE * of);
29
30 void printFromToType(sym_link *from, sym_link *to) {
31   fprintf (stderr, "from type '");
32   printTypeChain (from, stderr);
33   fprintf (stderr, "'\nto type '");
34   printTypeChain (to, stderr);
35   fprintf (stderr, "'\n");
36 }
37
38 /* noun strings */
39 char *nounName(sym_link *sl) {
40   switch (SPEC_NOUN(sl)) 
41     {
42     case V_INT: {
43       if (SPEC_LONG(sl)) return "long";
44       if (sl->select.s._short) return "short";
45       return "int";
46     }
47     case V_FLOAT: return "float";
48     case V_CHAR: return "char";
49     case V_VOID: return "void";
50     case V_STRUCT: return "struct";
51     case V_LABEL: return "label";
52     case V_BITFIELD: return "bitfield";
53     case V_BIT: return "bit";
54     case V_SBIT: return "sbit";
55     case V_DOUBLE: return "double";
56     }
57   return "unknown";
58 };
59
60 bucket *SymbolTab[256];         /* the symbol    table  */
61 bucket *StructTab[256];         /* the structure table  */
62 bucket *TypedefTab[256];        /* the typedef   table  */
63 bucket *LabelTab[256];          /* the Label     table  */
64 bucket *enumTab[256];           /* enumerated    table  */
65
66 /*------------------------------------------------------------------*/
67 /* initSymt () - initialises symbol table related stuff             */
68 /*------------------------------------------------------------------*/
69 void 
70 initSymt ()
71 {
72   int i = 0;
73
74   for (i = 0; i < 256; i++)
75     SymbolTab[i] = StructTab[i] = (void *) NULL;
76
77
78 }
79 /*-----------------------------------------------------------------*/
80 /* newBucket - allocates & returns a new bucket        */
81 /*-----------------------------------------------------------------*/
82 bucket *
83 newBucket ()
84 {
85   bucket *bp;
86
87   bp = Safe_alloc ( sizeof (bucket));
88
89   return bp;
90 }
91
92 /*-----------------------------------------------------------------*/
93 /* hashKey - computes the hashkey given a symbol name              */
94 /*-----------------------------------------------------------------*/
95 int 
96 hashKey (const char *s)
97 {
98   unsigned long key = 0;
99
100   while (*s)
101     key += *s++;
102   return key % 256;
103 }
104
105 /*-----------------------------------------------------------------*/
106 /* addSym - adds a symbol to the hash Table                        */
107 /*-----------------------------------------------------------------*/
108 void 
109 addSym (bucket ** stab,
110         void *sym,
111         char *sname,
112         int level,
113         int block,
114         int checkType)
115 {
116   int i;                        /* index into the hash Table */
117   bucket *bp;                   /* temp bucket    *         */
118
119   if (checkType) {
120     symbol *csym = (symbol *)sym;
121
122     if (getenv("DEBUG_SANITY")) {
123       fprintf (stderr, "addSym: %s ", sname);
124     }
125     /* make sure the type is complete and sane */
126     checkTypeSanity(csym->etype, csym->name);
127   }
128
129   /* prevent overflow of the (r)name buffers */
130   if (strlen(sname)>SDCC_SYMNAME_MAX) {
131     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
132     sname[SDCC_SYMNAME_MAX]='\0';
133   }
134
135   /* the symbols are always added at the head of the list  */
136   i = hashKey (sname);
137   /* get a free entry */
138   bp = Safe_alloc ( sizeof (bucket));
139
140   bp->sym = sym;                /* update the symbol pointer  */
141   bp->level = level;            /* update the nest level      */
142   bp->block = block;
143   strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
144
145   /* if this is the first entry */
146   if (stab[i] == NULL)
147     {
148       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
149       stab[i] = bp;
150     }
151   /* not first entry then add @ head of list */
152   else
153     {
154       bp->prev = NULL;
155       stab[i]->prev = bp;
156       bp->next = stab[i];
157       stab[i] = bp;
158     }
159 }
160
161 /*-----------------------------------------------------------------*/
162 /* deleteSym - deletes a symbol from the hash Table  entry     */
163 /*-----------------------------------------------------------------*/
164 void 
165 deleteSym (bucket ** stab, void *sym, char *sname)
166 {
167   int i = 0;
168   bucket *bp;
169
170   i = hashKey (sname);
171
172   bp = stab[i];
173   /* find the symbol */
174   while (bp)
175     {
176       if (bp->sym == sym)       /* found it then break out */
177         break;                  /* of the loop       */
178       bp = bp->next;
179     }
180
181   if (!bp)                      /* did not find it */
182     return;
183   /* if this is the first one in the chain */
184   if (!bp->prev)
185     {
186       stab[i] = bp->next;
187       if (stab[i])              /* if chain ! empty */
188         stab[i]->prev = (void *) NULL;
189     }
190   /* middle || end of chain */
191   else
192     {
193       if (bp->next)             /* if not end of chain */
194         bp->next->prev = bp->prev;
195
196       bp->prev->next = bp->next;
197     }
198
199 }
200
201 /*-----------------------------------------------------------------*/
202 /* findSym - finds a symbol in a table           */
203 /*-----------------------------------------------------------------*/
204 void *
205 findSym (bucket ** stab, void *sym, const char *sname)
206 {
207   bucket *bp;
208
209   bp = stab[hashKey (sname)];
210   while (bp)
211     {
212       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
213         break;
214       bp = bp->next;
215     }
216
217   return (bp ? bp->sym : (void *) NULL);
218 }
219
220 /*-----------------------------------------------------------------*/
221 /* findSymWithLevel - finds a symbol with a name & level           */
222 /*-----------------------------------------------------------------*/
223 void *
224 findSymWithLevel (bucket ** stab, symbol * sym)
225 {
226   bucket *bp;
227
228   bp = stab[hashKey (sym->name)];
229
230   /**
231    **  do the search from the head of the list since the
232    **  elements are added at the head it is ensured that
233    ** we will find the deeper definitions before we find
234    ** the global ones. we need to check for symbols with
235    ** level <= to the level given, if levels match then block
236    ** numbers need to match as well
237    **/
238   while (bp)
239     {
240       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
241         {
242           /* if this is parameter then nothing else need to be checked */
243           if (((symbol *) (bp->sym))->_isparm)
244             return (bp->sym);
245           /* if levels match then block numbers should also match */
246           if (bp->level && bp->level == sym->level && bp->block == sym->block)
247             return (bp->sym);
248           /* if levels don't match then we are okay */
249           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
250             return (bp->sym);
251           /* if this is a global variable then we are ok too */
252           if (bp->level == 0)
253             return (bp->sym);
254         }
255
256       bp = bp->next;
257     }
258
259   return (void *) NULL;
260 }
261
262 /*-----------------------------------------------------------------*/
263 /* findSymWithBlock - finds a symbol with name in with a block     */
264 /*-----------------------------------------------------------------*/
265 void *
266 findSymWithBlock (bucket ** stab, symbol * sym, int block)
267 {
268   bucket *bp;
269
270   bp = stab[hashKey (sym->name)];
271   while (bp)
272     {
273       if (strcmp (bp->name, sym->name) == 0 &&
274           bp->block <= block)
275         break;
276       bp = bp->next;
277     }
278
279   return (bp ? bp->sym : (void *) NULL);
280 }
281
282 /*------------------------------------------------------------------*/
283 /* newSymbol () - returns a new pointer to a symbol                 */
284 /*------------------------------------------------------------------*/
285 symbol *
286 newSymbol (char *name, int scope)
287 {
288   symbol *sym;
289
290   sym = Safe_alloc ( sizeof (symbol));
291
292   strncpyz (sym->name, name, sizeof(sym->name));        /* copy the name */
293   sym->level = scope;           /* set the level    */
294   sym->block = currBlockno;
295   sym->lineDef = mylineno;      /* set the line number */
296   sym->fileDef = currFname;
297   return sym;
298 }
299
300 /*------------------------------------------------------------------*/
301 /* newLink - creates a new link (declarator,specifier)              */
302 /*------------------------------------------------------------------*/
303 sym_link *
304 newLink (SYM_LINK_CLASS select)
305 {
306   sym_link *p;
307
308   p = Safe_alloc ( sizeof (sym_link));
309   p->class=select;
310
311   return p;
312 }
313
314 /*------------------------------------------------------------------*/
315 /* newStruct - creats a new structdef from the free list            */
316 /*------------------------------------------------------------------*/
317 structdef *
318 newStruct (char *tag)
319 {
320   structdef *s;
321
322   s = Safe_alloc ( sizeof (structdef));
323
324   strncpyz (s->tag, tag, sizeof(s->tag));               /* copy the tag */
325   return s;
326 }
327   
328 /*------------------------------------------------------------------*/
329 /* sclsFromPtr - Return the storage class a pointer points into.    */
330 /*               S_FIXED is returned for generic pointers or other  */
331 /*               unexpected cases                                   */
332 /*------------------------------------------------------------------*/
333 STORAGE_CLASS
334 sclsFromPtr(sym_link *ptr)
335 {
336   switch (DCL_TYPE (ptr))
337     {
338     case POINTER:
339       return S_DATA;
340     case GPOINTER:
341       return S_FIXED;
342     case FPOINTER:
343       return S_XDATA;
344     case CPOINTER:
345       return S_CODE;
346     case IPOINTER:
347       return S_IDATA;
348     case PPOINTER:
349       return S_PDATA;
350     case EEPPOINTER:
351       return S_EEPROM;
352     case FUNCTION:
353       return S_CODE;
354     default:
355       return S_FIXED;
356     }
357 }
358
359 /*------------------------------------------------------------------*/
360 /* pointerTypes - do the computation for the pointer types          */
361 /*------------------------------------------------------------------*/
362 void 
363 pointerTypes (sym_link * ptr, sym_link * type)
364 {
365   if (IS_SPEC (ptr))
366     return;
367
368   /* find the first pointer type */
369   while (ptr && !IS_PTR (ptr))
370     ptr = ptr->next;
371
372   /* could not find it */
373   if (!ptr || IS_SPEC (ptr))
374     return;
375   
376   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
377     pointerTypes (ptr->next, type);
378     return;
379   }
380
381   /* change the pointer type depending on the
382      storage class of the type */
383   if (IS_SPEC (type))
384     {
385       switch (SPEC_SCLS (type))
386         {
387         case S_XDATA:
388           DCL_TYPE (ptr) = FPOINTER;
389           break;
390         case S_IDATA:
391           DCL_TYPE (ptr) = IPOINTER;
392           break;
393         case S_PDATA:
394           DCL_TYPE (ptr) = PPOINTER;
395           break;
396         case S_DATA:
397           DCL_TYPE (ptr) = POINTER;
398           break;
399         case S_CODE:
400           DCL_TYPE (ptr) = CPOINTER;
401           break;
402         case S_EEPROM:
403           DCL_TYPE (ptr) = EEPPOINTER;
404           break;
405         default:
406           DCL_TYPE (ptr) = port->unqualified_pointer;
407           break;
408         }
409       /* the storage class of type ends here */
410       SPEC_SCLS (type) = 0;
411     }
412
413   /* now change all the remaining unknown pointers
414      to generic pointers */
415   while (ptr)
416     {
417       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
418         DCL_TYPE (ptr) = port->unqualified_pointer;
419       ptr = ptr->next;
420     }
421
422   /* same for the type although it is highly unlikely that
423      type will have a pointer */
424   while (type)
425     {
426       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
427         DCL_TYPE (type) = port->unqualified_pointer;
428       type = type->next;
429     }
430 }
431
432 /*------------------------------------------------------------------*/
433 /* addDecl - adds a declarator @ the end of a chain                 */
434 /*------------------------------------------------------------------*/
435 void 
436 addDecl (symbol * sym, int type, sym_link * p)
437 {
438   sym_link *head;
439   sym_link *tail;
440   sym_link *t;
441
442   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
443     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
444
445   /* if we are passed a link then set head & tail */
446   if (p)
447     {
448       tail = head = p;
449       while (tail->next)
450         tail = tail->next;
451     }
452   else
453     {
454       head = tail = newLink (DECLARATOR);
455       DCL_TYPE (head) = type;
456     }
457
458   /* if this is the first entry   */
459   if (!sym->type)
460     {
461       sym->type = head;
462       sym->etype = tail;
463     }
464   else
465     {
466       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
467         {
468           sym->etype = mergeSpec (sym->etype, head, sym->name);
469         }
470       else
471         {
472           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
473             {
474               t = sym->type;
475               while (t->next != sym->etype)
476                 t = t->next;
477               t->next = head;
478               tail->next = sym->etype;
479             }
480           else
481             {
482               sym->etype->next = head;
483               sym->etype = tail;
484             }
485         }
486     }
487
488   /* if the type is an unknown pointer and has
489      a tspec then take the storage class const & volatile
490      attribute from the tspec & make it those of this
491      symbol */
492   if (p &&
493       !IS_SPEC (p) &&
494       //DCL_TYPE (p) == UPOINTER &&
495       DCL_TSPEC (p))
496     {
497       if (!IS_SPEC (sym->etype))
498         {
499           sym->etype = sym->etype->next = newLink (SPECIFIER);
500         }
501       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
502       DCL_TSPEC (p) = NULL;
503     }
504
505   // if there is a function in this type chain
506   if (p && funcInChain(sym->type)) {
507     processFuncArgs (sym);
508   }
509
510   return;
511 }
512
513 /*------------------------------------------------------------------
514   checkTypeSanity: prevent the user from doing e.g.:
515   unsigned float uf;
516   ------------------------------------------------------------------*/
517 void checkTypeSanity(sym_link *etype, char *name) {
518   char *noun;
519
520   if (!etype) {
521     if (getenv("DEBUG_SANITY")) {
522       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
523     }
524     return;
525   }
526
527   if (!IS_SPEC(etype)) {
528     if (getenv("DEBUG_SANITY")) {
529       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
530     }
531     return;
532   }
533
534   noun=nounName(etype);
535
536   if (getenv("DEBUG_SANITY")) {
537     fprintf (stderr, "checking sanity for %s %p\n", name, etype);
538   }
539
540   if ((SPEC_NOUN(etype)==V_CHAR || 
541        SPEC_NOUN(etype)==V_FLOAT || 
542        SPEC_NOUN(etype)==V_DOUBLE || 
543        SPEC_NOUN(etype)==V_VOID) &&
544       (etype->select.s._short || SPEC_LONG(etype))) {
545     // long or short for char float double or void
546     werror (E_LONG_OR_SHORT_INVALID, noun, name);
547   }
548   if ((SPEC_NOUN(etype)==V_FLOAT || 
549        SPEC_NOUN(etype)==V_DOUBLE || 
550        SPEC_NOUN(etype)==V_VOID) && 
551       (etype->select.s._signed || SPEC_USIGN(etype))) {
552     // signed or unsigned for float double or void
553     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
554   }
555
556   // special case for "short"
557   if (etype->select.s._short) {
558     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
559     etype->select.s._short = 0;
560   }
561
562   /* if no noun e.g. 
563      "const a;" or "data b;" or "signed s" or "long l"
564      assume an int */
565   if (!SPEC_NOUN(etype)) {
566     SPEC_NOUN(etype)=V_INT;
567   }
568
569   if (etype->select.s._signed && SPEC_USIGN(etype)) {
570     // signed AND unsigned 
571     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
572   }
573   if (etype->select.s._short && SPEC_LONG(etype)) {
574     // short AND long
575     werror (E_LONG_AND_SHORT_INVALID, noun, name);
576   }
577
578 }
579
580 /*------------------------------------------------------------------*/
581 /* mergeSpec - merges two specifiers and returns the new one        */
582 /*------------------------------------------------------------------*/
583 sym_link *
584 mergeSpec (sym_link * dest, sym_link * src, char *name)
585 {
586   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
587 #if 0
588     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
589     exit (1);
590 #else
591     werror (E_SYNTAX_ERROR, yytext);
592     // the show must go on
593     return newIntLink();
594 #endif
595   }
596
597   if (SPEC_NOUN(src)) {
598     if (!SPEC_NOUN(dest)) {
599       SPEC_NOUN(dest)=SPEC_NOUN(src);
600     } else {
601       /* we shouldn't redeclare the type */
602       if (getenv("DEBUG_SANITY")) {
603         fprintf (stderr, "mergeSpec: ");
604       }
605       werror(E_TWO_OR_MORE_DATA_TYPES, name);
606     }
607   }
608   
609   if (SPEC_SCLS(src)) {
610     /* if destination has no storage class */
611     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
612       SPEC_SCLS (dest) = SPEC_SCLS (src);
613     } else {
614       if (getenv("DEBUG_SANITY")) {
615         fprintf (stderr, "mergeSpec: ");
616       }
617       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
618     }
619   }
620
621   /* copy all the specifications  */
622
623   // we really should do: 
624 #if 0
625   if (SPEC_what(src)) {
626     if (SPEC_what(dest)) {
627       werror(W_DUPLICATE_SPEC, "what");
628     }
629     SPEC_what(dst)|=SPEC_what(src);
630   }
631 #endif
632   // but there are more important thing right now
633
634   SPEC_LONG (dest) |= SPEC_LONG (src);
635   dest->select.s._short|=src->select.s._short;
636   SPEC_USIGN (dest) |= SPEC_USIGN (src);
637   dest->select.s._signed|=src->select.s._signed;
638   SPEC_STAT (dest) |= SPEC_STAT (src);
639   SPEC_EXTR (dest) |= SPEC_EXTR (src);
640   SPEC_CONST(dest) |= SPEC_CONST (src);
641   SPEC_ABSA (dest) |= SPEC_ABSA (src);
642   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
643   SPEC_ADDR (dest) |= SPEC_ADDR (src);
644   SPEC_OCLS (dest) = SPEC_OCLS (src);
645   SPEC_BLEN (dest) |= SPEC_BLEN (src);
646   SPEC_BSTR (dest) |= SPEC_BSTR (src);
647   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
648   SPEC_ENUM (dest) |= SPEC_ENUM (src);
649   if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
650       SPEC_ARGREG(dest) = SPEC_ARGREG(src);
651   
652   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
653     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
654
655   /* these are the only function attributes that will be set 
656      in a specifier while parsing */
657   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
658   FUNC_BANKED(dest) |= FUNC_BANKED(src);
659   FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
660   FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
661   FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
662   FUNC_ISISR(dest) |= FUNC_ISISR(src);
663   FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
664   FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
665   FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
666   FUNC_INTNO(dest) |= FUNC_INTNO(src);
667   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
668
669   return dest;
670 }
671
672 /*------------------------------------------------------------------*/
673 /* genSymName - generates and returns a name used for anonymous vars */
674 /*------------------------------------------------------------------*/
675 char *
676 genSymName (int level)
677 {
678   static int gCount = 0;
679   static char gname[SDCC_NAME_MAX + 1];
680
681   SNPRINTF (gname, sizeof(gname), "__%04d%04d", level, gCount++);
682   return gname;
683 }
684
685 /*------------------------------------------------------------------*/
686 /* getSpec - returns the specifier part from a declaration chain    */
687 /*------------------------------------------------------------------*/
688 sym_link *
689 getSpec (sym_link * p)
690 {
691   sym_link *loop;
692
693   loop = p;
694   while (p && !(IS_SPEC (p)))
695     p = p->next;
696
697   return p;
698 }
699
700 /*------------------------------------------------------------------*/
701 /* newCharLink() - creates an char type                             */
702 /*------------------------------------------------------------------*/
703 sym_link *
704 newCharLink ()
705 {
706   sym_link *p;
707
708   p = newLink (SPECIFIER);
709   SPEC_NOUN (p) = V_CHAR;
710
711   return p;
712 }
713
714 /*------------------------------------------------------------------*/
715 /* newFloatLink - a new Float type                                  */
716 /*------------------------------------------------------------------*/
717 sym_link *
718 newFloatLink ()
719 {
720   sym_link *p;
721
722   p = newLink (SPECIFIER);
723   SPEC_NOUN (p) = V_FLOAT;
724
725   return p;
726 }
727
728 /*------------------------------------------------------------------*/
729 /* newLongLink() - new long type                                    */
730 /*------------------------------------------------------------------*/
731 sym_link *
732 newLongLink ()
733 {
734   sym_link *p;
735
736   p = newLink (SPECIFIER);
737   SPEC_NOUN (p) = V_INT;
738   SPEC_LONG (p) = 1;
739
740   return p;
741 }
742
743 /*------------------------------------------------------------------*/
744 /* newIntLink() - creates an int type                               */
745 /*------------------------------------------------------------------*/
746 sym_link *
747 newIntLink ()
748 {
749   sym_link *p;
750
751   p = newLink (SPECIFIER);
752   SPEC_NOUN (p) = V_INT;
753
754   return p;
755 }
756
757 /*------------------------------------------------------------------*/
758 /* getSize - returns size of a type chain in bits                   */
759 /*------------------------------------------------------------------*/
760 unsigned int 
761 getSize (sym_link * p)
762 {
763   /* if nothing return 0 */
764   if (!p)
765     return 0;
766   if (IS_SPEC (p))
767     {                           /* if this is the specifier then */
768       switch (SPEC_NOUN (p))
769         {                       /* depending on the specifier type */
770         case V_INT:
771           return (IS_LONG (p) ? LONGSIZE : INTSIZE);
772         case V_FLOAT:
773           return FLOATSIZE;
774         case V_CHAR:
775           return CHARSIZE;
776         case V_VOID:
777           return 0;
778         case V_STRUCT:
779           return SPEC_STRUCT (p)->size;
780         case V_LABEL:
781           return 0;
782         case V_SBIT:
783         case V_BIT:
784           return BITSIZE;
785         case V_BITFIELD:
786           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
787         default:
788           return 0;
789         }
790     }
791
792   /* this is a specifier  */
793   switch (DCL_TYPE (p))
794     {
795     case ARRAY:
796       if (DCL_ELEM(p)) {
797         return DCL_ELEM (p) * getSize (p->next);
798       } else {
799           //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
800           //    "can not tell the size of an array[]");
801         return 0;
802       }
803     case IPOINTER:
804     case PPOINTER:
805     case POINTER:
806       return (PTRSIZE);
807     case EEPPOINTER:
808     case FPOINTER:
809     case CPOINTER:
810     case FUNCTION:
811       return (FPTRSIZE);
812     case GPOINTER:
813       return (GPTRSIZE);
814
815     default:
816       return 0;
817     }
818 }
819
820 /*------------------------------------------------------------------*/
821 /* bitsForType - returns # of bits required to store this type      */
822 /*------------------------------------------------------------------*/
823 unsigned int 
824 bitsForType (sym_link * p)
825 {
826   /* if nothing return 0 */
827   if (!p)
828     return 0;
829
830   if (IS_SPEC (p))
831     {                           /* if this is the specifier then */
832
833       switch (SPEC_NOUN (p))
834         {                       /* depending on the specifier type */
835         case V_INT:
836           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
837         case V_FLOAT:
838           return FLOATSIZE * 8;
839         case V_CHAR:
840           return CHARSIZE * 8;
841         case V_VOID:
842           return 0;
843         case V_STRUCT:
844           return SPEC_STRUCT (p)->size * 8;
845         case V_LABEL:
846           return 0;
847         case V_SBIT:
848         case V_BIT:
849           return 1;
850         case V_BITFIELD:
851           return SPEC_BLEN (p);
852         default:
853           return 0;
854         }
855     }
856
857   /* this is a specifier  */
858   switch (DCL_TYPE (p))
859     {
860     case ARRAY:
861       return DCL_ELEM (p) * getSize (p->next) * 8;
862     case IPOINTER:
863     case PPOINTER:
864     case POINTER:
865       return (PTRSIZE * 8);
866     case EEPPOINTER:
867     case FPOINTER:
868     case CPOINTER:
869     case FUNCTION:
870       return (FPTRSIZE * 8);
871     case GPOINTER:
872       return (GPTRSIZE * 8);
873
874     default:
875       return 0;
876     }
877 }
878
879 /*------------------------------------------------------------------*/
880 /* copySymbolChain - copies a symbol chain                          */
881 /*------------------------------------------------------------------*/
882 symbol *
883 copySymbolChain (symbol * src)
884 {
885   symbol *dest;
886
887   if (!src)
888     return NULL;
889
890   dest = copySymbol (src);
891   dest->next = copySymbolChain (src->next);
892   return dest;
893 }
894
895 /*------------------------------------------------------------------*/
896 /* copySymbol - makes a copy of a symbol                            */
897 /*------------------------------------------------------------------*/
898 symbol *
899 copySymbol (symbol * src)
900 {
901   symbol *dest;
902
903   if (!src)
904     return NULL;
905
906   dest = newSymbol (src->name, src->level);
907   memcpy (dest, src, sizeof (symbol));
908   dest->level = src->level;
909   dest->block = src->block;
910   dest->ival = copyIlist (src->ival);
911   dest->type = copyLinkChain (src->type);
912   dest->etype = getSpec (dest->type);
913   dest->next = NULL;
914   dest->key = src->key;
915   dest->allocreq = src->allocreq;
916   return dest;
917 }
918
919 /*------------------------------------------------------------------*/
920 /* reverseSyms - reverses the links for a symbol chain      */
921 /*------------------------------------------------------------------*/
922 symbol *
923 reverseSyms (symbol * sym)
924 {
925   symbol *prev, *curr, *next;
926
927   if (!sym)
928     return NULL;
929
930   prev = sym;
931   curr = sym->next;
932
933   while (curr)
934     {
935       next = curr->next;
936       curr->next = prev;
937       prev = curr;
938       curr = next;
939     }
940   sym->next = (void *) NULL;
941   return prev;
942 }
943
944 /*------------------------------------------------------------------*/
945 /* reverseLink - reverses the links for a type chain        */
946 /*------------------------------------------------------------------*/
947 sym_link *
948 reverseLink (sym_link * type)
949 {
950   sym_link *prev, *curr, *next;
951
952   if (!type)
953     return NULL;
954
955   prev = type;
956   curr = type->next;
957
958   while (curr)
959     {
960       next = curr->next;
961       curr->next = prev;
962       prev = curr;
963       curr = next;
964     }
965   type->next = (void *) NULL;
966   return prev;
967 }
968
969 /*------------------------------------------------------------------*/
970 /* addSymChain - adds a symbol chain to the symboltable             */
971 /*------------------------------------------------------------------*/
972 void 
973 addSymChain (symbol * symHead)
974 {
975   symbol *sym = symHead;
976   symbol *csym = NULL;
977   int error = 0;
978
979   for (; sym != NULL; sym = sym->next)
980     {
981       changePointer(sym);
982       checkTypeSanity(sym->etype, sym->name);
983
984       if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype)))
985         checkDecl (sym, 0);
986       
987       /* if already exists in the symbol table then check if
988          one of them is an extern definition if yes then
989          then check if the type match, if the types match then
990          delete the current entry and add the new entry      */
991       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
992           csym->level == sym->level) {
993
994         /* If the previous definition was for an array with incomplete */
995         /* type, and the new definition has completed the type, update */
996         /* the original type to match */
997         if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
998             && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
999           {
1000             if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
1001               DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
1002           }
1003
1004         #if 0
1005         /* If only one of the definitions used the "at" keyword, copy */
1006         /* the address to the other. */
1007         if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
1008             && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
1009           {
1010             SPEC_ABSA (sym->etype) = 1;
1011             SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1012           }
1013         if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
1014             && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
1015           {
1016             SPEC_ABSA (csym->etype) = 1;
1017             SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1018           }
1019         #endif
1020   
1021         error = 0;        
1022         if (csym->ival && sym->ival)
1023           error = 1;
1024         if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1025           error = 1;
1026         
1027         if (error) {
1028           /* one definition extern ? */
1029           if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1030             werror (E_EXTERN_MISMATCH, sym->name);
1031           else
1032             werror (E_DUPLICATE, sym->name);
1033           fprintf (stderr, "from type '");
1034           printTypeChain (csym->type, stderr);
1035           if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1036             fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1037           fprintf (stderr, "'\nto type '");
1038           printTypeChain (sym->type, stderr);
1039           if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1040             fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1041           fprintf (stderr, "'\n");
1042           continue;
1043         }
1044
1045         if (csym->ival && !sym->ival)
1046           sym->ival = csym->ival;
1047
1048         /* delete current entry */
1049         deleteSym (SymbolTab, csym, csym->name);
1050         deleteFromSeg(csym);
1051       }
1052       
1053       /* add new entry */
1054       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1055     }
1056 }
1057
1058
1059 /*------------------------------------------------------------------*/
1060 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1061 /*------------------------------------------------------------------*/
1062 int 
1063 funcInChain (sym_link * lnk)
1064 {
1065   while (lnk)
1066     {
1067       if (IS_FUNC (lnk))
1068         return 1;
1069       lnk = lnk->next;
1070     }
1071   return 0;
1072 }
1073
1074 /*------------------------------------------------------------------*/
1075 /* structElemType - returns the type info of a struct member        */
1076 /*------------------------------------------------------------------*/
1077 sym_link *
1078 structElemType (sym_link * stype, value * id)
1079 {
1080   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1081   sym_link *type, *etype;
1082   sym_link *petype = getSpec (stype);
1083
1084   if (fields && id) {
1085     
1086     /* look for the id */
1087     while (fields)
1088       {
1089         if (strcmp (fields->rname, id->name) == 0)
1090           {
1091             type = copyLinkChain (fields->type);
1092             etype = getSpec (type);
1093             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1094                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
1095             if (IS_SPEC (type))
1096               SPEC_CONST (type) |= SPEC_CONST (stype);
1097             else
1098               DCL_PTR_CONST (type) |= SPEC_CONST (stype);
1099             return type;
1100           }
1101         fields = fields->next;
1102       }
1103   }
1104
1105   werror (E_NOT_MEMBER, id->name);
1106     
1107   // the show must go on
1108   return newIntLink();
1109 }
1110
1111 /*------------------------------------------------------------------*/
1112 /* getStructElement - returns element of a tructure definition      */
1113 /*------------------------------------------------------------------*/
1114 symbol *
1115 getStructElement (structdef * sdef, symbol * sym)
1116 {
1117   symbol *field;
1118
1119   for (field = sdef->fields; field; field = field->next)
1120     if (strcmp (field->name, sym->name) == 0)
1121       return field;
1122
1123   werror (E_NOT_MEMBER, sym->name);
1124
1125   return sdef->fields;
1126 }
1127
1128 /*------------------------------------------------------------------*/
1129 /* compStructSize - computes the size of a structure                */
1130 /*------------------------------------------------------------------*/
1131 int 
1132 compStructSize (int su, structdef * sdef)
1133 {
1134     int sum = 0, usum = 0;
1135     int bitOffset = 0;
1136     symbol *loop;
1137
1138     /* for the identifiers  */
1139     loop = sdef->fields;
1140     while (loop) {
1141
1142         /* create the internal name for this variable */
1143         SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1144         if (su == UNION) {
1145             sum = 0;
1146             bitOffset = 0;
1147         }
1148         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1149
1150         /* if this is a bit field  */
1151         if (loop->bitVar) {
1152
1153             /* change it to a unsigned bit */
1154             SPEC_NOUN (loop->etype) = V_BITFIELD;
1155             SPEC_USIGN (loop->etype) = 1;
1156             SPEC_BLEN (loop->etype) = loop->bitVar;
1157
1158             if (loop->bitVar == BITVAR_PAD) {
1159                 /* A zero length bitfield forces padding */
1160                 SPEC_BSTR (loop->etype) = bitOffset;
1161                 SPEC_BLEN (loop->etype) = 0;
1162                 bitOffset = 8;
1163                 loop->offset = sum;
1164             }
1165             else {
1166                 if (bitOffset == 8) {
1167                     bitOffset = 0;
1168                     sum++;
1169                 }
1170                 /* check if this fit into the remaining   */
1171                 /* bits of this byte else align it to the */
1172                 /* next byte boundary                     */
1173                 if (loop->bitVar <= (8 - bitOffset)) {
1174                     /* fits into current byte */
1175                     loop->offset = sum;
1176                     SPEC_BSTR (loop->etype) = bitOffset;
1177                     bitOffset += loop->bitVar;
1178                 }
1179                 else if (!bitOffset) {
1180                     /* does not fit, but is already byte aligned */
1181                     loop->offset = sum;
1182                     SPEC_BSTR (loop->etype) = bitOffset;
1183                     bitOffset += loop->bitVar;
1184                 } 
1185                 else {
1186                     /* does not fit; need to realign first */
1187                     sum++;
1188                     loop->offset = (su == UNION ? sum = 0 : sum);
1189                     bitOffset = 0;
1190                     SPEC_BSTR (loop->etype) = bitOffset;
1191                     bitOffset += loop->bitVar;
1192                 }
1193                 while (bitOffset>8) {
1194                     bitOffset -= 8;
1195                     sum++;
1196                 } 
1197             }
1198         }
1199         else {
1200             /* This is a non-bit field. Make sure we are */
1201             /* byte aligned first */
1202             if (bitOffset) {
1203                 sum++;
1204                 loop->offset = (su == UNION ? sum = 0 : sum);
1205                 bitOffset = 0;
1206             }
1207             loop->offset = sum;
1208             checkDecl (loop, 1);
1209             sum += getSize (loop->type);
1210         }
1211
1212         loop = loop->next;
1213
1214         /* if union then size = sizeof larget field */
1215         if (su == UNION) {
1216             /* For UNION, round up after each field */
1217             sum += ((bitOffset+7)/8);
1218             usum = max (usum, sum);
1219         }
1220
1221     }
1222     
1223     /* For STRUCT, round up after all fields processed */
1224     if (su != UNION)
1225         sum += ((bitOffset+7)/8);
1226
1227     return (su == UNION ? usum : sum);
1228 }
1229
1230 /*------------------------------------------------------------------*/
1231 /* checkSClass - check the storage class specification              */
1232 /*------------------------------------------------------------------*/
1233 static void 
1234 checkSClass (symbol * sym, int isProto)
1235 {
1236   sym_link *t;
1237   
1238   if (getenv("DEBUG_SANITY")) {
1239     fprintf (stderr, "checkSClass: %s \n", sym->name);
1240   }
1241   
1242   /* type is literal can happen for enums change
1243      to auto */
1244   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1245     SPEC_SCLS (sym->etype) = S_AUTO;
1246   
1247   /* if sfr or sbit then must also be volatile */
1248   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1249       SPEC_SCLS (sym->etype) == S_SFR)
1250     {
1251       SPEC_VOLATILE (sym->etype) = 1;
1252     }
1253   
1254   /* if absolute address given then it mark it as
1255      volatile -- except in the PIC port */
1256
1257 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1258   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1259   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1260 #endif
1261
1262     if (IS_ABSOLUTE (sym->etype))
1263       SPEC_VOLATILE (sym->etype) = 1;
1264   
1265   /* If code memory is read only, then pointers to code memory */
1266   /* implicitly point to constants -- make this explicit       */
1267   t = sym->type;
1268   while (t && t->next) {
1269     if (IS_CODEPTR(t) && port->mem.code_ro) {
1270       if (IS_SPEC(t->next)) {
1271         SPEC_CONST (t->next) = 1;
1272       } else {
1273         DCL_PTR_CONST (t->next) = 1;
1274       }
1275     }
1276     t = t->next;
1277   }
1278
1279   /* global variables declared const put into code */
1280   /* if no other storage class specified */
1281   if (sym->level == 0 &&
1282       SPEC_SCLS(sym->etype) == S_FIXED &&
1283       !IS_FUNC(sym->type)) {
1284     /* find the first non-array link */
1285     t = sym->type;
1286     while (IS_ARRAY(t))
1287       t = t->next;
1288     if (IS_CONSTANT (t)) {
1289       SPEC_SCLS (sym->etype) = S_CODE;
1290     }
1291   }
1292
1293   /* global variable in code space is a constant */
1294   if (sym->level == 0 &&
1295       SPEC_SCLS (sym->etype) == S_CODE &&
1296       port->mem.code_ro) {
1297     /* find the first non-array link */
1298     t = sym->type;
1299     while (IS_ARRAY(t))
1300       t = t->next;
1301     if (IS_SPEC(t)) {
1302       SPEC_CONST (t) = 1;
1303     } else {
1304       DCL_PTR_CONST (t) = 1;
1305     }
1306   }
1307
1308   /* if bit variable then no storage class can be */
1309   /* specified since bit is already a storage */
1310   if (IS_BITVAR (sym->etype) &&
1311       (SPEC_SCLS (sym->etype) != S_FIXED &&
1312        SPEC_SCLS (sym->etype) != S_SBIT &&
1313        SPEC_SCLS (sym->etype) != S_BIT)
1314     )
1315     {
1316       werror (E_BITVAR_STORAGE, sym->name);
1317       SPEC_SCLS (sym->etype) = S_FIXED;
1318     }
1319
1320   /* extern variables cannot be initialized */
1321   if (IS_EXTERN (sym->etype) && sym->ival)
1322     {
1323       werror (E_EXTERN_INIT, sym->name);
1324       sym->ival = NULL;
1325     }
1326
1327   /* if this is an automatic symbol */
1328   if (sym->level && (options.stackAuto || reentrant)) {
1329     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1330          SPEC_SCLS (sym->etype) == S_FIXED ||
1331          SPEC_SCLS (sym->etype) == S_REGISTER ||
1332          SPEC_SCLS (sym->etype) == S_STACK ||
1333          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1334       SPEC_SCLS (sym->etype) = S_AUTO;
1335     } else {
1336       /* storage class may only be specified for statics */
1337       if (!IS_STATIC(sym->etype)) {
1338         werror (E_AUTO_ASSUMED, sym->name);
1339       }
1340     }
1341   }
1342
1343   /* automatic symbols cannot be given   */
1344   /* an absolute address ignore it      */
1345   if (sym->level &&
1346       SPEC_ABSA (sym->etype) &&
1347       (options.stackAuto || reentrant))
1348     {
1349       werror (E_AUTO_ABSA, sym->name);
1350       SPEC_ABSA (sym->etype) = 0;
1351     }
1352
1353   /* arrays & pointers cannot be defined for bits   */
1354   /* SBITS or SFRs or BIT                           */
1355   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1356       (SPEC_NOUN (sym->etype) == V_BIT ||
1357        SPEC_NOUN (sym->etype) == V_SBIT ||
1358        SPEC_NOUN (sym->etype) == V_BITFIELD ||
1359        SPEC_SCLS (sym->etype) == S_SFR))
1360     werror (E_BIT_ARRAY, sym->name);
1361
1362   /* if this is a bit|sbit then set length & start  */
1363   if (SPEC_NOUN (sym->etype) == V_BIT ||
1364       SPEC_NOUN (sym->etype) == V_SBIT)
1365     {
1366       SPEC_BLEN (sym->etype) = 1;
1367       SPEC_BSTR (sym->etype) = 0;
1368     }
1369
1370   if (!isProto) {
1371     /* variables declared in CODE space must have */
1372     /* initializers if not an extern */
1373     if (SPEC_SCLS (sym->etype) == S_CODE &&
1374         sym->ival == NULL &&
1375         //!sym->level &&
1376         port->mem.code_ro &&
1377         !IS_EXTERN (sym->etype) &&
1378         !funcInChain (sym->type))
1379       werror (E_CODE_NO_INIT, sym->name);
1380   }
1381
1382   /* if parameter or local variable then change */
1383   /* the storage class to reflect where the var will go */
1384   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1385       !IS_STATIC(sym->etype))
1386     {
1387       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1388         {
1389           SPEC_SCLS (sym->etype) = (options.useXstack ?
1390                                     S_XSTACK : S_STACK);
1391         }
1392       else
1393         {
1394           /* hack-o-matic! I see no reason why the useXstack option should ever
1395            * control this allcoation, but the code was originally that way, and
1396            * changing it for non-390 ports breaks the compiler badly.
1397            */
1398           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1399                 1 : options.useXstack;
1400           SPEC_SCLS (sym->etype) = (useXdata ?
1401                                     S_XDATA : S_FIXED);
1402         }
1403     }
1404 }
1405
1406 /*------------------------------------------------------------------*/
1407 /* changePointer - change pointer to functions                      */
1408 /*------------------------------------------------------------------*/
1409 void 
1410 changePointer (symbol * sym)
1411 {
1412   sym_link *p;
1413
1414   /* go thru the chain of declarations   */
1415   /* if we find a pointer to a function  */
1416   /* unconditionally change it to a ptr  */
1417   /* to code area                        */
1418   for (p = sym->type; p; p = p->next)
1419     {
1420       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1421         DCL_TYPE (p) = port->unqualified_pointer;
1422       if (IS_PTR (p) && IS_FUNC (p->next))
1423         DCL_TYPE (p) = CPOINTER;
1424     }
1425 }
1426
1427 /*------------------------------------------------------------------*/
1428 /* checkDecl - does semantic validation of a declaration                   */
1429 /*------------------------------------------------------------------*/
1430 int 
1431 checkDecl (symbol * sym, int isProto)
1432 {
1433
1434   checkSClass (sym, isProto);           /* check the storage class      */
1435   changePointer (sym);          /* change pointers if required */
1436
1437   /* if this is an array without any dimension
1438      then update the dimension from the initial value */
1439   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1440     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1441
1442   return 0;
1443 }
1444
1445 /*------------------------------------------------------------------*/
1446 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1447 /*------------------------------------------------------------------*/
1448 sym_link *
1449 copyLinkChain (sym_link * p)
1450 {
1451   sym_link *head, *curr, *loop;
1452
1453   curr = p;
1454   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1455   while (curr)
1456     {
1457       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1458       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1459       loop = loop->next;
1460       curr = curr->next;
1461     }
1462
1463   return head;
1464 }
1465
1466
1467 /*------------------------------------------------------------------*/
1468 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1469 /*                symbols in the given block                        */
1470 /*------------------------------------------------------------------*/
1471 void 
1472 cleanUpBlock (bucket ** table, int block)
1473 {
1474   int i;
1475   bucket *chain;
1476
1477   /* go thru the entire  table  */
1478   for (i = 0; i < 256; i++)
1479     {
1480       for (chain = table[i]; chain; chain = chain->next)
1481         {
1482           if (chain->block >= block)
1483             {
1484               deleteSym (table, chain->sym, chain->name);
1485             }
1486         }
1487     }
1488 }
1489
1490 /*------------------------------------------------------------------*/
1491 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1492 /*                symbols in the given level                        */
1493 /*------------------------------------------------------------------*/
1494 void 
1495 cleanUpLevel (bucket ** table, int level)
1496 {
1497   int i;
1498   bucket *chain;
1499
1500   /* go thru the entire  table  */
1501   for (i = 0; i < 256; i++)
1502     {
1503       for (chain = table[i]; chain; chain = chain->next)
1504         {
1505           if (chain->level >= level)
1506             {
1507               deleteSym (table, chain->sym, chain->name);
1508             }
1509         }
1510     }
1511 }
1512
1513 /*------------------------------------------------------------------*/
1514 /* computeType - computes the resultant type from two types         */
1515 /*------------------------------------------------------------------*/
1516 sym_link *
1517 computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
1518 {
1519   sym_link *rType;
1520   sym_link *reType;
1521   sym_link *etype1 = getSpec (type1);
1522   sym_link *etype2;
1523    
1524   etype2 = type2 ? getSpec (type2) : type1;
1525
1526   /* if one of them is a float then result is a float */
1527   /* here we assume that the types passed are okay */
1528   /* and can be cast to one another                */
1529   /* which ever is greater in size */
1530   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1531     rType = newFloatLink ();
1532   else
1533     /* if only one of them is a bit variable
1534        then the other one prevails */
1535   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1536     rType = copyLinkChain (type2);
1537   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1538     rType = copyLinkChain (type1);
1539   else
1540     /* if one of them is a pointer or array then that
1541        prevails */
1542   if (IS_PTR (type1) || IS_ARRAY (type1))
1543     rType = copyLinkChain (type1);
1544   else if (IS_PTR (type2) || IS_ARRAY (type2))
1545     rType = copyLinkChain (type2);
1546   else if (getSize (type1) > getSize (type2))
1547     rType = copyLinkChain (type1);
1548   else
1549     rType = copyLinkChain (type2);
1550
1551   reType = getSpec (rType);
1552
1553   /* avoid conflicting types */
1554   reType->select.s._signed = 0;
1555
1556   if (IS_CHAR (reType) && promoteCharToInt)
1557     SPEC_NOUN (reType) = V_INT;
1558
1559   /* SDCC's sign promotion:
1560      - if one or both operands are unsigned, the resultant type will be unsigned
1561        (except char, see below)
1562      - if an operand is promoted to a larger type (char -> int, int -> long),
1563        the larger type will be signed
1564
1565      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1566      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1567      the standard. The standard demands, that the result has to be the same
1568      "as if" the promotion would have been performed:
1569
1570      - if the result of an operation with two char's is promoted to a
1571        larger type, the result will be signed.
1572
1573      More sophisticated is the last one:
1574      - if the result of an operation with two char's is a char again,
1575        the result will only then be unsigned, if both operands are
1576        unsigned. In all other cases the result will be signed.
1577
1578        This seems to be contradictionary to the first two rules, but it makes
1579        real sense (all types are char's):
1580
1581         A signed char can be negative; this must be preserved in the result
1582                 -1 * 100 = -100;
1583
1584         Only if both operands are unsigned it's safe to make the result
1585         unsigned; this helps to avoid overflow:
1586                 2 * 100 =  200;
1587
1588      Homework: - why is (200 * 200 < 0) true?
1589                - why is { char l = 200, r = 200; (r * l > 0) } true?
1590   */
1591
1592   if (!IS_FLOAT (reType)
1593       && (   (SPEC_USIGN (etype1)
1594               /* if this operand is promoted to a larger type,
1595                  then it will be promoted to a signed type */
1596               && !(getSize (etype1) < getSize (reType))
1597               /* char require special handling */
1598               && !IS_CHAR (etype1))
1599           || /* same for 2nd operand */  
1600              (SPEC_USIGN (etype2)
1601               && !(getSize (etype2) < getSize (reType))
1602               && !IS_CHAR (etype2))
1603           || /* if both are 'unsigned char' and not promoted
1604                 let the result be unsigned too */
1605              (   SPEC_USIGN (etype1)
1606               && SPEC_USIGN (etype2)
1607               && IS_CHAR (etype1)
1608               && IS_CHAR (etype2)
1609               && IS_CHAR (reType))))
1610     SPEC_USIGN (reType) = 1;
1611   else
1612     SPEC_USIGN (reType) = 0;
1613
1614   /* if result is a literal then make not so */
1615   if (IS_LITERAL (reType))
1616     SPEC_SCLS (reType) = S_REGISTER;
1617
1618   return rType;
1619 }
1620
1621 /*--------------------------------------------------------------------*/
1622 /* compareType - will do type check return 1 if match, -1 if castable */
1623 /*--------------------------------------------------------------------*/
1624 int
1625 compareType (sym_link * dest, sym_link * src)
1626 {
1627   if (!dest && !src)
1628     return 1;
1629
1630   if (dest && !src)
1631     return 0;
1632
1633   if (src && !dest)
1634     return 0;
1635
1636   /* if dest is a declarator then */
1637   if (IS_DECL (dest))
1638     {
1639       if (IS_DECL (src))
1640         {
1641           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1642             if (IS_FUNC(src)) {
1643               //checkFunction(src,dest);
1644             }
1645             return compareType (dest->next, src->next);
1646           }
1647           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1648             return 1;
1649           }
1650           if (IS_PTR (src) && IS_GENPTR (dest))
1651             return -1;
1652           if (IS_PTR (dest) && IS_ARRAY (src)) {
1653             value *val=aggregateToPointer (valFromType(src));
1654             int res=compareType (dest, val->type);
1655             Safe_free(val->type);
1656             Safe_free(val);
1657             return res;
1658           }
1659           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1660             return compareType (dest->next, src);
1661           return 0;
1662         }
1663       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1664         return -1;
1665       else
1666         return 0;
1667     }
1668
1669   /* if one is a specifier and the other is not */
1670   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1671       (IS_SPEC (dest) && !IS_SPEC (src)))
1672     return 0;
1673
1674   /* if one of them is a void then ok */
1675   if (SPEC_NOUN (dest) == V_VOID &&
1676       SPEC_NOUN (src) != V_VOID)
1677     return -1;
1678
1679   if (SPEC_NOUN (dest) != V_VOID &&
1680       SPEC_NOUN (src) == V_VOID)
1681     return -1;
1682
1683   /* if they are both bitfields then if the lengths
1684      and starts don't match */
1685   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1686       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1687        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1688     return -1;
1689
1690   /* it is a specifier */
1691   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1692     {
1693       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1694           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1695           getSize (dest) == getSize (src))
1696         return 1;
1697       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1698         return -1;
1699       else
1700         return 0;
1701     }
1702   else if (IS_STRUCT (dest))
1703     {
1704       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1705         return 0;
1706       else
1707         return 1;
1708     }
1709   if (SPEC_LONG (dest) != SPEC_LONG (src))
1710     return -1;
1711
1712   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1713     return -1;
1714
1715   return 1;
1716 }
1717
1718 /*--------------------------------------------------------------------*/
1719 /* compareTypeExact - will do type check return 1 if match exactly    */
1720 /*--------------------------------------------------------------------*/
1721 int
1722 compareTypeExact (sym_link * dest, sym_link * src, int level)
1723 {
1724   STORAGE_CLASS srcScls, destScls;
1725   
1726   if (!dest && !src)
1727     return 1;
1728
1729   if (dest && !src)
1730     return 0;
1731
1732   if (src && !dest)
1733     return 0;
1734
1735   /* if dest is a declarator then */
1736   if (IS_DECL (dest))
1737     {
1738       if (IS_DECL (src))
1739         {
1740           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1741             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
1742               return 0;
1743             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
1744               return 0;
1745             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
1746               return 0;
1747             if (IS_FUNC(src))
1748               {
1749                 value *exargs, *acargs, *checkValue;
1750
1751                 /* verify function return type */
1752                 if (!compareTypeExact (dest->next, src->next, -1))
1753                   return 0;
1754                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
1755                   return 0;
1756                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
1757                   return 0;
1758                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
1759                   return 0;
1760                 #if 0
1761                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
1762                   return 0;
1763                 #endif
1764
1765                 /* compare expected args with actual args */
1766                 exargs = FUNC_ARGS(dest);
1767                 acargs = FUNC_ARGS(src);
1768
1769                 /* for all the expected args do */
1770                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
1771                   {
1772                     //checkTypeSanity(acargs->etype, acargs->name);
1773
1774                     if (IS_AGGREGATE (acargs->type))
1775                       {
1776                         checkValue = copyValue (acargs);
1777                         aggregateToPointer (checkValue);
1778                       }
1779                     else
1780                       checkValue = acargs;
1781
1782                     #if 0
1783                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
1784                       return 0;
1785                     #endif
1786                   }
1787
1788                   /* if one them ended we have a problem */
1789                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1790                       (!exargs && acargs && !IS_VOID (acargs->type)))
1791                     return 0;                  
1792                   return 1;
1793               }
1794             return compareTypeExact (dest->next, src->next, level);
1795           }
1796           return 0;
1797         }
1798       return 0;
1799     }
1800
1801   /* if one is a specifier and the other is not */
1802   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1803       (IS_SPEC (dest) && !IS_SPEC (src)))
1804     return 0;
1805
1806   /* if one of them is a void then ok */
1807   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1808     return 0;
1809
1810   /* if they are both bitfields then if the lengths
1811      and starts don't match */
1812   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1813       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1814        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1815     return 0;
1816
1817   if (IS_INTEGRAL (dest))
1818     {
1819       /* signedness must match */
1820       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1821         return 0;
1822       /* size must match */
1823       if (SPEC_LONG (dest) != SPEC_LONG (src))
1824         return 0;
1825       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1826         return 0;
1827     }
1828   
1829   if (IS_STRUCT (dest))
1830     {
1831       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1832         return 0;
1833     }
1834
1835   if (SPEC_CONST (dest) != SPEC_CONST (src))
1836     return 0;
1837   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
1838     return 0;
1839   if (SPEC_STAT (dest) != SPEC_STAT (src))
1840     return 0;
1841   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
1842     return 0;
1843   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
1844     return 0;
1845       
1846   destScls = SPEC_SCLS (dest);
1847   srcScls = SPEC_SCLS (src);
1848   
1849   /* Compensate for const to const code change in checkSClass() */
1850   if (!level & port->mem.code_ro && SPEC_CONST (dest))
1851     {
1852       if (srcScls == S_CODE && destScls == S_FIXED)
1853         destScls = S_CODE;
1854       if (destScls == S_CODE && srcScls == S_FIXED)
1855         srcScls = S_CODE;
1856     }
1857
1858   /* compensate for allocGlobal() */  
1859   if ((srcScls == S_FIXED || srcScls == S_AUTO)
1860       && port->mem.default_globl_map == xdata
1861       && !level)
1862     srcScls = S_XDATA;
1863   
1864   if (level>0 && !SPEC_STAT (dest))
1865     {
1866       /* Compensate for hack-o-matic in checkSClass() */
1867       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1868         {
1869           if (destScls == S_FIXED)
1870             destScls = (options.useXstack ? S_XSTACK : S_STACK);
1871           if (srcScls == S_FIXED)
1872             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
1873         }
1874       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
1875         {
1876           if (destScls == S_FIXED)
1877             destScls = S_XDATA;
1878           if (srcScls == S_FIXED)
1879             srcScls = S_XDATA;
1880         }
1881     }
1882
1883   if (srcScls != destScls)
1884     {
1885       #if 0
1886       printf ("level = %d\n", level);
1887       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
1888                 SPEC_SCLS (src), SPEC_SCLS (dest));
1889       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
1890       #endif
1891       return 0;
1892     }
1893   
1894   return 1;
1895 }
1896
1897 /*------------------------------------------------------------------*/
1898 /* inCalleeSaveList - return 1 if found in callee save list          */
1899 /*------------------------------------------------------------------*/
1900 static int
1901 calleeCmp(void *p1, void *p2)
1902 {
1903   return (strcmp((char *)p1, (char *)(p2)) == 0);
1904 }
1905
1906 bool
1907 inCalleeSaveList(char *s)
1908 {
1909   if (options.all_callee_saves)
1910     return 1;
1911   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
1912 }
1913
1914 /*-----------------------------------------------------------------*/
1915 /* aggregateToPointer:  change an agggregate type function      */
1916 /*         argument to a pointer to that type.     */
1917 /*-----------------------------------------------------------------*/
1918 value *
1919 aggregateToPointer (value * val)
1920 {
1921   if (IS_AGGREGATE (val->type))
1922     {
1923       /* if this is a structure */
1924       /* then we need to add a new link */
1925       if (IS_STRUCT (val->type))
1926         {
1927           /* first lets add DECLARATOR type */
1928           sym_link *p = val->type;
1929
1930           werror (W_STRUCT_AS_ARG, val->name);
1931           val->type = newLink (DECLARATOR);
1932           val->type->next = p;
1933         }
1934
1935       /* change to a pointer depending on the */
1936       /* storage class specified        */
1937       switch (SPEC_SCLS (val->etype))
1938         {
1939         case S_IDATA:
1940           DCL_TYPE (val->type) = IPOINTER;
1941           break;
1942         case S_PDATA:
1943           DCL_TYPE (val->type) = PPOINTER;
1944           break;
1945         case S_FIXED:
1946           if (SPEC_OCLS(val->etype)) {
1947             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1948           } else {
1949             // this happens for (external) function parameters
1950             DCL_TYPE (val->type) = port->unqualified_pointer;
1951           }
1952           break;
1953         case S_AUTO:
1954         case S_DATA:
1955         case S_REGISTER:
1956           DCL_TYPE (val->type) = POINTER;
1957           break;
1958         case S_CODE:
1959           DCL_TYPE (val->type) = CPOINTER;
1960           break;
1961         case S_XDATA:
1962           DCL_TYPE (val->type) = FPOINTER;
1963           break;
1964         case S_EEPROM:
1965           DCL_TYPE (val->type) = EEPPOINTER;
1966           break;
1967         default:
1968           DCL_TYPE (val->type) = port->unqualified_pointer;
1969         }
1970       
1971       /* is there is a symbol associated then */
1972       /* change the type of the symbol as well */
1973       if (val->sym)
1974         {
1975           val->sym->type = copyLinkChain (val->type);
1976           val->sym->etype = getSpec (val->sym->type);
1977         }
1978     }
1979   return val;
1980 }
1981 /*------------------------------------------------------------------*/
1982 /* checkFunction - does all kinds of check on a function            */
1983 /*------------------------------------------------------------------*/
1984 int 
1985 checkFunction (symbol * sym, symbol *csym)
1986 {
1987   value *exargs, *acargs;
1988   value *checkValue;
1989   int argCnt = 0;
1990
1991   if (getenv("DEBUG_SANITY")) {
1992     fprintf (stderr, "checkFunction: %s ", sym->name);
1993   }
1994
1995   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
1996     {
1997       werror(E_SYNTAX_ERROR, sym->name);
1998       return 0;
1999     }
2000     
2001   /* make sure the type is complete and sane */
2002   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2003
2004   /* if not type then some kind of error */
2005   if (!sym->type)
2006     return 0;
2007
2008   /* if the function has no type then make it return int */
2009   if (!sym->type->next)
2010     sym->type->next = sym->etype = newIntLink ();
2011
2012   /* function cannot return aggregate */
2013   if (IS_AGGREGATE (sym->type->next))
2014     {
2015       werror (E_FUNC_AGGR, sym->name);
2016       return 0;
2017     }
2018
2019   /* function cannot return bit */
2020   if (IS_BITVAR (sym->type->next))
2021     {
2022       werror (E_FUNC_BIT, sym->name);
2023       return 0;
2024     }
2025
2026   /* check if this function is defined as calleeSaves
2027      then mark it as such */
2028   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2029
2030   /* if interrupt service routine  */
2031   /* then it cannot have arguments */
2032   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2033     {
2034       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2035         werror (E_INT_ARGS, sym->name);
2036         FUNC_ARGS(sym->type)=NULL;
2037       }
2038     }
2039
2040   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
2041        acargs; 
2042        acargs=acargs->next, argCnt++) {
2043     if (!acargs->sym) { 
2044       // this can happen for reentrant functions
2045       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2046       // the show must go on: synthesize a name and symbol
2047       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2048       acargs->sym = newSymbol (acargs->name, 1);
2049       SPEC_OCLS (acargs->etype) = istack;
2050       acargs->sym->type = copyLinkChain (acargs->type);
2051       acargs->sym->etype = getSpec (acargs->sym->type);
2052       acargs->sym->_isparm = 1;
2053       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2054     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2055       // synthesized name
2056       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2057     }
2058   }
2059   argCnt--;
2060
2061   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2062     return 1;                   /* not defined nothing more to check  */
2063
2064   /* check if body already present */
2065   if (csym && IFFUNC_HASBODY(csym->type))
2066     {
2067       werror (E_FUNC_BODY, sym->name);
2068       return 0;
2069     }
2070
2071   /* check the return value type   */
2072   if (compareType (csym->type, sym->type) <= 0)
2073     {
2074       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2075       printFromToType(csym->type, sym->type);
2076       return 0;
2077     }
2078
2079   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2080     {
2081       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2082     }
2083
2084   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
2085     {
2086       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2087     }
2088
2089   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2090     {
2091       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2092     }
2093   
2094   /* Really, reentrant should match regardless of argCnt, but     */
2095   /* this breaks some existing code (the fp lib functions). If    */
2096   /* the first argument is always passed the same way, this       */
2097   /* lax checking is ok (but may not be true for in future ports) */
2098   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2099       && argCnt>1)
2100     {
2101       //printf("argCnt = %d\n",argCnt);
2102       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2103     }
2104
2105   /* compare expected args with actual args */
2106   exargs = FUNC_ARGS(csym->type);
2107   acargs = FUNC_ARGS(sym->type);
2108
2109   /* for all the expected args do */
2110   for (argCnt = 1;
2111        exargs && acargs;
2112        exargs = exargs->next, acargs = acargs->next, argCnt++)
2113     {
2114       if (getenv("DEBUG_SANITY")) {
2115         fprintf (stderr, "checkFunction: %s ", exargs->name);
2116       }
2117       /* make sure the type is complete and sane */
2118       checkTypeSanity(exargs->etype, exargs->name);
2119
2120       /* If the actual argument is an array, any prototype
2121        * will have modified it to a pointer. Duplicate that
2122        * change here.
2123        */
2124       if (IS_AGGREGATE (acargs->type))
2125         {
2126           checkValue = copyValue (acargs);
2127           aggregateToPointer (checkValue);
2128         }
2129       else
2130         {
2131           checkValue = acargs;
2132         }
2133
2134       if (compareType (exargs->type, checkValue->type) <= 0)
2135         {
2136           werror (E_ARG_TYPE, argCnt);
2137           printFromToType(exargs->type, checkValue->type);
2138           return 0;
2139         }
2140     }
2141
2142   /* if one them ended we have a problem */
2143   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2144       (!exargs && acargs && !IS_VOID (acargs->type)))
2145     werror (E_ARG_COUNT);
2146
2147   /* replace with this defition */
2148   sym->cdef = csym->cdef;
2149   deleteSym (SymbolTab, csym, csym->name);
2150   deleteFromSeg(csym);
2151   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2152   if (IS_EXTERN (csym->etype) && !
2153       IS_EXTERN (sym->etype))
2154     {
2155       addSet (&publics, sym);
2156     }
2157   return 1;
2158 }
2159
2160 /*------------------------------------------------------------------*/
2161 /* cdbStructBlock - calls struct printing for a blcks               */
2162 /*------------------------------------------------------------------*/
2163 void cdbStructBlock (int block)
2164 {
2165   int i;
2166   bucket **table = StructTab;
2167   bucket *chain;
2168
2169   /* go thru the entire  table  */
2170   for (i = 0; i < 256; i++)
2171     {
2172       for (chain = table[i]; chain; chain = chain->next)
2173         {
2174           if (chain->block >= block)
2175             {
2176               if(debugFile)
2177                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2178             }
2179         }
2180     }
2181 }
2182
2183 /*-----------------------------------------------------------------*/
2184 /* processFuncArgs - does some processing with function args       */
2185 /*-----------------------------------------------------------------*/
2186 void 
2187 processFuncArgs (symbol * func)
2188 {
2189   value *val;
2190   int pNum = 1;
2191   sym_link *funcType=func->type;
2192
2193   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2194     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2195
2196   /* find the function declaration within the type */
2197   while (funcType && !IS_FUNC(funcType))
2198     funcType=funcType->next;
2199
2200   /* if this function has variable argument list */
2201   /* then make the function a reentrant one    */
2202   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2203     FUNC_ISREENT(funcType)=1;
2204
2205   /* check if this function is defined as calleeSaves
2206      then mark it as such */
2207   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2208
2209   /* loop thru all the arguments   */
2210   val = FUNC_ARGS(funcType);
2211
2212   /* if it is void then remove parameters */
2213   if (val && IS_VOID (val->type))
2214     {
2215       FUNC_ARGS(funcType) = NULL;
2216       return;
2217     }
2218
2219   /* reset regparm for the port */
2220   (*port->reset_regparms) ();
2221   /* if any of the arguments is an aggregate */
2222   /* change it to pointer to the same type */
2223   while (val)
2224     {
2225         int argreg = 0;
2226       /* mark it as a register parameter if
2227          the function does not have VA_ARG
2228          and as port dictates */
2229       if (!IFFUNC_HASVARARGS(funcType) &&
2230           (argreg = (*port->reg_parm) (val->type)))
2231         {
2232           SPEC_REGPARM (val->etype) = 1;
2233           SPEC_ARGREG(val->etype) = argreg;
2234         } else if (IFFUNC_ISREENT(funcType)) {
2235             FUNC_HASSTACKPARM(funcType) = 1;
2236         }
2237
2238       if (IS_AGGREGATE (val->type))
2239         {
2240           aggregateToPointer (val);
2241         }
2242
2243       val = val->next;
2244       pNum++;
2245     }
2246
2247   /* if this is an internal generated function call */
2248   if (func->cdef) {
2249     /* ignore --stack-auto for this one, we don't know how it is compiled */
2250     /* simply trust on --int-long-reent or --float-reent */
2251     if (IFFUNC_ISREENT(funcType)) {
2252       return;
2253     }
2254   } else {
2255     /* if this function is reentrant or */
2256     /* automatics r 2b stacked then nothing */
2257     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2258       return;
2259   }
2260
2261   val = FUNC_ARGS(funcType);
2262   pNum = 1;
2263   while (val)
2264     {
2265
2266       /* if a symbolname is not given  */
2267       /* synthesize a variable name */
2268       if (!val->sym)
2269         {
2270           SNPRINTF (val->name, sizeof(val->name), 
2271                     "_%s_PARM_%d", func->name, pNum++);
2272           val->sym = newSymbol (val->name, 1);
2273           SPEC_OCLS (val->etype) = port->mem.default_local_map;
2274           val->sym->type = copyLinkChain (val->type);
2275           val->sym->etype = getSpec (val->sym->type);
2276           val->sym->_isparm = 1;
2277           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2278           #if 0
2279           /* ?? static functions shouldn't imply static parameters - EEP */
2280           if (IS_SPEC(func->etype)) {
2281             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2282               SPEC_STAT (func->etype);
2283           }
2284           #endif
2285           addSymChain (val->sym);
2286
2287         }
2288       else                      /* symbol name given create synth name */
2289         {
2290
2291           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2292           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2293           val->sym->_isparm = 1;
2294           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2295             (options.model != MODEL_SMALL ? xdata : data);
2296           
2297           #if 0
2298           /* ?? static functions shouldn't imply static parameters - EEP */
2299           if (IS_SPEC(func->etype)) {
2300             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2301               SPEC_STAT (func->etype);
2302           }
2303           #endif
2304         }
2305       if (!isinSet(operKeyReset, val->sym)) {
2306         addSet (&operKeyReset, val->sym);
2307         applyToSet (operKeyReset, resetParmKey);
2308       }
2309       val = val->next;
2310     }
2311 }
2312
2313 /*-----------------------------------------------------------------*/
2314 /* isSymbolEqual - compares two symbols return 1 if they match     */
2315 /*-----------------------------------------------------------------*/
2316 int 
2317 isSymbolEqual (symbol * dest, symbol * src)
2318 {
2319   /* if pointers match then equal */
2320   if (dest == src)
2321     return 1;
2322
2323   /* if one of them is null then don't match */
2324   if (!dest || !src)
2325     return 0;
2326
2327   /* if both of them have rname match on rname */
2328   if (dest->rname[0] && src->rname[0])
2329     return (!strcmp (dest->rname, src->rname));
2330
2331   /* otherwise match on name */
2332   return (!strcmp (dest->name, src->name));
2333 }
2334
2335 void PT(sym_link *type)
2336 {
2337         printTypeChain(type,0);
2338 }
2339 /*-----------------------------------------------------------------*/
2340 /* printTypeChain - prints the type chain in human readable form   */
2341 /*-----------------------------------------------------------------*/
2342 void
2343 printTypeChain (sym_link * start, FILE * of)
2344 {
2345   int nlr = 0;
2346   value *args;
2347   sym_link * type, * search;
2348   STORAGE_CLASS scls;
2349
2350   if (!of)
2351     {
2352       of = stdout;
2353       nlr = 1;
2354     }
2355
2356   if (start==NULL) {
2357     fprintf (of, "void");
2358     return;
2359   }
2360
2361   /* Print the chain as it is written in the source: */
2362   /* start with the last entry.                      */
2363   /* However, the storage class at the end of the    */
2364   /* chain reall applies to the first in the chain!  */
2365
2366   for (type = start; type && type->next; type = type->next)
2367     ;
2368   if (IS_SPEC (type))
2369     scls=SPEC_SCLS(type);
2370   else
2371     scls=0;
2372   while (type)
2373     {
2374       if (type==start) {
2375         switch (scls) 
2376           {
2377           case S_DATA: fprintf (of, "data-"); break;
2378           case S_XDATA: fprintf (of, "xdata-"); break;
2379           case S_SFR: fprintf (of, "sfr-"); break;
2380           case S_SBIT: fprintf (of, "sbit-"); break;
2381           case S_CODE: fprintf (of, "code-"); break;
2382           case S_IDATA: fprintf (of, "idata-"); break;
2383           case S_PDATA: fprintf (of, "pdata-"); break;
2384           case S_LITERAL: fprintf (of, "literal-"); break;
2385           case S_STACK: fprintf (of, "stack-"); break;
2386           case S_XSTACK: fprintf (of, "xstack-"); break;
2387           case S_BIT: fprintf (of, "bit-"); break;
2388           case S_EEPROM: fprintf (of, "eeprom-"); break;
2389           default: break;
2390           }
2391       }
2392
2393       if (IS_DECL (type))
2394         {
2395           if (!IS_FUNC(type)) {
2396             if (DCL_PTR_VOLATILE (type)) {
2397               fprintf (of, "volatile-");
2398             }
2399             if (DCL_PTR_CONST (type)) {
2400               fprintf (of, "const-");
2401             }
2402           }
2403           switch (DCL_TYPE (type))
2404             {
2405             case FUNCTION:
2406               fprintf (of, "function %s %s", 
2407                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2408                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2409               fprintf (of, "( ");
2410               for (args = FUNC_ARGS(type); 
2411                    args; 
2412                    args=args->next) {
2413                 printTypeChain(args->type, of);
2414                 if (args->next)
2415                   fprintf(of, ", ");
2416               }
2417               fprintf (of, ") ");
2418               break;
2419             case GPOINTER:
2420               fprintf (of, "generic* ");
2421               break;
2422             case CPOINTER:
2423               fprintf (of, "code* ");
2424               break;
2425             case FPOINTER:
2426               fprintf (of, "xdata* ");
2427               break;
2428             case EEPPOINTER:
2429               fprintf (of, "eeprom* ");
2430               break;
2431             case POINTER:
2432               fprintf (of, "near* ");
2433               break;
2434             case IPOINTER:
2435               fprintf (of, "idata* ");
2436               break;
2437             case PPOINTER:
2438               fprintf (of, "pdata* ");
2439               break;
2440             case UPOINTER:
2441               fprintf (of, "unknown* ");
2442               break;
2443             case ARRAY:
2444               if (DCL_ELEM(type)) {
2445                 fprintf (of, "[%d] ", DCL_ELEM(type));
2446               } else {
2447                 fprintf (of, "[] ");
2448               }
2449               break;
2450             }
2451         }
2452       else
2453         {
2454           if (SPEC_VOLATILE (type))
2455             fprintf (of, "volatile-");
2456           if (SPEC_CONST (type))
2457             fprintf (of, "const-");
2458           if (SPEC_USIGN (type))
2459             fprintf (of, "unsigned-");
2460           switch (SPEC_NOUN (type))
2461             {
2462             case V_INT:
2463               if (IS_LONG (type))
2464                 fprintf (of, "long-");
2465               fprintf (of, "int");
2466               break;
2467
2468             case V_CHAR:
2469               fprintf (of, "char");
2470               break;
2471
2472             case V_VOID:
2473               fprintf (of, "void");
2474               break;
2475
2476             case V_FLOAT:
2477               fprintf (of, "float");
2478               break;
2479
2480             case V_STRUCT:
2481               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2482               break;
2483
2484             case V_SBIT:
2485               fprintf (of, "sbit");
2486               break;
2487
2488             case V_BIT:
2489               fprintf (of, "bit");
2490               break;
2491
2492             case V_BITFIELD:
2493               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2494               break;
2495
2496             case V_DOUBLE:
2497               fprintf (of, "double");
2498               break;
2499
2500             default:
2501               fprintf (of, "unknown type");
2502               break;
2503             }
2504         }
2505       /* search entry in list before "type" */
2506       for (search = start; search && search->next != type;)
2507         search = search->next;
2508       type = search;
2509       if (type)
2510         fputc (' ', of);
2511     }
2512   if (nlr)
2513     fprintf (of, "\n");
2514 }
2515
2516 /*--------------------------------------------------------------------*/
2517 /* printTypeChainRaw - prints the type chain in human readable form   */
2518 /*                     in the raw data structure ordering             */
2519 /*--------------------------------------------------------------------*/
2520 void
2521 printTypeChainRaw (sym_link * start, FILE * of)
2522 {
2523   int nlr = 0;
2524   value *args;
2525   sym_link * type;
2526
2527   if (!of)
2528     {
2529       of = stdout;
2530       nlr = 1;
2531     }
2532
2533   if (start==NULL) {
2534     fprintf (of, "void");
2535     return;
2536   }
2537
2538   type = start;
2539   
2540   while (type)
2541     {
2542       if (IS_DECL (type))
2543         {
2544           if (!IS_FUNC(type)) {
2545             if (DCL_PTR_VOLATILE (type)) {
2546               fprintf (of, "volatile-");
2547             }
2548             if (DCL_PTR_CONST (type)) {
2549               fprintf (of, "const-");
2550             }
2551           }
2552           switch (DCL_TYPE (type))
2553             {
2554             case FUNCTION:
2555               fprintf (of, "function %s %s", 
2556                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2557                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2558               fprintf (of, "( ");
2559               for (args = FUNC_ARGS(type); 
2560                    args; 
2561                    args=args->next) {
2562                 printTypeChain(args->type, of);
2563                 if (args->next)
2564                   fprintf(of, ", ");
2565               }
2566               fprintf (of, ") ");
2567               break;
2568             case GPOINTER:
2569               fprintf (of, "generic* ");
2570               break;
2571             case CPOINTER:
2572               fprintf (of, "code* ");
2573               break;
2574             case FPOINTER:
2575               fprintf (of, "xdata* ");
2576               break;
2577             case EEPPOINTER:
2578               fprintf (of, "eeprom* ");
2579               break;
2580             case POINTER:
2581               fprintf (of, "near* ");
2582               break;
2583             case IPOINTER:
2584               fprintf (of, "idata* ");
2585               break;
2586             case PPOINTER:
2587               fprintf (of, "pdata* ");
2588               break;
2589             case UPOINTER:
2590               fprintf (of, "unknown* ");
2591               break;
2592             case ARRAY:
2593               if (DCL_ELEM(type)) {
2594                 fprintf (of, "[%d] ", DCL_ELEM(type));
2595               } else {
2596                 fprintf (of, "[] ");
2597               }
2598               break;
2599             }
2600           if (DCL_TSPEC(type))
2601             {
2602               fprintf (of, "{");
2603               printTypeChainRaw(DCL_TSPEC(type), of);
2604               fprintf (of, "}");
2605             }
2606         }
2607       else if (IS_SPEC (type))
2608         {
2609         switch (SPEC_SCLS (type)) 
2610           {
2611           case S_DATA: fprintf (of, "data-"); break;
2612           case S_XDATA: fprintf (of, "xdata-"); break;
2613           case S_SFR: fprintf (of, "sfr-"); break;
2614           case S_SBIT: fprintf (of, "sbit-"); break;
2615           case S_CODE: fprintf (of, "code-"); break;
2616           case S_IDATA: fprintf (of, "idata-"); break;
2617           case S_PDATA: fprintf (of, "pdata-"); break;
2618           case S_LITERAL: fprintf (of, "literal-"); break;
2619           case S_STACK: fprintf (of, "stack-"); break;
2620           case S_XSTACK: fprintf (of, "xstack-"); break;
2621           case S_BIT: fprintf (of, "bit-"); break;
2622           case S_EEPROM: fprintf (of, "eeprom-"); break;
2623           default: break;
2624           }
2625           if (SPEC_VOLATILE (type))
2626             fprintf (of, "volatile-");
2627           if (SPEC_CONST (type))
2628             fprintf (of, "const-");
2629           if (SPEC_USIGN (type))
2630             fprintf (of, "unsigned-");
2631           switch (SPEC_NOUN (type))
2632             {
2633             case V_INT:
2634               if (IS_LONG (type))
2635                 fprintf (of, "long-");
2636               fprintf (of, "int");
2637               break;
2638
2639             case V_CHAR:
2640               fprintf (of, "char");
2641               break;
2642
2643             case V_VOID:
2644               fprintf (of, "void");
2645               break;
2646
2647             case V_FLOAT:
2648               fprintf (of, "float");
2649               break;
2650
2651             case V_STRUCT:
2652               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2653               break;
2654
2655             case V_SBIT:
2656               fprintf (of, "sbit");
2657               break;
2658
2659             case V_BIT:
2660               fprintf (of, "bit");
2661               break;
2662
2663             case V_BITFIELD:
2664               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2665               break;
2666
2667             case V_DOUBLE:
2668               fprintf (of, "double");
2669               break;
2670
2671             default:
2672               fprintf (of, "unknown type");
2673               break;
2674             }
2675         }
2676       else
2677         fprintf (of, "NOT_SPEC_OR_DECL");
2678       type = type->next;
2679       if (type)
2680         fputc (' ', of);
2681     }
2682   if (nlr)
2683     fprintf (of, "\n");
2684 }
2685
2686
2687 /*-----------------------------------------------------------------*/
2688 /* powof2 - returns power of two for the number if number is pow 2 */
2689 /*-----------------------------------------------------------------*/
2690 int
2691 powof2 (TYPE_UDWORD num)
2692 {
2693   int nshifts = 0;
2694   int n1s = 0;
2695
2696   while (num)
2697     {
2698       if (num & 1)
2699         n1s++;
2700       num >>= 1;
2701       nshifts++;
2702     }
2703
2704   if (n1s > 1 || nshifts == 0)
2705     return 0;
2706   return nshifts - 1;
2707 }
2708
2709 symbol *__fsadd;
2710 symbol *__fssub;
2711 symbol *__fsmul;
2712 symbol *__fsdiv;
2713 symbol *__fseq;
2714 symbol *__fsneq;
2715 symbol *__fslt;
2716 symbol *__fslteq;
2717 symbol *__fsgt;
2718 symbol *__fsgteq;
2719
2720 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2721 symbol *__muldiv[3][3][2];
2722 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2723 sym_link *__multypes[3][2];
2724 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2725 symbol *__conv[2][3][2];
2726 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2727 symbol *__rlrr[2][3][2];
2728
2729 sym_link *floatType;
2730
2731 static char *
2732 _mangleFunctionName(char *in)
2733 {
2734   if (port->getMangledFunctionName)
2735     {
2736       return port->getMangledFunctionName(in);
2737     }
2738   else
2739     {
2740       return in;
2741     }
2742 }
2743
2744 /*-----------------------------------------------------------------*/
2745 /* typeFromStr - create a typechain from an encoded string         */
2746 /* basic types -        'c' - char                                 */
2747 /*                      's' - short                                */
2748 /*                      'i' - int                                  */
2749 /*                      'l' - long                                 */
2750 /*                      'f' - float                                */
2751 /*                      'v' - void                                 */
2752 /*                      '*' - pointer - default (GPOINTER)         */
2753 /* modifiers -          'u' - unsigned                             */
2754 /* pointer modifiers -  'g' - generic                              */
2755 /*                      'x' - xdata                                */
2756 /*                      'p' - code                                 */
2757 /*                      'd' - data                                 */                     
2758 /*                      'F' - function                             */                     
2759 /* examples : "ig*" - generic int *                                */
2760 /*            "cx*" - char xdata *                                 */
2761 /*            "ui" -  unsigned int                                 */
2762 /*-----------------------------------------------------------------*/
2763 sym_link *typeFromStr (char *s)
2764 {
2765     sym_link *r = newLink(DECLARATOR);
2766     int usign = 0;
2767
2768     do {
2769         sym_link *nr;
2770         switch (*s) {
2771         case 'u' : 
2772             usign = 1;
2773             s++;
2774             continue ;
2775             break ;
2776         case 'c':
2777             r->class = SPECIFIER;
2778             SPEC_NOUN(r) = V_CHAR;
2779             break;
2780         case 's':
2781         case 'i':
2782             r->class = SPECIFIER;
2783             SPEC_NOUN(r) = V_INT;
2784             break;
2785         case 'l':
2786             r->class = SPECIFIER;
2787             SPEC_NOUN(r) = V_INT;
2788             SPEC_LONG(r) = 1;
2789             break;
2790         case 'f':
2791             r->class = SPECIFIER;
2792             SPEC_NOUN(r) = V_FLOAT;
2793             break;
2794         case 'v':
2795             r->class = SPECIFIER;
2796             SPEC_NOUN(r) = V_VOID;
2797             break;
2798         case '*':
2799             DCL_TYPE(r) = port->unqualified_pointer;
2800             break;
2801         case 'g':
2802         case 'x':
2803         case 'p':
2804         case 'd':
2805         case 'F':
2806             assert(*(s+1)=='*');
2807             nr = newLink(DECLARATOR);
2808             nr->next = r;
2809             r = nr;
2810             switch (*s) {
2811             case 'g':
2812                 DCL_TYPE(r) = GPOINTER;
2813                 break;
2814             case 'x':
2815                 DCL_TYPE(r) = FPOINTER;
2816                 break;
2817             case 'p':
2818                 DCL_TYPE(r) = CPOINTER;
2819                 break;
2820             case 'd':
2821                 DCL_TYPE(r) = POINTER;
2822                 break;
2823             case 'F':
2824                 DCL_TYPE(r) = FUNCTION;
2825                 nr = newLink(DECLARATOR);
2826                 nr->next = r;
2827                 r = nr;
2828                 DCL_TYPE(r) = CPOINTER;
2829                 break;
2830             }
2831             s++;
2832             break;
2833         default:
2834             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2835                    "typeFromStr: unknown type");
2836             break;
2837         }
2838         if (IS_SPEC(r) && usign) {
2839             SPEC_USIGN(r) = 1;
2840             usign = 0;
2841         }
2842         s++;
2843     } while (*s);
2844     return r;
2845 }
2846
2847 /*-----------------------------------------------------------------*/
2848 /* initCSupport - create functions for C support routines          */
2849 /*-----------------------------------------------------------------*/
2850 void 
2851 initCSupport ()
2852 {
2853   const char *smuldivmod[] =
2854   {
2855     "mul", "div", "mod"
2856   };
2857   const char *sbwd[] =
2858   {
2859     "char", "int", "long"
2860   };
2861   const char *ssu[] =
2862   {
2863     "s", "u"
2864   };
2865   const char *srlrr[] =
2866   {
2867     "rl", "rr"
2868   };
2869
2870   int bwd, su, muldivmod, tofrom, rlrr;
2871
2872   if (getenv("SDCC_NO_C_SUPPORT")) {
2873     /* for debugging only */
2874     return;
2875   }
2876
2877   floatType = newFloatLink ();
2878
2879   for (bwd = 0; bwd < 3; bwd++)
2880     {
2881       sym_link *l = NULL;
2882       switch (bwd)
2883         {
2884         case 0:
2885           l = newCharLink ();
2886           break;
2887         case 1:
2888           l = newIntLink ();
2889           break;
2890         case 2:
2891           l = newLongLink ();
2892           break;
2893         default:
2894           assert (0);
2895         }
2896       __multypes[bwd][0] = l;
2897       __multypes[bwd][1] = copyLinkChain (l);
2898       SPEC_USIGN (__multypes[bwd][1]) = 1;
2899     }
2900
2901   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2902   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2903   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2904   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2905   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2906   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2907   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2908   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2909   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2910   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2911
2912   for (tofrom = 0; tofrom < 2; tofrom++)
2913     {
2914       for (bwd = 0; bwd < 3; bwd++)
2915         {
2916           for (su = 0; su < 2; su++)
2917             {
2918               if (tofrom)
2919                 {
2920                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2921                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2922                 }
2923               else
2924                 {
2925                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2926                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2927                 }
2928             }
2929         }
2930     }
2931
2932 /*
2933   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2934     {
2935       for (bwd = 0; bwd < 3; bwd++)
2936         {
2937           for (su = 0; su < 2; su++)
2938             {
2939               SNPRINTF (buffer, sizeof(buffer),
2940                         "_%s%s%s",
2941                        smuldivmod[muldivmod],
2942                        ssu[su],
2943                        sbwd[bwd]);
2944               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2945               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2946             }
2947         }
2948     }
2949
2950   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2951   Therefore they've been merged into mulint() and mullong().
2952 */
2953
2954   for (bwd = 0; bwd < 3; bwd++)
2955     {
2956       for (su = 0; su < 2; su++)
2957         {
2958           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2959             {
2960               /* div and mod */
2961               SNPRINTF (buffer, sizeof(buffer),
2962                         "_%s%s%s",
2963                        smuldivmod[muldivmod],
2964                        ssu[su],
2965                        sbwd[bwd]);
2966               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2967               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2968             }
2969         }
2970     }
2971   /* mul only */
2972   muldivmod = 0;
2973   /* byte */
2974   bwd = 0;
2975   for (su = 0; su < 2; su++)
2976     {
2977       /* muluchar and mulschar are still separate functions, because e.g. the z80
2978          port is sign/zero-extending to int before calling mulint() */
2979       SNPRINTF (buffer, sizeof(buffer),
2980                 "_%s%s%s",
2981                 smuldivmod[muldivmod],
2982                 ssu[su],
2983                 sbwd[bwd]);
2984       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2985       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2986     }
2987   /* signed only */
2988   su = 0;
2989   /* word and doubleword */
2990   for (bwd = 1; bwd < 3; bwd++)
2991     {
2992       /* mul, int/long */
2993       SNPRINTF (buffer, sizeof(buffer),
2994                 "_%s%s",
2995                 smuldivmod[muldivmod],
2996                 sbwd[bwd]);
2997       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2998       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2999       /* signed = unsigned */
3000       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3001     }
3002
3003   for (rlrr = 0; rlrr < 2; rlrr++)
3004     {
3005       for (bwd = 0; bwd < 3; bwd++)
3006         {
3007           for (su = 0; su < 2; su++)
3008             {
3009               SNPRINTF (buffer, sizeof(buffer),
3010                         "_%s%s%s",
3011                        srlrr[rlrr],
3012                        ssu[su],
3013                        sbwd[bwd]);
3014               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3015               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3016             }
3017         }
3018     }
3019 }
3020
3021 /*-----------------------------------------------------------------*/
3022 /* initBuiltIns - create prototypes for builtin functions          */
3023 /*-----------------------------------------------------------------*/
3024 void initBuiltIns()
3025 {
3026     int i;
3027     symbol *sym;
3028
3029     if (!port->builtintable) return ;
3030
3031     for (i = 0 ; port->builtintable[i].name ; i++) {
3032         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3033                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3034         FUNC_ISBUILTIN(sym->type) = 1;
3035         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3036     }
3037 }
3038
3039 sym_link *validateLink(sym_link         *l, 
3040                         const char      *macro,
3041                         const char      *args,
3042                         const char      select,
3043                         const char      *file, 
3044                         unsigned        line)
3045 {    
3046   if (l && l->class==select)
3047     {
3048         return l;
3049     }
3050     fprintf(stderr, 
3051             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3052             " expected %s, got %s\n",
3053             macro, args, file, line, 
3054             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3055     exit(-1);
3056     return l; // never reached, makes compiler happy.
3057 }
3058
3059 /*--------------------------------------------------------------------*/
3060 /* newEnumType - create an integer type compatible with enumerations  */
3061 /*--------------------------------------------------------------------*/
3062 sym_link *
3063 newEnumType (symbol *enumlist)
3064 {
3065   int min, max, v;
3066   symbol *sym;
3067   sym_link *type;
3068
3069   if (!enumlist)
3070     {
3071       type = newLink (SPECIFIER);
3072       SPEC_NOUN (type) = V_INT;
3073       return type;
3074     }
3075       
3076   /* Determine the range of the enumerated values */
3077   sym = enumlist;
3078   min = max = (int) floatFromVal (valFromType (sym->type));
3079   for (sym = sym->next; sym; sym = sym->next)
3080     {
3081       v = (int) floatFromVal (valFromType (sym->type));
3082       if (v<min)
3083         min = v;
3084       if (v>max)
3085         max = v;
3086     }
3087
3088   /* Determine the smallest integer type that is compatible with this range */
3089   type = newLink (SPECIFIER);
3090   if (min>=0 && max<=255)
3091     {
3092       SPEC_NOUN (type) = V_CHAR;
3093       SPEC_USIGN (type) = 1;
3094     }
3095   else if (min>=-128 && max<=127)
3096     {
3097       SPEC_NOUN (type) = V_CHAR;
3098     }
3099   else if (min>=0 && max<=65535)
3100     {
3101       SPEC_NOUN (type) = V_INT;
3102       SPEC_USIGN (type) = 1;
3103     }
3104   else if (min>=-32768 && max<=32767)
3105     {
3106       SPEC_NOUN (type) = V_INT;
3107     }
3108   else
3109     {
3110       SPEC_NOUN (type) = V_INT;
3111       SPEC_LONG (type) = 1;
3112       if (min>=0)
3113         SPEC_USIGN (type) = 1;
3114     }
3115   
3116   return type;    
3117 }