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