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