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