reimplemented function inCalleeSaveList() by using sets instead fixed width array...
[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
29 void printFromToType(sym_link *from, sym_link *to) {
30   fprintf (stderr, "from type '");
31   printTypeChain (from, stderr);
32   fprintf (stderr, "'\nto type '");
33   printTypeChain (to, stderr);
34   fprintf (stderr, "'\n");
35 }
36
37 /* noun strings */
38 char *nounName(sym_link *sl) {
39   switch (SPEC_NOUN(sl)) 
40     {
41     case V_INT: {
42       if (SPEC_LONG(sl)) return "long";
43       if (sl->select.s._short) return "short";
44       return "int";
45     }
46     case V_FLOAT: return "float";
47     case V_CHAR: return "char";
48     case V_VOID: return "void";
49     case V_STRUCT: return "struct";
50     case V_LABEL: return "label";
51     case V_BIT: return "bit";
52     case V_SBIT: return "sbit";
53     case V_DOUBLE: return "double";
54     }
55   return "unknown";
56 };
57
58 bucket *SymbolTab[256];         /* the symbol    table  */
59 bucket *StructTab[256];         /* the structure table  */
60 bucket *TypedefTab[256];        /* the typedef   table  */
61 bucket *LabelTab[256];          /* the Label     table  */
62 bucket *enumTab[256];           /* enumerated    table  */
63
64 /*------------------------------------------------------------------*/
65 /* initSymt () - initialises symbol table related stuff             */
66 /*------------------------------------------------------------------*/
67 void 
68 initSymt ()
69 {
70   int i = 0;
71
72   for (i = 0; i < 256; i++)
73     SymbolTab[i] = StructTab[i] = (void *) NULL;
74
75
76 }
77 /*-----------------------------------------------------------------*/
78 /* newBucket - allocates & returns a new bucket        */
79 /*-----------------------------------------------------------------*/
80 bucket *
81 newBucket ()
82 {
83   bucket *bp;
84
85   bp = Safe_alloc ( sizeof (bucket));
86
87   return bp;
88 }
89
90 /*-----------------------------------------------------------------*/
91 /* hashKey - computes the hashkey given a symbol name              */
92 /*-----------------------------------------------------------------*/
93 int 
94 hashKey (const char *s)
95 {
96   unsigned long key = 0;
97
98   while (*s)
99     key += *s++;
100   return key % 256;
101 }
102
103 /*-----------------------------------------------------------------*/
104 /* addSym - adds a symbol to the hash Table                        */
105 /*-----------------------------------------------------------------*/
106 void 
107 addSym (bucket ** stab,
108         void *sym,
109         char *sname,
110         int level,
111         int block,
112         int checkType)
113 {
114   int i;                        /* index into the hash Table */
115   bucket *bp;                   /* temp bucket    *         */
116
117   if (checkType) {
118     symbol *csym = (symbol *)sym;
119
120     if (getenv("DEBUG_SANITY")) {
121       fprintf (stderr, "addSym: %s ", sname);
122     }
123     /* make sure the type is complete and sane */
124     checkTypeSanity(csym->etype, csym->name);
125   }
126
127   /* prevent overflow of the (r)name buffers */
128   if (strlen(sname)>SDCC_SYMNAME_MAX) {
129     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
130     sname[SDCC_SYMNAME_MAX]='\0';
131   }
132
133   /* the symbols are always added at the head of the list  */
134   i = hashKey (sname);
135   /* get a free entry */
136   bp = Safe_alloc ( sizeof (bucket));
137
138   bp->sym = sym;                /* update the symbol pointer  */
139   bp->level = level;            /* update the nest level      */
140   bp->block = block;
141   strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
142
143   /* if this is the first entry */
144   if (stab[i] == NULL)
145     {
146       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
147       stab[i] = bp;
148     }
149   /* not first entry then add @ head of list */
150   else
151     {
152       bp->prev = NULL;
153       stab[i]->prev = bp;
154       bp->next = stab[i];
155       stab[i] = bp;
156     }
157 }
158
159 /*-----------------------------------------------------------------*/
160 /* deleteSym - deletes a symbol from the hash Table  entry     */
161 /*-----------------------------------------------------------------*/
162 void 
163 deleteSym (bucket ** stab, void *sym, char *sname)
164 {
165   int i = 0;
166   bucket *bp;
167
168   i = hashKey (sname);
169
170   bp = stab[i];
171   /* find the symbol */
172   while (bp)
173     {
174       if (bp->sym == sym)       /* found it then break out */
175         break;                  /* of the loop       */
176       bp = bp->next;
177     }
178
179   if (!bp)                      /* did not find it */
180     return;
181   /* if this is the first one in the chain */
182   if (!bp->prev)
183     {
184       stab[i] = bp->next;
185       if (stab[i])              /* if chain ! empty */
186         stab[i]->prev = (void *) NULL;
187     }
188   /* middle || end of chain */
189   else
190     {
191       if (bp->next)             /* if not end of chain */
192         bp->next->prev = bp->prev;
193
194       bp->prev->next = bp->next;
195     }
196
197 }
198
199 /*-----------------------------------------------------------------*/
200 /* findSym - finds a symbol in a table           */
201 /*-----------------------------------------------------------------*/
202 void *
203 findSym (bucket ** stab, void *sym, const char *sname)
204 {
205   bucket *bp;
206
207   bp = stab[hashKey (sname)];
208   while (bp)
209     {
210       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
211         break;
212       bp = bp->next;
213     }
214
215   return (bp ? bp->sym : (void *) NULL);
216 }
217
218 /*-----------------------------------------------------------------*/
219 /* findSymWithLevel - finds a symbol with a name & level           */
220 /*-----------------------------------------------------------------*/
221 void *
222 findSymWithLevel (bucket ** stab, symbol * sym)
223 {
224   bucket *bp;
225
226   bp = stab[hashKey (sym->name)];
227
228   /**
229    **  do the search from the head of the list since the
230    **  elements are added at the head it is ensured that
231    ** we will find the deeper definitions before we find
232    ** the global ones. we need to check for symbols with
233    ** level <= to the level given, if levels match then block
234    ** numbers need to match as well
235    **/
236   while (bp)
237     {
238       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
239         {
240           /* if this is parameter then nothing else need to be checked */
241           if (((symbol *) (bp->sym))->_isparm)
242             return (bp->sym);
243           /* if levels match then block numbers should also match */
244           if (bp->level && bp->level == sym->level && bp->block == sym->block)
245             return (bp->sym);
246           /* if levels don't match then we are okay */
247           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
248             return (bp->sym);
249           /* if this is a global variable then we are ok too */
250           if (bp->level == 0)
251             return (bp->sym);
252         }
253
254       bp = bp->next;
255     }
256
257   return (void *) NULL;
258 }
259
260 /*-----------------------------------------------------------------*/
261 /* findSymWithBlock - finds a symbol with name in with a block     */
262 /*-----------------------------------------------------------------*/
263 void *
264 findSymWithBlock (bucket ** stab, symbol * sym, int block)
265 {
266   bucket *bp;
267
268   bp = stab[hashKey (sym->name)];
269   while (bp)
270     {
271       if (strcmp (bp->name, sym->name) == 0 &&
272           bp->block <= block)
273         break;
274       bp = bp->next;
275     }
276
277   return (bp ? bp->sym : (void *) NULL);
278 }
279
280 /*------------------------------------------------------------------*/
281 /* newSymbol () - returns a new pointer to a symbol                 */
282 /*------------------------------------------------------------------*/
283 symbol *
284 newSymbol (char *name, int scope)
285 {
286   symbol *sym;
287
288   sym = Safe_alloc ( sizeof (symbol));
289
290   strncpyz (sym->name, name, sizeof(sym->name));        /* copy the name */
291   sym->level = scope;           /* set the level    */
292   sym->block = currBlockno;
293   sym->lineDef = mylineno;      /* set the line number */
294   return sym;
295 }
296
297 /*------------------------------------------------------------------*/
298 /* newLink - creates a new link (declarator,specifier)              */
299 /*------------------------------------------------------------------*/
300 sym_link *
301 newLink (SYM_LINK_CLASS select)
302 {
303   sym_link *p;
304
305   p = Safe_alloc ( sizeof (sym_link));
306   p->class=select;
307
308   return p;
309 }
310
311 /*------------------------------------------------------------------*/
312 /* newStruct - creats a new structdef from the free list            */
313 /*------------------------------------------------------------------*/
314 structdef *
315 newStruct (char *tag)
316 {
317   structdef *s;
318
319   s = Safe_alloc ( sizeof (structdef));
320
321   strncpyz (s->tag, tag, sizeof(s->tag));               /* copy the tag */
322   return s;
323 }
324
325 /*------------------------------------------------------------------*/
326 /* pointerTypes - do the computation for the pointer types          */
327 /*------------------------------------------------------------------*/
328 void 
329 pointerTypes (sym_link * ptr, sym_link * type)
330 {
331   if (IS_SPEC (ptr))
332     return;
333
334   /* find the first pointer type */
335   while (ptr && !IS_PTR (ptr))
336     ptr = ptr->next;
337
338   /* could not find it */
339   if (!ptr || IS_SPEC (ptr))
340     return;
341   
342   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
343     pointerTypes (ptr->next, type);
344     return;
345   }
346
347   /* change the pointer type depending on the
348      storage class of the type */
349   if (IS_SPEC (type))
350     {
351       DCL_PTR_CONST (ptr) = SPEC_CONST (type);
352       DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
353       switch (SPEC_SCLS (type))
354         {
355         case S_XDATA:
356           DCL_TYPE (ptr) = FPOINTER;
357           break;
358         case S_IDATA:
359           DCL_TYPE (ptr) = IPOINTER;
360           break;
361         case S_PDATA:
362           DCL_TYPE (ptr) = PPOINTER;
363           break;
364         case S_DATA:
365           DCL_TYPE (ptr) = POINTER;
366           break;
367         case S_CODE:
368           DCL_PTR_CONST (ptr) = port->mem.code_ro;
369           DCL_TYPE (ptr) = CPOINTER;
370           break;
371         case S_EEPROM:
372           DCL_TYPE (ptr) = EEPPOINTER;
373           break;
374         default:
375           DCL_TYPE (ptr) = port->unqualified_pointer;
376           break;
377         }
378       /* the storage class of type ends here */
379       SPEC_SCLS (type) = 
380         SPEC_CONST (type) =
381         SPEC_VOLATILE (type) = 0;
382     }
383
384   /* now change all the remaining unknown pointers
385      to generic pointers */
386   while (ptr)
387     {
388       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
389         DCL_TYPE (ptr) = port->unqualified_pointer;
390       ptr = ptr->next;
391     }
392
393   /* same for the type although it is highly unlikely that
394      type will have a pointer */
395   while (type)
396     {
397       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
398         DCL_TYPE (type) = port->unqualified_pointer;
399       type = type->next;
400     }
401
402 }
403
404 /*------------------------------------------------------------------*/
405 /* addDecl - adds a declarator @ the end of a chain                 */
406 /*------------------------------------------------------------------*/
407 void 
408 addDecl (symbol * sym, int type, sym_link * p)
409 {
410   sym_link *head;
411   sym_link *tail;
412   sym_link *t;
413
414   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
415     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
416
417   /* if we are passed a link then set head & tail */
418   if (p)
419     {
420       tail = head = p;
421       while (tail->next)
422         tail = tail->next;
423     }
424   else
425     {
426       head = tail = newLink (DECLARATOR);
427       DCL_TYPE (head) = type;
428     }
429
430   /* if this is the first entry   */
431   if (!sym->type)
432     {
433       sym->type = head;
434       sym->etype = tail;
435     }
436   else
437     {
438       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
439         {
440           sym->etype = mergeSpec (sym->etype, head, sym->name);
441         }
442       else
443         {
444           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
445             {
446               t = sym->type;
447               while (t->next != sym->etype)
448                 t = t->next;
449               t->next = head;
450               tail->next = sym->etype;
451             }
452           else
453             {
454               sym->etype->next = head;
455               sym->etype = tail;
456             }
457         }
458     }
459
460   /* if the type is an unknown pointer and has
461      a tspec then take the storage class const & volatile
462      attribute from the tspec & make it those of this
463      symbol */
464   if (p &&
465       !IS_SPEC (p) &&
466       //DCL_TYPE (p) == UPOINTER &&
467       DCL_TSPEC (p))
468     {
469       if (!IS_SPEC (sym->etype))
470         {
471           sym->etype = sym->etype->next = newLink (SPECIFIER);
472         }
473       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
474       SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
475       SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
476       DCL_TSPEC (p) = NULL;
477     }
478
479   // if there is a function in this type chain
480   if (p && funcInChain(sym->type)) {
481     processFuncArgs (sym);
482   }
483
484   return;
485 }
486
487 /*------------------------------------------------------------------
488   checkTypeSanity: prevent the user from doing e.g.:
489   unsigned float uf;
490   ------------------------------------------------------------------*/
491 void checkTypeSanity(sym_link *etype, char *name) {
492   char *noun;
493
494   if (!etype) {
495     if (getenv("DEBUG_SANITY")) {
496       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
497     }
498     return;
499   }
500
501   if (!IS_SPEC(etype)) {
502     if (getenv("DEBUG_SANITY")) {
503       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
504     }
505     return;
506   }
507
508   noun=nounName(etype);
509
510   if (getenv("DEBUG_SANITY")) {
511     fprintf (stderr, "checking sanity for %s %p\n", name, etype);
512   }
513
514   if ((SPEC_NOUN(etype)==V_CHAR || 
515        SPEC_NOUN(etype)==V_FLOAT || 
516        SPEC_NOUN(etype)==V_DOUBLE || 
517        SPEC_NOUN(etype)==V_VOID) &&
518       (etype->select.s._short || SPEC_LONG(etype))) {
519     // long or short for char float double or void
520     werror (E_LONG_OR_SHORT_INVALID, noun, name);
521   }
522   if ((SPEC_NOUN(etype)==V_FLOAT || 
523        SPEC_NOUN(etype)==V_DOUBLE || 
524        SPEC_NOUN(etype)==V_VOID) && 
525       (etype->select.s._signed || SPEC_USIGN(etype))) {
526     // signed or unsigned for float double or void
527     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
528   }
529
530   // special case for "short"
531   if (etype->select.s._short) {
532     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
533     etype->select.s._short = 0;
534   }
535
536   /* if no noun e.g. 
537      "const a;" or "data b;" or "signed s" or "long l"
538      assume an int */
539   if (!SPEC_NOUN(etype)) {
540     SPEC_NOUN(etype)=V_INT;
541   }
542
543   if (etype->select.s._signed && SPEC_USIGN(etype)) {
544     // signed AND unsigned 
545     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
546   }
547   if (etype->select.s._short && SPEC_LONG(etype)) {
548     // short AND long
549     werror (E_LONG_AND_SHORT_INVALID, noun, name);
550   }
551
552 }
553
554 /*------------------------------------------------------------------*/
555 /* mergeSpec - merges two specifiers and returns the new one        */
556 /*------------------------------------------------------------------*/
557 sym_link *
558 mergeSpec (sym_link * dest, sym_link * src, char *name)
559 {
560   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
561 #if 0
562     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
563     exit (1);
564 #else
565     werror (E_SYNTAX_ERROR, yytext);
566     // the show must go on
567     return newIntLink();
568 #endif
569   }
570
571   if (SPEC_NOUN(src)) {
572     if (!SPEC_NOUN(dest)) {
573       SPEC_NOUN(dest)=SPEC_NOUN(src);
574     } else {
575       /* we shouldn't redeclare the type */
576       if (getenv("DEBUG_SANITY")) {
577         fprintf (stderr, "mergeSpec: ");
578       }
579       werror(E_TWO_OR_MORE_DATA_TYPES, name);
580     }
581   }
582   
583   if (SPEC_SCLS(src)) {
584     /* if destination has no storage class */
585     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
586       SPEC_SCLS (dest) = SPEC_SCLS (src);
587     } else {
588       if (getenv("DEBUG_SANITY")) {
589         fprintf (stderr, "mergeSpec: ");
590       }
591       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
592     }
593   }
594
595   /* copy all the specifications  */
596
597   // we really should do: 
598 #if 0
599   if (SPEC_what(src)) {
600     if (SPEC_what(dest)) {
601       werror(W_DUPLICATE_SPEC, "what");
602     }
603     SPEC_what(dst)|=SPEC_what(src);
604   }
605 #endif
606   // but there are more important thing right now
607
608   SPEC_LONG (dest) |= SPEC_LONG (src);
609   dest->select.s._short|=src->select.s._short;
610   SPEC_USIGN (dest) |= SPEC_USIGN (src);
611   dest->select.s._signed|=src->select.s._signed;
612   SPEC_STAT (dest) |= SPEC_STAT (src);
613   SPEC_EXTR (dest) |= SPEC_EXTR (src);
614   SPEC_CONST(dest) |= SPEC_CONST (src);
615   SPEC_ABSA (dest) |= SPEC_ABSA (src);
616   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
617   SPEC_ADDR (dest) |= SPEC_ADDR (src);
618   SPEC_OCLS (dest) = SPEC_OCLS (src);
619   SPEC_BLEN (dest) |= SPEC_BLEN (src);
620   SPEC_BSTR (dest) |= SPEC_BSTR (src);
621   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
622   SPEC_ENUM (dest) |= SPEC_ENUM (src);
623   if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
624       SPEC_ARGREG(dest) = SPEC_ARGREG(src);
625   
626   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
627     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
628
629   /* these are the only function attributes that will be set 
630      in a specifier while parsing */
631   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
632   FUNC_BANKED(dest) |= FUNC_BANKED(src);
633   FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
634   FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
635   FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
636   FUNC_ISISR(dest) |= FUNC_ISISR(src);
637   FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
638   FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
639   FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
640   FUNC_INTNO(dest) |= FUNC_INTNO(src);
641   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
642
643   return dest;
644 }
645
646 /*------------------------------------------------------------------*/
647 /* genSymName - generates and returns a name used for anonymous vars */
648 /*------------------------------------------------------------------*/
649 char *
650 genSymName (int level)
651 {
652   static int gCount = 0;
653   static char gname[SDCC_NAME_MAX + 1];
654
655   SNPRINTF (gname, sizeof(gname), "__%04d%04d", level, gCount++);
656   return gname;
657 }
658
659 /*------------------------------------------------------------------*/
660 /* getSpec - returns the specifier part from a declaration chain    */
661 /*------------------------------------------------------------------*/
662 sym_link *
663 getSpec (sym_link * p)
664 {
665   sym_link *loop;
666
667   loop = p;
668   while (p && !(IS_SPEC (p)))
669     p = p->next;
670
671   return p;
672 }
673
674 /*------------------------------------------------------------------*/
675 /* newCharLink() - creates an char type                             */
676 /*------------------------------------------------------------------*/
677 sym_link *
678 newCharLink ()
679 {
680   sym_link *p;
681
682   p = newLink (SPECIFIER);
683   SPEC_NOUN (p) = V_CHAR;
684
685   return p;
686 }
687
688 /*------------------------------------------------------------------*/
689 /* newFloatLink - a new Float type                                  */
690 /*------------------------------------------------------------------*/
691 sym_link *
692 newFloatLink ()
693 {
694   sym_link *p;
695
696   p = newLink (SPECIFIER);
697   SPEC_NOUN (p) = V_FLOAT;
698
699   return p;
700 }
701
702 /*------------------------------------------------------------------*/
703 /* newLongLink() - new long type                                    */
704 /*------------------------------------------------------------------*/
705 sym_link *
706 newLongLink ()
707 {
708   sym_link *p;
709
710   p = newLink (SPECIFIER);
711   SPEC_NOUN (p) = V_INT;
712   SPEC_LONG (p) = 1;
713
714   return p;
715 }
716
717 /*------------------------------------------------------------------*/
718 /* newIntLink() - creates an int type                               */
719 /*------------------------------------------------------------------*/
720 sym_link *
721 newIntLink ()
722 {
723   sym_link *p;
724
725   p = newLink (SPECIFIER);
726   SPEC_NOUN (p) = V_INT;
727
728   return p;
729 }
730
731 /*------------------------------------------------------------------*/
732 /* getSize - returns size of a type chain in bits                   */
733 /*------------------------------------------------------------------*/
734 unsigned int 
735 getSize (sym_link * p)
736 {
737   /* if nothing return 0 */
738   if (!p)
739     return 0;
740   if (IS_SPEC (p))
741     {                           /* if this is the specifier then */
742       switch (SPEC_NOUN (p))
743         {                       /* depending on the specifier type */
744         case V_INT:
745           return (IS_LONG (p) ? LONGSIZE : INTSIZE);
746         case V_FLOAT:
747           return FLOATSIZE;
748         case V_CHAR:
749           return CHARSIZE;
750         case V_VOID:
751           return 0;
752         case V_STRUCT:
753           return SPEC_STRUCT (p)->size;
754         case V_LABEL:
755           return 0;
756         case V_SBIT:
757           return BITSIZE;
758         case V_BIT:
759           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
760         default:
761           return 0;
762         }
763     }
764
765   /* this is a specifier  */
766   switch (DCL_TYPE (p))
767     {
768     case ARRAY:
769       if (DCL_ELEM(p)) {
770         return DCL_ELEM (p) * getSize (p->next);
771       } else {
772           //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
773           //    "can not tell the size of an array[]");
774         return 0;
775       }
776     case IPOINTER:
777     case PPOINTER:
778     case POINTER:
779       return (PTRSIZE);
780     case EEPPOINTER:
781     case FPOINTER:
782     case CPOINTER:
783     case FUNCTION:
784       return (FPTRSIZE);
785     case GPOINTER:
786       return (GPTRSIZE);
787
788     default:
789       return 0;
790     }
791 }
792
793 /*------------------------------------------------------------------*/
794 /* bitsForType - returns # of bits required to store this type      */
795 /*------------------------------------------------------------------*/
796 unsigned int 
797 bitsForType (sym_link * p)
798 {
799   /* if nothing return 0 */
800   if (!p)
801     return 0;
802
803   if (IS_SPEC (p))
804     {                           /* if this is the specifier then */
805
806       switch (SPEC_NOUN (p))
807         {                       /* depending on the specifier type */
808         case V_INT:
809           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
810         case V_FLOAT:
811           return FLOATSIZE * 8;
812         case V_CHAR:
813           return CHARSIZE * 8;
814         case V_VOID:
815           return 0;
816         case V_STRUCT:
817           return SPEC_STRUCT (p)->size * 8;
818         case V_LABEL:
819           return 0;
820         case V_SBIT:
821           return 1;
822         case V_BIT:
823           return SPEC_BLEN (p);
824         default:
825           return 0;
826         }
827     }
828
829   /* this is a specifier  */
830   switch (DCL_TYPE (p))
831     {
832     case ARRAY:
833       return DCL_ELEM (p) * getSize (p->next) * 8;
834     case IPOINTER:
835     case PPOINTER:
836     case POINTER:
837       return (PTRSIZE * 8);
838     case EEPPOINTER:
839     case FPOINTER:
840     case CPOINTER:
841     case FUNCTION:
842       return (FPTRSIZE * 8);
843     case GPOINTER:
844       return (GPTRSIZE * 8);
845
846     default:
847       return 0;
848     }
849 }
850
851 /*------------------------------------------------------------------*/
852 /* copySymbolChain - copies a symbol chain                          */
853 /*------------------------------------------------------------------*/
854 symbol *
855 copySymbolChain (symbol * src)
856 {
857   symbol *dest;
858
859   if (!src)
860     return NULL;
861
862   dest = copySymbol (src);
863   dest->next = copySymbolChain (src->next);
864   return dest;
865 }
866
867 /*------------------------------------------------------------------*/
868 /* copySymbol - makes a copy of a symbol                            */
869 /*------------------------------------------------------------------*/
870 symbol *
871 copySymbol (symbol * src)
872 {
873   symbol *dest;
874
875   if (!src)
876     return NULL;
877
878   dest = newSymbol (src->name, src->level);
879   memcpy (dest, src, sizeof (symbol));
880   dest->level = src->level;
881   dest->block = src->block;
882   dest->ival = copyIlist (src->ival);
883   dest->type = copyLinkChain (src->type);
884   dest->etype = getSpec (dest->type);
885   dest->next = NULL;
886   dest->key = src->key;
887   dest->allocreq = src->allocreq;
888   return dest;
889 }
890
891 /*------------------------------------------------------------------*/
892 /* reverseSyms - reverses the links for a symbol chain      */
893 /*------------------------------------------------------------------*/
894 symbol *
895 reverseSyms (symbol * sym)
896 {
897   symbol *prev, *curr, *next;
898
899   if (!sym)
900     return NULL;
901
902   prev = sym;
903   curr = sym->next;
904
905   while (curr)
906     {
907       next = curr->next;
908       curr->next = prev;
909       prev = curr;
910       curr = next;
911     }
912   sym->next = (void *) NULL;
913   return prev;
914 }
915
916 /*------------------------------------------------------------------*/
917 /* reverseLink - reverses the links for a type chain        */
918 /*------------------------------------------------------------------*/
919 sym_link *
920 reverseLink (sym_link * type)
921 {
922   sym_link *prev, *curr, *next;
923
924   if (!type)
925     return NULL;
926
927   prev = type;
928   curr = type->next;
929
930   while (curr)
931     {
932       next = curr->next;
933       curr->next = prev;
934       prev = curr;
935       curr = next;
936     }
937   type->next = (void *) NULL;
938   return prev;
939 }
940
941 /*------------------------------------------------------------------*/
942 /* addSymChain - adds a symbol chain to the symboltable             */
943 /*------------------------------------------------------------------*/
944 void 
945 addSymChain (symbol * symHead)
946 {
947   symbol *sym = symHead;
948   symbol *csym = NULL;
949
950   for (; sym != NULL; sym = sym->next)
951     {
952       changePointer(sym);
953       checkTypeSanity(sym->etype, sym->name);
954
955       /* if already exists in the symbol table then check if
956          one of them is an extern definition if yes then
957          then check if the type match, if the types match then
958          delete the current entry and add the new entry      */
959       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
960           csym->level == sym->level) {
961         
962         /* one definition extern ? */
963         if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
964           /* do types match ? */
965           if (compareType (csym->type, sym->type) != 1) {
966             /* no then error */
967             werror (E_EXTERN_MISMATCH, csym->name);
968             continue;
969           }
970         } else {
971           /* not extern */
972           if (compareType (csym->type, sym->type) != 1) {
973             werror (E_DUPLICATE, sym->name);
974             continue;
975           }
976         }
977         /* delete current entry */
978         deleteSym (SymbolTab, csym, csym->name);
979         deleteFromSeg(csym);
980       }
981
982       /* add new entry */
983       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
984     }
985 }
986
987
988 /*------------------------------------------------------------------*/
989 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
990 /*------------------------------------------------------------------*/
991 int 
992 funcInChain (sym_link * lnk)
993 {
994   while (lnk)
995     {
996       if (IS_FUNC (lnk))
997         return 1;
998       lnk = lnk->next;
999     }
1000   return 0;
1001 }
1002
1003 /*------------------------------------------------------------------*/
1004 /* structElemType - returns the type info of a sturct member        */
1005 /*------------------------------------------------------------------*/
1006 sym_link *
1007 structElemType (sym_link * stype, value * id)
1008 {
1009   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1010   sym_link *type, *etype;
1011   sym_link *petype = getSpec (stype);
1012
1013   if (fields && id) {
1014     
1015     /* look for the id */
1016     while (fields)
1017       {
1018         if (strcmp (fields->rname, id->name) == 0)
1019           {
1020             type = copyLinkChain (fields->type);
1021             etype = getSpec (type);
1022             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1023                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
1024             return type;
1025           }
1026         fields = fields->next;
1027       }
1028   }
1029
1030   werror (E_NOT_MEMBER, id->name);
1031     
1032   // the show must go on
1033   return newIntLink();
1034 }
1035
1036 /*------------------------------------------------------------------*/
1037 /* getStructElement - returns element of a tructure definition      */
1038 /*------------------------------------------------------------------*/
1039 symbol *
1040 getStructElement (structdef * sdef, symbol * sym)
1041 {
1042   symbol *field;
1043
1044   for (field = sdef->fields; field; field = field->next)
1045     if (strcmp (field->name, sym->name) == 0)
1046       return field;
1047
1048   werror (E_NOT_MEMBER, sym->name);
1049
1050   return sdef->fields;
1051 }
1052
1053 /*------------------------------------------------------------------*/
1054 /* compStructSize - computes the size of a structure                */
1055 /*------------------------------------------------------------------*/
1056 int 
1057 compStructSize (int su, structdef * sdef)
1058 {
1059     int sum = 0, usum = 0;
1060     int bitOffset = 0;
1061     symbol *loop;
1062
1063     /* for the identifiers  */
1064     loop = sdef->fields;
1065     while (loop) {
1066
1067         /* create the internal name for this variable */
1068         SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1069         loop->offset = (su == UNION ? sum = 0 : sum);
1070         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1071
1072         /* if this is a bit field  */
1073         if (loop->bitVar) {
1074
1075             /* change it to a unsigned bit */
1076             SPEC_NOUN (loop->etype) = V_BIT;
1077             SPEC_USIGN (loop->etype) = 1;
1078             /* check if this fit into the remaining   */
1079             /* bits of this byte else align it to the */
1080             /* next byte boundary                     */
1081             if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
1082                 SPEC_BSTR (loop->etype) = bitOffset;
1083                 if ((bitOffset += (loop->bitVar % 8)) == 8)
1084                     sum++;
1085             }
1086             else /* does not fit */ {
1087                 bitOffset = 0;
1088                 SPEC_BSTR (loop->etype) = bitOffset;
1089                 sum += (loop->bitVar / 8);
1090                 bitOffset += (loop->bitVar % 8);
1091             }
1092             /* if this is the last field then pad */
1093             if (!loop->next && bitOffset && bitOffset != 8) {
1094                 bitOffset = 0;
1095                 sum++;
1096             }
1097         }
1098         else {
1099             checkDecl (loop, 1);
1100             sum += getSize (loop->type);
1101         }
1102
1103         loop = loop->next;
1104
1105         /* if this is not a bitfield but the */
1106         /* previous one was and did not take */
1107         /* the whole byte then pad the rest  */
1108         if ((loop && !loop->bitVar) && bitOffset) {
1109             bitOffset = 0;
1110             sum++;
1111         }
1112
1113         /* if union then size = sizeof larget field */
1114         if (su == UNION)
1115             usum = max (usum, sum);
1116
1117     }
1118
1119     return (su == UNION ? usum : sum);
1120 }
1121
1122 /*------------------------------------------------------------------*/
1123 /* checkSClass - check the storage class specification              */
1124 /*------------------------------------------------------------------*/
1125 static void 
1126 checkSClass (symbol * sym, int isProto)
1127 {
1128   if (getenv("DEBUG_SANITY")) {
1129     fprintf (stderr, "checkSClass: %s \n", sym->name);
1130   }
1131   
1132   /* type is literal can happen foe enums change
1133      to auto */
1134   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1135     SPEC_SCLS (sym->etype) = S_AUTO;
1136   
1137   /* if sfr or sbit then must also be volatile */
1138   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1139       SPEC_SCLS (sym->etype) == S_SFR)
1140     {
1141       SPEC_VOLATILE (sym->etype) = 1;
1142     }
1143   
1144   /* if absolute address given then it mark it as
1145      volatile -- except in the PIC port */
1146
1147 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1148   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1149   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1150 #endif
1151
1152     if (IS_ABSOLUTE (sym->etype))
1153       SPEC_VOLATILE (sym->etype) = 1;
1154   
1155
1156   /* global variables declared const put into code */
1157   /* if no other storage class specified */
1158   if (sym->level == 0 &&
1159       SPEC_CONST (sym->etype) &&
1160       SPEC_SCLS(sym->etype) == S_FIXED &&
1161       !IS_FUNC(sym->type)) {
1162     SPEC_SCLS (sym->etype) = S_CODE;
1163   }
1164
1165   /* global variable in code space is a constant */
1166   if (sym->level == 0 &&
1167       SPEC_SCLS (sym->etype) == S_CODE &&
1168       port->mem.code_ro) {
1169     if (IS_SPEC(sym->type)) {
1170       SPEC_CONST (sym->type) = 1;
1171     } else {
1172       DCL_PTR_CONST (sym->type) = 1;
1173     }
1174   }
1175
1176   /* if bit variable then no storage class can be */
1177   /* specified since bit is already a storage */
1178   if (IS_BITVAR (sym->etype) &&
1179       (SPEC_SCLS (sym->etype) != S_FIXED &&
1180        SPEC_SCLS (sym->etype) != S_SBIT &&
1181        SPEC_SCLS (sym->etype) != S_BIT)
1182     )
1183     {
1184       werror (E_BITVAR_STORAGE, sym->name);
1185       SPEC_SCLS (sym->etype) = S_FIXED;
1186     }
1187
1188   /* extern variables cannot be initialized */
1189   if (IS_EXTERN (sym->etype) && sym->ival)
1190     {
1191       werror (E_EXTERN_INIT, sym->name);
1192       sym->ival = NULL;
1193     }
1194
1195   /* if this is an atomatic symbol */
1196   if (sym->level && (options.stackAuto || reentrant)) {
1197     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1198          SPEC_SCLS (sym->etype) == S_FIXED ||
1199          SPEC_SCLS (sym->etype) == S_REGISTER ||
1200          SPEC_SCLS (sym->etype) == S_STACK ||
1201          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1202       SPEC_SCLS (sym->etype) = S_AUTO;
1203     } else {
1204       /* storage class may only be specified for statics */
1205       if (!IS_STATIC(sym->etype)) {
1206         werror (E_AUTO_ASSUMED, sym->name);
1207       }
1208     }
1209   }
1210   
1211   /* automatic symbols cannot be given   */
1212   /* an absolute address ignore it      */
1213   if (sym->level &&
1214       SPEC_ABSA (sym->etype) &&
1215       (options.stackAuto || reentrant))
1216     {
1217       werror (E_AUTO_ABSA, sym->name);
1218       SPEC_ABSA (sym->etype) = 0;
1219     }
1220
1221   /* arrays & pointers cannot be defined for bits   */
1222   /* SBITS or SFRs or BIT                           */
1223   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1224       (SPEC_NOUN (sym->etype) == V_BIT ||
1225        SPEC_NOUN (sym->etype) == V_SBIT ||
1226        SPEC_SCLS (sym->etype) == S_SFR))
1227     werror (E_BIT_ARRAY, sym->name);
1228
1229   /* if this is a bit|sbit then set length & start  */
1230   if (SPEC_NOUN (sym->etype) == V_BIT ||
1231       SPEC_NOUN (sym->etype) == V_SBIT)
1232     {
1233       SPEC_BLEN (sym->etype) = 1;
1234       SPEC_BSTR (sym->etype) = 0;
1235     }
1236
1237   if (!isProto) {
1238     /* variables declared in CODE space must have */
1239     /* initializers if not an extern */
1240     if (SPEC_SCLS (sym->etype) == S_CODE &&
1241         sym->ival == NULL &&
1242         //!sym->level &&
1243         port->mem.code_ro &&
1244         !IS_EXTERN (sym->etype) &&
1245         !funcInChain (sym->type))
1246       werror (E_CODE_NO_INIT, sym->name);
1247   }
1248
1249   /* if parameter or local variable then change */
1250   /* the storage class to reflect where the var will go */
1251   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1252       !IS_STATIC(sym->etype))
1253     {
1254       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1255         {
1256           SPEC_SCLS (sym->etype) = (options.useXstack ?
1257                                     S_XSTACK : S_STACK);
1258         }
1259       else
1260         {
1261           /* hack-o-matic! I see no reason why the useXstack option should ever
1262            * control this allcoation, but the code was originally that way, and
1263            * changing it for non-390 ports breaks the compiler badly.
1264            */
1265           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1266                 1 : options.useXstack;
1267           SPEC_SCLS (sym->etype) = (useXdata ?
1268                                     S_XDATA : S_FIXED);
1269         }
1270     }
1271 }
1272
1273 /*------------------------------------------------------------------*/
1274 /* changePointer - change pointer to functions                      */
1275 /*------------------------------------------------------------------*/
1276 void 
1277 changePointer (symbol * sym)
1278 {
1279   sym_link *p;
1280
1281   /* go thru the chain of declarations   */
1282   /* if we find a pointer to a function  */
1283   /* unconditionally change it to a ptr  */
1284   /* to code area                        */
1285   for (p = sym->type; p; p = p->next)
1286     {
1287       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1288         DCL_TYPE (p) = port->unqualified_pointer;
1289       if (IS_PTR (p) && IS_FUNC (p->next))
1290         DCL_TYPE (p) = CPOINTER;
1291     }
1292 }
1293
1294 /*------------------------------------------------------------------*/
1295 /* checkDecl - does semantic validation of a declaration                   */
1296 /*------------------------------------------------------------------*/
1297 int 
1298 checkDecl (symbol * sym, int isProto)
1299 {
1300
1301   checkSClass (sym, isProto);           /* check the storage class      */
1302   changePointer (sym);          /* change pointers if required */
1303
1304   /* if this is an array without any dimension
1305      then update the dimension from the initial value */
1306   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1307     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1308
1309   return 0;
1310 }
1311
1312 /*------------------------------------------------------------------*/
1313 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1314 /*------------------------------------------------------------------*/
1315 sym_link *
1316 copyLinkChain (sym_link * p)
1317 {
1318   sym_link *head, *curr, *loop;
1319
1320   curr = p;
1321   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1322   while (curr)
1323     {
1324       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1325       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1326       loop = loop->next;
1327       curr = curr->next;
1328     }
1329
1330   return head;
1331 }
1332
1333
1334 /*------------------------------------------------------------------*/
1335 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1336 /*                symbols in the given block                        */
1337 /*------------------------------------------------------------------*/
1338 void 
1339 cleanUpBlock (bucket ** table, int block)
1340 {
1341   int i;
1342   bucket *chain;
1343
1344   /* go thru the entire  table  */
1345   for (i = 0; i < 256; i++)
1346     {
1347       for (chain = table[i]; chain; chain = chain->next)
1348         {
1349           if (chain->block >= block)
1350             {
1351               deleteSym (table, chain->sym, chain->name);
1352             }
1353         }
1354     }
1355 }
1356
1357 /*------------------------------------------------------------------*/
1358 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1359 /*                symbols in the given level                        */
1360 /*------------------------------------------------------------------*/
1361 void 
1362 cleanUpLevel (bucket ** table, int level)
1363 {
1364   int i;
1365   bucket *chain;
1366
1367   /* go thru the entire  table  */
1368   for (i = 0; i < 256; i++)
1369     {
1370       for (chain = table[i]; chain; chain = chain->next)
1371         {
1372           if (chain->level >= level)
1373             {
1374               deleteSym (table, chain->sym, chain->name);
1375             }
1376         }
1377     }
1378 }
1379
1380 /*------------------------------------------------------------------*/
1381 /* computeType - computes the resultant type from two types         */
1382 /*------------------------------------------------------------------*/
1383 sym_link *
1384 computeType (sym_link * type1, sym_link * type2)
1385 {
1386   sym_link *rType;
1387   sym_link *reType;
1388   sym_link *etype1 = getSpec (type1);
1389   sym_link *etype2 = getSpec (type2);
1390
1391   /* if one of them is a float then result is a float */
1392   /* here we assume that the types passed are okay */
1393   /* and can be cast to one another                */
1394   /* which ever is greater in size */
1395   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1396     rType = newFloatLink ();
1397   else
1398     /* if only one of them is a bit variable
1399        then the other one prevails */
1400   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1401     rType = copyLinkChain (type2);
1402   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1403     rType = copyLinkChain (type1);
1404   else
1405     /* if one of them is a pointer or array then that
1406        prevails */
1407   if (IS_PTR (type1) || IS_ARRAY (type1))
1408     rType = copyLinkChain (type1);
1409   else if (IS_PTR (type2) || IS_ARRAY (type2))
1410     rType = copyLinkChain (type2);
1411   else if (getSize (type1) > getSize (type2))
1412     rType = copyLinkChain (type1);
1413   else
1414     rType = copyLinkChain (type2);
1415
1416   reType = getSpec (rType);
1417
1418   /* if either of them unsigned but not val then make this unsigned */
1419   if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || 
1420        (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && 
1421       !IS_FLOAT (reType))
1422     SPEC_USIGN (reType) = 1;
1423   else
1424     SPEC_USIGN (reType) = 0;
1425   
1426   /* if result is a literal then make not so */
1427   if (IS_LITERAL (reType))
1428     SPEC_SCLS (reType) = S_REGISTER;
1429
1430   return rType;
1431 }
1432
1433 /*--------------------------------------------------------------------*/
1434 /* compareType - will do type check return 1 if match, -1 if castable */
1435 /*--------------------------------------------------------------------*/
1436 int 
1437 compareType (sym_link * dest, sym_link * src)
1438 {
1439   if (!dest && !src)
1440     return 1;
1441
1442   if (dest && !src)
1443     return 0;
1444
1445   if (src && !dest)
1446     return 0;
1447
1448   /* if dest is a declarator then */
1449   if (IS_DECL (dest))
1450     {
1451       if (IS_DECL (src))
1452         {
1453           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1454             if (IS_FUNC(src)) {
1455               //checkFunction(src,dest);
1456             }
1457             return compareType (dest->next, src->next);
1458           }
1459           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1460             return 1;
1461           }
1462           if (IS_PTR (src) && IS_GENPTR (dest))
1463             return -1;
1464           if (IS_PTR (dest) && IS_ARRAY (src)) {
1465             value *val=aggregateToPointer (valFromType(src));
1466             int res=compareType (dest, val->type);
1467             Safe_free(val->type);
1468             Safe_free(val);
1469             return res;
1470           }
1471           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1472             return compareType (dest->next, src);
1473           return 0;
1474         }
1475       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1476         return -1;
1477       else
1478         return 0;
1479     }
1480
1481   /* if one is a specifier and the other is not */
1482   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1483       (IS_SPEC (dest) && !IS_SPEC (src)))
1484     return 0;
1485
1486   /* if one of them is a void then ok */
1487   if (SPEC_NOUN (dest) == V_VOID &&
1488       SPEC_NOUN (src) != V_VOID)
1489     return -1;
1490
1491   if (SPEC_NOUN (dest) != V_VOID &&
1492       SPEC_NOUN (src) == V_VOID)
1493     return -1;
1494
1495   /* if they are both bitfields then if the lengths
1496      and starts don't match */
1497   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1498       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1499        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1500     return -1;
1501
1502   /* it is a specifier */
1503   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1504     {
1505       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1506           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1507           getSize (dest) == getSize (src))
1508         return 1;
1509       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1510         return -1;
1511       else
1512         return 0;
1513     }
1514   else if (IS_STRUCT (dest))
1515     {
1516       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1517         return 0;
1518       else
1519         return 1;
1520     }
1521   if (SPEC_LONG (dest) != SPEC_LONG (src))
1522     return -1;
1523
1524   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1525     return -1;
1526
1527   return 1;
1528 }
1529
1530 /*------------------------------------------------------------------*/
1531 /* inCalleeSaveList - return 1 if found in callee save list          */
1532 /*------------------------------------------------------------------*/
1533 static int
1534 calleeCmp(void *p1, void *p2)
1535 {
1536   return (strcmp((char *)p1, (char *)(p2)) == 0);
1537 }
1538
1539 bool
1540 inCalleeSaveList(char *s)
1541 {
1542   if (options.all_callee_saves)
1543     return 1;
1544   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
1545 }
1546
1547 /*-----------------------------------------------------------------*/
1548 /* aggregateToPointer:  change an agggregate type function      */
1549 /*         argument to a pointer to that type.     */
1550 /*-----------------------------------------------------------------*/
1551 value *
1552 aggregateToPointer (value * val)
1553 {
1554   if (IS_AGGREGATE (val->type))
1555     {
1556       /* if this is a structure */
1557       /* then we need to add a new link */
1558       if (IS_STRUCT (val->type))
1559         {
1560           /* first lets add DECLARATOR type */
1561           sym_link *p = val->type;
1562
1563           werror (W_STRUCT_AS_ARG, val->name);
1564           val->type = newLink (DECLARATOR);
1565           val->type->next = p;
1566         }
1567
1568       /* change to a pointer depending on the */
1569       /* storage class specified        */
1570       switch (SPEC_SCLS (val->etype))
1571         {
1572         case S_IDATA:
1573           DCL_TYPE (val->type) = IPOINTER;
1574           break;
1575         case S_PDATA:
1576           DCL_TYPE (val->type) = PPOINTER;
1577           break;
1578         case S_FIXED:
1579           if (SPEC_OCLS(val->etype)) {
1580             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1581           } else {
1582             // this happens for (external) function parameters
1583             DCL_TYPE (val->type) = port->unqualified_pointer;
1584           }
1585           break;
1586         case S_AUTO:
1587         case S_DATA:
1588         case S_REGISTER:
1589           DCL_TYPE (val->type) = POINTER;
1590           break;
1591         case S_CODE:
1592           DCL_TYPE (val->type) = CPOINTER;
1593           break;
1594         case S_XDATA:
1595           DCL_TYPE (val->type) = FPOINTER;
1596           break;
1597         case S_EEPROM:
1598           DCL_TYPE (val->type) = EEPPOINTER;
1599           break;
1600         default:
1601           DCL_TYPE (val->type) = port->unqualified_pointer;
1602         }
1603       
1604       /* is there is a symbol associated then */
1605       /* change the type of the symbol as well */
1606       if (val->sym)
1607         {
1608           val->sym->type = copyLinkChain (val->type);
1609           val->sym->etype = getSpec (val->sym->type);
1610         }
1611     }
1612   return val;
1613 }
1614 /*------------------------------------------------------------------*/
1615 /* checkFunction - does all kinds of check on a function            */
1616 /*------------------------------------------------------------------*/
1617 int 
1618 checkFunction (symbol * sym, symbol *csym)
1619 {
1620   value *exargs, *acargs;
1621   value *checkValue;
1622   int argCnt = 0;
1623
1624   if (getenv("DEBUG_SANITY")) {
1625     fprintf (stderr, "checkFunction: %s ", sym->name);
1626   }
1627
1628   /* make sure the type is complete and sane */
1629   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1630
1631   /* if not type then some kind of error */
1632   if (!sym->type)
1633     return 0;
1634
1635   /* if the function has no type then make it return int */
1636   if (!sym->type->next)
1637     sym->type->next = sym->etype = newIntLink ();
1638
1639   /* function cannot return aggregate */
1640   if (IS_AGGREGATE (sym->type->next))
1641     {
1642       werror (E_FUNC_AGGR, sym->name);
1643       return 0;
1644     }
1645
1646   /* function cannot return bit */
1647   if (IS_BITVAR (sym->type->next))
1648     {
1649       werror (E_FUNC_BIT, sym->name);
1650       return 0;
1651     }
1652
1653   /* check if this function is defined as calleeSaves
1654      then mark it as such */
1655   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1656
1657   /* if interrupt service routine  */
1658   /* then it cannot have arguments */
1659   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1660     {
1661       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1662         werror (E_INT_ARGS, sym->name);
1663         FUNC_ARGS(sym->type)=NULL;
1664       }
1665     }
1666
1667   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1668        acargs; 
1669        acargs=acargs->next, argCnt++) {
1670     if (!acargs->sym) { 
1671       // this can happen for reentrant functions
1672       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1673       // the show must go on: synthesize a name and symbol
1674       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
1675       acargs->sym = newSymbol (acargs->name, 1);
1676       SPEC_OCLS (acargs->etype) = istack;
1677       acargs->sym->type = copyLinkChain (acargs->type);
1678       acargs->sym->etype = getSpec (acargs->sym->type);
1679       acargs->sym->_isparm = 1;
1680       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
1681     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
1682       // synthesized name
1683       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1684     }
1685   }
1686
1687   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1688     return 1;                   /* not defined nothing more to check  */
1689
1690   /* check if body already present */
1691   if (csym && IFFUNC_HASBODY(csym->type))
1692     {
1693       werror (E_FUNC_BODY, sym->name);
1694       return 0;
1695     }
1696
1697   /* check the return value type   */
1698   if (compareType (csym->type, sym->type) <= 0)
1699     {
1700       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1701       printFromToType(csym->type, sym->type);
1702       return 0;
1703     }
1704
1705   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1706     {
1707       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1708     }
1709
1710   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1711     {
1712       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1713     }
1714
1715   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1716     {
1717       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1718     }
1719
1720   /* compare expected args with actual args */
1721   exargs = FUNC_ARGS(csym->type);
1722   acargs = FUNC_ARGS(sym->type);
1723
1724   /* for all the expected args do */
1725   for (argCnt = 1;
1726        exargs && acargs;
1727        exargs = exargs->next, acargs = acargs->next, argCnt++)
1728     {
1729       if (getenv("DEBUG_SANITY")) {
1730         fprintf (stderr, "checkFunction: %s ", exargs->name);
1731       }
1732       /* make sure the type is complete and sane */
1733       checkTypeSanity(exargs->etype, exargs->name);
1734
1735       /* If the actual argument is an array, any prototype
1736        * will have modified it to a pointer. Duplicate that
1737        * change here.
1738        */
1739       if (IS_AGGREGATE (acargs->type))
1740         {
1741           checkValue = copyValue (acargs);
1742           aggregateToPointer (checkValue);
1743         }
1744       else
1745         {
1746           checkValue = acargs;
1747         }
1748
1749       if (compareType (exargs->type, checkValue->type) <= 0)
1750         {
1751           werror (E_ARG_TYPE, argCnt);
1752           printFromToType(exargs->type, checkValue->type);
1753           return 0;
1754         }
1755     }
1756
1757   /* if one them ended we have a problem */
1758   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1759       (!exargs && acargs && !IS_VOID (acargs->type)))
1760     werror (E_ARG_COUNT);
1761
1762   /* replace with this defition */
1763   sym->cdef = csym->cdef;
1764   deleteSym (SymbolTab, csym, csym->name);
1765   deleteFromSeg(csym);
1766   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1767   if (IS_EXTERN (csym->etype) && !
1768       IS_EXTERN (sym->etype))
1769     {
1770       addSet (&publics, sym);
1771     }
1772   return 1;
1773 }
1774
1775 /*------------------------------------------------------------------*/
1776 /* cdbStructBlock - calls struct printing for a blcks               */
1777 /*------------------------------------------------------------------*/
1778 void cdbStructBlock (int block)
1779 {
1780   int i;
1781   bucket **table = StructTab;
1782   bucket *chain;
1783
1784   /* go thru the entire  table  */
1785   for (i = 0; i < 256; i++)
1786     {
1787       for (chain = table[i]; chain; chain = chain->next)
1788         {
1789           if (chain->block >= block)
1790             {
1791               if(debugFile)
1792                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
1793             }
1794         }
1795     }
1796 }
1797
1798 /*-----------------------------------------------------------------*/
1799 /* processFuncArgs - does some processing with function args       */
1800 /*-----------------------------------------------------------------*/
1801 void 
1802 processFuncArgs (symbol * func)
1803 {
1804   value *val;
1805   int pNum = 1;
1806   sym_link *funcType=func->type;
1807
1808   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1809     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1810
1811   // if this is a pointer to a function
1812   if (IS_PTR(funcType)) {
1813     funcType=funcType->next;
1814   }
1815
1816   /* if this function has variable argument list */
1817   /* then make the function a reentrant one    */
1818   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1819     FUNC_ISREENT(funcType)=1;
1820
1821   /* check if this function is defined as calleeSaves
1822      then mark it as such */
1823   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1824
1825   /* loop thru all the arguments   */
1826   val = FUNC_ARGS(funcType);
1827
1828   /* if it is void then remove parameters */
1829   if (val && IS_VOID (val->type))
1830     {
1831       FUNC_ARGS(funcType) = NULL;
1832       return;
1833     }
1834
1835   /* reset regparm for the port */
1836   (*port->reset_regparms) ();
1837   /* if any of the arguments is an aggregate */
1838   /* change it to pointer to the same type */
1839   while (val)
1840     {
1841         int argreg = 0;
1842       /* mark it as a register parameter if
1843          the function does not have VA_ARG
1844          and as port dictates */
1845       if (!IFFUNC_HASVARARGS(funcType) &&
1846           (argreg = (*port->reg_parm) (val->type)))
1847         {
1848           SPEC_REGPARM (val->etype) = 1;
1849           SPEC_ARGREG(val->etype) = argreg;
1850         } else if (IFFUNC_ISREENT(funcType)) {
1851             FUNC_HASSTACKPARM(funcType) = 1;
1852         }
1853
1854       if (IS_AGGREGATE (val->type))
1855         {
1856           aggregateToPointer (val);
1857         }
1858
1859       val = val->next;
1860       pNum++;
1861     }
1862
1863   /* if this is an internal generated function call */
1864   if (func->cdef) {
1865     /* ignore --stack-auto for this one, we don't know how it is compiled */
1866     /* simply trust on --int-long-reent or --float-reent */
1867     if (IFFUNC_ISREENT(funcType)) {
1868       return;
1869     }
1870   } else {
1871     /* if this function is reentrant or */
1872     /* automatics r 2b stacked then nothing */
1873     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1874       return;
1875   }
1876
1877   val = FUNC_ARGS(funcType);
1878   pNum = 1;
1879   while (val)
1880     {
1881
1882       /* if a symbolname is not given  */
1883       /* synthesize a variable name */
1884       if (!val->sym)
1885         {
1886           SNPRINTF (val->name, sizeof(val->name), 
1887                     "_%s_PARM_%d", func->name, pNum++);
1888           val->sym = newSymbol (val->name, 1);
1889           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1890           val->sym->type = copyLinkChain (val->type);
1891           val->sym->etype = getSpec (val->sym->type);
1892           val->sym->_isparm = 1;
1893           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1894           if (IS_SPEC(func->etype)) {
1895             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1896               SPEC_STAT (func->etype);
1897           }
1898           addSymChain (val->sym);
1899
1900         }
1901       else                      /* symbol name given create synth name */
1902         {
1903
1904           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
1905           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1906           val->sym->_isparm = 1;
1907           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1908             (options.model != MODEL_SMALL ? xdata : data);
1909           if (IS_SPEC(func->etype)) {
1910             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1911               SPEC_STAT (func->etype);
1912           }
1913         }
1914       if (!isinSet(operKeyReset, val->sym)) {
1915         addSet (&operKeyReset, val->sym);
1916         applyToSet (operKeyReset, resetParmKey);
1917       }
1918       val = val->next;
1919     }
1920 }
1921
1922 /*-----------------------------------------------------------------*/
1923 /* isSymbolEqual - compares two symbols return 1 if they match     */
1924 /*-----------------------------------------------------------------*/
1925 int 
1926 isSymbolEqual (symbol * dest, symbol * src)
1927 {
1928   /* if pointers match then equal */
1929   if (dest == src)
1930     return 1;
1931
1932   /* if one of them is null then don't match */
1933   if (!dest || !src)
1934     return 0;
1935
1936   /* if both of them have rname match on rname */
1937   if (dest->rname[0] && src->rname[0])
1938     return (!strcmp (dest->rname, src->rname));
1939
1940   /* otherwise match on name */
1941   return (!strcmp (dest->name, src->name));
1942 }
1943
1944 void PT(sym_link *type)
1945 {
1946         printTypeChain(type,0);
1947 }
1948 /*-----------------------------------------------------------------*/
1949 /* printTypeChain - prints the type chain in human readable form   */
1950 /*-----------------------------------------------------------------*/
1951 void
1952 printTypeChain (sym_link * start, FILE * of)
1953 {
1954   int nlr = 0;
1955   sym_link * type, * search;
1956   STORAGE_CLASS scls;
1957
1958   if (!of)
1959     {
1960       of = stdout;
1961       nlr = 1;
1962     }
1963
1964   if (start==NULL) {
1965     fprintf (of, "void");
1966     return;
1967   }
1968
1969   /* Print the chain as it is written in the source: */
1970   /* start with the last entry.                      */
1971   /* However, the storage class at the end of the    */
1972   /* chain reall applies to the first in the chain!  */
1973
1974   for (type = start; type && type->next; type = type->next)
1975     ;
1976   scls=SPEC_SCLS(type);
1977   while (type)
1978     {
1979       if (type==start) {
1980         switch (scls) 
1981           {
1982           case S_DATA: fprintf (of, "data-"); break;
1983           case S_XDATA: fprintf (of, "xdata-"); break;
1984           case S_SFR: fprintf (of, "sfr-"); break;
1985           case S_SBIT: fprintf (of, "sbit-"); break;
1986           case S_CODE: fprintf (of, "code-"); break;
1987           case S_IDATA: fprintf (of, "idata-"); break;
1988           case S_PDATA: fprintf (of, "pdata-"); break;
1989           case S_LITERAL: fprintf (of, "literal-"); break;
1990           case S_STACK: fprintf (of, "stack-"); break;
1991           case S_XSTACK: fprintf (of, "xstack-"); break;
1992           case S_BIT: fprintf (of, "bit-"); break;
1993           case S_EEPROM: fprintf (of, "eeprom-"); break;
1994           default: break;
1995           }
1996       }
1997
1998       if (IS_DECL (type))
1999         {
2000           if (!IS_FUNC(type)) {
2001             if (DCL_PTR_VOLATILE (type)) {
2002               fprintf (of, "volatile-");
2003             }
2004             if (DCL_PTR_CONST (type)) {
2005               fprintf (of, "const-");
2006             }
2007           }
2008           switch (DCL_TYPE (type))
2009             {
2010             case FUNCTION:
2011               fprintf (of, "function %s %s", 
2012                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2013                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2014               break;
2015             case GPOINTER:
2016               fprintf (of, "generic* ");
2017               break;
2018             case CPOINTER:
2019               fprintf (of, "code* ");
2020               break;
2021             case FPOINTER:
2022               fprintf (of, "xdata* ");
2023               break;
2024             case EEPPOINTER:
2025               fprintf (of, "eeprom* ");
2026               break;
2027             case POINTER:
2028               fprintf (of, "near* ");
2029               break;
2030             case IPOINTER:
2031               fprintf (of, "idata* ");
2032               break;
2033             case PPOINTER:
2034               fprintf (of, "pdata* ");
2035               break;
2036             case UPOINTER:
2037               fprintf (of, "unkown* ");
2038               break;
2039             case ARRAY:
2040               if (DCL_ELEM(type)) {
2041                 fprintf (of, "[%d] ", DCL_ELEM(type));
2042               } else {
2043                 fprintf (of, "[] ");
2044               }
2045               break;
2046             }
2047         }
2048       else
2049         {
2050           if (SPEC_VOLATILE (type))
2051             fprintf (of, "volatile-");
2052           if (SPEC_CONST (type))
2053             fprintf (of, "const-");
2054           if (SPEC_USIGN (type))
2055             fprintf (of, "unsigned-");
2056           switch (SPEC_NOUN (type))
2057             {
2058             case V_INT:
2059               if (IS_LONG (type))
2060                 fprintf (of, "long-");
2061               fprintf (of, "int");
2062               break;
2063
2064             case V_CHAR:
2065               fprintf (of, "char");
2066               break;
2067
2068             case V_VOID:
2069               fprintf (of, "void");
2070               break;
2071
2072             case V_FLOAT:
2073               fprintf (of, "float");
2074               break;
2075
2076             case V_STRUCT:
2077               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2078               break;
2079
2080             case V_SBIT:
2081               fprintf (of, "sbit");
2082               break;
2083
2084             case V_BIT:
2085               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2086               break;
2087
2088             case V_DOUBLE:
2089               fprintf (of, "double");
2090               break;
2091
2092             default:
2093               fprintf (of, "unknown type");
2094               break;
2095             }
2096         }
2097       /* search entry in list before "type" */
2098       for (search = start; search && search->next != type;)
2099         search = search->next;
2100       type = search;
2101       if (type)
2102         fputc (' ', of);
2103     }
2104   if (nlr)
2105     fprintf (of, "\n");
2106 }
2107
2108
2109 /*-----------------------------------------------------------------*/
2110 /* powof2 - returns power of two for the number if number is pow 2 */
2111 /*-----------------------------------------------------------------*/
2112 int 
2113 powof2 (unsigned long num)
2114 {
2115   int nshifts = 0;
2116   int n1s = 0;
2117
2118   while (num)
2119     {
2120       if (num & 1)
2121         n1s++;
2122       num >>= 1;
2123       nshifts++;
2124     }
2125
2126   if (n1s > 1 || nshifts == 0)
2127     return 0;
2128   return nshifts - 1;
2129 }
2130
2131 symbol *__fsadd;
2132 symbol *__fssub;
2133 symbol *__fsmul;
2134 symbol *__fsdiv;
2135 symbol *__fseq;
2136 symbol *__fsneq;
2137 symbol *__fslt;
2138 symbol *__fslteq;
2139 symbol *__fsgt;
2140 symbol *__fsgteq;
2141
2142 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2143 symbol *__muldiv[3][3][2];
2144 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2145 sym_link *__multypes[3][2];
2146 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2147 symbol *__conv[2][3][2];
2148 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2149 symbol *__rlrr[2][3][2];
2150
2151 sym_link *floatType;
2152
2153 static char *
2154 _mangleFunctionName(char *in)
2155 {
2156   if (port->getMangledFunctionName) 
2157     {
2158       return port->getMangledFunctionName(in);
2159     }
2160   else
2161     {
2162       return in;
2163     }
2164 }
2165
2166 /*-----------------------------------------------------------------*/
2167 /* typeFromStr - create a typechain from an encoded string         */
2168 /* basic types -        'c' - char                                 */
2169 /*                      's' - short                                */
2170 /*                      'i' - int                                  */
2171 /*                      'l' - long                                 */
2172 /*                      'f' - float                                */
2173 /*                      'v' - void                                 */
2174 /*                      '*' - pointer - default (GPOINTER)         */
2175 /* modifiers -          'u' - unsigned                             */
2176 /* pointer modifiers -  'g' - generic                              */
2177 /*                      'x' - xdata                                */
2178 /*                      'p' - code                                 */
2179 /*                      'd' - data                                 */                     
2180 /*                      'F' - function                             */                     
2181 /* examples : "ig*" - generic int *                                */
2182 /*            "cx*" - char xdata *                                 */
2183 /*            "ui" -  unsigned int                                 */
2184 /*-----------------------------------------------------------------*/
2185 sym_link *typeFromStr (char *s)
2186 {
2187     sym_link *r = newLink(DECLARATOR);
2188     int usign = 0;
2189
2190     do {
2191         sym_link *nr;
2192         switch (*s) {
2193         case 'u' : 
2194             usign = 1;
2195             s++;
2196             continue ;
2197             break ;
2198         case 'c':
2199             r->class = SPECIFIER;
2200             SPEC_NOUN(r) = V_CHAR;
2201             break;
2202         case 's':
2203         case 'i':
2204             r->class = SPECIFIER;
2205             SPEC_NOUN(r) = V_INT;
2206             break;
2207         case 'l':
2208             r->class = SPECIFIER;
2209             SPEC_NOUN(r) = V_INT;
2210             SPEC_LONG(r) = 1;
2211             break;
2212         case 'f':
2213             r->class = SPECIFIER;
2214             SPEC_NOUN(r) = V_FLOAT;
2215             break;
2216         case 'v':
2217             r->class = SPECIFIER;
2218             SPEC_NOUN(r) = V_VOID;
2219             break;
2220         case '*':
2221             DCL_TYPE(r) = port->unqualified_pointer;
2222             break;
2223         case 'g':
2224         case 'x':
2225         case 'p':
2226         case 'd':
2227         case 'F':
2228             assert(*(s+1)=='*');
2229             nr = newLink(DECLARATOR);
2230             nr->next = r;
2231             r = nr;
2232             switch (*s) {
2233             case 'g':
2234                 DCL_TYPE(r) = GPOINTER;
2235                 break;
2236             case 'x':
2237                 DCL_TYPE(r) = FPOINTER;
2238                 break;
2239             case 'p':
2240                 DCL_TYPE(r) = CPOINTER;
2241                 break;
2242             case 'd':
2243                 DCL_TYPE(r) = POINTER;
2244                 break;
2245             case 'F':
2246                 DCL_TYPE(r) = FUNCTION;
2247                 nr = newLink(DECLARATOR);
2248                 nr->next = r;
2249                 r = nr;
2250                 DCL_TYPE(r) = CPOINTER;
2251                 break;
2252             }
2253             s++;
2254             break;
2255         default:
2256             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2257                    "typeFromStr: unknown type");
2258             break;
2259         }
2260         if (IS_SPEC(r) && usign) {
2261             SPEC_USIGN(r) = 1;
2262             usign = 0;
2263         }
2264         s++;
2265     } while (*s);
2266     return r;
2267 }
2268
2269 /*-----------------------------------------------------------------*/
2270 /* initCSupport - create functions for C support routines          */
2271 /*-----------------------------------------------------------------*/
2272 void 
2273 initCSupport ()
2274 {
2275   const char *smuldivmod[] =
2276   {
2277     "mul", "div", "mod"
2278   };
2279   const char *sbwd[] =
2280   {
2281     "char", "int", "long"
2282   };
2283   const char *ssu[] =
2284   {
2285     "s", "u"
2286   };
2287   const char *srlrr[] =
2288   {
2289     "rl", "rr"
2290   };
2291
2292   int bwd, su, muldivmod, tofrom, rlrr;
2293
2294   if (getenv("SDCC_NO_C_SUPPORT")) {
2295     /* for debugging only */
2296     return;
2297   }
2298
2299   floatType = newFloatLink ();
2300
2301   for (bwd = 0; bwd < 3; bwd++)
2302     {
2303       sym_link *l = NULL;
2304       switch (bwd)
2305         {
2306         case 0:
2307           l = newCharLink ();
2308           break;
2309         case 1:
2310           l = newIntLink ();
2311           break;
2312         case 2:
2313           l = newLongLink ();
2314           break;
2315         default:
2316           assert (0);
2317         }
2318       __multypes[bwd][0] = l;
2319       __multypes[bwd][1] = copyLinkChain (l);
2320       SPEC_USIGN (__multypes[bwd][1]) = 1;
2321     }
2322
2323   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2324   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2325   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2326   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2327   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2328   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2329   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2330   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2331   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2332   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2333
2334   for (tofrom = 0; tofrom < 2; tofrom++)
2335     {
2336       for (bwd = 0; bwd < 3; bwd++)
2337         {
2338           for (su = 0; su < 2; su++)
2339             {
2340               if (tofrom)
2341                 {
2342                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2343                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2344                 }
2345               else
2346                 {
2347                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2348                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2349                 }
2350             }
2351         }
2352     }
2353
2354 /*
2355   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2356     {
2357       for (bwd = 0; bwd < 3; bwd++)
2358         {
2359           for (su = 0; su < 2; su++)
2360             {
2361               SNPRINTF (buffer, sizeof(buffer),
2362                         "_%s%s%s",
2363                        smuldivmod[muldivmod],
2364                        ssu[su],
2365                        sbwd[bwd]);
2366               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2367               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2368             }
2369         }
2370     }
2371
2372   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2373   Therefore they've been merged into mulint() and mullong().
2374 */
2375
2376   for (bwd = 0; bwd < 3; bwd++)
2377     {
2378       for (su = 0; su < 2; su++)
2379         {
2380           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2381             {
2382               /* div and mod */
2383               SNPRINTF (buffer, sizeof(buffer),
2384                         "_%s%s%s",
2385                        smuldivmod[muldivmod],
2386                        ssu[su],
2387                        sbwd[bwd]);
2388               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2389               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2390             }
2391         }
2392     }
2393   /* mul only */
2394   muldivmod = 0;
2395   /* byte */
2396   bwd = 0;
2397   for (su = 0; su < 2; su++)
2398     {
2399       /* muluchar and mulschar are still separate functions, because e.g. the z80
2400          port is sign/zero-extending to int before calling mulint() */
2401       SNPRINTF (buffer, sizeof(buffer),
2402                 "_%s%s%s",
2403                 smuldivmod[muldivmod],
2404                 ssu[su],
2405                 sbwd[bwd]);
2406       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2407       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2408     }
2409   /* signed only */
2410   su = 0;
2411   /* word and doubleword */
2412   for (bwd = 1; bwd < 3; bwd++)
2413     {
2414       /* mul, int/long */
2415       SNPRINTF (buffer, sizeof(buffer),
2416                 "_%s%s",
2417                 smuldivmod[muldivmod],
2418                 sbwd[bwd]);
2419       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2420       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2421       /* signed = unsigned */
2422       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
2423     }
2424
2425   for (rlrr = 0; rlrr < 2; rlrr++)
2426     {
2427       for (bwd = 0; bwd < 3; bwd++)
2428         {
2429           for (su = 0; su < 2; su++)
2430             {
2431               SNPRINTF (buffer, sizeof(buffer),
2432                         "_%s%s%s",
2433                        srlrr[rlrr],
2434                        ssu[su],
2435                        sbwd[bwd]);
2436               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2437               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2438             }
2439         }
2440     }
2441 }
2442
2443 /*-----------------------------------------------------------------*/
2444 /* initBuiltIns - create prototypes for builtin functions          */
2445 /*-----------------------------------------------------------------*/
2446 void initBuiltIns()
2447 {
2448     int i;
2449     symbol *sym;
2450
2451     if (!port->builtintable) return ;
2452
2453     for (i = 0 ; port->builtintable[i].name ; i++) {
2454         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2455                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2456         FUNC_ISBUILTIN(sym->type) = 1;
2457         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2458     }
2459 }
2460
2461 sym_link *validateLink(sym_link         *l, 
2462                         const char      *macro,
2463                         const char      *args,
2464                         const char      select,
2465                         const char      *file, 
2466                         unsigned        line)
2467 {    
2468   if (l && l->class==select)
2469     {
2470         return l;
2471     }
2472     fprintf(stderr, 
2473             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2474             " expected %s, got %s\n",
2475             macro, args, file, line, 
2476             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2477     exit(-1);
2478     return l; // never reached, makes compiler happy.
2479 }