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