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