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