* as/hc08/lkaomf51.c (OutputName),
[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         !funcInChain (sym->type))
1591       werror (E_CODE_NO_INIT, sym->name);
1592   }
1593
1594   /* if parameter or local variable then change */
1595   /* the storage class to reflect where the var will go */
1596   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
1597    && !IS_STATIC(sym->etype)
1598       )
1599     {
1600       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1601         {
1602           SPEC_SCLS (sym->etype) = (options.useXstack ?
1603                                     S_XSTACK : S_STACK);
1604         }
1605       else
1606         {
1607           /* hack-o-matic! I see no reason why the useXstack option should ever
1608            * control this allocation, but the code was originally that way, and
1609            * changing it for non-390 ports breaks the compiler badly.
1610            */
1611           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1612                 1 : options.useXstack;
1613           SPEC_SCLS (sym->etype) = (useXdata ?
1614                                     S_XDATA : S_FIXED);
1615         }
1616     }
1617 }
1618
1619 /*------------------------------------------------------------------*/
1620 /* changePointer - change pointer to functions                      */
1621 /*------------------------------------------------------------------*/
1622 void 
1623 changePointer (sym_link * p)
1624 {
1625
1626   /* go thru the chain of declarations   */
1627   /* if we find a pointer to a function  */
1628   /* change it to a ptr to code area     */
1629   /* unless the function is banked.      */
1630   for (; p; p = p->next)
1631     {
1632       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1633         DCL_TYPE (p) = port->unqualified_pointer;
1634       if (IS_PTR (p) && IS_FUNC (p->next))
1635         if (!IFFUNC_BANKED(p->next))
1636         DCL_TYPE (p) = CPOINTER;
1637     }
1638 }
1639
1640 /*------------------------------------------------------------------*/
1641 /* checkDecl - does semantic validation of a declaration                   */
1642 /*------------------------------------------------------------------*/
1643 int 
1644 checkDecl (symbol * sym, int isProto)
1645 {
1646
1647   checkSClass (sym, isProto);           /* check the storage class      */
1648   changePointer (sym->type);          /* change pointers if required */
1649
1650   /* if this is an array without any dimension
1651      then update the dimension from the initial value */
1652   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1653     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1654
1655   return 0;
1656 }
1657
1658 /*------------------------------------------------------------------*/
1659 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1660 /*------------------------------------------------------------------*/
1661 sym_link *
1662 copyLinkChain (sym_link * p)
1663 {
1664   sym_link *head, *curr, *loop;
1665
1666   /* note: v_struct and v_struct->fields are not copied! */
1667   curr = p;
1668   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1669   while (curr)
1670     {
1671       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1672       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1673       loop = loop->next;
1674       curr = curr->next;
1675     }
1676
1677   return head;
1678 }
1679
1680 /*------------------------------------------------------------------*/
1681 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1682 /*                symbols in the given block                        */
1683 /*------------------------------------------------------------------*/
1684 void 
1685 cleanUpBlock (bucket ** table, int block)
1686 {
1687   int i;
1688   bucket *chain;
1689
1690   /* go thru the entire  table  */
1691   for (i = 0; i < 256; i++)
1692     {
1693       for (chain = table[i]; chain; chain = chain->next)
1694         {
1695           if (chain->block >= block)
1696             {
1697               deleteSym (table, chain->sym, chain->name);
1698             }
1699         }
1700     }
1701 }
1702
1703 /*------------------------------------------------------------------*/
1704 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1705 /*                symbols in the given level                        */
1706 /*------------------------------------------------------------------*/
1707 void 
1708 cleanUpLevel (bucket ** table, int level)
1709 {
1710   int i;
1711   bucket *chain;
1712
1713   /* go thru the entire  table  */
1714   for (i = 0; i < 256; i++)
1715     {
1716       for (chain = table[i]; chain; chain = chain->next)
1717         {
1718           if (chain->level >= level)
1719             {
1720               deleteSym (table, chain->sym, chain->name);
1721             }
1722         }
1723     }
1724 }
1725
1726 /*------------------------------------------------------------------*/
1727 /* computeTypeOr - computes the resultant type from two types       */
1728 /*------------------------------------------------------------------*/
1729 static sym_link *
1730 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1731 {
1732   /* sanity check */
1733   assert (   (IS_CHAR (etype1) || IS_BIT (etype1))
1734           && (IS_CHAR (etype2) || IS_BIT (etype2)));
1735
1736   if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1737     {
1738       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1739       return reType;
1740     }
1741   
1742   if (SPEC_USIGN (etype1))
1743     {
1744       if (   IS_LITERAL (etype2)
1745           && floatFromVal (valFromType (etype2)) >= 0)
1746         SPEC_USIGN (reType) = 1;
1747       else
1748         {
1749           /* promote to int */
1750           SPEC_USIGN (reType) = 0;
1751           SPEC_NOUN (reType) = V_INT;
1752         }
1753     }
1754   else /* etype1 signed */
1755     {
1756       if (   IS_LITERAL (etype2)
1757           && floatFromVal (valFromType (etype2)) <= 127)
1758         SPEC_USIGN (reType) = 0;
1759       else
1760         {
1761           /* promote to int */
1762           SPEC_USIGN (reType) = 0;
1763           SPEC_NOUN (reType) = V_INT;
1764         }
1765     }
1766
1767   if (SPEC_USIGN (etype2))
1768     {
1769       if (   IS_LITERAL (etype1)
1770           && floatFromVal (valFromType (etype1)) >= 0)
1771         SPEC_USIGN (reType) = 1;
1772       else
1773         {
1774           /* promote to int */
1775           SPEC_USIGN (reType) = 0;
1776           SPEC_NOUN (reType) = V_INT;
1777         }
1778     }
1779   else /* etype2 signed */
1780     {
1781       if (   IS_LITERAL (etype1)
1782           && floatFromVal (valFromType (etype1)) <= 127)
1783         SPEC_USIGN (reType) = 0;
1784       else
1785         {
1786           /* promote to int */
1787           SPEC_USIGN (reType) = 0;
1788           SPEC_NOUN (reType) = V_INT;
1789         }
1790     }
1791   return reType;
1792 }
1793
1794 /*------------------------------------------------------------------*/
1795 /* computeType - computes the resultant type from two types         */
1796 /*------------------------------------------------------------------*/
1797 sym_link *
1798 computeType (sym_link * type1, sym_link * type2,
1799              RESULT_TYPE resultType, int op)
1800 {
1801   sym_link *rType;
1802   sym_link *reType;
1803   sym_link *etype1 = getSpec (type1);
1804   sym_link *etype2;
1805
1806   etype2 = type2 ? getSpec (type2) : type1;
1807
1808   /* if one of them is a float then result is a float */
1809   /* here we assume that the types passed are okay */
1810   /* and can be cast to one another                */
1811   /* which ever is greater in size */
1812   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1813     rType = newFloatLink ();
1814   /* if both are fixed16x16 then result is float */
1815   else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
1816     rType = newFixed16x16Link();
1817   else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
1818     rType = newFloatLink ();
1819   else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
1820     rType = newFloatLink ();
1821             
1822   /* if both are bitvars choose the larger one */
1823   else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1824     rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1825             copyLinkChain (type1) : copyLinkChain (type1);
1826                           
1827   /* if only one of them is a bit variable then the other one prevails */
1828   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1829     {
1830       rType = copyLinkChain (type2);
1831       /* bitfield can have up to 16 bits */
1832       if (getSize (etype1) > 1)
1833         SPEC_NOUN (getSpec (rType)) = V_INT;
1834     }
1835   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1836     {
1837       rType = copyLinkChain (type1);
1838       /* bitfield can have up to 16 bits */
1839       if (getSize (etype2) > 1)
1840         SPEC_NOUN (getSpec (rType)) = V_INT;
1841     }
1842   /* if one of them is a pointer or array then that
1843      prevails */
1844   else if (IS_PTR (type1) || IS_ARRAY (type1))
1845     rType = copyLinkChain (type1);
1846   else if (IS_PTR (type2) || IS_ARRAY (type2))
1847     rType = copyLinkChain (type2);
1848   else if (getSize (type1) > getSize (type2))
1849     rType = copyLinkChain (type1);
1850   else
1851     rType = copyLinkChain (type2);
1852
1853   reType = getSpec (rType);
1854
1855   /* avoid conflicting types */
1856   reType->select.s.b_signed = 0;
1857
1858   /* if result is a literal then make not so */
1859   if (IS_LITERAL (reType))
1860     SPEC_SCLS (reType) = S_REGISTER;
1861
1862   switch (resultType)
1863     {
1864       case RESULT_TYPE_CHAR:
1865         if (IS_BITVAR (reType))
1866           {
1867             SPEC_NOUN (reType) = V_CHAR;
1868             SPEC_SCLS (reType) = 0;
1869             SPEC_USIGN (reType) = 0;
1870             return rType;
1871           }
1872         break;
1873       case RESULT_TYPE_INT:
1874       case RESULT_TYPE_NONE:
1875       case RESULT_TYPE_OTHER:
1876         if (IS_BIT (reType))
1877           {
1878             SPEC_NOUN (reType) = V_CHAR;
1879             SPEC_SCLS (reType) = 0;
1880             SPEC_USIGN (reType) = 0;
1881             return rType;
1882           }
1883         else if (IS_BITFIELD (reType))
1884           {
1885             /* could be smarter, but it depends on the op */
1886             /* this is for the worst case: a multiplication of 4 * 4 bit */
1887             SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1888             SPEC_SCLS (reType) = 0;
1889             SPEC_USIGN (reType) = 0;
1890             return rType;
1891           }
1892         else if (IS_CHAR (reType))
1893           {
1894             /* promotion of some special cases */
1895             switch (op)
1896               {
1897                 case '|':
1898                 case '^':
1899                   return computeTypeOr (etype1, etype2, reType);
1900                 case '&':
1901                   if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1902                     {
1903                       SPEC_USIGN (reType) = 1;
1904                       return rType;
1905                     }
1906                   break;
1907                 case '*':
1908                   SPEC_NOUN (reType) = V_INT;
1909                   SPEC_USIGN (reType) = 0;
1910                   return rType;
1911                 case '/':
1912                   /* if both are unsigned char then no promotion required */
1913                   if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
1914                     {
1915                       SPEC_NOUN (reType) = V_INT;
1916                       SPEC_USIGN (reType) = 0;
1917                       return rType;
1918                     }
1919                   break;
1920                 default:
1921                   break;
1922               }
1923           }
1924         break;
1925       default:
1926         break;
1927     }
1928
1929   /* SDCC's sign promotion:
1930      - if one or both operands are unsigned, the resultant type will be unsigned
1931        (except char, see below)
1932      - if an operand is promoted to a larger type (char -> int, int -> long),
1933        the larger type will be signed
1934
1935      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1936      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1937      the standard. The standard demands, that the result has to be the same
1938      "as if" the promotion would have been performed:
1939
1940      - if the result of an operation with two char's is promoted to a
1941        larger type, the result will be signed.
1942
1943      More sophisticated are these:
1944      - if the result of an operation with two char's is a char again,
1945        the result will only then be unsigned, if both operands are
1946        unsigned. In all other cases the result will be signed.
1947
1948        This seems to be contradictionary to the first two rules, but it makes
1949        real sense (all types are char's):
1950
1951         A signed char can be negative; this must be preserved in the result
1952                 -1 * 100 = -100;
1953
1954         Only if both operands are unsigned it's safe to make the result
1955         unsigned; this helps to avoid overflow:
1956                 2 * 100 =  200;
1957
1958      - ToDo: document '|', '^' and '&'
1959      
1960      Homework: - why is (200 * 200 < 0) true?
1961                - why is { char l = 200, r = 200; (r * l > 0) } true?
1962   */
1963
1964   if (!IS_FLOAT (reType)
1965       && (   (SPEC_USIGN (etype1)
1966               /* if this operand is promoted to a larger type,
1967                  then it will be promoted to a signed type */
1968               && !(bitsForType (etype1) < bitsForType (reType))
1969               /* char require special handling */
1970               && !IS_CHAR (etype1))
1971           || /* same for 2nd operand */  
1972              (SPEC_USIGN (etype2)
1973               && !(bitsForType (etype2) < bitsForType (reType))
1974               && !IS_CHAR (etype2))
1975           || /* if both are 'unsigned char' and not promoted
1976                 let the result be unsigned too */
1977              (   SPEC_USIGN (etype1)
1978               && SPEC_USIGN (etype2)
1979               && IS_CHAR (etype1)
1980               && IS_CHAR (etype2)
1981               && IS_CHAR (reType))))
1982     SPEC_USIGN (reType) = 1;
1983   else
1984     SPEC_USIGN (reType) = 0;
1985
1986   return rType;
1987 }
1988
1989 /*--------------------------------------------------------------------*/
1990 /* compareType - will do type check return 1 if match, -1 if castable */
1991 /*--------------------------------------------------------------------*/
1992 int
1993 compareType (sym_link * dest, sym_link * src)
1994 {
1995   if (!dest && !src)
1996     return 1;
1997
1998   if (dest && !src)
1999     return 0;
2000
2001   if (src && !dest)
2002     return 0;
2003
2004   /* if dest is a declarator then */
2005   if (IS_DECL (dest))
2006     {
2007       if (IS_DECL (src))
2008         {
2009           /* banked function pointer */
2010           if (IS_GENPTR (dest) && IS_GENPTR (src))
2011             {
2012               if (IS_FUNC (src->next) && IS_VOID(dest->next))
2013                 return -1;
2014               if (IS_FUNC (dest->next) && IS_VOID(src->next))
2015                 return -1;
2016               return compareType (dest->next, src->next);
2017             }
2018
2019           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2020             if (IS_FUNC(src)) {
2021               //checkFunction(src,dest);
2022             }
2023             return compareType (dest->next, src->next);
2024           }
2025           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
2026             return -1;
2027           }
2028           if (IS_PTR (src) && 
2029               (IS_GENPTR (dest) ||
2030                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
2031              ))
2032             return -1;
2033           if (IS_PTR (dest) && IS_ARRAY (src)) {
2034             value *val=aggregateToPointer (valFromType(src));
2035             int res=compareType (dest, val->type);
2036             Safe_free(val->type);
2037             Safe_free(val);
2038             return res;
2039           }
2040           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2041             return compareType (dest->next, src);
2042           return 0;
2043         }
2044       else if (IS_PTR (dest) && IS_INTEGRAL (src))
2045         return -1;
2046       else
2047         return 0;
2048     }
2049
2050   /* if one is a specifier and the other is not */
2051   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2052       (IS_SPEC (dest) && !IS_SPEC (src)))
2053     return 0;
2054
2055   /* if one of them is a void then ok */
2056   if (SPEC_NOUN (dest) == V_VOID &&
2057       SPEC_NOUN (src) != V_VOID)
2058     return -1;
2059
2060   if (SPEC_NOUN (dest) != V_VOID &&
2061       SPEC_NOUN (src) == V_VOID)
2062     return -1;
2063
2064   /* if they are both bitfields then if the lengths
2065      and starts don't match */
2066   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2067       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2068        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2069     return -1;
2070
2071   /* it is a specifier */
2072   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2073     {
2074       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
2075           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2076           /* I would prefer
2077           bitsForType (dest) == bitsForType (src))
2078              instead of the next two lines, but the regression tests fail with
2079              them; I guess it's a problem with replaceCheaperOp  */
2080           getSize (dest) == getSize (src) &&
2081           !(!IS_BIT (dest) && IS_BIT (src)))
2082         return 1;
2083       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2084         return -1;
2085       else
2086         return 0;
2087     }
2088   else if (IS_STRUCT (dest))
2089     {
2090       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2091         return 0;
2092       else
2093         return 1;
2094     }
2095   if (SPEC_LONG (dest) != SPEC_LONG (src))
2096     return -1;
2097
2098   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2099     return -1;
2100
2101   return 1;
2102 }
2103
2104 /*--------------------------------------------------------------------*/
2105 /* compareTypeExact - will do type check return 1 if match exactly    */
2106 /*--------------------------------------------------------------------*/
2107 int
2108 compareTypeExact (sym_link * dest, sym_link * src, int level)
2109 {
2110   STORAGE_CLASS srcScls, destScls;
2111   
2112   if (!dest && !src)
2113     return 1;
2114
2115   if (dest && !src)
2116     return 0;
2117
2118   if (src && !dest)
2119     return 0;
2120
2121   /* if dest is a declarator then */
2122   if (IS_DECL (dest))
2123     {
2124       if (IS_DECL (src))
2125         {
2126           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2127             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2128               return 0;
2129             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2130               return 0;
2131             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2132               return 0;
2133             if (IS_FUNC(src))
2134               {
2135                 value *exargs, *acargs, *checkValue;
2136
2137                 /* verify function return type */
2138                 if (!compareTypeExact (dest->next, src->next, -1))
2139                   return 0;
2140                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2141                   return 0;
2142                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2143                   return 0;
2144                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2145                   return 0;
2146                 #if 0
2147                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2148                   return 0;
2149                 #endif
2150
2151                 /* compare expected args with actual args */
2152                 exargs = FUNC_ARGS(dest);
2153                 acargs = FUNC_ARGS(src);
2154
2155                 /* for all the expected args do */
2156                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2157                   {
2158                     //checkTypeSanity(acargs->etype, acargs->name);
2159
2160                     if (IS_AGGREGATE (acargs->type))
2161                       {
2162                         checkValue = copyValue (acargs);
2163                         aggregateToPointer (checkValue);
2164                       }
2165                     else
2166                       checkValue = acargs;
2167
2168                     #if 0
2169                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
2170                       return 0;
2171                     #endif
2172                   }
2173
2174                   /* if one them ended we have a problem */
2175                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2176                       (!exargs && acargs && !IS_VOID (acargs->type)))
2177                     return 0;                  
2178                   return 1;
2179               }
2180             return compareTypeExact (dest->next, src->next, level);
2181           }
2182           return 0;
2183         }
2184       return 0;
2185     }
2186
2187   /* if one is a specifier and the other is not */
2188   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2189       (IS_SPEC (dest) && !IS_SPEC (src)))
2190     return 0;
2191
2192   /* if one of them is a void then ok */
2193   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2194     return 0;
2195
2196   /* if they are both bitfields then if the lengths
2197      and starts don't match */
2198   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2199       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2200        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2201     return 0;
2202
2203   if (IS_INTEGRAL (dest))
2204     {
2205       /* signedness must match */
2206       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2207         return 0;
2208       /* size must match */
2209       if (SPEC_LONG (dest) != SPEC_LONG (src))
2210         return 0;
2211       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2212         return 0;
2213     }
2214   
2215   if (IS_STRUCT (dest))
2216     {
2217       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2218         return 0;
2219     }
2220
2221   if (SPEC_CONST (dest) != SPEC_CONST (src))
2222     return 0;
2223   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2224     return 0;
2225   if (SPEC_STAT (dest) != SPEC_STAT (src))
2226     return 0;
2227   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2228     return 0;
2229   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2230     return 0;
2231       
2232   destScls = SPEC_SCLS (dest);
2233   srcScls = SPEC_SCLS (src);
2234   
2235   /* Compensate for const to const code change in checkSClass() */
2236   if (!level & port->mem.code_ro && SPEC_CONST (dest))
2237     {
2238       if (srcScls == S_CODE && destScls == S_FIXED)
2239         destScls = S_CODE;
2240       if (destScls == S_CODE && srcScls == S_FIXED)
2241         srcScls = S_CODE;
2242     }
2243
2244   /* compensate for allocGlobal() */  
2245   if ((srcScls == S_FIXED || srcScls == S_AUTO)
2246       && port->mem.default_globl_map == xdata
2247       && !level)
2248     srcScls = S_XDATA;
2249   
2250   if (level>0 && !SPEC_STAT (dest))
2251     {
2252       /* Compensate for hack-o-matic in checkSClass() */
2253       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2254         {
2255           if (destScls == S_FIXED)
2256             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2257           if (srcScls == S_FIXED)
2258             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2259         }
2260       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2261         {
2262           if (destScls == S_FIXED)
2263             destScls = S_XDATA;
2264           if (srcScls == S_FIXED)
2265             srcScls = S_XDATA;
2266         }
2267     }
2268
2269   if (srcScls != destScls)
2270     {
2271       #if 0
2272       printf ("level = %d\n", level);
2273       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2274                 SPEC_SCLS (src), SPEC_SCLS (dest));
2275       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2276       #endif
2277       return 0;
2278     }
2279   
2280   return 1;
2281 }
2282
2283 /*------------------------------------------------------------------*/
2284 /* inCalleeSaveList - return 1 if found in callee save list          */
2285 /*------------------------------------------------------------------*/
2286 static int
2287 calleeCmp(void *p1, void *p2)
2288 {
2289   return (strcmp((char *)p1, (char *)(p2)) == 0);
2290 }
2291
2292 bool
2293 inCalleeSaveList(char *s)
2294 {
2295   if (options.all_callee_saves)
2296     return 1;
2297   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2298 }
2299
2300 /*-----------------------------------------------------------------*/
2301 /* aggregateToPointer:  change an agggregate type function      */
2302 /*         argument to a pointer to that type.     */
2303 /*-----------------------------------------------------------------*/
2304 value *
2305 aggregateToPointer (value * val)
2306 {
2307   if (IS_AGGREGATE (val->type))
2308     {
2309       /* if this is a structure */
2310       /* then we need to add a new link */
2311       if (IS_STRUCT (val->type))
2312         {
2313           /* first lets add DECLARATOR type */
2314           sym_link *p = val->type;
2315
2316           werror (W_STRUCT_AS_ARG, val->name);
2317           val->type = newLink (DECLARATOR);
2318           val->type->next = p;
2319         }
2320
2321       /* change to a pointer depending on the */
2322       /* storage class specified        */
2323       switch (SPEC_SCLS (val->etype))
2324         {
2325         case S_IDATA:
2326           DCL_TYPE (val->type) = IPOINTER;
2327           break;
2328         case S_PDATA:
2329           DCL_TYPE (val->type) = PPOINTER;
2330           break;
2331         case S_FIXED:
2332           if (SPEC_OCLS(val->etype)) {
2333             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2334           } else {
2335             // this happens for (external) function parameters
2336             DCL_TYPE (val->type) = port->unqualified_pointer;
2337           }
2338           break;
2339         case S_AUTO:
2340         case S_DATA:
2341         case S_REGISTER:
2342           DCL_TYPE (val->type) = POINTER;
2343           break;
2344         case S_CODE:
2345           DCL_TYPE (val->type) = CPOINTER;
2346           break;
2347         case S_XDATA:
2348           DCL_TYPE (val->type) = FPOINTER;
2349           break;
2350         case S_EEPROM:
2351           DCL_TYPE (val->type) = EEPPOINTER;
2352           break;
2353         default:
2354           DCL_TYPE (val->type) = port->unqualified_pointer;
2355         }
2356       
2357       /* is there is a symbol associated then */
2358       /* change the type of the symbol as well */
2359       if (val->sym)
2360         {
2361           val->sym->type = copyLinkChain (val->type);
2362           val->sym->etype = getSpec (val->sym->type);
2363         }
2364     }
2365   return val;
2366 }
2367 /*------------------------------------------------------------------*/
2368 /* checkFunction - does all kinds of check on a function            */
2369 /*------------------------------------------------------------------*/
2370 int 
2371 checkFunction (symbol * sym, symbol *csym)
2372 {
2373   value *exargs, *acargs;
2374   value *checkValue;
2375   int argCnt = 0;
2376
2377   if (getenv("DEBUG_SANITY")) {
2378     fprintf (stderr, "checkFunction: %s ", sym->name);
2379   }
2380
2381   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2382     {
2383       werror(E_SYNTAX_ERROR, sym->name);
2384       return 0;
2385     }
2386     
2387   /* make sure the type is complete and sane */
2388   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2389
2390   /* if not type then some kind of error */
2391   if (!sym->type)
2392     return 0;
2393
2394   /* if the function has no type then make it return int */
2395   if (!sym->type->next)
2396     sym->type->next = sym->etype = newIntLink ();
2397
2398   /* function cannot return aggregate */
2399   if (IS_AGGREGATE (sym->type->next))
2400     {
2401       werror (E_FUNC_AGGR, sym->name);
2402       return 0;
2403     }
2404
2405   /* check if this function is defined as calleeSaves
2406      then mark it as such */
2407   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2408
2409   /* if interrupt service routine  */
2410   /* then it cannot have arguments */
2411   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2412     {
2413       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2414         werror (E_INT_ARGS, sym->name);
2415         FUNC_ARGS(sym->type)=NULL;
2416       }
2417     }
2418
2419   if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2420     {
2421       werror (E_SHADOWREGS_NO_ISR, sym->name);
2422     }
2423
2424
2425   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
2426        acargs; 
2427        acargs=acargs->next, argCnt++) {
2428     if (!acargs->sym) { 
2429       // this can happen for reentrant functions
2430       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2431       // the show must go on: synthesize a name and symbol
2432       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2433       acargs->sym = newSymbol (acargs->name, 1);
2434       SPEC_OCLS (acargs->etype) = istack;
2435       acargs->sym->type = copyLinkChain (acargs->type);
2436       acargs->sym->etype = getSpec (acargs->sym->type);
2437       acargs->sym->_isparm = 1;
2438       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2439     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2440       // synthesized name
2441       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2442     }
2443   }
2444   argCnt--;
2445
2446   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2447     return 1;                   /* not defined nothing more to check  */
2448
2449   /* check if body already present */
2450   if (csym && IFFUNC_HASBODY(csym->type))
2451     {
2452       werror (E_FUNC_BODY, sym->name);
2453       return 0;
2454     }
2455
2456   /* check the return value type   */
2457   if (compareType (csym->type, sym->type) <= 0)
2458     {
2459       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2460       printFromToType(csym->type, sym->type);
2461       return 0;
2462     }
2463
2464   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2465     {
2466       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2467     }
2468
2469   /* I don't think this is necessary for interrupts. An isr is a  */
2470   /* root in the calling tree.                                    */
2471   if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2472       (!FUNC_ISISR (sym->type)))
2473     {
2474       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2475     }
2476
2477   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2478     {
2479       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2480     }
2481
2482   /* Really, reentrant should match regardless of argCnt, but     */
2483   /* this breaks some existing code (the fp lib functions). If    */
2484   /* the first argument is always passed the same way, this       */
2485   /* lax checking is ok (but may not be true for in future ports) */
2486   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2487       && argCnt>1)
2488     {
2489       //printf("argCnt = %d\n",argCnt);
2490       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2491     }
2492
2493   if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2494     {
2495       werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2496     }
2497
2498   if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2499     {
2500       werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2501     }
2502   
2503
2504   /* compare expected args with actual args */
2505   exargs = FUNC_ARGS(csym->type);
2506   acargs = FUNC_ARGS(sym->type);
2507
2508   /* for all the expected args do */
2509   for (argCnt = 1;
2510        exargs && acargs;
2511        exargs = exargs->next, acargs = acargs->next, argCnt++)
2512     {
2513       if (getenv("DEBUG_SANITY")) {
2514         fprintf (stderr, "checkFunction: %s ", exargs->name);
2515       }
2516       /* make sure the type is complete and sane */
2517       checkTypeSanity(exargs->etype, exargs->name);
2518
2519       /* If the actual argument is an array, any prototype
2520        * will have modified it to a pointer. Duplicate that
2521        * change here.
2522        */
2523       if (IS_AGGREGATE (acargs->type))
2524         {
2525           checkValue = copyValue (acargs);
2526           aggregateToPointer (checkValue);
2527         }
2528       else
2529         {
2530           checkValue = acargs;
2531         }
2532
2533       if (compareType (exargs->type, checkValue->type) <= 0)
2534         {
2535           werror (E_ARG_TYPE, argCnt);
2536           printFromToType(exargs->type, checkValue->type);
2537           return 0;
2538         }
2539     }
2540
2541   /* if one them ended we have a problem */
2542   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2543       (!exargs && acargs && !IS_VOID (acargs->type)))
2544     werror (E_ARG_COUNT);
2545
2546   /* replace with this defition */
2547   sym->cdef = csym->cdef;
2548   deleteSym (SymbolTab, csym, csym->name);
2549   deleteFromSeg(csym);
2550   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2551   if (IS_EXTERN (csym->etype) && !
2552       IS_EXTERN (sym->etype))
2553     {
2554       addSet (&publics, sym);
2555     }
2556   return 1;
2557 }
2558
2559 /*------------------------------------------------------------------*/
2560 /* cdbStructBlock - calls struct printing for a blcks               */
2561 /*------------------------------------------------------------------*/
2562 void cdbStructBlock (int block)
2563 {
2564   int i;
2565   bucket **table = StructTab;
2566   bucket *chain;
2567
2568   /* go thru the entire  table  */
2569   for (i = 0; i < 256; i++)
2570     {
2571       for (chain = table[i]; chain; chain = chain->next)
2572         {
2573           if (chain->block >= block)
2574             {
2575               if(debugFile)
2576                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2577             }
2578         }
2579     }
2580 }
2581
2582 /*-----------------------------------------------------------------*/
2583 /* processFuncPtrArgs - does some processing with args of func ptrs*/
2584 /*-----------------------------------------------------------------*/
2585 void 
2586 processFuncPtrArgs (sym_link * funcType)
2587 {
2588   value *val = FUNC_ARGS(funcType);
2589
2590   /* if it is void then remove parameters */
2591   if (val && IS_VOID (val->type))
2592     {
2593       FUNC_ARGS(funcType) = NULL;
2594       return;
2595     }
2596 }
2597
2598 /*-----------------------------------------------------------------*/
2599 /* processFuncArgs - does some processing with function args       */
2600 /*-----------------------------------------------------------------*/
2601 void 
2602 processFuncArgs (symbol * func)
2603 {
2604   value *val;
2605   int pNum = 1;
2606   sym_link *funcType=func->type;
2607
2608   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2609     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2610
2611   /* find the function declaration within the type */
2612   while (funcType && !IS_FUNC(funcType))
2613     funcType=funcType->next;
2614
2615   /* if this function has variable argument list */
2616   /* then make the function a reentrant one    */
2617   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2618     FUNC_ISREENT(funcType)=1;
2619
2620   /* check if this function is defined as calleeSaves
2621      then mark it as such */
2622   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2623
2624   /* loop thru all the arguments   */
2625   val = FUNC_ARGS(funcType);
2626
2627   /* if it is void then remove parameters */
2628   if (val && IS_VOID (val->type))
2629     {
2630       FUNC_ARGS(funcType) = NULL;
2631       return;
2632     }
2633
2634   /* reset regparm for the port */
2635   (*port->reset_regparms) ();
2636
2637   /* if any of the arguments is an aggregate */
2638   /* change it to pointer to the same type */
2639   while (val)
2640     {
2641       int argreg = 0;
2642       char buffer[SDCC_NAME_MAX+1];
2643       
2644       SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2645       checkTypeSanity (val->etype, buffer);
2646       
2647       /* mark it as a register parameter if
2648          the function does not have VA_ARG
2649          and as port dictates */
2650       if (!IFFUNC_HASVARARGS(funcType) &&
2651           (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
2652         {
2653           SPEC_REGPARM (val->etype) = 1;
2654           SPEC_ARGREG(val->etype) = argreg;
2655         } else if (IFFUNC_ISREENT(funcType)) {
2656             FUNC_HASSTACKPARM(funcType) = 1;
2657         }
2658
2659       if (IS_AGGREGATE (val->type))
2660         {
2661           aggregateToPointer (val);
2662         }
2663
2664       val = val->next;
2665       pNum++;
2666     }
2667
2668   /* if this is an internal generated function call */
2669   if (func->cdef) {
2670     /* ignore --stack-auto for this one, we don't know how it is compiled */
2671     /* simply trust on --int-long-reent or --float-reent */
2672     if (IFFUNC_ISREENT(funcType)) {
2673       return;
2674     }
2675   } else {
2676     /* if this function is reentrant or */
2677     /* automatics r 2b stacked then nothing */
2678     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2679       return;
2680   }
2681
2682   val = FUNC_ARGS(funcType);
2683   pNum = 1;
2684   while (val)
2685     {
2686
2687       /* if a symbolname is not given  */
2688       /* synthesize a variable name */
2689       if (!val->sym)
2690         {
2691           SNPRINTF (val->name, sizeof(val->name), 
2692                     "_%s_PARM_%d", func->name, pNum++);
2693           val->sym = newSymbol (val->name, 1);
2694           if (SPEC_SCLS(val->etype) == S_BIT)
2695             SPEC_OCLS (val->etype) = bit;
2696           else
2697             SPEC_OCLS (val->etype) = port->mem.default_local_map;
2698           val->sym->type = copyLinkChain (val->type);
2699           val->sym->etype = getSpec (val->sym->type);
2700           val->sym->_isparm = 1;
2701           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2702           #if 0
2703           /* ?? static functions shouldn't imply static parameters - EEP */
2704           if (IS_SPEC(func->etype)) {
2705             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2706               SPEC_STAT (func->etype);
2707           }
2708           #endif
2709           addSymChain (&val->sym);
2710
2711         }
2712       else                      /* symbol name given create synth name */
2713         {
2714
2715           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2716           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2717           val->sym->_isparm = 1;
2718           if (SPEC_SCLS(val->etype) == S_BIT)
2719             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2720           else
2721             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2722               port->mem.default_local_map;
2723           
2724           #if 0
2725           /* ?? static functions shouldn't imply static parameters - EEP */
2726           if (IS_SPEC(func->etype)) {
2727             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2728               SPEC_STAT (func->etype);
2729           }
2730           #endif
2731         }
2732       if (SPEC_OCLS (val->sym->etype) == pdata)
2733         val->sym->iaccess = 1;
2734       if (!isinSet(operKeyReset, val->sym)) {
2735         addSet (&operKeyReset, val->sym);
2736         applyToSet (operKeyReset, resetParmKey);
2737       }
2738       val = val->next;
2739     }
2740 }
2741
2742 /*-----------------------------------------------------------------*/
2743 /* isSymbolEqual - compares two symbols return 1 if they match     */
2744 /*-----------------------------------------------------------------*/
2745 int 
2746 isSymbolEqual (symbol * dest, symbol * src)
2747 {
2748   /* if pointers match then equal */
2749   if (dest == src)
2750     return 1;
2751
2752   /* if one of them is null then don't match */
2753   if (!dest || !src)
2754     return 0;
2755
2756   /* if both of them have rname match on rname */
2757   if (dest->rname[0] && src->rname[0])
2758     return (!strcmp (dest->rname, src->rname));
2759
2760   /* otherwise match on name */
2761   return (!strcmp (dest->name, src->name));
2762 }
2763
2764 void PT(sym_link *type)
2765 {
2766         printTypeChain(type,0);
2767 }
2768 /*-----------------------------------------------------------------*/
2769 /* printTypeChain - prints the type chain in human readable form   */
2770 /*-----------------------------------------------------------------*/
2771 void
2772 printTypeChain (sym_link * start, FILE * of)
2773 {
2774   int nlr = 0;
2775   value *args;
2776   sym_link * type, * search;
2777   STORAGE_CLASS scls;
2778
2779   if (!of)
2780     {
2781       of = stdout;
2782       nlr = 1;
2783     }
2784
2785   if (start==NULL) {
2786     fprintf (of, "void");
2787     return;
2788   }
2789
2790   /* Print the chain as it is written in the source: */
2791   /* start with the last entry.                      */
2792   /* However, the storage class at the end of the    */
2793   /* chain reall applies to the first in the chain!  */
2794
2795   for (type = start; type && type->next; type = type->next)
2796     ;
2797   if (IS_SPEC (type))
2798     scls=SPEC_SCLS(type);
2799   else
2800     scls=0;
2801   while (type)
2802     {
2803       if (type==start) {
2804         switch (scls) 
2805           {
2806           case S_DATA: fprintf (of, "data-"); break;
2807           case S_XDATA: fprintf (of, "xdata-"); break;
2808           case S_SFR: fprintf (of, "sfr-"); break;
2809           case S_SBIT: fprintf (of, "sbit-"); break;
2810           case S_CODE: fprintf (of, "code-"); break;
2811           case S_IDATA: fprintf (of, "idata-"); break;
2812           case S_PDATA: fprintf (of, "pdata-"); break;
2813           case S_LITERAL: fprintf (of, "literal-"); break;
2814           case S_STACK: fprintf (of, "stack-"); break;
2815           case S_XSTACK: fprintf (of, "xstack-"); break;
2816           case S_BIT: fprintf (of, "bit-"); break;
2817           case S_EEPROM: fprintf (of, "eeprom-"); break;
2818           default: break;
2819           }
2820       }
2821
2822       if (IS_DECL (type))
2823         {
2824           if (!IS_FUNC(type)) {
2825             if (DCL_PTR_VOLATILE (type)) {
2826               fprintf (of, "volatile-");
2827             }
2828             if (DCL_PTR_CONST (type)) {
2829               fprintf (of, "const-");
2830             }
2831           }
2832           switch (DCL_TYPE (type))
2833             {
2834             case FUNCTION:
2835               fprintf (of, "function %s %s", 
2836                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2837                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2838               fprintf (of, "( ");
2839               for (args = FUNC_ARGS(type); 
2840                    args; 
2841                    args=args->next) {
2842                 printTypeChain(args->type, of);
2843                 if (args->next)
2844                   fprintf(of, ", ");
2845               }
2846               fprintf (of, ") ");
2847               break;
2848             case GPOINTER:
2849               fprintf (of, "generic* ");
2850               break;
2851             case CPOINTER:
2852               fprintf (of, "code* ");
2853               break;
2854             case FPOINTER:
2855               fprintf (of, "xdata* ");
2856               break;
2857             case EEPPOINTER:
2858               fprintf (of, "eeprom* ");
2859               break;
2860             case POINTER:
2861               fprintf (of, "near* ");
2862               break;
2863             case IPOINTER:
2864               fprintf (of, "idata* ");
2865               break;
2866             case PPOINTER:
2867               fprintf (of, "pdata* ");
2868               break;
2869             case UPOINTER:
2870               fprintf (of, "unknown* ");
2871               break;
2872             case ARRAY:
2873               if (DCL_ELEM(type)) {
2874                 fprintf (of, "[%d] ", DCL_ELEM(type));
2875               } else {
2876                 fprintf (of, "[] ");
2877               }
2878               break;
2879             }
2880         }
2881       else
2882         {
2883           if (SPEC_VOLATILE (type))
2884             fprintf (of, "volatile-");
2885           if (SPEC_CONST (type))
2886             fprintf (of, "const-");
2887           if (SPEC_USIGN (type))
2888             fprintf (of, "unsigned-");
2889           switch (SPEC_NOUN (type))
2890             {
2891             case V_INT:
2892               if (IS_LONG (type))
2893                 fprintf (of, "long-");
2894               fprintf (of, "int");
2895               break;
2896
2897             case V_CHAR:
2898               fprintf (of, "char");
2899               break;
2900
2901             case V_VOID:
2902               fprintf (of, "void");
2903               break;
2904
2905             case V_FLOAT:
2906               fprintf (of, "float");
2907               break;
2908
2909             case V_FIXED16X16:
2910               fprintf (of, "fixed16x16");
2911               break;
2912
2913             case V_STRUCT:
2914               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2915               break;
2916
2917             case V_SBIT:
2918               fprintf (of, "sbit");
2919               break;
2920
2921             case V_BIT:
2922               fprintf (of, "bit");
2923               break;
2924
2925             case V_BITFIELD:
2926               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2927               break;
2928
2929             case V_DOUBLE:
2930               fprintf (of, "double");
2931               break;
2932
2933             default:
2934               fprintf (of, "unknown type");
2935               break;
2936             }
2937         }
2938       /* search entry in list before "type" */
2939       for (search = start; search && search->next != type;)
2940         search = search->next;
2941       type = search;
2942       if (type)
2943         fputc (' ', of);
2944     }
2945   if (nlr)
2946     fprintf (of, "\n");
2947 }
2948
2949 /*--------------------------------------------------------------------*/
2950 /* printTypeChainRaw - prints the type chain in human readable form   */
2951 /*                     in the raw data structure ordering             */
2952 /*--------------------------------------------------------------------*/
2953 void
2954 printTypeChainRaw (sym_link * start, FILE * of)
2955 {
2956   int nlr = 0;
2957   value *args;
2958   sym_link * type;
2959
2960   if (!of)
2961     {
2962       of = stdout;
2963       nlr = 1;
2964     }
2965
2966   if (start==NULL) {
2967     fprintf (of, "void");
2968     return;
2969   }
2970
2971   type = start;
2972   
2973   while (type)
2974     {
2975       if (IS_DECL (type))
2976         {
2977           if (!IS_FUNC(type)) {
2978             if (DCL_PTR_VOLATILE (type)) {
2979               fprintf (of, "volatile-");
2980             }
2981             if (DCL_PTR_CONST (type)) {
2982               fprintf (of, "const-");
2983             }
2984           }
2985           switch (DCL_TYPE (type))
2986             {
2987             case FUNCTION:
2988               fprintf (of, "function %s %s", 
2989                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2990                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2991               fprintf (of, "( ");
2992               for (args = FUNC_ARGS(type); 
2993                    args; 
2994                    args=args->next) {
2995                 printTypeChain(args->type, of);
2996                 if (args->next)
2997                   fprintf(of, ", ");
2998               }
2999               fprintf (of, ") ");
3000               break;
3001             case GPOINTER:
3002               fprintf (of, "generic* ");
3003               break;
3004             case CPOINTER:
3005               fprintf (of, "code* ");
3006               break;
3007             case FPOINTER:
3008               fprintf (of, "xdata* ");
3009               break;
3010             case EEPPOINTER:
3011               fprintf (of, "eeprom* ");
3012               break;
3013             case POINTER:
3014               fprintf (of, "near* ");
3015               break;
3016             case IPOINTER:
3017               fprintf (of, "idata* ");
3018               break;
3019             case PPOINTER:
3020               fprintf (of, "pdata* ");
3021               break;
3022             case UPOINTER:
3023               fprintf (of, "unknown* ");
3024               break;
3025             case ARRAY:
3026               if (DCL_ELEM(type)) {
3027                 fprintf (of, "[%d] ", DCL_ELEM(type));
3028               } else {
3029                 fprintf (of, "[] ");
3030               }
3031               break;
3032             }
3033           if (DCL_TSPEC(type))
3034             {
3035               fprintf (of, "{");
3036               printTypeChainRaw(DCL_TSPEC(type), of);
3037               fprintf (of, "}");
3038             }
3039         }
3040       else if (IS_SPEC (type))
3041         {
3042         switch (SPEC_SCLS (type)) 
3043           {
3044           case S_DATA: fprintf (of, "data-"); break;
3045           case S_XDATA: fprintf (of, "xdata-"); break;
3046           case S_SFR: fprintf (of, "sfr-"); break;
3047           case S_SBIT: fprintf (of, "sbit-"); break;
3048           case S_CODE: fprintf (of, "code-"); break;
3049           case S_IDATA: fprintf (of, "idata-"); break;
3050           case S_PDATA: fprintf (of, "pdata-"); break;
3051           case S_LITERAL: fprintf (of, "literal-"); break;
3052           case S_STACK: fprintf (of, "stack-"); break;
3053           case S_XSTACK: fprintf (of, "xstack-"); break;
3054           case S_BIT: fprintf (of, "bit-"); break;
3055           case S_EEPROM: fprintf (of, "eeprom-"); break;
3056           default: break;
3057           }
3058           if (SPEC_VOLATILE (type))
3059             fprintf (of, "volatile-");
3060           if (SPEC_CONST (type))
3061             fprintf (of, "const-");
3062           if (SPEC_USIGN (type))
3063             fprintf (of, "unsigned-");
3064           switch (SPEC_NOUN (type))
3065             {
3066             case V_INT:
3067               if (IS_LONG (type))
3068                 fprintf (of, "long-");
3069               fprintf (of, "int");
3070               break;
3071
3072             case V_CHAR:
3073               fprintf (of, "char");
3074               break;
3075
3076             case V_VOID:
3077               fprintf (of, "void");
3078               break;
3079
3080             case V_FLOAT:
3081               fprintf (of, "float");
3082               break;
3083
3084             case V_FIXED16X16:
3085               fprintf (of, "fixed16x16");
3086               break;
3087
3088             case V_STRUCT:
3089               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3090               break;
3091
3092             case V_SBIT:
3093               fprintf (of, "sbit");
3094               break;
3095
3096             case V_BIT:
3097               fprintf (of, "bit");
3098               break;
3099
3100             case V_BITFIELD:
3101               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3102               break;
3103
3104             case V_DOUBLE:
3105               fprintf (of, "double");
3106               break;
3107
3108             default:
3109               fprintf (of, "unknown type");
3110               break;
3111             }
3112         }
3113       else
3114         fprintf (of, "NOT_SPEC_OR_DECL");
3115       type = type->next;
3116       if (type)
3117         fputc (' ', of);
3118     }
3119   if (nlr)
3120     fprintf (of, "\n");
3121 }
3122
3123
3124 /*-----------------------------------------------------------------*/
3125 /* powof2 - returns power of two for the number if number is pow 2 */
3126 /*-----------------------------------------------------------------*/
3127 int
3128 powof2 (TYPE_TARGET_ULONG num)
3129 {
3130   int nshifts = 0;
3131   int n1s = 0;
3132
3133   while (num)
3134     {
3135       if (num & 1)
3136         n1s++;
3137       num >>= 1;
3138       nshifts++;
3139     }
3140
3141   if (n1s > 1 || nshifts == 0)
3142     return -1;
3143   return nshifts - 1;
3144 }
3145
3146 symbol *__fsadd;
3147 symbol *__fssub;
3148 symbol *__fsmul;
3149 symbol *__fsdiv;
3150 symbol *__fseq;
3151 symbol *__fsneq;
3152 symbol *__fslt;
3153 symbol *__fslteq;
3154 symbol *__fsgt;
3155 symbol *__fsgteq;
3156
3157 symbol *__fps16x16_add;
3158 symbol *__fps16x16_sub;
3159 symbol *__fps16x16_mul;
3160 symbol *__fps16x16_div;
3161 symbol *__fps16x16_eq;
3162 symbol *__fps16x16_neq;
3163 symbol *__fps16x16_lt;
3164 symbol *__fps16x16_lteq;
3165 symbol *__fps16x16_gt;
3166 symbol *__fps16x16_gteq;
3167
3168 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3169 symbol *__muldiv[3][3][2];
3170 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3171 sym_link *__multypes[3][2];
3172 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3173 symbol *__conv[2][3][2];
3174 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
3175 symbol *__fp16x16conv[2][4][2];
3176 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3177 symbol *__rlrr[2][3][2];
3178
3179 sym_link *floatType;
3180 sym_link *fixed16x16Type;
3181
3182 static char *
3183 _mangleFunctionName(char *in)
3184 {
3185   if (port->getMangledFunctionName)
3186     {
3187       return port->getMangledFunctionName(in);
3188     }
3189   else
3190     {
3191       return in;
3192     }
3193 }
3194
3195 /*-----------------------------------------------------------------*/
3196 /* typeFromStr - create a typechain from an encoded string         */
3197 /* basic types -        'c' - char                                 */
3198 /*                      's' - short                                */
3199 /*                      'i' - int                                  */
3200 /*                      'l' - long                                 */
3201 /*                      'f' - float                                */
3202 /*                      'q' - fixed16x16                           */
3203 /*                      'v' - void                                 */
3204 /*                      '*' - pointer - default (GPOINTER)         */
3205 /* modifiers -          'u' - unsigned                             */
3206 /* pointer modifiers -  'g' - generic                              */
3207 /*                      'x' - xdata                                */
3208 /*                      'p' - code                                 */
3209 /*                      'd' - data                                 */                     
3210 /*                      'F' - function                             */                     
3211 /* examples : "ig*" - generic int *                                */
3212 /*            "cx*" - char xdata *                                 */
3213 /*            "ui" -  unsigned int                                 */
3214 /*-----------------------------------------------------------------*/
3215 sym_link *typeFromStr (char *s)
3216 {
3217     sym_link *r = newLink(DECLARATOR);
3218     int usign = 0;
3219
3220     do {
3221         sym_link *nr;
3222         switch (*s) {
3223         case 'u' : 
3224             usign = 1;
3225             s++;
3226             continue ;
3227             break ;
3228         case 'c':
3229             r->class = SPECIFIER;
3230             SPEC_NOUN(r) = V_CHAR;
3231             break;
3232         case 's':
3233         case 'i':
3234             r->class = SPECIFIER;
3235             SPEC_NOUN(r) = V_INT;
3236             break;
3237         case 'l':
3238             r->class = SPECIFIER;
3239             SPEC_NOUN(r) = V_INT;
3240             SPEC_LONG(r) = 1;
3241             break;
3242         case 'f':
3243             r->class = SPECIFIER;
3244             SPEC_NOUN(r) = V_FLOAT;
3245             break;
3246         case 'q':
3247             r->class = SPECIFIER;
3248             SPEC_NOUN(r) = V_FIXED16X16;
3249             break;
3250         case 'v':
3251             r->class = SPECIFIER;
3252             SPEC_NOUN(r) = V_VOID;
3253             break;
3254         case '*':
3255             DCL_TYPE(r) = port->unqualified_pointer;
3256             break;
3257         case 'g':
3258         case 'x':
3259         case 'p':
3260         case 'd':
3261         case 'F':
3262             assert(*(s+1)=='*');
3263             nr = newLink(DECLARATOR);
3264             nr->next = r;
3265             r = nr;
3266             switch (*s) {
3267             case 'g':
3268                 DCL_TYPE(r) = GPOINTER;
3269                 break;
3270             case 'x':
3271                 DCL_TYPE(r) = FPOINTER;
3272                 break;
3273             case 'p':
3274                 DCL_TYPE(r) = CPOINTER;
3275                 break;
3276             case 'd':
3277                 DCL_TYPE(r) = POINTER;
3278                 break;
3279             case 'F':
3280                 DCL_TYPE(r) = FUNCTION;
3281                 nr = newLink(DECLARATOR);
3282                 nr->next = r;
3283                 r = nr;
3284                 DCL_TYPE(r) = CPOINTER;
3285                 break;
3286             }
3287             s++;
3288             break;
3289         default:
3290             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
3291                    "typeFromStr: unknown type");
3292             break;
3293         }
3294         if (IS_SPEC(r) && usign) {
3295             SPEC_USIGN(r) = 1;
3296             usign = 0;
3297         }
3298         s++;
3299     } while (*s);
3300     return r;
3301 }
3302
3303 /*-----------------------------------------------------------------*/
3304 /* initCSupport - create functions for C support routines          */
3305 /*-----------------------------------------------------------------*/
3306 void 
3307 initCSupport ()
3308 {
3309   const char *smuldivmod[] =
3310   {
3311     "mul", "div", "mod"
3312   };
3313   const char *sbwd[] =
3314   {
3315     "char", "int", "long", "fixed16x16",
3316   };
3317   const char *fp16x16sbwd[] =
3318   {
3319     "char", "int", "long", "float",
3320   };
3321   const char *ssu[] =
3322   {
3323     "s", "u"
3324   };
3325   const char *srlrr[] =
3326   {
3327     "rl", "rr"
3328   };
3329
3330   int bwd, su, muldivmod, tofrom, rlrr;
3331
3332   if (getenv("SDCC_NO_C_SUPPORT")) {
3333     /* for debugging only */
3334     return;
3335   }
3336
3337   floatType = newFloatLink ();
3338   fixed16x16Type = newFixed16x16Link ();
3339
3340   for (bwd = 0; bwd < 3; bwd++)
3341     {
3342       sym_link *l = NULL;
3343       switch (bwd)
3344         {
3345         case 0:
3346           l = newCharLink ();
3347           break;
3348         case 1:
3349           l = newIntLink ();
3350           break;
3351         case 2:
3352           l = newLongLink ();
3353           break;
3354         default:
3355           assert (0);
3356         }
3357       __multypes[bwd][0] = l;
3358       __multypes[bwd][1] = copyLinkChain (l);
3359       SPEC_USIGN (__multypes[bwd][1]) = 1;
3360     }
3361
3362   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3363   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3364   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3365   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3366   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3367   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3368   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3369   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3370   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3371   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3372
3373   __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3374   __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3375   __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3376   __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3377   __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3378   __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3379   __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3380   __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3381   __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3382   __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3383
3384
3385   for (tofrom = 0; tofrom < 2; tofrom++)
3386     {
3387       for (bwd = 0; bwd < 3; bwd++)
3388         {
3389           for (su = 0; su < 2; su++)
3390             {
3391               if (tofrom)
3392                 {
3393                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3394                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3395                 }
3396               else
3397                 {
3398                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3399                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3400                 }
3401             }
3402         }
3403     }
3404
3405   for (tofrom = 0; tofrom < 2; tofrom++)
3406     {
3407       for (bwd = 0; bwd < 4; bwd++)
3408         {
3409           for (su = 0; su < 2; su++)
3410             {
3411               if (tofrom)
3412                 {
3413                   SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
3414                   if(bwd == 3) {
3415                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
3416                   } else
3417                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
3418                 }
3419               else
3420                 {
3421                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
3422                   if(bwd == 3) {
3423                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
3424                   } else
3425                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
3426                 }
3427             }
3428         }
3429     }
3430
3431 /*
3432   for (muldivmod = 0; muldivmod < 3; muldivmod++)
3433     {
3434       for (bwd = 0; bwd < 3; bwd++)
3435         {
3436           for (su = 0; su < 2; su++)
3437             {
3438               SNPRINTF (buffer, sizeof(buffer),
3439                         "_%s%s%s",
3440                        smuldivmod[muldivmod],
3441                        ssu[su],
3442                        sbwd[bwd]);
3443               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3444               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3445             }
3446         }
3447     }
3448
3449   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3450   Therefore they've been merged into mulint() and mullong().
3451 */
3452
3453   for (bwd = 0; bwd < 3; bwd++)
3454     {
3455       for (su = 0; su < 2; su++)
3456         {
3457           for (muldivmod = 1; muldivmod < 3; muldivmod++)
3458             {
3459               /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
3460               if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0)
3461               {
3462                 SNPRINTF (buffer, sizeof(buffer),
3463                     "_%s%s%s",
3464                     smuldivmod[muldivmod],
3465                     ssu[su],
3466                     sbwd[bwd]);
3467                 __muldiv[muldivmod][bwd][su] = funcOfType (
3468                     _mangleFunctionName(buffer),
3469                     __multypes[bwd][su],
3470                     __multypes[bwd][su],
3471                     2,
3472                     options.intlong_rent);
3473                 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3474               }
3475             }
3476         }
3477     }
3478
3479   if (TARGET_IS_PIC16)
3480   {
3481     /* PIC16 port wants __divschar/__modschar to return an int, so that both
3482      * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
3483      * (first one would have to be sign extended, second one must not be).
3484      * Similarly, modschar should be handled, but the iCode introduces cast
3485      * here and forces '% : s8 x s8 -> s8' ... */
3486     su = 0; bwd = 0;
3487     for (muldivmod = 1; muldivmod < 2; muldivmod++) {
3488       SNPRINTF (buffer, sizeof(buffer),
3489           "_%s%s%s",
3490           smuldivmod[muldivmod],
3491           ssu[su],
3492           sbwd[bwd]);
3493       __muldiv[muldivmod][bwd][su] = funcOfType (
3494           _mangleFunctionName(buffer),
3495           __multypes[1][su],
3496           __multypes[bwd][su],
3497           2,
3498           options.intlong_rent);
3499       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3500     }
3501   }
3502
3503   /* mul only */
3504   muldivmod = 0;
3505   /* byte */
3506   bwd = 0;
3507   for (su = 0; su < 2; su++)
3508     {
3509       /* muluchar and mulschar are still separate functions, because e.g. the z80
3510          port is sign/zero-extending to int before calling mulint() */
3511       SNPRINTF (buffer, sizeof(buffer),
3512                 "_%s%s%s",
3513                 smuldivmod[muldivmod],
3514                 ssu[su],
3515                 sbwd[bwd]);
3516       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3517       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3518     }
3519   /* signed only */
3520   su = 0;
3521   /* word and doubleword */
3522   for (bwd = 1; bwd < 3; bwd++)
3523     {
3524       /* mul, int/long */
3525       SNPRINTF (buffer, sizeof(buffer),
3526                 "_%s%s",
3527                 smuldivmod[muldivmod],
3528                 sbwd[bwd]);
3529       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3530       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3531       /* signed = unsigned */
3532       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3533     }
3534
3535   for (rlrr = 0; rlrr < 2; rlrr++)
3536     {
3537       for (bwd = 0; bwd < 3; bwd++)
3538         {
3539           for (su = 0; su < 2; su++)
3540             {
3541               SNPRINTF (buffer, sizeof(buffer),
3542                         "_%s%s%s",
3543                        srlrr[rlrr],
3544                        ssu[su],
3545                        sbwd[bwd]);
3546               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3547               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3548             }
3549         }
3550     }
3551 }
3552
3553 /*-----------------------------------------------------------------*/
3554 /* initBuiltIns - create prototypes for builtin functions          */
3555 /*-----------------------------------------------------------------*/
3556 void initBuiltIns()
3557 {
3558     int i;
3559     symbol *sym;
3560
3561     if (!port->builtintable) return ;
3562
3563     for (i = 0 ; port->builtintable[i].name ; i++) {
3564         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3565                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3566         FUNC_ISBUILTIN(sym->type) = 1;
3567         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3568     }
3569 }
3570
3571 sym_link *validateLink(sym_link         *l, 
3572                         const char      *macro,
3573                         const char      *args,
3574                         const char      select,
3575                         const char      *file, 
3576                         unsigned        line)
3577 {    
3578   if (l && l->class==select)
3579     {
3580         return l;
3581     }
3582     fprintf(stderr, 
3583             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3584             " expected %s, got %s\n",
3585             macro, args, file, line, 
3586             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3587     exit(EXIT_FAILURE);
3588     return l; // never reached, makes compiler happy.
3589 }
3590
3591 /*--------------------------------------------------------------------*/
3592 /* newEnumType - create an integer type compatible with enumerations  */
3593 /*--------------------------------------------------------------------*/
3594 sym_link *
3595 newEnumType (symbol *enumlist)
3596 {
3597   int min, max, v;
3598   symbol *sym;
3599   sym_link *type;
3600
3601   if (!enumlist)
3602     {
3603       type = newLink (SPECIFIER);
3604       SPEC_NOUN (type) = V_INT;
3605       return type;
3606     }
3607       
3608   /* Determine the range of the enumerated values */
3609   sym = enumlist;
3610   min = max = (int) floatFromVal (valFromType (sym->type));
3611   for (sym = sym->next; sym; sym = sym->next)
3612     {
3613       v = (int) floatFromVal (valFromType (sym->type));
3614       if (v<min)
3615         min = v;
3616       if (v>max)
3617         max = v;
3618     }
3619
3620   /* Determine the smallest integer type that is compatible with this range */
3621   type = newLink (SPECIFIER);
3622   if (min>=0 && max<=255)
3623     {
3624       SPEC_NOUN (type) = V_CHAR;
3625       SPEC_USIGN (type) = 1;
3626     }
3627   else if (min>=-128 && max<=127)
3628     {
3629       SPEC_NOUN (type) = V_CHAR;
3630     }
3631   else if (min>=0 && max<=65535)
3632     {
3633       SPEC_NOUN (type) = V_INT;
3634       SPEC_USIGN (type) = 1;
3635     }
3636   else if (min>=-32768 && max<=32767)
3637     {
3638       SPEC_NOUN (type) = V_INT;
3639     }
3640   else
3641     {
3642       SPEC_NOUN (type) = V_INT;
3643       SPEC_LONG (type) = 1;
3644       if (min>=0)
3645         SPEC_USIGN (type) = 1;
3646     }
3647   
3648   return type;    
3649 }