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