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