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