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