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