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