* support/scripts/listerr.c: program to create the list of errors and
[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 &&
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             if (IS_FUNC(src)) {
2064               //checkFunction(src,dest);
2065             }
2066             return compareType (dest->next, src->next);
2067           }
2068           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
2069             return -1;
2070           }
2071           if (IS_PTR (src) && 
2072               (IS_GENPTR (dest) ||
2073                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
2074              ))
2075             return -1;
2076           if (IS_PTR (dest) && IS_ARRAY (src)) {
2077             value *val=aggregateToPointer (valFromType(src));
2078             int res=compareType (dest, val->type);
2079             Safe_free(val->type);
2080             Safe_free(val);
2081             return res;
2082           }
2083           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2084             return compareType (dest->next, src);
2085           return 0;
2086         }
2087       else if (IS_PTR (dest) && IS_INTEGRAL (src))
2088         return -1;
2089       else
2090         return 0;
2091     }
2092
2093   /* if one is a specifier and the other is not */
2094   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2095       (IS_SPEC (dest) && !IS_SPEC (src)))
2096     return 0;
2097
2098   /* if one of them is a void then ok */
2099   if (SPEC_NOUN (dest) == V_VOID &&
2100       SPEC_NOUN (src) != V_VOID)
2101     return -1;
2102
2103   if (SPEC_NOUN (dest) != V_VOID &&
2104       SPEC_NOUN (src) == V_VOID)
2105     return -1;
2106
2107   /* if they are both bitfields then if the lengths
2108      and starts don't match */
2109   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2110       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2111        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2112     return -1;
2113
2114   /* it is a specifier */
2115   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2116     {
2117       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
2118           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2119           /* I would prefer
2120           bitsForType (dest) == bitsForType (src))
2121              instead of the next two lines, but the regression tests fail with
2122              them; I guess it's a problem with replaceCheaperOp  */
2123           getSize (dest) == getSize (src) &&
2124           !(!IS_BIT (dest) && IS_BIT (src)))
2125         return 1;
2126       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2127         return -1;
2128       else
2129         return 0;
2130     }
2131   else if (IS_STRUCT (dest))
2132     {
2133       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2134         return 0;
2135       else
2136         return 1;
2137     }
2138   if (SPEC_LONG (dest) != SPEC_LONG (src))
2139     return -1;
2140
2141   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2142     return -1;
2143
2144   return 1;
2145 }
2146
2147 /*--------------------------------------------------------------------*/
2148 /* compareTypeExact - will do type check return 1 if match exactly    */
2149 /*--------------------------------------------------------------------*/
2150 int
2151 compareTypeExact (sym_link * dest, sym_link * src, int level)
2152 {
2153   STORAGE_CLASS srcScls, destScls;
2154   
2155   if (!dest && !src)
2156     return 1;
2157
2158   if (dest && !src)
2159     return 0;
2160
2161   if (src && !dest)
2162     return 0;
2163
2164   /* if dest is a declarator then */
2165   if (IS_DECL (dest))
2166     {
2167       if (IS_DECL (src))
2168         {
2169           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2170             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2171               return 0;
2172             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2173               return 0;
2174             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2175               return 0;
2176             if (IS_FUNC(src))
2177               {
2178                 value *exargs, *acargs, *checkValue;
2179
2180                 /* verify function return type */
2181                 if (!compareTypeExact (dest->next, src->next, -1))
2182                   return 0;
2183                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2184                   return 0;
2185                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2186                   return 0;
2187                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2188                   return 0;
2189                 #if 0
2190                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2191                   return 0;
2192                 #endif
2193
2194                 /* compare expected args with actual args */
2195                 exargs = FUNC_ARGS(dest);
2196                 acargs = FUNC_ARGS(src);
2197
2198                 /* for all the expected args do */
2199                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2200                   {
2201                     //checkTypeSanity(acargs->etype, acargs->name);
2202
2203                     if (IS_AGGREGATE (acargs->type))
2204                       {
2205                         checkValue = copyValue (acargs);
2206                         aggregateToPointer (checkValue);
2207                       }
2208                     else
2209                       checkValue = acargs;
2210
2211                     #if 0
2212                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
2213                       return 0;
2214                     #endif
2215                   }
2216
2217                   /* if one them ended we have a problem */
2218                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2219                       (!exargs && acargs && !IS_VOID (acargs->type)))
2220                     return 0;                  
2221                   return 1;
2222               }
2223             return compareTypeExact (dest->next, src->next, level);
2224           }
2225           return 0;
2226         }
2227       return 0;
2228     }
2229
2230   /* if one is a specifier and the other is not */
2231   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2232       (IS_SPEC (dest) && !IS_SPEC (src)))
2233     return 0;
2234
2235   /* if one of them is a void then ok */
2236   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2237     return 0;
2238
2239   /* if they are both bitfields then if the lengths
2240      and starts don't match */
2241   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2242       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2243        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2244     return 0;
2245
2246   if (IS_INTEGRAL (dest))
2247     {
2248       /* signedness must match */
2249       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2250         return 0;
2251       /* size must match */
2252       if (SPEC_LONG (dest) != SPEC_LONG (src))
2253         return 0;
2254       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2255         return 0;
2256     }
2257   
2258   if (IS_STRUCT (dest))
2259     {
2260       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2261         return 0;
2262     }
2263
2264   if (SPEC_CONST (dest) != SPEC_CONST (src))
2265     return 0;
2266   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2267     return 0;
2268   if (SPEC_STAT (dest) != SPEC_STAT (src))
2269     return 0;
2270   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2271     return 0;
2272   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2273     return 0;
2274       
2275   destScls = SPEC_SCLS (dest);
2276   srcScls = SPEC_SCLS (src);
2277   
2278   /* Compensate for const to const code change in checkSClass() */
2279   if (!level & port->mem.code_ro && SPEC_CONST (dest))
2280     {
2281       if (srcScls == S_CODE && destScls == S_FIXED)
2282         destScls = S_CODE;
2283       if (destScls == S_CODE && srcScls == S_FIXED)
2284         srcScls = S_CODE;
2285     }
2286
2287   /* compensate for allocGlobal() */  
2288   if ((srcScls == S_FIXED || srcScls == S_AUTO)
2289       && port->mem.default_globl_map == xdata
2290       && !level)
2291     srcScls = S_XDATA;
2292   
2293   if (level>0 && !SPEC_STAT (dest))
2294     {
2295       /* Compensate for hack-o-matic in checkSClass() */
2296       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2297         {
2298           if (destScls == S_FIXED)
2299             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2300           if (srcScls == S_FIXED)
2301             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2302         }
2303       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2304         {
2305           if (destScls == S_FIXED)
2306             destScls = S_XDATA;
2307           if (srcScls == S_FIXED)
2308             srcScls = S_XDATA;
2309         }
2310     }
2311
2312   if (srcScls != destScls)
2313     {
2314       #if 0
2315       printf ("level = %d\n", level);
2316       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2317                 SPEC_SCLS (src), SPEC_SCLS (dest));
2318       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2319       #endif
2320       return 0;
2321     }
2322   
2323   return 1;
2324 }
2325
2326 /*------------------------------------------------------------------*/
2327 /* inCalleeSaveList - return 1 if found in callee save list          */
2328 /*------------------------------------------------------------------*/
2329 static int
2330 calleeCmp(void *p1, void *p2)
2331 {
2332   return (strcmp((char *)p1, (char *)(p2)) == 0);
2333 }
2334
2335 bool
2336 inCalleeSaveList(char *s)
2337 {
2338   if (options.all_callee_saves)
2339     return 1;
2340   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2341 }
2342
2343 /*-----------------------------------------------------------------*/
2344 /* aggregateToPointer:  change an agggregate type function      */
2345 /*         argument to a pointer to that type.     */
2346 /*-----------------------------------------------------------------*/
2347 value *
2348 aggregateToPointer (value * val)
2349 {
2350   if (IS_AGGREGATE (val->type))
2351     {
2352       /* if this is a structure */
2353       /* then we need to add a new link */
2354       if (IS_STRUCT (val->type))
2355         {
2356           /* first lets add DECLARATOR type */
2357           sym_link *p = val->type;
2358
2359           werror (W_STRUCT_AS_ARG, val->name);
2360           val->type = newLink (DECLARATOR);
2361           val->type->next = p;
2362         }
2363
2364       /* change to a pointer depending on the */
2365       /* storage class specified        */
2366       switch (SPEC_SCLS (val->etype))
2367         {
2368         case S_IDATA:
2369           DCL_TYPE (val->type) = IPOINTER;
2370           break;
2371         case S_PDATA:
2372           DCL_TYPE (val->type) = PPOINTER;
2373           break;
2374         case S_FIXED:
2375           if (SPEC_OCLS(val->etype)) {
2376             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2377           } else {
2378             // this happens for (external) function parameters
2379             DCL_TYPE (val->type) = port->unqualified_pointer;
2380           }
2381           break;
2382         case S_AUTO:
2383         case S_DATA:
2384         case S_REGISTER:
2385           DCL_TYPE (val->type) = POINTER;
2386           break;
2387         case S_CODE:
2388           DCL_TYPE (val->type) = CPOINTER;
2389           break;
2390         case S_XDATA:
2391           DCL_TYPE (val->type) = FPOINTER;
2392           break;
2393         case S_EEPROM:
2394           DCL_TYPE (val->type) = EEPPOINTER;
2395           break;
2396         default:
2397           DCL_TYPE (val->type) = port->unqualified_pointer;
2398         }
2399       
2400       /* is there is a symbol associated then */
2401       /* change the type of the symbol as well */
2402       if (val->sym)
2403         {
2404           val->sym->type = copyLinkChain (val->type);
2405           val->sym->etype = getSpec (val->sym->type);
2406         }
2407     }
2408   return val;
2409 }
2410 /*------------------------------------------------------------------*/
2411 /* checkFunction - does all kinds of check on a function            */
2412 /*------------------------------------------------------------------*/
2413 int 
2414 checkFunction (symbol * sym, symbol *csym)
2415 {
2416   value *exargs, *acargs;
2417   value *checkValue;
2418   int argCnt = 0;
2419
2420   if (getenv("DEBUG_SANITY")) {
2421     fprintf (stderr, "checkFunction: %s ", sym->name);
2422   }
2423
2424   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2425     {
2426       werror(E_SYNTAX_ERROR, sym->name);
2427       return 0;
2428     }
2429   
2430   /* move inline specifier from return type to function attributes */
2431   if (IS_INLINE (sym->etype))
2432     {
2433       SPEC_INLINE (sym->etype) = 0;
2434       FUNC_ISINLINE (sym->type) = 1;
2435     }
2436
2437   /* make sure the type is complete and sane */
2438   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2439
2440   /* if not type then some kind of error */
2441   if (!sym->type)
2442     return 0;
2443
2444   /* if the function has no type then make it return int */
2445   if (!sym->type->next)
2446     sym->type->next = sym->etype = newIntLink ();
2447
2448   /* function cannot return aggregate */
2449   if (IS_AGGREGATE (sym->type->next))
2450     {
2451       werror (E_FUNC_AGGR, sym->name);
2452       return 0;
2453     }
2454
2455   /* check if this function is defined as calleeSaves
2456      then mark it as such */
2457   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2458
2459   /* if interrupt service routine  */
2460   /* then it cannot have arguments */
2461   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2462     {
2463       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2464         werror (E_INT_ARGS, sym->name);
2465         FUNC_ARGS(sym->type)=NULL;
2466       }
2467     }
2468
2469   if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2470     {
2471       werror (E_SHADOWREGS_NO_ISR, sym->name);
2472     }
2473
2474
2475   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
2476        acargs; 
2477        acargs=acargs->next, argCnt++) {
2478     if (!acargs->sym) { 
2479       // this can happen for reentrant functions
2480       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2481       // the show must go on: synthesize a name and symbol
2482       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2483       acargs->sym = newSymbol (acargs->name, 1);
2484       SPEC_OCLS (acargs->etype) = istack;
2485       acargs->sym->type = copyLinkChain (acargs->type);
2486       acargs->sym->etype = getSpec (acargs->sym->type);
2487       acargs->sym->_isparm = 1;
2488       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2489     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2490       // synthesized name
2491       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2492     }
2493   }
2494   argCnt--;
2495
2496   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2497     return 1;                   /* not defined nothing more to check  */
2498
2499   /* check if body already present */
2500   if (csym && IFFUNC_HASBODY(csym->type))
2501     {
2502       werror (E_FUNC_BODY, sym->name);
2503       return 0;
2504     }
2505
2506   /* check the return value type   */
2507   if (compareType (csym->type, sym->type) <= 0)
2508     {
2509       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2510       printFromToType(csym->type, sym->type);
2511       return 0;
2512     }
2513
2514   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2515     {
2516       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2517     }
2518
2519   /* I don't think this is necessary for interrupts. An isr is a  */
2520   /* root in the calling tree.                                    */
2521   if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2522       (!FUNC_ISISR (sym->type)))
2523     {
2524       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2525     }
2526
2527   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2528     {
2529       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2530     }
2531
2532   /* Really, reentrant should match regardless of argCnt, but     */
2533   /* this breaks some existing code (the fp lib functions). If    */
2534   /* the first argument is always passed the same way, this       */
2535   /* lax checking is ok (but may not be true for in future ports) */
2536   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2537       && argCnt>1)
2538     {
2539       //printf("argCnt = %d\n",argCnt);
2540       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2541     }
2542
2543   if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2544     {
2545       werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2546     }
2547
2548   if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2549     {
2550       werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2551     }
2552   
2553
2554   /* compare expected args with actual args */
2555   exargs = FUNC_ARGS(csym->type);
2556   acargs = FUNC_ARGS(sym->type);
2557
2558   /* for all the expected args do */
2559   for (argCnt = 1;
2560        exargs && acargs;
2561        exargs = exargs->next, acargs = acargs->next, argCnt++)
2562     {
2563       if (getenv("DEBUG_SANITY")) {
2564         fprintf (stderr, "checkFunction: %s ", exargs->name);
2565       }
2566       /* make sure the type is complete and sane */
2567       checkTypeSanity(exargs->etype, exargs->name);
2568
2569       /* If the actual argument is an array, any prototype
2570        * will have modified it to a pointer. Duplicate that
2571        * change here.
2572        */
2573       if (IS_AGGREGATE (acargs->type))
2574         {
2575           checkValue = copyValue (acargs);
2576           aggregateToPointer (checkValue);
2577         }
2578       else
2579         {
2580           checkValue = acargs;
2581         }
2582
2583       if (compareType (exargs->type, checkValue->type) <= 0)
2584         {
2585           werror (E_ARG_TYPE, argCnt);
2586           printFromToType(exargs->type, checkValue->type);
2587           return 0;
2588         }
2589     }
2590
2591   /* if one them ended we have a problem */
2592   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2593       (!exargs && acargs && !IS_VOID (acargs->type)))
2594     werror (E_ARG_COUNT);
2595
2596   /* replace with this defition */
2597   sym->cdef = csym->cdef;
2598   deleteSym (SymbolTab, csym, csym->name);
2599   deleteFromSeg(csym);
2600   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2601   if (IS_EXTERN (csym->etype) && !
2602       IS_EXTERN (sym->etype))
2603     {
2604       addSet (&publics, sym);
2605     }
2606   return 1;
2607 }
2608
2609 /*------------------------------------------------------------------*/
2610 /* cdbStructBlock - calls struct printing for a blcks               */
2611 /*------------------------------------------------------------------*/
2612 void cdbStructBlock (int block)
2613 {
2614   int i;
2615   bucket **table = StructTab;
2616   bucket *chain;
2617
2618   /* go thru the entire  table  */
2619   for (i = 0; i < 256; i++)
2620     {
2621       for (chain = table[i]; chain; chain = chain->next)
2622         {
2623           if (chain->block >= block)
2624             {
2625               if(debugFile)
2626                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2627             }
2628         }
2629     }
2630 }
2631
2632 /*-----------------------------------------------------------------*/
2633 /* processFuncPtrArgs - does some processing with args of func ptrs*/
2634 /*-----------------------------------------------------------------*/
2635 void 
2636 processFuncPtrArgs (sym_link * funcType)
2637 {
2638   value *val = FUNC_ARGS(funcType);
2639
2640   /* if it is void then remove parameters */
2641   if (val && IS_VOID (val->type))
2642     {
2643       FUNC_ARGS(funcType) = NULL;
2644       return;
2645     }
2646 }
2647
2648 /*-----------------------------------------------------------------*/
2649 /* processFuncArgs - does some processing with function args       */
2650 /*-----------------------------------------------------------------*/
2651 void 
2652 processFuncArgs (symbol * func)
2653 {
2654   value *val;
2655   int pNum = 1;
2656   sym_link *funcType=func->type;
2657
2658   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2659     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2660
2661   /* find the function declaration within the type */
2662   while (funcType && !IS_FUNC(funcType))
2663     funcType=funcType->next;
2664
2665   /* if this function has variable argument list */
2666   /* then make the function a reentrant one    */
2667   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2668     FUNC_ISREENT(funcType)=1;
2669
2670   /* check if this function is defined as calleeSaves
2671      then mark it as such */
2672   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2673
2674   /* loop thru all the arguments   */
2675   val = FUNC_ARGS(funcType);
2676
2677   /* if it is void then remove parameters */
2678   if (val && IS_VOID (val->type))
2679     {
2680       FUNC_ARGS(funcType) = NULL;
2681       return;
2682     }
2683
2684   /* reset regparm for the port */
2685   (*port->reset_regparms) ();
2686
2687   /* if any of the arguments is an aggregate */
2688   /* change it to pointer to the same type */
2689   while (val)
2690     {
2691       int argreg = 0;
2692       char buffer[SDCC_NAME_MAX+1];
2693       
2694       SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2695       checkTypeSanity (val->etype, buffer);
2696       
2697       /* mark it as a register parameter if
2698          the function does not have VA_ARG
2699          and as port dictates */
2700       if (!IFFUNC_HASVARARGS(funcType) &&
2701           (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
2702         {
2703           SPEC_REGPARM (val->etype) = 1;
2704           SPEC_ARGREG(val->etype) = argreg;
2705         } else if (IFFUNC_ISREENT(funcType)) {
2706             FUNC_HASSTACKPARM(funcType) = 1;
2707         }
2708
2709       if (IS_AGGREGATE (val->type))
2710         {
2711           aggregateToPointer (val);
2712         }
2713
2714       val = val->next;
2715       pNum++;
2716     }
2717
2718   /* if this is an internal generated function call */
2719   if (func->cdef) {
2720     /* ignore --stack-auto for this one, we don't know how it is compiled */
2721     /* simply trust on --int-long-reent or --float-reent */
2722     if (IFFUNC_ISREENT(funcType)) {
2723       return;
2724     }
2725   } else {
2726     /* if this function is reentrant or */
2727     /* automatics r 2b stacked then nothing */
2728     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2729       return;
2730   }
2731
2732   val = FUNC_ARGS(funcType);
2733   pNum = 1;
2734   while (val)
2735     {
2736
2737       /* if a symbolname is not given  */
2738       /* synthesize a variable name */
2739       if (!val->sym)
2740         {
2741           SNPRINTF (val->name, sizeof(val->name), 
2742                     "_%s_PARM_%d", func->name, pNum++);
2743           val->sym = newSymbol (val->name, 1);
2744           if (SPEC_SCLS(val->etype) == S_BIT)
2745             SPEC_OCLS (val->etype) = bit;
2746           else
2747             SPEC_OCLS (val->etype) = port->mem.default_local_map;
2748           val->sym->type = copyLinkChain (val->type);
2749           val->sym->etype = getSpec (val->sym->type);
2750           val->sym->_isparm = 1;
2751           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2752           #if 0
2753           /* ?? static functions shouldn't imply static parameters - EEP */
2754           if (IS_SPEC(func->etype)) {
2755             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2756               SPEC_STAT (func->etype);
2757           }
2758           #endif
2759           addSymChain (&val->sym);
2760
2761         }
2762       else                      /* symbol name given create synth name */
2763         {
2764
2765           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2766           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2767           val->sym->_isparm = 1;
2768           if (SPEC_SCLS(val->etype) == S_BIT)
2769             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2770           else
2771             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2772               port->mem.default_local_map;
2773           
2774           #if 0
2775           /* ?? static functions shouldn't imply static parameters - EEP */
2776           if (IS_SPEC(func->etype)) {
2777             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2778               SPEC_STAT (func->etype);
2779           }
2780           #endif
2781         }
2782       if (SPEC_OCLS (val->sym->etype) == pdata)
2783         val->sym->iaccess = 1;
2784       if (!isinSet(operKeyReset, val->sym)) {
2785         addSet (&operKeyReset, val->sym);
2786         applyToSet (operKeyReset, resetParmKey);
2787       }
2788       val = val->next;
2789     }
2790 }
2791
2792 /*-----------------------------------------------------------------*/
2793 /* isSymbolEqual - compares two symbols return 1 if they match     */
2794 /*-----------------------------------------------------------------*/
2795 int 
2796 isSymbolEqual (symbol * dest, symbol * src)
2797 {
2798   /* if pointers match then equal */
2799   if (dest == src)
2800     return 1;
2801
2802   /* if one of them is null then don't match */
2803   if (!dest || !src)
2804     return 0;
2805
2806   /* if both of them have rname match on rname */
2807   if (dest->rname[0] && src->rname[0])
2808     return (!strcmp (dest->rname, src->rname));
2809
2810   /* otherwise match on name */
2811   return (!strcmp (dest->name, src->name));
2812 }
2813
2814 void PT(sym_link *type)
2815 {
2816         printTypeChain(type,0);
2817 }
2818 /*-----------------------------------------------------------------*/
2819 /* printTypeChain - prints the type chain in human readable form   */
2820 /*-----------------------------------------------------------------*/
2821 void
2822 printTypeChain (sym_link * start, FILE * of)
2823 {
2824   struct dbuf_s dbuf;
2825   int nlr = 0;
2826
2827   if (!of)
2828     {
2829       of = stdout;
2830       nlr = 1;
2831     }
2832
2833   dbuf_init (&dbuf, 1024);
2834   dbuf_printTypeChain (start, &dbuf);
2835   dbuf_write_and_destroy (&dbuf, of);
2836
2837   if (nlr)
2838     putc ('\n', of);
2839 }
2840
2841 void
2842 dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
2843 {
2844   value *args;
2845   sym_link * type, * search;
2846   STORAGE_CLASS scls;
2847
2848   if (start==NULL) {
2849     dbuf_append_str (dbuf, "void");
2850     return;
2851   }
2852
2853   /* Print the chain as it is written in the source: */
2854   /* start with the last entry.                      */
2855   /* However, the storage class at the end of the    */
2856   /* chain reall applies to the first in the chain!  */
2857
2858   for (type = start; type && type->next; type = type->next)
2859     ;
2860   if (IS_SPEC (type))
2861     scls=SPEC_SCLS(type);
2862   else
2863     scls=0;
2864   while (type)
2865     {
2866       if (type==start) {
2867         switch (scls) 
2868           {
2869           case S_DATA: dbuf_append_str (dbuf, "data-"); break;
2870           case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break;
2871           case S_SFR: dbuf_append_str (dbuf, "sfr-"); break;
2872           case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break;
2873           case S_CODE: dbuf_append_str (dbuf, "code-"); break;
2874           case S_IDATA: dbuf_append_str (dbuf, "idata-"); break;
2875           case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break;
2876           case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break;
2877           case S_STACK: dbuf_append_str (dbuf, "stack-"); break;
2878           case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break;
2879           case S_BIT: dbuf_append_str (dbuf, "bit-"); break;
2880           case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break;
2881           default: break;
2882           }
2883       }
2884
2885       if (IS_DECL (type))
2886         {
2887           if (!IS_FUNC(type)) {
2888             if (DCL_PTR_VOLATILE (type)) {
2889               dbuf_append_str (dbuf, "volatile-");
2890             }
2891             if (DCL_PTR_CONST (type)) {
2892               dbuf_append_str (dbuf, "const-");
2893             }
2894             if (DCL_PTR_RESTRICT (type)) {
2895               dbuf_append_str (dbuf, "restrict-");
2896             }
2897           }
2898           switch (DCL_TYPE (type))
2899             {
2900             case FUNCTION:
2901               dbuf_printf (dbuf, "function %s %s", 
2902                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2903                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2904               dbuf_append_str (dbuf, "( ");
2905               for (args = FUNC_ARGS(type); 
2906                    args; 
2907                    args=args->next) {
2908                 dbuf_printTypeChain(args->type, dbuf);
2909                 if (args->next)
2910                   dbuf_append_str (dbuf, ", ");
2911               }
2912               dbuf_append_str (dbuf, ") ");
2913               break;
2914             case GPOINTER:
2915               dbuf_append_str (dbuf, "generic* ");
2916               break;
2917             case CPOINTER:
2918               dbuf_append_str (dbuf, "code* ");
2919               break;
2920             case FPOINTER:
2921               dbuf_append_str (dbuf, "xdata* ");
2922               break;
2923             case EEPPOINTER:
2924               dbuf_append_str (dbuf, "eeprom* ");
2925               break;
2926             case POINTER:
2927               dbuf_append_str (dbuf, "near* ");
2928               break;
2929             case IPOINTER:
2930               dbuf_append_str (dbuf, "idata* ");
2931               break;
2932             case PPOINTER:
2933               dbuf_append_str (dbuf, "pdata* ");
2934               break;
2935             case UPOINTER:
2936               dbuf_append_str (dbuf, "unknown* ");
2937               break;
2938             case ARRAY:
2939               if (DCL_ELEM(type)) {
2940                 dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type));
2941               } else {
2942                 dbuf_append_str (dbuf, "[] ");
2943               }
2944               break;
2945             }
2946         }
2947       else
2948         {
2949           if (SPEC_VOLATILE (type))
2950             dbuf_append_str (dbuf, "volatile-");
2951           if (SPEC_CONST (type))
2952             dbuf_append_str (dbuf, "const-");
2953           if (SPEC_USIGN (type))
2954             dbuf_append_str (dbuf, "unsigned-");
2955           switch (SPEC_NOUN (type))
2956             {
2957             case V_INT:
2958               if (IS_LONG (type))
2959                 dbuf_append_str (dbuf, "long-");
2960               dbuf_append_str (dbuf, "int");
2961               break;
2962
2963             case V_CHAR:
2964               dbuf_append_str (dbuf, "char");
2965               break;
2966
2967             case V_VOID:
2968               dbuf_append_str (dbuf, "void");
2969               break;
2970
2971             case V_FLOAT:
2972               dbuf_append_str (dbuf, "float");
2973               break;
2974
2975             case V_FIXED16X16:
2976               dbuf_append_str (dbuf, "fixed16x16");
2977               break;
2978
2979             case V_STRUCT:
2980               dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
2981               break;
2982
2983             case V_SBIT:
2984               dbuf_append_str (dbuf, "sbit");
2985               break;
2986
2987             case V_BIT:
2988               dbuf_append_str (dbuf, "bit");
2989               break;
2990
2991             case V_BITFIELD:
2992               dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2993               break;
2994
2995             case V_DOUBLE:
2996               dbuf_append_str (dbuf, "double");
2997               break;
2998
2999             default:
3000               dbuf_append_str (dbuf, "unknown type");
3001               break;
3002             }
3003         }
3004       /* search entry in list before "type" */
3005       for (search = start; search && search->next != type;)
3006         search = search->next;
3007       type = search;
3008       if (type)
3009           dbuf_append_char(dbuf, ' ');
3010     }
3011 }
3012
3013 /*--------------------------------------------------------------------*/
3014 /* printTypeChainRaw - prints the type chain in human readable form   */
3015 /*                     in the raw data structure ordering             */
3016 /*--------------------------------------------------------------------*/
3017 void
3018 printTypeChainRaw (sym_link * start, FILE * of)
3019 {
3020   int nlr = 0;
3021   value *args;
3022   sym_link * type;
3023
3024   if (!of)
3025     {
3026       of = stdout;
3027       nlr = 1;
3028     }
3029
3030   if (start==NULL) {
3031     fprintf (of, "void");
3032     return;
3033   }
3034
3035   type = start;
3036   
3037   while (type)
3038     {
3039       if (IS_DECL (type))
3040         {
3041           if (!IS_FUNC(type)) {
3042             if (DCL_PTR_VOLATILE (type)) {
3043               fprintf (of, "volatile-");
3044             }
3045             if (DCL_PTR_CONST (type)) {
3046               fprintf (of, "const-");
3047             }
3048             if (DCL_PTR_RESTRICT (type)) {
3049               fprintf (of, "restrict-");
3050             }
3051           }
3052           switch (DCL_TYPE (type))
3053             {
3054             case FUNCTION:
3055               if (IFFUNC_ISINLINE(type)) {
3056                 fprintf (of, "inline-");
3057               }
3058               fprintf (of, "function %s %s", 
3059                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
3060                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
3061               fprintf (of, "( ");
3062               for (args = FUNC_ARGS(type); 
3063                    args; 
3064                    args=args->next) {
3065                 printTypeChain(args->type, of);
3066                 if (args->next)
3067                   fprintf(of, ", ");
3068               }
3069               fprintf (of, ") ");
3070               break;
3071             case GPOINTER:
3072               fprintf (of, "generic* ");
3073               break;
3074             case CPOINTER:
3075               fprintf (of, "code* ");
3076               break;
3077             case FPOINTER:
3078               fprintf (of, "xdata* ");
3079               break;
3080             case EEPPOINTER:
3081               fprintf (of, "eeprom* ");
3082               break;
3083             case POINTER:
3084               fprintf (of, "near* ");
3085               break;
3086             case IPOINTER:
3087               fprintf (of, "idata* ");
3088               break;
3089             case PPOINTER:
3090               fprintf (of, "pdata* ");
3091               break;
3092             case UPOINTER:
3093               fprintf (of, "unknown* ");
3094               break;
3095             case ARRAY:
3096               if (DCL_ELEM(type)) {
3097                 fprintf (of, "[%d] ", DCL_ELEM(type));
3098               } else {
3099                 fprintf (of, "[] ");
3100               }
3101               break;
3102             }
3103           if (DCL_TSPEC(type))
3104             {
3105               fprintf (of, "{");
3106               printTypeChainRaw(DCL_TSPEC(type), of);
3107               fprintf (of, "}");
3108             }
3109         }
3110       else if (IS_SPEC (type))
3111         {
3112         switch (SPEC_SCLS (type)) 
3113           {
3114           case S_DATA: fprintf (of, "data-"); break;
3115           case S_XDATA: fprintf (of, "xdata-"); break;
3116           case S_SFR: fprintf (of, "sfr-"); break;
3117           case S_SBIT: fprintf (of, "sbit-"); break;
3118           case S_CODE: fprintf (of, "code-"); break;
3119           case S_IDATA: fprintf (of, "idata-"); break;
3120           case S_PDATA: fprintf (of, "pdata-"); break;
3121           case S_LITERAL: fprintf (of, "literal-"); break;
3122           case S_STACK: fprintf (of, "stack-"); break;
3123           case S_XSTACK: fprintf (of, "xstack-"); break;
3124           case S_BIT: fprintf (of, "bit-"); break;
3125           case S_EEPROM: fprintf (of, "eeprom-"); break;
3126           default: break;
3127           }
3128           if (SPEC_VOLATILE (type))
3129             fprintf (of, "volatile-");
3130           if (SPEC_CONST (type))
3131             fprintf (of, "const-");
3132           if (SPEC_USIGN (type))
3133             fprintf (of, "unsigned-");
3134           switch (SPEC_NOUN (type))
3135             {
3136             case V_INT:
3137               if (IS_LONG (type))
3138                 fprintf (of, "long-");
3139               fprintf (of, "int");
3140               break;
3141
3142             case V_CHAR:
3143               fprintf (of, "char");
3144               break;
3145
3146             case V_VOID:
3147               fprintf (of, "void");
3148               break;
3149
3150             case V_FLOAT:
3151               fprintf (of, "float");
3152               break;
3153
3154             case V_FIXED16X16:
3155               fprintf (of, "fixed16x16");
3156               break;
3157
3158             case V_STRUCT:
3159               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3160               break;
3161
3162             case V_SBIT:
3163               fprintf (of, "sbit");
3164               break;
3165
3166             case V_BIT:
3167               fprintf (of, "bit");
3168               break;
3169
3170             case V_BITFIELD:
3171               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3172               break;
3173
3174             case V_DOUBLE:
3175               fprintf (of, "double");
3176               break;
3177
3178             default:
3179               fprintf (of, "unknown type");
3180               break;
3181             }
3182         }
3183       else
3184         fprintf (of, "NOT_SPEC_OR_DECL");
3185       type = type->next;
3186       if (type)
3187         fputc (' ', of);
3188     }
3189   if (nlr)
3190     fprintf (of, "\n");
3191 }
3192
3193
3194 /*-----------------------------------------------------------------*/
3195 /* powof2 - returns power of two for the number if number is pow 2 */
3196 /*-----------------------------------------------------------------*/
3197 int
3198 powof2 (TYPE_TARGET_ULONG num)
3199 {
3200   int nshifts = 0;
3201   int n1s = 0;
3202
3203   while (num)
3204     {
3205       if (num & 1)
3206         n1s++;
3207       num >>= 1;
3208       nshifts++;
3209     }
3210
3211   if (n1s > 1 || nshifts == 0)
3212     return -1;
3213   return nshifts - 1;
3214 }
3215
3216 symbol *__fsadd;
3217 symbol *__fssub;
3218 symbol *__fsmul;
3219 symbol *__fsdiv;
3220 symbol *__fseq;
3221 symbol *__fsneq;
3222 symbol *__fslt;
3223 symbol *__fslteq;
3224 symbol *__fsgt;
3225 symbol *__fsgteq;
3226
3227 symbol *__fps16x16_add;
3228 symbol *__fps16x16_sub;
3229 symbol *__fps16x16_mul;
3230 symbol *__fps16x16_div;
3231 symbol *__fps16x16_eq;
3232 symbol *__fps16x16_neq;
3233 symbol *__fps16x16_lt;
3234 symbol *__fps16x16_lteq;
3235 symbol *__fps16x16_gt;
3236 symbol *__fps16x16_gteq;
3237
3238 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3239 symbol *__muldiv[3][3][2];
3240 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3241 sym_link *__multypes[3][2];
3242 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3243 symbol *__conv[2][3][2];
3244 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
3245 symbol *__fp16x16conv[2][4][2];
3246 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3247 symbol *__rlrr[2][3][2];
3248
3249 sym_link *floatType;
3250 sym_link *fixed16x16Type;
3251
3252 static char *
3253 _mangleFunctionName(char *in)
3254 {
3255   if (port->getMangledFunctionName)
3256     {
3257       return port->getMangledFunctionName(in);
3258     }
3259   else
3260     {
3261       return in;
3262     }
3263 }
3264
3265 /*-----------------------------------------------------------------*/
3266 /* typeFromStr - create a typechain from an encoded string         */
3267 /* basic types -        'c' - char                                 */
3268 /*                      's' - short                                */
3269 /*                      'i' - int                                  */
3270 /*                      'l' - long                                 */
3271 /*                      'f' - float                                */
3272 /*                      'q' - fixed16x16                           */
3273 /*                      'v' - void                                 */
3274 /*                      '*' - pointer - default (GPOINTER)         */
3275 /* modifiers -          'u' - unsigned                             */
3276 /* pointer modifiers -  'g' - generic                              */
3277 /*                      'x' - xdata                                */
3278 /*                      'p' - code                                 */
3279 /*                      'd' - data                                 */                     
3280 /*                      'F' - function                             */                     
3281 /* examples : "ig*" - generic int *                                */
3282 /*            "cx*" - char xdata *                                 */
3283 /*            "ui" -  unsigned int                                 */
3284 /*-----------------------------------------------------------------*/
3285 sym_link *typeFromStr (char *s)
3286 {
3287     sym_link *r = newLink(DECLARATOR);
3288     int usign = 0;
3289
3290     do {
3291         sym_link *nr;
3292         switch (*s) {
3293         case 'u' : 
3294             usign = 1;
3295             s++;
3296             continue ;
3297             break ;
3298         case 'c':
3299             r->class = SPECIFIER;
3300             SPEC_NOUN(r) = V_CHAR;
3301             break;
3302         case 's':
3303         case 'i':
3304             r->class = SPECIFIER;
3305             SPEC_NOUN(r) = V_INT;
3306             break;
3307         case 'l':
3308             r->class = SPECIFIER;
3309             SPEC_NOUN(r) = V_INT;
3310             SPEC_LONG(r) = 1;
3311             break;
3312         case 'f':
3313             r->class = SPECIFIER;
3314             SPEC_NOUN(r) = V_FLOAT;
3315             break;
3316         case 'q':
3317             r->class = SPECIFIER;
3318             SPEC_NOUN(r) = V_FIXED16X16;
3319             break;
3320         case 'v':
3321             r->class = SPECIFIER;
3322             SPEC_NOUN(r) = V_VOID;
3323             break;
3324         case '*':
3325             DCL_TYPE(r) = port->unqualified_pointer;
3326             break;
3327         case 'g':
3328         case 'x':
3329         case 'p':
3330         case 'd':
3331         case 'F':
3332             assert(*(s+1)=='*');
3333             nr = newLink(DECLARATOR);
3334             nr->next = r;
3335             r = nr;
3336             switch (*s) {
3337             case 'g':
3338                 DCL_TYPE(r) = GPOINTER;
3339                 break;
3340             case 'x':
3341                 DCL_TYPE(r) = FPOINTER;
3342                 break;
3343             case 'p':
3344                 DCL_TYPE(r) = CPOINTER;
3345                 break;
3346             case 'd':
3347                 DCL_TYPE(r) = POINTER;
3348                 break;
3349             case 'F':
3350                 DCL_TYPE(r) = FUNCTION;
3351                 nr = newLink(DECLARATOR);
3352                 nr->next = r;
3353                 r = nr;
3354                 DCL_TYPE(r) = CPOINTER;
3355                 break;
3356             }
3357             s++;
3358             break;
3359         default:
3360             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
3361                    "typeFromStr: unknown type");
3362             break;
3363         }
3364         if (IS_SPEC(r) && usign) {
3365             SPEC_USIGN(r) = 1;
3366             usign = 0;
3367         }
3368         s++;
3369     } while (*s);
3370     return r;
3371 }
3372
3373 /*-----------------------------------------------------------------*/
3374 /* initCSupport - create functions for C support routines          */
3375 /*-----------------------------------------------------------------*/
3376 void 
3377 initCSupport ()
3378 {
3379   const char *smuldivmod[] =
3380   {
3381     "mul", "div", "mod"
3382   };
3383   const char *sbwd[] =
3384   {
3385     "char", "int", "long", "fixed16x16",
3386   };
3387   const char *fp16x16sbwd[] =
3388   {
3389     "char", "int", "long", "float",
3390   };
3391   const char *ssu[] =
3392   {
3393     "s", "u"
3394   };
3395   const char *srlrr[] =
3396   {
3397     "rl", "rr"
3398   };
3399
3400   int bwd, su, muldivmod, tofrom, rlrr;
3401
3402   if (getenv("SDCC_NO_C_SUPPORT")) {
3403     /* for debugging only */
3404     return;
3405   }
3406
3407   floatType = newFloatLink ();
3408   fixed16x16Type = newFixed16x16Link ();
3409
3410   for (bwd = 0; bwd < 3; bwd++)
3411     {
3412       sym_link *l = NULL;
3413       switch (bwd)
3414         {
3415         case 0:
3416           l = newCharLink ();
3417           break;
3418         case 1:
3419           l = newIntLink ();
3420           break;
3421         case 2:
3422           l = newLongLink ();
3423           break;
3424         default:
3425           assert (0);
3426         }
3427       __multypes[bwd][0] = l;
3428       __multypes[bwd][1] = copyLinkChain (l);
3429       SPEC_USIGN (__multypes[bwd][1]) = 1;
3430     }
3431
3432   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3433   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3434   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3435   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3436   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3437   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3438   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3439   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3440   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3441   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3442
3443   __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3444   __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3445   __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3446   __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3447   __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3448   __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3449   __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3450   __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3451   __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3452   __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3453
3454
3455   for (tofrom = 0; tofrom < 2; tofrom++)
3456     {
3457       for (bwd = 0; bwd < 3; bwd++)
3458         {
3459           for (su = 0; su < 2; su++)
3460             {
3461               if (tofrom)
3462                 {
3463                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3464                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3465                 }
3466               else
3467                 {
3468                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3469                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3470                 }
3471             }
3472         }
3473     }
3474
3475   for (tofrom = 0; tofrom < 2; tofrom++)
3476     {
3477       for (bwd = 0; bwd < 4; bwd++)
3478         {
3479           for (su = 0; su < 2; su++)
3480             {
3481               if (tofrom)
3482                 {
3483                   SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
3484                   if(bwd == 3) {
3485                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
3486                   } else
3487                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
3488                 }
3489               else
3490                 {
3491                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
3492                   if(bwd == 3) {
3493                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
3494                   } else
3495                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
3496                 }
3497             }
3498         }
3499     }
3500
3501 /*
3502   for (muldivmod = 0; muldivmod < 3; muldivmod++)
3503     {
3504       for (bwd = 0; bwd < 3; bwd++)
3505         {
3506           for (su = 0; su < 2; su++)
3507             {
3508               SNPRINTF (buffer, sizeof(buffer),
3509                         "_%s%s%s",
3510                        smuldivmod[muldivmod],
3511                        ssu[su],
3512                        sbwd[bwd]);
3513               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3514               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3515             }
3516         }
3517     }
3518
3519   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3520   Therefore they've been merged into mulint() and mullong().
3521 */
3522
3523   for (bwd = 0; bwd < 3; bwd++)
3524     {
3525       for (su = 0; su < 2; su++)
3526         {
3527           for (muldivmod = 1; muldivmod < 3; muldivmod++)
3528             {
3529               /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
3530               if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0)
3531               {
3532                 SNPRINTF (buffer, sizeof(buffer),
3533                     "_%s%s%s",
3534                     smuldivmod[muldivmod],
3535                     ssu[su],
3536                     sbwd[bwd]);
3537                 __muldiv[muldivmod][bwd][su] = funcOfType (
3538                     _mangleFunctionName(buffer),
3539                     __multypes[bwd][su],
3540                     __multypes[bwd][su],
3541                     2,
3542                     options.intlong_rent);
3543                 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3544               }
3545             }
3546         }
3547     }
3548
3549   if (TARGET_IS_PIC16)
3550   {
3551     /* PIC16 port wants __divschar/__modschar to return an int, so that both
3552      * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
3553      * (first one would have to be sign extended, second one must not be).
3554      * Similarly, modschar should be handled, but the iCode introduces cast
3555      * here and forces '% : s8 x s8 -> s8' ... */
3556     su = 0; bwd = 0;
3557     for (muldivmod = 1; muldivmod < 2; muldivmod++) {
3558       SNPRINTF (buffer, sizeof(buffer),
3559           "_%s%s%s",
3560           smuldivmod[muldivmod],
3561           ssu[su],
3562           sbwd[bwd]);
3563       __muldiv[muldivmod][bwd][su] = funcOfType (
3564           _mangleFunctionName(buffer),
3565           __multypes[1][su],
3566           __multypes[bwd][su],
3567           2,
3568           options.intlong_rent);
3569       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3570     }
3571   }
3572
3573   /* mul only */
3574   muldivmod = 0;
3575   /* byte */
3576   bwd = 0;
3577   for (su = 0; su < 2; su++)
3578     {
3579       /* muluchar and mulschar are still separate functions, because e.g. the z80
3580          port is sign/zero-extending to int before calling mulint() */
3581       SNPRINTF (buffer, sizeof(buffer),
3582                 "_%s%s%s",
3583                 smuldivmod[muldivmod],
3584                 ssu[su],
3585                 sbwd[bwd]);
3586       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3587       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3588     }
3589   /* signed only */
3590   su = 0;
3591   /* word and doubleword */
3592   for (bwd = 1; bwd < 3; bwd++)
3593     {
3594       /* mul, int/long */
3595       SNPRINTF (buffer, sizeof(buffer),
3596                 "_%s%s",
3597                 smuldivmod[muldivmod],
3598                 sbwd[bwd]);
3599       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3600       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3601       /* signed = unsigned */
3602       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3603     }
3604
3605   for (rlrr = 0; rlrr < 2; rlrr++)
3606     {
3607       for (bwd = 0; bwd < 3; bwd++)
3608         {
3609           for (su = 0; su < 2; su++)
3610             {
3611               SNPRINTF (buffer, sizeof(buffer),
3612                         "_%s%s%s",
3613                        srlrr[rlrr],
3614                        ssu[su],
3615                        sbwd[bwd]);
3616               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3617               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3618             }
3619         }
3620     }
3621 }
3622
3623 /*-----------------------------------------------------------------*/
3624 /* initBuiltIns - create prototypes for builtin functions          */
3625 /*-----------------------------------------------------------------*/
3626 void initBuiltIns()
3627 {
3628     int i;
3629     symbol *sym;
3630
3631     if (!port->builtintable) return ;
3632
3633     for (i = 0 ; port->builtintable[i].name ; i++) {
3634         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3635                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3636         FUNC_ISBUILTIN(sym->type) = 1;
3637         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3638     }
3639 }
3640
3641 sym_link *validateLink(sym_link         *l,
3642                         const char      *macro,
3643                         const char      *args,
3644                         const char      select,
3645                         const char      *file,
3646                         unsigned        line)
3647 {    
3648   if (l && l->class==select)
3649     {
3650         return l;
3651     }
3652     fprintf(stderr, 
3653             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3654             " expected %s, got %s\n",
3655             macro, args, file, line, 
3656             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3657     exit(EXIT_FAILURE);
3658     return l; // never reached, makes compiler happy.
3659 }
3660
3661 /*--------------------------------------------------------------------*/
3662 /* newEnumType - create an integer type compatible with enumerations  */
3663 /*--------------------------------------------------------------------*/
3664 sym_link *
3665 newEnumType (symbol *enumlist)
3666 {
3667   int min, max, v;
3668   symbol *sym;
3669   sym_link *type;
3670
3671   if (!enumlist)
3672     {
3673       type = newLink (SPECIFIER);
3674       SPEC_NOUN (type) = V_INT;
3675       return type;
3676     }
3677       
3678   /* Determine the range of the enumerated values */
3679   sym = enumlist;
3680   min = max = (int) floatFromVal (valFromType (sym->type));
3681   for (sym = sym->next; sym; sym = sym->next)
3682     {
3683       v = (int) floatFromVal (valFromType (sym->type));
3684       if (v<min)
3685         min = v;
3686       if (v>max)
3687         max = v;
3688     }
3689
3690   /* Determine the smallest integer type that is compatible with this range */
3691   type = newLink (SPECIFIER);
3692   if (min>=0 && max<=255)
3693     {
3694       SPEC_NOUN (type) = V_CHAR;
3695       SPEC_USIGN (type) = 1;
3696     }
3697   else if (min>=-128 && max<=127)
3698     {
3699       SPEC_NOUN (type) = V_CHAR;
3700     }
3701   else if (min>=0 && max<=65535)
3702     {
3703       SPEC_NOUN (type) = V_INT;
3704       SPEC_USIGN (type) = 1;
3705     }
3706   else if (min>=-32768 && max<=32767)
3707     {
3708       SPEC_NOUN (type) = V_INT;
3709     }
3710   else
3711     {
3712       SPEC_NOUN (type) = V_INT;
3713       SPEC_LONG (type) = 1;
3714       if (min>=0)
3715         SPEC_USIGN (type) = 1;
3716     }
3717   
3718   return type;
3719 }