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