* device/lib/medium/Makefile: added for new memory model medium
[fw/sdcc] / src / SDCCsymt.c
1 /*-------------------------------------------------------------------------
2   SDCCsymt.c - Code file for Symbols table related structures and MACRO's.
3         Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any
8    later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19    In other words, you are welcome to use, share and improve this program.
20    You are forbidden to forbid anyone else to use, share and improve
21    what you give them.   Help stamp out software-hoarding!
22 -------------------------------------------------------------------------*/
23
24 #include "common.h"
25 #include "newalloc.h"
26
27 #include "SDCCsymt.h"
28
29 value *aggregateToPointer (value *val);
30 void printTypeChainRaw (sym_link * start, FILE * of);
31
32 void printFromToType(sym_link *from, sym_link *to) {
33   fprintf (stderr, "from type '");
34   printTypeChain (from, stderr);
35   fprintf (stderr, "'\nto type '");
36   printTypeChain (to, stderr);
37   fprintf (stderr, "'\n");
38 }
39
40 /* noun strings */
41 char *nounName(sym_link *sl) {
42   switch (SPEC_NOUN(sl)) 
43     {
44     case V_INT: {
45       if (SPEC_LONG(sl)) return "long";
46       if (SPEC_SHORT(sl)) return "short";
47       return "int";
48     }
49     case V_FLOAT: return "float";
50     case V_FIXED16X16: return "fixed16x16";
51     case V_CHAR: return "char";
52     case V_VOID: return "void";
53     case V_STRUCT: return "struct";
54     case V_LABEL: return "label";
55     case V_BITFIELD: return "bitfield";
56     case V_BIT: return "bit";
57     case V_SBIT: return "sbit";
58     case V_DOUBLE: return "double";
59     }
60   return "unknown";
61 };
62
63 bucket *SymbolTab[256];         /* the symbol    table  */
64 bucket *StructTab[256];         /* the structure table  */
65 bucket *TypedefTab[256];        /* the typedef   table  */
66 bucket *LabelTab[256];          /* the Label     table  */
67 bucket *enumTab[256];           /* enumerated    table  */
68
69 /*------------------------------------------------------------------*/
70 /* initSymt () - initialises symbol table related stuff             */
71 /*------------------------------------------------------------------*/
72 void 
73 initSymt ()
74 {
75   int i = 0;
76
77   for (i = 0; i < 256; i++)
78     SymbolTab[i] = StructTab[i] = (void *) NULL;
79
80
81 }
82 /*-----------------------------------------------------------------*/
83 /* newBucket - allocates & returns a new bucket        */
84 /*-----------------------------------------------------------------*/
85 bucket *
86 newBucket ()
87 {
88   bucket *bp;
89
90   bp = Safe_alloc ( sizeof (bucket));
91
92   return bp;
93 }
94
95 /*-----------------------------------------------------------------*/
96 /* hashKey - computes the hashkey given a symbol name              */
97 /*-----------------------------------------------------------------*/
98 int 
99 hashKey (const char *s)
100 {
101   unsigned long key = 0;
102
103   while (*s)
104     key += *s++;
105   return key % 256;
106 }
107
108 /*-----------------------------------------------------------------*/
109 /* addSym - adds a symbol to the hash Table                        */
110 /*-----------------------------------------------------------------*/
111 void 
112 addSym (bucket ** stab,
113         void *sym,
114         char *sname,
115         int level,
116         int block,
117         int checkType)
118 {
119   int i;                        /* index into the hash Table */
120   bucket *bp;                   /* temp bucket    *         */
121
122   if (checkType) {
123     symbol *csym = (symbol *)sym;
124
125     if (getenv("DEBUG_SANITY")) {
126       fprintf (stderr, "addSym: %s ", sname);
127     }
128     /* make sure the type is complete and sane */
129     checkTypeSanity(csym->etype, csym->name);
130   }
131
132   /* prevent overflow of the (r)name buffers */
133   if (strlen(sname)>SDCC_SYMNAME_MAX) {
134     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
135     sname[SDCC_SYMNAME_MAX]='\0';
136   }
137
138   /* the symbols are always added at the head of the list  */
139   i = hashKey (sname);
140   /* get a free entry */
141   bp = Safe_alloc ( sizeof (bucket));
142
143   bp->sym = sym;                /* update the symbol pointer  */
144   bp->level = level;            /* update the nest level      */
145   bp->block = block;
146   strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
147
148   /* if this is the first entry */
149   if (stab[i] == NULL)
150     {
151       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
152       stab[i] = bp;
153     }
154   /* not first entry then add @ head of list */
155   else
156     {
157       bp->prev = NULL;
158       stab[i]->prev = bp;
159       bp->next = stab[i];
160       stab[i] = bp;
161     }
162 }
163
164 /*-----------------------------------------------------------------*/
165 /* deleteSym - deletes a symbol from the hash Table  entry     */
166 /*-----------------------------------------------------------------*/
167 void 
168 deleteSym (bucket ** stab, void *sym, char *sname)
169 {
170   int i = 0;
171   bucket *bp;
172
173   i = hashKey (sname);
174
175   bp = stab[i];
176   /* find the symbol */
177   while (bp)
178     {
179       if (bp->sym == sym)       /* found it then break out */
180         break;                  /* of the loop       */
181       bp = bp->next;
182     }
183
184   if (!bp)                      /* did not find it */
185     return;
186   /* if this is the first one in the chain */
187   if (!bp->prev)
188     {
189       stab[i] = bp->next;
190       if (stab[i])              /* if chain ! empty */
191         stab[i]->prev = (void *) NULL;
192     }
193   /* middle || end of chain */
194   else
195     {
196       if (bp->next)             /* if not end of chain */
197         bp->next->prev = bp->prev;
198
199       bp->prev->next = bp->next;
200     }
201
202 }
203
204 /*-----------------------------------------------------------------*/
205 /* findSym - finds a symbol in a table           */
206 /*-----------------------------------------------------------------*/
207 void *
208 findSym (bucket ** stab, void *sym, const char *sname)
209 {
210   bucket *bp;
211
212   bp = stab[hashKey (sname)];
213   while (bp)
214     {
215       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
216         break;
217       bp = bp->next;
218     }
219
220   return (bp ? bp->sym : (void *) NULL);
221 }
222
223 /*-----------------------------------------------------------------*/
224 /* findSymWithLevel - finds a symbol with a name & level           */
225 /*-----------------------------------------------------------------*/
226 void *
227 findSymWithLevel (bucket ** stab, symbol * sym)
228 {
229   bucket *bp;
230
231   bp = stab[hashKey (sym->name)];
232
233   /**
234    **  do the search from the head of the list since the
235    **  elements are added at the head it is ensured that
236    ** we will find the deeper definitions before we find
237    ** the global ones. we need to check for symbols with
238    ** level <= to the level given, if levels match then block
239    ** numbers need to match as well
240    **/
241   while (bp)
242     {
243       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
244         {
245           /* if this is parameter then nothing else need to be checked */
246           if (((symbol *) (bp->sym))->_isparm)
247             return (bp->sym);
248           /* if levels match then block numbers should also match */
249           if (bp->level && bp->level == sym->level && bp->block == sym->block)
250             return (bp->sym);
251           /* if levels don't match then we are okay */
252           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
253             return (bp->sym);
254           /* if this is a global variable then we are ok too */
255           if (bp->level == 0)
256             return (bp->sym);
257         }
258
259       bp = bp->next;
260     }
261
262   return (void *) NULL;
263 }
264
265 /*-----------------------------------------------------------------*/
266 /* findSymWithBlock - finds a symbol with name in with a block     */
267 /*-----------------------------------------------------------------*/
268 void *
269 findSymWithBlock (bucket ** stab, symbol * sym, int block)
270 {
271   bucket *bp;
272
273   bp = stab[hashKey (sym->name)];
274   while (bp)
275     {
276       if (strcmp (bp->name, sym->name) == 0 &&
277           bp->block <= block)
278         break;
279       bp = bp->next;
280     }
281
282   return (bp ? bp->sym : (void *) NULL);
283 }
284
285 /*------------------------------------------------------------------*/
286 /* newSymbol () - returns a new pointer to a symbol                 */
287 /*------------------------------------------------------------------*/
288 symbol *
289 newSymbol (char *name, int scope)
290 {
291   symbol *sym;
292
293   sym = Safe_alloc ( sizeof (symbol));
294
295   strncpyz (sym->name, name, sizeof(sym->name));        /* copy the name */
296   sym->level = scope;           /* set the level    */
297   sym->block = currBlockno;
298   sym->lineDef = mylineno;      /* set the line number */
299   sym->fileDef = currFname;
300   return sym;
301 }
302
303 /*------------------------------------------------------------------*/
304 /* newLink - creates a new link (declarator,specifier)              */
305 /*------------------------------------------------------------------*/
306 sym_link *
307 newLink (SYM_LINK_CLASS select)
308 {
309   sym_link *p;
310
311   p = Safe_alloc ( sizeof (sym_link));
312   p->class=select;
313
314   return p;
315 }
316
317 /*------------------------------------------------------------------*/
318 /* newStruct - creats a new structdef from the free list            */
319 /*------------------------------------------------------------------*/
320 structdef *
321 newStruct (char *tag)
322 {
323   structdef *s;
324
325   s = Safe_alloc ( sizeof (structdef));
326
327   strncpyz (s->tag, tag, sizeof(s->tag));               /* copy the tag */
328   return s;
329 }
330   
331 /*------------------------------------------------------------------*/
332 /* sclsFromPtr - Return the storage class a pointer points into.    */
333 /*               S_FIXED is returned for generic pointers or other  */
334 /*               unexpected cases                                   */
335 /*------------------------------------------------------------------*/
336 STORAGE_CLASS
337 sclsFromPtr(sym_link *ptr)
338 {
339   switch (DCL_TYPE (ptr))
340     {
341     case POINTER:
342       return S_DATA;
343     case GPOINTER:
344       return S_FIXED;
345     case FPOINTER:
346       return S_XDATA;
347     case CPOINTER:
348       return S_CODE;
349     case IPOINTER:
350       return S_IDATA;
351     case PPOINTER:
352       return S_PDATA;
353     case EEPPOINTER:
354       return S_EEPROM;
355     case FUNCTION:
356       return S_CODE;
357     default:
358       return S_FIXED;
359     }
360 }
361
362 /*------------------------------------------------------------------*/
363 /* pointerTypes - do the computation for the pointer types          */
364 /*------------------------------------------------------------------*/
365 void 
366 pointerTypes (sym_link * ptr, sym_link * type)
367 {
368   if (IS_SPEC (ptr))
369     return;
370
371   /* find the first pointer type */
372   while (ptr && !IS_PTR (ptr))
373     ptr = ptr->next;
374
375   /* could not find it */
376   if (!ptr || IS_SPEC (ptr))
377     return;
378   
379   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
380     pointerTypes (ptr->next, type);
381     return;
382   }
383
384   /* change the pointer type depending on the
385      storage class of the type */
386   if (IS_SPEC (type))
387     {
388       switch (SPEC_SCLS (type))
389         {
390         case S_XDATA:
391           DCL_TYPE (ptr) = FPOINTER;
392           break;
393         case S_IDATA:
394           DCL_TYPE (ptr) = IPOINTER;
395           break;
396         case S_PDATA:
397           DCL_TYPE (ptr) = PPOINTER;
398           break;
399         case S_DATA:
400           DCL_TYPE (ptr) = POINTER;
401           break;
402         case S_CODE:
403           DCL_TYPE (ptr) = CPOINTER;
404           break;
405         case S_EEPROM:
406           DCL_TYPE (ptr) = EEPPOINTER;
407           break;
408         default:
409           DCL_TYPE (ptr) = port->unqualified_pointer;
410           break;
411         }
412       /* the storage class of type ends here */
413       SPEC_SCLS (type) = 0;
414     }
415
416   /* now change all the remaining unknown pointers
417      to generic pointers */
418   while (ptr)
419     {
420       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
421         DCL_TYPE (ptr) = port->unqualified_pointer;
422       ptr = ptr->next;
423     }
424
425   /* same for the type although it is highly unlikely that
426      type will have a pointer */
427   while (type)
428     {
429       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
430         DCL_TYPE (type) = port->unqualified_pointer;
431       type = type->next;
432     }
433 }
434
435 /*------------------------------------------------------------------*/
436 /* addDecl - adds a declarator @ the end of a chain                 */
437 /*------------------------------------------------------------------*/
438 void 
439 addDecl (symbol * sym, int type, sym_link * p)
440 {
441   sym_link *head;
442   sym_link *tail;
443   sym_link *t;
444
445   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
446     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
447
448   /* if we are passed a link then set head & tail */
449   if (p)
450     {
451       tail = head = p;
452       while (tail->next)
453         tail = tail->next;
454     }
455   else
456     {
457       head = tail = newLink (DECLARATOR);
458       DCL_TYPE (head) = type;
459     }
460
461   /* if this is the first entry   */
462   if (!sym->type)
463     {
464       sym->type = head;
465       sym->etype = tail;
466     }
467   else
468     {
469       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
470         {
471           sym->etype = mergeSpec (sym->etype, head, sym->name);
472         }
473       else
474         {
475           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
476             {
477               t = sym->type;
478               while (t->next != sym->etype)
479                 t = t->next;
480               t->next = head;
481               tail->next = sym->etype;
482             }
483           else
484             {
485               sym->etype->next = head;
486               sym->etype = tail;
487             }
488         }
489     }
490
491   /* if the type is an unknown pointer and has
492      a tspec then take the storage class const & volatile
493      attribute from the tspec & make it those of this
494      symbol */
495   if (p &&
496       !IS_SPEC (p) &&
497       //DCL_TYPE (p) == UPOINTER &&
498       DCL_TSPEC (p))
499     {
500       if (!IS_SPEC (sym->etype))
501         {
502           sym->etype = sym->etype->next = newLink (SPECIFIER);
503         }
504       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
505       DCL_TSPEC (p) = NULL;
506     }
507
508   // if there is a function in this type chain
509   if (p && funcInChain(sym->type)) {
510     processFuncArgs (sym);
511   }
512
513   return;
514 }
515
516 /*------------------------------------------------------------------
517   checkTypeSanity: prevent the user from doing e.g.:
518   unsigned float uf;
519   ------------------------------------------------------------------*/
520 void checkTypeSanity(sym_link *etype, char *name) {
521   char *noun;
522
523   if (!etype) {
524     if (getenv("DEBUG_SANITY")) {
525       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
526     }
527     return;
528   }
529
530   if (!IS_SPEC(etype)) {
531     if (getenv("DEBUG_SANITY")) {
532       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
533     }
534     return;
535   }
536
537   noun=nounName(etype);
538
539   if (getenv("DEBUG_SANITY")) {
540     fprintf (stderr, "checking sanity for %s %p\n", name, etype);
541   }
542
543   if ((SPEC_NOUN(etype)==V_CHAR || 
544        SPEC_NOUN(etype)==V_FLOAT || 
545        SPEC_NOUN(etype)==V_FIXED16X16 ||
546        SPEC_NOUN(etype)==V_DOUBLE || 
547        SPEC_NOUN(etype)==V_VOID) &&
548       (SPEC_SHORT(etype) || SPEC_LONG(etype))) {
549     // long or short for char float double or void
550     werror (E_LONG_OR_SHORT_INVALID, noun, name);
551   }
552   if ((SPEC_NOUN(etype)==V_FLOAT || 
553        SPEC_NOUN(etype)==V_FIXED16X16 ||
554        SPEC_NOUN(etype)==V_DOUBLE || 
555        SPEC_NOUN(etype)==V_VOID) && 
556       (etype->select.s.b_signed || SPEC_USIGN(etype))) {
557     // signed or unsigned for float double or void
558     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
559   }
560
561   // special case for "short"
562   if (SPEC_SHORT(etype)) {
563     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
564     SPEC_SHORT(etype) = 0;
565   }
566
567   /* if no noun e.g. 
568      "const a;" or "data b;" or "signed s" or "long l"
569      assume an int */
570   if (!SPEC_NOUN(etype)) {
571     SPEC_NOUN(etype)=V_INT;
572   }
573
574   /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
575   /* a "plain" int bitfield is unsigned */
576   if (SPEC_NOUN(etype)==V_BIT ||
577       SPEC_NOUN(etype)==V_SBIT) {
578     if (!etype->select.s.b_signed)
579       SPEC_USIGN(etype) = 1;
580   }
581
582   if (etype->select.s.b_signed && SPEC_USIGN(etype)) {
583     // signed AND unsigned 
584     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
585   }
586   if (SPEC_SHORT(etype) && SPEC_LONG(etype)) {
587     // short AND long
588     werror (E_LONG_AND_SHORT_INVALID, noun, name);
589   }
590
591 }
592
593 /*------------------------------------------------------------------*/
594 /* mergeSpec - merges two specifiers and returns the new one        */
595 /*------------------------------------------------------------------*/
596 sym_link *
597 mergeSpec (sym_link * dest, sym_link * src, char *name)
598 {
599   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
600 #if 0
601     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
602     exit (1);
603 #else
604     werror (E_SYNTAX_ERROR, yytext);
605     // the show must go on
606     return newIntLink();
607 #endif
608   }
609
610   if (SPEC_NOUN(src)) {
611     if (!SPEC_NOUN(dest)) {
612       SPEC_NOUN(dest)=SPEC_NOUN(src);
613     } else {
614       /* we shouldn't redeclare the type */
615       if (getenv("DEBUG_SANITY")) {
616         fprintf (stderr, "mergeSpec: ");
617       }
618       werror(E_TWO_OR_MORE_DATA_TYPES, name);
619     }
620   }
621   
622   if (SPEC_SCLS(src)) {
623     /* if destination has no storage class */
624     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
625       SPEC_SCLS (dest) = SPEC_SCLS (src);
626     } else {
627       if (getenv("DEBUG_SANITY")) {
628         fprintf (stderr, "mergeSpec: ");
629       }
630       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
631     }
632   }
633
634   /* copy all the specifications  */
635
636   // we really should do: 
637 #if 0
638   if (SPEC_what(src)) {
639     if (SPEC_what(dest)) {
640       werror(W_DUPLICATE_SPEC, "what");
641     }
642     SPEC_what(dst)|=SPEC_what(src);
643   }
644 #endif
645   // but there are more important thing right now
646
647   SPEC_LONG (dest) |= SPEC_LONG (src);
648   SPEC_SHORT(dest) |= SPEC_SHORT(src);
649   SPEC_USIGN (dest) |= SPEC_USIGN (src);
650   dest->select.s.b_signed|=src->select.s.b_signed;
651   SPEC_STAT (dest) |= SPEC_STAT (src);
652   SPEC_EXTR (dest) |= SPEC_EXTR (src);
653   SPEC_CONST(dest) |= SPEC_CONST (src);
654   SPEC_ABSA (dest) |= SPEC_ABSA (src);
655   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
656   SPEC_ADDR (dest) |= SPEC_ADDR (src);
657   SPEC_OCLS (dest) = SPEC_OCLS (src);
658   SPEC_BLEN (dest) |= SPEC_BLEN (src);
659   SPEC_BSTR (dest) |= SPEC_BSTR (src);
660   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
661   SPEC_ENUM (dest) |= SPEC_ENUM (src);
662   if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
663       SPEC_ARGREG(dest) = SPEC_ARGREG(src);
664   
665   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
666     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
667
668   /* these are the only function attributes that will be set 
669      in a specifier while parsing */
670   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
671   FUNC_BANKED(dest) |= FUNC_BANKED(src);
672   FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
673   FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
674   FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
675   FUNC_ISISR(dest) |= FUNC_ISISR(src);
676   FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
677   FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
678   FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
679   FUNC_INTNO(dest) |= FUNC_INTNO(src);
680   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
681
682   return dest;
683 }
684
685 /*------------------------------------------------------------------*/
686 /* genSymName - generates and returns a name used for anonymous vars */
687 /*------------------------------------------------------------------*/
688 char *
689 genSymName (int level)
690 {
691   static int gCount = 0;
692   static char gname[SDCC_NAME_MAX + 1];
693
694   SNPRINTF (gname, sizeof(gname), "__%04d%04d", level, gCount++);
695   return gname;
696 }
697
698 /*------------------------------------------------------------------*/
699 /* getSpec - returns the specifier part from a declaration chain    */
700 /*------------------------------------------------------------------*/
701 sym_link *
702 getSpec (sym_link * p)
703 {
704   sym_link *loop;
705
706   loop = p;
707   while (p && !(IS_SPEC (p)))
708     p = p->next;
709
710   return p;
711 }
712
713 /*------------------------------------------------------------------*/
714 /* newCharLink() - creates an char type                             */
715 /*------------------------------------------------------------------*/
716 sym_link *
717 newCharLink ()
718 {
719   sym_link *p;
720
721   p = newLink (SPECIFIER);
722   SPEC_NOUN (p) = V_CHAR;
723
724   return p;
725 }
726
727 /*------------------------------------------------------------------*/
728 /* newFloatLink - a new Float type                                  */
729 /*------------------------------------------------------------------*/
730 sym_link *
731 newFloatLink ()
732 {
733   sym_link *p;
734
735   p = newLink (SPECIFIER);
736   SPEC_NOUN (p) = V_FLOAT;
737
738   return p;
739 }
740
741 /*------------------------------------------------------------------*/
742 /* newFixed16x16Link - a new Float type                                  */
743 /*------------------------------------------------------------------*/
744 sym_link *
745 newFixed16x16Link ()
746 {
747   sym_link *p;
748
749   p = newLink (SPECIFIER);
750   SPEC_NOUN (p) = V_FIXED16X16;
751
752   return p;
753 }
754
755 /*------------------------------------------------------------------*/
756 /* newLongLink() - new long type                                    */
757 /*------------------------------------------------------------------*/
758 sym_link *
759 newLongLink ()
760 {
761   sym_link *p;
762
763   p = newLink (SPECIFIER);
764   SPEC_NOUN (p) = V_INT;
765   SPEC_LONG (p) = 1;
766
767   return p;
768 }
769
770 /*------------------------------------------------------------------*/
771 /* newIntLink() - creates an int type                               */
772 /*------------------------------------------------------------------*/
773 sym_link *
774 newIntLink ()
775 {
776   sym_link *p;
777
778   p = newLink (SPECIFIER);
779   SPEC_NOUN (p) = V_INT;
780
781   return p;
782 }
783
784 /*------------------------------------------------------------------*/
785 /* newBoolLink() - creates an bool type                             */
786 /*------------------------------------------------------------------*/
787 sym_link *
788 newBoolLink ()
789 {
790   sym_link *p;
791
792   p = newLink (SPECIFIER);
793   SPEC_NOUN (p) = V_BIT;
794
795   return p;
796 }
797
798 /*------------------------------------------------------------------*/
799 /* getSize - returns size of a type chain in bits                   */
800 /*------------------------------------------------------------------*/
801 unsigned int 
802 getSize (sym_link * p)
803 {
804   /* if nothing return 0 */
805   if (!p)
806     return 0;
807   if (IS_SPEC (p))
808     {                           /* if this is the specifier then */
809       switch (SPEC_NOUN (p))
810         {                       /* depending on the specifier type */
811         case V_INT:
812           return (IS_LONG (p) ? LONGSIZE : INTSIZE);
813         case V_FLOAT:
814           return FLOATSIZE;
815         case V_FIXED16X16:
816           return (4);
817         case V_CHAR:
818           return CHARSIZE;
819         case V_VOID:
820           return 0;
821         case V_STRUCT:
822           return SPEC_STRUCT (p)->size;
823         case V_LABEL:
824           return 0;
825         case V_SBIT:
826         case V_BIT:
827           return BITSIZE;
828         case V_BITFIELD:
829           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
830         default:
831           return 0;
832         }
833     }
834
835   /* this is a declarator */
836   switch (DCL_TYPE (p))
837     {
838     case ARRAY:
839       if (DCL_ELEM(p)) {
840         return DCL_ELEM (p) * getSize (p->next);
841       } else {
842           //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
843           //    "can not tell the size of an array[]");
844         return 0;
845       }
846     case IPOINTER:
847     case PPOINTER:
848     case POINTER:
849       return (PTRSIZE);
850     case EEPPOINTER:
851     case FPOINTER:
852     case CPOINTER:
853     case FUNCTION:
854       return (IFFUNC_BANKED (p) ? GPTRSIZE : FPTRSIZE);
855     case GPOINTER:
856       return (GPTRSIZE);
857
858     default:
859       return 0;
860     }
861 }
862
863 /*---------------------------------------------------------------------*/
864 /* getAllocSize - returns size of a type chain in bytes for allocation */
865 /*---------------------------------------------------------------------*/
866 unsigned int
867 getAllocSize (sym_link *p)
868 {
869   if (IS_STRUCT (p) && SPEC_STRUCT (p)->type == STRUCT)
870     {
871       /* if this is a struct specifier then  */
872       /* calculate the size as it could end  */
873       /* with an array of unspecified length */
874       symbol *sflds = SPEC_STRUCT (p)->fields;
875
876       while (sflds && sflds->next)
877         sflds = sflds->next;
878
879       if (sflds && !IS_BITFIELD (sflds->type))
880         return sflds->offset + getAllocSize (sflds->type);
881       else
882         return SPEC_STRUCT (p)->size;
883     }
884   else
885     return getSize (p);
886 }
887
888 /*------------------------------------------------------------------*/
889 /* bitsForType - returns # of bits required to store this type      */
890 /*------------------------------------------------------------------*/
891 unsigned int 
892 bitsForType (sym_link * p)
893 {
894   /* if nothing return 0 */
895   if (!p)
896     return 0;
897
898   if (IS_SPEC (p))
899     {                           /* if this is the specifier then */
900
901       switch (SPEC_NOUN (p))
902         {                       /* depending on the specifier type */
903         case V_INT:
904           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
905         case V_FLOAT:
906           return FLOATSIZE * 8;
907         case V_FIXED16X16:
908           return (32);
909         case V_CHAR:
910           return CHARSIZE * 8;
911         case V_VOID:
912           return 0;
913         case V_STRUCT:
914           return SPEC_STRUCT (p)->size * 8;
915         case V_LABEL:
916           return 0;
917         case V_SBIT:
918         case V_BIT:
919           return 1;
920         case V_BITFIELD:
921           return SPEC_BLEN (p);
922         default:
923           return 0;
924         }
925     }
926
927   /* this is a specifier  */
928   switch (DCL_TYPE (p))
929     {
930     case ARRAY:
931       return DCL_ELEM (p) * getSize (p->next) * 8;
932     case IPOINTER:
933     case PPOINTER:
934     case POINTER:
935       return (PTRSIZE * 8);
936     case EEPPOINTER:
937     case FPOINTER:
938     case CPOINTER:
939     case FUNCTION:
940       return (FPTRSIZE * 8);
941     case GPOINTER:
942       return (GPTRSIZE * 8);
943
944     default:
945       return 0;
946     }
947 }
948
949 /*------------------------------------------------------------------*/
950 /* copySymbolChain - copies a symbol chain                          */
951 /*------------------------------------------------------------------*/
952 symbol *
953 copySymbolChain (symbol * src)
954 {
955   symbol *dest;
956
957   if (!src)
958     return NULL;
959
960   dest = copySymbol (src);
961   dest->next = copySymbolChain (src->next);
962   return dest;
963 }
964
965 /*------------------------------------------------------------------*/
966 /* copySymbol - makes a copy of a symbol                            */
967 /*------------------------------------------------------------------*/
968 symbol *
969 copySymbol (symbol * src)
970 {
971   symbol *dest;
972
973   if (!src)
974     return NULL;
975
976   dest = newSymbol (src->name, src->level);
977   memcpy (dest, src, sizeof (symbol));
978   dest->level = src->level;
979   dest->block = src->block;
980   dest->ival = copyIlist (src->ival);
981   dest->type = copyLinkChain (src->type);
982   dest->etype = getSpec (dest->type);
983   dest->next = NULL;
984   dest->key = src->key;
985   dest->allocreq = src->allocreq;
986   return dest;
987 }
988
989 /*------------------------------------------------------------------*/
990 /* reverseSyms - reverses the links for a symbol chain      */
991 /*------------------------------------------------------------------*/
992 symbol *
993 reverseSyms (symbol * sym)
994 {
995   symbol *prev, *curr, *next;
996
997   if (!sym)
998     return NULL;
999
1000   prev = sym;
1001   curr = sym->next;
1002
1003   while (curr)
1004     {
1005       next = curr->next;
1006       curr->next = prev;
1007       prev = curr;
1008       curr = next;
1009     }
1010   sym->next = (void *) NULL;
1011   return prev;
1012 }
1013
1014 /*------------------------------------------------------------------*/
1015 /* reverseLink - reverses the links for a type chain        */
1016 /*------------------------------------------------------------------*/
1017 sym_link *
1018 reverseLink (sym_link * type)
1019 {
1020   sym_link *prev, *curr, *next;
1021
1022   if (!type)
1023     return NULL;
1024
1025   prev = type;
1026   curr = type->next;
1027
1028   while (curr)
1029     {
1030       next = curr->next;
1031       curr->next = prev;
1032       prev = curr;
1033       curr = next;
1034     }
1035   type->next = (void *) NULL;
1036   return prev;
1037 }
1038
1039 /*------------------------------------------------------------------*/
1040 /* addSymChain - adds a symbol chain to the symboltable             */
1041 /*------------------------------------------------------------------*/
1042 void 
1043 addSymChain (symbol ** symHead)
1044 {
1045   symbol *sym = *symHead;
1046   symbol *csym = NULL;
1047   symbol **symPtrPtr;
1048   int error = 0;
1049
1050   for (; sym != NULL; sym = sym->next)
1051     {
1052       changePointer(sym->type);
1053       checkTypeSanity(sym->etype, sym->name);
1054
1055       if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype)))
1056         checkDecl (sym, 0);
1057       
1058       /* if already exists in the symbol table then check if
1059          one of them is an extern definition if yes then
1060          then check if the type match, if the types match then
1061          delete the current entry and add the new entry      */
1062       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
1063           csym->level == sym->level) {
1064
1065         /* If the previous definition was for an array with incomplete */
1066         /* type, and the new definition has completed the type, update */
1067         /* the original type to match */
1068         if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
1069             && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
1070           {
1071             if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
1072               DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
1073           }
1074
1075         #if 0
1076         /* If only one of the definitions used the "at" keyword, copy */
1077         /* the address to the other. */
1078         if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
1079             && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
1080           {
1081             SPEC_ABSA (sym->etype) = 1;
1082             SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1083           }
1084         if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
1085             && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
1086           {
1087             SPEC_ABSA (csym->etype) = 1;
1088             SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1089           }
1090         #endif
1091   
1092         error = 0;        
1093         if (csym->ival && sym->ival)
1094           error = 1;
1095         if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1096           error = 1;
1097         
1098         if (error) {
1099           /* one definition extern ? */
1100           if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1101             werror (E_EXTERN_MISMATCH, sym->name);
1102           else
1103             werror (E_DUPLICATE, sym->name);
1104           werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1105           #if 0
1106           fprintf (stderr, "from type '");
1107           printTypeChain (csym->type, stderr);
1108           if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1109             fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1110           fprintf (stderr, "'\nto type '");
1111           printTypeChain (sym->type, stderr);
1112           if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1113             fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1114           fprintf (stderr, "'\n");
1115           #endif
1116           continue;
1117         }
1118
1119         if (csym->ival && !sym->ival)
1120           sym->ival = csym->ival;
1121
1122         /* delete current entry */
1123         deleteSym (SymbolTab, csym, csym->name);
1124         deleteFromSeg(csym);
1125         
1126         symPtrPtr = symHead;
1127         while (*symPtrPtr && *symPtrPtr != csym)
1128           symPtrPtr = &(*symPtrPtr)->next;
1129         if (*symPtrPtr == csym)
1130           *symPtrPtr = csym->next;
1131           
1132       }
1133       
1134       /* add new entry */
1135       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1136     }
1137 }
1138
1139
1140 /*------------------------------------------------------------------*/
1141 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1142 /*------------------------------------------------------------------*/
1143 int 
1144 funcInChain (sym_link * lnk)
1145 {
1146   while (lnk)
1147     {
1148       if (IS_FUNC (lnk))
1149         return 1;
1150       lnk = lnk->next;
1151     }
1152   return 0;
1153 }
1154
1155 /*------------------------------------------------------------------*/
1156 /* structElemType - returns the type info of a struct member        */
1157 /*------------------------------------------------------------------*/
1158 sym_link *
1159 structElemType (sym_link * stype, value * id)
1160 {
1161   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1162   sym_link *type, *etype;
1163   sym_link *petype = getSpec (stype);
1164
1165   if (fields && id) {
1166     
1167     /* look for the id */
1168     while (fields)
1169       {
1170         if (strcmp (fields->rname, id->name) == 0)
1171           {
1172             type = copyLinkChain (fields->type);
1173             etype = getSpec (type);
1174             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1175                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
1176             if (IS_SPEC (type))
1177               SPEC_CONST (type) |= SPEC_CONST (stype);
1178             else
1179               DCL_PTR_CONST (type) |= SPEC_CONST (stype);
1180             return type;
1181           }
1182         fields = fields->next;
1183       }
1184   }
1185
1186   werror (E_NOT_MEMBER, id->name);
1187     
1188   // the show must go on
1189   return newIntLink();
1190 }
1191
1192 /*------------------------------------------------------------------*/
1193 /* getStructElement - returns element of a tructure definition      */
1194 /*------------------------------------------------------------------*/
1195 symbol *
1196 getStructElement (structdef * sdef, symbol * sym)
1197 {
1198   symbol *field;
1199
1200   for (field = sdef->fields; field; field = field->next)
1201     if (strcmp (field->name, sym->name) == 0)
1202       return field;
1203
1204   werror (E_NOT_MEMBER, sym->name);
1205
1206   return sdef->fields;
1207 }
1208
1209 /*------------------------------------------------------------------*/
1210 /* compStructSize - computes the size of a structure                */
1211 /*------------------------------------------------------------------*/
1212 int 
1213 compStructSize (int su, structdef * sdef)
1214 {
1215     int sum = 0, usum = 0;
1216     int bitOffset = 0;
1217     symbol *loop;
1218
1219     /* for the identifiers  */
1220     loop = sdef->fields;
1221     while (loop) {
1222
1223         /* create the internal name for this variable */
1224         SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1225         if (su == UNION) {
1226             sum = 0;
1227             bitOffset = 0;
1228         }
1229         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1230
1231         /* if this is a bit field  */
1232         if (loop->bitVar) {
1233
1234             /* change it to a unsigned bit */
1235             SPEC_NOUN (loop->etype) = V_BITFIELD;
1236                 if (TARGET_IS_PIC16 || TARGET_IS_PIC) {
1237                 /* PIC users requested signed bitfields as well */
1238             } else {
1239                 SPEC_USIGN (loop->etype) = 1;
1240                 }
1241             SPEC_BLEN (loop->etype) = loop->bitVar;
1242
1243             if (loop->bitVar == BITVAR_PAD) {
1244                 /* A zero length bitfield forces padding */
1245                 SPEC_BSTR (loop->etype) = bitOffset;
1246                 SPEC_BLEN (loop->etype) = 0;
1247                 bitOffset = 8;
1248                 loop->offset = sum;
1249             }
1250             else {
1251                 if (bitOffset == 8) {
1252                     bitOffset = 0;
1253                     sum++;
1254                 }
1255                 /* check if this fit into the remaining   */
1256                 /* bits of this byte else align it to the */
1257                 /* next byte boundary                     */
1258                 if (loop->bitVar <= (8 - bitOffset)) {
1259                     /* fits into current byte */
1260                     loop->offset = sum;
1261                     SPEC_BSTR (loop->etype) = bitOffset;
1262                     bitOffset += loop->bitVar;
1263                 }
1264                 else if (!bitOffset) {
1265                     /* does not fit, but is already byte aligned */
1266                     loop->offset = sum;
1267                     SPEC_BSTR (loop->etype) = bitOffset;
1268                     bitOffset += loop->bitVar;
1269                 } 
1270                 else {
1271                     /* does not fit; need to realign first */
1272                     sum++;
1273                     loop->offset = (su == UNION ? sum = 0 : sum);
1274                     bitOffset = 0;
1275                     SPEC_BSTR (loop->etype) = bitOffset;
1276                     bitOffset += loop->bitVar;
1277                 }
1278                 while (bitOffset>8) {
1279                     bitOffset -= 8;
1280                     sum++;
1281                 } 
1282             }
1283         }
1284         else {
1285             /* This is a non-bit field. Make sure we are */
1286             /* byte aligned first */
1287             if (bitOffset) {
1288                 sum++;
1289                 loop->offset = (su == UNION ? sum = 0 : sum);
1290                 bitOffset = 0;
1291             }
1292             loop->offset = sum;
1293             checkDecl (loop, 1);
1294             sum += getSize (loop->type);
1295         }
1296
1297         loop = loop->next;
1298
1299         /* if union then size = sizeof largest field */
1300         if (su == UNION) {
1301             /* For UNION, round up after each field */
1302             sum += ((bitOffset+7)/8);
1303             usum = max (usum, sum);
1304         }
1305
1306     }
1307     
1308     /* For STRUCT, round up after all fields processed */
1309     if (su != UNION)
1310         sum += ((bitOffset+7)/8);
1311
1312     return (su == UNION ? usum : sum);
1313 }
1314
1315 /*-------------------------------------------------------------------*/
1316 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1317 /*                      an enclosing struct/union                    */
1318 /*-------------------------------------------------------------------*/
1319 void
1320 promoteAnonStructs (int su, structdef * sdef)
1321 {
1322   symbol *field;
1323   symbol *subfield;
1324   symbol **tofield;
1325   symbol *nextfield;
1326   symbol *dupfield;
1327   int base;
1328
1329   tofield = &sdef->fields;
1330   field = sdef->fields;
1331   while (field)
1332     {
1333       nextfield = field->next;
1334       if (!*field->name && IS_STRUCT (field->type))
1335         {
1336           /* Found an anonymous struct/union. Replace it */
1337           /* with the fields it contains and adjust all  */
1338           /* the offsets */
1339           
1340           base = field->offset;
1341           subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1342           if (!subfield)
1343             continue;           /* just in case it's empty */
1344           
1345           *tofield = subfield;
1346           for (;;)
1347             {
1348               /* check for field name conflicts resulting from promotion */
1349               dupfield = sdef->fields;
1350               while (dupfield && dupfield != subfield)
1351                 {
1352                   if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1353                     {
1354                       werrorfl (subfield->fileDef, subfield->lineDef,
1355                                 E_DUPLICATE_MEMBER,
1356                                 su==STRUCT ? "struct" : "union",
1357                                 subfield->name);
1358                       werrorfl (dupfield->fileDef, dupfield->lineDef,
1359                                 E_PREVIOUS_DEF);
1360                     }
1361                   dupfield = dupfield->next;
1362                 }
1363               
1364               subfield->offset += base;
1365               if (subfield->next)
1366                 subfield = subfield->next;
1367               else
1368                 break;
1369             }
1370           subfield->next = nextfield;
1371           tofield = &subfield->next;
1372         }
1373       else
1374         tofield = &field->next;
1375       field = nextfield;
1376     }
1377 }
1378
1379
1380 /*------------------------------------------------------------------*/
1381 /* checkSClass - check the storage class specification              */
1382 /*------------------------------------------------------------------*/
1383 static void 
1384 checkSClass (symbol * sym, int isProto)
1385 {
1386   sym_link *t;
1387   
1388   if (getenv("DEBUG_SANITY")) {
1389     fprintf (stderr, "checkSClass: %s \n", sym->name);
1390   }
1391   
1392   /* type is literal can happen for enums change
1393      to auto */
1394   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1395     SPEC_SCLS (sym->etype) = S_AUTO;
1396   
1397   /* if sfr or sbit then must also be volatile */
1398   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1399       SPEC_SCLS (sym->etype) == S_SFR)
1400     {
1401       SPEC_VOLATILE (sym->etype) = 1;
1402     }
1403   
1404   /* if absolute address given then it mark it as
1405      volatile -- except in the PIC port */
1406
1407 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1408   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1409   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1410 #endif
1411
1412     if (IS_ABSOLUTE (sym->etype))
1413       SPEC_VOLATILE (sym->etype) = 1;
1414   
1415   if (TARGET_IS_MCS51 &&
1416       IS_ABSOLUTE (sym->etype) &&
1417       SPEC_SCLS (sym->etype) == S_SFR)
1418     {
1419       int n, size;
1420       unsigned addr;
1421
1422       if (SPEC_NOUN (sym->etype) == V_CHAR)
1423         size = 8;
1424       else if (SPEC_LONG (sym->etype) == 0)
1425         size = 16;
1426       else
1427         size = 32;
1428
1429       addr = SPEC_ADDR (sym->etype);
1430       for (n=0; n<size; n+=8)
1431         if (((addr >> n) & 0xFF) < 0x80)
1432           werror (W_SFR_ABSRANGE, sym->name);
1433     }
1434
1435   /* If code memory is read only, then pointers to code memory */
1436   /* implicitly point to constants -- make this explicit       */
1437   t = sym->type;
1438   while (t && t->next) {
1439     if (IS_CODEPTR(t) && port->mem.code_ro) {
1440       if (IS_SPEC(t->next)) {
1441         SPEC_CONST (t->next) = 1;
1442       } else {
1443         DCL_PTR_CONST (t->next) = 1;
1444       }
1445     }
1446     t = t->next;
1447   }
1448
1449   /* global variables declared const put into code */
1450   /* if no other storage class specified */
1451   if (sym->level == 0 &&
1452       SPEC_SCLS(sym->etype) == S_FIXED &&
1453       !IS_FUNC(sym->type)) {
1454     /* find the first non-array link */
1455     t = sym->type;
1456     while (IS_ARRAY(t))
1457       t = t->next;
1458     if (IS_CONSTANT (t)) {
1459       SPEC_SCLS (sym->etype) = S_CODE;
1460     }
1461   }
1462
1463   /* global variable in code space is a constant */
1464   if (sym->level == 0 &&
1465       SPEC_SCLS (sym->etype) == S_CODE &&
1466       port->mem.code_ro) {
1467     /* find the first non-array link */
1468     t = sym->type;
1469     while (IS_ARRAY(t))
1470       t = t->next;
1471     if (IS_SPEC(t)) {
1472       SPEC_CONST (t) = 1;
1473     } else {
1474       DCL_PTR_CONST (t) = 1;
1475     }
1476   }
1477
1478   /* if bit variable then no storage class can be */
1479   /* specified since bit is already a storage */
1480   if (IS_BITVAR (sym->etype) &&
1481       (SPEC_SCLS (sym->etype) != S_FIXED &&
1482        SPEC_SCLS (sym->etype) != S_SBIT &&
1483        SPEC_SCLS (sym->etype) != S_BIT)
1484     )
1485     {
1486       werror (E_BITVAR_STORAGE, sym->name);
1487       SPEC_SCLS (sym->etype) = S_FIXED;
1488     }
1489
1490   /* extern variables cannot be initialized */
1491   if (IS_EXTERN (sym->etype) && sym->ival)
1492     {
1493       werror (E_EXTERN_INIT, sym->name);
1494       sym->ival = NULL;
1495     }
1496
1497   /* if this is an automatic symbol */
1498   if (sym->level && (options.stackAuto || reentrant)) {
1499     if (SPEC_SCLS (sym->etype) != S_BIT) {
1500       if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1501            SPEC_SCLS (sym->etype) == S_FIXED ||
1502            SPEC_SCLS (sym->etype) == S_REGISTER ||
1503            SPEC_SCLS (sym->etype) == S_STACK ||
1504            SPEC_SCLS (sym->etype) == S_XSTACK)) {
1505         SPEC_SCLS (sym->etype) = S_AUTO;
1506       } else {
1507         /* storage class may only be specified for statics */
1508         if (!IS_STATIC(sym->etype)) {
1509           werror (E_AUTO_ASSUMED, sym->name);
1510         }
1511       }
1512     }
1513   }
1514
1515   /* automatic symbols cannot be given   */
1516   /* an absolute address ignore it      */
1517   if (sym->level &&
1518       SPEC_ABSA (sym->etype) &&
1519       (options.stackAuto || reentrant))
1520     {
1521       werror (E_AUTO_ABSA, sym->name);
1522       SPEC_ABSA (sym->etype) = 0;
1523     }
1524
1525   /* arrays & pointers cannot be defined for bits   */
1526   /* SBITS or SFRs or BIT                           */
1527   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1528       !IS_FUNCPTR (sym->type) &&
1529       (SPEC_NOUN (sym->etype) == V_BIT ||
1530        SPEC_NOUN (sym->etype) == V_SBIT ||
1531        SPEC_NOUN (sym->etype) == V_BITFIELD ||
1532        SPEC_SCLS (sym->etype) == S_SFR))
1533     werror (E_BIT_ARRAY, sym->name);
1534
1535   /* if this is a bit|sbit then set length & start  */
1536   if (SPEC_NOUN (sym->etype) == V_BIT ||
1537       SPEC_NOUN (sym->etype) == V_SBIT)
1538     {
1539       SPEC_BLEN (sym->etype) = 1;
1540       SPEC_BSTR (sym->etype) = 0;
1541     }
1542
1543   if (!isProto) {
1544     /* variables declared in CODE space must have */
1545     /* initializers if not an extern */
1546     if (SPEC_SCLS (sym->etype) == S_CODE &&
1547         sym->ival == NULL &&
1548         !sym->_isparm &&
1549         //!sym->level &&
1550         port->mem.code_ro &&
1551         !IS_EXTERN (sym->etype) &&
1552         !funcInChain (sym->type))
1553       werror (E_CODE_NO_INIT, sym->name);
1554   }
1555
1556   /* if parameter or local variable then change */
1557   /* the storage class to reflect where the var will go */
1558   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
1559    && !IS_STATIC(sym->etype)
1560       )
1561     {
1562       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1563         {
1564           SPEC_SCLS (sym->etype) = (options.useXstack ?
1565                                     S_XSTACK : S_STACK);
1566         }
1567       else
1568         {
1569           /* hack-o-matic! I see no reason why the useXstack option should ever
1570            * control this allocation, but the code was originally that way, and
1571            * changing it for non-390 ports breaks the compiler badly.
1572            */
1573           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1574                 1 : options.useXstack;
1575           SPEC_SCLS (sym->etype) = (useXdata ?
1576                                     S_XDATA : S_FIXED);
1577         }
1578     }
1579 }
1580
1581 /*------------------------------------------------------------------*/
1582 /* changePointer - change pointer to functions                      */
1583 /*------------------------------------------------------------------*/
1584 void 
1585 changePointer (sym_link * p)
1586 {
1587
1588   /* go thru the chain of declarations   */
1589   /* if we find a pointer to a function  */
1590   /* change it to a ptr to code area     */
1591   /* unless the function is banked.      */
1592   for (; p; p = p->next)
1593     {
1594       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1595         DCL_TYPE (p) = port->unqualified_pointer;
1596       if (IS_PTR (p) && IS_FUNC (p->next))
1597         if (!IFFUNC_BANKED(p->next))
1598         DCL_TYPE (p) = CPOINTER;
1599     }
1600 }
1601
1602 /*------------------------------------------------------------------*/
1603 /* checkDecl - does semantic validation of a declaration                   */
1604 /*------------------------------------------------------------------*/
1605 int 
1606 checkDecl (symbol * sym, int isProto)
1607 {
1608
1609   checkSClass (sym, isProto);           /* check the storage class      */
1610   changePointer (sym->type);          /* change pointers if required */
1611
1612   /* if this is an array without any dimension
1613      then update the dimension from the initial value */
1614   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1615     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1616
1617   return 0;
1618 }
1619
1620 /*------------------------------------------------------------------*/
1621 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1622 /*------------------------------------------------------------------*/
1623 sym_link *
1624 copyLinkChain (sym_link * p)
1625 {
1626   sym_link *head, *curr, *loop;
1627
1628   curr = p;
1629   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1630   while (curr)
1631     {
1632       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1633       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1634       loop = loop->next;
1635       curr = curr->next;
1636     }
1637
1638   return head;
1639 }
1640
1641 /*------------------------------------------------------------------*/
1642 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1643 /*                symbols in the given block                        */
1644 /*------------------------------------------------------------------*/
1645 void 
1646 cleanUpBlock (bucket ** table, int block)
1647 {
1648   int i;
1649   bucket *chain;
1650
1651   /* go thru the entire  table  */
1652   for (i = 0; i < 256; i++)
1653     {
1654       for (chain = table[i]; chain; chain = chain->next)
1655         {
1656           if (chain->block >= block)
1657             {
1658               deleteSym (table, chain->sym, chain->name);
1659             }
1660         }
1661     }
1662 }
1663
1664 /*------------------------------------------------------------------*/
1665 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1666 /*                symbols in the given level                        */
1667 /*------------------------------------------------------------------*/
1668 void 
1669 cleanUpLevel (bucket ** table, int level)
1670 {
1671   int i;
1672   bucket *chain;
1673
1674   /* go thru the entire  table  */
1675   for (i = 0; i < 256; i++)
1676     {
1677       for (chain = table[i]; chain; chain = chain->next)
1678         {
1679           if (chain->level >= level)
1680             {
1681               deleteSym (table, chain->sym, chain->name);
1682             }
1683         }
1684     }
1685 }
1686
1687 /*------------------------------------------------------------------*/
1688 /* computeTypeOr - computes the resultant type from two types       */
1689 /*------------------------------------------------------------------*/
1690 static sym_link *
1691 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1692 {
1693   /* sanity check */
1694   assert (   (IS_CHAR (etype1) || IS_BIT (etype1))
1695           && (IS_CHAR (etype2) || IS_BIT (etype2)));
1696
1697   if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1698     {
1699       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1700       return reType;
1701     }
1702   
1703   if (SPEC_USIGN (etype1))
1704     {
1705       if (   IS_LITERAL (etype2)
1706           && floatFromVal (valFromType (etype2)) >= 0)
1707         SPEC_USIGN (reType) = 1;
1708       else
1709         {
1710           /* promote to int */
1711           SPEC_USIGN (reType) = 0;
1712           SPEC_NOUN (reType) = V_INT;
1713         }
1714     }
1715   else /* etype1 signed */
1716     {
1717       if (   IS_LITERAL (etype2)
1718           && floatFromVal (valFromType (etype2)) <= 127)
1719         SPEC_USIGN (reType) = 0;
1720       else
1721         {
1722           /* promote to int */
1723           SPEC_USIGN (reType) = 0;
1724           SPEC_NOUN (reType) = V_INT;
1725         }
1726     }
1727
1728   if (SPEC_USIGN (etype2))
1729     {
1730       if (   IS_LITERAL (etype1)
1731           && floatFromVal (valFromType (etype1)) >= 0)
1732         SPEC_USIGN (reType) = 1;
1733       else
1734         {
1735           /* promote to int */
1736           SPEC_USIGN (reType) = 0;
1737           SPEC_NOUN (reType) = V_INT;
1738         }
1739     }
1740   else /* etype2 signed */
1741     {
1742       if (   IS_LITERAL (etype1)
1743           && floatFromVal (valFromType (etype1)) <= 127)
1744         SPEC_USIGN (reType) = 0;
1745       else
1746         {
1747           /* promote to int */
1748           SPEC_USIGN (reType) = 0;
1749           SPEC_NOUN (reType) = V_INT;
1750         }
1751     }
1752   return reType;
1753 }
1754
1755 /*------------------------------------------------------------------*/
1756 /* computeType - computes the resultant type from two types         */
1757 /*------------------------------------------------------------------*/
1758 sym_link *
1759 computeType (sym_link * type1, sym_link * type2,
1760              RESULT_TYPE resultType, int op)
1761 {
1762   sym_link *rType;
1763   sym_link *reType;
1764   sym_link *etype1 = getSpec (type1);
1765   sym_link *etype2;
1766
1767   etype2 = type2 ? getSpec (type2) : type1;
1768
1769   /* if one of them is a float then result is a float */
1770   /* here we assume that the types passed are okay */
1771   /* and can be cast to one another                */
1772   /* which ever is greater in size */
1773   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1774     rType = newFloatLink ();
1775   else
1776     /* if both are fixed16x16 then result is float */
1777   if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
1778     rType = newFixed16x16Link();
1779   else
1780   if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
1781     rType = newFloatLink ();
1782   if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
1783     rType = newFloatLink ();
1784   else
1785     /* if both are bitvars choose the larger one */
1786   if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1787     {
1788       rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1789                 copyLinkChain (type1) : copyLinkChain (type1);
1790     }
1791     /* if only one of them is a bit variable
1792        then the other one prevails */
1793   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1794     {
1795       rType = copyLinkChain (type2);
1796       /* bitfield can have up to 16 bits */
1797       if (getSize (etype1) > 1)
1798         SPEC_NOUN (getSpec (rType)) = V_INT;
1799     }
1800   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1801     {
1802       rType = copyLinkChain (type1);
1803       /* bitfield can have up to 16 bits */
1804       if (getSize (etype2) > 1)
1805         SPEC_NOUN (getSpec (rType)) = V_INT;
1806     }
1807   else
1808     /* if one of them is a pointer or array then that
1809        prevails */
1810   if (IS_PTR (type1) || IS_ARRAY (type1))
1811     rType = copyLinkChain (type1);
1812   else if (IS_PTR (type2) || IS_ARRAY (type2))
1813     rType = copyLinkChain (type2);
1814   else if (getSize (type1) > getSize (type2))
1815     rType = copyLinkChain (type1);
1816   else
1817     rType = copyLinkChain (type2);
1818
1819   reType = getSpec (rType);
1820
1821   /* avoid conflicting types */
1822   reType->select.s.b_signed = 0;
1823
1824   /* if result is a literal then make not so */
1825   if (IS_LITERAL (reType))
1826     SPEC_SCLS (reType) = S_REGISTER;
1827
1828   switch (resultType)
1829     {
1830       case RESULT_TYPE_CHAR:
1831         if (IS_BITVAR (reType))
1832           {
1833             SPEC_NOUN (reType) = V_CHAR;
1834             SPEC_SCLS (reType) = 0;
1835             SPEC_USIGN (reType) = 0;
1836             return rType;
1837           }
1838         break;
1839       case RESULT_TYPE_INT:
1840       case RESULT_TYPE_NONE:
1841       case RESULT_TYPE_OTHER:
1842         if (IS_BIT (reType))
1843           {
1844             SPEC_NOUN (reType) = V_CHAR;
1845             SPEC_SCLS (reType) = 0;
1846             SPEC_USIGN (reType) = 0;
1847             return rType;
1848           }
1849         else if (IS_BITFIELD (reType))
1850           {
1851             /* could be smarter, but it depends on the op */
1852             /* this is for the worst case: a multiplication of 4 * 4 bit */
1853             SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1854             SPEC_SCLS (reType) = 0;
1855             SPEC_USIGN (reType) = 0;
1856             return rType;
1857           }
1858         else if (IS_CHAR (reType))
1859           {
1860             if (op == '|' || op == '^')
1861               return computeTypeOr (etype1, etype2, reType);
1862             else if (   op == '&'
1863                      && SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1864               {
1865                 SPEC_USIGN (reType) = 1;
1866                 return rType;
1867               }
1868             else if (op == '*')
1869               {
1870                 SPEC_NOUN (reType) = V_INT;
1871                 SPEC_USIGN (reType) = 0;
1872                 return rType;
1873               }
1874             /* TODO: should be in SDCCast.c */
1875             else if (   op == '/'
1876                      && (   !SPEC_USIGN (etype1)
1877                          || !SPEC_USIGN (etype2)))
1878               {
1879                 SPEC_NOUN (reType) = V_INT;
1880                 SPEC_USIGN (reType) = 0;
1881                 return rType;
1882               }
1883           }
1884         break;
1885       default:
1886         break;
1887     }
1888
1889   /* SDCC's sign promotion:
1890      - if one or both operands are unsigned, the resultant type will be unsigned
1891        (except char, see below)
1892      - if an operand is promoted to a larger type (char -> int, int -> long),
1893        the larger type will be signed
1894
1895      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1896      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1897      the standard. The standard demands, that the result has to be the same
1898      "as if" the promotion would have been performed:
1899
1900      - if the result of an operation with two char's is promoted to a
1901        larger type, the result will be signed.
1902
1903      More sophisticated are these:
1904      - if the result of an operation with two char's is a char again,
1905        the result will only then be unsigned, if both operands are
1906        unsigned. In all other cases the result will be signed.
1907
1908        This seems to be contradictionary to the first two rules, but it makes
1909        real sense (all types are char's):
1910
1911         A signed char can be negative; this must be preserved in the result
1912                 -1 * 100 = -100;
1913
1914         Only if both operands are unsigned it's safe to make the result
1915         unsigned; this helps to avoid overflow:
1916                 2 * 100 =  200;
1917
1918      - ToDo: document '|', '^' and '&'
1919      
1920      Homework: - why is (200 * 200 < 0) true?
1921                - why is { char l = 200, r = 200; (r * l > 0) } true?
1922   */
1923
1924   if (!IS_FLOAT (reType)
1925       && (   (SPEC_USIGN (etype1)
1926               /* if this operand is promoted to a larger type,
1927                  then it will be promoted to a signed type */
1928               && !(getSize (etype1) < getSize (reType))
1929               /* char require special handling */
1930               && !IS_CHAR (etype1))
1931           || /* same for 2nd operand */  
1932              (SPEC_USIGN (etype2)
1933               && !(getSize (etype2) < getSize (reType))
1934               && !IS_CHAR (etype2))
1935           || /* if both are 'unsigned char' and not promoted
1936                 let the result be unsigned too */
1937              (   SPEC_USIGN (etype1)
1938               && SPEC_USIGN (etype2)
1939               && IS_CHAR (etype1)
1940               && IS_CHAR (etype2)
1941               && IS_CHAR (reType))))
1942     SPEC_USIGN (reType) = 1;
1943   else
1944     SPEC_USIGN (reType) = 0;
1945
1946   return rType;
1947 }
1948
1949 /*--------------------------------------------------------------------*/
1950 /* compareType - will do type check return 1 if match, -1 if castable */
1951 /*--------------------------------------------------------------------*/
1952 int
1953 compareType (sym_link * dest, sym_link * src)
1954 {
1955   if (!dest && !src)
1956     return 1;
1957
1958   if (dest && !src)
1959     return 0;
1960
1961   if (src && !dest)
1962     return 0;
1963
1964   /* if dest is a declarator then */
1965   if (IS_DECL (dest))
1966     {
1967       if (IS_DECL (src))
1968         {
1969           /* banked function pointer */
1970           if (IS_GENPTR (dest) && IS_GENPTR (src))
1971             {
1972               if (IS_FUNC (src->next) && IS_VOID(dest->next))
1973                 return -1;
1974               if (IS_FUNC (dest->next) && IS_VOID(src->next))
1975                 return -1;
1976               return compareType (dest->next, src->next);
1977             }
1978
1979           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1980             if (IS_FUNC(src)) {
1981               //checkFunction(src,dest);
1982             }
1983             return compareType (dest->next, src->next);
1984           }
1985           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1986             return -1;
1987           }
1988           if (IS_PTR (src) && 
1989               (IS_GENPTR (dest) ||
1990                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
1991              ))
1992             return -1;
1993           if (IS_PTR (dest) && IS_ARRAY (src)) {
1994             value *val=aggregateToPointer (valFromType(src));
1995             int res=compareType (dest, val->type);
1996             Safe_free(val->type);
1997             Safe_free(val);
1998             return res;
1999           }
2000           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2001             return compareType (dest->next, src);
2002           return 0;
2003         }
2004       else if (IS_PTR (dest) && IS_INTEGRAL (src))
2005         return -1;
2006       else
2007         return 0;
2008     }
2009
2010   /* if one is a specifier and the other is not */
2011   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2012       (IS_SPEC (dest) && !IS_SPEC (src)))
2013     return 0;
2014
2015   /* if one of them is a void then ok */
2016   if (SPEC_NOUN (dest) == V_VOID &&
2017       SPEC_NOUN (src) != V_VOID)
2018     return -1;
2019
2020   if (SPEC_NOUN (dest) != V_VOID &&
2021       SPEC_NOUN (src) == V_VOID)
2022     return -1;
2023
2024   /* if they are both bitfields then if the lengths
2025      and starts don't match */
2026   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2027       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2028        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2029     return -1;
2030
2031   /* it is a specifier */
2032   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2033     {
2034       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
2035           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2036           /* I would prefer
2037           bitsForType (dest) == bitsForType (src))
2038              instead of the next two lines, but the regression tests fail with
2039              them; I guess it's a problem with replaceCheaperOp  */
2040           getSize (dest) == getSize (src) &&
2041           !(!IS_BIT (dest) && IS_BIT (src)))
2042         return 1;
2043       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2044         return -1;
2045       else
2046         return 0;
2047     }
2048   else if (IS_STRUCT (dest))
2049     {
2050       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2051         return 0;
2052       else
2053         return 1;
2054     }
2055   if (SPEC_LONG (dest) != SPEC_LONG (src))
2056     return -1;
2057
2058   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2059     return -1;
2060
2061   return 1;
2062 }
2063
2064 /*--------------------------------------------------------------------*/
2065 /* compareTypeExact - will do type check return 1 if match exactly    */
2066 /*--------------------------------------------------------------------*/
2067 int
2068 compareTypeExact (sym_link * dest, sym_link * src, int level)
2069 {
2070   STORAGE_CLASS srcScls, destScls;
2071   
2072   if (!dest && !src)
2073     return 1;
2074
2075   if (dest && !src)
2076     return 0;
2077
2078   if (src && !dest)
2079     return 0;
2080
2081   /* if dest is a declarator then */
2082   if (IS_DECL (dest))
2083     {
2084       if (IS_DECL (src))
2085         {
2086           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2087             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2088               return 0;
2089             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2090               return 0;
2091             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2092               return 0;
2093             if (IS_FUNC(src))
2094               {
2095                 value *exargs, *acargs, *checkValue;
2096
2097                 /* verify function return type */
2098                 if (!compareTypeExact (dest->next, src->next, -1))
2099                   return 0;
2100                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2101                   return 0;
2102                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2103                   return 0;
2104                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2105                   return 0;
2106                 #if 0
2107                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2108                   return 0;
2109                 #endif
2110
2111                 /* compare expected args with actual args */
2112                 exargs = FUNC_ARGS(dest);
2113                 acargs = FUNC_ARGS(src);
2114
2115                 /* for all the expected args do */
2116                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2117                   {
2118                     //checkTypeSanity(acargs->etype, acargs->name);
2119
2120                     if (IS_AGGREGATE (acargs->type))
2121                       {
2122                         checkValue = copyValue (acargs);
2123                         aggregateToPointer (checkValue);
2124                       }
2125                     else
2126                       checkValue = acargs;
2127
2128                     #if 0
2129                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
2130                       return 0;
2131                     #endif
2132                   }
2133
2134                   /* if one them ended we have a problem */
2135                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2136                       (!exargs && acargs && !IS_VOID (acargs->type)))
2137                     return 0;                  
2138                   return 1;
2139               }
2140             return compareTypeExact (dest->next, src->next, level);
2141           }
2142           return 0;
2143         }
2144       return 0;
2145     }
2146
2147   /* if one is a specifier and the other is not */
2148   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2149       (IS_SPEC (dest) && !IS_SPEC (src)))
2150     return 0;
2151
2152   /* if one of them is a void then ok */
2153   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2154     return 0;
2155
2156   /* if they are both bitfields then if the lengths
2157      and starts don't match */
2158   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2159       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2160        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2161     return 0;
2162
2163   if (IS_INTEGRAL (dest))
2164     {
2165       /* signedness must match */
2166       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2167         return 0;
2168       /* size must match */
2169       if (SPEC_LONG (dest) != SPEC_LONG (src))
2170         return 0;
2171       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2172         return 0;
2173     }
2174   
2175   if (IS_STRUCT (dest))
2176     {
2177       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2178         return 0;
2179     }
2180
2181   if (SPEC_CONST (dest) != SPEC_CONST (src))
2182     return 0;
2183   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2184     return 0;
2185   if (SPEC_STAT (dest) != SPEC_STAT (src))
2186     return 0;
2187   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2188     return 0;
2189   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2190     return 0;
2191       
2192   destScls = SPEC_SCLS (dest);
2193   srcScls = SPEC_SCLS (src);
2194   
2195   /* Compensate for const to const code change in checkSClass() */
2196   if (!level & port->mem.code_ro && SPEC_CONST (dest))
2197     {
2198       if (srcScls == S_CODE && destScls == S_FIXED)
2199         destScls = S_CODE;
2200       if (destScls == S_CODE && srcScls == S_FIXED)
2201         srcScls = S_CODE;
2202     }
2203
2204   /* compensate for allocGlobal() */  
2205   if ((srcScls == S_FIXED || srcScls == S_AUTO)
2206       && port->mem.default_globl_map == xdata
2207       && !level)
2208     srcScls = S_XDATA;
2209   
2210   if (level>0 && !SPEC_STAT (dest))
2211     {
2212       /* Compensate for hack-o-matic in checkSClass() */
2213       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2214         {
2215           if (destScls == S_FIXED)
2216             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2217           if (srcScls == S_FIXED)
2218             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2219         }
2220       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2221         {
2222           if (destScls == S_FIXED)
2223             destScls = S_XDATA;
2224           if (srcScls == S_FIXED)
2225             srcScls = S_XDATA;
2226         }
2227     }
2228
2229   if (srcScls != destScls)
2230     {
2231       #if 0
2232       printf ("level = %d\n", level);
2233       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2234                 SPEC_SCLS (src), SPEC_SCLS (dest));
2235       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2236       #endif
2237       return 0;
2238     }
2239   
2240   return 1;
2241 }
2242
2243 /*------------------------------------------------------------------*/
2244 /* inCalleeSaveList - return 1 if found in callee save list          */
2245 /*------------------------------------------------------------------*/
2246 static int
2247 calleeCmp(void *p1, void *p2)
2248 {
2249   return (strcmp((char *)p1, (char *)(p2)) == 0);
2250 }
2251
2252 bool
2253 inCalleeSaveList(char *s)
2254 {
2255   if (options.all_callee_saves)
2256     return 1;
2257   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2258 }
2259
2260 /*-----------------------------------------------------------------*/
2261 /* aggregateToPointer:  change an agggregate type function      */
2262 /*         argument to a pointer to that type.     */
2263 /*-----------------------------------------------------------------*/
2264 value *
2265 aggregateToPointer (value * val)
2266 {
2267   if (IS_AGGREGATE (val->type))
2268     {
2269       /* if this is a structure */
2270       /* then we need to add a new link */
2271       if (IS_STRUCT (val->type))
2272         {
2273           /* first lets add DECLARATOR type */
2274           sym_link *p = val->type;
2275
2276           werror (W_STRUCT_AS_ARG, val->name);
2277           val->type = newLink (DECLARATOR);
2278           val->type->next = p;
2279         }
2280
2281       /* change to a pointer depending on the */
2282       /* storage class specified        */
2283       switch (SPEC_SCLS (val->etype))
2284         {
2285         case S_IDATA:
2286           DCL_TYPE (val->type) = IPOINTER;
2287           break;
2288         case S_PDATA:
2289           DCL_TYPE (val->type) = PPOINTER;
2290           break;
2291         case S_FIXED:
2292           if (SPEC_OCLS(val->etype)) {
2293             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2294           } else {
2295             // this happens for (external) function parameters
2296             DCL_TYPE (val->type) = port->unqualified_pointer;
2297           }
2298           break;
2299         case S_AUTO:
2300         case S_DATA:
2301         case S_REGISTER:
2302           DCL_TYPE (val->type) = POINTER;
2303           break;
2304         case S_CODE:
2305           DCL_TYPE (val->type) = CPOINTER;
2306           break;
2307         case S_XDATA:
2308           DCL_TYPE (val->type) = FPOINTER;
2309           break;
2310         case S_EEPROM:
2311           DCL_TYPE (val->type) = EEPPOINTER;
2312           break;
2313         default:
2314           DCL_TYPE (val->type) = port->unqualified_pointer;
2315         }
2316       
2317       /* is there is a symbol associated then */
2318       /* change the type of the symbol as well */
2319       if (val->sym)
2320         {
2321           val->sym->type = copyLinkChain (val->type);
2322           val->sym->etype = getSpec (val->sym->type);
2323         }
2324     }
2325   return val;
2326 }
2327 /*------------------------------------------------------------------*/
2328 /* checkFunction - does all kinds of check on a function            */
2329 /*------------------------------------------------------------------*/
2330 int 
2331 checkFunction (symbol * sym, symbol *csym)
2332 {
2333   value *exargs, *acargs;
2334   value *checkValue;
2335   int argCnt = 0;
2336
2337   if (getenv("DEBUG_SANITY")) {
2338     fprintf (stderr, "checkFunction: %s ", sym->name);
2339   }
2340
2341   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2342     {
2343       werror(E_SYNTAX_ERROR, sym->name);
2344       return 0;
2345     }
2346     
2347   /* make sure the type is complete and sane */
2348   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2349
2350   /* if not type then some kind of error */
2351   if (!sym->type)
2352     return 0;
2353
2354   /* if the function has no type then make it return int */
2355   if (!sym->type->next)
2356     sym->type->next = sym->etype = newIntLink ();
2357
2358   /* function cannot return aggregate */
2359   if (IS_AGGREGATE (sym->type->next))
2360     {
2361       werror (E_FUNC_AGGR, sym->name);
2362       return 0;
2363     }
2364
2365   /* check if this function is defined as calleeSaves
2366      then mark it as such */
2367   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2368
2369   /* if interrupt service routine  */
2370   /* then it cannot have arguments */
2371   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2372     {
2373       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2374         werror (E_INT_ARGS, sym->name);
2375         FUNC_ARGS(sym->type)=NULL;
2376       }
2377     }
2378
2379   if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2380     {
2381       werror (E_SHADOWREGS_NO_ISR, sym->name);
2382     }
2383
2384
2385   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
2386        acargs; 
2387        acargs=acargs->next, argCnt++) {
2388     if (!acargs->sym) { 
2389       // this can happen for reentrant functions
2390       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2391       // the show must go on: synthesize a name and symbol
2392       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2393       acargs->sym = newSymbol (acargs->name, 1);
2394       SPEC_OCLS (acargs->etype) = istack;
2395       acargs->sym->type = copyLinkChain (acargs->type);
2396       acargs->sym->etype = getSpec (acargs->sym->type);
2397       acargs->sym->_isparm = 1;
2398       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2399     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2400       // synthesized name
2401       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2402     }
2403   }
2404   argCnt--;
2405
2406   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2407     return 1;                   /* not defined nothing more to check  */
2408
2409   /* check if body already present */
2410   if (csym && IFFUNC_HASBODY(csym->type))
2411     {
2412       werror (E_FUNC_BODY, sym->name);
2413       return 0;
2414     }
2415
2416   /* check the return value type   */
2417   if (compareType (csym->type, sym->type) <= 0)
2418     {
2419       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2420       printFromToType(csym->type, sym->type);
2421       return 0;
2422     }
2423
2424   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2425     {
2426       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2427     }
2428
2429   /* I don't think this is necessary for interrupts. An isr is a  */
2430   /* root in the calling tree.                                    */
2431   if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2432       (!FUNC_ISISR (sym->type)))
2433     {
2434       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2435     }
2436
2437   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2438     {
2439       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2440     }
2441
2442   /* Really, reentrant should match regardless of argCnt, but     */
2443   /* this breaks some existing code (the fp lib functions). If    */
2444   /* the first argument is always passed the same way, this       */
2445   /* lax checking is ok (but may not be true for in future ports) */
2446   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2447       && argCnt>1)
2448     {
2449       //printf("argCnt = %d\n",argCnt);
2450       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2451     }
2452
2453   if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2454     {
2455       werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2456     }
2457
2458   if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2459     {
2460       werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2461     }
2462   
2463
2464   /* compare expected args with actual args */
2465   exargs = FUNC_ARGS(csym->type);
2466   acargs = FUNC_ARGS(sym->type);
2467
2468   /* for all the expected args do */
2469   for (argCnt = 1;
2470        exargs && acargs;
2471        exargs = exargs->next, acargs = acargs->next, argCnt++)
2472     {
2473       if (getenv("DEBUG_SANITY")) {
2474         fprintf (stderr, "checkFunction: %s ", exargs->name);
2475       }
2476       /* make sure the type is complete and sane */
2477       checkTypeSanity(exargs->etype, exargs->name);
2478
2479       /* If the actual argument is an array, any prototype
2480        * will have modified it to a pointer. Duplicate that
2481        * change here.
2482        */
2483       if (IS_AGGREGATE (acargs->type))
2484         {
2485           checkValue = copyValue (acargs);
2486           aggregateToPointer (checkValue);
2487         }
2488       else
2489         {
2490           checkValue = acargs;
2491         }
2492
2493       if (compareType (exargs->type, checkValue->type) <= 0)
2494         {
2495           werror (E_ARG_TYPE, argCnt);
2496           printFromToType(exargs->type, checkValue->type);
2497           return 0;
2498         }
2499     }
2500
2501   /* if one them ended we have a problem */
2502   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2503       (!exargs && acargs && !IS_VOID (acargs->type)))
2504     werror (E_ARG_COUNT);
2505
2506   /* replace with this defition */
2507   sym->cdef = csym->cdef;
2508   deleteSym (SymbolTab, csym, csym->name);
2509   deleteFromSeg(csym);
2510   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2511   if (IS_EXTERN (csym->etype) && !
2512       IS_EXTERN (sym->etype))
2513     {
2514       addSet (&publics, sym);
2515     }
2516   return 1;
2517 }
2518
2519 /*------------------------------------------------------------------*/
2520 /* cdbStructBlock - calls struct printing for a blcks               */
2521 /*------------------------------------------------------------------*/
2522 void cdbStructBlock (int block)
2523 {
2524   int i;
2525   bucket **table = StructTab;
2526   bucket *chain;
2527
2528   /* go thru the entire  table  */
2529   for (i = 0; i < 256; i++)
2530     {
2531       for (chain = table[i]; chain; chain = chain->next)
2532         {
2533           if (chain->block >= block)
2534             {
2535               if(debugFile)
2536                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2537             }
2538         }
2539     }
2540 }
2541
2542 /*-----------------------------------------------------------------*/
2543 /* processFuncArgs - does some processing with function args       */
2544 /*-----------------------------------------------------------------*/
2545 void 
2546 processFuncArgs (symbol * func)
2547 {
2548   value *val;
2549   int pNum = 1;
2550   sym_link *funcType=func->type;
2551
2552   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2553     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2554
2555   /* find the function declaration within the type */
2556   while (funcType && !IS_FUNC(funcType))
2557     funcType=funcType->next;
2558
2559   /* if this function has variable argument list */
2560   /* then make the function a reentrant one    */
2561   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2562     FUNC_ISREENT(funcType)=1;
2563
2564   /* check if this function is defined as calleeSaves
2565      then mark it as such */
2566   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2567
2568   /* loop thru all the arguments   */
2569   val = FUNC_ARGS(funcType);
2570
2571   /* if it is void then remove parameters */
2572   if (val && IS_VOID (val->type))
2573     {
2574       FUNC_ARGS(funcType) = NULL;
2575       return;
2576     }
2577
2578   /* reset regparm for the port */
2579   (*port->reset_regparms) ();
2580
2581   /* if any of the arguments is an aggregate */
2582   /* change it to pointer to the same type */
2583   while (val)
2584     {
2585       int argreg = 0;
2586       char buffer[SDCC_NAME_MAX+1];
2587       
2588       SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2589       checkTypeSanity (val->etype, buffer);
2590       
2591       /* mark it as a register parameter if
2592          the function does not have VA_ARG
2593          and as port dictates */
2594       if (!IFFUNC_HASVARARGS(funcType) &&
2595           (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
2596         {
2597           SPEC_REGPARM (val->etype) = 1;
2598           SPEC_ARGREG(val->etype) = argreg;
2599         } else if (IFFUNC_ISREENT(funcType)) {
2600             FUNC_HASSTACKPARM(funcType) = 1;
2601         }
2602
2603       if (IS_AGGREGATE (val->type))
2604         {
2605           aggregateToPointer (val);
2606         }
2607
2608       val = val->next;
2609       pNum++;
2610     }
2611
2612   /* if this is an internal generated function call */
2613   if (func->cdef) {
2614     /* ignore --stack-auto for this one, we don't know how it is compiled */
2615     /* simply trust on --int-long-reent or --float-reent */
2616     if (IFFUNC_ISREENT(funcType)) {
2617       return;
2618     }
2619   } else {
2620     /* if this function is reentrant or */
2621     /* automatics r 2b stacked then nothing */
2622     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2623       return;
2624   }
2625
2626   val = FUNC_ARGS(funcType);
2627   pNum = 1;
2628   while (val)
2629     {
2630
2631       /* if a symbolname is not given  */
2632       /* synthesize a variable name */
2633       if (!val->sym)
2634         {
2635           SNPRINTF (val->name, sizeof(val->name), 
2636                     "_%s_PARM_%d", func->name, pNum++);
2637           val->sym = newSymbol (val->name, 1);
2638           if (SPEC_SCLS(val->etype) == S_BIT)
2639             SPEC_OCLS (val->etype) = bit;
2640           else
2641             SPEC_OCLS (val->etype) = port->mem.default_local_map;
2642           val->sym->type = copyLinkChain (val->type);
2643           val->sym->etype = getSpec (val->sym->type);
2644           val->sym->_isparm = 1;
2645           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2646           #if 0
2647           /* ?? static functions shouldn't imply static parameters - EEP */
2648           if (IS_SPEC(func->etype)) {
2649             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2650               SPEC_STAT (func->etype);
2651           }
2652           #endif
2653           addSymChain (&val->sym);
2654
2655         }
2656       else                      /* symbol name given create synth name */
2657         {
2658
2659           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2660           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2661           val->sym->_isparm = 1;
2662           if (SPEC_SCLS(val->etype) == S_BIT)
2663             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2664           else
2665             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2666               port->mem.default_local_map;
2667           
2668           #if 0
2669           /* ?? static functions shouldn't imply static parameters - EEP */
2670           if (IS_SPEC(func->etype)) {
2671             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2672               SPEC_STAT (func->etype);
2673           }
2674           #endif
2675         }
2676       if (SPEC_OCLS (val->sym->etype) == pdata)
2677         val->sym->iaccess = 1;
2678       if (!isinSet(operKeyReset, val->sym)) {
2679         addSet (&operKeyReset, val->sym);
2680         applyToSet (operKeyReset, resetParmKey);
2681       }
2682       val = val->next;
2683     }
2684 }
2685
2686 /*-----------------------------------------------------------------*/
2687 /* isSymbolEqual - compares two symbols return 1 if they match     */
2688 /*-----------------------------------------------------------------*/
2689 int 
2690 isSymbolEqual (symbol * dest, symbol * src)
2691 {
2692   /* if pointers match then equal */
2693   if (dest == src)
2694     return 1;
2695
2696   /* if one of them is null then don't match */
2697   if (!dest || !src)
2698     return 0;
2699
2700   /* if both of them have rname match on rname */
2701   if (dest->rname[0] && src->rname[0])
2702     return (!strcmp (dest->rname, src->rname));
2703
2704   /* otherwise match on name */
2705   return (!strcmp (dest->name, src->name));
2706 }
2707
2708 void PT(sym_link *type)
2709 {
2710         printTypeChain(type,0);
2711 }
2712 /*-----------------------------------------------------------------*/
2713 /* printTypeChain - prints the type chain in human readable form   */
2714 /*-----------------------------------------------------------------*/
2715 void
2716 printTypeChain (sym_link * start, FILE * of)
2717 {
2718   int nlr = 0;
2719   value *args;
2720   sym_link * type, * search;
2721   STORAGE_CLASS scls;
2722
2723   if (!of)
2724     {
2725       of = stdout;
2726       nlr = 1;
2727     }
2728
2729   if (start==NULL) {
2730     fprintf (of, "void");
2731     return;
2732   }
2733
2734   /* Print the chain as it is written in the source: */
2735   /* start with the last entry.                      */
2736   /* However, the storage class at the end of the    */
2737   /* chain reall applies to the first in the chain!  */
2738
2739   for (type = start; type && type->next; type = type->next)
2740     ;
2741   if (IS_SPEC (type))
2742     scls=SPEC_SCLS(type);
2743   else
2744     scls=0;
2745   while (type)
2746     {
2747       if (type==start) {
2748         switch (scls) 
2749           {
2750           case S_DATA: fprintf (of, "data-"); break;
2751           case S_XDATA: fprintf (of, "xdata-"); break;
2752           case S_SFR: fprintf (of, "sfr-"); break;
2753           case S_SBIT: fprintf (of, "sbit-"); break;
2754           case S_CODE: fprintf (of, "code-"); break;
2755           case S_IDATA: fprintf (of, "idata-"); break;
2756           case S_PDATA: fprintf (of, "pdata-"); break;
2757           case S_LITERAL: fprintf (of, "literal-"); break;
2758           case S_STACK: fprintf (of, "stack-"); break;
2759           case S_XSTACK: fprintf (of, "xstack-"); break;
2760           case S_BIT: fprintf (of, "bit-"); break;
2761           case S_EEPROM: fprintf (of, "eeprom-"); break;
2762           default: break;
2763           }
2764       }
2765
2766       if (IS_DECL (type))
2767         {
2768           if (!IS_FUNC(type)) {
2769             if (DCL_PTR_VOLATILE (type)) {
2770               fprintf (of, "volatile-");
2771             }
2772             if (DCL_PTR_CONST (type)) {
2773               fprintf (of, "const-");
2774             }
2775           }
2776           switch (DCL_TYPE (type))
2777             {
2778             case FUNCTION:
2779               fprintf (of, "function %s %s", 
2780                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2781                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2782               fprintf (of, "( ");
2783               for (args = FUNC_ARGS(type); 
2784                    args; 
2785                    args=args->next) {
2786                 printTypeChain(args->type, of);
2787                 if (args->next)
2788                   fprintf(of, ", ");
2789               }
2790               fprintf (of, ") ");
2791               break;
2792             case GPOINTER:
2793               fprintf (of, "generic* ");
2794               break;
2795             case CPOINTER:
2796               fprintf (of, "code* ");
2797               break;
2798             case FPOINTER:
2799               fprintf (of, "xdata* ");
2800               break;
2801             case EEPPOINTER:
2802               fprintf (of, "eeprom* ");
2803               break;
2804             case POINTER:
2805               fprintf (of, "near* ");
2806               break;
2807             case IPOINTER:
2808               fprintf (of, "idata* ");
2809               break;
2810             case PPOINTER:
2811               fprintf (of, "pdata* ");
2812               break;
2813             case UPOINTER:
2814               fprintf (of, "unknown* ");
2815               break;
2816             case ARRAY:
2817               if (DCL_ELEM(type)) {
2818                 fprintf (of, "[%d] ", DCL_ELEM(type));
2819               } else {
2820                 fprintf (of, "[] ");
2821               }
2822               break;
2823             }
2824         }
2825       else
2826         {
2827           if (SPEC_VOLATILE (type))
2828             fprintf (of, "volatile-");
2829           if (SPEC_CONST (type))
2830             fprintf (of, "const-");
2831           if (SPEC_USIGN (type))
2832             fprintf (of, "unsigned-");
2833           switch (SPEC_NOUN (type))
2834             {
2835             case V_INT:
2836               if (IS_LONG (type))
2837                 fprintf (of, "long-");
2838               fprintf (of, "int");
2839               break;
2840
2841             case V_CHAR:
2842               fprintf (of, "char");
2843               break;
2844
2845             case V_VOID:
2846               fprintf (of, "void");
2847               break;
2848
2849             case V_FLOAT:
2850               fprintf (of, "float");
2851               break;
2852
2853             case V_FIXED16X16:
2854               fprintf (of, "fixed16x16");
2855               break;
2856
2857             case V_STRUCT:
2858               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2859               break;
2860
2861             case V_SBIT:
2862               fprintf (of, "sbit");
2863               break;
2864
2865             case V_BIT:
2866               fprintf (of, "bit");
2867               break;
2868
2869             case V_BITFIELD:
2870               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2871               break;
2872
2873             case V_DOUBLE:
2874               fprintf (of, "double");
2875               break;
2876
2877             default:
2878               fprintf (of, "unknown type");
2879               break;
2880             }
2881         }
2882       /* search entry in list before "type" */
2883       for (search = start; search && search->next != type;)
2884         search = search->next;
2885       type = search;
2886       if (type)
2887         fputc (' ', of);
2888     }
2889   if (nlr)
2890     fprintf (of, "\n");
2891 }
2892
2893 /*--------------------------------------------------------------------*/
2894 /* printTypeChainRaw - prints the type chain in human readable form   */
2895 /*                     in the raw data structure ordering             */
2896 /*--------------------------------------------------------------------*/
2897 void
2898 printTypeChainRaw (sym_link * start, FILE * of)
2899 {
2900   int nlr = 0;
2901   value *args;
2902   sym_link * type;
2903
2904   if (!of)
2905     {
2906       of = stdout;
2907       nlr = 1;
2908     }
2909
2910   if (start==NULL) {
2911     fprintf (of, "void");
2912     return;
2913   }
2914
2915   type = start;
2916   
2917   while (type)
2918     {
2919       if (IS_DECL (type))
2920         {
2921           if (!IS_FUNC(type)) {
2922             if (DCL_PTR_VOLATILE (type)) {
2923               fprintf (of, "volatile-");
2924             }
2925             if (DCL_PTR_CONST (type)) {
2926               fprintf (of, "const-");
2927             }
2928           }
2929           switch (DCL_TYPE (type))
2930             {
2931             case FUNCTION:
2932               fprintf (of, "function %s %s", 
2933                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2934                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2935               fprintf (of, "( ");
2936               for (args = FUNC_ARGS(type); 
2937                    args; 
2938                    args=args->next) {
2939                 printTypeChain(args->type, of);
2940                 if (args->next)
2941                   fprintf(of, ", ");
2942               }
2943               fprintf (of, ") ");
2944               break;
2945             case GPOINTER:
2946               fprintf (of, "generic* ");
2947               break;
2948             case CPOINTER:
2949               fprintf (of, "code* ");
2950               break;
2951             case FPOINTER:
2952               fprintf (of, "xdata* ");
2953               break;
2954             case EEPPOINTER:
2955               fprintf (of, "eeprom* ");
2956               break;
2957             case POINTER:
2958               fprintf (of, "near* ");
2959               break;
2960             case IPOINTER:
2961               fprintf (of, "idata* ");
2962               break;
2963             case PPOINTER:
2964               fprintf (of, "pdata* ");
2965               break;
2966             case UPOINTER:
2967               fprintf (of, "unknown* ");
2968               break;
2969             case ARRAY:
2970               if (DCL_ELEM(type)) {
2971                 fprintf (of, "[%d] ", DCL_ELEM(type));
2972               } else {
2973                 fprintf (of, "[] ");
2974               }
2975               break;
2976             }
2977           if (DCL_TSPEC(type))
2978             {
2979               fprintf (of, "{");
2980               printTypeChainRaw(DCL_TSPEC(type), of);
2981               fprintf (of, "}");
2982             }
2983         }
2984       else if (IS_SPEC (type))
2985         {
2986         switch (SPEC_SCLS (type)) 
2987           {
2988           case S_DATA: fprintf (of, "data-"); break;
2989           case S_XDATA: fprintf (of, "xdata-"); break;
2990           case S_SFR: fprintf (of, "sfr-"); break;
2991           case S_SBIT: fprintf (of, "sbit-"); break;
2992           case S_CODE: fprintf (of, "code-"); break;
2993           case S_IDATA: fprintf (of, "idata-"); break;
2994           case S_PDATA: fprintf (of, "pdata-"); break;
2995           case S_LITERAL: fprintf (of, "literal-"); break;
2996           case S_STACK: fprintf (of, "stack-"); break;
2997           case S_XSTACK: fprintf (of, "xstack-"); break;
2998           case S_BIT: fprintf (of, "bit-"); break;
2999           case S_EEPROM: fprintf (of, "eeprom-"); break;
3000           default: break;
3001           }
3002           if (SPEC_VOLATILE (type))
3003             fprintf (of, "volatile-");
3004           if (SPEC_CONST (type))
3005             fprintf (of, "const-");
3006           if (SPEC_USIGN (type))
3007             fprintf (of, "unsigned-");
3008           switch (SPEC_NOUN (type))
3009             {
3010             case V_INT:
3011               if (IS_LONG (type))
3012                 fprintf (of, "long-");
3013               fprintf (of, "int");
3014               break;
3015
3016             case V_CHAR:
3017               fprintf (of, "char");
3018               break;
3019
3020             case V_VOID:
3021               fprintf (of, "void");
3022               break;
3023
3024             case V_FLOAT:
3025               fprintf (of, "float");
3026               break;
3027
3028             case V_FIXED16X16:
3029               fprintf (of, "fixed16x16");
3030               break;
3031
3032             case V_STRUCT:
3033               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3034               break;
3035
3036             case V_SBIT:
3037               fprintf (of, "sbit");
3038               break;
3039
3040             case V_BIT:
3041               fprintf (of, "bit");
3042               break;
3043
3044             case V_BITFIELD:
3045               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3046               break;
3047
3048             case V_DOUBLE:
3049               fprintf (of, "double");
3050               break;
3051
3052             default:
3053               fprintf (of, "unknown type");
3054               break;
3055             }
3056         }
3057       else
3058         fprintf (of, "NOT_SPEC_OR_DECL");
3059       type = type->next;
3060       if (type)
3061         fputc (' ', of);
3062     }
3063   if (nlr)
3064     fprintf (of, "\n");
3065 }
3066
3067
3068 /*-----------------------------------------------------------------*/
3069 /* powof2 - returns power of two for the number if number is pow 2 */
3070 /*-----------------------------------------------------------------*/
3071 int
3072 powof2 (TYPE_UDWORD num)
3073 {
3074   int nshifts = 0;
3075   int n1s = 0;
3076
3077   while (num)
3078     {
3079       if (num & 1)
3080         n1s++;
3081       num >>= 1;
3082       nshifts++;
3083     }
3084
3085   if (n1s > 1 || nshifts == 0)
3086     return -1;
3087   return nshifts - 1;
3088 }
3089
3090 symbol *__fsadd;
3091 symbol *__fssub;
3092 symbol *__fsmul;
3093 symbol *__fsdiv;
3094 symbol *__fseq;
3095 symbol *__fsneq;
3096 symbol *__fslt;
3097 symbol *__fslteq;
3098 symbol *__fsgt;
3099 symbol *__fsgteq;
3100
3101 symbol *__fps16x16_add;
3102 symbol *__fps16x16_sub;
3103 symbol *__fps16x16_mul;
3104 symbol *__fps16x16_div;
3105 symbol *__fps16x16_eq;
3106 symbol *__fps16x16_neq;
3107 symbol *__fps16x16_lt;
3108 symbol *__fps16x16_lteq;
3109 symbol *__fps16x16_gt;
3110 symbol *__fps16x16_gteq;
3111
3112 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3113 symbol *__muldiv[3][3][2];
3114 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3115 sym_link *__multypes[3][2];
3116 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3117 symbol *__conv[2][3][2];
3118 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
3119 symbol *__fp16x16conv[2][4][2];
3120 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3121 symbol *__rlrr[2][3][2];
3122
3123 sym_link *floatType;
3124 sym_link *fixed16x16Type;
3125
3126 static char *
3127 _mangleFunctionName(char *in)
3128 {
3129   if (port->getMangledFunctionName)
3130     {
3131       return port->getMangledFunctionName(in);
3132     }
3133   else
3134     {
3135       return in;
3136     }
3137 }
3138
3139 /*-----------------------------------------------------------------*/
3140 /* typeFromStr - create a typechain from an encoded string         */
3141 /* basic types -        'c' - char                                 */
3142 /*                      's' - short                                */
3143 /*                      'i' - int                                  */
3144 /*                      'l' - long                                 */
3145 /*                      'f' - float                                */
3146 /*                      'q' - fixed16x16                           */
3147 /*                      'v' - void                                 */
3148 /*                      '*' - pointer - default (GPOINTER)         */
3149 /* modifiers -          'u' - unsigned                             */
3150 /* pointer modifiers -  'g' - generic                              */
3151 /*                      'x' - xdata                                */
3152 /*                      'p' - code                                 */
3153 /*                      'd' - data                                 */                     
3154 /*                      'F' - function                             */                     
3155 /* examples : "ig*" - generic int *                                */
3156 /*            "cx*" - char xdata *                                 */
3157 /*            "ui" -  unsigned int                                 */
3158 /*-----------------------------------------------------------------*/
3159 sym_link *typeFromStr (char *s)
3160 {
3161     sym_link *r = newLink(DECLARATOR);
3162     int usign = 0;
3163
3164     do {
3165         sym_link *nr;
3166         switch (*s) {
3167         case 'u' : 
3168             usign = 1;
3169             s++;
3170             continue ;
3171             break ;
3172         case 'c':
3173             r->class = SPECIFIER;
3174             SPEC_NOUN(r) = V_CHAR;
3175             break;
3176         case 's':
3177         case 'i':
3178             r->class = SPECIFIER;
3179             SPEC_NOUN(r) = V_INT;
3180             break;
3181         case 'l':
3182             r->class = SPECIFIER;
3183             SPEC_NOUN(r) = V_INT;
3184             SPEC_LONG(r) = 1;
3185             break;
3186         case 'f':
3187             r->class = SPECIFIER;
3188             SPEC_NOUN(r) = V_FLOAT;
3189             break;
3190         case 'q':
3191             r->class = SPECIFIER;
3192             SPEC_NOUN(r) = V_FIXED16X16;
3193             break;
3194         case 'v':
3195             r->class = SPECIFIER;
3196             SPEC_NOUN(r) = V_VOID;
3197             break;
3198         case '*':
3199             DCL_TYPE(r) = port->unqualified_pointer;
3200             break;
3201         case 'g':
3202         case 'x':
3203         case 'p':
3204         case 'd':
3205         case 'F':
3206             assert(*(s+1)=='*');
3207             nr = newLink(DECLARATOR);
3208             nr->next = r;
3209             r = nr;
3210             switch (*s) {
3211             case 'g':
3212                 DCL_TYPE(r) = GPOINTER;
3213                 break;
3214             case 'x':
3215                 DCL_TYPE(r) = FPOINTER;
3216                 break;
3217             case 'p':
3218                 DCL_TYPE(r) = CPOINTER;
3219                 break;
3220             case 'd':
3221                 DCL_TYPE(r) = POINTER;
3222                 break;
3223             case 'F':
3224                 DCL_TYPE(r) = FUNCTION;
3225                 nr = newLink(DECLARATOR);
3226                 nr->next = r;
3227                 r = nr;
3228                 DCL_TYPE(r) = CPOINTER;
3229                 break;
3230             }
3231             s++;
3232             break;
3233         default:
3234             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
3235                    "typeFromStr: unknown type");
3236             break;
3237         }
3238         if (IS_SPEC(r) && usign) {
3239             SPEC_USIGN(r) = 1;
3240             usign = 0;
3241         }
3242         s++;
3243     } while (*s);
3244     return r;
3245 }
3246
3247 /*-----------------------------------------------------------------*/
3248 /* initCSupport - create functions for C support routines          */
3249 /*-----------------------------------------------------------------*/
3250 void 
3251 initCSupport ()
3252 {
3253   const char *smuldivmod[] =
3254   {
3255     "mul", "div", "mod"
3256   };
3257   const char *sbwd[] =
3258   {
3259     "char", "int", "long", "fixed16x16",
3260   };
3261   const char *fp16x16sbwd[] =
3262   {
3263     "char", "int", "long", "float",
3264   };
3265   const char *ssu[] =
3266   {
3267     "s", "u"
3268   };
3269   const char *srlrr[] =
3270   {
3271     "rl", "rr"
3272   };
3273
3274   int bwd, su, muldivmod, tofrom, rlrr;
3275
3276   if (getenv("SDCC_NO_C_SUPPORT")) {
3277     /* for debugging only */
3278     return;
3279   }
3280
3281   floatType = newFloatLink ();
3282   fixed16x16Type = newFixed16x16Link ();
3283
3284   for (bwd = 0; bwd < 3; bwd++)
3285     {
3286       sym_link *l = NULL;
3287       switch (bwd)
3288         {
3289         case 0:
3290           l = newCharLink ();
3291           break;
3292         case 1:
3293           l = newIntLink ();
3294           break;
3295         case 2:
3296           l = newLongLink ();
3297           break;
3298         default:
3299           assert (0);
3300         }
3301       __multypes[bwd][0] = l;
3302       __multypes[bwd][1] = copyLinkChain (l);
3303       SPEC_USIGN (__multypes[bwd][1]) = 1;
3304     }
3305
3306   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3307   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3308   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3309   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3310   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3311   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3312   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3313   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3314   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3315   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3316
3317   __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3318   __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3319   __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3320   __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3321   __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3322   __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3323   __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3324   __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3325   __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3326   __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3327
3328
3329   for (tofrom = 0; tofrom < 2; tofrom++)
3330     {
3331       for (bwd = 0; bwd < 3; bwd++)
3332         {
3333           for (su = 0; su < 2; su++)
3334             {
3335               if (tofrom)
3336                 {
3337                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3338                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3339                 }
3340               else
3341                 {
3342                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3343                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3344                 }
3345             }
3346         }
3347     }
3348
3349   for (tofrom = 0; tofrom < 2; tofrom++)
3350     {
3351       for (bwd = 0; bwd < 4; bwd++)
3352         {
3353           for (su = 0; su < 2; su++)
3354             {
3355               if (tofrom)
3356                 {
3357                   SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
3358                   if(bwd == 3) {
3359                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
3360                   } else
3361                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
3362                 }
3363               else
3364                 {
3365                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
3366                   if(bwd == 3) {
3367                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
3368                   } else
3369                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
3370                 }
3371             }
3372         }
3373     }
3374
3375 /*
3376   for (muldivmod = 0; muldivmod < 3; muldivmod++)
3377     {
3378       for (bwd = 0; bwd < 3; bwd++)
3379         {
3380           for (su = 0; su < 2; su++)
3381             {
3382               SNPRINTF (buffer, sizeof(buffer),
3383                         "_%s%s%s",
3384                        smuldivmod[muldivmod],
3385                        ssu[su],
3386                        sbwd[bwd]);
3387               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3388               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3389             }
3390         }
3391     }
3392
3393   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3394   Therefore they've been merged into mulint() and mullong().
3395 */
3396
3397   for (bwd = 0; bwd < 3; bwd++)
3398     {
3399       for (su = 0; su < 2; su++)
3400         {
3401           for (muldivmod = 1; muldivmod < 3; muldivmod++)
3402             {
3403               /* div and mod */
3404               SNPRINTF (buffer, sizeof(buffer),
3405                         "_%s%s%s",
3406                        smuldivmod[muldivmod],
3407                        ssu[su],
3408                        sbwd[bwd]);
3409               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3410               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3411             }
3412         }
3413     }
3414   /* mul only */
3415   muldivmod = 0;
3416   /* byte */
3417   bwd = 0;
3418   for (su = 0; su < 2; su++)
3419     {
3420       /* muluchar and mulschar are still separate functions, because e.g. the z80
3421          port is sign/zero-extending to int before calling mulint() */
3422       SNPRINTF (buffer, sizeof(buffer),
3423                 "_%s%s%s",
3424                 smuldivmod[muldivmod],
3425                 ssu[su],
3426                 sbwd[bwd]);
3427       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3428       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3429     }
3430   /* signed only */
3431   su = 0;
3432   /* word and doubleword */
3433   for (bwd = 1; bwd < 3; bwd++)
3434     {
3435       /* mul, int/long */
3436       SNPRINTF (buffer, sizeof(buffer),
3437                 "_%s%s",
3438                 smuldivmod[muldivmod],
3439                 sbwd[bwd]);
3440       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3441       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3442       /* signed = unsigned */
3443       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3444     }
3445
3446   for (rlrr = 0; rlrr < 2; rlrr++)
3447     {
3448       for (bwd = 0; bwd < 3; bwd++)
3449         {
3450           for (su = 0; su < 2; su++)
3451             {
3452               SNPRINTF (buffer, sizeof(buffer),
3453                         "_%s%s%s",
3454                        srlrr[rlrr],
3455                        ssu[su],
3456                        sbwd[bwd]);
3457               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3458               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3459             }
3460         }
3461     }
3462 }
3463
3464 /*-----------------------------------------------------------------*/
3465 /* initBuiltIns - create prototypes for builtin functions          */
3466 /*-----------------------------------------------------------------*/
3467 void initBuiltIns()
3468 {
3469     int i;
3470     symbol *sym;
3471
3472     if (!port->builtintable) return ;
3473
3474     for (i = 0 ; port->builtintable[i].name ; i++) {
3475         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3476                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3477         FUNC_ISBUILTIN(sym->type) = 1;
3478         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3479     }
3480 }
3481
3482 sym_link *validateLink(sym_link         *l, 
3483                         const char      *macro,
3484                         const char      *args,
3485                         const char      select,
3486                         const char      *file, 
3487                         unsigned        line)
3488 {    
3489   if (l && l->class==select)
3490     {
3491         return l;
3492     }
3493     fprintf(stderr, 
3494             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3495             " expected %s, got %s\n",
3496             macro, args, file, line, 
3497             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3498     exit(-1);
3499     return l; // never reached, makes compiler happy.
3500 }
3501
3502 /*--------------------------------------------------------------------*/
3503 /* newEnumType - create an integer type compatible with enumerations  */
3504 /*--------------------------------------------------------------------*/
3505 sym_link *
3506 newEnumType (symbol *enumlist)
3507 {
3508   int min, max, v;
3509   symbol *sym;
3510   sym_link *type;
3511
3512   if (!enumlist)
3513     {
3514       type = newLink (SPECIFIER);
3515       SPEC_NOUN (type) = V_INT;
3516       return type;
3517     }
3518       
3519   /* Determine the range of the enumerated values */
3520   sym = enumlist;
3521   min = max = (int) floatFromVal (valFromType (sym->type));
3522   for (sym = sym->next; sym; sym = sym->next)
3523     {
3524       v = (int) floatFromVal (valFromType (sym->type));
3525       if (v<min)
3526         min = v;
3527       if (v>max)
3528         max = v;
3529     }
3530
3531   /* Determine the smallest integer type that is compatible with this range */
3532   type = newLink (SPECIFIER);
3533   if (min>=0 && max<=255)
3534     {
3535       SPEC_NOUN (type) = V_CHAR;
3536       SPEC_USIGN (type) = 1;
3537     }
3538   else if (min>=-128 && max<=127)
3539     {
3540       SPEC_NOUN (type) = V_CHAR;
3541     }
3542   else if (min>=0 && max<=65535)
3543     {
3544       SPEC_NOUN (type) = V_INT;
3545       SPEC_USIGN (type) = 1;
3546     }
3547   else if (min>=-32768 && max<=32767)
3548     {
3549       SPEC_NOUN (type) = V_INT;
3550     }
3551   else
3552     {
3553       SPEC_NOUN (type) = V_INT;
3554       SPEC_LONG (type) = 1;
3555       if (min>=0)
3556         SPEC_USIGN (type) = 1;
3557     }
3558   
3559   return type;    
3560 }