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