14bcaee6f72dd93fbdc313ad35100c7c783f183c
[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)
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 #if 0
1550   if (SPEC_NOUN (reType) == V_CHAR)
1551     SPEC_NOUN (reType) = V_INT;
1552 #endif
1553
1554   /* if either of them unsigned but not val then make this unsigned */
1555   if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) &&
1556       !IS_FLOAT (reType))
1557     SPEC_USIGN (reType) = 1;
1558   else
1559     SPEC_USIGN (reType) = 0;
1560
1561   /* if result is a literal then make not so */
1562   if (IS_LITERAL (reType))
1563     SPEC_SCLS (reType) = S_REGISTER;
1564
1565   return rType;
1566 }
1567
1568 /*--------------------------------------------------------------------*/
1569 /* compareType - will do type check return 1 if match, -1 if castable */
1570 /*--------------------------------------------------------------------*/
1571 int
1572 compareType (sym_link * dest, sym_link * src)
1573 {
1574   if (!dest && !src)
1575     return 1;
1576
1577   if (dest && !src)
1578     return 0;
1579
1580   if (src && !dest)
1581     return 0;
1582
1583   /* if dest is a declarator then */
1584   if (IS_DECL (dest))
1585     {
1586       if (IS_DECL (src))
1587         {
1588           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1589             if (IS_FUNC(src)) {
1590               //checkFunction(src,dest);
1591             }
1592             return compareType (dest->next, src->next);
1593           }
1594           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1595             return 1;
1596           }
1597           if (IS_PTR (src) && IS_GENPTR (dest))
1598             return -1;
1599           if (IS_PTR (dest) && IS_ARRAY (src)) {
1600             value *val=aggregateToPointer (valFromType(src));
1601             int res=compareType (dest, val->type);
1602             Safe_free(val->type);
1603             Safe_free(val);
1604             return res;
1605           }
1606           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1607             return compareType (dest->next, src);
1608           return 0;
1609         }
1610       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1611         return -1;
1612       else
1613         return 0;
1614     }
1615
1616   /* if one is a specifier and the other is not */
1617   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1618       (IS_SPEC (dest) && !IS_SPEC (src)))
1619     return 0;
1620
1621   /* if one of them is a void then ok */
1622   if (SPEC_NOUN (dest) == V_VOID &&
1623       SPEC_NOUN (src) != V_VOID)
1624     return -1;
1625
1626   if (SPEC_NOUN (dest) != V_VOID &&
1627       SPEC_NOUN (src) == V_VOID)
1628     return -1;
1629
1630   /* if they are both bitfields then if the lengths
1631      and starts don't match */
1632   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1633       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1634        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1635     return -1;
1636
1637   /* it is a specifier */
1638   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1639     {
1640       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1641           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1642           getSize (dest) == getSize (src))
1643         return 1;
1644       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1645         return -1;
1646       else
1647         return 0;
1648     }
1649   else if (IS_STRUCT (dest))
1650     {
1651       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1652         return 0;
1653       else
1654         return 1;
1655     }
1656   if (SPEC_LONG (dest) != SPEC_LONG (src))
1657     return -1;
1658
1659   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1660     return -1;
1661
1662   return 1;
1663 }
1664
1665 /*--------------------------------------------------------------------*/
1666 /* compareTypeExact - will do type check return 1 if match exactly    */
1667 /*--------------------------------------------------------------------*/
1668 int
1669 compareTypeExact (sym_link * dest, sym_link * src, int level)
1670 {
1671   STORAGE_CLASS srcScls, destScls;
1672   
1673   if (!dest && !src)
1674     return 1;
1675
1676   if (dest && !src)
1677     return 0;
1678
1679   if (src && !dest)
1680     return 0;
1681
1682   /* if dest is a declarator then */
1683   if (IS_DECL (dest))
1684     {
1685       if (IS_DECL (src))
1686         {
1687           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1688             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
1689               return 0;
1690             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
1691               return 0;
1692             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
1693               return 0;
1694             if (IS_FUNC(src))
1695               {
1696                 value *exargs, *acargs, *checkValue;
1697
1698                 /* verify function return type */
1699                 if (!compareTypeExact (dest->next, src->next, -1))
1700                   return 0;
1701                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
1702                   return 0;
1703                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
1704                   return 0;
1705                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
1706                   return 0;
1707                 #if 0
1708                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
1709                   return 0;
1710                 #endif
1711
1712                 /* compare expected args with actual args */
1713                 exargs = FUNC_ARGS(dest);
1714                 acargs = FUNC_ARGS(src);
1715
1716                 /* for all the expected args do */
1717                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
1718                   {
1719                     //checkTypeSanity(acargs->etype, acargs->name);
1720
1721                     if (IS_AGGREGATE (acargs->type))
1722                       {
1723                         checkValue = copyValue (acargs);
1724                         aggregateToPointer (checkValue);
1725                       }
1726                     else
1727                       checkValue = acargs;
1728
1729                     #if 0
1730                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
1731                       return 0;
1732                     #endif
1733                   }
1734
1735                   /* if one them ended we have a problem */
1736                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1737                       (!exargs && acargs && !IS_VOID (acargs->type)))
1738                     return 0;                  
1739                   return 1;
1740               }
1741             return compareTypeExact (dest->next, src->next, level);
1742           }
1743           return 0;
1744         }
1745       return 0;
1746     }
1747
1748   /* if one is a specifier and the other is not */
1749   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1750       (IS_SPEC (dest) && !IS_SPEC (src)))
1751     return 0;
1752
1753   /* if one of them is a void then ok */
1754   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1755     return 0;
1756
1757   /* if they are both bitfields then if the lengths
1758      and starts don't match */
1759   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1760       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1761        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1762     return 0;
1763
1764   if (IS_INTEGRAL (dest))
1765     {
1766       /* signedness must match */
1767       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1768         return 0;
1769       /* size must match */
1770       if (SPEC_LONG (dest) != SPEC_LONG (src))
1771         return 0;
1772       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1773         return 0;
1774     }
1775   
1776   if (IS_STRUCT (dest))
1777     {
1778       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1779         return 0;
1780     }
1781
1782   if (SPEC_CONST (dest) != SPEC_CONST (src))
1783     return 0;
1784   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
1785     return 0;
1786   if (SPEC_STAT (dest) != SPEC_STAT (src))
1787     return 0;
1788   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
1789     return 0;
1790   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
1791     return 0;
1792       
1793   destScls = SPEC_SCLS (dest);
1794   srcScls = SPEC_SCLS (src);
1795   
1796   /* Compensate for const to const code change in checkSClass() */
1797   if (!level & port->mem.code_ro && SPEC_CONST (dest))
1798     {
1799       if (srcScls == S_CODE && destScls == S_FIXED)
1800         destScls = S_CODE;
1801       if (destScls == S_CODE && srcScls == S_FIXED)
1802         srcScls = S_CODE;
1803     }
1804
1805   /* compensate for allocGlobal() */  
1806   if ((srcScls == S_FIXED || srcScls == S_AUTO)
1807       && port->mem.default_globl_map == xdata
1808       && !level)
1809     srcScls = S_XDATA;
1810   
1811   if (level>0 && !SPEC_STAT (dest))
1812     {
1813       /* Compensate for hack-o-matic in checkSClass() */
1814       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1815         {
1816           if (destScls == S_FIXED)
1817             destScls = (options.useXstack ? S_XSTACK : S_STACK);
1818           if (srcScls == S_FIXED)
1819             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
1820         }
1821       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
1822         {
1823           if (destScls == S_FIXED)
1824             destScls = S_XDATA;
1825           if (srcScls == S_FIXED)
1826             srcScls = S_XDATA;
1827         }
1828     }
1829
1830   if (srcScls != destScls)
1831     {
1832       #if 0
1833       printf ("level = %d\n", level);
1834       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
1835                 SPEC_SCLS (src), SPEC_SCLS (dest));
1836       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
1837       #endif
1838       return 0;
1839     }
1840   
1841   return 1;
1842 }
1843
1844 /*------------------------------------------------------------------*/
1845 /* inCalleeSaveList - return 1 if found in callee save list          */
1846 /*------------------------------------------------------------------*/
1847 static int
1848 calleeCmp(void *p1, void *p2)
1849 {
1850   return (strcmp((char *)p1, (char *)(p2)) == 0);
1851 }
1852
1853 bool
1854 inCalleeSaveList(char *s)
1855 {
1856   if (options.all_callee_saves)
1857     return 1;
1858   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
1859 }
1860
1861 /*-----------------------------------------------------------------*/
1862 /* aggregateToPointer:  change an agggregate type function      */
1863 /*         argument to a pointer to that type.     */
1864 /*-----------------------------------------------------------------*/
1865 value *
1866 aggregateToPointer (value * val)
1867 {
1868   if (IS_AGGREGATE (val->type))
1869     {
1870       /* if this is a structure */
1871       /* then we need to add a new link */
1872       if (IS_STRUCT (val->type))
1873         {
1874           /* first lets add DECLARATOR type */
1875           sym_link *p = val->type;
1876
1877           werror (W_STRUCT_AS_ARG, val->name);
1878           val->type = newLink (DECLARATOR);
1879           val->type->next = p;
1880         }
1881
1882       /* change to a pointer depending on the */
1883       /* storage class specified        */
1884       switch (SPEC_SCLS (val->etype))
1885         {
1886         case S_IDATA:
1887           DCL_TYPE (val->type) = IPOINTER;
1888           break;
1889         case S_PDATA:
1890           DCL_TYPE (val->type) = PPOINTER;
1891           break;
1892         case S_FIXED:
1893           if (SPEC_OCLS(val->etype)) {
1894             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1895           } else {
1896             // this happens for (external) function parameters
1897             DCL_TYPE (val->type) = port->unqualified_pointer;
1898           }
1899           break;
1900         case S_AUTO:
1901         case S_DATA:
1902         case S_REGISTER:
1903           DCL_TYPE (val->type) = POINTER;
1904           break;
1905         case S_CODE:
1906           DCL_TYPE (val->type) = CPOINTER;
1907           break;
1908         case S_XDATA:
1909           DCL_TYPE (val->type) = FPOINTER;
1910           break;
1911         case S_EEPROM:
1912           DCL_TYPE (val->type) = EEPPOINTER;
1913           break;
1914         default:
1915           DCL_TYPE (val->type) = port->unqualified_pointer;
1916         }
1917       
1918       /* is there is a symbol associated then */
1919       /* change the type of the symbol as well */
1920       if (val->sym)
1921         {
1922           val->sym->type = copyLinkChain (val->type);
1923           val->sym->etype = getSpec (val->sym->type);
1924         }
1925     }
1926   return val;
1927 }
1928 /*------------------------------------------------------------------*/
1929 /* checkFunction - does all kinds of check on a function            */
1930 /*------------------------------------------------------------------*/
1931 int 
1932 checkFunction (symbol * sym, symbol *csym)
1933 {
1934   value *exargs, *acargs;
1935   value *checkValue;
1936   int argCnt = 0;
1937
1938   if (getenv("DEBUG_SANITY")) {
1939     fprintf (stderr, "checkFunction: %s ", sym->name);
1940   }
1941
1942   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
1943     {
1944       werror(E_SYNTAX_ERROR, sym->name);
1945       return 0;
1946     }
1947     
1948   /* make sure the type is complete and sane */
1949   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1950
1951   /* if not type then some kind of error */
1952   if (!sym->type)
1953     return 0;
1954
1955   /* if the function has no type then make it return int */
1956   if (!sym->type->next)
1957     sym->type->next = sym->etype = newIntLink ();
1958
1959   /* function cannot return aggregate */
1960   if (IS_AGGREGATE (sym->type->next))
1961     {
1962       werror (E_FUNC_AGGR, sym->name);
1963       return 0;
1964     }
1965
1966   /* function cannot return bit */
1967   if (IS_BITVAR (sym->type->next))
1968     {
1969       werror (E_FUNC_BIT, sym->name);
1970       return 0;
1971     }
1972
1973   /* check if this function is defined as calleeSaves
1974      then mark it as such */
1975   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1976
1977   /* if interrupt service routine  */
1978   /* then it cannot have arguments */
1979   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1980     {
1981       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1982         werror (E_INT_ARGS, sym->name);
1983         FUNC_ARGS(sym->type)=NULL;
1984       }
1985     }
1986
1987   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1988        acargs; 
1989        acargs=acargs->next, argCnt++) {
1990     if (!acargs->sym) { 
1991       // this can happen for reentrant functions
1992       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1993       // the show must go on: synthesize a name and symbol
1994       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
1995       acargs->sym = newSymbol (acargs->name, 1);
1996       SPEC_OCLS (acargs->etype) = istack;
1997       acargs->sym->type = copyLinkChain (acargs->type);
1998       acargs->sym->etype = getSpec (acargs->sym->type);
1999       acargs->sym->_isparm = 1;
2000       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2001     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2002       // synthesized name
2003       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2004     }
2005   }
2006   argCnt--;
2007
2008   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2009     return 1;                   /* not defined nothing more to check  */
2010
2011   /* check if body already present */
2012   if (csym && IFFUNC_HASBODY(csym->type))
2013     {
2014       werror (E_FUNC_BODY, sym->name);
2015       return 0;
2016     }
2017
2018   /* check the return value type   */
2019   if (compareType (csym->type, sym->type) <= 0)
2020     {
2021       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2022       printFromToType(csym->type, sym->type);
2023       return 0;
2024     }
2025
2026   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2027     {
2028       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2029     }
2030
2031   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
2032     {
2033       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2034     }
2035
2036   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2037     {
2038       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2039     }
2040   
2041   /* Really, reentrant should match regardless of argCnt, but     */
2042   /* this breaks some existing code (the fp lib functions). If    */
2043   /* the first argument is always passed the same way, this       */
2044   /* lax checking is ok (but may not be true for in future ports) */
2045   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2046       && argCnt>1)
2047     {
2048       //printf("argCnt = %d\n",argCnt);
2049       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2050     }
2051
2052   /* compare expected args with actual args */
2053   exargs = FUNC_ARGS(csym->type);
2054   acargs = FUNC_ARGS(sym->type);
2055
2056   /* for all the expected args do */
2057   for (argCnt = 1;
2058        exargs && acargs;
2059        exargs = exargs->next, acargs = acargs->next, argCnt++)
2060     {
2061       if (getenv("DEBUG_SANITY")) {
2062         fprintf (stderr, "checkFunction: %s ", exargs->name);
2063       }
2064       /* make sure the type is complete and sane */
2065       checkTypeSanity(exargs->etype, exargs->name);
2066
2067       /* If the actual argument is an array, any prototype
2068        * will have modified it to a pointer. Duplicate that
2069        * change here.
2070        */
2071       if (IS_AGGREGATE (acargs->type))
2072         {
2073           checkValue = copyValue (acargs);
2074           aggregateToPointer (checkValue);
2075         }
2076       else
2077         {
2078           checkValue = acargs;
2079         }
2080
2081       if (compareType (exargs->type, checkValue->type) <= 0)
2082         {
2083           werror (E_ARG_TYPE, argCnt);
2084           printFromToType(exargs->type, checkValue->type);
2085           return 0;
2086         }
2087     }
2088
2089   /* if one them ended we have a problem */
2090   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2091       (!exargs && acargs && !IS_VOID (acargs->type)))
2092     werror (E_ARG_COUNT);
2093
2094   /* replace with this defition */
2095   sym->cdef = csym->cdef;
2096   deleteSym (SymbolTab, csym, csym->name);
2097   deleteFromSeg(csym);
2098   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2099   if (IS_EXTERN (csym->etype) && !
2100       IS_EXTERN (sym->etype))
2101     {
2102       addSet (&publics, sym);
2103     }
2104   return 1;
2105 }
2106
2107 /*------------------------------------------------------------------*/
2108 /* cdbStructBlock - calls struct printing for a blcks               */
2109 /*------------------------------------------------------------------*/
2110 void cdbStructBlock (int block)
2111 {
2112   int i;
2113   bucket **table = StructTab;
2114   bucket *chain;
2115
2116   /* go thru the entire  table  */
2117   for (i = 0; i < 256; i++)
2118     {
2119       for (chain = table[i]; chain; chain = chain->next)
2120         {
2121           if (chain->block >= block)
2122             {
2123               if(debugFile)
2124                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2125             }
2126         }
2127     }
2128 }
2129
2130 /*-----------------------------------------------------------------*/
2131 /* processFuncArgs - does some processing with function args       */
2132 /*-----------------------------------------------------------------*/
2133 void 
2134 processFuncArgs (symbol * func)
2135 {
2136   value *val;
2137   int pNum = 1;
2138   sym_link *funcType=func->type;
2139
2140   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2141     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2142
2143   // if this is a pointer to a function
2144   if (IS_PTR(funcType)) {
2145     funcType=funcType->next;
2146   }
2147
2148   /* if this function has variable argument list */
2149   /* then make the function a reentrant one    */
2150   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2151     FUNC_ISREENT(funcType)=1;
2152
2153   /* check if this function is defined as calleeSaves
2154      then mark it as such */
2155   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2156
2157   /* loop thru all the arguments   */
2158   val = FUNC_ARGS(funcType);
2159
2160   /* if it is void then remove parameters */
2161   if (val && IS_VOID (val->type))
2162     {
2163       FUNC_ARGS(funcType) = NULL;
2164       return;
2165     }
2166
2167   /* reset regparm for the port */
2168   (*port->reset_regparms) ();
2169   /* if any of the arguments is an aggregate */
2170   /* change it to pointer to the same type */
2171   while (val)
2172     {
2173         int argreg = 0;
2174       /* mark it as a register parameter if
2175          the function does not have VA_ARG
2176          and as port dictates */
2177       if (!IFFUNC_HASVARARGS(funcType) &&
2178           (argreg = (*port->reg_parm) (val->type)))
2179         {
2180           SPEC_REGPARM (val->etype) = 1;
2181           SPEC_ARGREG(val->etype) = argreg;
2182         } else if (IFFUNC_ISREENT(funcType)) {
2183             FUNC_HASSTACKPARM(funcType) = 1;
2184         }
2185
2186       if (IS_AGGREGATE (val->type))
2187         {
2188           aggregateToPointer (val);
2189         }
2190
2191       val = val->next;
2192       pNum++;
2193     }
2194
2195   /* if this is an internal generated function call */
2196   if (func->cdef) {
2197     /* ignore --stack-auto for this one, we don't know how it is compiled */
2198     /* simply trust on --int-long-reent or --float-reent */
2199     if (IFFUNC_ISREENT(funcType)) {
2200       return;
2201     }
2202   } else {
2203     /* if this function is reentrant or */
2204     /* automatics r 2b stacked then nothing */
2205     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2206       return;
2207   }
2208
2209   val = FUNC_ARGS(funcType);
2210   pNum = 1;
2211   while (val)
2212     {
2213
2214       /* if a symbolname is not given  */
2215       /* synthesize a variable name */
2216       if (!val->sym)
2217         {
2218           SNPRINTF (val->name, sizeof(val->name), 
2219                     "_%s_PARM_%d", func->name, pNum++);
2220           val->sym = newSymbol (val->name, 1);
2221           SPEC_OCLS (val->etype) = port->mem.default_local_map;
2222           val->sym->type = copyLinkChain (val->type);
2223           val->sym->etype = getSpec (val->sym->type);
2224           val->sym->_isparm = 1;
2225           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2226           if (IS_SPEC(func->etype)) {
2227             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2228               SPEC_STAT (func->etype);
2229           }
2230           addSymChain (val->sym);
2231
2232         }
2233       else                      /* symbol name given create synth name */
2234         {
2235
2236           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2237           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2238           val->sym->_isparm = 1;
2239           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2240             (options.model != MODEL_SMALL ? xdata : data);
2241           if (IS_SPEC(func->etype)) {
2242             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2243               SPEC_STAT (func->etype);
2244           }
2245         }
2246       if (!isinSet(operKeyReset, val->sym)) {
2247         addSet (&operKeyReset, val->sym);
2248         applyToSet (operKeyReset, resetParmKey);
2249       }
2250       val = val->next;
2251     }
2252 }
2253
2254 /*-----------------------------------------------------------------*/
2255 /* isSymbolEqual - compares two symbols return 1 if they match     */
2256 /*-----------------------------------------------------------------*/
2257 int 
2258 isSymbolEqual (symbol * dest, symbol * src)
2259 {
2260   /* if pointers match then equal */
2261   if (dest == src)
2262     return 1;
2263
2264   /* if one of them is null then don't match */
2265   if (!dest || !src)
2266     return 0;
2267
2268   /* if both of them have rname match on rname */
2269   if (dest->rname[0] && src->rname[0])
2270     return (!strcmp (dest->rname, src->rname));
2271
2272   /* otherwise match on name */
2273   return (!strcmp (dest->name, src->name));
2274 }
2275
2276 void PT(sym_link *type)
2277 {
2278         printTypeChain(type,0);
2279 }
2280 /*-----------------------------------------------------------------*/
2281 /* printTypeChain - prints the type chain in human readable form   */
2282 /*-----------------------------------------------------------------*/
2283 void
2284 printTypeChain (sym_link * start, FILE * of)
2285 {
2286   int nlr = 0;
2287   value *args;
2288   sym_link * type, * search;
2289   STORAGE_CLASS scls;
2290
2291   if (!of)
2292     {
2293       of = stdout;
2294       nlr = 1;
2295     }
2296
2297   if (start==NULL) {
2298     fprintf (of, "void");
2299     return;
2300   }
2301
2302   /* Print the chain as it is written in the source: */
2303   /* start with the last entry.                      */
2304   /* However, the storage class at the end of the    */
2305   /* chain reall applies to the first in the chain!  */
2306
2307   for (type = start; type && type->next; type = type->next)
2308     ;
2309   if (IS_SPEC (type))
2310     scls=SPEC_SCLS(type);
2311   else
2312     scls=0;
2313   while (type)
2314     {
2315       if (type==start) {
2316         switch (scls) 
2317           {
2318           case S_DATA: fprintf (of, "data-"); break;
2319           case S_XDATA: fprintf (of, "xdata-"); break;
2320           case S_SFR: fprintf (of, "sfr-"); break;
2321           case S_SBIT: fprintf (of, "sbit-"); break;
2322           case S_CODE: fprintf (of, "code-"); break;
2323           case S_IDATA: fprintf (of, "idata-"); break;
2324           case S_PDATA: fprintf (of, "pdata-"); break;
2325           case S_LITERAL: fprintf (of, "literal-"); break;
2326           case S_STACK: fprintf (of, "stack-"); break;
2327           case S_XSTACK: fprintf (of, "xstack-"); break;
2328           case S_BIT: fprintf (of, "bit-"); break;
2329           case S_EEPROM: fprintf (of, "eeprom-"); break;
2330           default: break;
2331           }
2332       }
2333
2334       if (IS_DECL (type))
2335         {
2336           if (!IS_FUNC(type)) {
2337             if (DCL_PTR_VOLATILE (type)) {
2338               fprintf (of, "volatile-");
2339             }
2340             if (DCL_PTR_CONST (type)) {
2341               fprintf (of, "const-");
2342             }
2343           }
2344           switch (DCL_TYPE (type))
2345             {
2346             case FUNCTION:
2347               fprintf (of, "function %s %s", 
2348                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2349                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2350               fprintf (of, "( ");
2351               for (args = FUNC_ARGS(type); 
2352                    args; 
2353                    args=args->next) {
2354                 printTypeChain(args->type, of);
2355                 if (args->next)
2356                   fprintf(of, ", ");
2357               }
2358               fprintf (of, ") ");
2359               break;
2360             case GPOINTER:
2361               fprintf (of, "generic* ");
2362               break;
2363             case CPOINTER:
2364               fprintf (of, "code* ");
2365               break;
2366             case FPOINTER:
2367               fprintf (of, "xdata* ");
2368               break;
2369             case EEPPOINTER:
2370               fprintf (of, "eeprom* ");
2371               break;
2372             case POINTER:
2373               fprintf (of, "near* ");
2374               break;
2375             case IPOINTER:
2376               fprintf (of, "idata* ");
2377               break;
2378             case PPOINTER:
2379               fprintf (of, "pdata* ");
2380               break;
2381             case UPOINTER:
2382               fprintf (of, "unknown* ");
2383               break;
2384             case ARRAY:
2385               if (DCL_ELEM(type)) {
2386                 fprintf (of, "[%d] ", DCL_ELEM(type));
2387               } else {
2388                 fprintf (of, "[] ");
2389               }
2390               break;
2391             }
2392         }
2393       else
2394         {
2395           if (SPEC_VOLATILE (type))
2396             fprintf (of, "volatile-");
2397           if (SPEC_CONST (type))
2398             fprintf (of, "const-");
2399           if (SPEC_USIGN (type))
2400             fprintf (of, "unsigned-");
2401           switch (SPEC_NOUN (type))
2402             {
2403             case V_INT:
2404               if (IS_LONG (type))
2405                 fprintf (of, "long-");
2406               fprintf (of, "int");
2407               break;
2408
2409             case V_CHAR:
2410               fprintf (of, "char");
2411               break;
2412
2413             case V_VOID:
2414               fprintf (of, "void");
2415               break;
2416
2417             case V_FLOAT:
2418               fprintf (of, "float");
2419               break;
2420
2421             case V_STRUCT:
2422               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2423               break;
2424
2425             case V_SBIT:
2426               fprintf (of, "sbit");
2427               break;
2428
2429             case V_BIT:
2430               fprintf (of, "bit");
2431               break;
2432
2433             case V_BITFIELD:
2434               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2435               break;
2436
2437             case V_DOUBLE:
2438               fprintf (of, "double");
2439               break;
2440
2441             default:
2442               fprintf (of, "unknown type");
2443               break;
2444             }
2445         }
2446       /* search entry in list before "type" */
2447       for (search = start; search && search->next != type;)
2448         search = search->next;
2449       type = search;
2450       if (type)
2451         fputc (' ', of);
2452     }
2453   if (nlr)
2454     fprintf (of, "\n");
2455 }
2456
2457 /*--------------------------------------------------------------------*/
2458 /* printTypeChainRaw - prints the type chain in human readable form   */
2459 /*                     in the raw data structure ordering             */
2460 /*--------------------------------------------------------------------*/
2461 void
2462 printTypeChainRaw (sym_link * start, FILE * of)
2463 {
2464   int nlr = 0;
2465   value *args;
2466   sym_link * type;
2467
2468   if (!of)
2469     {
2470       of = stdout;
2471       nlr = 1;
2472     }
2473
2474   if (start==NULL) {
2475     fprintf (of, "void");
2476     return;
2477   }
2478
2479   type = start;
2480   
2481   while (type)
2482     {
2483       if (IS_DECL (type))
2484         {
2485           if (!IS_FUNC(type)) {
2486             if (DCL_PTR_VOLATILE (type)) {
2487               fprintf (of, "volatile-");
2488             }
2489             if (DCL_PTR_CONST (type)) {
2490               fprintf (of, "const-");
2491             }
2492           }
2493           switch (DCL_TYPE (type))
2494             {
2495             case FUNCTION:
2496               fprintf (of, "function %s %s", 
2497                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2498                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2499               fprintf (of, "( ");
2500               for (args = FUNC_ARGS(type); 
2501                    args; 
2502                    args=args->next) {
2503                 printTypeChain(args->type, of);
2504                 if (args->next)
2505                   fprintf(of, ", ");
2506               }
2507               fprintf (of, ") ");
2508               break;
2509             case GPOINTER:
2510               fprintf (of, "generic* ");
2511               break;
2512             case CPOINTER:
2513               fprintf (of, "code* ");
2514               break;
2515             case FPOINTER:
2516               fprintf (of, "xdata* ");
2517               break;
2518             case EEPPOINTER:
2519               fprintf (of, "eeprom* ");
2520               break;
2521             case POINTER:
2522               fprintf (of, "near* ");
2523               break;
2524             case IPOINTER:
2525               fprintf (of, "idata* ");
2526               break;
2527             case PPOINTER:
2528               fprintf (of, "pdata* ");
2529               break;
2530             case UPOINTER:
2531               fprintf (of, "unknown* ");
2532               break;
2533             case ARRAY:
2534               if (DCL_ELEM(type)) {
2535                 fprintf (of, "[%d] ", DCL_ELEM(type));
2536               } else {
2537                 fprintf (of, "[] ");
2538               }
2539               break;
2540             }
2541           if (DCL_TSPEC(type))
2542             {
2543               fprintf (of, "{");
2544               printTypeChainRaw(DCL_TSPEC(type), of);
2545               fprintf (of, "}");
2546             }
2547         }
2548       else if (IS_SPEC (type))
2549         {
2550         switch (SPEC_SCLS (type)) 
2551           {
2552           case S_DATA: fprintf (of, "data-"); break;
2553           case S_XDATA: fprintf (of, "xdata-"); break;
2554           case S_SFR: fprintf (of, "sfr-"); break;
2555           case S_SBIT: fprintf (of, "sbit-"); break;
2556           case S_CODE: fprintf (of, "code-"); break;
2557           case S_IDATA: fprintf (of, "idata-"); break;
2558           case S_PDATA: fprintf (of, "pdata-"); break;
2559           case S_LITERAL: fprintf (of, "literal-"); break;
2560           case S_STACK: fprintf (of, "stack-"); break;
2561           case S_XSTACK: fprintf (of, "xstack-"); break;
2562           case S_BIT: fprintf (of, "bit-"); break;
2563           case S_EEPROM: fprintf (of, "eeprom-"); break;
2564           default: break;
2565           }
2566           if (SPEC_VOLATILE (type))
2567             fprintf (of, "volatile-");
2568           if (SPEC_CONST (type))
2569             fprintf (of, "const-");
2570           if (SPEC_USIGN (type))
2571             fprintf (of, "unsigned-");
2572           switch (SPEC_NOUN (type))
2573             {
2574             case V_INT:
2575               if (IS_LONG (type))
2576                 fprintf (of, "long-");
2577               fprintf (of, "int");
2578               break;
2579
2580             case V_CHAR:
2581               fprintf (of, "char");
2582               break;
2583
2584             case V_VOID:
2585               fprintf (of, "void");
2586               break;
2587
2588             case V_FLOAT:
2589               fprintf (of, "float");
2590               break;
2591
2592             case V_STRUCT:
2593               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2594               break;
2595
2596             case V_SBIT:
2597               fprintf (of, "sbit");
2598               break;
2599
2600             case V_BIT:
2601               fprintf (of, "bit");
2602               break;
2603
2604             case V_BITFIELD:
2605               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2606               break;
2607
2608             case V_DOUBLE:
2609               fprintf (of, "double");
2610               break;
2611
2612             default:
2613               fprintf (of, "unknown type");
2614               break;
2615             }
2616         }
2617       else
2618         fprintf (of, "NOT_SPEC_OR_DECL");
2619       type = type->next;
2620       if (type)
2621         fputc (' ', of);
2622     }
2623   if (nlr)
2624     fprintf (of, "\n");
2625 }
2626
2627
2628 /*-----------------------------------------------------------------*/
2629 /* powof2 - returns power of two for the number if number is pow 2 */
2630 /*-----------------------------------------------------------------*/
2631 int 
2632 powof2 (unsigned long num)
2633 {
2634   int nshifts = 0;
2635   int n1s = 0;
2636
2637   while (num)
2638     {
2639       if (num & 1)
2640         n1s++;
2641       num >>= 1;
2642       nshifts++;
2643     }
2644
2645   if (n1s > 1 || nshifts == 0)
2646     return 0;
2647   return nshifts - 1;
2648 }
2649
2650 symbol *__fsadd;
2651 symbol *__fssub;
2652 symbol *__fsmul;
2653 symbol *__fsdiv;
2654 symbol *__fseq;
2655 symbol *__fsneq;
2656 symbol *__fslt;
2657 symbol *__fslteq;
2658 symbol *__fsgt;
2659 symbol *__fsgteq;
2660
2661 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2662 symbol *__muldiv[3][3][2];
2663 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2664 sym_link *__multypes[3][2];
2665 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2666 symbol *__conv[2][3][2];
2667 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2668 symbol *__rlrr[2][3][2];
2669
2670 sym_link *floatType;
2671
2672 static char *
2673 _mangleFunctionName(char *in)
2674 {
2675   if (port->getMangledFunctionName) 
2676     {
2677       return port->getMangledFunctionName(in);
2678     }
2679   else
2680     {
2681       return in;
2682     }
2683 }
2684
2685 /*-----------------------------------------------------------------*/
2686 /* typeFromStr - create a typechain from an encoded string         */
2687 /* basic types -        'c' - char                                 */
2688 /*                      's' - short                                */
2689 /*                      'i' - int                                  */
2690 /*                      'l' - long                                 */
2691 /*                      'f' - float                                */
2692 /*                      'v' - void                                 */
2693 /*                      '*' - pointer - default (GPOINTER)         */
2694 /* modifiers -          'u' - unsigned                             */
2695 /* pointer modifiers -  'g' - generic                              */
2696 /*                      'x' - xdata                                */
2697 /*                      'p' - code                                 */
2698 /*                      'd' - data                                 */                     
2699 /*                      'F' - function                             */                     
2700 /* examples : "ig*" - generic int *                                */
2701 /*            "cx*" - char xdata *                                 */
2702 /*            "ui" -  unsigned int                                 */
2703 /*-----------------------------------------------------------------*/
2704 sym_link *typeFromStr (char *s)
2705 {
2706     sym_link *r = newLink(DECLARATOR);
2707     int usign = 0;
2708
2709     do {
2710         sym_link *nr;
2711         switch (*s) {
2712         case 'u' : 
2713             usign = 1;
2714             s++;
2715             continue ;
2716             break ;
2717         case 'c':
2718             r->class = SPECIFIER;
2719             SPEC_NOUN(r) = V_CHAR;
2720             break;
2721         case 's':
2722         case 'i':
2723             r->class = SPECIFIER;
2724             SPEC_NOUN(r) = V_INT;
2725             break;
2726         case 'l':
2727             r->class = SPECIFIER;
2728             SPEC_NOUN(r) = V_INT;
2729             SPEC_LONG(r) = 1;
2730             break;
2731         case 'f':
2732             r->class = SPECIFIER;
2733             SPEC_NOUN(r) = V_FLOAT;
2734             break;
2735         case 'v':
2736             r->class = SPECIFIER;
2737             SPEC_NOUN(r) = V_VOID;
2738             break;
2739         case '*':
2740             DCL_TYPE(r) = port->unqualified_pointer;
2741             break;
2742         case 'g':
2743         case 'x':
2744         case 'p':
2745         case 'd':
2746         case 'F':
2747             assert(*(s+1)=='*');
2748             nr = newLink(DECLARATOR);
2749             nr->next = r;
2750             r = nr;
2751             switch (*s) {
2752             case 'g':
2753                 DCL_TYPE(r) = GPOINTER;
2754                 break;
2755             case 'x':
2756                 DCL_TYPE(r) = FPOINTER;
2757                 break;
2758             case 'p':
2759                 DCL_TYPE(r) = CPOINTER;
2760                 break;
2761             case 'd':
2762                 DCL_TYPE(r) = POINTER;
2763                 break;
2764             case 'F':
2765                 DCL_TYPE(r) = FUNCTION;
2766                 nr = newLink(DECLARATOR);
2767                 nr->next = r;
2768                 r = nr;
2769                 DCL_TYPE(r) = CPOINTER;
2770                 break;
2771             }
2772             s++;
2773             break;
2774         default:
2775             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2776                    "typeFromStr: unknown type");
2777             break;
2778         }
2779         if (IS_SPEC(r) && usign) {
2780             SPEC_USIGN(r) = 1;
2781             usign = 0;
2782         }
2783         s++;
2784     } while (*s);
2785     return r;
2786 }
2787
2788 /*-----------------------------------------------------------------*/
2789 /* initCSupport - create functions for C support routines          */
2790 /*-----------------------------------------------------------------*/
2791 void 
2792 initCSupport ()
2793 {
2794   const char *smuldivmod[] =
2795   {
2796     "mul", "div", "mod"
2797   };
2798   const char *sbwd[] =
2799   {
2800     "char", "int", "long"
2801   };
2802   const char *ssu[] =
2803   {
2804     "s", "u"
2805   };
2806   const char *srlrr[] =
2807   {
2808     "rl", "rr"
2809   };
2810
2811   int bwd, su, muldivmod, tofrom, rlrr;
2812
2813   if (getenv("SDCC_NO_C_SUPPORT")) {
2814     /* for debugging only */
2815     return;
2816   }
2817
2818   floatType = newFloatLink ();
2819
2820   for (bwd = 0; bwd < 3; bwd++)
2821     {
2822       sym_link *l = NULL;
2823       switch (bwd)
2824         {
2825         case 0:
2826           l = newCharLink ();
2827           break;
2828         case 1:
2829           l = newIntLink ();
2830           break;
2831         case 2:
2832           l = newLongLink ();
2833           break;
2834         default:
2835           assert (0);
2836         }
2837       __multypes[bwd][0] = l;
2838       __multypes[bwd][1] = copyLinkChain (l);
2839       SPEC_USIGN (__multypes[bwd][1]) = 1;
2840     }
2841
2842   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2843   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2844   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2845   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2846   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2847   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2848   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2849   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2850   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2851   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2852
2853   for (tofrom = 0; tofrom < 2; tofrom++)
2854     {
2855       for (bwd = 0; bwd < 3; bwd++)
2856         {
2857           for (su = 0; su < 2; su++)
2858             {
2859               if (tofrom)
2860                 {
2861                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2862                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2863                 }
2864               else
2865                 {
2866                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2867                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2868                 }
2869             }
2870         }
2871     }
2872
2873 /*
2874   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2875     {
2876       for (bwd = 0; bwd < 3; bwd++)
2877         {
2878           for (su = 0; su < 2; su++)
2879             {
2880               SNPRINTF (buffer, sizeof(buffer),
2881                         "_%s%s%s",
2882                        smuldivmod[muldivmod],
2883                        ssu[su],
2884                        sbwd[bwd]);
2885               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2886               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2887             }
2888         }
2889     }
2890
2891   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2892   Therefore they've been merged into mulint() and mullong().
2893 */
2894
2895   for (bwd = 0; bwd < 3; bwd++)
2896     {
2897       for (su = 0; su < 2; su++)
2898         {
2899           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2900             {
2901               /* div and mod */
2902               SNPRINTF (buffer, sizeof(buffer),
2903                         "_%s%s%s",
2904                        smuldivmod[muldivmod],
2905                        ssu[su],
2906                        sbwd[bwd]);
2907               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2908               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2909             }
2910         }
2911     }
2912   /* mul only */
2913   muldivmod = 0;
2914   /* byte */
2915   bwd = 0;
2916   for (su = 0; su < 2; su++)
2917     {
2918       /* muluchar and mulschar are still separate functions, because e.g. the z80
2919          port is sign/zero-extending to int before calling mulint() */
2920       SNPRINTF (buffer, sizeof(buffer),
2921                 "_%s%s%s",
2922                 smuldivmod[muldivmod],
2923                 ssu[su],
2924                 sbwd[bwd]);
2925       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2926       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2927     }
2928   /* signed only */
2929   su = 0;
2930   /* word and doubleword */
2931   for (bwd = 1; bwd < 3; bwd++)
2932     {
2933       /* mul, int/long */
2934       SNPRINTF (buffer, sizeof(buffer),
2935                 "_%s%s",
2936                 smuldivmod[muldivmod],
2937                 sbwd[bwd]);
2938       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2939       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2940       /* signed = unsigned */
2941       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
2942     }
2943
2944   for (rlrr = 0; rlrr < 2; rlrr++)
2945     {
2946       for (bwd = 0; bwd < 3; bwd++)
2947         {
2948           for (su = 0; su < 2; su++)
2949             {
2950               SNPRINTF (buffer, sizeof(buffer),
2951                         "_%s%s%s",
2952                        srlrr[rlrr],
2953                        ssu[su],
2954                        sbwd[bwd]);
2955               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2956               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2957             }
2958         }
2959     }
2960 }
2961
2962 /*-----------------------------------------------------------------*/
2963 /* initBuiltIns - create prototypes for builtin functions          */
2964 /*-----------------------------------------------------------------*/
2965 void initBuiltIns()
2966 {
2967     int i;
2968     symbol *sym;
2969
2970     if (!port->builtintable) return ;
2971
2972     for (i = 0 ; port->builtintable[i].name ; i++) {
2973         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2974                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2975         FUNC_ISBUILTIN(sym->type) = 1;
2976         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2977     }
2978 }
2979
2980 sym_link *validateLink(sym_link         *l, 
2981                         const char      *macro,
2982                         const char      *args,
2983                         const char      select,
2984                         const char      *file, 
2985                         unsigned        line)
2986 {    
2987   if (l && l->class==select)
2988     {
2989         return l;
2990     }
2991     fprintf(stderr, 
2992             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2993             " expected %s, got %s\n",
2994             macro, args, file, line, 
2995             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2996     exit(-1);
2997     return l; // never reached, makes compiler happy.
2998 }