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