Fixed numerous bitfield problems.
[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         if (su == UNION) {
1070             sum = 0;
1071             bitOffset = 0;
1072         }
1073         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1074
1075         /* if this is a bit field  */
1076         if (loop->bitVar) {
1077
1078             /* change it to a unsigned bit */
1079             SPEC_NOUN (loop->etype) = V_BIT;
1080             SPEC_USIGN (loop->etype) = 1;
1081             SPEC_BLEN (loop->etype) = loop->bitVar;
1082
1083             if (loop->bitVar == BITVAR_PAD) {
1084                 /* A zero length bitfield forces padding */
1085                 SPEC_BSTR (loop->etype) = bitOffset;
1086                 SPEC_BLEN (loop->etype) = 0;
1087                 bitOffset = 8;
1088                 loop->offset = sum;
1089             }
1090             else {
1091                 if (bitOffset == 8) {
1092                     bitOffset = 0;
1093                     sum++;
1094                 }
1095                 /* check if this fit into the remaining   */
1096                 /* bits of this byte else align it to the */
1097                 /* next byte boundary                     */
1098                 if (loop->bitVar <= (8 - bitOffset)) {
1099                     /* fits into current byte */
1100                     loop->offset = sum;
1101                     SPEC_BSTR (loop->etype) = bitOffset;
1102                     bitOffset += loop->bitVar;
1103                 }
1104                 else if (!bitOffset) {
1105                     /* does not fit, but is already byte aligned */
1106                     loop->offset = sum;
1107                     SPEC_BSTR (loop->etype) = bitOffset;
1108                     bitOffset += loop->bitVar;
1109                 } 
1110                 else {
1111                     /* does not fit; need to realign first */
1112                     sum++;
1113                     loop->offset = (su == UNION ? sum = 0 : sum);
1114                     bitOffset = 0;
1115                     SPEC_BSTR (loop->etype) = bitOffset;
1116                     bitOffset += loop->bitVar;
1117                 }
1118                 while (bitOffset>8) {
1119                     bitOffset -= 8;
1120                     sum++;
1121                 } 
1122             }
1123         }
1124         else {
1125             /* This is a non-bit field. Make sure we are */
1126             /* byte aligned first */
1127             if (bitOffset) {
1128                 sum++;
1129                 loop->offset = (su == UNION ? sum = 0 : sum);
1130                 bitOffset = 0;
1131             }
1132             loop->offset = sum;
1133             checkDecl (loop, 1);
1134             sum += getSize (loop->type);
1135         }
1136
1137         loop = loop->next;
1138
1139         /* if union then size = sizeof larget field */
1140         if (su == UNION) {
1141             /* For UNION, round up after each field */
1142             sum += ((bitOffset+7)/8);
1143             usum = max (usum, sum);
1144         }
1145
1146     }
1147     
1148     /* For STRUCT, round up after all fields processed */
1149     if (su != UNION)
1150         sum += ((bitOffset+7)/8);
1151
1152     return (su == UNION ? usum : sum);
1153 }
1154
1155 /*------------------------------------------------------------------*/
1156 /* checkSClass - check the storage class specification              */
1157 /*------------------------------------------------------------------*/
1158 static void 
1159 checkSClass (symbol * sym, int isProto)
1160 {
1161   if (getenv("DEBUG_SANITY")) {
1162     fprintf (stderr, "checkSClass: %s \n", sym->name);
1163   }
1164   
1165   /* type is literal can happen foe enums change
1166      to auto */
1167   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1168     SPEC_SCLS (sym->etype) = S_AUTO;
1169   
1170   /* if sfr or sbit then must also be volatile */
1171   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1172       SPEC_SCLS (sym->etype) == S_SFR)
1173     {
1174       SPEC_VOLATILE (sym->etype) = 1;
1175     }
1176   
1177   /* if absolute address given then it mark it as
1178      volatile -- except in the PIC port */
1179
1180 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1181   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1182   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1183 #endif
1184
1185     if (IS_ABSOLUTE (sym->etype))
1186       SPEC_VOLATILE (sym->etype) = 1;
1187   
1188
1189   /* global variables declared const put into code */
1190   /* if no other storage class specified */
1191   if (sym->level == 0 &&
1192       SPEC_CONST (sym->etype) &&
1193       SPEC_SCLS(sym->etype) == S_FIXED &&
1194       !IS_FUNC(sym->type)) {
1195     SPEC_SCLS (sym->etype) = S_CODE;
1196   }
1197
1198   /* global variable in code space is a constant */
1199   if (sym->level == 0 &&
1200       SPEC_SCLS (sym->etype) == S_CODE &&
1201       port->mem.code_ro) {
1202     if (IS_SPEC(sym->type)) {
1203       SPEC_CONST (sym->type) = 1;
1204     } else {
1205       DCL_PTR_CONST (sym->type) = 1;
1206     }
1207   }
1208
1209   /* if bit variable then no storage class can be */
1210   /* specified since bit is already a storage */
1211   if (IS_BITVAR (sym->etype) &&
1212       (SPEC_SCLS (sym->etype) != S_FIXED &&
1213        SPEC_SCLS (sym->etype) != S_SBIT &&
1214        SPEC_SCLS (sym->etype) != S_BIT)
1215     )
1216     {
1217       werror (E_BITVAR_STORAGE, sym->name);
1218       SPEC_SCLS (sym->etype) = S_FIXED;
1219     }
1220
1221   /* extern variables cannot be initialized */
1222   if (IS_EXTERN (sym->etype) && sym->ival)
1223     {
1224       werror (E_EXTERN_INIT, sym->name);
1225       sym->ival = NULL;
1226     }
1227
1228   /* if this is an atomatic symbol */
1229   if (sym->level && (options.stackAuto || reentrant)) {
1230     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1231          SPEC_SCLS (sym->etype) == S_FIXED ||
1232          SPEC_SCLS (sym->etype) == S_REGISTER ||
1233          SPEC_SCLS (sym->etype) == S_STACK ||
1234          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1235       SPEC_SCLS (sym->etype) = S_AUTO;
1236     } else {
1237       /* storage class may only be specified for statics */
1238       if (!IS_STATIC(sym->etype)) {
1239         werror (E_AUTO_ASSUMED, sym->name);
1240       }
1241     }
1242   }
1243   
1244   /* automatic symbols cannot be given   */
1245   /* an absolute address ignore it      */
1246   if (sym->level &&
1247       SPEC_ABSA (sym->etype) &&
1248       (options.stackAuto || reentrant))
1249     {
1250       werror (E_AUTO_ABSA, sym->name);
1251       SPEC_ABSA (sym->etype) = 0;
1252     }
1253
1254   /* arrays & pointers cannot be defined for bits   */
1255   /* SBITS or SFRs or BIT                           */
1256   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1257       (SPEC_NOUN (sym->etype) == V_BIT ||
1258        SPEC_NOUN (sym->etype) == V_SBIT ||
1259        SPEC_SCLS (sym->etype) == S_SFR))
1260     werror (E_BIT_ARRAY, sym->name);
1261
1262   /* if this is a bit|sbit then set length & start  */
1263   if (SPEC_NOUN (sym->etype) == V_BIT ||
1264       SPEC_NOUN (sym->etype) == V_SBIT)
1265     {
1266       SPEC_BLEN (sym->etype) = 1;
1267       SPEC_BSTR (sym->etype) = 0;
1268     }
1269
1270   if (!isProto) {
1271     /* variables declared in CODE space must have */
1272     /* initializers if not an extern */
1273     if (SPEC_SCLS (sym->etype) == S_CODE &&
1274         sym->ival == NULL &&
1275         //!sym->level &&
1276         port->mem.code_ro &&
1277         !IS_EXTERN (sym->etype) &&
1278         !funcInChain (sym->type))
1279       werror (E_CODE_NO_INIT, sym->name);
1280   }
1281
1282   /* if parameter or local variable then change */
1283   /* the storage class to reflect where the var will go */
1284   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1285       !IS_STATIC(sym->etype))
1286     {
1287       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1288         {
1289           SPEC_SCLS (sym->etype) = (options.useXstack ?
1290                                     S_XSTACK : S_STACK);
1291         }
1292       else
1293         {
1294           /* hack-o-matic! I see no reason why the useXstack option should ever
1295            * control this allcoation, but the code was originally that way, and
1296            * changing it for non-390 ports breaks the compiler badly.
1297            */
1298           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1299                 1 : options.useXstack;
1300           SPEC_SCLS (sym->etype) = (useXdata ?
1301                                     S_XDATA : S_FIXED);
1302         }
1303     }
1304 }
1305
1306 /*------------------------------------------------------------------*/
1307 /* changePointer - change pointer to functions                      */
1308 /*------------------------------------------------------------------*/
1309 void 
1310 changePointer (symbol * sym)
1311 {
1312   sym_link *p;
1313
1314   /* go thru the chain of declarations   */
1315   /* if we find a pointer to a function  */
1316   /* unconditionally change it to a ptr  */
1317   /* to code area                        */
1318   for (p = sym->type; p; p = p->next)
1319     {
1320       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1321         DCL_TYPE (p) = port->unqualified_pointer;
1322       if (IS_PTR (p) && IS_FUNC (p->next))
1323         DCL_TYPE (p) = CPOINTER;
1324     }
1325 }
1326
1327 /*------------------------------------------------------------------*/
1328 /* checkDecl - does semantic validation of a declaration                   */
1329 /*------------------------------------------------------------------*/
1330 int 
1331 checkDecl (symbol * sym, int isProto)
1332 {
1333
1334   checkSClass (sym, isProto);           /* check the storage class      */
1335   changePointer (sym);          /* change pointers if required */
1336
1337   /* if this is an array without any dimension
1338      then update the dimension from the initial value */
1339   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1340     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1341
1342   return 0;
1343 }
1344
1345 /*------------------------------------------------------------------*/
1346 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1347 /*------------------------------------------------------------------*/
1348 sym_link *
1349 copyLinkChain (sym_link * p)
1350 {
1351   sym_link *head, *curr, *loop;
1352
1353   curr = p;
1354   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1355   while (curr)
1356     {
1357       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1358       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1359       loop = loop->next;
1360       curr = curr->next;
1361     }
1362
1363   return head;
1364 }
1365
1366
1367 /*------------------------------------------------------------------*/
1368 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1369 /*                symbols in the given block                        */
1370 /*------------------------------------------------------------------*/
1371 void 
1372 cleanUpBlock (bucket ** table, int block)
1373 {
1374   int i;
1375   bucket *chain;
1376
1377   /* go thru the entire  table  */
1378   for (i = 0; i < 256; i++)
1379     {
1380       for (chain = table[i]; chain; chain = chain->next)
1381         {
1382           if (chain->block >= block)
1383             {
1384               deleteSym (table, chain->sym, chain->name);
1385             }
1386         }
1387     }
1388 }
1389
1390 /*------------------------------------------------------------------*/
1391 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1392 /*                symbols in the given level                        */
1393 /*------------------------------------------------------------------*/
1394 void 
1395 cleanUpLevel (bucket ** table, int level)
1396 {
1397   int i;
1398   bucket *chain;
1399
1400   /* go thru the entire  table  */
1401   for (i = 0; i < 256; i++)
1402     {
1403       for (chain = table[i]; chain; chain = chain->next)
1404         {
1405           if (chain->level >= level)
1406             {
1407               deleteSym (table, chain->sym, chain->name);
1408             }
1409         }
1410     }
1411 }
1412
1413 /*------------------------------------------------------------------*/
1414 /* computeType - computes the resultant type from two types         */
1415 /*------------------------------------------------------------------*/
1416 sym_link *
1417 computeType (sym_link * type1, sym_link * type2)
1418 {
1419   sym_link *rType;
1420   sym_link *reType;
1421   sym_link *etype1 = getSpec (type1);
1422   sym_link *etype2 = getSpec (type2);
1423
1424   /* if one of them is a float then result is a float */
1425   /* here we assume that the types passed are okay */
1426   /* and can be cast to one another                */
1427   /* which ever is greater in size */
1428   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1429     rType = newFloatLink ();
1430   else
1431     /* if only one of them is a bit variable
1432        then the other one prevails */
1433   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1434     rType = copyLinkChain (type2);
1435   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1436     rType = copyLinkChain (type1);
1437   else
1438     /* if one of them is a pointer or array then that
1439        prevails */
1440   if (IS_PTR (type1) || IS_ARRAY (type1))
1441     rType = copyLinkChain (type1);
1442   else if (IS_PTR (type2) || IS_ARRAY (type2))
1443     rType = copyLinkChain (type2);
1444   else if (getSize (type1) > getSize (type2))
1445     rType = copyLinkChain (type1);
1446   else
1447     rType = copyLinkChain (type2);
1448
1449   reType = getSpec (rType);
1450
1451   /* if either of them unsigned but not val then make this unsigned */
1452   if (((/*!IS_LITERAL(type1) &&*/ SPEC_USIGN (etype1)) ||
1453        (/*!IS_LITERAL(type2) &&*/ SPEC_USIGN (etype2))) &&
1454       !IS_FLOAT (reType))
1455     SPEC_USIGN (reType) = 1;
1456   else
1457     SPEC_USIGN (reType) = 0;
1458
1459   /* if result is a literal then make not so */
1460   if (IS_LITERAL (reType))
1461     SPEC_SCLS (reType) = S_REGISTER;
1462
1463   return rType;
1464 }
1465
1466 /*--------------------------------------------------------------------*/
1467 /* compareType - will do type check return 1 if match, -1 if castable */
1468 /*--------------------------------------------------------------------*/
1469 int
1470 compareType (sym_link * dest, sym_link * src)
1471 {
1472   if (!dest && !src)
1473     return 1;
1474
1475   if (dest && !src)
1476     return 0;
1477
1478   if (src && !dest)
1479     return 0;
1480
1481   /* if dest is a declarator then */
1482   if (IS_DECL (dest))
1483     {
1484       if (IS_DECL (src))
1485         {
1486           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1487             if (IS_FUNC(src)) {
1488               //checkFunction(src,dest);
1489             }
1490             return compareType (dest->next, src->next);
1491           }
1492           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1493             return 1;
1494           }
1495           if (IS_PTR (src) && IS_GENPTR (dest))
1496             return -1;
1497           if (IS_PTR (dest) && IS_ARRAY (src)) {
1498             value *val=aggregateToPointer (valFromType(src));
1499             int res=compareType (dest, val->type);
1500             Safe_free(val->type);
1501             Safe_free(val);
1502             return res;
1503           }
1504           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1505             return compareType (dest->next, src);
1506           return 0;
1507         }
1508       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1509         return -1;
1510       else
1511         return 0;
1512     }
1513
1514   /* if one is a specifier and the other is not */
1515   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1516       (IS_SPEC (dest) && !IS_SPEC (src)))
1517     return 0;
1518
1519   /* if one of them is a void then ok */
1520   if (SPEC_NOUN (dest) == V_VOID &&
1521       SPEC_NOUN (src) != V_VOID)
1522     return -1;
1523
1524   if (SPEC_NOUN (dest) != V_VOID &&
1525       SPEC_NOUN (src) == V_VOID)
1526     return -1;
1527
1528   /* if they are both bitfields then if the lengths
1529      and starts don't match */
1530   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1531       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1532        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1533     return -1;
1534
1535   /* it is a specifier */
1536   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1537     {
1538       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1539           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1540           getSize (dest) == getSize (src))
1541         return 1;
1542       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1543         return -1;
1544       else
1545         return 0;
1546     }
1547   else if (IS_STRUCT (dest))
1548     {
1549       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1550         return 0;
1551       else
1552         return 1;
1553     }
1554   if (SPEC_LONG (dest) != SPEC_LONG (src))
1555     return -1;
1556
1557   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1558     return -1;
1559
1560   return 1;
1561 }
1562
1563 /*------------------------------------------------------------------*/
1564 /* inCalleeSaveList - return 1 if found in callee save list          */
1565 /*------------------------------------------------------------------*/
1566 static int
1567 calleeCmp(void *p1, void *p2)
1568 {
1569   return (strcmp((char *)p1, (char *)(p2)) == 0);
1570 }
1571
1572 bool
1573 inCalleeSaveList(char *s)
1574 {
1575   if (options.all_callee_saves)
1576     return 1;
1577   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
1578 }
1579
1580 /*-----------------------------------------------------------------*/
1581 /* aggregateToPointer:  change an agggregate type function      */
1582 /*         argument to a pointer to that type.     */
1583 /*-----------------------------------------------------------------*/
1584 value *
1585 aggregateToPointer (value * val)
1586 {
1587   if (IS_AGGREGATE (val->type))
1588     {
1589       /* if this is a structure */
1590       /* then we need to add a new link */
1591       if (IS_STRUCT (val->type))
1592         {
1593           /* first lets add DECLARATOR type */
1594           sym_link *p = val->type;
1595
1596           werror (W_STRUCT_AS_ARG, val->name);
1597           val->type = newLink (DECLARATOR);
1598           val->type->next = p;
1599         }
1600
1601       /* change to a pointer depending on the */
1602       /* storage class specified        */
1603       switch (SPEC_SCLS (val->etype))
1604         {
1605         case S_IDATA:
1606           DCL_TYPE (val->type) = IPOINTER;
1607           break;
1608         case S_PDATA:
1609           DCL_TYPE (val->type) = PPOINTER;
1610           break;
1611         case S_FIXED:
1612           if (SPEC_OCLS(val->etype)) {
1613             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1614           } else {
1615             // this happens for (external) function parameters
1616             DCL_TYPE (val->type) = port->unqualified_pointer;
1617           }
1618           break;
1619         case S_AUTO:
1620         case S_DATA:
1621         case S_REGISTER:
1622           DCL_TYPE (val->type) = POINTER;
1623           break;
1624         case S_CODE:
1625           DCL_TYPE (val->type) = CPOINTER;
1626           break;
1627         case S_XDATA:
1628           DCL_TYPE (val->type) = FPOINTER;
1629           break;
1630         case S_EEPROM:
1631           DCL_TYPE (val->type) = EEPPOINTER;
1632           break;
1633         default:
1634           DCL_TYPE (val->type) = port->unqualified_pointer;
1635         }
1636       
1637       /* is there is a symbol associated then */
1638       /* change the type of the symbol as well */
1639       if (val->sym)
1640         {
1641           val->sym->type = copyLinkChain (val->type);
1642           val->sym->etype = getSpec (val->sym->type);
1643         }
1644     }
1645   return val;
1646 }
1647 /*------------------------------------------------------------------*/
1648 /* checkFunction - does all kinds of check on a function            */
1649 /*------------------------------------------------------------------*/
1650 int 
1651 checkFunction (symbol * sym, symbol *csym)
1652 {
1653   value *exargs, *acargs;
1654   value *checkValue;
1655   int argCnt = 0;
1656
1657   if (getenv("DEBUG_SANITY")) {
1658     fprintf (stderr, "checkFunction: %s ", sym->name);
1659   }
1660
1661   /* make sure the type is complete and sane */
1662   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1663
1664   /* if not type then some kind of error */
1665   if (!sym->type)
1666     return 0;
1667
1668   /* if the function has no type then make it return int */
1669   if (!sym->type->next)
1670     sym->type->next = sym->etype = newIntLink ();
1671
1672   /* function cannot return aggregate */
1673   if (IS_AGGREGATE (sym->type->next))
1674     {
1675       werror (E_FUNC_AGGR, sym->name);
1676       return 0;
1677     }
1678
1679   /* function cannot return bit */
1680   if (IS_BITVAR (sym->type->next))
1681     {
1682       werror (E_FUNC_BIT, sym->name);
1683       return 0;
1684     }
1685
1686   /* check if this function is defined as calleeSaves
1687      then mark it as such */
1688   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1689
1690   /* if interrupt service routine  */
1691   /* then it cannot have arguments */
1692   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1693     {
1694       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1695         werror (E_INT_ARGS, sym->name);
1696         FUNC_ARGS(sym->type)=NULL;
1697       }
1698     }
1699
1700   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1701        acargs; 
1702        acargs=acargs->next, argCnt++) {
1703     if (!acargs->sym) { 
1704       // this can happen for reentrant functions
1705       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1706       // the show must go on: synthesize a name and symbol
1707       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
1708       acargs->sym = newSymbol (acargs->name, 1);
1709       SPEC_OCLS (acargs->etype) = istack;
1710       acargs->sym->type = copyLinkChain (acargs->type);
1711       acargs->sym->etype = getSpec (acargs->sym->type);
1712       acargs->sym->_isparm = 1;
1713       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
1714     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
1715       // synthesized name
1716       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1717     }
1718   }
1719
1720   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1721     return 1;                   /* not defined nothing more to check  */
1722
1723   /* check if body already present */
1724   if (csym && IFFUNC_HASBODY(csym->type))
1725     {
1726       werror (E_FUNC_BODY, sym->name);
1727       return 0;
1728     }
1729
1730   /* check the return value type   */
1731   if (compareType (csym->type, sym->type) <= 0)
1732     {
1733       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1734       printFromToType(csym->type, sym->type);
1735       return 0;
1736     }
1737
1738   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1739     {
1740       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1741     }
1742
1743   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1744     {
1745       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1746     }
1747
1748   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1749     {
1750       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1751     }
1752
1753   /* compare expected args with actual args */
1754   exargs = FUNC_ARGS(csym->type);
1755   acargs = FUNC_ARGS(sym->type);
1756
1757   /* for all the expected args do */
1758   for (argCnt = 1;
1759        exargs && acargs;
1760        exargs = exargs->next, acargs = acargs->next, argCnt++)
1761     {
1762       if (getenv("DEBUG_SANITY")) {
1763         fprintf (stderr, "checkFunction: %s ", exargs->name);
1764       }
1765       /* make sure the type is complete and sane */
1766       checkTypeSanity(exargs->etype, exargs->name);
1767
1768       /* If the actual argument is an array, any prototype
1769        * will have modified it to a pointer. Duplicate that
1770        * change here.
1771        */
1772       if (IS_AGGREGATE (acargs->type))
1773         {
1774           checkValue = copyValue (acargs);
1775           aggregateToPointer (checkValue);
1776         }
1777       else
1778         {
1779           checkValue = acargs;
1780         }
1781
1782       if (compareType (exargs->type, checkValue->type) <= 0)
1783         {
1784           werror (E_ARG_TYPE, argCnt);
1785           printFromToType(exargs->type, checkValue->type);
1786           return 0;
1787         }
1788     }
1789
1790   /* if one them ended we have a problem */
1791   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1792       (!exargs && acargs && !IS_VOID (acargs->type)))
1793     werror (E_ARG_COUNT);
1794
1795   /* replace with this defition */
1796   sym->cdef = csym->cdef;
1797   deleteSym (SymbolTab, csym, csym->name);
1798   deleteFromSeg(csym);
1799   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1800   if (IS_EXTERN (csym->etype) && !
1801       IS_EXTERN (sym->etype))
1802     {
1803       addSet (&publics, sym);
1804     }
1805   return 1;
1806 }
1807
1808 /*------------------------------------------------------------------*/
1809 /* cdbStructBlock - calls struct printing for a blcks               */
1810 /*------------------------------------------------------------------*/
1811 void cdbStructBlock (int block)
1812 {
1813   int i;
1814   bucket **table = StructTab;
1815   bucket *chain;
1816
1817   /* go thru the entire  table  */
1818   for (i = 0; i < 256; i++)
1819     {
1820       for (chain = table[i]; chain; chain = chain->next)
1821         {
1822           if (chain->block >= block)
1823             {
1824               if(debugFile)
1825                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
1826             }
1827         }
1828     }
1829 }
1830
1831 /*-----------------------------------------------------------------*/
1832 /* processFuncArgs - does some processing with function args       */
1833 /*-----------------------------------------------------------------*/
1834 void 
1835 processFuncArgs (symbol * func)
1836 {
1837   value *val;
1838   int pNum = 1;
1839   sym_link *funcType=func->type;
1840
1841   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1842     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1843
1844   // if this is a pointer to a function
1845   if (IS_PTR(funcType)) {
1846     funcType=funcType->next;
1847   }
1848
1849   /* if this function has variable argument list */
1850   /* then make the function a reentrant one    */
1851   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1852     FUNC_ISREENT(funcType)=1;
1853
1854   /* check if this function is defined as calleeSaves
1855      then mark it as such */
1856   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1857
1858   /* loop thru all the arguments   */
1859   val = FUNC_ARGS(funcType);
1860
1861   /* if it is void then remove parameters */
1862   if (val && IS_VOID (val->type))
1863     {
1864       FUNC_ARGS(funcType) = NULL;
1865       return;
1866     }
1867
1868   /* reset regparm for the port */
1869   (*port->reset_regparms) ();
1870   /* if any of the arguments is an aggregate */
1871   /* change it to pointer to the same type */
1872   while (val)
1873     {
1874         int argreg = 0;
1875       /* mark it as a register parameter if
1876          the function does not have VA_ARG
1877          and as port dictates */
1878       if (!IFFUNC_HASVARARGS(funcType) &&
1879           (argreg = (*port->reg_parm) (val->type)))
1880         {
1881           SPEC_REGPARM (val->etype) = 1;
1882           SPEC_ARGREG(val->etype) = argreg;
1883         } else if (IFFUNC_ISREENT(funcType)) {
1884             FUNC_HASSTACKPARM(funcType) = 1;
1885         }
1886
1887       if (IS_AGGREGATE (val->type))
1888         {
1889           aggregateToPointer (val);
1890         }
1891
1892       val = val->next;
1893       pNum++;
1894     }
1895
1896   /* if this is an internal generated function call */
1897   if (func->cdef) {
1898     /* ignore --stack-auto for this one, we don't know how it is compiled */
1899     /* simply trust on --int-long-reent or --float-reent */
1900     if (IFFUNC_ISREENT(funcType)) {
1901       return;
1902     }
1903   } else {
1904     /* if this function is reentrant or */
1905     /* automatics r 2b stacked then nothing */
1906     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1907       return;
1908   }
1909
1910   val = FUNC_ARGS(funcType);
1911   pNum = 1;
1912   while (val)
1913     {
1914
1915       /* if a symbolname is not given  */
1916       /* synthesize a variable name */
1917       if (!val->sym)
1918         {
1919           SNPRINTF (val->name, sizeof(val->name), 
1920                     "_%s_PARM_%d", func->name, pNum++);
1921           val->sym = newSymbol (val->name, 1);
1922           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1923           val->sym->type = copyLinkChain (val->type);
1924           val->sym->etype = getSpec (val->sym->type);
1925           val->sym->_isparm = 1;
1926           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1927           if (IS_SPEC(func->etype)) {
1928             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1929               SPEC_STAT (func->etype);
1930           }
1931           addSymChain (val->sym);
1932
1933         }
1934       else                      /* symbol name given create synth name */
1935         {
1936
1937           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
1938           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1939           val->sym->_isparm = 1;
1940           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1941             (options.model != MODEL_SMALL ? xdata : data);
1942           if (IS_SPEC(func->etype)) {
1943             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1944               SPEC_STAT (func->etype);
1945           }
1946         }
1947       if (!isinSet(operKeyReset, val->sym)) {
1948         addSet (&operKeyReset, val->sym);
1949         applyToSet (operKeyReset, resetParmKey);
1950       }
1951       val = val->next;
1952     }
1953 }
1954
1955 /*-----------------------------------------------------------------*/
1956 /* isSymbolEqual - compares two symbols return 1 if they match     */
1957 /*-----------------------------------------------------------------*/
1958 int 
1959 isSymbolEqual (symbol * dest, symbol * src)
1960 {
1961   /* if pointers match then equal */
1962   if (dest == src)
1963     return 1;
1964
1965   /* if one of them is null then don't match */
1966   if (!dest || !src)
1967     return 0;
1968
1969   /* if both of them have rname match on rname */
1970   if (dest->rname[0] && src->rname[0])
1971     return (!strcmp (dest->rname, src->rname));
1972
1973   /* otherwise match on name */
1974   return (!strcmp (dest->name, src->name));
1975 }
1976
1977 void PT(sym_link *type)
1978 {
1979         printTypeChain(type,0);
1980 }
1981 /*-----------------------------------------------------------------*/
1982 /* printTypeChain - prints the type chain in human readable form   */
1983 /*-----------------------------------------------------------------*/
1984 void
1985 printTypeChain (sym_link * start, FILE * of)
1986 {
1987   int nlr = 0;
1988   sym_link * type, * search;
1989   STORAGE_CLASS scls;
1990
1991   if (!of)
1992     {
1993       of = stdout;
1994       nlr = 1;
1995     }
1996
1997   if (start==NULL) {
1998     fprintf (of, "void");
1999     return;
2000   }
2001
2002   /* Print the chain as it is written in the source: */
2003   /* start with the last entry.                      */
2004   /* However, the storage class at the end of the    */
2005   /* chain reall applies to the first in the chain!  */
2006
2007   for (type = start; type && type->next; type = type->next)
2008     ;
2009   scls=SPEC_SCLS(type);
2010   while (type)
2011     {
2012       if (type==start) {
2013         switch (scls) 
2014           {
2015           case S_DATA: fprintf (of, "data-"); break;
2016           case S_XDATA: fprintf (of, "xdata-"); break;
2017           case S_SFR: fprintf (of, "sfr-"); break;
2018           case S_SBIT: fprintf (of, "sbit-"); break;
2019           case S_CODE: fprintf (of, "code-"); break;
2020           case S_IDATA: fprintf (of, "idata-"); break;
2021           case S_PDATA: fprintf (of, "pdata-"); break;
2022           case S_LITERAL: fprintf (of, "literal-"); break;
2023           case S_STACK: fprintf (of, "stack-"); break;
2024           case S_XSTACK: fprintf (of, "xstack-"); break;
2025           case S_BIT: fprintf (of, "bit-"); break;
2026           case S_EEPROM: fprintf (of, "eeprom-"); break;
2027           default: break;
2028           }
2029       }
2030
2031       if (IS_DECL (type))
2032         {
2033           if (!IS_FUNC(type)) {
2034             if (DCL_PTR_VOLATILE (type)) {
2035               fprintf (of, "volatile-");
2036             }
2037             if (DCL_PTR_CONST (type)) {
2038               fprintf (of, "const-");
2039             }
2040           }
2041           switch (DCL_TYPE (type))
2042             {
2043             case FUNCTION:
2044               fprintf (of, "function %s %s", 
2045                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2046                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2047               break;
2048             case GPOINTER:
2049               fprintf (of, "generic* ");
2050               break;
2051             case CPOINTER:
2052               fprintf (of, "code* ");
2053               break;
2054             case FPOINTER:
2055               fprintf (of, "xdata* ");
2056               break;
2057             case EEPPOINTER:
2058               fprintf (of, "eeprom* ");
2059               break;
2060             case POINTER:
2061               fprintf (of, "near* ");
2062               break;
2063             case IPOINTER:
2064               fprintf (of, "idata* ");
2065               break;
2066             case PPOINTER:
2067               fprintf (of, "pdata* ");
2068               break;
2069             case UPOINTER:
2070               fprintf (of, "unkown* ");
2071               break;
2072             case ARRAY:
2073               if (DCL_ELEM(type)) {
2074                 fprintf (of, "[%d] ", DCL_ELEM(type));
2075               } else {
2076                 fprintf (of, "[] ");
2077               }
2078               break;
2079             }
2080         }
2081       else
2082         {
2083           if (SPEC_VOLATILE (type))
2084             fprintf (of, "volatile-");
2085           if (SPEC_CONST (type))
2086             fprintf (of, "const-");
2087           if (SPEC_USIGN (type))
2088             fprintf (of, "unsigned-");
2089           switch (SPEC_NOUN (type))
2090             {
2091             case V_INT:
2092               if (IS_LONG (type))
2093                 fprintf (of, "long-");
2094               fprintf (of, "int");
2095               break;
2096
2097             case V_CHAR:
2098               fprintf (of, "char");
2099               break;
2100
2101             case V_VOID:
2102               fprintf (of, "void");
2103               break;
2104
2105             case V_FLOAT:
2106               fprintf (of, "float");
2107               break;
2108
2109             case V_STRUCT:
2110               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2111               break;
2112
2113             case V_SBIT:
2114               fprintf (of, "sbit");
2115               break;
2116
2117             case V_BIT:
2118               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2119               break;
2120
2121             case V_DOUBLE:
2122               fprintf (of, "double");
2123               break;
2124
2125             default:
2126               fprintf (of, "unknown type");
2127               break;
2128             }
2129         }
2130       /* search entry in list before "type" */
2131       for (search = start; search && search->next != type;)
2132         search = search->next;
2133       type = search;
2134       if (type)
2135         fputc (' ', of);
2136     }
2137   if (nlr)
2138     fprintf (of, "\n");
2139 }
2140
2141
2142 /*-----------------------------------------------------------------*/
2143 /* powof2 - returns power of two for the number if number is pow 2 */
2144 /*-----------------------------------------------------------------*/
2145 int 
2146 powof2 (unsigned long num)
2147 {
2148   int nshifts = 0;
2149   int n1s = 0;
2150
2151   while (num)
2152     {
2153       if (num & 1)
2154         n1s++;
2155       num >>= 1;
2156       nshifts++;
2157     }
2158
2159   if (n1s > 1 || nshifts == 0)
2160     return 0;
2161   return nshifts - 1;
2162 }
2163
2164 symbol *__fsadd;
2165 symbol *__fssub;
2166 symbol *__fsmul;
2167 symbol *__fsdiv;
2168 symbol *__fseq;
2169 symbol *__fsneq;
2170 symbol *__fslt;
2171 symbol *__fslteq;
2172 symbol *__fsgt;
2173 symbol *__fsgteq;
2174
2175 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2176 symbol *__muldiv[3][3][2];
2177 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2178 sym_link *__multypes[3][2];
2179 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2180 symbol *__conv[2][3][2];
2181 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2182 symbol *__rlrr[2][3][2];
2183
2184 sym_link *floatType;
2185
2186 static char *
2187 _mangleFunctionName(char *in)
2188 {
2189   if (port->getMangledFunctionName) 
2190     {
2191       return port->getMangledFunctionName(in);
2192     }
2193   else
2194     {
2195       return in;
2196     }
2197 }
2198
2199 /*-----------------------------------------------------------------*/
2200 /* typeFromStr - create a typechain from an encoded string         */
2201 /* basic types -        'c' - char                                 */
2202 /*                      's' - short                                */
2203 /*                      'i' - int                                  */
2204 /*                      'l' - long                                 */
2205 /*                      'f' - float                                */
2206 /*                      'v' - void                                 */
2207 /*                      '*' - pointer - default (GPOINTER)         */
2208 /* modifiers -          'u' - unsigned                             */
2209 /* pointer modifiers -  'g' - generic                              */
2210 /*                      'x' - xdata                                */
2211 /*                      'p' - code                                 */
2212 /*                      'd' - data                                 */                     
2213 /*                      'F' - function                             */                     
2214 /* examples : "ig*" - generic int *                                */
2215 /*            "cx*" - char xdata *                                 */
2216 /*            "ui" -  unsigned int                                 */
2217 /*-----------------------------------------------------------------*/
2218 sym_link *typeFromStr (char *s)
2219 {
2220     sym_link *r = newLink(DECLARATOR);
2221     int usign = 0;
2222
2223     do {
2224         sym_link *nr;
2225         switch (*s) {
2226         case 'u' : 
2227             usign = 1;
2228             s++;
2229             continue ;
2230             break ;
2231         case 'c':
2232             r->class = SPECIFIER;
2233             SPEC_NOUN(r) = V_CHAR;
2234             break;
2235         case 's':
2236         case 'i':
2237             r->class = SPECIFIER;
2238             SPEC_NOUN(r) = V_INT;
2239             break;
2240         case 'l':
2241             r->class = SPECIFIER;
2242             SPEC_NOUN(r) = V_INT;
2243             SPEC_LONG(r) = 1;
2244             break;
2245         case 'f':
2246             r->class = SPECIFIER;
2247             SPEC_NOUN(r) = V_FLOAT;
2248             break;
2249         case 'v':
2250             r->class = SPECIFIER;
2251             SPEC_NOUN(r) = V_VOID;
2252             break;
2253         case '*':
2254             DCL_TYPE(r) = port->unqualified_pointer;
2255             break;
2256         case 'g':
2257         case 'x':
2258         case 'p':
2259         case 'd':
2260         case 'F':
2261             assert(*(s+1)=='*');
2262             nr = newLink(DECLARATOR);
2263             nr->next = r;
2264             r = nr;
2265             switch (*s) {
2266             case 'g':
2267                 DCL_TYPE(r) = GPOINTER;
2268                 break;
2269             case 'x':
2270                 DCL_TYPE(r) = FPOINTER;
2271                 break;
2272             case 'p':
2273                 DCL_TYPE(r) = CPOINTER;
2274                 break;
2275             case 'd':
2276                 DCL_TYPE(r) = POINTER;
2277                 break;
2278             case 'F':
2279                 DCL_TYPE(r) = FUNCTION;
2280                 nr = newLink(DECLARATOR);
2281                 nr->next = r;
2282                 r = nr;
2283                 DCL_TYPE(r) = CPOINTER;
2284                 break;
2285             }
2286             s++;
2287             break;
2288         default:
2289             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2290                    "typeFromStr: unknown type");
2291             break;
2292         }
2293         if (IS_SPEC(r) && usign) {
2294             SPEC_USIGN(r) = 1;
2295             usign = 0;
2296         }
2297         s++;
2298     } while (*s);
2299     return r;
2300 }
2301
2302 /*-----------------------------------------------------------------*/
2303 /* initCSupport - create functions for C support routines          */
2304 /*-----------------------------------------------------------------*/
2305 void 
2306 initCSupport ()
2307 {
2308   const char *smuldivmod[] =
2309   {
2310     "mul", "div", "mod"
2311   };
2312   const char *sbwd[] =
2313   {
2314     "char", "int", "long"
2315   };
2316   const char *ssu[] =
2317   {
2318     "s", "u"
2319   };
2320   const char *srlrr[] =
2321   {
2322     "rl", "rr"
2323   };
2324
2325   int bwd, su, muldivmod, tofrom, rlrr;
2326
2327   if (getenv("SDCC_NO_C_SUPPORT")) {
2328     /* for debugging only */
2329     return;
2330   }
2331
2332   floatType = newFloatLink ();
2333
2334   for (bwd = 0; bwd < 3; bwd++)
2335     {
2336       sym_link *l = NULL;
2337       switch (bwd)
2338         {
2339         case 0:
2340           l = newCharLink ();
2341           break;
2342         case 1:
2343           l = newIntLink ();
2344           break;
2345         case 2:
2346           l = newLongLink ();
2347           break;
2348         default:
2349           assert (0);
2350         }
2351       __multypes[bwd][0] = l;
2352       __multypes[bwd][1] = copyLinkChain (l);
2353       SPEC_USIGN (__multypes[bwd][1]) = 1;
2354     }
2355
2356   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2357   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2358   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2359   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2360   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2361   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2362   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2363   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2364   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2365   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2366
2367   for (tofrom = 0; tofrom < 2; tofrom++)
2368     {
2369       for (bwd = 0; bwd < 3; bwd++)
2370         {
2371           for (su = 0; su < 2; su++)
2372             {
2373               if (tofrom)
2374                 {
2375                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2376                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2377                 }
2378               else
2379                 {
2380                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2381                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2382                 }
2383             }
2384         }
2385     }
2386
2387 /*
2388   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2389     {
2390       for (bwd = 0; bwd < 3; bwd++)
2391         {
2392           for (su = 0; su < 2; su++)
2393             {
2394               SNPRINTF (buffer, sizeof(buffer),
2395                         "_%s%s%s",
2396                        smuldivmod[muldivmod],
2397                        ssu[su],
2398                        sbwd[bwd]);
2399               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2400               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2401             }
2402         }
2403     }
2404
2405   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2406   Therefore they've been merged into mulint() and mullong().
2407 */
2408
2409   for (bwd = 0; bwd < 3; bwd++)
2410     {
2411       for (su = 0; su < 2; su++)
2412         {
2413           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2414             {
2415               /* div and mod */
2416               SNPRINTF (buffer, sizeof(buffer),
2417                         "_%s%s%s",
2418                        smuldivmod[muldivmod],
2419                        ssu[su],
2420                        sbwd[bwd]);
2421               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2422               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2423             }
2424         }
2425     }
2426   /* mul only */
2427   muldivmod = 0;
2428   /* byte */
2429   bwd = 0;
2430   for (su = 0; su < 2; su++)
2431     {
2432       /* muluchar and mulschar are still separate functions, because e.g. the z80
2433          port is sign/zero-extending to int before calling mulint() */
2434       SNPRINTF (buffer, sizeof(buffer),
2435                 "_%s%s%s",
2436                 smuldivmod[muldivmod],
2437                 ssu[su],
2438                 sbwd[bwd]);
2439       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2440       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2441     }
2442   /* signed only */
2443   su = 0;
2444   /* word and doubleword */
2445   for (bwd = 1; bwd < 3; bwd++)
2446     {
2447       /* mul, int/long */
2448       SNPRINTF (buffer, sizeof(buffer),
2449                 "_%s%s",
2450                 smuldivmod[muldivmod],
2451                 sbwd[bwd]);
2452       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2453       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2454       /* signed = unsigned */
2455       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
2456     }
2457
2458   for (rlrr = 0; rlrr < 2; rlrr++)
2459     {
2460       for (bwd = 0; bwd < 3; bwd++)
2461         {
2462           for (su = 0; su < 2; su++)
2463             {
2464               SNPRINTF (buffer, sizeof(buffer),
2465                         "_%s%s%s",
2466                        srlrr[rlrr],
2467                        ssu[su],
2468                        sbwd[bwd]);
2469               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2470               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2471             }
2472         }
2473     }
2474 }
2475
2476 /*-----------------------------------------------------------------*/
2477 /* initBuiltIns - create prototypes for builtin functions          */
2478 /*-----------------------------------------------------------------*/
2479 void initBuiltIns()
2480 {
2481     int i;
2482     symbol *sym;
2483
2484     if (!port->builtintable) return ;
2485
2486     for (i = 0 ; port->builtintable[i].name ; i++) {
2487         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2488                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2489         FUNC_ISBUILTIN(sym->type) = 1;
2490         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2491     }
2492 }
2493
2494 sym_link *validateLink(sym_link         *l, 
2495                         const char      *macro,
2496                         const char      *args,
2497                         const char      select,
2498                         const char      *file, 
2499                         unsigned        line)
2500 {    
2501   if (l && l->class==select)
2502     {
2503         return l;
2504     }
2505     fprintf(stderr, 
2506             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2507             " expected %s, got %s\n",
2508             macro, args, file, line, 
2509             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2510     exit(-1);
2511     return l; // never reached, makes compiler happy.
2512 }