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