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