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