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