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