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