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