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