PIC16 - Applied patch from Vangelis Rokas. Many fixes for the PIC16 port.
[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 = yylineno;      /* 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 bool 
1534 inCalleeSaveList (char *s)
1535 {
1536   int i;
1537
1538   if (options.all_callee_saves) return 1;
1539   for (i = 0; options.calleeSaves[i]; i++)
1540     if (strcmp (options.calleeSaves[i], s) == 0)
1541       return 1;
1542
1543   return 0;
1544 }
1545
1546 /*-----------------------------------------------------------------*/
1547 /* aggregateToPointer:  change an agggregate type function      */
1548 /*         argument to a pointer to that type.     */
1549 /*-----------------------------------------------------------------*/
1550 value *
1551 aggregateToPointer (value * val)
1552 {
1553   if (IS_AGGREGATE (val->type))
1554     {
1555       /* if this is a structure */
1556       /* then we need to add a new link */
1557       if (IS_STRUCT (val->type))
1558         {
1559           /* first lets add DECLARATOR type */
1560           sym_link *p = val->type;
1561
1562           werror (W_STRUCT_AS_ARG, val->name);
1563           val->type = newLink (DECLARATOR);
1564           val->type->next = p;
1565         }
1566
1567       /* change to a pointer depending on the */
1568       /* storage class specified        */
1569       switch (SPEC_SCLS (val->etype))
1570         {
1571         case S_IDATA:
1572           DCL_TYPE (val->type) = IPOINTER;
1573           break;
1574         case S_PDATA:
1575           DCL_TYPE (val->type) = PPOINTER;
1576           break;
1577         case S_FIXED:
1578           if (SPEC_OCLS(val->etype)) {
1579             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1580           } else {
1581             // this happens for (external) function parameters
1582             DCL_TYPE (val->type) = port->unqualified_pointer;
1583           }
1584           break;
1585         case S_AUTO:
1586         case S_DATA:
1587         case S_REGISTER:
1588           DCL_TYPE (val->type) = POINTER;
1589           break;
1590         case S_CODE:
1591           DCL_TYPE (val->type) = CPOINTER;
1592           break;
1593         case S_XDATA:
1594           DCL_TYPE (val->type) = FPOINTER;
1595           break;
1596         case S_EEPROM:
1597           DCL_TYPE (val->type) = EEPPOINTER;
1598           break;
1599         default:
1600           DCL_TYPE (val->type) = port->unqualified_pointer;
1601         }
1602       
1603       /* is there is a symbol associated then */
1604       /* change the type of the symbol as well */
1605       if (val->sym)
1606         {
1607           val->sym->type = copyLinkChain (val->type);
1608           val->sym->etype = getSpec (val->sym->type);
1609         }
1610     }
1611   return val;
1612 }
1613 /*------------------------------------------------------------------*/
1614 /* checkFunction - does all kinds of check on a function            */
1615 /*------------------------------------------------------------------*/
1616 int 
1617 checkFunction (symbol * sym, symbol *csym)
1618 {
1619   value *exargs, *acargs;
1620   value *checkValue;
1621   int argCnt = 0;
1622
1623   if (getenv("DEBUG_SANITY")) {
1624     fprintf (stderr, "checkFunction: %s ", sym->name);
1625   }
1626
1627   /* make sure the type is complete and sane */
1628   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1629
1630   /* if not type then some kind of error */
1631   if (!sym->type)
1632     return 0;
1633
1634   /* if the function has no type then make it return int */
1635   if (!sym->type->next)
1636     sym->type->next = sym->etype = newIntLink ();
1637
1638   /* function cannot return aggregate */
1639   if (IS_AGGREGATE (sym->type->next))
1640     {
1641       werror (E_FUNC_AGGR, sym->name);
1642       return 0;
1643     }
1644
1645   /* function cannot return bit */
1646   if (IS_BITVAR (sym->type->next))
1647     {
1648       werror (E_FUNC_BIT, sym->name);
1649       return 0;
1650     }
1651
1652   /* check if this function is defined as calleeSaves
1653      then mark it as such */
1654   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1655
1656   /* if interrupt service routine  */
1657   /* then it cannot have arguments */
1658   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1659     {
1660       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1661         werror (E_INT_ARGS, sym->name);
1662         FUNC_ARGS(sym->type)=NULL;
1663       }
1664     }
1665
1666   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1667        acargs; 
1668        acargs=acargs->next, argCnt++) {
1669     if (!acargs->sym) { 
1670       // this can happen for reentrant functions
1671       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1672       // the show must go on: synthesize a name and symbol
1673       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
1674       acargs->sym = newSymbol (acargs->name, 1);
1675       SPEC_OCLS (acargs->etype) = istack;
1676       acargs->sym->type = copyLinkChain (acargs->type);
1677       acargs->sym->etype = getSpec (acargs->sym->type);
1678       acargs->sym->_isparm = 1;
1679       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
1680     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
1681       // synthesized name
1682       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1683     }
1684   }
1685
1686   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1687     return 1;                   /* not defined nothing more to check  */
1688
1689   /* check if body already present */
1690   if (csym && IFFUNC_HASBODY(csym->type))
1691     {
1692       werror (E_FUNC_BODY, sym->name);
1693       return 0;
1694     }
1695
1696   /* check the return value type   */
1697   if (compareType (csym->type, sym->type) <= 0)
1698     {
1699       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1700       printFromToType(csym->type, sym->type);
1701       return 0;
1702     }
1703
1704   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1705     {
1706       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1707     }
1708
1709   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1710     {
1711       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1712     }
1713
1714   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1715     {
1716       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1717     }
1718
1719   /* compare expected args with actual args */
1720   exargs = FUNC_ARGS(csym->type);
1721   acargs = FUNC_ARGS(sym->type);
1722
1723   /* for all the expected args do */
1724   for (argCnt = 1;
1725        exargs && acargs;
1726        exargs = exargs->next, acargs = acargs->next, argCnt++)
1727     {
1728       if (getenv("DEBUG_SANITY")) {
1729         fprintf (stderr, "checkFunction: %s ", exargs->name);
1730       }
1731       /* make sure the type is complete and sane */
1732       checkTypeSanity(exargs->etype, exargs->name);
1733
1734       /* If the actual argument is an array, any prototype
1735        * will have modified it to a pointer. Duplicate that
1736        * change here.
1737        */
1738       if (IS_AGGREGATE (acargs->type))
1739         {
1740           checkValue = copyValue (acargs);
1741           aggregateToPointer (checkValue);
1742         }
1743       else
1744         {
1745           checkValue = acargs;
1746         }
1747
1748       if (compareType (exargs->type, checkValue->type) <= 0)
1749         {
1750           werror (E_ARG_TYPE, argCnt);
1751           printFromToType(exargs->type, checkValue->type);
1752           return 0;
1753         }
1754     }
1755
1756   /* if one them ended we have a problem */
1757   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1758       (!exargs && acargs && !IS_VOID (acargs->type)))
1759     werror (E_ARG_COUNT);
1760
1761   /* replace with this defition */
1762   sym->cdef = csym->cdef;
1763   deleteSym (SymbolTab, csym, csym->name);
1764   deleteFromSeg(csym);
1765   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1766   if (IS_EXTERN (csym->etype) && !
1767       IS_EXTERN (sym->etype))
1768     {
1769       addSet (&publics, sym);
1770     }
1771   return 1;
1772 }
1773
1774 /*------------------------------------------------------------------*/
1775 /* cdbStructBlock - calls struct printing for a blcks               */
1776 /*------------------------------------------------------------------*/
1777 void cdbStructBlock (int block)
1778 {
1779   int i;
1780   bucket **table = StructTab;
1781   bucket *chain;
1782
1783   /* go thru the entire  table  */
1784   for (i = 0; i < 256; i++)
1785     {
1786       for (chain = table[i]; chain; chain = chain->next)
1787         {
1788           if (chain->block >= block)
1789             {
1790               if(debugFile)
1791                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
1792             }
1793         }
1794     }
1795 }
1796
1797 /*-----------------------------------------------------------------*/
1798 /* processFuncArgs - does some processing with function args       */
1799 /*-----------------------------------------------------------------*/
1800 void 
1801 processFuncArgs (symbol * func)
1802 {
1803   value *val;
1804   int pNum = 1;
1805   sym_link *funcType=func->type;
1806
1807   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1808     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1809
1810   // if this is a pointer to a function
1811   if (IS_PTR(funcType)) {
1812     funcType=funcType->next;
1813   }
1814
1815   /* if this function has variable argument list */
1816   /* then make the function a reentrant one    */
1817   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1818     FUNC_ISREENT(funcType)=1;
1819
1820   /* check if this function is defined as calleeSaves
1821      then mark it as such */
1822   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1823
1824   /* loop thru all the arguments   */
1825   val = FUNC_ARGS(funcType);
1826
1827   /* if it is void then remove parameters */
1828   if (val && IS_VOID (val->type))
1829     {
1830       FUNC_ARGS(funcType) = NULL;
1831       return;
1832     }
1833
1834   /* reset regparm for the port */
1835   (*port->reset_regparms) ();
1836   /* if any of the arguments is an aggregate */
1837   /* change it to pointer to the same type */
1838   while (val)
1839     {
1840         int argreg = 0;
1841       /* mark it as a register parameter if
1842          the function does not have VA_ARG
1843          and as port dictates */
1844       if (!IFFUNC_HASVARARGS(funcType) &&
1845           (argreg = (*port->reg_parm) (val->type)))
1846         {
1847           SPEC_REGPARM (val->etype) = 1;
1848           SPEC_ARGREG(val->etype) = argreg;
1849         } else if (IFFUNC_ISREENT(funcType)) {
1850             FUNC_HASSTACKPARM(funcType) = 1;
1851         }
1852
1853       if (IS_AGGREGATE (val->type))
1854         {
1855           aggregateToPointer (val);
1856         }
1857
1858       val = val->next;
1859       pNum++;
1860     }
1861
1862   /* if this is an internal generated function call */
1863   if (func->cdef) {
1864     /* ignore --stack-auto for this one, we don't know how it is compiled */
1865     /* simply trust on --int-long-reent or --float-reent */
1866     if (IFFUNC_ISREENT(funcType)) {
1867       return;
1868     }
1869   } else {
1870     /* if this function is reentrant or */
1871     /* automatics r 2b stacked then nothing */
1872     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1873       return;
1874   }
1875
1876   val = FUNC_ARGS(funcType);
1877   pNum = 1;
1878   while (val)
1879     {
1880
1881       /* if a symbolname is not given  */
1882       /* synthesize a variable name */
1883       if (!val->sym)
1884         {
1885           SNPRINTF (val->name, sizeof(val->name), 
1886                     "_%s_PARM_%d", func->name, pNum++);
1887           val->sym = newSymbol (val->name, 1);
1888           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1889           val->sym->type = copyLinkChain (val->type);
1890           val->sym->etype = getSpec (val->sym->type);
1891           val->sym->_isparm = 1;
1892           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1893           if (IS_SPEC(func->etype)) {
1894             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1895               SPEC_STAT (func->etype);
1896           }
1897           addSymChain (val->sym);
1898
1899         }
1900       else                      /* symbol name given create synth name */
1901         {
1902
1903           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
1904           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1905           val->sym->_isparm = 1;
1906           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1907             (options.model != MODEL_SMALL ? xdata : data);
1908           if (IS_SPEC(func->etype)) {
1909             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1910               SPEC_STAT (func->etype);
1911           }
1912         }
1913       if (!isinSet(operKeyReset, val->sym)) {
1914         addSet (&operKeyReset, val->sym);
1915         applyToSet (operKeyReset, resetParmKey);
1916       }
1917       val = val->next;
1918     }
1919 }
1920
1921 /*-----------------------------------------------------------------*/
1922 /* isSymbolEqual - compares two symbols return 1 if they match     */
1923 /*-----------------------------------------------------------------*/
1924 int 
1925 isSymbolEqual (symbol * dest, symbol * src)
1926 {
1927   /* if pointers match then equal */
1928   if (dest == src)
1929     return 1;
1930
1931   /* if one of them is null then don't match */
1932   if (!dest || !src)
1933     return 0;
1934
1935   /* if both of them have rname match on rname */
1936   if (dest->rname[0] && src->rname[0])
1937     return (!strcmp (dest->rname, src->rname));
1938
1939   /* otherwise match on name */
1940   return (!strcmp (dest->name, src->name));
1941 }
1942
1943 void PT(sym_link *type)
1944 {
1945         printTypeChain(type,0);
1946 }
1947 /*-----------------------------------------------------------------*/
1948 /* printTypeChain - prints the type chain in human readable form   */
1949 /*-----------------------------------------------------------------*/
1950 void
1951 printTypeChain (sym_link * start, FILE * of)
1952 {
1953   int nlr = 0;
1954   sym_link * type, * search;
1955   STORAGE_CLASS scls;
1956
1957   if (!of)
1958     {
1959       of = stdout;
1960       nlr = 1;
1961     }
1962
1963   if (start==NULL) {
1964     fprintf (of, "void");
1965     return;
1966   }
1967
1968   /* Print the chain as it is written in the source: */
1969   /* start with the last entry.                      */
1970   /* However, the storage class at the end of the    */
1971   /* chain reall applies to the first in the chain!  */
1972
1973   for (type = start; type && type->next; type = type->next)
1974     ;
1975   scls=SPEC_SCLS(type);
1976   while (type)
1977     {
1978       if (type==start) {
1979         switch (scls) 
1980           {
1981           case S_DATA: fprintf (of, "data-"); break;
1982           case S_XDATA: fprintf (of, "xdata-"); break;
1983           case S_SFR: fprintf (of, "sfr-"); break;
1984           case S_SBIT: fprintf (of, "sbit-"); break;
1985           case S_CODE: fprintf (of, "code-"); break;
1986           case S_IDATA: fprintf (of, "idata-"); break;
1987           case S_PDATA: fprintf (of, "pdata-"); break;
1988           case S_LITERAL: fprintf (of, "literal-"); break;
1989           case S_STACK: fprintf (of, "stack-"); break;
1990           case S_XSTACK: fprintf (of, "xstack-"); break;
1991           case S_BIT: fprintf (of, "bit-"); break;
1992           case S_EEPROM: fprintf (of, "eeprom-"); break;
1993           default: break;
1994           }
1995       }
1996
1997       if (IS_DECL (type))
1998         {
1999           if (!IS_FUNC(type)) {
2000             if (DCL_PTR_VOLATILE (type)) {
2001               fprintf (of, "volatile-");
2002             }
2003             if (DCL_PTR_CONST (type)) {
2004               fprintf (of, "const-");
2005             }
2006           }
2007           switch (DCL_TYPE (type))
2008             {
2009             case FUNCTION:
2010               fprintf (of, "function %s %s", 
2011                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2012                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2013               break;
2014             case GPOINTER:
2015               fprintf (of, "generic* ");
2016               break;
2017             case CPOINTER:
2018               fprintf (of, "code* ");
2019               break;
2020             case FPOINTER:
2021               fprintf (of, "xdata* ");
2022               break;
2023             case EEPPOINTER:
2024               fprintf (of, "eeprom* ");
2025               break;
2026             case POINTER:
2027               fprintf (of, "near* ");
2028               break;
2029             case IPOINTER:
2030               fprintf (of, "idata* ");
2031               break;
2032             case PPOINTER:
2033               fprintf (of, "pdata* ");
2034               break;
2035             case UPOINTER:
2036               fprintf (of, "unkown* ");
2037               break;
2038             case ARRAY:
2039               if (DCL_ELEM(type)) {
2040                 fprintf (of, "[%d] ", DCL_ELEM(type));
2041               } else {
2042                 fprintf (of, "[] ");
2043               }
2044               break;
2045             }
2046         }
2047       else
2048         {
2049           if (SPEC_VOLATILE (type))
2050             fprintf (of, "volatile-");
2051           if (SPEC_CONST (type))
2052             fprintf (of, "const-");
2053           if (SPEC_USIGN (type))
2054             fprintf (of, "unsigned-");
2055           switch (SPEC_NOUN (type))
2056             {
2057             case V_INT:
2058               if (IS_LONG (type))
2059                 fprintf (of, "long-");
2060               fprintf (of, "int");
2061               break;
2062
2063             case V_CHAR:
2064               fprintf (of, "char");
2065               break;
2066
2067             case V_VOID:
2068               fprintf (of, "void");
2069               break;
2070
2071             case V_FLOAT:
2072               fprintf (of, "float");
2073               break;
2074
2075             case V_STRUCT:
2076               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2077               break;
2078
2079             case V_SBIT:
2080               fprintf (of, "sbit");
2081               break;
2082
2083             case V_BIT:
2084               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2085               break;
2086
2087             case V_DOUBLE:
2088               fprintf (of, "double");
2089               break;
2090
2091             default:
2092               fprintf (of, "unknown type");
2093               break;
2094             }
2095         }
2096       /* search entry in list before "type" */
2097       for (search = start; search && search->next != type;)
2098         search = search->next;
2099       type = search;
2100       if (type)
2101         fputc (' ', of);
2102     }
2103   if (nlr)
2104     fprintf (of, "\n");
2105 }
2106
2107
2108 /*-----------------------------------------------------------------*/
2109 /* powof2 - returns power of two for the number if number is pow 2 */
2110 /*-----------------------------------------------------------------*/
2111 int 
2112 powof2 (unsigned long num)
2113 {
2114   int nshifts = 0;
2115   int n1s = 0;
2116
2117   while (num)
2118     {
2119       if (num & 1)
2120         n1s++;
2121       num >>= 1;
2122       nshifts++;
2123     }
2124
2125   if (n1s > 1 || nshifts == 0)
2126     return 0;
2127   return nshifts - 1;
2128 }
2129
2130 symbol *__fsadd;
2131 symbol *__fssub;
2132 symbol *__fsmul;
2133 symbol *__fsdiv;
2134 symbol *__fseq;
2135 symbol *__fsneq;
2136 symbol *__fslt;
2137 symbol *__fslteq;
2138 symbol *__fsgt;
2139 symbol *__fsgteq;
2140
2141 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2142 symbol *__muldiv[3][3][2];
2143 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2144 sym_link *__multypes[3][2];
2145 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2146 symbol *__conv[2][3][2];
2147 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2148 symbol *__rlrr[2][3][2];
2149
2150 sym_link *floatType;
2151
2152 static char *
2153 _mangleFunctionName(char *in)
2154 {
2155   if (port->getMangledFunctionName) 
2156     {
2157       return port->getMangledFunctionName(in);
2158     }
2159   else
2160     {
2161       return in;
2162     }
2163 }
2164
2165 /*-----------------------------------------------------------------*/
2166 /* typeFromStr - create a typechain from an encoded string         */
2167 /* basic types -        'c' - char                                 */
2168 /*                      's' - short                                */
2169 /*                      'i' - int                                  */
2170 /*                      'l' - long                                 */
2171 /*                      'f' - float                                */
2172 /*                      'v' - void                                 */
2173 /*                      '*' - pointer - default (GPOINTER)         */
2174 /* modifiers -          'u' - unsigned                             */
2175 /* pointer modifiers -  'g' - generic                              */
2176 /*                      'x' - xdata                                */
2177 /*                      'p' - code                                 */
2178 /*                      'd' - data                                 */                     
2179 /*                      'F' - function                             */                     
2180 /* examples : "ig*" - generic int *                                */
2181 /*            "cx*" - char xdata *                                 */
2182 /*            "ui" -  unsigned int                                 */
2183 /*-----------------------------------------------------------------*/
2184 sym_link *typeFromStr (char *s)
2185 {
2186     sym_link *r = newLink(DECLARATOR);
2187     int usign = 0;
2188
2189     do {
2190         sym_link *nr;
2191         switch (*s) {
2192         case 'u' : 
2193             usign = 1;
2194             s++;
2195             continue ;
2196             break ;
2197         case 'c':
2198             r->class = SPECIFIER;
2199             SPEC_NOUN(r) = V_CHAR;
2200             break;
2201         case 's':
2202         case 'i':
2203             r->class = SPECIFIER;
2204             SPEC_NOUN(r) = V_INT;
2205             break;
2206         case 'l':
2207             r->class = SPECIFIER;
2208             SPEC_NOUN(r) = V_INT;
2209             SPEC_LONG(r) = 1;
2210             break;
2211         case 'f':
2212             r->class = SPECIFIER;
2213             SPEC_NOUN(r) = V_FLOAT;
2214             break;
2215         case 'v':
2216             r->class = SPECIFIER;
2217             SPEC_NOUN(r) = V_VOID;
2218             break;
2219         case '*':
2220             DCL_TYPE(r) = port->unqualified_pointer;
2221             break;
2222         case 'g':
2223         case 'x':
2224         case 'p':
2225         case 'd':
2226         case 'F':
2227             assert(*(s+1)=='*');
2228             nr = newLink(DECLARATOR);
2229             nr->next = r;
2230             r = nr;
2231             switch (*s) {
2232             case 'g':
2233                 DCL_TYPE(r) = GPOINTER;
2234                 break;
2235             case 'x':
2236                 DCL_TYPE(r) = FPOINTER;
2237                 break;
2238             case 'p':
2239                 DCL_TYPE(r) = CPOINTER;
2240                 break;
2241             case 'd':
2242                 DCL_TYPE(r) = POINTER;
2243                 break;
2244             case 'F':
2245                 DCL_TYPE(r) = FUNCTION;
2246                 nr = newLink(DECLARATOR);
2247                 nr->next = r;
2248                 r = nr;
2249                 DCL_TYPE(r) = CPOINTER;
2250                 break;
2251             }
2252             s++;
2253             break;
2254         default:
2255             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2256                    "typeFromStr: unknown type");
2257             break;
2258         }
2259         if (IS_SPEC(r) && usign) {
2260             SPEC_USIGN(r) = 1;
2261             usign = 0;
2262         }
2263         s++;
2264     } while (*s);
2265     return r;
2266 }
2267
2268 /*-----------------------------------------------------------------*/
2269 /* initCSupport - create functions for C support routines          */
2270 /*-----------------------------------------------------------------*/
2271 void 
2272 initCSupport ()
2273 {
2274   const char *smuldivmod[] =
2275   {
2276     "mul", "div", "mod"
2277   };
2278   const char *sbwd[] =
2279   {
2280     "char", "int", "long"
2281   };
2282   const char *ssu[] =
2283   {
2284     "s", "u"
2285   };
2286   const char *srlrr[] =
2287   {
2288     "rl", "rr"
2289   };
2290
2291   int bwd, su, muldivmod, tofrom, rlrr;
2292
2293   if (getenv("SDCC_NO_C_SUPPORT")) {
2294     /* for debugging only */
2295     return;
2296   }
2297
2298   floatType = newFloatLink ();
2299
2300   for (bwd = 0; bwd < 3; bwd++)
2301     {
2302       sym_link *l = NULL;
2303       switch (bwd)
2304         {
2305         case 0:
2306           l = newCharLink ();
2307           break;
2308         case 1:
2309           l = newIntLink ();
2310           break;
2311         case 2:
2312           l = newLongLink ();
2313           break;
2314         default:
2315           assert (0);
2316         }
2317       __multypes[bwd][0] = l;
2318       __multypes[bwd][1] = copyLinkChain (l);
2319       SPEC_USIGN (__multypes[bwd][1]) = 1;
2320     }
2321
2322   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2323   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2324   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2325   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2326   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2327   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2328   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2329   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2330   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2331   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2332
2333   for (tofrom = 0; tofrom < 2; tofrom++)
2334     {
2335       for (bwd = 0; bwd < 3; bwd++)
2336         {
2337           for (su = 0; su < 2; su++)
2338             {
2339               if (tofrom)
2340                 {
2341                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2342                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2343                 }
2344               else
2345                 {
2346                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2347                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2348                 }
2349             }
2350         }
2351     }
2352
2353   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2354     {
2355       for (bwd = 0; bwd < 3; bwd++)
2356         {
2357           for (su = 0; su < 2; su++)
2358             {
2359               SNPRINTF (buffer, sizeof(buffer), 
2360                         "_%s%s%s",
2361                        smuldivmod[muldivmod],
2362                        ssu[su],
2363                        sbwd[bwd]);
2364               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2365               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2366             }
2367         }
2368     }
2369
2370   for (rlrr = 0; rlrr < 2; rlrr++)
2371     {
2372       for (bwd = 0; bwd < 3; bwd++)
2373         {
2374           for (su = 0; su < 2; su++)
2375             {
2376               SNPRINTF (buffer, sizeof(buffer), 
2377                         "_%s%s%s",
2378                        srlrr[rlrr],
2379                        ssu[su],
2380                        sbwd[bwd]);
2381               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2382               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2383             }
2384         }
2385     }
2386 }
2387
2388 /*-----------------------------------------------------------------*/
2389 /* initBuiltIns - create prototypes for builtin functions          */
2390 /*-----------------------------------------------------------------*/
2391 void initBuiltIns()
2392 {
2393     int i;
2394     symbol *sym;
2395
2396     if (!port->builtintable) return ;
2397
2398     for (i = 0 ; port->builtintable[i].name ; i++) {
2399         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2400                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2401         FUNC_ISBUILTIN(sym->type) = 1;
2402         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2403     }
2404 }
2405
2406 sym_link *validateLink(sym_link         *l, 
2407                         const char      *macro,
2408                         const char      *args,
2409                         const char      select,
2410                         const char      *file, 
2411                         unsigned        line)
2412 {    
2413   if (l && l->class==select)
2414     {
2415         return l;
2416     }
2417     fprintf(stderr, 
2418             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2419             " expected %s, got %s\n",
2420             macro, args, file, line, 
2421             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2422     exit(-1);
2423     return l; // never reached, makes compiler happy.
2424 }