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