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