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