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