* src/SDCCsymt.c (structElemType): fixed bug #808291 (members
[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 sturct 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 (((/*!IS_LITERAL(type1) &&*/ SPEC_USIGN (etype1)) ||
1513        (/*!IS_LITERAL(type2) &&*/ SPEC_USIGN (etype2))) &&
1514       !IS_FLOAT (reType))
1515     SPEC_USIGN (reType) = 1;
1516   else
1517     SPEC_USIGN (reType) = 0;
1518
1519   /* if result is a literal then make not so */
1520   if (IS_LITERAL (reType))
1521     SPEC_SCLS (reType) = S_REGISTER;
1522
1523   return rType;
1524 }
1525
1526 /*--------------------------------------------------------------------*/
1527 /* compareType - will do type check return 1 if match, -1 if castable */
1528 /*--------------------------------------------------------------------*/
1529 int
1530 compareType (sym_link * dest, sym_link * src)
1531 {
1532   if (!dest && !src)
1533     return 1;
1534
1535   if (dest && !src)
1536     return 0;
1537
1538   if (src && !dest)
1539     return 0;
1540
1541   /* if dest is a declarator then */
1542   if (IS_DECL (dest))
1543     {
1544       if (IS_DECL (src))
1545         {
1546           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1547             if (IS_FUNC(src)) {
1548               //checkFunction(src,dest);
1549             }
1550             return compareType (dest->next, src->next);
1551           }
1552           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1553             return 1;
1554           }
1555           if (IS_PTR (src) && IS_GENPTR (dest))
1556             return -1;
1557           if (IS_PTR (dest) && IS_ARRAY (src)) {
1558             value *val=aggregateToPointer (valFromType(src));
1559             int res=compareType (dest, val->type);
1560             Safe_free(val->type);
1561             Safe_free(val);
1562             return res;
1563           }
1564           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1565             return compareType (dest->next, src);
1566           return 0;
1567         }
1568       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1569         return -1;
1570       else
1571         return 0;
1572     }
1573
1574   /* if one is a specifier and the other is not */
1575   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1576       (IS_SPEC (dest) && !IS_SPEC (src)))
1577     return 0;
1578
1579   /* if one of them is a void then ok */
1580   if (SPEC_NOUN (dest) == V_VOID &&
1581       SPEC_NOUN (src) != V_VOID)
1582     return -1;
1583
1584   if (SPEC_NOUN (dest) != V_VOID &&
1585       SPEC_NOUN (src) == V_VOID)
1586     return -1;
1587
1588   /* if they are both bitfields then if the lengths
1589      and starts don't match */
1590   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1591       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1592        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1593     return -1;
1594
1595   /* it is a specifier */
1596   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1597     {
1598       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1599           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1600           getSize (dest) == getSize (src))
1601         return 1;
1602       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1603         return -1;
1604       else
1605         return 0;
1606     }
1607   else if (IS_STRUCT (dest))
1608     {
1609       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1610         return 0;
1611       else
1612         return 1;
1613     }
1614   if (SPEC_LONG (dest) != SPEC_LONG (src))
1615     return -1;
1616
1617   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1618     return -1;
1619
1620   return 1;
1621 }
1622
1623 /*------------------------------------------------------------------*/
1624 /* inCalleeSaveList - return 1 if found in callee save list          */
1625 /*------------------------------------------------------------------*/
1626 static int
1627 calleeCmp(void *p1, void *p2)
1628 {
1629   return (strcmp((char *)p1, (char *)(p2)) == 0);
1630 }
1631
1632 bool
1633 inCalleeSaveList(char *s)
1634 {
1635   if (options.all_callee_saves)
1636     return 1;
1637   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
1638 }
1639
1640 /*-----------------------------------------------------------------*/
1641 /* aggregateToPointer:  change an agggregate type function      */
1642 /*         argument to a pointer to that type.     */
1643 /*-----------------------------------------------------------------*/
1644 value *
1645 aggregateToPointer (value * val)
1646 {
1647   if (IS_AGGREGATE (val->type))
1648     {
1649       /* if this is a structure */
1650       /* then we need to add a new link */
1651       if (IS_STRUCT (val->type))
1652         {
1653           /* first lets add DECLARATOR type */
1654           sym_link *p = val->type;
1655
1656           werror (W_STRUCT_AS_ARG, val->name);
1657           val->type = newLink (DECLARATOR);
1658           val->type->next = p;
1659         }
1660
1661       /* change to a pointer depending on the */
1662       /* storage class specified        */
1663       switch (SPEC_SCLS (val->etype))
1664         {
1665         case S_IDATA:
1666           DCL_TYPE (val->type) = IPOINTER;
1667           break;
1668         case S_PDATA:
1669           DCL_TYPE (val->type) = PPOINTER;
1670           break;
1671         case S_FIXED:
1672           if (SPEC_OCLS(val->etype)) {
1673             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1674           } else {
1675             // this happens for (external) function parameters
1676             DCL_TYPE (val->type) = port->unqualified_pointer;
1677           }
1678           break;
1679         case S_AUTO:
1680         case S_DATA:
1681         case S_REGISTER:
1682           DCL_TYPE (val->type) = POINTER;
1683           break;
1684         case S_CODE:
1685           DCL_TYPE (val->type) = CPOINTER;
1686           break;
1687         case S_XDATA:
1688           DCL_TYPE (val->type) = FPOINTER;
1689           break;
1690         case S_EEPROM:
1691           DCL_TYPE (val->type) = EEPPOINTER;
1692           break;
1693         default:
1694           DCL_TYPE (val->type) = port->unqualified_pointer;
1695         }
1696       
1697       /* is there is a symbol associated then */
1698       /* change the type of the symbol as well */
1699       if (val->sym)
1700         {
1701           val->sym->type = copyLinkChain (val->type);
1702           val->sym->etype = getSpec (val->sym->type);
1703         }
1704     }
1705   return val;
1706 }
1707 /*------------------------------------------------------------------*/
1708 /* checkFunction - does all kinds of check on a function            */
1709 /*------------------------------------------------------------------*/
1710 int 
1711 checkFunction (symbol * sym, symbol *csym)
1712 {
1713   value *exargs, *acargs;
1714   value *checkValue;
1715   int argCnt = 0;
1716
1717   if (getenv("DEBUG_SANITY")) {
1718     fprintf (stderr, "checkFunction: %s ", sym->name);
1719   }
1720
1721   /* make sure the type is complete and sane */
1722   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1723
1724   /* if not type then some kind of error */
1725   if (!sym->type)
1726     return 0;
1727
1728   /* if the function has no type then make it return int */
1729   if (!sym->type->next)
1730     sym->type->next = sym->etype = newIntLink ();
1731
1732   /* function cannot return aggregate */
1733   if (IS_AGGREGATE (sym->type->next))
1734     {
1735       werror (E_FUNC_AGGR, sym->name);
1736       return 0;
1737     }
1738
1739   /* function cannot return bit */
1740   if (IS_BITVAR (sym->type->next))
1741     {
1742       werror (E_FUNC_BIT, sym->name);
1743       return 0;
1744     }
1745
1746   /* check if this function is defined as calleeSaves
1747      then mark it as such */
1748   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1749
1750   /* if interrupt service routine  */
1751   /* then it cannot have arguments */
1752   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1753     {
1754       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1755         werror (E_INT_ARGS, sym->name);
1756         FUNC_ARGS(sym->type)=NULL;
1757       }
1758     }
1759
1760   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1761        acargs; 
1762        acargs=acargs->next, argCnt++) {
1763     if (!acargs->sym) { 
1764       // this can happen for reentrant functions
1765       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1766       // the show must go on: synthesize a name and symbol
1767       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
1768       acargs->sym = newSymbol (acargs->name, 1);
1769       SPEC_OCLS (acargs->etype) = istack;
1770       acargs->sym->type = copyLinkChain (acargs->type);
1771       acargs->sym->etype = getSpec (acargs->sym->type);
1772       acargs->sym->_isparm = 1;
1773       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
1774     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
1775       // synthesized name
1776       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1777     }
1778   }
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   /* compare expected args with actual args */
1814   exargs = FUNC_ARGS(csym->type);
1815   acargs = FUNC_ARGS(sym->type);
1816
1817   /* for all the expected args do */
1818   for (argCnt = 1;
1819        exargs && acargs;
1820        exargs = exargs->next, acargs = acargs->next, argCnt++)
1821     {
1822       if (getenv("DEBUG_SANITY")) {
1823         fprintf (stderr, "checkFunction: %s ", exargs->name);
1824       }
1825       /* make sure the type is complete and sane */
1826       checkTypeSanity(exargs->etype, exargs->name);
1827
1828       /* If the actual argument is an array, any prototype
1829        * will have modified it to a pointer. Duplicate that
1830        * change here.
1831        */
1832       if (IS_AGGREGATE (acargs->type))
1833         {
1834           checkValue = copyValue (acargs);
1835           aggregateToPointer (checkValue);
1836         }
1837       else
1838         {
1839           checkValue = acargs;
1840         }
1841
1842       if (compareType (exargs->type, checkValue->type) <= 0)
1843         {
1844           werror (E_ARG_TYPE, argCnt);
1845           printFromToType(exargs->type, checkValue->type);
1846           return 0;
1847         }
1848     }
1849
1850   /* if one them ended we have a problem */
1851   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1852       (!exargs && acargs && !IS_VOID (acargs->type)))
1853     werror (E_ARG_COUNT);
1854
1855   /* replace with this defition */
1856   sym->cdef = csym->cdef;
1857   deleteSym (SymbolTab, csym, csym->name);
1858   deleteFromSeg(csym);
1859   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1860   if (IS_EXTERN (csym->etype) && !
1861       IS_EXTERN (sym->etype))
1862     {
1863       addSet (&publics, sym);
1864     }
1865   return 1;
1866 }
1867
1868 /*------------------------------------------------------------------*/
1869 /* cdbStructBlock - calls struct printing for a blcks               */
1870 /*------------------------------------------------------------------*/
1871 void cdbStructBlock (int block)
1872 {
1873   int i;
1874   bucket **table = StructTab;
1875   bucket *chain;
1876
1877   /* go thru the entire  table  */
1878   for (i = 0; i < 256; i++)
1879     {
1880       for (chain = table[i]; chain; chain = chain->next)
1881         {
1882           if (chain->block >= block)
1883             {
1884               if(debugFile)
1885                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
1886             }
1887         }
1888     }
1889 }
1890
1891 /*-----------------------------------------------------------------*/
1892 /* processFuncArgs - does some processing with function args       */
1893 /*-----------------------------------------------------------------*/
1894 void 
1895 processFuncArgs (symbol * func)
1896 {
1897   value *val;
1898   int pNum = 1;
1899   sym_link *funcType=func->type;
1900
1901   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1902     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1903
1904   // if this is a pointer to a function
1905   if (IS_PTR(funcType)) {
1906     funcType=funcType->next;
1907   }
1908
1909   /* if this function has variable argument list */
1910   /* then make the function a reentrant one    */
1911   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1912     FUNC_ISREENT(funcType)=1;
1913
1914   /* check if this function is defined as calleeSaves
1915      then mark it as such */
1916   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1917
1918   /* loop thru all the arguments   */
1919   val = FUNC_ARGS(funcType);
1920
1921   /* if it is void then remove parameters */
1922   if (val && IS_VOID (val->type))
1923     {
1924       FUNC_ARGS(funcType) = NULL;
1925       return;
1926     }
1927
1928   /* reset regparm for the port */
1929   (*port->reset_regparms) ();
1930   /* if any of the arguments is an aggregate */
1931   /* change it to pointer to the same type */
1932   while (val)
1933     {
1934         int argreg = 0;
1935       /* mark it as a register parameter if
1936          the function does not have VA_ARG
1937          and as port dictates */
1938       if (!IFFUNC_HASVARARGS(funcType) &&
1939           (argreg = (*port->reg_parm) (val->type)))
1940         {
1941           SPEC_REGPARM (val->etype) = 1;
1942           SPEC_ARGREG(val->etype) = argreg;
1943         } else if (IFFUNC_ISREENT(funcType)) {
1944             FUNC_HASSTACKPARM(funcType) = 1;
1945         }
1946
1947       if (IS_AGGREGATE (val->type))
1948         {
1949           aggregateToPointer (val);
1950         }
1951
1952       val = val->next;
1953       pNum++;
1954     }
1955
1956   /* if this is an internal generated function call */
1957   if (func->cdef) {
1958     /* ignore --stack-auto for this one, we don't know how it is compiled */
1959     /* simply trust on --int-long-reent or --float-reent */
1960     if (IFFUNC_ISREENT(funcType)) {
1961       return;
1962     }
1963   } else {
1964     /* if this function is reentrant or */
1965     /* automatics r 2b stacked then nothing */
1966     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1967       return;
1968   }
1969
1970   val = FUNC_ARGS(funcType);
1971   pNum = 1;
1972   while (val)
1973     {
1974
1975       /* if a symbolname is not given  */
1976       /* synthesize a variable name */
1977       if (!val->sym)
1978         {
1979           SNPRINTF (val->name, sizeof(val->name), 
1980                     "_%s_PARM_%d", func->name, pNum++);
1981           val->sym = newSymbol (val->name, 1);
1982           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1983           val->sym->type = copyLinkChain (val->type);
1984           val->sym->etype = getSpec (val->sym->type);
1985           val->sym->_isparm = 1;
1986           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1987           if (IS_SPEC(func->etype)) {
1988             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1989               SPEC_STAT (func->etype);
1990           }
1991           addSymChain (val->sym);
1992
1993         }
1994       else                      /* symbol name given create synth name */
1995         {
1996
1997           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
1998           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1999           val->sym->_isparm = 1;
2000           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2001             (options.model != MODEL_SMALL ? xdata : data);
2002           if (IS_SPEC(func->etype)) {
2003             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2004               SPEC_STAT (func->etype);
2005           }
2006         }
2007       if (!isinSet(operKeyReset, val->sym)) {
2008         addSet (&operKeyReset, val->sym);
2009         applyToSet (operKeyReset, resetParmKey);
2010       }
2011       val = val->next;
2012     }
2013 }
2014
2015 /*-----------------------------------------------------------------*/
2016 /* isSymbolEqual - compares two symbols return 1 if they match     */
2017 /*-----------------------------------------------------------------*/
2018 int 
2019 isSymbolEqual (symbol * dest, symbol * src)
2020 {
2021   /* if pointers match then equal */
2022   if (dest == src)
2023     return 1;
2024
2025   /* if one of them is null then don't match */
2026   if (!dest || !src)
2027     return 0;
2028
2029   /* if both of them have rname match on rname */
2030   if (dest->rname[0] && src->rname[0])
2031     return (!strcmp (dest->rname, src->rname));
2032
2033   /* otherwise match on name */
2034   return (!strcmp (dest->name, src->name));
2035 }
2036
2037 void PT(sym_link *type)
2038 {
2039         printTypeChain(type,0);
2040 }
2041 /*-----------------------------------------------------------------*/
2042 /* printTypeChain - prints the type chain in human readable form   */
2043 /*-----------------------------------------------------------------*/
2044 void
2045 printTypeChain (sym_link * start, FILE * of)
2046 {
2047   int nlr = 0;
2048   value *args;
2049   sym_link * type, * search;
2050   STORAGE_CLASS scls;
2051
2052   if (!of)
2053     {
2054       of = stdout;
2055       nlr = 1;
2056     }
2057
2058   if (start==NULL) {
2059     fprintf (of, "void");
2060     return;
2061   }
2062
2063   /* Print the chain as it is written in the source: */
2064   /* start with the last entry.                      */
2065   /* However, the storage class at the end of the    */
2066   /* chain reall applies to the first in the chain!  */
2067
2068   for (type = start; type && type->next; type = type->next)
2069     ;
2070   if (IS_SPEC (type))
2071     scls=SPEC_SCLS(type);
2072   else
2073     scls=0;
2074   while (type)
2075     {
2076       if (type==start) {
2077         switch (scls) 
2078           {
2079           case S_DATA: fprintf (of, "data-"); break;
2080           case S_XDATA: fprintf (of, "xdata-"); break;
2081           case S_SFR: fprintf (of, "sfr-"); break;
2082           case S_SBIT: fprintf (of, "sbit-"); break;
2083           case S_CODE: fprintf (of, "code-"); break;
2084           case S_IDATA: fprintf (of, "idata-"); break;
2085           case S_PDATA: fprintf (of, "pdata-"); break;
2086           case S_LITERAL: fprintf (of, "literal-"); break;
2087           case S_STACK: fprintf (of, "stack-"); break;
2088           case S_XSTACK: fprintf (of, "xstack-"); break;
2089           case S_BIT: fprintf (of, "bit-"); break;
2090           case S_EEPROM: fprintf (of, "eeprom-"); break;
2091           default: break;
2092           }
2093       }
2094
2095       if (IS_DECL (type))
2096         {
2097           if (!IS_FUNC(type)) {
2098             if (DCL_PTR_VOLATILE (type)) {
2099               fprintf (of, "volatile-");
2100             }
2101             if (DCL_PTR_CONST (type)) {
2102               fprintf (of, "const-");
2103             }
2104           }
2105           switch (DCL_TYPE (type))
2106             {
2107             case FUNCTION:
2108               fprintf (of, "function %s %s", 
2109                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2110                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2111               fprintf (of, "( ");
2112               for (args = FUNC_ARGS(type); 
2113                    args; 
2114                    args=args->next) {
2115                 printTypeChain(args->type, of);
2116                 if (args->next)
2117                   fprintf(of, ", ");
2118               }
2119               fprintf (of, ") ");
2120               break;
2121             case GPOINTER:
2122               fprintf (of, "generic* ");
2123               break;
2124             case CPOINTER:
2125               fprintf (of, "code* ");
2126               break;
2127             case FPOINTER:
2128               fprintf (of, "xdata* ");
2129               break;
2130             case EEPPOINTER:
2131               fprintf (of, "eeprom* ");
2132               break;
2133             case POINTER:
2134               fprintf (of, "near* ");
2135               break;
2136             case IPOINTER:
2137               fprintf (of, "idata* ");
2138               break;
2139             case PPOINTER:
2140               fprintf (of, "pdata* ");
2141               break;
2142             case UPOINTER:
2143               fprintf (of, "unknown* ");
2144               break;
2145             case ARRAY:
2146               if (DCL_ELEM(type)) {
2147                 fprintf (of, "[%d] ", DCL_ELEM(type));
2148               } else {
2149                 fprintf (of, "[] ");
2150               }
2151               break;
2152             }
2153         }
2154       else
2155         {
2156           if (SPEC_VOLATILE (type))
2157             fprintf (of, "volatile-");
2158           if (SPEC_CONST (type))
2159             fprintf (of, "const-");
2160           if (SPEC_USIGN (type))
2161             fprintf (of, "unsigned-");
2162           switch (SPEC_NOUN (type))
2163             {
2164             case V_INT:
2165               if (IS_LONG (type))
2166                 fprintf (of, "long-");
2167               fprintf (of, "int");
2168               break;
2169
2170             case V_CHAR:
2171               fprintf (of, "char");
2172               break;
2173
2174             case V_VOID:
2175               fprintf (of, "void");
2176               break;
2177
2178             case V_FLOAT:
2179               fprintf (of, "float");
2180               break;
2181
2182             case V_STRUCT:
2183               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2184               break;
2185
2186             case V_SBIT:
2187               fprintf (of, "sbit");
2188               break;
2189
2190             case V_BIT:
2191               fprintf (of, "bit");
2192               break;
2193
2194             case V_BITFIELD:
2195               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2196               break;
2197
2198             case V_DOUBLE:
2199               fprintf (of, "double");
2200               break;
2201
2202             default:
2203               fprintf (of, "unknown type");
2204               break;
2205             }
2206         }
2207       /* search entry in list before "type" */
2208       for (search = start; search && search->next != type;)
2209         search = search->next;
2210       type = search;
2211       if (type)
2212         fputc (' ', of);
2213     }
2214   if (nlr)
2215     fprintf (of, "\n");
2216 }
2217
2218 /*--------------------------------------------------------------------*/
2219 /* printTypeChainRaw - prints the type chain in human readable form   */
2220 /*                     in the raw data structure ordering             */
2221 /*--------------------------------------------------------------------*/
2222 void
2223 printTypeChainRaw (sym_link * start, FILE * of)
2224 {
2225   int nlr = 0;
2226   value *args;
2227   sym_link * type;
2228
2229   if (!of)
2230     {
2231       of = stdout;
2232       nlr = 1;
2233     }
2234
2235   if (start==NULL) {
2236     fprintf (of, "void");
2237     return;
2238   }
2239
2240   type = start;
2241   
2242   while (type)
2243     {
2244       if (IS_DECL (type))
2245         {
2246           if (!IS_FUNC(type)) {
2247             if (DCL_PTR_VOLATILE (type)) {
2248               fprintf (of, "volatile-");
2249             }
2250             if (DCL_PTR_CONST (type)) {
2251               fprintf (of, "const-");
2252             }
2253           }
2254           switch (DCL_TYPE (type))
2255             {
2256             case FUNCTION:
2257               fprintf (of, "function %s %s", 
2258                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2259                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2260               fprintf (of, "( ");
2261               for (args = FUNC_ARGS(type); 
2262                    args; 
2263                    args=args->next) {
2264                 printTypeChain(args->type, of);
2265                 if (args->next)
2266                   fprintf(of, ", ");
2267               }
2268               fprintf (of, ") ");
2269               break;
2270             case GPOINTER:
2271               fprintf (of, "generic* ");
2272               break;
2273             case CPOINTER:
2274               fprintf (of, "code* ");
2275               break;
2276             case FPOINTER:
2277               fprintf (of, "xdata* ");
2278               break;
2279             case EEPPOINTER:
2280               fprintf (of, "eeprom* ");
2281               break;
2282             case POINTER:
2283               fprintf (of, "near* ");
2284               break;
2285             case IPOINTER:
2286               fprintf (of, "idata* ");
2287               break;
2288             case PPOINTER:
2289               fprintf (of, "pdata* ");
2290               break;
2291             case UPOINTER:
2292               fprintf (of, "unknown* ");
2293               break;
2294             case ARRAY:
2295               if (DCL_ELEM(type)) {
2296                 fprintf (of, "[%d] ", DCL_ELEM(type));
2297               } else {
2298                 fprintf (of, "[] ");
2299               }
2300               break;
2301             }
2302           if (DCL_TSPEC(type))
2303             {
2304               fprintf (of, "{");
2305               printTypeChainRaw(DCL_TSPEC(type), of);
2306               fprintf (of, "}");
2307             }
2308         }
2309       else if (IS_SPEC (type))
2310         {
2311         switch (SPEC_SCLS (type)) 
2312           {
2313           case S_DATA: fprintf (of, "data-"); break;
2314           case S_XDATA: fprintf (of, "xdata-"); break;
2315           case S_SFR: fprintf (of, "sfr-"); break;
2316           case S_SBIT: fprintf (of, "sbit-"); break;
2317           case S_CODE: fprintf (of, "code-"); break;
2318           case S_IDATA: fprintf (of, "idata-"); break;
2319           case S_PDATA: fprintf (of, "pdata-"); break;
2320           case S_LITERAL: fprintf (of, "literal-"); break;
2321           case S_STACK: fprintf (of, "stack-"); break;
2322           case S_XSTACK: fprintf (of, "xstack-"); break;
2323           case S_BIT: fprintf (of, "bit-"); break;
2324           case S_EEPROM: fprintf (of, "eeprom-"); break;
2325           default: break;
2326           }
2327           if (SPEC_VOLATILE (type))
2328             fprintf (of, "volatile-");
2329           if (SPEC_CONST (type))
2330             fprintf (of, "const-");
2331           if (SPEC_USIGN (type))
2332             fprintf (of, "unsigned-");
2333           switch (SPEC_NOUN (type))
2334             {
2335             case V_INT:
2336               if (IS_LONG (type))
2337                 fprintf (of, "long-");
2338               fprintf (of, "int");
2339               break;
2340
2341             case V_CHAR:
2342               fprintf (of, "char");
2343               break;
2344
2345             case V_VOID:
2346               fprintf (of, "void");
2347               break;
2348
2349             case V_FLOAT:
2350               fprintf (of, "float");
2351               break;
2352
2353             case V_STRUCT:
2354               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2355               break;
2356
2357             case V_SBIT:
2358               fprintf (of, "sbit");
2359               break;
2360
2361             case V_BIT:
2362               fprintf (of, "bit");
2363               break;
2364
2365             case V_BITFIELD:
2366               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2367               break;
2368
2369             case V_DOUBLE:
2370               fprintf (of, "double");
2371               break;
2372
2373             default:
2374               fprintf (of, "unknown type");
2375               break;
2376             }
2377         }
2378       else
2379         fprintf (of, "NOT_SPEC_OR_DECL");
2380       type = type->next;
2381       if (type)
2382         fputc (' ', of);
2383     }
2384   if (nlr)
2385     fprintf (of, "\n");
2386 }
2387
2388
2389 /*-----------------------------------------------------------------*/
2390 /* powof2 - returns power of two for the number if number is pow 2 */
2391 /*-----------------------------------------------------------------*/
2392 int 
2393 powof2 (unsigned long num)
2394 {
2395   int nshifts = 0;
2396   int n1s = 0;
2397
2398   while (num)
2399     {
2400       if (num & 1)
2401         n1s++;
2402       num >>= 1;
2403       nshifts++;
2404     }
2405
2406   if (n1s > 1 || nshifts == 0)
2407     return 0;
2408   return nshifts - 1;
2409 }
2410
2411 symbol *__fsadd;
2412 symbol *__fssub;
2413 symbol *__fsmul;
2414 symbol *__fsdiv;
2415 symbol *__fseq;
2416 symbol *__fsneq;
2417 symbol *__fslt;
2418 symbol *__fslteq;
2419 symbol *__fsgt;
2420 symbol *__fsgteq;
2421
2422 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2423 symbol *__muldiv[3][3][2];
2424 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2425 sym_link *__multypes[3][2];
2426 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2427 symbol *__conv[2][3][2];
2428 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2429 symbol *__rlrr[2][3][2];
2430
2431 sym_link *floatType;
2432
2433 static char *
2434 _mangleFunctionName(char *in)
2435 {
2436   if (port->getMangledFunctionName) 
2437     {
2438       return port->getMangledFunctionName(in);
2439     }
2440   else
2441     {
2442       return in;
2443     }
2444 }
2445
2446 /*-----------------------------------------------------------------*/
2447 /* typeFromStr - create a typechain from an encoded string         */
2448 /* basic types -        'c' - char                                 */
2449 /*                      's' - short                                */
2450 /*                      'i' - int                                  */
2451 /*                      'l' - long                                 */
2452 /*                      'f' - float                                */
2453 /*                      'v' - void                                 */
2454 /*                      '*' - pointer - default (GPOINTER)         */
2455 /* modifiers -          'u' - unsigned                             */
2456 /* pointer modifiers -  'g' - generic                              */
2457 /*                      'x' - xdata                                */
2458 /*                      'p' - code                                 */
2459 /*                      'd' - data                                 */                     
2460 /*                      'F' - function                             */                     
2461 /* examples : "ig*" - generic int *                                */
2462 /*            "cx*" - char xdata *                                 */
2463 /*            "ui" -  unsigned int                                 */
2464 /*-----------------------------------------------------------------*/
2465 sym_link *typeFromStr (char *s)
2466 {
2467     sym_link *r = newLink(DECLARATOR);
2468     int usign = 0;
2469
2470     do {
2471         sym_link *nr;
2472         switch (*s) {
2473         case 'u' : 
2474             usign = 1;
2475             s++;
2476             continue ;
2477             break ;
2478         case 'c':
2479             r->class = SPECIFIER;
2480             SPEC_NOUN(r) = V_CHAR;
2481             break;
2482         case 's':
2483         case 'i':
2484             r->class = SPECIFIER;
2485             SPEC_NOUN(r) = V_INT;
2486             break;
2487         case 'l':
2488             r->class = SPECIFIER;
2489             SPEC_NOUN(r) = V_INT;
2490             SPEC_LONG(r) = 1;
2491             break;
2492         case 'f':
2493             r->class = SPECIFIER;
2494             SPEC_NOUN(r) = V_FLOAT;
2495             break;
2496         case 'v':
2497             r->class = SPECIFIER;
2498             SPEC_NOUN(r) = V_VOID;
2499             break;
2500         case '*':
2501             DCL_TYPE(r) = port->unqualified_pointer;
2502             break;
2503         case 'g':
2504         case 'x':
2505         case 'p':
2506         case 'd':
2507         case 'F':
2508             assert(*(s+1)=='*');
2509             nr = newLink(DECLARATOR);
2510             nr->next = r;
2511             r = nr;
2512             switch (*s) {
2513             case 'g':
2514                 DCL_TYPE(r) = GPOINTER;
2515                 break;
2516             case 'x':
2517                 DCL_TYPE(r) = FPOINTER;
2518                 break;
2519             case 'p':
2520                 DCL_TYPE(r) = CPOINTER;
2521                 break;
2522             case 'd':
2523                 DCL_TYPE(r) = POINTER;
2524                 break;
2525             case 'F':
2526                 DCL_TYPE(r) = FUNCTION;
2527                 nr = newLink(DECLARATOR);
2528                 nr->next = r;
2529                 r = nr;
2530                 DCL_TYPE(r) = CPOINTER;
2531                 break;
2532             }
2533             s++;
2534             break;
2535         default:
2536             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2537                    "typeFromStr: unknown type");
2538             break;
2539         }
2540         if (IS_SPEC(r) && usign) {
2541             SPEC_USIGN(r) = 1;
2542             usign = 0;
2543         }
2544         s++;
2545     } while (*s);
2546     return r;
2547 }
2548
2549 /*-----------------------------------------------------------------*/
2550 /* initCSupport - create functions for C support routines          */
2551 /*-----------------------------------------------------------------*/
2552 void 
2553 initCSupport ()
2554 {
2555   const char *smuldivmod[] =
2556   {
2557     "mul", "div", "mod"
2558   };
2559   const char *sbwd[] =
2560   {
2561     "char", "int", "long"
2562   };
2563   const char *ssu[] =
2564   {
2565     "s", "u"
2566   };
2567   const char *srlrr[] =
2568   {
2569     "rl", "rr"
2570   };
2571
2572   int bwd, su, muldivmod, tofrom, rlrr;
2573
2574   if (getenv("SDCC_NO_C_SUPPORT")) {
2575     /* for debugging only */
2576     return;
2577   }
2578
2579   floatType = newFloatLink ();
2580
2581   for (bwd = 0; bwd < 3; bwd++)
2582     {
2583       sym_link *l = NULL;
2584       switch (bwd)
2585         {
2586         case 0:
2587           l = newCharLink ();
2588           break;
2589         case 1:
2590           l = newIntLink ();
2591           break;
2592         case 2:
2593           l = newLongLink ();
2594           break;
2595         default:
2596           assert (0);
2597         }
2598       __multypes[bwd][0] = l;
2599       __multypes[bwd][1] = copyLinkChain (l);
2600       SPEC_USIGN (__multypes[bwd][1]) = 1;
2601     }
2602
2603   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2604   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2605   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2606   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2607   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2608   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2609   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2610   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2611   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2612   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2613
2614   for (tofrom = 0; tofrom < 2; tofrom++)
2615     {
2616       for (bwd = 0; bwd < 3; bwd++)
2617         {
2618           for (su = 0; su < 2; su++)
2619             {
2620               if (tofrom)
2621                 {
2622                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2623                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2624                 }
2625               else
2626                 {
2627                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2628                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2629                 }
2630             }
2631         }
2632     }
2633
2634 /*
2635   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2636     {
2637       for (bwd = 0; bwd < 3; bwd++)
2638         {
2639           for (su = 0; su < 2; su++)
2640             {
2641               SNPRINTF (buffer, sizeof(buffer),
2642                         "_%s%s%s",
2643                        smuldivmod[muldivmod],
2644                        ssu[su],
2645                        sbwd[bwd]);
2646               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2647               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2648             }
2649         }
2650     }
2651
2652   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2653   Therefore they've been merged into mulint() and mullong().
2654 */
2655
2656   for (bwd = 0; bwd < 3; bwd++)
2657     {
2658       for (su = 0; su < 2; su++)
2659         {
2660           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2661             {
2662               /* div and mod */
2663               SNPRINTF (buffer, sizeof(buffer),
2664                         "_%s%s%s",
2665                        smuldivmod[muldivmod],
2666                        ssu[su],
2667                        sbwd[bwd]);
2668               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2669               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2670             }
2671         }
2672     }
2673   /* mul only */
2674   muldivmod = 0;
2675   /* byte */
2676   bwd = 0;
2677   for (su = 0; su < 2; su++)
2678     {
2679       /* muluchar and mulschar are still separate functions, because e.g. the z80
2680          port is sign/zero-extending to int before calling mulint() */
2681       SNPRINTF (buffer, sizeof(buffer),
2682                 "_%s%s%s",
2683                 smuldivmod[muldivmod],
2684                 ssu[su],
2685                 sbwd[bwd]);
2686       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2687       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2688     }
2689   /* signed only */
2690   su = 0;
2691   /* word and doubleword */
2692   for (bwd = 1; bwd < 3; bwd++)
2693     {
2694       /* mul, int/long */
2695       SNPRINTF (buffer, sizeof(buffer),
2696                 "_%s%s",
2697                 smuldivmod[muldivmod],
2698                 sbwd[bwd]);
2699       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2700       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2701       /* signed = unsigned */
2702       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
2703     }
2704
2705   for (rlrr = 0; rlrr < 2; rlrr++)
2706     {
2707       for (bwd = 0; bwd < 3; bwd++)
2708         {
2709           for (su = 0; su < 2; su++)
2710             {
2711               SNPRINTF (buffer, sizeof(buffer),
2712                         "_%s%s%s",
2713                        srlrr[rlrr],
2714                        ssu[su],
2715                        sbwd[bwd]);
2716               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2717               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2718             }
2719         }
2720     }
2721 }
2722
2723 /*-----------------------------------------------------------------*/
2724 /* initBuiltIns - create prototypes for builtin functions          */
2725 /*-----------------------------------------------------------------*/
2726 void initBuiltIns()
2727 {
2728     int i;
2729     symbol *sym;
2730
2731     if (!port->builtintable) return ;
2732
2733     for (i = 0 ; port->builtintable[i].name ; i++) {
2734         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2735                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2736         FUNC_ISBUILTIN(sym->type) = 1;
2737         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2738     }
2739 }
2740
2741 sym_link *validateLink(sym_link         *l, 
2742                         const char      *macro,
2743                         const char      *args,
2744                         const char      select,
2745                         const char      *file, 
2746                         unsigned        line)
2747 {    
2748   if (l && l->class==select)
2749     {
2750         return l;
2751     }
2752     fprintf(stderr, 
2753             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2754             " expected %s, got %s\n",
2755             macro, args, file, line, 
2756             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2757     exit(-1);
2758     return l; // never reached, makes compiler happy.
2759 }