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