* src/SDCCsymt.c (initCSupport): fix compile warning on Cygwin
[fw/sdcc] / src / SDCCsymt.c
1 /*-------------------------------------------------------------------------
2   SDCCsymt.c - Code file for Symbols table related structures and MACRO's.
3         Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any
8    later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19    In other words, you are welcome to use, share and improve this program.
20    You are forbidden to forbid anyone else to use, share and improve
21    what you give them.   Help stamp out software-hoarding!
22 -------------------------------------------------------------------------*/
23
24 #include "common.h"
25 #include "newalloc.h"
26
27 value *aggregateToPointer (value *val);
28
29 void printFromToType(sym_link *from, sym_link *to) {
30   fprintf (stderr, "from type '");
31   printTypeChain (from, stderr);
32   fprintf (stderr, "'\nto type '");
33   printTypeChain (to, stderr);
34   fprintf (stderr, "'\n");
35 }
36
37 /* noun strings */
38 char *nounName(sym_link *sl) {
39   switch (SPEC_NOUN(sl)) 
40     {
41     case V_INT: {
42       if (SPEC_LONG(sl)) return "long";
43       if (sl->select.s._short) return "short";
44       return "int";
45     }
46     case V_FLOAT: return "float";
47     case V_CHAR: return "char";
48     case V_VOID: return "void";
49     case V_STRUCT: return "struct";
50     case V_LABEL: return "label";
51     case V_BIT: return "bit";
52     case V_SBIT: return "sbit";
53     case V_DOUBLE: return "double";
54     }
55   return "unknown";
56 };
57
58 bucket *SymbolTab[256];         /* the symbol    table  */
59 bucket *StructTab[256];         /* the structure table  */
60 bucket *TypedefTab[256];        /* the typedef   table  */
61 bucket *LabelTab[256];          /* the Label     table  */
62 bucket *enumTab[256];           /* enumerated    table  */
63
64 /*------------------------------------------------------------------*/
65 /* initSymt () - initialises symbol table related stuff             */
66 /*------------------------------------------------------------------*/
67 void 
68 initSymt ()
69 {
70   int i = 0;
71
72   for (i = 0; i < 256; i++)
73     SymbolTab[i] = StructTab[i] = (void *) NULL;
74
75
76 }
77 /*-----------------------------------------------------------------*/
78 /* newBucket - allocates & returns a new bucket        */
79 /*-----------------------------------------------------------------*/
80 bucket *
81 newBucket ()
82 {
83   bucket *bp;
84
85   bp = Safe_alloc ( sizeof (bucket));
86
87   return bp;
88 }
89
90 /*-----------------------------------------------------------------*/
91 /* hashKey - computes the hashkey given a symbol name              */
92 /*-----------------------------------------------------------------*/
93 int 
94 hashKey (const char *s)
95 {
96   unsigned long key = 0;
97
98   while (*s)
99     key += *s++;
100   return key % 256;
101 }
102
103 /*-----------------------------------------------------------------*/
104 /* addSym - adds a symbol to the hash Table                        */
105 /*-----------------------------------------------------------------*/
106 void 
107 addSym (bucket ** stab,
108         void *sym,
109         char *sname,
110         int level,
111         int block,
112         int checkType)
113 {
114   int i;                        /* index into the hash Table */
115   bucket *bp;                   /* temp bucket    *         */
116
117   if (checkType) {
118     symbol *csym = (symbol *)sym;
119
120     if (getenv("DEBUG_SANITY")) {
121       fprintf (stderr, "addSym: %s ", sname);
122     }
123     /* make sure the type is complete and sane */
124     checkTypeSanity(csym->etype, csym->name);
125   }
126
127   /* prevent overflow of the (r)name buffers */
128   if (strlen(sname)>SDCC_SYMNAME_MAX) {
129     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
130     sname[SDCC_SYMNAME_MAX]='\0';
131   }
132
133   /* the symbols are always added at the head of the list  */
134   i = hashKey (sname);
135   /* get a free entry */
136   bp = Safe_alloc ( sizeof (bucket));
137
138   bp->sym = sym;                /* update the symbol pointer  */
139   bp->level = level;            /* update the nest level      */
140   bp->block = block;
141   strcpy (bp->name, sname);     /* copy the name into place */
142
143   /* if this is the first entry */
144   if (stab[i] == NULL)
145     {
146       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
147       stab[i] = bp;
148     }
149   /* not first entry then add @ head of list */
150   else
151     {
152       bp->prev = NULL;
153       stab[i]->prev = bp;
154       bp->next = stab[i];
155       stab[i] = bp;
156     }
157 }
158
159 /*-----------------------------------------------------------------*/
160 /* deleteSym - deletes a symbol from the hash Table  entry     */
161 /*-----------------------------------------------------------------*/
162 void 
163 deleteSym (bucket ** stab, void *sym, char *sname)
164 {
165   int i = 0;
166   bucket *bp;
167
168   i = hashKey (sname);
169
170   bp = stab[i];
171   /* find the symbol */
172   while (bp)
173     {
174       if (bp->sym == sym)       /* found it then break out */
175         break;                  /* of the loop       */
176       bp = bp->next;
177     }
178
179   if (!bp)                      /* did not find it */
180     return;
181   /* if this is the first one in the chain */
182   if (!bp->prev)
183     {
184       stab[i] = bp->next;
185       if (stab[i])              /* if chain ! empty */
186         stab[i]->prev = (void *) NULL;
187     }
188   /* middle || end of chain */
189   else
190     {
191       if (bp->next)             /* if not end of chain */
192         bp->next->prev = bp->prev;
193
194       bp->prev->next = bp->next;
195     }
196
197 }
198
199 /*-----------------------------------------------------------------*/
200 /* findSym - finds a symbol in a table           */
201 /*-----------------------------------------------------------------*/
202 void *
203 findSym (bucket ** stab, void *sym, const char *sname)
204 {
205   bucket *bp;
206
207   bp = stab[hashKey (sname)];
208   while (bp)
209     {
210       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
211         break;
212       bp = bp->next;
213     }
214
215   return (bp ? bp->sym : (void *) NULL);
216 }
217
218 /*-----------------------------------------------------------------*/
219 /* findSymWithLevel - finds a symbol with a name & level           */
220 /*-----------------------------------------------------------------*/
221 void *
222 findSymWithLevel (bucket ** stab, symbol * sym)
223 {
224   bucket *bp;
225
226   bp = stab[hashKey (sym->name)];
227
228   /**
229    **  do the search from the head of the list since the
230    **  elements are added at the head it is ensured that
231    ** we will find the deeper definitions before we find
232    ** the global ones. we need to check for symbols with
233    ** level <= to the level given, if levels match then block
234    ** numbers need to match as well
235    **/
236   while (bp)
237     {
238       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
239         {
240           /* if this is parameter then nothing else need to be checked */
241           if (((symbol *) (bp->sym))->_isparm)
242             return (bp->sym);
243           /* if levels match then block numbers should also match */
244           if (bp->level && bp->level == sym->level && bp->block == sym->block)
245             return (bp->sym);
246           /* if levels don't match then we are okay */
247           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
248             return (bp->sym);
249           /* if this is a global variable then we are ok too */
250           if (bp->level == 0)
251             return (bp->sym);
252         }
253
254       bp = bp->next;
255     }
256
257   return (void *) NULL;
258 }
259
260 /*-----------------------------------------------------------------*/
261 /* findSymWithBlock - finds a symbol with name in with a block     */
262 /*-----------------------------------------------------------------*/
263 void *
264 findSymWithBlock (bucket ** stab, symbol * sym, int block)
265 {
266   bucket *bp;
267
268   bp = stab[hashKey (sym->name)];
269   while (bp)
270     {
271       if (strcmp (bp->name, sym->name) == 0 &&
272           bp->block <= block)
273         break;
274       bp = bp->next;
275     }
276
277   return (bp ? bp->sym : (void *) NULL);
278 }
279
280 /*------------------------------------------------------------------*/
281 /* newSymbol () - returns a new pointer to a symbol                 */
282 /*------------------------------------------------------------------*/
283 symbol *
284 newSymbol (char *name, int scope)
285 {
286   symbol *sym;
287
288   sym = Safe_alloc ( sizeof (symbol));
289
290   strcpy (sym->name, name);     /* copy the name    */
291   sym->level = scope;           /* set the level    */
292   sym->block = currBlockno;
293   sym->lineDef = yylineno;      /* set the line number */
294   return sym;
295 }
296
297 /*------------------------------------------------------------------*/
298 /* newLink - creates a new link (declarator,specifier)              */
299 /*------------------------------------------------------------------*/
300 sym_link *
301 newLink ()
302 {
303   sym_link *p;
304
305   p = Safe_alloc ( sizeof (sym_link));
306
307   return p;
308 }
309
310 /*------------------------------------------------------------------*/
311 /* newStruct - creats a new structdef from the free list            */
312 /*------------------------------------------------------------------*/
313 structdef *
314 newStruct (char *tag)
315 {
316   structdef *s;
317
318   s = Safe_alloc ( sizeof (structdef));
319
320   strcpy (s->tag, tag);         /* copy the tag            */
321   return s;
322 }
323
324 /*------------------------------------------------------------------*/
325 /* pointerTypes - do the computation for the pointer types          */
326 /*------------------------------------------------------------------*/
327 void 
328 pointerTypes (sym_link * ptr, sym_link * type)
329 {
330   if (IS_SPEC (ptr))
331     return;
332
333   /* find the first pointer type */
334   while (ptr && !IS_PTR (ptr))
335     ptr = ptr->next;
336
337   /* could not find it */
338   if (!ptr || IS_SPEC (ptr))
339     return;
340   
341   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
342     pointerTypes (ptr->next, type);
343     return;
344   }
345
346   /* change the pointer type depending on the
347      storage class of the type */
348   if (IS_SPEC (type))
349     {
350       DCL_PTR_CONST (ptr) = SPEC_CONST (type);
351       DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
352       switch (SPEC_SCLS (type))
353         {
354         case S_XDATA:
355           DCL_TYPE (ptr) = FPOINTER;
356           break;
357         case S_IDATA:
358           DCL_TYPE (ptr) = IPOINTER;
359           break;
360         case S_PDATA:
361           DCL_TYPE (ptr) = PPOINTER;
362           break;
363         case S_DATA:
364           DCL_TYPE (ptr) = POINTER;
365           break;
366         case S_CODE:
367           DCL_PTR_CONST (ptr) = port->mem.code_ro;
368           DCL_TYPE (ptr) = CPOINTER;
369           break;
370         case S_EEPROM:
371           DCL_TYPE (ptr) = EEPPOINTER;
372           break;
373         default:
374           DCL_TYPE (ptr) = port->unqualified_pointer;
375           break;
376         }
377       /* the storage class of type ends here */
378       SPEC_SCLS (type) =
379         SPEC_CONST (type) =
380         SPEC_VOLATILE (type) = 0;
381     }
382
383   /* now change all the remaining unknown pointers
384      to generic pointers */
385   while (ptr)
386     {
387       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
388         DCL_TYPE (ptr) = port->unqualified_pointer;
389       ptr = ptr->next;
390     }
391
392   /* same for the type although it is highly unlikely that
393      type will have a pointer */
394   while (type)
395     {
396       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
397         DCL_TYPE (type) = port->unqualified_pointer;
398       type = type->next;
399     }
400
401 }
402
403 /*------------------------------------------------------------------*/
404 /* addDecl - adds a declarator @ the end of a chain                 */
405 /*------------------------------------------------------------------*/
406 void 
407 addDecl (symbol * sym, int type, sym_link * p)
408 {
409   sym_link *head;
410   sym_link *tail;
411   sym_link *t;
412
413   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
414     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
415
416   /* if we are passed a link then set head & tail */
417   if (p)
418     {
419       tail = head = p;
420       while (tail->next)
421         tail = tail->next;
422     }
423   else
424     {
425       head = tail = newLink ();
426       DCL_TYPE (head) = type;
427     }
428
429   /* if this is the first entry   */
430   if (!sym->type)
431     {
432       sym->type = head;
433       sym->etype = tail;
434     }
435   else
436     {
437       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
438         {
439           sym->etype = mergeSpec (sym->etype, head, sym->name);
440         }
441       else
442         {
443           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
444             {
445               t = sym->type;
446               while (t->next != sym->etype)
447                 t = t->next;
448               t->next = head;
449               tail->next = sym->etype;
450             }
451           else
452             {
453               sym->etype->next = head;
454               sym->etype = tail;
455             }
456         }
457     }
458
459   /* if the type is an unknown pointer and has
460      a tspec then take the storage class const & volatile
461      attribute from the tspec & make it those of this
462      symbol */
463   if (p &&
464       !IS_SPEC (p) &&
465       //DCL_TYPE (p) == UPOINTER &&
466       DCL_TSPEC (p))
467     {
468       if (!IS_SPEC (sym->etype))
469         {
470           sym->etype = sym->etype->next = newLink ();
471           sym->etype->class = SPECIFIER;
472         }
473       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
474       SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
475       SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
476       DCL_TSPEC (p) = NULL;
477     }
478
479   // if there is a function in this type chain
480   if (p && funcInChain(sym->type)) {
481     processFuncArgs (sym);
482   }
483
484   return;
485 }
486
487 /*------------------------------------------------------------------
488   checkTypeSanity: prevent the user from doing e.g.:
489   unsigned float uf;
490   ------------------------------------------------------------------*/
491 void checkTypeSanity(sym_link *etype, char *name) {
492   char *noun;
493
494   if (!etype) {
495     if (getenv("DEBUG_SANITY")) {
496       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
497     }
498     return;
499   }
500
501   if (!IS_SPEC(etype)) {
502     if (getenv("DEBUG_SANITY")) {
503       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
504     }
505     return;
506   }
507
508   noun=nounName(etype);
509
510   if (getenv("DEBUG_SANITY")) {
511     fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype);
512   }
513
514   if ((SPEC_NOUN(etype)==V_CHAR || 
515        SPEC_NOUN(etype)==V_FLOAT || 
516        SPEC_NOUN(etype)==V_DOUBLE || 
517        SPEC_NOUN(etype)==V_VOID) &&
518       (etype->select.s._short || SPEC_LONG(etype))) {
519     // long or short for char float double or void
520     werror (E_LONG_OR_SHORT_INVALID, noun, name);
521   }
522   if ((SPEC_NOUN(etype)==V_FLOAT || 
523        SPEC_NOUN(etype)==V_DOUBLE || 
524        SPEC_NOUN(etype)==V_VOID) && 
525       (etype->select.s._signed || SPEC_USIGN(etype))) {
526     // signed or unsigned for float double or void
527     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
528   }
529
530   // special case for "short"
531   if (etype->select.s._short) {
532     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
533     etype->select.s._short = 0;
534   }
535
536   /* if no noun e.g. 
537      "const a;" or "data b;" or "signed s" or "long l"
538      assume an int */
539   if (!SPEC_NOUN(etype)) {
540     SPEC_NOUN(etype)=V_INT;
541   }
542
543   if (etype->select.s._signed && SPEC_USIGN(etype)) {
544     // signed AND unsigned 
545     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
546   }
547   if (etype->select.s._short && SPEC_LONG(etype)) {
548     // short AND long
549     werror (E_LONG_AND_SHORT_INVALID, noun, name);
550   }
551
552 }
553
554 /*------------------------------------------------------------------*/
555 /* mergeSpec - merges two specifiers and returns the new one        */
556 /*------------------------------------------------------------------*/
557 sym_link *
558 mergeSpec (sym_link * dest, sym_link * src, char *name)
559 {
560   sym_link *symlink=dest;
561
562   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
563 #if 0
564     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
565     exit (1);
566 #else
567     werror (E_SYNTAX_ERROR, yytext);
568     // the show must go on
569     return newIntLink();
570 #endif
571   }
572
573   if (SPEC_NOUN(src)) {
574     if (!SPEC_NOUN(dest)) {
575       SPEC_NOUN(dest)=SPEC_NOUN(src);
576     } else {
577       /* we shouldn't redeclare the type */
578       if (getenv("DEBUG_SANITY")) {
579         fprintf (stderr, "mergeSpec: ");
580       }
581       werror(E_TWO_OR_MORE_DATA_TYPES, name);
582     }
583   }
584   
585   if (SPEC_SCLS(src)) {
586     /* if destination has no storage class */
587     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
588       SPEC_SCLS (dest) = SPEC_SCLS (src);
589     } else {
590       if (getenv("DEBUG_SANITY")) {
591         fprintf (stderr, "mergeSpec: ");
592       }
593       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
594     }
595   }
596
597   /* copy all the specifications  */
598
599   // we really should do: 
600 #if 0
601   if (SPEC_what(src)) {
602     if (SPEC_what(dest)) {
603       werror(W_DUPLICATE_SPEC, "what");
604     }
605     SPEC_what(dst)|=SPEC_what(src);
606   }
607 #endif
608   // but there are more important thing right now
609
610   SPEC_LONG (dest) |= SPEC_LONG (src);
611   dest->select.s._short|=src->select.s._short;
612   SPEC_USIGN (dest) |= SPEC_USIGN (src);
613   dest->select.s._signed|=src->select.s._signed;
614   SPEC_STAT (dest) |= SPEC_STAT (src);
615   SPEC_EXTR (dest) |= SPEC_EXTR (src);
616   SPEC_CONST(dest) |= SPEC_CONST (src);
617   SPEC_ABSA (dest) |= SPEC_ABSA (src);
618   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
619   SPEC_ADDR (dest) |= SPEC_ADDR (src);
620   SPEC_OCLS (dest) = SPEC_OCLS (src);
621   SPEC_BLEN (dest) |= SPEC_BLEN (src);
622   SPEC_BSTR (dest) |= SPEC_BSTR (src);
623   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
624   SPEC_ENUM (dest) |= SPEC_ENUM (src);
625   if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
626       SPEC_ARGREG(dest) = SPEC_ARGREG(src);
627   
628   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
629     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
630
631   /* these are the only function attributes that will be set 
632      in a specifier while parsing */
633   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
634   FUNC_BANKED(dest) |= FUNC_BANKED(src);
635   FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
636   FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
637   FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
638   FUNC_ISISR(dest) |= FUNC_ISISR(src);
639   FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
640   FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
641   FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
642   FUNC_INTNO(dest) |= FUNC_INTNO(src);
643   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
644
645   return symlink;
646 }
647
648 /*------------------------------------------------------------------*/
649 /* cloneSpec - copies the entire spec and returns a new spec        */
650 /*------------------------------------------------------------------*/
651 sym_link *
652 cloneSpec (sym_link * src)
653 {
654   sym_link *spec;
655
656   /* go thru chain till we find the specifier */
657   while (src && src->class != SPECIFIER)
658     src = src->next;
659
660   spec = newLink ();
661   memcpy (spec, src, sizeof (sym_link));
662   return spec;
663 }
664
665 /*------------------------------------------------------------------*/
666 /* genSymName - generates and returns a name used for anonymous vars */
667 /*------------------------------------------------------------------*/
668 char *
669 genSymName (int level)
670 {
671   static int gCount = 0;
672   static char gname[SDCC_NAME_MAX + 1];
673
674   sprintf (gname, "__%04d%04d", level, gCount++);
675   return gname;
676 }
677
678 /*------------------------------------------------------------------*/
679 /* getSpec - returns the specifier part from a declaration chain    */
680 /*------------------------------------------------------------------*/
681 sym_link *
682 getSpec (sym_link * p)
683 {
684   sym_link *loop;
685
686   loop = p;
687   while (p && !(IS_SPEC (p)))
688     p = p->next;
689
690   return p;
691 }
692
693 /*------------------------------------------------------------------*/
694 /* newCharLink() - creates an char type                             */
695 /*------------------------------------------------------------------*/
696 sym_link *
697 newCharLink ()
698 {
699   sym_link *p;
700
701   p = newLink ();
702   p->class = SPECIFIER;
703   SPEC_NOUN (p) = V_CHAR;
704
705   return p;
706 }
707
708 /*------------------------------------------------------------------*/
709 /* newFloatLink - a new Float type                                  */
710 /*------------------------------------------------------------------*/
711 sym_link *
712 newFloatLink ()
713 {
714   sym_link *p;
715
716   p = newLink ();
717   p->class = SPECIFIER;
718   SPEC_NOUN (p) = V_FLOAT;
719
720   return p;
721 }
722
723 /*------------------------------------------------------------------*/
724 /* newLongLink() - new long type                                    */
725 /*------------------------------------------------------------------*/
726 sym_link *
727 newLongLink ()
728 {
729   sym_link *p;
730
731   p = newLink ();
732   p->class = SPECIFIER;
733   SPEC_NOUN (p) = V_INT;
734   SPEC_LONG (p) = 1;
735
736   return p;
737 }
738
739 /*------------------------------------------------------------------*/
740 /* newIntLink() - creates an int type                               */
741 /*------------------------------------------------------------------*/
742 sym_link *
743 newIntLink ()
744 {
745   sym_link *p;
746
747   p = newLink ();
748   p->class = SPECIFIER;
749   SPEC_NOUN (p) = V_INT;
750
751   return p;
752 }
753
754 /*------------------------------------------------------------------*/
755 /* getSize - returns size of a type chain in bits                   */
756 /*------------------------------------------------------------------*/
757 unsigned int 
758 getSize (sym_link * p)
759 {
760   /* if nothing return 0 */
761   if (!p)
762     return 0;
763   if (IS_SPEC (p))
764     {                           /* if this is the specifier then */
765       switch (SPEC_NOUN (p))
766         {                       /* depending on the specifier type */
767         case V_INT:
768           return (IS_LONG (p) ? LONGSIZE : INTSIZE);
769         case V_FLOAT:
770           return FLOATSIZE;
771         case V_CHAR:
772           return CHARSIZE;
773         case V_VOID:
774           return 0;
775         case V_STRUCT:
776           return SPEC_STRUCT (p)->size;
777         case V_LABEL:
778           return 0;
779         case V_SBIT:
780           return BITSIZE;
781         case V_BIT:
782           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
783         default:
784           return 0;
785         }
786     }
787
788   /* this is a specifier  */
789   switch (DCL_TYPE (p))
790     {
791     case ARRAY:
792       if (DCL_ELEM(p)) {
793         return DCL_ELEM (p) * getSize (p->next);
794       } else {
795           //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
796           //    "can not tell the size of an array[]");
797         return 0;
798       }
799     case IPOINTER:
800     case PPOINTER:
801     case POINTER:
802       return (PTRSIZE);
803     case EEPPOINTER:
804     case FPOINTER:
805     case CPOINTER:
806     case FUNCTION:
807       return (FPTRSIZE);
808     case GPOINTER:
809       return (GPTRSIZE);
810
811     default:
812       return 0;
813     }
814 }
815
816 /*------------------------------------------------------------------*/
817 /* bitsForType - returns # of bits required to store this type      */
818 /*------------------------------------------------------------------*/
819 unsigned int 
820 bitsForType (sym_link * p)
821 {
822   /* if nothing return 0 */
823   if (!p)
824     return 0;
825
826   if (IS_SPEC (p))
827     {                           /* if this is the specifier then */
828
829       switch (SPEC_NOUN (p))
830         {                       /* depending on the specifier type */
831         case V_INT:
832           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
833         case V_FLOAT:
834           return FLOATSIZE * 8;
835         case V_CHAR:
836           return CHARSIZE * 8;
837         case V_VOID:
838           return 0;
839         case V_STRUCT:
840           return SPEC_STRUCT (p)->size * 8;
841         case V_LABEL:
842           return 0;
843         case V_SBIT:
844           return 1;
845         case V_BIT:
846           return SPEC_BLEN (p);
847         default:
848           return 0;
849         }
850     }
851
852   /* this is a specifier  */
853   switch (DCL_TYPE (p))
854     {
855     case ARRAY:
856       return DCL_ELEM (p) * getSize (p->next) * 8;
857     case IPOINTER:
858     case PPOINTER:
859     case POINTER:
860       return (PTRSIZE * 8);
861     case EEPPOINTER:
862     case FPOINTER:
863     case CPOINTER:
864     case FUNCTION:
865       return (FPTRSIZE * 8);
866     case GPOINTER:
867       return (GPTRSIZE * 8);
868
869     default:
870       return 0;
871     }
872 }
873
874 /*------------------------------------------------------------------*/
875 /* copySymbolChain - copies a symbol chain                          */
876 /*------------------------------------------------------------------*/
877 symbol *
878 copySymbolChain (symbol * src)
879 {
880   symbol *dest;
881
882   if (!src)
883     return NULL;
884
885   dest = copySymbol (src);
886   dest->next = copySymbolChain (src->next);
887   return dest;
888 }
889
890 /*------------------------------------------------------------------*/
891 /* copySymbol - makes a copy of a symbol                            */
892 /*------------------------------------------------------------------*/
893 symbol *
894 copySymbol (symbol * src)
895 {
896   symbol *dest;
897
898   if (!src)
899     return NULL;
900
901   dest = newSymbol (src->name, src->level);
902   memcpy (dest, src, sizeof (symbol));
903   dest->level = src->level;
904   dest->block = src->block;
905   dest->ival = copyIlist (src->ival);
906   dest->type = copyLinkChain (src->type);
907   dest->etype = getSpec (dest->type);
908   dest->next = NULL;
909   dest->key = src->key;
910   dest->allocreq = src->allocreq;
911   return dest;
912 }
913
914 /*------------------------------------------------------------------*/
915 /* reverseSyms - reverses the links for a symbol chain      */
916 /*------------------------------------------------------------------*/
917 symbol *
918 reverseSyms (symbol * sym)
919 {
920   symbol *prev, *curr, *next;
921
922   if (!sym)
923     return NULL;
924
925   prev = sym;
926   curr = sym->next;
927
928   while (curr)
929     {
930       next = curr->next;
931       curr->next = prev;
932       prev = curr;
933       curr = next;
934     }
935   sym->next = (void *) NULL;
936   return prev;
937 }
938
939 /*------------------------------------------------------------------*/
940 /* reverseLink - reverses the links for a type chain        */
941 /*------------------------------------------------------------------*/
942 sym_link *
943 reverseLink (sym_link * type)
944 {
945   sym_link *prev, *curr, *next;
946
947   if (!type)
948     return NULL;
949
950   prev = type;
951   curr = type->next;
952
953   while (curr)
954     {
955       next = curr->next;
956       curr->next = prev;
957       prev = curr;
958       curr = next;
959     }
960   type->next = (void *) NULL;
961   return prev;
962 }
963
964 /*------------------------------------------------------------------*/
965 /* addSymChain - adds a symbol chain to the symboltable             */
966 /*------------------------------------------------------------------*/
967 void 
968 addSymChain (symbol * symHead)
969 {
970   symbol *sym = symHead;
971   symbol *csym = NULL;
972
973   for (; sym != NULL; sym = sym->next)
974     {
975       changePointer(sym);
976       checkTypeSanity(sym->etype, sym->name);
977
978       /* if already exists in the symbol table then check if
979          one of them is an extern definition if yes then
980          then check if the type match, if the types match then
981          delete the current entry and add the new entry      */
982       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
983           csym->level == sym->level) {
984         
985         /* one definition extern ? */
986         if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
987           /* do types match ? */
988           if (compareType (csym->type, sym->type) != 1) {
989             /* no then error */
990             werror (E_EXTERN_MISMATCH, csym->name);
991             continue;
992           }
993           /* delete current entry */
994           deleteSym (SymbolTab, csym, csym->name);
995           deleteFromSeg(csym);
996         } else {
997           /* not extern */
998           werror (E_DUPLICATE, sym->name);
999           continue;
1000         }
1001       }
1002
1003       /* add new entry */
1004       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1005     }
1006 }
1007
1008
1009 /*------------------------------------------------------------------*/
1010 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1011 /*------------------------------------------------------------------*/
1012 int 
1013 funcInChain (sym_link * lnk)
1014 {
1015   while (lnk)
1016     {
1017       if (IS_FUNC (lnk))
1018         return 1;
1019       lnk = lnk->next;
1020     }
1021   return 0;
1022 }
1023
1024 /*------------------------------------------------------------------*/
1025 /* structElemType - returns the type info of a sturct member        */
1026 /*------------------------------------------------------------------*/
1027 sym_link *
1028 structElemType (sym_link * stype, value * id)
1029 {
1030   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1031   sym_link *type, *etype;
1032   sym_link *petype = getSpec (stype);
1033
1034   if (fields && id) {
1035     
1036     /* look for the id */
1037     while (fields)
1038       {
1039         if (strcmp (fields->rname, id->name) == 0)
1040           {
1041             type = copyLinkChain (fields->type);
1042             etype = getSpec (type);
1043             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1044                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
1045             return type;
1046           }
1047         fields = fields->next;
1048       }
1049   }
1050
1051   werror (E_NOT_MEMBER, id->name);
1052     
1053   // the show must go on
1054   return newIntLink();
1055 }
1056
1057 /*------------------------------------------------------------------*/
1058 /* getStructElement - returns element of a tructure definition      */
1059 /*------------------------------------------------------------------*/
1060 symbol *
1061 getStructElement (structdef * sdef, symbol * sym)
1062 {
1063   symbol *field;
1064
1065   for (field = sdef->fields; field; field = field->next)
1066     if (strcmp (field->name, sym->name) == 0)
1067       return field;
1068
1069   werror (E_NOT_MEMBER, sym->name);
1070
1071   return sdef->fields;
1072 }
1073
1074 /*------------------------------------------------------------------*/
1075 /* compStructSize - computes the size of a structure                */
1076 /*------------------------------------------------------------------*/
1077 int 
1078 compStructSize (int su, structdef * sdef)
1079 {
1080     int sum = 0, usum = 0;
1081     int bitOffset = 0;
1082     symbol *loop;
1083
1084     /* for the identifiers  */
1085     loop = sdef->fields;
1086     while (loop) {
1087
1088         /* create the internal name for this variable */
1089         sprintf (loop->rname, "_%s", loop->name);
1090         loop->offset = (su == UNION ? sum = 0 : sum);
1091         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1092
1093         /* if this is a bit field  */
1094         if (loop->bitVar) {
1095
1096             /* change it to a unsigned bit */
1097             SPEC_NOUN (loop->etype) = V_BIT;
1098             SPEC_USIGN (loop->etype) = 1;
1099             /* check if this fit into the remaining   */
1100             /* bits of this byte else align it to the */
1101             /* next byte boundary                     */
1102             if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
1103                 SPEC_BSTR (loop->etype) = bitOffset;
1104                 if ((bitOffset += (loop->bitVar % 8)) == 8)
1105                     sum++;
1106             }
1107             else /* does not fit */ {
1108                 bitOffset = 0;
1109                 SPEC_BSTR (loop->etype) = bitOffset;
1110                 sum += (loop->bitVar / 8);
1111                 bitOffset += (loop->bitVar % 8);
1112             }
1113             /* if this is the last field then pad */
1114             if (!loop->next && bitOffset && bitOffset != 8) {
1115                 bitOffset = 0;
1116                 sum++;
1117             }
1118         }
1119         else {
1120             checkDecl (loop, 1);
1121             sum += getSize (loop->type);
1122         }
1123
1124         loop = loop->next;
1125
1126         /* if this is not a bitfield but the */
1127         /* previous one was and did not take */
1128         /* the whole byte then pad the rest  */
1129         if ((loop && !loop->bitVar) && bitOffset) {
1130             bitOffset = 0;
1131             sum++;
1132         }
1133
1134         /* if union then size = sizeof larget field */
1135         if (su == UNION)
1136             usum = max (usum, sum);
1137
1138     }
1139
1140     return (su == UNION ? usum : sum);
1141 }
1142
1143 /*------------------------------------------------------------------*/
1144 /* checkSClass - check the storage class specification              */
1145 /*------------------------------------------------------------------*/
1146 static void 
1147 checkSClass (symbol * sym, int isProto)
1148 {
1149   if (getenv("DEBUG_SANITY")) {
1150     fprintf (stderr, "checkSClass: %s \n", sym->name);
1151   }
1152   
1153   /* type is literal can happen foe enums change
1154      to auto */
1155   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1156     SPEC_SCLS (sym->etype) = S_AUTO;
1157   
1158   /* if sfr or sbit then must also be */
1159   /* volatile the initial value will be xlated */
1160   /* to an absolute address */
1161   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1162       SPEC_SCLS (sym->etype) == S_SFR)
1163     {
1164       SPEC_VOLATILE (sym->etype) = 1;
1165       /* if initial value given */
1166       if (sym->ival)
1167         {
1168           SPEC_ABSA (sym->etype) = 1;
1169           SPEC_ADDR (sym->etype) =
1170             (int) list2int (sym->ival);
1171           sym->ival = NULL;
1172         }
1173     }
1174   
1175   /* if absolute address given then it mark it as
1176      volatile -- 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       sprintf (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       strcpy (acargs->sym->rname, acargs->name);
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           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1901           val->sym = newSymbol (val->name, 1);
1902           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1903           val->sym->type = copyLinkChain (val->type);
1904           val->sym->etype = getSpec (val->sym->type);
1905           val->sym->_isparm = 1;
1906           strcpy (val->sym->rname, val->name);
1907           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1908             SPEC_STAT (func->etype);
1909           addSymChain (val->sym);
1910
1911         }
1912       else                      /* symbol name given create synth name */
1913         {
1914
1915           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1916           strcpy (val->sym->rname, val->name);
1917           val->sym->_isparm = 1;
1918           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1919             (options.model != MODEL_SMALL ? xdata : data);
1920           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1921             SPEC_STAT (func->etype);
1922         }
1923       val = val->next;
1924     }
1925 }
1926
1927 /*-----------------------------------------------------------------*/
1928 /* isSymbolEqual - compares two symbols return 1 if they match     */
1929 /*-----------------------------------------------------------------*/
1930 int 
1931 isSymbolEqual (symbol * dest, symbol * src)
1932 {
1933   /* if pointers match then equal */
1934   if (dest == src)
1935     return 1;
1936
1937   /* if one of them is null then don't match */
1938   if (!dest || !src)
1939     return 0;
1940
1941   /* if both of them have rname match on rname */
1942   if (dest->rname[0] && src->rname[0])
1943     return (!strcmp (dest->rname, src->rname));
1944
1945   /* otherwise match on name */
1946   return (!strcmp (dest->name, src->name));
1947 }
1948
1949 void PT(sym_link *type)
1950 {
1951         printTypeChain(type,0);
1952 }
1953 /*-----------------------------------------------------------------*/
1954 /* printTypeChain - prints the type chain in human readable form   */
1955 /*-----------------------------------------------------------------*/
1956 void
1957 printTypeChain (sym_link * start, FILE * of)
1958 {
1959   int nlr = 0;
1960   sym_link * type, * search;
1961
1962   if (!of)
1963     {
1964       of = stdout;
1965       nlr = 1;
1966     }
1967
1968   if (start==NULL) {
1969     fprintf (of, "void");
1970     return;
1971   }
1972
1973   /* print the chain as it is written in the source: */
1974   /* start with the last entry                       */
1975   for (type = start; type && type->next; type = type->next)
1976     ;
1977   while (type)
1978     {
1979       if (IS_DECL (type))
1980         {
1981           if (DCL_PTR_VOLATILE (type)) {
1982             fprintf (of, "volatile ");
1983           }
1984           switch (DCL_TYPE (type))
1985             {
1986             case FUNCTION:
1987               fprintf (of, "function %s %s", 
1988                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
1989                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
1990               break;
1991             case GPOINTER:
1992               if (DCL_PTR_CONST (type))
1993                 fprintf (of, "const ");
1994               fprintf (of, "generic * ");
1995               break;
1996             case CPOINTER:
1997               if (DCL_PTR_CONST (type))
1998                 fprintf (of, "const ");
1999               fprintf (of, "code * ");
2000               break;
2001             case FPOINTER:
2002               if (DCL_PTR_CONST (type))
2003                 fprintf (of, "const ");
2004               fprintf (of, "xdata * ");
2005               break;
2006             case EEPPOINTER:
2007               if (DCL_PTR_CONST (type))
2008                 fprintf (of, "const ");
2009               fprintf (of, "eeprom * ");
2010               break;
2011
2012             case POINTER:
2013               if (DCL_PTR_CONST (type))
2014                 fprintf (of, "const ");
2015               fprintf (of, "near *");
2016               break;
2017             case IPOINTER:
2018               if (DCL_PTR_CONST (type))
2019                 fprintf (of, "const ");
2020               fprintf (of, "idata * ");
2021               break;
2022             case PPOINTER:
2023               if (DCL_PTR_CONST (type))
2024                 fprintf (of, "const ");
2025               fprintf (of, "pdata * ");
2026               break;
2027             case UPOINTER:
2028               if (DCL_PTR_CONST (type))
2029                 fprintf (of, "const ");
2030               fprintf (of, "unkown * ");
2031               break;
2032             case ARRAY:
2033               if (DCL_ELEM(type)) {
2034                 fprintf (of, "[%d] ", DCL_ELEM(type));
2035               } else {
2036                 fprintf (of, "[] ");
2037               }
2038               break;
2039             }
2040         }
2041       else
2042         {
2043           switch (SPEC_SCLS(type)) 
2044             {
2045             case S_DATA: fprintf (of, "data "); break;
2046             case S_XDATA: fprintf (of, "xdata "); break;
2047             case S_SFR: fprintf (of, "sfr "); break;
2048             case S_SBIT: fprintf (of, "sbit "); break;
2049             case S_CODE: fprintf (of, "code "); break;
2050             case S_IDATA: fprintf (of, "idata "); break;
2051             case S_PDATA: fprintf (of, "pdata "); break;
2052             case S_LITERAL: fprintf (of, "literal "); break;
2053             case S_STACK: fprintf (of, "stack "); break;
2054             case S_XSTACK: fprintf (of, "xstack "); break;
2055             case S_BIT: fprintf (of, "bit "); break;
2056             case S_EEPROM: fprintf (of, "eeprom "); break;
2057             default: break;
2058             }
2059
2060           if (SPEC_VOLATILE (type))
2061             fprintf (of, "volatile ");
2062           if (SPEC_USIGN (type))
2063             fprintf (of, "unsigned ");
2064           if (SPEC_CONST (type))
2065             fprintf (of, "const ");
2066           switch (SPEC_NOUN (type))
2067             {
2068             case V_INT:
2069               if (IS_LONG (type))
2070                 fprintf (of, "long ");
2071               fprintf (of, "int");
2072               break;
2073
2074             case V_CHAR:
2075               fprintf (of, "char");
2076               break;
2077
2078             case V_VOID:
2079               fprintf (of, "void");
2080               break;
2081
2082             case V_FLOAT:
2083               fprintf (of, "float");
2084               break;
2085
2086             case V_STRUCT:
2087               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2088               break;
2089
2090             case V_SBIT:
2091               fprintf (of, "sbit");
2092               break;
2093
2094             case V_BIT:
2095               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2096               break;
2097
2098             case V_DOUBLE:
2099               fprintf (of, "double");
2100               break;
2101
2102             default:
2103               fprintf (of, "unknown type");
2104               break;
2105             }
2106         }
2107         /* search entry in list before "type" */
2108     for (search = start; search && search->next != type;)
2109        search = search->next;
2110     type = search;
2111     if (type)
2112       fputc (' ', of);
2113     }
2114   if (nlr)
2115     fprintf (of, "\n");
2116 }
2117
2118 /*-----------------------------------------------------------------*/
2119 /* cdbTypeInfo - print the type information for debugger           */
2120 /*-----------------------------------------------------------------*/
2121 void
2122 cdbTypeInfo (sym_link * type, FILE * of)
2123 {
2124   fprintf (of, "{%d}", getSize (type));
2125   while (type)
2126     {
2127       if (IS_DECL (type))
2128         {
2129           switch (DCL_TYPE (type))
2130             {
2131             case FUNCTION:
2132               fprintf (of, "DF,");
2133               break;
2134             case GPOINTER:
2135               fprintf (of, "DG,");
2136               break;
2137             case CPOINTER:
2138               fprintf (of, "DC,");
2139               break;
2140             case FPOINTER:
2141               fprintf (of, "DX,");
2142               break;
2143             case POINTER:
2144               fprintf (of, "DD,");
2145               break;
2146             case IPOINTER:
2147               fprintf (of, "DI,");
2148               break;
2149             case PPOINTER:
2150               fprintf (of, "DP,");
2151               break;
2152             case EEPPOINTER:
2153               fprintf (of, "DA,");
2154               break;
2155             case ARRAY:
2156               fprintf (of, "DA%d,", DCL_ELEM (type));
2157               break;
2158             default:
2159               break;
2160             }
2161         }
2162       else
2163         {
2164           switch (SPEC_NOUN (type))
2165             {
2166             case V_INT:
2167               if (IS_LONG (type))
2168                 fprintf (of, "SL");
2169               else
2170                 fprintf (of, "SI");
2171               break;
2172
2173             case V_CHAR:
2174               fprintf (of, "SC");
2175               break;
2176
2177             case V_VOID:
2178               fprintf (of, "SV");
2179               break;
2180
2181             case V_FLOAT:
2182               fprintf (of, "SF");
2183               break;
2184
2185             case V_STRUCT:
2186               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2187               break;
2188
2189             case V_SBIT:
2190               fprintf (of, "SX");
2191               break;
2192
2193             case V_BIT:
2194               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2195               break;
2196
2197             default:
2198               break;
2199             }
2200           fputs (":", of);
2201           if (SPEC_USIGN (type))
2202             fputs ("U", of);
2203           else
2204             fputs ("S", of);
2205         }
2206       type = type->next;
2207     }
2208 }
2209 /*-----------------------------------------------------------------*/
2210 /* cdbSymbol - prints a symbol & its type information for debugger */
2211 /*-----------------------------------------------------------------*/
2212 void 
2213 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2214 {
2215   memmap *map;
2216
2217   if (!sym)
2218     return;
2219   if (!of)
2220     of = stdout;
2221
2222   if (isFunc)
2223     fprintf (of, "F:");
2224   else
2225     fprintf (of, "S:");         /* symbol record */
2226   /* if this is not a structure symbol then
2227      we need to figure out the scope information */
2228   if (!isStructSym)
2229     {
2230       if (!sym->level)
2231         {
2232           /* global */
2233           if (IS_STATIC (sym->etype))
2234             fprintf (of, "F%s$", moduleName);   /* scope is file */
2235           else
2236             fprintf (of, "G$"); /* scope is global */
2237         }
2238       else
2239         /* symbol is local */
2240         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2241     }
2242   else
2243     fprintf (of, "S$");         /* scope is structure */
2244
2245   /* print the name, & mangled name */
2246   fprintf (of, "%s$%d$%d(", sym->name,
2247            sym->level, sym->block);
2248
2249   cdbTypeInfo (sym->type, of);
2250   fprintf (of, "),");
2251
2252   /* print the address space */
2253   map = SPEC_OCLS (sym->etype);
2254   fprintf (of, "%c,%d,%d",
2255            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2256
2257   /* if assigned to registers then output register names */
2258   /* if this is a function then print
2259      if is it an interrupt routine & interrupt number
2260      and the register bank it is using */
2261   if (isFunc)
2262     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2263              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2264   /* alternate location to find this symbol @ : eg registers
2265      or spillication */
2266
2267   if (!isStructSym)
2268     fprintf (of, "\n");
2269 }
2270
2271 /*-----------------------------------------------------------------*/
2272 /* cdbStruct - print a structure for debugger                      */
2273 /*-----------------------------------------------------------------*/
2274 void 
2275 cdbStruct (structdef * sdef, int block, FILE * of,
2276            int inStruct, char *tag)
2277 {
2278   symbol *sym;
2279
2280   fprintf (of, "T:");
2281   /* if block # then must have function scope */
2282   fprintf (of, "F%s$", moduleName);
2283   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2284   for (sym = sdef->fields; sym; sym = sym->next)
2285     {
2286       fprintf (of, "({%d}", sym->offset);
2287       cdbSymbol (sym, of, TRUE, FALSE);
2288       fprintf (of, ")");
2289     }
2290   fprintf (of, "]");
2291   if (!inStruct)
2292     fprintf (of, "\n");
2293 }
2294
2295 /*------------------------------------------------------------------*/
2296 /* cdbStructBlock - calls struct printing for a blcks               */
2297 /*------------------------------------------------------------------*/
2298 void 
2299 cdbStructBlock (int block, FILE * of)
2300 {
2301   int i;
2302   bucket **table = StructTab;
2303   bucket *chain;
2304   wassert (of);
2305
2306   /* go thru the entire  table  */
2307   for (i = 0; i < 256; i++)
2308     {
2309       for (chain = table[i]; chain; chain = chain->next)
2310         {
2311           if (chain->block >= block)
2312             {
2313               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2314             }
2315         }
2316     }
2317 }
2318
2319 /*-----------------------------------------------------------------*/
2320 /* powof2 - returns power of two for the number if number is pow 2 */
2321 /*-----------------------------------------------------------------*/
2322 int 
2323 powof2 (unsigned long num)
2324 {
2325   int nshifts = 0;
2326   int n1s = 0;
2327
2328   while (num)
2329     {
2330       if (num & 1)
2331         n1s++;
2332       num >>= 1;
2333       nshifts++;
2334     }
2335
2336   if (n1s > 1 || nshifts == 0)
2337     return 0;
2338   return nshifts - 1;
2339 }
2340
2341 symbol *__fsadd;
2342 symbol *__fssub;
2343 symbol *__fsmul;
2344 symbol *__fsdiv;
2345 symbol *__fseq;
2346 symbol *__fsneq;
2347 symbol *__fslt;
2348 symbol *__fslteq;
2349 symbol *__fsgt;
2350 symbol *__fsgteq;
2351
2352 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2353 symbol *__muldiv[3][3][2];
2354 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2355 sym_link *__multypes[3][2];
2356 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2357 symbol *__conv[2][3][2];
2358 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2359 symbol *__rlrr[2][3][2];
2360
2361 sym_link *floatType;
2362
2363 static char *
2364 _mangleFunctionName(char *in)
2365 {
2366   if (port->getMangledFunctionName) 
2367     {
2368       return port->getMangledFunctionName(in);
2369     }
2370   else
2371     {
2372       return in;
2373     }
2374 }
2375
2376 /*-----------------------------------------------------------------*/
2377 /* typeFromStr - create a typechain from an encoded string         */
2378 /* basic types -        'c' - char                                 */
2379 /*                      's' - short                                */
2380 /*                      'i' - int                                  */
2381 /*                      'l' - long                                 */
2382 /*                      'f' - float                                */
2383 /*                      'v' - void                                 */
2384 /*                      '*' - pointer - default (GPOINTER)         */
2385 /* modifiers -          'u' - unsigned                             */
2386 /* pointer modifiers -  'g' - generic                              */
2387 /*                      'x' - xdata                                */
2388 /*                      'p' - code                                 */
2389 /*                      'd' - data                                 */                     
2390 /*                      'F' - function                             */                     
2391 /* examples : "ig*" - generic int *                                */
2392 /*            "cx*" - char xdata *                                 */
2393 /*            "ui" -  unsigned int                                 */
2394 /*-----------------------------------------------------------------*/
2395 sym_link *typeFromStr (char *s)
2396 {
2397     sym_link *r = newLink();
2398     int usign = 0;
2399
2400     do {
2401         sym_link *nr;
2402         switch (*s) {
2403         case 'u' : 
2404             usign = 1;
2405             s++;
2406             continue ;
2407             break ;
2408         case 'c':
2409             r->class = SPECIFIER;
2410             SPEC_NOUN(r) = V_CHAR;
2411             break;
2412         case 's':
2413         case 'i':
2414             r->class = SPECIFIER;
2415             SPEC_NOUN(r) = V_INT;
2416             break;
2417         case 'l':
2418             r->class = SPECIFIER;
2419             SPEC_NOUN(r) = V_INT;
2420             SPEC_LONG(r) = 1;
2421             break;
2422         case 'f':
2423             r->class = SPECIFIER;
2424             SPEC_NOUN(r) = V_FLOAT;
2425             break;
2426         case 'v':
2427             r->class = SPECIFIER;
2428             SPEC_NOUN(r) = V_VOID;
2429             break;
2430         case '*':
2431             DCL_TYPE(r) = port->unqualified_pointer;
2432             break;
2433         case 'g':
2434         case 'x':
2435         case 'p':
2436         case 'd':
2437         case 'F':
2438             assert(*(s+1)=='*');
2439             nr = newLink();
2440             nr->next = r;
2441             r = nr;
2442             r->class = DECLARATOR ;
2443             switch (*s) {
2444             case 'g':
2445                 DCL_TYPE(r) = GPOINTER;
2446                 break;
2447             case 'x':
2448                 DCL_TYPE(r) = FPOINTER;
2449                 break;
2450             case 'p':
2451                 DCL_TYPE(r) = CPOINTER;
2452                 break;
2453             case 'd':
2454                 DCL_TYPE(r) = POINTER;
2455                 break;
2456             case 'F':
2457                 DCL_TYPE(r) = FUNCTION;
2458                 nr = newLink();
2459                 nr->next = r;
2460                 r = nr;
2461                 r->class = DECLARATOR ;
2462                 DCL_TYPE(r) = CPOINTER;
2463                 break;
2464             }
2465             s++;
2466             break;
2467         default:
2468             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2469                    "typeFromStr: unknown type");
2470             break;
2471         }
2472         if (IS_SPEC(r) && usign) {
2473             SPEC_USIGN(r) = 1;
2474             usign = 0;
2475         }
2476         s++;
2477     } while (*s);
2478     return r;
2479 }
2480
2481 /*-----------------------------------------------------------------*/
2482 /* initCSupport - create functions for C support routines          */
2483 /*-----------------------------------------------------------------*/
2484 void 
2485 initCSupport ()
2486 {
2487   const char *smuldivmod[] =
2488   {
2489     "mul", "div", "mod"
2490   };
2491   const char *sbwd[] =
2492   {
2493     "char", "int", "long"
2494   };
2495   const char *ssu[] =
2496   {
2497     "s", "u"
2498   };
2499   const char *srlrr[] =
2500   {
2501     "rl", "rr"
2502   };
2503
2504   int bwd, su, muldivmod, tofrom, rlrr;
2505
2506   if (getenv("SDCC_NO_C_SUPPORT")) {
2507     /* for debugging only */
2508     return;
2509   }
2510
2511   floatType = newFloatLink ();
2512
2513   for (bwd = 0; bwd < 3; bwd++)
2514     {
2515       sym_link *l = NULL;
2516       switch (bwd)
2517         {
2518         case 0:
2519           l = newCharLink ();
2520           break;
2521         case 1:
2522           l = newIntLink ();
2523           break;
2524         case 2:
2525           l = newLongLink ();
2526           break;
2527         default:
2528           assert (0);
2529         }
2530       __multypes[bwd][0] = l;
2531       __multypes[bwd][1] = copyLinkChain (l);
2532       SPEC_USIGN (__multypes[bwd][1]) = 1;
2533     }
2534
2535   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2536   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2537   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2538   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2539   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2540   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2541   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2542   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2543   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2544   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2545
2546   for (tofrom = 0; tofrom < 2; tofrom++)
2547     {
2548       for (bwd = 0; bwd < 3; bwd++)
2549         {
2550           for (su = 0; su < 2; su++)
2551             {
2552               if (tofrom)
2553                 {
2554                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2555                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2556                 }
2557               else
2558                 {
2559                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2560                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2561                 }
2562             }
2563         }
2564     }
2565
2566   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2567     {
2568       for (bwd = 0; bwd < 3; bwd++)
2569         {
2570           for (su = 0; su < 2; su++)
2571             {
2572               sprintf (buffer, "_%s%s%s",
2573                        smuldivmod[muldivmod],
2574                        ssu[su],
2575                        sbwd[bwd]);
2576               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2577               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2578             }
2579         }
2580     }
2581
2582   for (rlrr = 0; rlrr < 2; rlrr++)
2583     {
2584       for (bwd = 0; bwd < 3; bwd++)
2585         {
2586           for (su = 0; su < 2; su++)
2587             {
2588               sprintf (buffer, "_%s%s%s",
2589                        srlrr[rlrr],
2590                        ssu[su],
2591                        sbwd[bwd]);
2592               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2593               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2594             }
2595         }
2596     }
2597 }
2598
2599 /*-----------------------------------------------------------------*/
2600 /* initBuiltIns - create prototypes for builtin functions          */
2601 /*-----------------------------------------------------------------*/
2602 void initBuiltIns()
2603 {
2604     int i;
2605     symbol *sym;
2606
2607     if (!port->builtintable) return ;
2608
2609     for (i = 0 ; port->builtintable[i].name ; i++) {
2610         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2611                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2612         FUNC_ISBUILTIN(sym->type) = 1;
2613         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2614     }
2615 }