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