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