7ffa31be56e08e7a4b28652d2912aa562db3e4c8
[fw/sdcc] / src / SDCCsymt.c
1 /*-------------------------------------------------------------------------
2   SDCCsymt.c - Code file for Symbols table related structures and MACRO's.
3         Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any
8    later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19    In other words, you are welcome to use, share and improve this program.
20    You are forbidden to forbid anyone else to use, share and improve
21    what you give them.   Help stamp out software-hoarding!
22 -------------------------------------------------------------------------*/
23
24 #include "common.h"
25 #include "newalloc.h"
26
27 value *aggregateToPointer (value *val);
28
29 void printFromToType(sym_link *from, sym_link *to) {
30   fprintf (stderr, "from type '");
31   printTypeChain (from, stderr);
32   fprintf (stderr, "'\nto type '");
33   printTypeChain (to, stderr);
34   fprintf (stderr, "'\n");
35 }
36
37 /* noun strings */
38 char *nounName(sym_link *sl) {
39   switch (SPEC_NOUN(sl)) 
40     {
41     case V_INT: {
42       if (SPEC_LONG(sl)) return "long";
43       if (sl->select.s._short) return "short";
44       return "int";
45     }
46     case V_FLOAT: return "float";
47     case V_CHAR: return "char";
48     case V_VOID: return "void";
49     case V_STRUCT: return "struct";
50     case V_LABEL: return "label";
51     case V_BIT: return "bit";
52     case V_SBIT: return "sbit";
53     case V_DOUBLE: return "double";
54     }
55   return "unknown";
56 };
57
58 bucket *SymbolTab[256];         /* the symbol    table  */
59 bucket *StructTab[256];         /* the structure table  */
60 bucket *TypedefTab[256];        /* the typedef   table  */
61 bucket *LabelTab[256];          /* the Label     table  */
62 bucket *enumTab[256];           /* enumerated    table  */
63
64 /*------------------------------------------------------------------*/
65 /* initSymt () - initialises symbol table related stuff             */
66 /*------------------------------------------------------------------*/
67 void 
68 initSymt ()
69 {
70   int i = 0;
71
72   for (i = 0; i < 256; i++)
73     SymbolTab[i] = StructTab[i] = (void *) NULL;
74
75
76 }
77 /*-----------------------------------------------------------------*/
78 /* newBucket - allocates & returns a new bucket        */
79 /*-----------------------------------------------------------------*/
80 bucket *
81 newBucket ()
82 {
83   bucket *bp;
84
85   bp = Safe_alloc ( sizeof (bucket));
86
87   return bp;
88 }
89
90 /*-----------------------------------------------------------------*/
91 /* hashKey - computes the hashkey given a symbol name              */
92 /*-----------------------------------------------------------------*/
93 int 
94 hashKey (const char *s)
95 {
96   unsigned long key = 0;
97
98   while (*s)
99     key += *s++;
100   return key % 256;
101 }
102
103 /*-----------------------------------------------------------------*/
104 /* addSym - adds a symbol to the hash Table                        */
105 /*-----------------------------------------------------------------*/
106 void 
107 addSym (bucket ** stab,
108         void *sym,
109         char *sname,
110         int level,
111         int block,
112         int checkType)
113 {
114   int i;                        /* index into the hash Table */
115   bucket *bp;                   /* temp bucket    *         */
116
117   if (checkType) {
118     symbol *csym = (symbol *)sym;
119
120     if (getenv("DEBUG_SANITY")) {
121       fprintf (stderr, "addSym: %s ", sname);
122     }
123     /* make sure the type is complete and sane */
124     checkTypeSanity(csym->etype, csym->name);
125   }
126
127   /* prevent overflow of the (r)name buffers */
128   if (strlen(sname)>SDCC_SYMNAME_MAX) {
129     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
130     sname[SDCC_SYMNAME_MAX]='\0';
131   }
132
133   /* the symbols are always added at the head of the list  */
134   i = hashKey (sname);
135   /* get a free entry */
136   bp = Safe_alloc ( sizeof (bucket));
137
138   bp->sym = sym;                /* update the symbol pointer  */
139   bp->level = level;            /* update the nest level      */
140   bp->block = block;
141   strcpy (bp->name, sname);     /* copy the name into place */
142
143   /* if this is the first entry */
144   if (stab[i] == NULL)
145     {
146       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
147       stab[i] = bp;
148     }
149   /* not first entry then add @ head of list */
150   else
151     {
152       bp->prev = NULL;
153       stab[i]->prev = bp;
154       bp->next = stab[i];
155       stab[i] = bp;
156     }
157 }
158
159 /*-----------------------------------------------------------------*/
160 /* deleteSym - deletes a symbol from the hash Table  entry     */
161 /*-----------------------------------------------------------------*/
162 void 
163 deleteSym (bucket ** stab, void *sym, char *sname)
164 {
165   int i = 0;
166   bucket *bp;
167
168   i = hashKey (sname);
169
170   bp = stab[i];
171   /* find the symbol */
172   while (bp)
173     {
174       if (bp->sym == sym)       /* found it then break out */
175         break;                  /* of the loop       */
176       bp = bp->next;
177     }
178
179   if (!bp)                      /* did not find it */
180     return;
181   /* if this is the first one in the chain */
182   if (!bp->prev)
183     {
184       stab[i] = bp->next;
185       if (stab[i])              /* if chain ! empty */
186         stab[i]->prev = (void *) NULL;
187     }
188   /* middle || end of chain */
189   else
190     {
191       if (bp->next)             /* if not end of chain */
192         bp->next->prev = bp->prev;
193
194       bp->prev->next = bp->next;
195     }
196
197 }
198
199 /*-----------------------------------------------------------------*/
200 /* findSym - finds a symbol in a table           */
201 /*-----------------------------------------------------------------*/
202 void *
203 findSym (bucket ** stab, void *sym, const char *sname)
204 {
205   bucket *bp;
206
207   bp = stab[hashKey (sname)];
208   while (bp)
209     {
210       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
211         break;
212       bp = bp->next;
213     }
214
215   return (bp ? bp->sym : (void *) NULL);
216 }
217
218 /*-----------------------------------------------------------------*/
219 /* findSymWithLevel - finds a symbol with a name & level           */
220 /*-----------------------------------------------------------------*/
221 void *
222 findSymWithLevel (bucket ** stab, symbol * sym)
223 {
224   bucket *bp;
225
226   bp = stab[hashKey (sym->name)];
227
228   /**
229    **  do the search from the head of the list since the
230    **  elements are added at the head it is ensured that
231    ** we will find the deeper definitions before we find
232    ** the global ones. we need to check for symbols with
233    ** level <= to the level given, if levels match then block
234    ** numbers need to match as well
235    **/
236   while (bp)
237     {
238       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
239         {
240           /* if this is parameter then nothing else need to be checked */
241           if (((symbol *) (bp->sym))->_isparm)
242             return (bp->sym);
243           /* if levels match then block numbers should also match */
244           if (bp->level && bp->level == sym->level && bp->block == sym->block)
245             return (bp->sym);
246           /* if levels don't match then we are okay */
247           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
248             return (bp->sym);
249           /* if this is a global variable then we are ok too */
250           if (bp->level == 0)
251             return (bp->sym);
252         }
253
254       bp = bp->next;
255     }
256
257   return (void *) NULL;
258 }
259
260 /*-----------------------------------------------------------------*/
261 /* findSymWithBlock - finds a symbol with name in with a block     */
262 /*-----------------------------------------------------------------*/
263 void *
264 findSymWithBlock (bucket ** stab, symbol * sym, int block)
265 {
266   bucket *bp;
267
268   bp = stab[hashKey (sym->name)];
269   while (bp)
270     {
271       if (strcmp (bp->name, sym->name) == 0 &&
272           bp->block <= block)
273         break;
274       bp = bp->next;
275     }
276
277   return (bp ? bp->sym : (void *) NULL);
278 }
279
280 /*------------------------------------------------------------------*/
281 /* newSymbol () - returns a new pointer to a symbol                 */
282 /*------------------------------------------------------------------*/
283 symbol *
284 newSymbol (char *name, int scope)
285 {
286   symbol *sym;
287
288   sym = Safe_alloc ( sizeof (symbol));
289
290   strcpy (sym->name, name);     /* copy the name    */
291   sym->level = scope;           /* set the level    */
292   sym->block = currBlockno;
293   sym->lineDef = yylineno;      /* set the line number */
294   return sym;
295 }
296
297 /*------------------------------------------------------------------*/
298 /* newLink - creates a new link (declarator,specifier)              */
299 /*------------------------------------------------------------------*/
300 sym_link *
301 newLink ()
302 {
303   sym_link *p;
304
305   p = Safe_alloc ( sizeof (sym_link));
306
307   return p;
308 }
309
310 /*------------------------------------------------------------------*/
311 /* newStruct - creats a new structdef from the free list            */
312 /*------------------------------------------------------------------*/
313 structdef *
314 newStruct (char *tag)
315 {
316   structdef *s;
317
318   s = Safe_alloc ( sizeof (structdef));
319
320   strcpy (s->tag, tag);         /* copy the tag            */
321   return s;
322 }
323
324 /*------------------------------------------------------------------*/
325 /* pointerTypes - do the computation for the pointer types          */
326 /*------------------------------------------------------------------*/
327 void 
328 pointerTypes (sym_link * ptr, sym_link * type)
329 {
330   if (IS_SPEC (ptr))
331     return;
332
333   /* find the first pointer type */
334   while (ptr && !IS_PTR (ptr))
335     ptr = ptr->next;
336
337   /* could not find it */
338   if (!ptr || IS_SPEC (ptr))
339     return;
340   
341   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
342     pointerTypes (ptr->next, type);
343     return;
344   }
345
346   /* change the pointer type depending on the
347      storage class of the type */
348   if (IS_SPEC (type))
349     {
350       DCL_PTR_CONST (ptr) = SPEC_CONST (type);
351       DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
352       switch (SPEC_SCLS (type))
353         {
354         case S_XDATA:
355           DCL_TYPE (ptr) = FPOINTER;
356           break;
357         case S_IDATA:
358           DCL_TYPE (ptr) = IPOINTER;
359           break;
360         case S_PDATA:
361           DCL_TYPE (ptr) = PPOINTER;
362           break;
363         case S_DATA:
364           DCL_TYPE (ptr) = POINTER;
365           break;
366         case S_CODE:
367           DCL_PTR_CONST (ptr) = port->mem.code_ro;
368           DCL_TYPE (ptr) = CPOINTER;
369           break;
370         case S_EEPROM:
371           DCL_TYPE (ptr) = EEPPOINTER;
372           break;
373         default:
374           DCL_TYPE (ptr) = port->unqualified_pointer;
375           break;
376         }
377       /* the storage class of type ends here */
378       SPEC_SCLS (type) =
379         SPEC_CONST (type) =
380         SPEC_VOLATILE (type) = 0;
381     }
382
383   /* now change all the remaining unknown pointers
384      to generic pointers */
385   while (ptr)
386     {
387       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
388         DCL_TYPE (ptr) = port->unqualified_pointer;
389       ptr = ptr->next;
390     }
391
392   /* same for the type although it is highly unlikely that
393      type will have a pointer */
394   while (type)
395     {
396       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
397         DCL_TYPE (type) = port->unqualified_pointer;
398       type = type->next;
399     }
400
401 }
402
403 /*------------------------------------------------------------------*/
404 /* addDecl - adds a declarator @ the end of a chain                 */
405 /*------------------------------------------------------------------*/
406 void 
407 addDecl (symbol * sym, int type, sym_link * p)
408 {
409   sym_link *head;
410   sym_link *tail;
411   sym_link *t;
412
413   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
414     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
415
416   /* if we are passed a link then set head & tail */
417   if (p)
418     {
419       tail = head = p;
420       while (tail->next)
421         tail = tail->next;
422     }
423   else
424     {
425       head = tail = newLink ();
426       DCL_TYPE (head) = type;
427     }
428
429   /* if this is the first entry   */
430   if (!sym->type)
431     {
432       sym->type = head;
433       sym->etype = tail;
434     }
435   else
436     {
437       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
438         {
439           sym->etype = mergeSpec (sym->etype, head, sym->name);
440         }
441       else
442         {
443           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
444             {
445               t = sym->type;
446               while (t->next != sym->etype)
447                 t = t->next;
448               t->next = head;
449               tail->next = sym->etype;
450             }
451           else
452             {
453               sym->etype->next = head;
454               sym->etype = tail;
455             }
456         }
457     }
458
459   /* if the type is an unknown pointer and has
460      a tspec then take the storage class const & volatile
461      attribute from the tspec & make it those of this
462      symbol */
463   if (p &&
464       !IS_SPEC (p) &&
465       //DCL_TYPE (p) == UPOINTER &&
466       DCL_TSPEC (p))
467     {
468       if (!IS_SPEC (sym->etype))
469         {
470           sym->etype = sym->etype->next = newLink ();
471           sym->etype->class = SPECIFIER;
472         }
473       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
474       SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
475       SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
476       DCL_TSPEC (p) = NULL;
477     }
478
479   // if there is a function in this type chain
480   if (p && funcInChain(sym->type)) {
481     processFuncArgs (sym);
482   }
483
484   return;
485 }
486
487 /*------------------------------------------------------------------
488   checkTypeSanity: prevent the user from doing e.g.:
489   unsigned float uf;
490   ------------------------------------------------------------------*/
491 void checkTypeSanity(sym_link *etype, char *name) {
492   char *noun;
493
494   if (!etype) {
495     if (getenv("DEBUG_SANITY")) {
496       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
497     }
498     return;
499   }
500
501   if (!IS_SPEC(etype)) {
502     if (getenv("DEBUG_SANITY")) {
503       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
504     }
505     return;
506   }
507
508   noun=nounName(etype);
509
510   if (getenv("DEBUG_SANITY")) {
511     fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype);
512   }
513
514   if ((SPEC_NOUN(etype)==V_CHAR || 
515        SPEC_NOUN(etype)==V_FLOAT || 
516        SPEC_NOUN(etype)==V_DOUBLE || 
517        SPEC_NOUN(etype)==V_VOID) &&
518       (etype->select.s._short || SPEC_LONG(etype))) {
519     // long or short for char float double or void
520     werror (E_LONG_OR_SHORT_INVALID, noun, name);
521   }
522   if ((SPEC_NOUN(etype)==V_FLOAT || 
523        SPEC_NOUN(etype)==V_DOUBLE || 
524        SPEC_NOUN(etype)==V_VOID) && 
525       (etype->select.s._signed || SPEC_USIGN(etype))) {
526     // signed or unsigned for float double or void
527     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
528   }
529
530   // special case for "short"
531   if (etype->select.s._short) {
532     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
533     etype->select.s._short = 0;
534   }
535
536   /* if no noun e.g. 
537      "const a;" or "data b;" or "signed s" or "long l"
538      assume an int */
539   if (!SPEC_NOUN(etype)) {
540     SPEC_NOUN(etype)=V_INT;
541   }
542
543   if (etype->select.s._signed && SPEC_USIGN(etype)) {
544     // signed AND unsigned 
545     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
546   }
547   if (etype->select.s._short && SPEC_LONG(etype)) {
548     // short AND long
549     werror (E_LONG_AND_SHORT_INVALID, noun, name);
550   }
551
552 }
553
554 /*------------------------------------------------------------------*/
555 /* mergeSpec - merges two specifiers and returns the new one        */
556 /*------------------------------------------------------------------*/
557 sym_link *
558 mergeSpec (sym_link * dest, sym_link * src, char *name)
559 {
560   sym_link *symlink=dest;
561
562   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
563 #if 0
564     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
565     exit (1);
566 #else
567     werror (E_SYNTAX_ERROR, yytext);
568     // the show must go on
569     return newIntLink();
570 #endif
571   }
572
573   if (SPEC_NOUN(src)) {
574     if (!SPEC_NOUN(dest)) {
575       SPEC_NOUN(dest)=SPEC_NOUN(src);
576     } else {
577       /* we shouldn't redeclare the type */
578       if (getenv("DEBUG_SANITY")) {
579         fprintf (stderr, "mergeSpec: ");
580       }
581       werror(E_TWO_OR_MORE_DATA_TYPES, name);
582     }
583   }
584   
585   if (SPEC_SCLS(src)) {
586     /* if destination has no storage class */
587     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
588       SPEC_SCLS (dest) = SPEC_SCLS (src);
589     } else {
590       if (getenv("DEBUG_SANITY")) {
591         fprintf (stderr, "mergeSpec: ");
592       }
593       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
594     }
595   }
596
597   /* copy all the specifications  */
598
599   // we really should do: 
600 #if 0
601   if (SPEC_what(src)) {
602     if (SPEC_what(dest)) {
603       werror(W_DUPLICATE_SPEC, "what");
604     }
605     SPEC_what(dst)|=SPEC_what(src);
606   }
607 #endif
608   // but there are more important thing right now
609
610   SPEC_LONG (dest) |= SPEC_LONG (src);
611   dest->select.s._short|=src->select.s._short;
612   SPEC_USIGN (dest) |= SPEC_USIGN (src);
613   dest->select.s._signed|=src->select.s._signed;
614   SPEC_STAT (dest) |= SPEC_STAT (src);
615   SPEC_EXTR (dest) |= SPEC_EXTR (src);
616   SPEC_CONST(dest) |= SPEC_CONST (src);
617   SPEC_ABSA (dest) |= SPEC_ABSA (src);
618   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
619   SPEC_ADDR (dest) |= SPEC_ADDR (src);
620   SPEC_OCLS (dest) = SPEC_OCLS (src);
621   SPEC_BLEN (dest) |= SPEC_BLEN (src);
622   SPEC_BSTR (dest) |= SPEC_BSTR (src);
623   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
624   SPEC_ENUM (dest) |= SPEC_ENUM (src);
625   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   sprintf (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         sprintf (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 */
1177   if (IS_ABSOLUTE (sym->etype))
1178     SPEC_VOLATILE (sym->etype) = 1;
1179   
1180   /* global variables declared const put into code */
1181   /* if no other storage class specified */
1182   if (sym->level == 0 &&
1183       SPEC_CONST (sym->etype) &&
1184       SPEC_SCLS(sym->etype) == S_FIXED) {
1185     SPEC_SCLS (sym->etype) = S_CODE;
1186   }
1187   
1188   /* global variable in code space is a constant */
1189   if (sym->level == 0 &&
1190       SPEC_SCLS (sym->etype) == S_CODE &&
1191       port->mem.code_ro)
1192     SPEC_CONST (sym->etype) = 1;
1193   
1194
1195   /* if bit variable then no storage class can be */
1196   /* specified since bit is already a storage */
1197   if (IS_BITVAR (sym->etype) &&
1198       (SPEC_SCLS (sym->etype) != S_FIXED &&
1199        SPEC_SCLS (sym->etype) != S_SBIT &&
1200        SPEC_SCLS (sym->etype) != S_BIT)
1201     )
1202     {
1203       werror (E_BITVAR_STORAGE, sym->name);
1204       SPEC_SCLS (sym->etype) = S_FIXED;
1205     }
1206
1207   /* extern variables cannot be initialized */
1208   if (IS_EXTERN (sym->etype) && sym->ival)
1209     {
1210       werror (E_EXTERN_INIT, sym->name);
1211       sym->ival = NULL;
1212     }
1213
1214   /* if this is an atomatic symbol */
1215   if (sym->level && (options.stackAuto || reentrant)) {
1216     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1217          SPEC_SCLS (sym->etype) == S_FIXED ||
1218          SPEC_SCLS (sym->etype) == S_REGISTER ||
1219          SPEC_SCLS (sym->etype) == S_STACK ||
1220          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1221       SPEC_SCLS (sym->etype) = S_AUTO;
1222     } else {
1223       /* storage class may only be specified for statics */
1224       if (!IS_STATIC(sym->etype)) {
1225         werror (E_AUTO_ASSUMED, sym->name);
1226       }
1227     }
1228   }
1229   
1230   /* automatic symbols cannot be given   */
1231   /* an absolute address ignore it      */
1232   if (sym->level &&
1233       SPEC_ABSA (sym->etype) &&
1234       (options.stackAuto || reentrant))
1235     {
1236       werror (E_AUTO_ABSA, sym->name);
1237       SPEC_ABSA (sym->etype) = 0;
1238     }
1239
1240   /* arrays & pointers cannot be defined for bits   */
1241   /* SBITS or SFRs or BIT                           */
1242   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1243       (SPEC_NOUN (sym->etype) == V_BIT ||
1244        SPEC_NOUN (sym->etype) == V_SBIT ||
1245        SPEC_SCLS (sym->etype) == S_SFR))
1246     werror (E_BIT_ARRAY, sym->name);
1247
1248   /* if this is a bit|sbit then set length & start  */
1249   if (SPEC_NOUN (sym->etype) == V_BIT ||
1250       SPEC_NOUN (sym->etype) == V_SBIT)
1251     {
1252       SPEC_BLEN (sym->etype) = 1;
1253       SPEC_BSTR (sym->etype) = 0;
1254     }
1255
1256   if (!isProto) {
1257     /* variables declared in CODE space must have */
1258     /* initializers if not an extern */
1259     if (SPEC_SCLS (sym->etype) == S_CODE &&
1260         sym->ival == NULL &&
1261         //!sym->level &&
1262         port->mem.code_ro &&
1263         !IS_EXTERN (sym->etype) &&
1264         !funcInChain (sym->type))
1265       werror (E_CODE_NO_INIT, sym->name);
1266   }
1267
1268   /* if parameter or local variable then change */
1269   /* the storage class to reflect where the var will go */
1270   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1271       !IS_STATIC(sym->etype))
1272     {
1273       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1274         {
1275           SPEC_SCLS (sym->etype) = (options.useXstack ?
1276                                     S_XSTACK : S_STACK);
1277         }
1278       else
1279         {
1280           /* hack-o-matic! I see no reason why the useXstack option should ever
1281            * control this allcoation, but the code was originally that way, and
1282            * changing it for non-390 ports breaks the compiler badly.
1283            */
1284           bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1285           SPEC_SCLS (sym->etype) = (useXdata ?
1286                                     S_XDATA : S_FIXED);
1287         }
1288     }
1289 }
1290
1291 /*------------------------------------------------------------------*/
1292 /* changePointer - change pointer to functions                      */
1293 /*------------------------------------------------------------------*/
1294 void 
1295 changePointer (symbol * sym)
1296 {
1297   sym_link *p;
1298
1299   /* go thru the chain of declarations   */
1300   /* if we find a pointer to a function  */
1301   /* unconditionally change it to a ptr  */
1302   /* to code area                        */
1303   for (p = sym->type; p; p = p->next)
1304     {
1305       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1306         DCL_TYPE (p) = port->unqualified_pointer;
1307       if (IS_PTR (p) && IS_FUNC (p->next))
1308         DCL_TYPE (p) = CPOINTER;
1309     }
1310 }
1311
1312 /*------------------------------------------------------------------*/
1313 /* checkDecl - does semantic validation of a declaration                   */
1314 /*------------------------------------------------------------------*/
1315 int 
1316 checkDecl (symbol * sym, int isProto)
1317 {
1318
1319   checkSClass (sym, isProto);           /* check the storage class      */
1320   changePointer (sym);          /* change pointers if required */
1321
1322   /* if this is an array without any dimension
1323      then update the dimension from the initial value */
1324   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1325     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1326
1327   return 0;
1328 }
1329
1330 /*------------------------------------------------------------------*/
1331 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1332 /*------------------------------------------------------------------*/
1333 sym_link *
1334 copyLinkChain (sym_link * p)
1335 {
1336   sym_link *head, *curr, *loop;
1337
1338   curr = p;
1339   head = loop = (curr ? newLink () : (void *) NULL);
1340   while (curr)
1341     {
1342       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1343       loop->next = (curr->next ? newLink () : (void *) NULL);
1344       loop = loop->next;
1345       curr = curr->next;
1346     }
1347
1348   return head;
1349 }
1350
1351
1352 /*------------------------------------------------------------------*/
1353 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1354 /*                symbols in the given block                        */
1355 /*------------------------------------------------------------------*/
1356 void 
1357 cleanUpBlock (bucket ** table, int block)
1358 {
1359   int i;
1360   bucket *chain;
1361
1362   /* go thru the entire  table  */
1363   for (i = 0; i < 256; i++)
1364     {
1365       for (chain = table[i]; chain; chain = chain->next)
1366         {
1367           if (chain->block >= block)
1368             {
1369               deleteSym (table, chain->sym, chain->name);
1370             }
1371         }
1372     }
1373 }
1374
1375 /*------------------------------------------------------------------*/
1376 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1377 /*                symbols in the given level                        */
1378 /*------------------------------------------------------------------*/
1379 void 
1380 cleanUpLevel (bucket ** table, int level)
1381 {
1382   int i;
1383   bucket *chain;
1384
1385   /* go thru the entire  table  */
1386   for (i = 0; i < 256; i++)
1387     {
1388       for (chain = table[i]; chain; chain = chain->next)
1389         {
1390           if (chain->level >= level)
1391             {
1392               deleteSym (table, chain->sym, chain->name);
1393             }
1394         }
1395     }
1396 }
1397
1398 /*------------------------------------------------------------------*/
1399 /* computeType - computes the resultant type from two types         */
1400 /*------------------------------------------------------------------*/
1401 sym_link *
1402 computeType (sym_link * type1, sym_link * type2)
1403 {
1404   sym_link *rType;
1405   sym_link *reType;
1406   sym_link *etype1 = getSpec (type1);
1407   sym_link *etype2 = getSpec (type2);
1408
1409   /* if one of them is a float then result is a float */
1410   /* here we assume that the types passed are okay */
1411   /* and can be cast to one another                */
1412   /* which ever is greater in size */
1413   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1414     rType = newFloatLink ();
1415   else
1416     /* if only one of them is a bit variable
1417        then the other one prevails */
1418   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1419     rType = copyLinkChain (type2);
1420   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1421     rType = copyLinkChain (type1);
1422   else
1423     /* if one of them is a pointer or array then that
1424        prevails */
1425   if (IS_PTR (type1) || IS_ARRAY (type1))
1426     rType = copyLinkChain (type1);
1427   else if (IS_PTR (type2) || IS_ARRAY (type2))
1428     rType = copyLinkChain (type2);
1429   else if (getSize (type1) > getSize (type2))
1430     rType = copyLinkChain (type1);
1431   else
1432     rType = copyLinkChain (type2);
1433
1434   reType = getSpec (rType);
1435
1436   /* if either of them unsigned but not val then make this unsigned */
1437   if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || 
1438        (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && 
1439       !IS_FLOAT (reType))
1440     SPEC_USIGN (reType) = 1;
1441   else
1442     SPEC_USIGN (reType) = 0;
1443   
1444   /* if result is a literal then make not so */
1445   if (IS_LITERAL (reType))
1446     SPEC_SCLS (reType) = S_REGISTER;
1447
1448   return rType;
1449 }
1450
1451 /*--------------------------------------------------------------------*/
1452 /* compareType - will do type check return 1 if match, -1 if castable */
1453 /*--------------------------------------------------------------------*/
1454 int 
1455 compareType (sym_link * dest, sym_link * src)
1456 {
1457   if (!dest && !src)
1458     return 1;
1459
1460   if (dest && !src)
1461     return 0;
1462
1463   if (src && !dest)
1464     return 0;
1465
1466   /* if dest is a declarator then */
1467   if (IS_DECL (dest))
1468     {
1469       if (IS_DECL (src))
1470         {
1471           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1472             if (IS_FUNC(src)) {
1473               //checkFunction(src,dest);
1474             }
1475             return compareType (dest->next, src->next);
1476           }
1477           if (IS_PTR (src) && IS_GENPTR (dest))
1478             return -1;
1479           if (IS_PTR (dest) && IS_ARRAY (src)) {
1480             value *val=aggregateToPointer (valFromType(src));
1481             int res=compareType (dest, val->type);
1482             Safe_free(val->type);
1483             Safe_free(val);
1484             //return res ? -1 : 0;
1485             return res;
1486           }
1487           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1488             return compareType (dest->next, src);
1489           return 0;
1490         }
1491       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1492         return -1;
1493       else
1494         return 0;
1495     }
1496
1497   /* if one is a specifier and the other is not */
1498   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1499       (IS_SPEC (dest) && !IS_SPEC (src)))
1500     return 0;
1501
1502   /* if one of them is a void then ok */
1503   if (SPEC_NOUN (dest) == V_VOID &&
1504       SPEC_NOUN (src) != V_VOID)
1505     return -1;
1506
1507   if (SPEC_NOUN (dest) != V_VOID &&
1508       SPEC_NOUN (src) == V_VOID)
1509     return -1;
1510
1511   /* if they are both bitfields then if the lengths
1512      and starts don't match */
1513   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1514       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1515        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1516     return -1;
1517
1518   /* it is a specifier */
1519   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1520     {
1521       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1522           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1523           getSize (dest) == getSize (src))
1524         return 1;
1525       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1526         return -1;
1527       else
1528         return 0;
1529     }
1530   else if (IS_STRUCT (dest))
1531     {
1532       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1533         return 0;
1534       else
1535         return 1;
1536     }
1537   if (SPEC_LONG (dest) != SPEC_LONG (src))
1538     return -1;
1539
1540   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1541     return -1;
1542
1543   return 1;
1544 }
1545
1546 /*------------------------------------------------------------------*/
1547 /* inCalleeSaveList - return 1 if found in callee save list          */
1548 /*------------------------------------------------------------------*/
1549 bool 
1550 inCalleeSaveList (char *s)
1551 {
1552   int i;
1553
1554   if (options.all_callee_saves) return 1;
1555   for (i = 0; options.calleeSaves[i]; i++)
1556     if (strcmp (options.calleeSaves[i], s) == 0)
1557       return 1;
1558
1559   return 0;
1560 }
1561
1562 /*-----------------------------------------------------------------*/
1563 /* aggregateToPointer:  change an agggregate type function      */
1564 /*         argument to a pointer to that type.     */
1565 /*-----------------------------------------------------------------*/
1566 value *
1567 aggregateToPointer (value * val)
1568 {
1569   if (IS_AGGREGATE (val->type))
1570     {
1571       /* if this is a structure */
1572       /* then we need to add a new link */
1573       if (IS_STRUCT (val->type))
1574         {
1575           /* first lets add DECLARATOR type */
1576           sym_link *p = val->type;
1577
1578           werror (W_STRUCT_AS_ARG, val->name);
1579           val->type = newLink ();
1580           val->type->next = p;
1581         }
1582
1583       /* change to a pointer depending on the */
1584       /* storage class specified        */
1585       switch (SPEC_SCLS (val->etype))
1586         {
1587         case S_IDATA:
1588           DCL_TYPE (val->type) = IPOINTER;
1589           break;
1590         case S_PDATA:
1591           DCL_TYPE (val->type) = PPOINTER;
1592           break;
1593         case S_FIXED:
1594           if (SPEC_OCLS(val->etype)) {
1595             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1596           } else {
1597 #if 1
1598             // this happens for (external) function parameters
1599             DCL_TYPE (val->type) = port->unqualified_pointer;
1600 #else
1601             if (TARGET_IS_DS390) {
1602               /* The AUTO and REGISTER classes should probably
1603                * also become generic pointers, but I haven't yet
1604                * devised a test case for that.
1605                */
1606               DCL_TYPE (val->type) = port->unqualified_pointer;
1607               break;
1608             }
1609             if (options.model==MODEL_LARGE) {
1610               DCL_TYPE (val->type) = FPOINTER;
1611               break;
1612             }
1613 #endif
1614           }
1615           break;
1616         case S_AUTO:
1617         case S_DATA:
1618         case S_REGISTER:
1619           DCL_TYPE (val->type) = POINTER;
1620           break;
1621         case S_CODE:
1622           DCL_TYPE (val->type) = CPOINTER;
1623           break;
1624         case S_XDATA:
1625           DCL_TYPE (val->type) = FPOINTER;
1626           break;
1627         case S_EEPROM:
1628           DCL_TYPE (val->type) = EEPPOINTER;
1629           break;
1630         default:
1631           DCL_TYPE (val->type) = port->unqualified_pointer;
1632         }
1633       
1634       /* is there is a symbol associated then */
1635       /* change the type of the symbol as well */
1636       if (val->sym)
1637         {
1638           val->sym->type = copyLinkChain (val->type);
1639           val->sym->etype = getSpec (val->sym->type);
1640         }
1641     }
1642   return val;
1643 }
1644 /*------------------------------------------------------------------*/
1645 /* checkFunction - does all kinds of check on a function            */
1646 /*------------------------------------------------------------------*/
1647 int 
1648 checkFunction (symbol * sym, symbol *csym)
1649 {
1650   value *exargs, *acargs;
1651   value *checkValue;
1652   int argCnt = 0;
1653
1654   if (getenv("DEBUG_SANITY")) {
1655     fprintf (stderr, "checkFunction: %s ", sym->name);
1656   }
1657
1658   /* make sure the type is complete and sane */
1659   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1660
1661   /* if not type then some kind of error */
1662   if (!sym->type)
1663     return 0;
1664
1665   /* if the function has no type then make it return int */
1666   if (!sym->type->next)
1667     sym->type->next = sym->etype = newIntLink ();
1668
1669   /* function cannot return aggregate */
1670   if (IS_AGGREGATE (sym->type->next))
1671     {
1672       werror (E_FUNC_AGGR, sym->name);
1673       return 0;
1674     }
1675
1676   /* function cannot return bit */
1677   if (IS_BITVAR (sym->type->next))
1678     {
1679       werror (E_FUNC_BIT, sym->name);
1680       return 0;
1681     }
1682
1683   /* check if this function is defined as calleeSaves
1684      then mark it as such */
1685   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1686
1687   /* if interrupt service routine  */
1688   /* then it cannot have arguments */
1689   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1690     {
1691       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1692         werror (E_INT_ARGS, sym->name);
1693         FUNC_ARGS(sym->type)=NULL;
1694       }
1695     }
1696
1697   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1698        acargs; 
1699        acargs=acargs->next, argCnt++) {
1700     if (!acargs->sym) { 
1701       // this can happen for reentrant functions
1702       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1703       // the show must go on: synthesize a name and symbol
1704       sprintf (acargs->name, "_%s_PARM_%d", sym->name, argCnt);
1705       acargs->sym = newSymbol (acargs->name, 1);
1706       SPEC_OCLS (acargs->etype) = istack;
1707       acargs->sym->type = copyLinkChain (acargs->type);
1708       acargs->sym->etype = getSpec (acargs->sym->type);
1709       acargs->sym->_isparm = 1;
1710       strcpy (acargs->sym->rname, acargs->name);
1711     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
1712       // synthesized name
1713       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1714     }
1715   }
1716
1717   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1718     return 1;                   /* not defined nothing more to check  */
1719
1720   /* check if body already present */
1721   if (csym && IFFUNC_HASBODY(csym->type))
1722     {
1723       werror (E_FUNC_BODY, sym->name);
1724       return 0;
1725     }
1726
1727   /* check the return value type   */
1728   if (compareType (csym->type, sym->type) <= 0)
1729     {
1730       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1731       printFromToType(csym->type, sym->type);
1732       return 0;
1733     }
1734
1735   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1736     {
1737       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1738     }
1739
1740   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1741     {
1742       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1743     }
1744
1745   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1746     {
1747       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1748     }
1749
1750   /* compare expected args with actual args */
1751   exargs = FUNC_ARGS(csym->type);
1752   acargs = FUNC_ARGS(sym->type);
1753
1754   /* for all the expected args do */
1755   for (argCnt = 1;
1756        exargs && acargs;
1757        exargs = exargs->next, acargs = acargs->next, argCnt++)
1758     {
1759       if (getenv("DEBUG_SANITY")) {
1760         fprintf (stderr, "checkFunction: %s ", exargs->name);
1761       }
1762       /* make sure the type is complete and sane */
1763       checkTypeSanity(exargs->etype, exargs->name);
1764
1765       /* If the actual argument is an array, any prototype
1766        * will have modified it to a pointer. Duplicate that
1767        * change here.
1768        */
1769       if (IS_AGGREGATE (acargs->type))
1770         {
1771           checkValue = copyValue (acargs);
1772           aggregateToPointer (checkValue);
1773         }
1774       else
1775         {
1776           checkValue = acargs;
1777         }
1778
1779       if (compareType (exargs->type, checkValue->type) <= 0)
1780         {
1781           werror (E_ARG_TYPE, argCnt);
1782           printFromToType(exargs->type, checkValue->type);
1783           return 0;
1784         }
1785     }
1786
1787   /* if one them ended we have a problem */
1788   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1789       (!exargs && acargs && !IS_VOID (acargs->type)))
1790     werror (E_ARG_COUNT);
1791
1792   /* replace with this defition */
1793   sym->cdef = csym->cdef;
1794   deleteSym (SymbolTab, csym, csym->name);
1795   deleteFromSeg(csym);
1796   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1797   if (IS_EXTERN (csym->etype) && !
1798       IS_EXTERN (sym->etype))
1799     {
1800       addSet (&publics, sym);
1801     }
1802   return 1;
1803 }
1804
1805 /*-----------------------------------------------------------------*/
1806 /* processFuncArgs - does some processing with function args       */
1807 /*-----------------------------------------------------------------*/
1808 void 
1809 processFuncArgs (symbol * func)
1810 {
1811   value *val;
1812   int pNum = 1;
1813   sym_link *funcType=func->type;
1814
1815   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1816     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1817
1818   // if this is a pointer to a function
1819   if (IS_PTR(funcType)) {
1820     funcType=funcType->next;
1821   }
1822
1823   /* if this function has variable argument list */
1824   /* then make the function a reentrant one    */
1825   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1826     FUNC_ISREENT(funcType)=1;
1827
1828   /* check if this function is defined as calleeSaves
1829      then mark it as such */
1830   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1831
1832   /* loop thru all the arguments   */
1833   val = FUNC_ARGS(funcType);
1834
1835   /* if it is void then remove parameters */
1836   if (val && IS_VOID (val->type))
1837     {
1838       FUNC_ARGS(funcType) = NULL;
1839       return;
1840     }
1841
1842   /* reset regparm for the port */
1843   (*port->reset_regparms) ();
1844   /* if any of the arguments is an aggregate */
1845   /* change it to pointer to the same type */
1846   while (val)
1847     {
1848         int argreg = 0;
1849       /* mark it as a register parameter if
1850          the function does not have VA_ARG
1851          and as port dictates */
1852       if (!IFFUNC_HASVARARGS(funcType) &&
1853           (argreg = (*port->reg_parm) (val->type)))
1854         {
1855           SPEC_REGPARM (val->etype) = 1;
1856           SPEC_ARGREG(val->etype) = argreg;
1857         } else if (IFFUNC_ISREENT(funcType)) {
1858             FUNC_HASSTACKPARM(funcType) = 1;
1859         }
1860
1861       if (IS_AGGREGATE (val->type))
1862         {
1863           aggregateToPointer (val);
1864         }
1865
1866       val = val->next;
1867       pNum++;
1868     }
1869
1870   /* if this is an internal generated function call */
1871   if (func->cdef) {
1872     /* ignore --stack-auto for this one, we don't know how it is compiled */
1873     /* simply trust on --int-long-reent or --float-reent */
1874     if (IFFUNC_ISREENT(funcType)) {
1875       return;
1876     }
1877   } else {
1878     /* if this function is reentrant or */
1879     /* automatics r 2b stacked then nothing */
1880     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1881       return;
1882   }
1883
1884   val = FUNC_ARGS(funcType);
1885   pNum = 1;
1886   while (val)
1887     {
1888
1889       /* if a symbolname is not given  */
1890       /* synthesize a variable name */
1891       if (!val->sym)
1892         {
1893           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1894           val->sym = newSymbol (val->name, 1);
1895           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1896           val->sym->type = copyLinkChain (val->type);
1897           val->sym->etype = getSpec (val->sym->type);
1898           val->sym->_isparm = 1;
1899           strcpy (val->sym->rname, val->name);
1900           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1901             SPEC_STAT (func->etype);
1902           addSymChain (val->sym);
1903
1904         }
1905       else                      /* symbol name given create synth name */
1906         {
1907
1908           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1909           strcpy (val->sym->rname, val->name);
1910           val->sym->_isparm = 1;
1911           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1912             (options.model != MODEL_SMALL ? xdata : data);
1913           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1914             SPEC_STAT (func->etype);
1915         }
1916       val = val->next;
1917     }
1918 }
1919
1920 /*-----------------------------------------------------------------*/
1921 /* isSymbolEqual - compares two symbols return 1 if they match     */
1922 /*-----------------------------------------------------------------*/
1923 int 
1924 isSymbolEqual (symbol * dest, symbol * src)
1925 {
1926   /* if pointers match then equal */
1927   if (dest == src)
1928     return 1;
1929
1930   /* if one of them is null then don't match */
1931   if (!dest || !src)
1932     return 0;
1933
1934   /* if both of them have rname match on rname */
1935   if (dest->rname[0] && src->rname[0])
1936     return (!strcmp (dest->rname, src->rname));
1937
1938   /* otherwise match on name */
1939   return (!strcmp (dest->name, src->name));
1940 }
1941
1942 void PT(sym_link *type)
1943 {
1944         printTypeChain(type,0);
1945 }
1946 /*-----------------------------------------------------------------*/
1947 /* printTypeChain - prints the type chain in human readable form   */
1948 /*-----------------------------------------------------------------*/
1949 void
1950 printTypeChain (sym_link * start, FILE * of)
1951 {
1952   int nlr = 0;
1953   sym_link * type, * search;
1954
1955   if (!of)
1956     {
1957       of = stdout;
1958       nlr = 1;
1959     }
1960
1961   if (start==NULL) {
1962     fprintf (of, "void");
1963     return;
1964   }
1965
1966   /* print the chain as it is written in the source: */
1967   /* start with the last entry                       */
1968   for (type = start; type && type->next; type = type->next)
1969     ;
1970   while (type)
1971     {
1972       if (IS_DECL (type))
1973         {
1974           if (DCL_PTR_VOLATILE (type)) {
1975             fprintf (of, "volatile ");
1976           }
1977           switch (DCL_TYPE (type))
1978             {
1979             case FUNCTION:
1980               fprintf (of, "function %s %s", 
1981                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
1982                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
1983               break;
1984             case GPOINTER:
1985               if (DCL_PTR_CONST (type))
1986                 fprintf (of, "const ");
1987               fprintf (of, "generic * ");
1988               break;
1989             case CPOINTER:
1990               if (DCL_PTR_CONST (type))
1991                 fprintf (of, "const ");
1992               fprintf (of, "code * ");
1993               break;
1994             case FPOINTER:
1995               if (DCL_PTR_CONST (type))
1996                 fprintf (of, "const ");
1997               fprintf (of, "xdata * ");
1998               break;
1999             case EEPPOINTER:
2000               if (DCL_PTR_CONST (type))
2001                 fprintf (of, "const ");
2002               fprintf (of, "eeprom * ");
2003               break;
2004
2005             case POINTER:
2006               if (DCL_PTR_CONST (type))
2007                 fprintf (of, "const ");
2008               fprintf (of, "near *");
2009               break;
2010             case IPOINTER:
2011               if (DCL_PTR_CONST (type))
2012                 fprintf (of, "const ");
2013               fprintf (of, "idata * ");
2014               break;
2015             case PPOINTER:
2016               if (DCL_PTR_CONST (type))
2017                 fprintf (of, "const ");
2018               fprintf (of, "pdata * ");
2019               break;
2020             case UPOINTER:
2021               if (DCL_PTR_CONST (type))
2022                 fprintf (of, "const ");
2023               fprintf (of, "unkown * ");
2024               break;
2025             case ARRAY:
2026               fprintf (of, "[] ");
2027               break;
2028             }
2029         }
2030       else
2031         {
2032           switch (SPEC_SCLS(type)) 
2033             {
2034             case S_DATA: fprintf (of, "data "); break;
2035             case S_XDATA: fprintf (of, "xdata "); break;
2036             case S_SFR: fprintf (of, "sfr "); break;
2037             case S_SBIT: fprintf (of, "sbit "); break;
2038             case S_CODE: fprintf (of, "code "); break;
2039             case S_IDATA: fprintf (of, "idata "); break;
2040             case S_PDATA: fprintf (of, "pdata "); break;
2041             case S_LITERAL: fprintf (of, "literal "); break;
2042             case S_STACK: fprintf (of, "stack "); break;
2043             case S_XSTACK: fprintf (of, "xstack "); break;
2044             case S_BIT: fprintf (of, "bit "); break;
2045             case S_EEPROM: fprintf (of, "eeprom "); break;
2046             default: break;
2047             }
2048
2049           if (SPEC_VOLATILE (type))
2050             fprintf (of, "volatile ");
2051           if (SPEC_USIGN (type))
2052             fprintf (of, "unsigned ");
2053           if (SPEC_CONST (type))
2054             fprintf (of, "const ");
2055           switch (SPEC_NOUN (type))
2056             {
2057             case V_INT:
2058               if (IS_LONG (type))
2059                 fprintf (of, "long ");
2060               fprintf (of, "int");
2061               break;
2062
2063             case V_CHAR:
2064               fprintf (of, "char");
2065               break;
2066
2067             case V_VOID:
2068               fprintf (of, "void");
2069               break;
2070
2071             case V_FLOAT:
2072               fprintf (of, "float");
2073               break;
2074
2075             case V_STRUCT:
2076               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2077               break;
2078
2079             case V_SBIT:
2080               fprintf (of, "sbit");
2081               break;
2082
2083             case V_BIT:
2084               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2085               break;
2086
2087             case V_DOUBLE:
2088               fprintf (of, "double");
2089               break;
2090
2091             default:
2092               fprintf (of, "unknown type");
2093               break;
2094             }
2095         }
2096         /* search entry in list before "type" */
2097     for (search = start; search && search->next != type;)
2098        search = search->next;
2099     type = search;
2100     if (type)
2101       fputc (' ', of);
2102     }
2103   if (nlr)
2104     fprintf (of, "\n");
2105 }
2106
2107 /*-----------------------------------------------------------------*/
2108 /* cdbTypeInfo - print the type information for debugger           */
2109 /*-----------------------------------------------------------------*/
2110 void
2111 cdbTypeInfo (sym_link * type, FILE * of)
2112 {
2113   fprintf (of, "{%d}", getSize (type));
2114   while (type)
2115     {
2116       if (IS_DECL (type))
2117         {
2118           switch (DCL_TYPE (type))
2119             {
2120             case FUNCTION:
2121               fprintf (of, "DF,");
2122               break;
2123             case GPOINTER:
2124               fprintf (of, "DG,");
2125               break;
2126             case CPOINTER:
2127               fprintf (of, "DC,");
2128               break;
2129             case FPOINTER:
2130               fprintf (of, "DX,");
2131               break;
2132             case POINTER:
2133               fprintf (of, "DD,");
2134               break;
2135             case IPOINTER:
2136               fprintf (of, "DI,");
2137               break;
2138             case PPOINTER:
2139               fprintf (of, "DP,");
2140               break;
2141             case EEPPOINTER:
2142               fprintf (of, "DA,");
2143               break;
2144             case ARRAY:
2145               fprintf (of, "DA%d,", DCL_ELEM (type));
2146               break;
2147             default:
2148               break;
2149             }
2150         }
2151       else
2152         {
2153           switch (SPEC_NOUN (type))
2154             {
2155             case V_INT:
2156               if (IS_LONG (type))
2157                 fprintf (of, "SL");
2158               else
2159                 fprintf (of, "SI");
2160               break;
2161
2162             case V_CHAR:
2163               fprintf (of, "SC");
2164               break;
2165
2166             case V_VOID:
2167               fprintf (of, "SV");
2168               break;
2169
2170             case V_FLOAT:
2171               fprintf (of, "SF");
2172               break;
2173
2174             case V_STRUCT:
2175               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2176               break;
2177
2178             case V_SBIT:
2179               fprintf (of, "SX");
2180               break;
2181
2182             case V_BIT:
2183               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2184               break;
2185
2186             default:
2187               break;
2188             }
2189           fputs (":", of);
2190           if (SPEC_USIGN (type))
2191             fputs ("U", of);
2192           else
2193             fputs ("S", of);
2194         }
2195       type = type->next;
2196     }
2197 }
2198 /*-----------------------------------------------------------------*/
2199 /* cdbSymbol - prints a symbol & its type information for debugger */
2200 /*-----------------------------------------------------------------*/
2201 void 
2202 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2203 {
2204   memmap *map;
2205
2206   if (!sym)
2207     return;
2208   if (!of)
2209     of = stdout;
2210
2211   if (isFunc)
2212     fprintf (of, "F:");
2213   else
2214     fprintf (of, "S:");         /* symbol record */
2215   /* if this is not a structure symbol then
2216      we need to figure out the scope information */
2217   if (!isStructSym)
2218     {
2219       if (!sym->level)
2220         {
2221           /* global */
2222           if (IS_STATIC (sym->etype))
2223             fprintf (of, "F%s$", moduleName);   /* scope is file */
2224           else
2225             fprintf (of, "G$"); /* scope is global */
2226         }
2227       else
2228         /* symbol is local */
2229         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2230     }
2231   else
2232     fprintf (of, "S$");         /* scope is structure */
2233
2234   /* print the name, & mangled name */
2235   fprintf (of, "%s$%d$%d(", sym->name,
2236            sym->level, sym->block);
2237
2238   cdbTypeInfo (sym->type, of);
2239   fprintf (of, "),");
2240
2241   /* print the address space */
2242   map = SPEC_OCLS (sym->etype);
2243   fprintf (of, "%c,%d,%d",
2244            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2245
2246   /* if assigned to registers then output register names */
2247   /* if this is a function then print
2248      if is it an interrupt routine & interrupt number
2249      and the register bank it is using */
2250   if (isFunc)
2251     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2252              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2253   /* alternate location to find this symbol @ : eg registers
2254      or spillication */
2255
2256   if (!isStructSym)
2257     fprintf (of, "\n");
2258 }
2259
2260 /*-----------------------------------------------------------------*/
2261 /* cdbStruct - print a structure for debugger                      */
2262 /*-----------------------------------------------------------------*/
2263 void 
2264 cdbStruct (structdef * sdef, int block, FILE * of,
2265            int inStruct, char *tag)
2266 {
2267   symbol *sym;
2268
2269   fprintf (of, "T:");
2270   /* if block # then must have function scope */
2271   fprintf (of, "F%s$", moduleName);
2272   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2273   for (sym = sdef->fields; sym; sym = sym->next)
2274     {
2275       fprintf (of, "({%d}", sym->offset);
2276       cdbSymbol (sym, of, TRUE, FALSE);
2277       fprintf (of, ")");
2278     }
2279   fprintf (of, "]");
2280   if (!inStruct)
2281     fprintf (of, "\n");
2282 }
2283
2284 /*------------------------------------------------------------------*/
2285 /* cdbStructBlock - calls struct printing for a blcks               */
2286 /*------------------------------------------------------------------*/
2287 void 
2288 cdbStructBlock (int block, FILE * of)
2289 {
2290   int i;
2291   bucket **table = StructTab;
2292   bucket *chain;
2293   wassert (of);
2294
2295   /* go thru the entire  table  */
2296   for (i = 0; i < 256; i++)
2297     {
2298       for (chain = table[i]; chain; chain = chain->next)
2299         {
2300           if (chain->block >= block)
2301             {
2302               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2303             }
2304         }
2305     }
2306 }
2307
2308 /*-----------------------------------------------------------------*/
2309 /* powof2 - returns power of two for the number if number is pow 2 */
2310 /*-----------------------------------------------------------------*/
2311 int 
2312 powof2 (unsigned long num)
2313 {
2314   int nshifts = 0;
2315   int n1s = 0;
2316
2317   while (num)
2318     {
2319       if (num & 1)
2320         n1s++;
2321       num >>= 1;
2322       nshifts++;
2323     }
2324
2325   if (n1s > 1 || nshifts == 0)
2326     return 0;
2327   return nshifts - 1;
2328 }
2329
2330 symbol *__fsadd;
2331 symbol *__fssub;
2332 symbol *__fsmul;
2333 symbol *__fsdiv;
2334 symbol *__fseq;
2335 symbol *__fsneq;
2336 symbol *__fslt;
2337 symbol *__fslteq;
2338 symbol *__fsgt;
2339 symbol *__fsgteq;
2340
2341 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2342 symbol *__muldiv[3][3][2];
2343 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2344 sym_link *__multypes[3][2];
2345 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2346 symbol *__conv[2][3][2];
2347 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2348 symbol *__rlrr[2][3][2];
2349
2350 sym_link *floatType;
2351
2352 static char *
2353 _mangleFunctionName(char *in)
2354 {
2355   if (port->getMangledFunctionName) 
2356     {
2357       return port->getMangledFunctionName(in);
2358     }
2359   else
2360     {
2361       return in;
2362     }
2363 }
2364
2365 /*-----------------------------------------------------------------*/
2366 /* typeFromStr - create a typechain from an encoded string         */
2367 /* basic types -        'c' - char                                 */
2368 /*                      's' - short                                */
2369 /*                      'i' - int                                  */
2370 /*                      'l' - long                                 */
2371 /*                      'f' - float                                */
2372 /*                      'v' - void                                 */
2373 /*                      '*' - pointer - default (GPOINTER)         */
2374 /* modifiers -          'u' - unsigned                             */
2375 /* pointer modifiers -  'g' - generic                              */
2376 /*                      'x' - xdata                                */
2377 /*                      'p' - code                                 */
2378 /*                      'd' - data                                 */                     
2379 /*                      'F' - function                             */                     
2380 /* examples : "ig*" - generic int *                                */
2381 /*            "cx*" - char xdata *                                 */
2382 /*            "ui" -  unsigned int                                 */
2383 /*-----------------------------------------------------------------*/
2384 sym_link *typeFromStr (char *s)
2385 {
2386     sym_link *r = newLink();
2387     int usign = 0;
2388
2389     do {
2390         sym_link *nr;
2391         switch (*s) {
2392         case 'u' : 
2393             usign = 1;
2394             s++;
2395             continue ;
2396             break ;
2397         case 'c':
2398             r->class = SPECIFIER;
2399             SPEC_NOUN(r) = V_CHAR;
2400             break;
2401         case 's':
2402         case 'i':
2403             r->class = SPECIFIER;
2404             SPEC_NOUN(r) = V_INT;
2405             break;
2406         case 'l':
2407             r->class = SPECIFIER;
2408             SPEC_NOUN(r) = V_INT;
2409             SPEC_LONG(r) = 1;
2410             break;
2411         case 'f':
2412             r->class = SPECIFIER;
2413             SPEC_NOUN(r) = V_FLOAT;
2414             break;
2415         case 'v':
2416             r->class = SPECIFIER;
2417             SPEC_NOUN(r) = V_VOID;
2418             break;
2419         case '*':
2420             DCL_TYPE(r) = port->unqualified_pointer;
2421             break;
2422         case 'g':
2423         case 'x':
2424         case 'p':
2425         case 'd':
2426         case 'F':
2427             assert(*(s+1)=='*');
2428             nr = newLink();
2429             nr->next = r;
2430             r = nr;
2431             r->class = DECLARATOR ;
2432             switch (*s) {
2433             case 'g':
2434                 DCL_TYPE(r) = GPOINTER;
2435                 break;
2436             case 'x':
2437                 DCL_TYPE(r) = FPOINTER;
2438                 break;
2439             case 'p':
2440                 DCL_TYPE(r) = CPOINTER;
2441                 break;
2442             case 'd':
2443                 DCL_TYPE(r) = POINTER;
2444                 break;
2445             case 'F':
2446                 DCL_TYPE(r) = FUNCTION;
2447                 nr = newLink();
2448                 nr->next = r;
2449                 r = nr;
2450                 r->class = DECLARATOR ;
2451                 DCL_TYPE(r) = CPOINTER;
2452                 break;
2453             }
2454             s++;
2455             break;
2456         default:
2457             werror(E_INTERNAL_ERROR,"typeFromStr");
2458             break;
2459         }
2460         if (IS_SPEC(r) && usign) {
2461             SPEC_USIGN(r) = 1;
2462             usign = 0;
2463         }
2464         s++;
2465     } while (*s);
2466     return r;
2467 }
2468
2469 /*-----------------------------------------------------------------*/
2470 /* initCSupport - create functions for C support routines          */
2471 /*-----------------------------------------------------------------*/
2472 void 
2473 initCSupport ()
2474 {
2475   const char *smuldivmod[] =
2476   {
2477     "mul", "div", "mod"
2478   };
2479   const char *sbwd[] =
2480   {
2481     "char", "int", "long"
2482   };
2483   const char *ssu[] =
2484   {
2485     "s", "u"
2486   };
2487   const char *srlrr[] =
2488   {
2489     "rl", "rr"
2490   };
2491
2492   int bwd, su, muldivmod, tofrom, rlrr;
2493
2494   if (getenv("SDCC_NO_C_SUPPORT")) {
2495     /* for debugging only */
2496     return;
2497   }
2498
2499   floatType = newFloatLink ();
2500
2501   for (bwd = 0; bwd < 3; bwd++)
2502     {
2503       sym_link *l;
2504       switch (bwd)
2505         {
2506         case 0:
2507           l = newCharLink ();
2508           break;
2509         case 1:
2510           l = newIntLink ();
2511           break;
2512         case 2:
2513           l = newLongLink ();
2514           break;
2515         default:
2516           assert (0);
2517         }
2518       __multypes[bwd][0] = l;
2519       __multypes[bwd][1] = copyLinkChain (l);
2520       SPEC_USIGN (__multypes[bwd][1]) = 1;
2521     }
2522
2523   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2524   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2525   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2526   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2527   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2528   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2529   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2530   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2531   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2532   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2533
2534   for (tofrom = 0; tofrom < 2; tofrom++)
2535     {
2536       for (bwd = 0; bwd < 3; bwd++)
2537         {
2538           for (su = 0; su < 2; su++)
2539             {
2540               if (tofrom)
2541                 {
2542                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2543                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
2544                 }
2545               else
2546                 {
2547                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2548                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
2549                 }
2550             }
2551         }
2552     }
2553
2554   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2555     {
2556       for (bwd = 0; bwd < 3; bwd++)
2557         {
2558           for (su = 0; su < 2; su++)
2559             {
2560               sprintf (buffer, "_%s%s%s",
2561                        smuldivmod[muldivmod],
2562                        ssu[su],
2563                        sbwd[bwd]);
2564               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2565               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2566             }
2567         }
2568     }
2569
2570   for (rlrr = 0; rlrr < 2; rlrr++)
2571     {
2572       for (bwd = 0; bwd < 3; bwd++)
2573         {
2574           for (su = 0; su < 2; su++)
2575             {
2576               sprintf (buffer, "_%s%s%s",
2577                        srlrr[rlrr],
2578                        ssu[su],
2579                        sbwd[bwd]);
2580               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2581               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2582             }
2583         }
2584     }
2585 }
2586
2587 /*-----------------------------------------------------------------*/
2588 /* initBuiltIns - create prototypes for builtin functions          */
2589 /*-----------------------------------------------------------------*/
2590 void initBuiltIns()
2591 {
2592     int i;
2593     symbol *sym;
2594
2595     if (!port->builtintable) return ;
2596
2597     for (i = 0 ; port->builtintable[i].name ; i++) {
2598         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2599                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2600         FUNC_ISBUILTIN(sym->type) = 1;
2601         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2602     }
2603 }