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