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