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