* device/lib/z80/mul.s (__mulsuchar_rrx_s, __muluschar_rrx_s),
[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       /* change it to a unsigned bit */
1276       SPEC_NOUN (loop->etype) = V_BITFIELD;
1277       /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
1278       /* a "plain" int bitfield is unsigned */
1279       if (!loop->etype->select.s.b_signed)
1280         SPEC_USIGN(loop->etype) = 1;
1281
1282       if (loop->bitVar == BITVAR_PAD) {
1283         /* A zero length bitfield forces padding */
1284         SPEC_BLEN (loop->etype) = 0;
1285         SPEC_BSTR (loop->etype) = bitOffset;
1286         if (bitOffset > 0)
1287           bitOffset = 8; /* padding is not needed when at bit 0 */
1288         loop->offset = sum;
1289       }
1290       else {
1291         SPEC_BLEN (loop->etype) = loop->bitVar;
1292
1293         if (bitOffset == 8) {
1294           bitOffset = 0;
1295           sum++;
1296         }
1297         /* check if this fit into the remaining   */
1298         /* bits of this byte else align it to the */
1299         /* next byte boundary                     */
1300         if (loop->bitVar <= (8 - bitOffset)) {
1301           /* fits into current byte */
1302           loop->offset = sum;
1303           SPEC_BSTR (loop->etype) = bitOffset;
1304           bitOffset += loop->bitVar;
1305         }
1306         else if (!bitOffset) {
1307           /* does not fit, but is already byte aligned */
1308           loop->offset = sum;
1309           SPEC_BSTR (loop->etype) = bitOffset;
1310           bitOffset += loop->bitVar;
1311         }
1312         else {
1313           if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
1314             /* if PIC16 && enviroment variable is set, then
1315              * tightly pack bitfields, this means that when a
1316              * bitfield goes beyond byte alignment, do not
1317              * automatically start allocatint from next byte,
1318              * but also use the available bits first */
1319             fprintf(stderr, ": packing bitfields in structures\n");
1320             SPEC_BSTR (loop->etype) = bitOffset;
1321             bitOffset += loop->bitVar;
1322             loop->offset = (su == UNION ? sum = 0 : sum);
1323           } else {
1324             /* does not fit; need to realign first */
1325             sum++;
1326             loop->offset = (su == UNION ? sum = 0 : sum);
1327             bitOffset = 0;
1328             SPEC_BSTR (loop->etype) = bitOffset;
1329             bitOffset += loop->bitVar;
1330           }
1331         }
1332         while (bitOffset>8) {
1333           bitOffset -= 8;
1334           sum++;
1335         }
1336       }
1337     }
1338     else {
1339       /* This is a non-bit field. Make sure we are */
1340       /* byte aligned first */
1341       if (bitOffset) {
1342         sum++;
1343         loop->offset = (su == UNION ? sum = 0 : sum);
1344         bitOffset = 0;
1345       }
1346       loop->offset = sum;
1347       checkDecl (loop, 1);
1348       sum += getSize (loop->type);
1349
1350       /* search for "flexibel array members" */
1351       /* and do some syntax checks */
1352       if (   su == STRUCT
1353           && checkStructFlexArray (loop, loop->type))
1354         {
1355           /* found a "flexible array member" */
1356           sdef->b_flexArrayMember = TRUE;
1357           /* is another struct-member following? */
1358           if (loop->next)
1359             werror (E_FLEXARRAY_NOTATEND);
1360           /* is it the first struct-member? */
1361           else if (loop == sdef->fields)
1362             werror (E_FLEXARRAY_INEMPTYSTRCT);
1363         }
1364     }
1365
1366     loop = loop->next;
1367
1368     /* if union then size = sizeof largest field */
1369     if (su == UNION) {
1370       /* For UNION, round up after each field */
1371       sum += ((bitOffset+7)/8);
1372       usum = max (usum, sum);
1373     }
1374
1375   }
1376
1377   /* For STRUCT, round up after all fields processed */
1378   if (su != UNION)
1379     sum += ((bitOffset+7)/8);
1380
1381   return (su == UNION ? usum : sum);
1382 }
1383
1384 /*-------------------------------------------------------------------*/
1385 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1386 /*                      an enclosing struct/union                    */
1387 /*-------------------------------------------------------------------*/
1388 void
1389 promoteAnonStructs (int su, structdef * sdef)
1390 {
1391   symbol *field;
1392   symbol *subfield;
1393   symbol **tofield;
1394   symbol *nextfield;
1395   symbol *dupfield;
1396   int base;
1397
1398   tofield = &sdef->fields;
1399   field = sdef->fields;
1400   while (field)
1401     {
1402       nextfield = field->next;
1403       if (!*field->name && IS_STRUCT (field->type))
1404         {
1405           /* Found an anonymous struct/union. Replace it */
1406           /* with the fields it contains and adjust all  */
1407           /* the offsets */
1408
1409           base = field->offset;
1410           subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1411           if (!subfield)
1412             continue;           /* just in case it's empty */
1413
1414           *tofield = subfield;
1415           for (;;)
1416             {
1417               /* check for field name conflicts resulting from promotion */
1418               dupfield = sdef->fields;
1419               while (dupfield && dupfield != subfield)
1420                 {
1421                   if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1422                     {
1423                       werrorfl (subfield->fileDef, subfield->lineDef,
1424                                 E_DUPLICATE_MEMBER,
1425                                 su==STRUCT ? "struct" : "union",
1426                                 subfield->name);
1427                       werrorfl (dupfield->fileDef, dupfield->lineDef,
1428                                 E_PREVIOUS_DEF);
1429                     }
1430                   dupfield = dupfield->next;
1431                 }
1432
1433               subfield->offset += base;
1434               if (subfield->next)
1435                 subfield = subfield->next;
1436               else
1437                 break;
1438             }
1439           subfield->next = nextfield;
1440           tofield = &subfield->next;
1441         }
1442       else
1443         tofield = &field->next;
1444       field = nextfield;
1445     }
1446 }
1447
1448
1449 /*------------------------------------------------------------------*/
1450 /* checkSClass - check the storage class specification              */
1451 /*------------------------------------------------------------------*/
1452 static void
1453 checkSClass (symbol * sym, int isProto)
1454 {
1455   sym_link *t;
1456
1457   if (getenv("DEBUG_SANITY")) {
1458     fprintf (stderr, "checkSClass: %s \n", sym->name);
1459   }
1460
1461   /* type is literal can happen for enums change to auto */
1462   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1463     SPEC_SCLS (sym->etype) = S_AUTO;
1464
1465   /* if sfr or sbit then must also be volatile */
1466   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1467       SPEC_SCLS (sym->etype) == S_SFR)
1468     {
1469       SPEC_VOLATILE (sym->etype) = 1;
1470     }
1471
1472   /* make sure restrict is only used with pointers */
1473   if (SPEC_RESTRICT (sym->etype))
1474     {
1475       werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1476       SPEC_RESTRICT (sym->etype) = 0;
1477     }
1478   t = sym->type;
1479   while (t)
1480     {
1481       if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !IS_PTR (t))
1482         {
1483           werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1484           DCL_PTR_RESTRICT (t) = 0;
1485           break;
1486         }
1487       t = t->next;
1488     }
1489
1490   /* if absolute address given then it mark it as
1491      volatile -- except in the PIC port */
1492
1493 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1494   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1495   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1496 #endif
1497
1498     if (IS_ABSOLUTE (sym->etype))
1499       SPEC_VOLATILE (sym->etype) = 1;
1500
1501   if (TARGET_IS_MCS51 &&
1502       IS_ABSOLUTE (sym->etype) &&
1503       SPEC_SCLS (sym->etype) == S_SFR)
1504     {
1505       int n, size;
1506       unsigned addr;
1507
1508       if (SPEC_NOUN (sym->etype) == V_CHAR)
1509         size = 8;
1510       else if (SPEC_LONG (sym->etype) == 0)
1511         size = 16;
1512       else
1513         size = 32;
1514
1515       addr = SPEC_ADDR (sym->etype);
1516       for (n=0; n<size; n+=8)
1517         if (((addr >> n) & 0xFF) < 0x80)
1518           werror (W_SFR_ABSRANGE, sym->name);
1519     }
1520
1521   /* If code memory is read only, then pointers to code memory */
1522   /* implicitly point to constants -- make this explicit       */
1523   t = sym->type;
1524   while (t && t->next) {
1525     if (IS_CODEPTR(t) && port->mem.code_ro) {
1526       if (IS_SPEC(t->next)) {
1527         SPEC_CONST (t->next) = 1;
1528       } else {
1529         DCL_PTR_CONST (t->next) = 1;
1530       }
1531     }
1532     t = t->next;
1533   }
1534
1535   /* global variables declared const put into code */
1536   /* if no other storage class specified */
1537   if (sym->level == 0 &&
1538       SPEC_SCLS(sym->etype) == S_FIXED &&
1539       !IS_FUNC(sym->type)) {
1540     /* find the first non-array link */
1541     t = sym->type;
1542     while (IS_ARRAY(t))
1543       t = t->next;
1544     if (IS_CONSTANT (t)) {
1545       SPEC_SCLS (sym->etype) = S_CODE;
1546     }
1547   }
1548
1549   /* global variable in code space is a constant */
1550   if (sym->level == 0 &&
1551       SPEC_SCLS (sym->etype) == S_CODE &&
1552       port->mem.code_ro) {
1553     /* find the first non-array link */
1554     t = sym->type;
1555     while (IS_ARRAY(t))
1556       t = t->next;
1557     if (IS_SPEC(t)) {
1558       SPEC_CONST (t) = 1;
1559     } else {
1560       DCL_PTR_CONST (t) = 1;
1561     }
1562   }
1563
1564   /* if bit variable then no storage class can be */
1565   /* specified since bit is already a storage */
1566   if (IS_BITVAR (sym->etype) &&
1567       (SPEC_SCLS (sym->etype) != S_FIXED &&
1568        SPEC_SCLS (sym->etype) != S_SBIT &&
1569        SPEC_SCLS (sym->etype) != S_BIT)
1570     )
1571     {
1572       werror (E_BITVAR_STORAGE, sym->name);
1573       SPEC_SCLS (sym->etype) = S_FIXED;
1574     }
1575
1576   /* extern variables cannot be initialized */
1577   if (IS_EXTERN (sym->etype) && sym->ival)
1578     {
1579       werror (E_EXTERN_INIT, sym->name);
1580       sym->ival = NULL;
1581     }
1582
1583   /* if this is an automatic symbol */
1584   if (sym->level && (options.stackAuto || reentrant)) {
1585     if (SPEC_SCLS (sym->etype) != S_BIT) {
1586       if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1587            SPEC_SCLS (sym->etype) == S_FIXED ||
1588            SPEC_SCLS (sym->etype) == S_REGISTER ||
1589            SPEC_SCLS (sym->etype) == S_STACK ||
1590            SPEC_SCLS (sym->etype) == S_XSTACK)) {
1591         SPEC_SCLS (sym->etype) = S_AUTO;
1592       } else {
1593         /* storage class may only be specified for statics */
1594         if (!IS_STATIC(sym->etype)) {
1595           werror (E_AUTO_ASSUMED, sym->name);
1596         }
1597       }
1598     }
1599   }
1600
1601   /* automatic symbols cannot be given   */
1602   /* an absolute address ignore it      */
1603   if (sym->level && !IS_STATIC(sym->etype) &&
1604       SPEC_ABSA (sym->etype) &&
1605       (options.stackAuto || reentrant))
1606     {
1607       werror (E_AUTO_ABSA, sym->name);
1608       SPEC_ABSA (sym->etype) = 0;
1609     }
1610
1611   /* arrays & pointers cannot be defined for bits   */
1612   /* SBITS or SFRs or BIT                           */
1613   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1614       !IS_FUNCPTR (sym->type) &&
1615       (SPEC_NOUN (sym->etype) == V_BIT ||
1616        SPEC_NOUN (sym->etype) == V_SBIT ||
1617        SPEC_NOUN (sym->etype) == V_BITFIELD ||
1618        SPEC_SCLS (sym->etype) == S_SFR))
1619     werror (E_BIT_ARRAY, sym->name);
1620
1621   /* if this is a bit|sbit then set length & start  */
1622   if (SPEC_NOUN (sym->etype) == V_BIT ||
1623       SPEC_NOUN (sym->etype) == V_SBIT)
1624     {
1625       SPEC_BLEN (sym->etype) = 1;
1626       SPEC_BSTR (sym->etype) = 0;
1627     }
1628
1629   if (!isProto) {
1630     /* variables declared in CODE space must have */
1631     /* initializers if not an extern */
1632     if (SPEC_SCLS (sym->etype) == S_CODE &&
1633         sym->ival == NULL &&
1634         !sym->_isparm &&
1635         //!sym->level &&
1636         port->mem.code_ro &&
1637         !IS_EXTERN (sym->etype) &&
1638         !SPEC_ABSA (sym->etype) &&
1639         !funcInChain (sym->type))
1640       werror (E_CODE_NO_INIT, sym->name);
1641   }
1642
1643   /* if parameter or local variable then change */
1644   /* the storage class to reflect where the var will go */
1645   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
1646    && !IS_STATIC(sym->etype)
1647       )
1648     {
1649       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1650         {
1651           SPEC_SCLS (sym->etype) = (options.useXstack ?
1652                                     S_XSTACK : S_STACK);
1653         }
1654       else
1655         {
1656           /* hack-o-matic! I see no reason why the useXstack option should ever
1657            * control this allocation, but the code was originally that way, and
1658            * changing it for non-390 ports breaks the compiler badly.
1659            */
1660           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ?
1661                 1 : options.useXstack;
1662           SPEC_SCLS (sym->etype) = (useXdata ?
1663                                     S_XDATA : S_FIXED);
1664         }
1665     }
1666 }
1667
1668 /*------------------------------------------------------------------*/
1669 /* changePointer - change pointer to functions                      */
1670 /*------------------------------------------------------------------*/
1671 void
1672 changePointer (sym_link * p)
1673 {
1674
1675   /* go thru the chain of declarations   */
1676   /* if we find a pointer to a function  */
1677   /* change it to a ptr to code area     */
1678   /* unless the function is banked.      */
1679   for (; p; p = p->next)
1680     {
1681       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1682         DCL_TYPE (p) = port->unqualified_pointer;
1683       if (IS_PTR (p) && IS_FUNC (p->next))
1684         if (!IFFUNC_BANKED(p->next))
1685         DCL_TYPE (p) = CPOINTER;
1686     }
1687 }
1688
1689 /*------------------------------------------------------------------*/
1690 /* checkDecl - does semantic validation of a declaration            */
1691 /*------------------------------------------------------------------*/
1692 int
1693 checkDecl (symbol * sym, int isProto)
1694 {
1695
1696   checkSClass (sym, isProto);        /* check the storage class     */
1697   changePointer (sym->type);         /* change pointers if required */
1698
1699   /* if this is an array without any dimension
1700      then update the dimension from the initial value */
1701   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1702     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1703
1704   return 0;
1705 }
1706
1707 /*------------------------------------------------------------------*/
1708 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1709 /*------------------------------------------------------------------*/
1710 sym_link *
1711 copyLinkChain (sym_link * p)
1712 {
1713   sym_link *head, *curr, *loop;
1714
1715   /* note: v_struct and v_struct->fields are not copied! */
1716   curr = p;
1717   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1718   while (curr)
1719     {
1720       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1721       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1722       loop = loop->next;
1723       curr = curr->next;
1724     }
1725
1726   return head;
1727 }
1728
1729 /*------------------------------------------------------------------*/
1730 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1731 /*                symbols in the given block                        */
1732 /*------------------------------------------------------------------*/
1733 void
1734 cleanUpBlock (bucket ** table, int block)
1735 {
1736   int i;
1737   bucket *chain;
1738
1739   /* go thru the entire  table  */
1740   for (i = 0; i < 256; i++)
1741     {
1742       for (chain = table[i]; chain; chain = chain->next)
1743         {
1744           if (chain->block >= block)
1745             {
1746               deleteSym (table, chain->sym, chain->name);
1747             }
1748         }
1749     }
1750 }
1751
1752 /*------------------------------------------------------------------*/
1753 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1754 /*                symbols in the given level                        */
1755 /*------------------------------------------------------------------*/
1756 void
1757 cleanUpLevel (bucket ** table, int level)
1758 {
1759   int i;
1760   bucket *chain;
1761
1762   /* go thru the entire  table  */
1763   for (i = 0; i < 256; i++)
1764     {
1765       for (chain = table[i]; chain; chain = chain->next)
1766         {
1767           if (chain->level >= level)
1768             {
1769               deleteSym (table, chain->sym, chain->name);
1770             }
1771         }
1772     }
1773 }
1774
1775 /*------------------------------------------------------------------*/
1776 /* computeTypeOr - computes the resultant type from two types       */
1777 /*------------------------------------------------------------------*/
1778 static sym_link *
1779 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1780 {
1781   /* sanity check */
1782   assert (   (IS_CHAR (etype1) || IS_BIT (etype1))
1783           && (IS_CHAR (etype2) || IS_BIT (etype2)));
1784
1785   if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1786     {
1787       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1788       return reType;
1789     }
1790
1791   if (SPEC_USIGN (etype1))
1792     {
1793       if (   IS_LITERAL (etype2)
1794           && floatFromVal (valFromType (etype2)) >= 0)
1795         SPEC_USIGN (reType) = 1;
1796       else
1797         {
1798           /* promote to int */
1799           SPEC_USIGN (reType) = 0;
1800           SPEC_NOUN (reType) = V_INT;
1801         }
1802     }
1803   else /* etype1 signed */
1804     {
1805       if (   IS_LITERAL (etype2)
1806           && floatFromVal (valFromType (etype2)) <= 127)
1807         SPEC_USIGN (reType) = 0;
1808       else
1809         {
1810           /* promote to int */
1811           SPEC_USIGN (reType) = 0;
1812           SPEC_NOUN (reType) = V_INT;
1813         }
1814     }
1815
1816   if (SPEC_USIGN (etype2))
1817     {
1818       if (   IS_LITERAL (etype1)
1819           && floatFromVal (valFromType (etype1)) >= 0)
1820         SPEC_USIGN (reType) = 1;
1821       else
1822         {
1823           /* promote to int */
1824           SPEC_USIGN (reType) = 0;
1825           SPEC_NOUN (reType) = V_INT;
1826         }
1827     }
1828   else /* etype2 signed */
1829     {
1830       if (   IS_LITERAL (etype1)
1831           && floatFromVal (valFromType (etype1)) <= 127)
1832         SPEC_USIGN (reType) = 0;
1833       else
1834         {
1835           /* promote to int */
1836           SPEC_USIGN (reType) = 0;
1837           SPEC_NOUN (reType) = V_INT;
1838         }
1839     }
1840   return reType;
1841 }
1842
1843 /*------------------------------------------------------------------*/
1844 /* computeType - computes the resultant type from two types         */
1845 /*------------------------------------------------------------------*/
1846 sym_link *
1847 computeType (sym_link * type1, sym_link * type2,
1848              RESULT_TYPE resultType, int op)
1849 {
1850   sym_link *rType;
1851   sym_link *reType;
1852   sym_link *etype1 = getSpec (type1);
1853   sym_link *etype2;
1854
1855   etype2 = type2 ? getSpec (type2) : type1;
1856
1857   /* if one of them is a float then result is a float */
1858   /* here we assume that the types passed are okay */
1859   /* and can be cast to one another                */
1860   /* which ever is greater in size */
1861   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1862     rType = newFloatLink ();
1863   /* if both are fixed16x16 then result is float */
1864   else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
1865     rType = newFixed16x16Link();
1866   else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
1867     rType = newFloatLink ();
1868   else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
1869     rType = newFloatLink ();
1870
1871   /* if both are bitvars choose the larger one */
1872   else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1873     rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1874             copyLinkChain (type1) : copyLinkChain (type2);
1875
1876   /* if only one of them is a bit variable then the other one prevails */
1877   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1878     {
1879       rType = copyLinkChain (type2);
1880       /* bitfield can have up to 16 bits */
1881       if (getSize (etype1) > 1)
1882         SPEC_NOUN (getSpec (rType)) = V_INT;
1883     }
1884   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1885     {
1886       rType = copyLinkChain (type1);
1887       /* bitfield can have up to 16 bits */
1888       if (getSize (etype2) > 1)
1889         SPEC_NOUN (getSpec (rType)) = V_INT;
1890     }
1891   /* if one of them is a pointer or array then that
1892      prevails */
1893   else if (IS_PTR (type1) || IS_ARRAY (type1))
1894     rType = copyLinkChain (type1);
1895   else if (IS_PTR (type2) || IS_ARRAY (type2))
1896     rType = copyLinkChain (type2);
1897   else if (getSize (type1) > getSize (type2))
1898     rType = copyLinkChain (type1);
1899   else
1900     rType = copyLinkChain (type2);
1901
1902   reType = getSpec (rType);
1903
1904   /* avoid conflicting types */
1905   reType->select.s.b_signed = 0;
1906
1907   /* if result is a literal then make not so */
1908   if (IS_LITERAL (reType))
1909     SPEC_SCLS (reType) = S_REGISTER;
1910
1911   switch (resultType)
1912     {
1913       case RESULT_TYPE_IFX:
1914         if (TARGET_IS_HC08)
1915           break;
1916         //fallthrough
1917       case RESULT_TYPE_BIT:
1918         if (op == ':')
1919           {
1920             SPEC_NOUN (reType) = V_BIT;
1921             return rType;
1922           }
1923         break;
1924       case RESULT_TYPE_CHAR:
1925         if (IS_BITVAR (reType))
1926           {
1927             SPEC_NOUN (reType) = V_CHAR;
1928             SPEC_SCLS (reType) = 0;
1929             SPEC_USIGN (reType) = 0;
1930             return rType;
1931           }
1932         break;
1933       case RESULT_TYPE_INT:
1934       case RESULT_TYPE_NONE:
1935       case RESULT_TYPE_OTHER:
1936         if (IS_BIT (reType))
1937           {
1938             SPEC_NOUN (reType) = V_CHAR;
1939             SPEC_SCLS (reType) = 0;
1940             SPEC_USIGN (reType) = 0;
1941             return rType;
1942           }
1943         else if (IS_BITFIELD (reType))
1944           {
1945             /* could be smarter, but it depends on the op */
1946             /* this is for the worst case: a multiplication of 4 * 4 bit */
1947             SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1948             SPEC_SCLS (reType) = 0;
1949             SPEC_USIGN (reType) = 0;
1950             return rType;
1951           }
1952         else if (IS_CHAR (reType))
1953           {
1954             /* promotion of some special cases */
1955             switch (op)
1956               {
1957                 case '|':
1958                 case '^':
1959                   return computeTypeOr (etype1, etype2, reType);
1960                 case '&':
1961                   if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1962                     {
1963                       SPEC_USIGN (reType) = 1;
1964                       return rType;
1965                     }
1966                   break;
1967                 case '*':
1968                   SPEC_NOUN (reType) = V_INT;
1969                   SPEC_USIGN (reType) = 0;
1970                   return rType;
1971                 case '/':
1972                   /* if both are unsigned char then no promotion required */
1973                   if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
1974                     {
1975                       SPEC_NOUN (reType) = V_INT;
1976                       SPEC_USIGN (reType) = 0;
1977                       return rType;
1978                     }
1979                   break;
1980                 default:
1981                   break;
1982               }
1983           }
1984         break;
1985       default:
1986         break;
1987     }
1988
1989   /* SDCC's sign promotion:
1990      - if one or both operands are unsigned, the resultant type will be unsigned
1991        (except char, see below)
1992      - if an operand is promoted to a larger type (char -> int, int -> long),
1993        the larger type will be signed
1994
1995      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1996      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1997      the standard. The standard demands, that the result has to be the same
1998      "as if" the promotion would have been performed:
1999
2000      - if the result of an operation with two char's is promoted to a
2001        larger type, the result will be signed.
2002
2003      More sophisticated are these:
2004      - if the result of an operation with two char's is a char again,
2005        the result will only then be unsigned, if both operands are
2006        unsigned. In all other cases the result will be signed.
2007
2008        This seems to be contradictionary to the first two rules, but it makes
2009        real sense (all types are char's):
2010
2011         A signed char can be negative; this must be preserved in the result
2012                 -1 * 100 = -100;
2013
2014         Only if both operands are unsigned it's safe to make the result
2015         unsigned; this helps to avoid overflow:
2016                 2 * 100 =  200;
2017
2018      - ToDo: document '|', '^' and '&'
2019
2020      Homework: - why is (200 * 200 < 0) true?
2021                - why is { char l = 200, r = 200; (r * l > 0) } true?
2022   */
2023
2024   if (!IS_FLOAT (reType)
2025       && (   (SPEC_USIGN (etype1)
2026               /* if this operand is promoted to a larger type,
2027                  then it will be promoted to a signed type */
2028               && !(bitsForType (etype1) < bitsForType (reType))
2029               /* char require special handling */
2030               && !IS_CHAR (etype1))
2031           || /* same for 2nd operand */
2032              (SPEC_USIGN (etype2)
2033               && !(bitsForType (etype2) < bitsForType (reType))
2034               && !IS_CHAR (etype2))
2035           || /* if both are 'unsigned char' and not promoted
2036                 let the result be unsigned too */
2037              (   SPEC_USIGN (etype1)
2038               && SPEC_USIGN (etype2)
2039               && IS_CHAR (etype1)
2040               && IS_CHAR (etype2)
2041               && IS_CHAR (reType))))
2042     SPEC_USIGN (reType) = 1;
2043   else
2044     SPEC_USIGN (reType) = 0;
2045
2046   return rType;
2047 }
2048
2049 int
2050 comparePtrType (sym_link * dest, sym_link * src, bool bMustCast)
2051 {
2052   int res;
2053
2054   if (IS_VOID (src->next) && IS_VOID (dest->next))
2055     return bMustCast ? -1 : 1;
2056   if ((IS_VOID (src->next) && !IS_VOID (dest->next)) ||
2057       (!IS_VOID (src->next) && IS_VOID (dest->next)) )
2058     return -1;
2059   res = compareType (dest->next, src->next);
2060   if (res == 1)
2061     return bMustCast ? -1 : 1;
2062   else if (res == -2)
2063     return -2;
2064   else
2065     return 0;
2066 }
2067
2068 /*--------------------------------------------------------------------*/
2069 /* compareType - will do type check return 1 if match, 0 if no match, */
2070 /*               -1 if castable, -2 if only signedness differs        */
2071 /*--------------------------------------------------------------------*/
2072 int
2073 compareType (sym_link * dest, sym_link * src)
2074 {
2075   if (!dest && !src)
2076     return 1;
2077
2078   if (dest && !src)
2079     return 0;
2080
2081   if (src && !dest)
2082     return 0;
2083
2084   /* if dest is a declarator then */
2085   if (IS_DECL (dest))
2086     {
2087       if (IS_DECL (src))
2088         {
2089           /* banked function pointer */
2090           if (IS_GENPTR (dest) && IS_GENPTR (src))
2091             {
2092               if (IS_FUNC (src->next) && IS_VOID(dest->next))
2093                 return -1;
2094               if (IS_FUNC (dest->next) && IS_VOID(src->next))
2095                 return -1;
2096               return comparePtrType(dest, src, FALSE);
2097             }
2098
2099           if (DCL_TYPE (src) == DCL_TYPE (dest))
2100             {
2101               if (IS_FUNC(src))
2102                 {
2103                   //checkFunction(src,dest);
2104                 }
2105               return comparePtrType(dest, src, FALSE);
2106             }
2107           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
2108             {
2109               return -1;
2110             }
2111           if (IS_PTR (src) &&
2112               (IS_GENPTR (dest) ||
2113                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
2114              ))
2115             {
2116               return comparePtrType(dest, src, TRUE);
2117             }
2118           if (IS_PTR (dest) && IS_ARRAY (src))
2119             {
2120               value *val=aggregateToPointer (valFromType(src));
2121               int res=compareType (dest, val->type);
2122               Safe_free(val->type);
2123               Safe_free(val);
2124               return res;
2125             }
2126           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2127             return compareType (dest->next, src);
2128           return 0;
2129         }
2130       else if (IS_PTR (dest) && IS_INTEGRAL (src))
2131         return -1;
2132       else
2133         return 0;
2134     }
2135
2136   if (IS_PTR (src) && IS_VOID (dest))
2137     return -1;
2138
2139   /* if one is a specifier and the other is not */
2140   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2141       (IS_SPEC (dest) && !IS_SPEC (src)))
2142     return 0;
2143
2144   /* if one of them is a void then ok */
2145   if (SPEC_NOUN (dest) == V_VOID &&
2146       SPEC_NOUN (src) != V_VOID)
2147     return -1;
2148
2149   if (SPEC_NOUN (dest) != V_VOID &&
2150       SPEC_NOUN (src) == V_VOID)
2151     return -1;
2152
2153   /* if they are both bitfields then if the lengths
2154      and starts don't match */
2155   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2156       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2157        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2158     return -1;
2159
2160   /* it is a specifier */
2161   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2162     {
2163       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
2164           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2165           /* I would prefer
2166           bitsForType (dest) == bitsForType (src))
2167              instead of the next two lines, but the regression tests fail with
2168              them; I guess it's a problem with replaceCheaperOp  */
2169           getSize (dest) == getSize (src) &&
2170           (IS_BIT (dest) == IS_BIT (src)))
2171         return 1;
2172       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2173         return -1;
2174       else
2175         return 0;
2176     }
2177   else if (IS_STRUCT (dest))
2178     {
2179       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2180         return 0;
2181       else
2182         return 1;
2183     }
2184   if (SPEC_LONG (dest) != SPEC_LONG (src))
2185     return -1;
2186
2187   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2188     return -2;
2189
2190   return 1;
2191 }
2192
2193 /*--------------------------------------------------------------------*/
2194 /* compareTypeExact - will do type check return 1 if match exactly    */
2195 /*--------------------------------------------------------------------*/
2196 int
2197 compareTypeExact (sym_link * dest, sym_link * src, int level)
2198 {
2199   STORAGE_CLASS srcScls, destScls;
2200
2201   if (!dest && !src)
2202     return 1;
2203
2204   if (dest && !src)
2205     return 0;
2206
2207   if (src && !dest)
2208     return 0;
2209
2210   /* if dest is a declarator then */
2211   if (IS_DECL (dest))
2212     {
2213       if (IS_DECL (src))
2214         {
2215           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2216             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2217               return 0;
2218             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2219               return 0;
2220             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2221               return 0;
2222             if (IS_FUNC(src))
2223               {
2224                 value *exargs, *acargs, *checkValue;
2225
2226                 /* verify function return type */
2227                 if (!compareTypeExact (dest->next, src->next, -1))
2228                   return 0;
2229                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2230                   return 0;
2231                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2232                   return 0;
2233                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2234                   return 0;
2235                 #if 0
2236                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2237                   return 0;
2238                 #endif
2239
2240                 /* compare expected args with actual args */
2241                 exargs = FUNC_ARGS(dest);
2242                 acargs = FUNC_ARGS(src);
2243
2244                 /* for all the expected args do */
2245                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2246                   {
2247                     //checkTypeSanity(acargs->etype, acargs->name);
2248
2249                     if (IS_AGGREGATE (acargs->type))
2250                       {
2251                         checkValue = copyValue (acargs);
2252                         aggregateToPointer (checkValue);
2253                       }
2254                     else
2255                       checkValue = acargs;
2256
2257                     #if 0
2258                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
2259                       return 0;
2260                     #endif
2261                   }
2262
2263                   /* if one them ended we have a problem */
2264                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2265                       (!exargs && acargs && !IS_VOID (acargs->type)))
2266                     return 0;
2267                   return 1;
2268               }
2269             return compareTypeExact (dest->next, src->next, level);
2270           }
2271           return 0;
2272         }
2273       return 0;
2274     }
2275
2276   /* if one is a specifier and the other is not */
2277   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2278       (IS_SPEC (dest) && !IS_SPEC (src)))
2279     return 0;
2280
2281   /* if one of them is a void then ok */
2282   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2283     return 0;
2284
2285   /* if they are both bitfields then if the lengths
2286      and starts don't match */
2287   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2288       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2289        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2290     return 0;
2291
2292   if (IS_INTEGRAL (dest))
2293     {
2294       /* signedness must match */
2295       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2296         return 0;
2297       /* size must match */
2298       if (SPEC_LONG (dest) != SPEC_LONG (src))
2299         return 0;
2300       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2301         return 0;
2302     }
2303
2304   if (IS_STRUCT (dest))
2305     {
2306       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2307         return 0;
2308     }
2309
2310   if (SPEC_CONST (dest) != SPEC_CONST (src))
2311     return 0;
2312   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2313     return 0;
2314   if (SPEC_STAT (dest) != SPEC_STAT (src))
2315     return 0;
2316   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2317     return 0;
2318   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2319     return 0;
2320
2321   destScls = SPEC_SCLS (dest);
2322   srcScls = SPEC_SCLS (src);
2323
2324   /* Compensate for const to const code change in checkSClass() */
2325   if (!level & port->mem.code_ro && SPEC_CONST (dest))
2326     {
2327       if (srcScls == S_CODE && destScls == S_FIXED)
2328         destScls = S_CODE;
2329       if (destScls == S_CODE && srcScls == S_FIXED)
2330         srcScls = S_CODE;
2331     }
2332
2333   /* compensate for allocGlobal() */
2334   if ((srcScls == S_FIXED || srcScls == S_AUTO)
2335       && port->mem.default_globl_map == xdata
2336       && !level)
2337     srcScls = S_XDATA;
2338
2339   if (level>0 && !SPEC_STAT (dest))
2340     {
2341       /* Compensate for hack-o-matic in checkSClass() */
2342       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2343         {
2344           if (destScls == S_FIXED)
2345             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2346           if (srcScls == S_FIXED)
2347             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2348         }
2349       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2350         {
2351           if (destScls == S_FIXED)
2352             destScls = S_XDATA;
2353           if (srcScls == S_FIXED)
2354             srcScls = S_XDATA;
2355         }
2356     }
2357
2358   if (srcScls != destScls)
2359     {
2360       #if 0
2361       printf ("level = %d\n", level);
2362       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2363                 SPEC_SCLS (src), SPEC_SCLS (dest));
2364       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2365       #endif
2366       return 0;
2367     }
2368
2369   return 1;
2370 }
2371
2372 /*------------------------------------------------------------------*/
2373 /* inCalleeSaveList - return 1 if found in callee save list         */
2374 /*------------------------------------------------------------------*/
2375 static int
2376 calleeCmp(void *p1, void *p2)
2377 {
2378   return (strcmp((char *)p1, (char *)(p2)) == 0);
2379 }
2380
2381 bool
2382 inCalleeSaveList(char *s)
2383 {
2384   if (options.all_callee_saves)
2385     return 1;
2386   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2387 }
2388
2389 /*-----------------------------------------------------------------*/
2390 /* aggregateToPointer:     change an aggregate type function       */
2391 /*                         argument to a pointer to that type.     */
2392 /*-----------------------------------------------------------------*/
2393 value *
2394 aggregateToPointer (value * val)
2395 {
2396   if (IS_AGGREGATE (val->type))
2397     {
2398       /* if this is a structure */
2399       /* then we need to add a new link */
2400       if (IS_STRUCT (val->type))
2401         {
2402           /* first lets add DECLARATOR type */
2403           sym_link *p = val->type;
2404
2405           werror (W_STRUCT_AS_ARG, val->name);
2406           val->type = newLink (DECLARATOR);
2407           val->type->next = p;
2408         }
2409
2410       /* change to a pointer depending on the */
2411       /* storage class specified        */
2412       switch (SPEC_SCLS (val->etype))
2413         {
2414         case S_IDATA:
2415           DCL_TYPE (val->type) = IPOINTER;
2416           break;
2417         case S_PDATA:
2418           DCL_TYPE (val->type) = PPOINTER;
2419           break;
2420         case S_FIXED:
2421           if (SPEC_OCLS(val->etype)) {
2422             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2423           } else {
2424             // this happens for (external) function parameters
2425             DCL_TYPE (val->type) = port->unqualified_pointer;
2426           }
2427           break;
2428         case S_AUTO:
2429           DCL_TYPE (val->type) = PTR_TYPE(SPEC_OCLS(val->etype));
2430           break;
2431         case S_DATA:
2432         case S_REGISTER:
2433           DCL_TYPE (val->type) = POINTER;
2434           break;
2435         case S_CODE:
2436           DCL_TYPE (val->type) = CPOINTER;
2437           break;
2438         case S_XDATA:
2439           DCL_TYPE (val->type) = FPOINTER;
2440           break;
2441         case S_EEPROM:
2442           DCL_TYPE (val->type) = EEPPOINTER;
2443           break;
2444         default:
2445           DCL_TYPE (val->type) = port->unqualified_pointer;
2446         }
2447
2448       /* is there is a symbol associated then */
2449       /* change the type of the symbol as well */
2450       if (val->sym)
2451         {
2452           val->sym->type = copyLinkChain (val->type);
2453           val->sym->etype = getSpec (val->sym->type);
2454         }
2455     }
2456   return val;
2457 }
2458 /*------------------------------------------------------------------*/
2459 /* checkFunction - does all kinds of check on a function            */
2460 /*------------------------------------------------------------------*/
2461 int
2462 checkFunction (symbol * sym, symbol *csym)
2463 {
2464   value *exargs, *acargs;
2465   value *checkValue;
2466   int argCnt = 0;
2467
2468   if (getenv("DEBUG_SANITY")) {
2469     fprintf (stderr, "checkFunction: %s ", sym->name);
2470   }
2471
2472   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2473     {
2474       werror(E_SYNTAX_ERROR, sym->name);
2475       return 0;
2476     }
2477
2478   /* move inline specifier from return type to function attributes */
2479   if (IS_INLINE (sym->etype))
2480     {
2481       SPEC_INLINE (sym->etype) = 0;
2482       FUNC_ISINLINE (sym->type) = 1;
2483     }
2484
2485   /* make sure the type is complete and sane */
2486   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2487
2488   /* if not type then some kind of error */
2489   if (!sym->type)
2490     return 0;
2491
2492   /* if the function has no type then make it return int */
2493   if (!sym->type->next)
2494     sym->type->next = sym->etype = newIntLink ();
2495
2496   /* function cannot return aggregate */
2497   if (IS_AGGREGATE (sym->type->next))
2498     {
2499       werror (E_FUNC_AGGR, sym->name);
2500       return 0;
2501     }
2502
2503   /* check if this function is defined as calleeSaves
2504      then mark it as such */
2505   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2506
2507   /* if interrupt service routine  */
2508   /* then it cannot have arguments */
2509   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2510     {
2511       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2512         werror (E_INT_ARGS, sym->name);
2513         FUNC_ARGS(sym->type)=NULL;
2514       }
2515     }
2516
2517   if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2518     {
2519       werror (E_SHADOWREGS_NO_ISR, sym->name);
2520     }
2521
2522   for (argCnt=1, acargs = FUNC_ARGS(sym->type);
2523        acargs;
2524        acargs=acargs->next, argCnt++) {
2525     if (!acargs->sym) {
2526       // this can happen for reentrant functions
2527       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2528       // the show must go on: synthesize a name and symbol
2529       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2530       acargs->sym = newSymbol (acargs->name, 1);
2531       SPEC_OCLS (acargs->etype) = istack;
2532       acargs->sym->type = copyLinkChain (acargs->type);
2533       acargs->sym->etype = getSpec (acargs->sym->type);
2534       acargs->sym->_isparm = 1;
2535       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2536     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) {
2537       // synthesized name
2538       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2539     }
2540   }
2541   argCnt--;
2542
2543   /*JCF: Mark the register bank as used*/
2544   RegBankUsed[FUNC_REGBANK (sym->type)] = 1;
2545
2546   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2547     return 1;                   /* not defined nothing more to check  */
2548
2549   /* check if body already present */
2550   if (csym && IFFUNC_HASBODY(csym->type))
2551     {
2552       werror (E_FUNC_BODY, sym->name);
2553       return 0;
2554     }
2555
2556   /* check the return value type   */
2557   if (compareType (csym->type, sym->type) <= 0)
2558     {
2559       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2560       printFromToType(csym->type, sym->type);
2561       return 0;
2562     }
2563
2564   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2565     {
2566       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2567     }
2568
2569   /* I don't think this is necessary for interrupts. An isr is a  */
2570   /* root in the calling tree.                                    */
2571   if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2572       (!FUNC_ISISR (sym->type)))
2573     {
2574       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2575     }
2576
2577   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2578     {
2579       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2580     }
2581
2582   /* Really, reentrant should match regardless of argCnt, but     */
2583   /* this breaks some existing code (the fp lib functions). If    */
2584   /* the first argument is always passed the same way, this       */
2585   /* lax checking is ok (but may not be true for in future ports) */
2586   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2587       && argCnt>1)
2588     {
2589       //printf("argCnt = %d\n",argCnt);
2590       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2591     }
2592
2593   if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2594     {
2595       werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2596     }
2597
2598   if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2599     {
2600       werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2601     }
2602
2603
2604   /* compare expected args with actual args */
2605   exargs = FUNC_ARGS(csym->type);
2606   acargs = FUNC_ARGS(sym->type);
2607
2608   /* for all the expected args do */
2609   for (argCnt = 1;
2610        exargs && acargs;
2611        exargs = exargs->next, acargs = acargs->next, argCnt++)
2612     {
2613       if (getenv("DEBUG_SANITY")) {
2614         fprintf (stderr, "checkFunction: %s ", exargs->name);
2615       }
2616       /* make sure the type is complete and sane */
2617       checkTypeSanity(exargs->etype, exargs->name);
2618
2619       /* If the actual argument is an array, any prototype
2620        * will have modified it to a pointer. Duplicate that
2621        * change here.
2622        */
2623       if (IS_AGGREGATE (acargs->type))
2624         {
2625           checkValue = copyValue (acargs);
2626           aggregateToPointer (checkValue);
2627         }
2628       else
2629         {
2630           checkValue = acargs;
2631         }
2632
2633       if (compareType (exargs->type, checkValue->type) <= 0)
2634         {
2635           werror (E_ARG_TYPE, argCnt);
2636           printFromToType(exargs->type, checkValue->type);
2637           return 0;
2638         }
2639     }
2640
2641   /* if one them ended we have a problem */
2642   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2643       (!exargs && acargs && !IS_VOID (acargs->type)))
2644     werror (E_ARG_COUNT);
2645
2646   /* replace with this defition */
2647   sym->cdef = csym->cdef;
2648   deleteSym (SymbolTab, csym, csym->name);
2649   deleteFromSeg(csym);
2650   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2651   if (IS_EXTERN (csym->etype) && !
2652       IS_EXTERN (sym->etype))
2653     {
2654       addSet (&publics, sym);
2655     }
2656   return 1;
2657 }
2658
2659 /*------------------------------------------------------------------*/
2660 /* cdbStructBlock - calls struct printing for a blcks               */
2661 /*------------------------------------------------------------------*/
2662 void cdbStructBlock (int block)
2663 {
2664   int i;
2665   bucket **table = StructTab;
2666   bucket *chain;
2667
2668   /* go thru the entire  table  */
2669   for (i = 0; i < 256; i++)
2670     {
2671       for (chain = table[i]; chain; chain = chain->next)
2672         {
2673           if (chain->block >= block)
2674             {
2675               if(debugFile)
2676                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2677             }
2678         }
2679     }
2680 }
2681
2682 /*-----------------------------------------------------------------*/
2683 /* processFuncPtrArgs - does some processing with args of func ptrs*/
2684 /*-----------------------------------------------------------------*/
2685 void
2686 processFuncPtrArgs (sym_link * funcType)
2687 {
2688   value *val = FUNC_ARGS(funcType);
2689
2690   /* if it is void then remove parameters */
2691   if (val && IS_VOID (val->type))
2692     {
2693       FUNC_ARGS(funcType) = NULL;
2694       return;
2695     }
2696 }
2697
2698 /*-----------------------------------------------------------------*/
2699 /* processFuncArgs - does some processing with function args       */
2700 /*-----------------------------------------------------------------*/
2701 void
2702 processFuncArgs (symbol * func)
2703 {
2704   value *val;
2705   int pNum = 1;
2706   sym_link *funcType=func->type;
2707
2708   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2709     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2710
2711   /* find the function declaration within the type */
2712   while (funcType && !IS_FUNC(funcType))
2713     funcType=funcType->next;
2714
2715   /* if this function has variable argument list */
2716   /* then make the function a reentrant one    */
2717   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2718     FUNC_ISREENT(funcType)=1;
2719
2720   /* check if this function is defined as calleeSaves
2721      then mark it as such */
2722   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2723
2724   /* loop thru all the arguments   */
2725   val = FUNC_ARGS(funcType);
2726
2727   /* if it is void then remove parameters */
2728   if (val && IS_VOID (val->type))
2729     {
2730       FUNC_ARGS(funcType) = NULL;
2731       return;
2732     }
2733
2734   /* reset regparm for the port */
2735   (*port->reset_regparms) ();
2736
2737   /* if any of the arguments is an aggregate */
2738   /* change it to pointer to the same type */
2739   while (val)
2740     {
2741       int argreg = 0;
2742       char buffer[SDCC_NAME_MAX+1];
2743
2744       SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2745       checkTypeSanity (val->etype, buffer);
2746
2747       /* mark it as a register parameter if
2748          the function does not have VA_ARG
2749          and as port dictates */
2750       if (!IFFUNC_HASVARARGS(funcType) &&
2751           (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
2752         {
2753           SPEC_REGPARM (val->etype) = 1;
2754           SPEC_ARGREG(val->etype) = argreg;
2755         } else if (IFFUNC_ISREENT(funcType)) {
2756             FUNC_HASSTACKPARM(funcType) = 1;
2757         }
2758
2759       if (IS_AGGREGATE (val->type))
2760         {
2761           aggregateToPointer (val);
2762         }
2763
2764       val = val->next;
2765       pNum++;
2766     }
2767
2768   /* if this is an internal generated function call */
2769   if (func->cdef) {
2770     /* ignore --stack-auto for this one, we don't know how it is compiled */
2771     /* simply trust on --int-long-reent or --float-reent */
2772     if (IFFUNC_ISREENT(funcType)) {
2773       return;
2774     }
2775   } else {
2776     /* if this function is reentrant or */
2777     /* automatics r 2b stacked then nothing */
2778     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2779       return;
2780   }
2781
2782   val = FUNC_ARGS(funcType);
2783   pNum = 1;
2784   while (val)
2785     {
2786
2787       /* if a symbolname is not given  */
2788       /* synthesize a variable name */
2789       if (!val->sym)
2790         {
2791           SNPRINTF (val->name, sizeof(val->name),
2792                     "_%s_PARM_%d", func->name, pNum++);
2793           val->sym = newSymbol (val->name, 1);
2794           if (SPEC_SCLS(val->etype) == S_BIT)
2795             SPEC_OCLS (val->etype) = bit;
2796           else
2797             SPEC_OCLS (val->etype) = port->mem.default_local_map;
2798           val->sym->type = copyLinkChain (val->type);
2799           val->sym->etype = getSpec (val->sym->type);
2800           val->sym->_isparm = 1;
2801           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2802           #if 0
2803           /* ?? static functions shouldn't imply static parameters - EEP */
2804           if (IS_SPEC(func->etype)) {
2805             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2806               SPEC_STAT (func->etype);
2807           }
2808           #endif
2809           addSymChain (&val->sym);
2810
2811         }
2812       else                      /* symbol name given create synth name */
2813         {
2814
2815           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2816           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2817           val->sym->_isparm = 1;
2818           if (SPEC_SCLS(val->etype) == S_BIT)
2819             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2820           else
2821             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2822               port->mem.default_local_map;
2823
2824           #if 0
2825           /* ?? static functions shouldn't imply static parameters - EEP */
2826           if (IS_SPEC(func->etype)) {
2827             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2828               SPEC_STAT (func->etype);
2829           }
2830           #endif
2831         }
2832       if (SPEC_OCLS (val->sym->etype) == pdata)
2833         val->sym->iaccess = 1;
2834       if (!isinSet(operKeyReset, val->sym)) {
2835         addSet (&operKeyReset, val->sym);
2836         applyToSet (operKeyReset, resetParmKey);
2837       }
2838       val = val->next;
2839     }
2840 }
2841
2842 /*-----------------------------------------------------------------*/
2843 /* isSymbolEqual - compares two symbols return 1 if they match     */
2844 /*-----------------------------------------------------------------*/
2845 int
2846 isSymbolEqual (symbol * dest, symbol * src)
2847 {
2848   /* if pointers match then equal */
2849   if (dest == src)
2850     return 1;
2851
2852   /* if one of them is null then don't match */
2853   if (!dest || !src)
2854     return 0;
2855
2856   /* if both of them have rname match on rname */
2857   if (dest->rname[0] && src->rname[0])
2858     return (!strcmp (dest->rname, src->rname));
2859
2860   /* otherwise match on name */
2861   return (!strcmp (dest->name, src->name));
2862 }
2863
2864 void PT(sym_link *type)
2865 {
2866         printTypeChain(type,0);
2867 }
2868 /*-----------------------------------------------------------------*/
2869 /* printTypeChain - prints the type chain in human readable form   */
2870 /*-----------------------------------------------------------------*/
2871 void
2872 printTypeChain (sym_link * start, FILE * of)
2873 {
2874   struct dbuf_s dbuf;
2875   int nlr = 0;
2876
2877   if (!of)
2878     {
2879       of = stdout;
2880       nlr = 1;
2881     }
2882
2883   dbuf_init (&dbuf, 1024);
2884   dbuf_printTypeChain (start, &dbuf);
2885   dbuf_write_and_destroy (&dbuf, of);
2886
2887   if (nlr)
2888     putc ('\n', of);
2889 }
2890
2891 void
2892 dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
2893 {
2894   value *args;
2895   sym_link * type, * search;
2896   STORAGE_CLASS scls;
2897
2898   if (start==NULL) {
2899     dbuf_append_str (dbuf, "void");
2900     return;
2901   }
2902
2903   /* Print the chain as it is written in the source: */
2904   /* start with the last entry.                      */
2905   /* However, the storage class at the end of the    */
2906   /* chain reall applies to the first in the chain!  */
2907
2908   for (type = start; type && type->next; type = type->next)
2909     ;
2910   if (IS_SPEC (type))
2911     scls=SPEC_SCLS(type);
2912   else
2913     scls=0;
2914   while (type)
2915     {
2916       if (type==start) {
2917         switch (scls)
2918           {
2919           case S_DATA: dbuf_append_str (dbuf, "data-"); break;
2920           case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break;
2921           case S_SFR: dbuf_append_str (dbuf, "sfr-"); break;
2922           case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break;
2923           case S_CODE: dbuf_append_str (dbuf, "code-"); break;
2924           case S_IDATA: dbuf_append_str (dbuf, "idata-"); break;
2925           case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break;
2926           case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break;
2927           case S_STACK: dbuf_append_str (dbuf, "stack-"); break;
2928           case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break;
2929           case S_BIT: dbuf_append_str (dbuf, "bit-"); break;
2930           case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break;
2931           default: break;
2932           }
2933       }
2934
2935       if (IS_DECL (type))
2936         {
2937           if (!IS_FUNC(type)) {
2938             if (DCL_PTR_VOLATILE (type)) {
2939               dbuf_append_str (dbuf, "volatile-");
2940             }
2941             if (DCL_PTR_CONST (type)) {
2942               dbuf_append_str (dbuf, "const-");
2943             }
2944             if (DCL_PTR_RESTRICT (type)) {
2945               dbuf_append_str (dbuf, "restrict-");
2946             }
2947           }
2948           switch (DCL_TYPE (type))
2949             {
2950             case FUNCTION:
2951               dbuf_printf (dbuf, "function %s %s",
2952                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2953                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2954               dbuf_append_str (dbuf, "( ");
2955               for (args = FUNC_ARGS(type);
2956                    args;
2957                    args=args->next) {
2958                 dbuf_printTypeChain(args->type, dbuf);
2959                 if (args->next)
2960                   dbuf_append_str (dbuf, ", ");
2961               }
2962               dbuf_append_str (dbuf, ") ");
2963               break;
2964             case GPOINTER:
2965               dbuf_append_str (dbuf, "generic* ");
2966               break;
2967             case CPOINTER:
2968               dbuf_append_str (dbuf, "code* ");
2969               break;
2970             case FPOINTER:
2971               dbuf_append_str (dbuf, "xdata* ");
2972               break;
2973             case EEPPOINTER:
2974               dbuf_append_str (dbuf, "eeprom* ");
2975               break;
2976             case POINTER:
2977               dbuf_append_str (dbuf, "near* ");
2978               break;
2979             case IPOINTER:
2980               dbuf_append_str (dbuf, "idata* ");
2981               break;
2982             case PPOINTER:
2983               dbuf_append_str (dbuf, "pdata* ");
2984               break;
2985             case UPOINTER:
2986               dbuf_append_str (dbuf, "unknown* ");
2987               break;
2988             case ARRAY:
2989               if (DCL_ELEM(type)) {
2990                 dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type));
2991               } else {
2992                 dbuf_append_str (dbuf, "[] ");
2993               }
2994               break;
2995             }
2996         }
2997       else
2998         {
2999           if (SPEC_VOLATILE (type))
3000             dbuf_append_str (dbuf, "volatile-");
3001           if (SPEC_CONST (type))
3002             dbuf_append_str (dbuf, "const-");
3003           if (SPEC_USIGN (type))
3004             dbuf_append_str (dbuf, "unsigned-");
3005           switch (SPEC_NOUN (type))
3006             {
3007             case V_INT:
3008               if (IS_LONG (type))
3009                 dbuf_append_str (dbuf, "long-");
3010               dbuf_append_str (dbuf, "int");
3011               break;
3012
3013             case V_CHAR:
3014               dbuf_append_str (dbuf, "char");
3015               break;
3016
3017             case V_VOID:
3018               dbuf_append_str (dbuf, "void");
3019               break;
3020
3021             case V_FLOAT:
3022               dbuf_append_str (dbuf, "float");
3023               break;
3024
3025             case V_FIXED16X16:
3026               dbuf_append_str (dbuf, "fixed16x16");
3027               break;
3028
3029             case V_STRUCT:
3030               dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
3031               break;
3032
3033             case V_SBIT:
3034               dbuf_append_str (dbuf, "sbit");
3035               break;
3036
3037             case V_BIT:
3038               dbuf_append_str (dbuf, "bit");
3039               break;
3040
3041             case V_BITFIELD:
3042               dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3043               break;
3044
3045             case V_DOUBLE:
3046               dbuf_append_str (dbuf, "double");
3047               break;
3048
3049             default:
3050               dbuf_append_str (dbuf, "unknown type");
3051               break;
3052             }
3053         }
3054       /* search entry in list before "type" */
3055       for (search = start; search && search->next != type;)
3056         search = search->next;
3057       type = search;
3058       if (type)
3059           dbuf_append_char(dbuf, ' ');
3060     }
3061 }
3062
3063 /*--------------------------------------------------------------------*/
3064 /* printTypeChainRaw - prints the type chain in human readable form   */
3065 /*                     in the raw data structure ordering             */
3066 /*--------------------------------------------------------------------*/
3067 void
3068 printTypeChainRaw (sym_link * start, FILE * of)
3069 {
3070   int nlr = 0;
3071   value *args;
3072   sym_link * type;
3073
3074   if (!of)
3075     {
3076       of = stdout;
3077       nlr = 1;
3078     }
3079
3080   if (start==NULL) {
3081     fprintf (of, "void");
3082     return;
3083   }
3084
3085   type = start;
3086
3087   while (type)
3088     {
3089       if (IS_DECL (type))
3090         {
3091           if (!IS_FUNC(type)) {
3092             if (DCL_PTR_VOLATILE (type)) {
3093               fprintf (of, "volatile-");
3094             }
3095             if (DCL_PTR_CONST (type)) {
3096               fprintf (of, "const-");
3097             }
3098             if (DCL_PTR_RESTRICT (type)) {
3099               fprintf (of, "restrict-");
3100             }
3101           }
3102           switch (DCL_TYPE (type))
3103             {
3104             case FUNCTION:
3105               if (IFFUNC_ISINLINE(type)) {
3106                 fprintf (of, "inline-");
3107               }
3108               fprintf (of, "function %s %s",
3109                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
3110                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
3111               fprintf (of, "( ");
3112               for (args = FUNC_ARGS(type);
3113                    args;
3114                    args=args->next) {
3115                 printTypeChain(args->type, of);
3116                 if (args->next)
3117                   fprintf(of, ", ");
3118               }
3119               fprintf (of, ") ");
3120               break;
3121             case GPOINTER:
3122               fprintf (of, "generic* ");
3123               break;
3124             case CPOINTER:
3125               fprintf (of, "code* ");
3126               break;
3127             case FPOINTER:
3128               fprintf (of, "xdata* ");
3129               break;
3130             case EEPPOINTER:
3131               fprintf (of, "eeprom* ");
3132               break;
3133             case POINTER:
3134               fprintf (of, "near* ");
3135               break;
3136             case IPOINTER:
3137               fprintf (of, "idata* ");
3138               break;
3139             case PPOINTER:
3140               fprintf (of, "pdata* ");
3141               break;
3142             case UPOINTER:
3143               fprintf (of, "unknown* ");
3144               break;
3145             case ARRAY:
3146               if (DCL_ELEM(type)) {
3147                 fprintf (of, "[%d] ", DCL_ELEM(type));
3148               } else {
3149                 fprintf (of, "[] ");
3150               }
3151               break;
3152             }
3153           if (DCL_TSPEC(type))
3154             {
3155               fprintf (of, "{");
3156               printTypeChainRaw(DCL_TSPEC(type), of);
3157               fprintf (of, "}");
3158             }
3159         }
3160       else if (IS_SPEC (type))
3161         {
3162         switch (SPEC_SCLS (type))
3163           {
3164           case S_DATA: fprintf (of, "data-"); break;
3165           case S_XDATA: fprintf (of, "xdata-"); break;
3166           case S_SFR: fprintf (of, "sfr-"); break;
3167           case S_SBIT: fprintf (of, "sbit-"); break;
3168           case S_CODE: fprintf (of, "code-"); break;
3169           case S_IDATA: fprintf (of, "idata-"); break;
3170           case S_PDATA: fprintf (of, "pdata-"); break;
3171           case S_LITERAL: fprintf (of, "literal-"); break;
3172           case S_STACK: fprintf (of, "stack-"); break;
3173           case S_XSTACK: fprintf (of, "xstack-"); break;
3174           case S_BIT: fprintf (of, "bit-"); break;
3175           case S_EEPROM: fprintf (of, "eeprom-"); break;
3176           default: break;
3177           }
3178           if (SPEC_VOLATILE (type))
3179             fprintf (of, "volatile-");
3180           if (SPEC_CONST (type))
3181             fprintf (of, "const-");
3182           if (SPEC_USIGN (type))
3183             fprintf (of, "unsigned-");
3184           switch (SPEC_NOUN (type))
3185             {
3186             case V_INT:
3187               if (IS_LONG (type))
3188                 fprintf (of, "long-");
3189               fprintf (of, "int");
3190               break;
3191
3192             case V_CHAR:
3193               fprintf (of, "char");
3194               break;
3195
3196             case V_VOID:
3197               fprintf (of, "void");
3198               break;
3199
3200             case V_FLOAT:
3201               fprintf (of, "float");
3202               break;
3203
3204             case V_FIXED16X16:
3205               fprintf (of, "fixed16x16");
3206               break;
3207
3208             case V_STRUCT:
3209               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3210               break;
3211
3212             case V_SBIT:
3213               fprintf (of, "sbit");
3214               break;
3215
3216             case V_BIT:
3217               fprintf (of, "bit");
3218               break;
3219
3220             case V_BITFIELD:
3221               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3222               break;
3223
3224             case V_DOUBLE:
3225               fprintf (of, "double");
3226               break;
3227
3228             default:
3229               fprintf (of, "unknown type");
3230               break;
3231             }
3232         }
3233       else
3234         fprintf (of, "NOT_SPEC_OR_DECL");
3235       type = type->next;
3236       if (type)
3237         fputc (' ', of);
3238     }
3239   if (nlr)
3240     fprintf (of, "\n");
3241 }
3242
3243
3244 /*-----------------------------------------------------------------*/
3245 /* powof2 - returns power of two for the number if number is pow 2 */
3246 /*-----------------------------------------------------------------*/
3247 int
3248 powof2 (TYPE_TARGET_ULONG num)
3249 {
3250   int nshifts = 0;
3251   int n1s = 0;
3252
3253   while (num)
3254     {
3255       if (num & 1)
3256         n1s++;
3257       num >>= 1;
3258       nshifts++;
3259     }
3260
3261   if (n1s > 1 || nshifts == 0)
3262     return -1;
3263   return nshifts - 1;
3264 }
3265
3266 symbol *__fsadd;
3267 symbol *__fssub;
3268 symbol *__fsmul;
3269 symbol *__fsdiv;
3270 symbol *__fseq;
3271 symbol *__fsneq;
3272 symbol *__fslt;
3273 symbol *__fslteq;
3274 symbol *__fsgt;
3275 symbol *__fsgteq;
3276
3277 symbol *__fps16x16_add;
3278 symbol *__fps16x16_sub;
3279 symbol *__fps16x16_mul;
3280 symbol *__fps16x16_div;
3281 symbol *__fps16x16_eq;
3282 symbol *__fps16x16_neq;
3283 symbol *__fps16x16_lt;
3284 symbol *__fps16x16_lteq;
3285 symbol *__fps16x16_gt;
3286 symbol *__fps16x16_gteq;
3287
3288 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */
3289 symbol *__muldiv[3][3][4];
3290 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3291 sym_link *__multypes[3][2];
3292 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3293 symbol *__conv[2][3][2];
3294 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
3295 symbol *__fp16x16conv[2][4][2];
3296 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3297 symbol *__rlrr[2][3][2];
3298
3299 sym_link *floatType;
3300 sym_link *fixed16x16Type;
3301
3302 static char *
3303 _mangleFunctionName(char *in)
3304 {
3305   if (port->getMangledFunctionName)
3306     {
3307       return port->getMangledFunctionName(in);
3308     }
3309   else
3310     {
3311       return in;
3312     }
3313 }
3314
3315 /*-----------------------------------------------------------------*/
3316 /* typeFromStr - create a typechain from an encoded string         */
3317 /* basic types -        'c' - char                                 */
3318 /*                      's' - short                                */
3319 /*                      'i' - int                                  */
3320 /*                      'l' - long                                 */
3321 /*                      'f' - float                                */
3322 /*                      'q' - fixed16x16                           */
3323 /*                      'v' - void                                 */
3324 /*                      '*' - pointer - default (GPOINTER)         */
3325 /* modifiers -          'u' - unsigned                             */
3326 /* pointer modifiers -  'g' - generic                              */
3327 /*                      'x' - xdata                                */
3328 /*                      'p' - code                                 */
3329 /*                      'd' - data                                 */
3330 /*                      'F' - function                             */
3331 /* examples : "ig*" - generic int *                                */
3332 /*            "cx*" - char xdata *                                 */
3333 /*            "ui" -  unsigned int                                 */
3334 /*-----------------------------------------------------------------*/
3335 sym_link *typeFromStr (char *s)
3336 {
3337     sym_link *r = newLink(DECLARATOR);
3338     int usign = 0;
3339
3340     do {
3341         sym_link *nr;
3342         switch (*s) {
3343         case 'u' :
3344             usign = 1;
3345             s++;
3346             continue ;
3347             break ;
3348         case 'c':
3349             r->class = SPECIFIER;
3350             SPEC_NOUN(r) = V_CHAR;
3351             break;
3352         case 's':
3353         case 'i':
3354             r->class = SPECIFIER;
3355             SPEC_NOUN(r) = V_INT;
3356             break;
3357         case 'l':
3358             r->class = SPECIFIER;
3359             SPEC_NOUN(r) = V_INT;
3360             SPEC_LONG(r) = 1;
3361             break;
3362         case 'f':
3363             r->class = SPECIFIER;
3364             SPEC_NOUN(r) = V_FLOAT;
3365             break;
3366         case 'q':
3367             r->class = SPECIFIER;
3368             SPEC_NOUN(r) = V_FIXED16X16;
3369             break;
3370         case 'v':
3371             r->class = SPECIFIER;
3372             SPEC_NOUN(r) = V_VOID;
3373             break;
3374         case '*':
3375             DCL_TYPE(r) = port->unqualified_pointer;
3376             break;
3377         case 'g':
3378         case 'x':
3379         case 'p':
3380         case 'd':
3381         case 'F':
3382             assert(*(s+1)=='*');
3383             nr = newLink(DECLARATOR);
3384             nr->next = r;
3385             r = nr;
3386             switch (*s) {
3387             case 'g':
3388                 DCL_TYPE(r) = GPOINTER;
3389                 break;
3390             case 'x':
3391                 DCL_TYPE(r) = FPOINTER;
3392                 break;
3393             case 'p':
3394                 DCL_TYPE(r) = CPOINTER;
3395                 break;
3396             case 'd':
3397                 DCL_TYPE(r) = POINTER;
3398                 break;
3399             case 'F':
3400                 DCL_TYPE(r) = FUNCTION;
3401                 nr = newLink(DECLARATOR);
3402                 nr->next = r;
3403                 r = nr;
3404                 DCL_TYPE(r) = CPOINTER;
3405                 break;
3406             }
3407             s++;
3408             break;
3409         default:
3410             werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
3411                    "typeFromStr: unknown type");
3412             break;
3413         }
3414         if (IS_SPEC(r) && usign) {
3415             SPEC_USIGN(r) = 1;
3416             usign = 0;
3417         }
3418         s++;
3419     } while (*s);
3420     return r;
3421 }
3422
3423 /*-----------------------------------------------------------------*/
3424 /* initCSupport - create functions for C support routines          */
3425 /*-----------------------------------------------------------------*/
3426 void
3427 initCSupport ()
3428 {
3429   const char *smuldivmod[] =
3430   {
3431     "mul", "div", "mod"
3432   };
3433   const char *sbwd[] =
3434   {
3435     "char", "int", "long", "fixed16x16",
3436   };
3437   const char *fp16x16sbwd[] =
3438   {
3439     "char", "int", "long", "float",
3440   };
3441   const char *ssu[] =
3442   {
3443     "s", "su", "us", "u"
3444   };
3445   const char *srlrr[] =
3446   {
3447     "rl", "rr"
3448   };
3449
3450   int bwd, su, muldivmod, tofrom, rlrr;
3451
3452   if (getenv("SDCC_NO_C_SUPPORT")) {
3453     /* for debugging only */
3454     return;
3455   }
3456
3457   floatType = newFloatLink ();
3458   fixed16x16Type = newFixed16x16Link ();
3459
3460   for (bwd = 0; bwd < 3; bwd++)
3461     {
3462       sym_link *l = NULL;
3463       switch (bwd)
3464         {
3465         case 0:
3466           l = newCharLink ();
3467           break;
3468         case 1:
3469           l = newIntLink ();
3470           break;
3471         case 2:
3472           l = newLongLink ();
3473           break;
3474         default:
3475           assert (0);
3476         }
3477       __multypes[bwd][0] = l;
3478       __multypes[bwd][1] = copyLinkChain (l);
3479       SPEC_USIGN (__multypes[bwd][1]) = 1;
3480     }
3481
3482   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3483   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3484   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3485   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3486   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3487   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3488   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3489   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3490   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3491   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3492
3493   __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3494   __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3495   __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3496   __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3497   __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3498   __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3499   __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3500   __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3501   __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3502   __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3503
3504
3505   for (tofrom = 0; tofrom < 2; tofrom++)
3506     {
3507       for (bwd = 0; bwd < 3; bwd++)
3508         {
3509           for (su = 0; su < 2; su++)
3510             {
3511               if (tofrom)
3512                 {
3513                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su*3], sbwd[bwd]);
3514                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3515                 }
3516               else
3517                 {
3518                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su*3], sbwd[bwd]);
3519                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3520                 }
3521             }
3522         }
3523     }
3524
3525   for (tofrom = 0; tofrom < 2; tofrom++)
3526     {
3527       for (bwd = 0; bwd < 4; bwd++)
3528         {
3529           for (su = 0; su < 2; su++)
3530             {
3531               if (tofrom)
3532                 {
3533                   SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su*3], fp16x16sbwd[bwd]);
3534                   if(bwd == 3) {
3535                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
3536                   } else
3537                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
3538                 }
3539               else
3540                 {
3541                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su*3], fp16x16sbwd[bwd]);
3542                   if(bwd == 3) {
3543                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
3544                   } else
3545                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
3546                 }
3547             }
3548         }
3549     }
3550
3551 /*
3552   for (muldivmod = 0; muldivmod < 3; muldivmod++)
3553     {
3554       for (bwd = 0; bwd < 3; bwd++)
3555         {
3556           for (su = 0; su < 2; su++)
3557             {
3558               SNPRINTF (buffer, sizeof(buffer),
3559                         "_%s%s%s",
3560                        smuldivmod[muldivmod],
3561                        ssu[su*3],
3562                        sbwd[bwd]);
3563               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3564               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3565             }
3566         }
3567     }
3568
3569   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3570   Therefore they've been merged into mulint() and mullong().
3571 */
3572
3573   /* byte */
3574   bwd = 0;
3575   for (su = 0; su < 4; su++)
3576     {
3577       for (muldivmod = 0; muldivmod < 3; muldivmod++)
3578         {
3579           /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80
3580              port is sign/zero-extending to int before calling mulint() */
3581           /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
3582           if (!TARGET_IS_PIC16 || muldivmod != 1 || su != 0)
3583             {
3584               SNPRINTF (buffer, sizeof(buffer),
3585                   "_%s%s%s",
3586                   smuldivmod[muldivmod],
3587                   ssu[su],
3588                   sbwd[bwd]);
3589               __muldiv[muldivmod][bwd][su] = funcOfType (
3590                   _mangleFunctionName(buffer),
3591                   __multypes[bwd][su%2],
3592                   __multypes[bwd][su/2],
3593                   2,
3594                   options.intlong_rent);
3595               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3596             }
3597         }
3598     }
3599
3600   for (bwd = 1; bwd < 3; bwd++)
3601     {
3602       for (su = 0; su < 2; su++)
3603         {
3604           for (muldivmod = 1; muldivmod < 3; muldivmod++)
3605             {
3606               /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
3607               if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0)
3608               {
3609                 SNPRINTF (buffer, sizeof(buffer),
3610                     "_%s%s%s",
3611                     smuldivmod[muldivmod],
3612                     ssu[su*3],
3613                     sbwd[bwd]);
3614                 __muldiv[muldivmod][bwd][su] = funcOfType (
3615                     _mangleFunctionName(buffer),
3616                     __multypes[bwd][su],
3617                     __multypes[bwd][su],
3618                     2,
3619                     options.intlong_rent);
3620                 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3621               }
3622             }
3623         }
3624     }
3625
3626   if (TARGET_IS_PIC16)
3627   {
3628     /* PIC16 port wants __divschar/__modschar to return an int, so that both
3629      * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
3630      * (first one would have to be sign extended, second one must not be).
3631      * Similarly, modschar should be handled, but the iCode introduces cast
3632      * here and forces '% : s8 x s8 -> s8' ... */
3633     su = 0; bwd = 0;
3634     for (muldivmod = 1; muldivmod < 2; muldivmod++) {
3635       SNPRINTF (buffer, sizeof(buffer),
3636           "_%s%s%s",
3637           smuldivmod[muldivmod],
3638           ssu[su],
3639           sbwd[bwd]);
3640       __muldiv[muldivmod][bwd][su] = funcOfType (
3641           _mangleFunctionName(buffer),
3642           __multypes[1][su],
3643           __multypes[bwd][su],
3644           2,
3645           options.intlong_rent);
3646       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3647     }
3648   }
3649
3650   /* mul only */
3651   muldivmod = 0;
3652   /* signed only */
3653   su = 0;
3654   /* word and doubleword */
3655   for (bwd = 1; bwd < 3; bwd++)
3656     {
3657       /* mul, int/long */
3658       SNPRINTF (buffer, sizeof(buffer),
3659                 "_%s%s",
3660                 smuldivmod[muldivmod],
3661                 sbwd[bwd]);
3662       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3663       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3664       /* signed = unsigned */
3665       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3666     }
3667
3668   for (rlrr = 0; rlrr < 2; rlrr++)
3669     {
3670       for (bwd = 0; bwd < 3; bwd++)
3671         {
3672           for (su = 0; su < 2; su++)
3673             {
3674               SNPRINTF (buffer, sizeof(buffer),
3675                         "_%s%s%s",
3676                        srlrr[rlrr],
3677                        ssu[su*3],
3678                        sbwd[bwd]);
3679               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3680               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3681             }
3682         }
3683     }
3684 }
3685
3686 /*-----------------------------------------------------------------*/
3687 /* initBuiltIns - create prototypes for builtin functions          */
3688 /*-----------------------------------------------------------------*/
3689 void initBuiltIns()
3690 {
3691     int i;
3692     symbol *sym;
3693
3694     if (!port->builtintable) return ;
3695
3696     for (i = 0 ; port->builtintable[i].name ; i++) {
3697         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3698                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3699         FUNC_ISBUILTIN(sym->type) = 1;
3700         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3701     }
3702 }
3703
3704 sym_link *validateLink(sym_link         *l,
3705                         const char      *macro,
3706                         const char      *args,
3707                         const char      select,
3708                         const char      *file,
3709                         unsigned        line)
3710 {
3711   if (l && l->class==select)
3712     {
3713         return l;
3714     }
3715     fprintf(stderr,
3716             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3717             " expected %s, got %s\n",
3718             macro, args, file, line,
3719             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3720     exit(EXIT_FAILURE);
3721     return l; // never reached, makes compiler happy.
3722 }
3723
3724 /*--------------------------------------------------------------------*/
3725 /* newEnumType - create an integer type compatible with enumerations  */
3726 /*--------------------------------------------------------------------*/
3727 sym_link *
3728 newEnumType (symbol *enumlist)
3729 {
3730   int min, max, v;
3731   symbol *sym;
3732   sym_link *type;
3733
3734   if (!enumlist)
3735     {
3736       type = newLink (SPECIFIER);
3737       SPEC_NOUN (type) = V_INT;
3738       return type;
3739     }
3740
3741   /* Determine the range of the enumerated values */
3742   sym = enumlist;
3743   min = max = (int) ulFromVal (valFromType (sym->type));
3744   for (sym = sym->next; sym; sym = sym->next)
3745     {
3746       v = (int) ulFromVal (valFromType (sym->type));
3747       if (v<min)
3748         min = v;
3749       if (v>max)
3750         max = v;
3751     }
3752
3753   /* Determine the smallest integer type that is compatible with this range */
3754   type = newLink (SPECIFIER);
3755   if (min>=0 && max<=255)
3756     {
3757       SPEC_NOUN (type) = V_CHAR;
3758       SPEC_USIGN (type) = 1;
3759     }
3760   else if (min>=-128 && max<=127)
3761     {
3762       SPEC_NOUN (type) = V_CHAR;
3763     }
3764   else if (min>=0 && max<=65535)
3765     {
3766       SPEC_NOUN (type) = V_INT;
3767       SPEC_USIGN (type) = 1;
3768     }
3769   else if (min>=-32768 && max<=32767)
3770     {
3771       SPEC_NOUN (type) = V_INT;
3772     }
3773   else
3774     {
3775       SPEC_NOUN (type) = V_INT;
3776       SPEC_LONG (type) = 1;
3777       if (min>=0)
3778         SPEC_USIGN (type) = 1;
3779     }
3780
3781   return type;
3782 }