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