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