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