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