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