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