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