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