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