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