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