* src/SDCCmain.c (setParseWithComma): fixed bug #816685
[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 (((/*!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   argCnt--;
1780
1781   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1782     return 1;                   /* not defined nothing more to check  */
1783
1784   /* check if body already present */
1785   if (csym && IFFUNC_HASBODY(csym->type))
1786     {
1787       werror (E_FUNC_BODY, sym->name);
1788       return 0;
1789     }
1790
1791   /* check the return value type   */
1792   if (compareType (csym->type, sym->type) <= 0)
1793     {
1794       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1795       printFromToType(csym->type, sym->type);
1796       return 0;
1797     }
1798
1799   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1800     {
1801       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1802     }
1803
1804   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1805     {
1806       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1807     }
1808
1809   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1810     {
1811       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1812     }
1813   
1814   /* Really, reentrant should match regardless of argCnt, but     */
1815   /* this breaks some existing code (the fp lib functions). If    */
1816   /* the first argument is always passed the same way, this       */
1817   /* lax checking is ok (but may not be true for in future ports) */
1818   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
1819       && argCnt>1)
1820     {
1821       //printf("argCnt = %d\n",argCnt);
1822       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
1823     }
1824
1825   /* compare expected args with actual args */
1826   exargs = FUNC_ARGS(csym->type);
1827   acargs = FUNC_ARGS(sym->type);
1828
1829   /* for all the expected args do */
1830   for (argCnt = 1;
1831        exargs && acargs;
1832        exargs = exargs->next, acargs = acargs->next, argCnt++)
1833     {
1834       if (getenv("DEBUG_SANITY")) {
1835         fprintf (stderr, "checkFunction: %s ", exargs->name);
1836       }
1837       /* make sure the type is complete and sane */
1838       checkTypeSanity(exargs->etype, exargs->name);
1839
1840       /* If the actual argument is an array, any prototype
1841        * will have modified it to a pointer. Duplicate that
1842        * change here.
1843        */
1844       if (IS_AGGREGATE (acargs->type))
1845         {
1846           checkValue = copyValue (acargs);
1847           aggregateToPointer (checkValue);
1848         }
1849       else
1850         {
1851           checkValue = acargs;
1852         }
1853
1854       if (compareType (exargs->type, checkValue->type) <= 0)
1855         {
1856           werror (E_ARG_TYPE, argCnt);
1857           printFromToType(exargs->type, checkValue->type);
1858           return 0;
1859         }
1860     }
1861
1862   /* if one them ended we have a problem */
1863   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1864       (!exargs && acargs && !IS_VOID (acargs->type)))
1865     werror (E_ARG_COUNT);
1866
1867   /* replace with this defition */
1868   sym->cdef = csym->cdef;
1869   deleteSym (SymbolTab, csym, csym->name);
1870   deleteFromSeg(csym);
1871   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1872   if (IS_EXTERN (csym->etype) && !
1873       IS_EXTERN (sym->etype))
1874     {
1875       addSet (&publics, sym);
1876     }
1877   return 1;
1878 }
1879
1880 /*------------------------------------------------------------------*/
1881 /* cdbStructBlock - calls struct printing for a blcks               */
1882 /*------------------------------------------------------------------*/
1883 void cdbStructBlock (int block)
1884 {
1885   int i;
1886   bucket **table = StructTab;
1887   bucket *chain;
1888
1889   /* go thru the entire  table  */
1890   for (i = 0; i < 256; i++)
1891     {
1892       for (chain = table[i]; chain; chain = chain->next)
1893         {
1894           if (chain->block >= block)
1895             {
1896               if(debugFile)
1897                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
1898             }
1899         }
1900     }
1901 }
1902
1903 /*-----------------------------------------------------------------*/
1904 /* processFuncArgs - does some processing with function args       */
1905 /*-----------------------------------------------------------------*/
1906 void 
1907 processFuncArgs (symbol * func)
1908 {
1909   value *val;
1910   int pNum = 1;
1911   sym_link *funcType=func->type;
1912
1913   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1914     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1915
1916   // if this is a pointer to a function
1917   if (IS_PTR(funcType)) {
1918     funcType=funcType->next;
1919   }
1920
1921   /* if this function has variable argument list */
1922   /* then make the function a reentrant one    */
1923   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1924     FUNC_ISREENT(funcType)=1;
1925
1926   /* check if this function is defined as calleeSaves
1927      then mark it as such */
1928   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1929
1930   /* loop thru all the arguments   */
1931   val = FUNC_ARGS(funcType);
1932
1933   /* if it is void then remove parameters */
1934   if (val && IS_VOID (val->type))
1935     {
1936       FUNC_ARGS(funcType) = NULL;
1937       return;
1938     }
1939
1940   /* reset regparm for the port */
1941   (*port->reset_regparms) ();
1942   /* if any of the arguments is an aggregate */
1943   /* change it to pointer to the same type */
1944   while (val)
1945     {
1946         int argreg = 0;
1947       /* mark it as a register parameter if
1948          the function does not have VA_ARG
1949          and as port dictates */
1950       if (!IFFUNC_HASVARARGS(funcType) &&
1951           (argreg = (*port->reg_parm) (val->type)))
1952         {
1953           SPEC_REGPARM (val->etype) = 1;
1954           SPEC_ARGREG(val->etype) = argreg;
1955         } else if (IFFUNC_ISREENT(funcType)) {
1956             FUNC_HASSTACKPARM(funcType) = 1;
1957         }
1958
1959       if (IS_AGGREGATE (val->type))
1960         {
1961           aggregateToPointer (val);
1962         }
1963
1964       val = val->next;
1965       pNum++;
1966     }
1967
1968   /* if this is an internal generated function call */
1969   if (func->cdef) {
1970     /* ignore --stack-auto for this one, we don't know how it is compiled */
1971     /* simply trust on --int-long-reent or --float-reent */
1972     if (IFFUNC_ISREENT(funcType)) {
1973       return;
1974     }
1975   } else {
1976     /* if this function is reentrant or */
1977     /* automatics r 2b stacked then nothing */
1978     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1979       return;
1980   }
1981
1982   val = FUNC_ARGS(funcType);
1983   pNum = 1;
1984   while (val)
1985     {
1986
1987       /* if a symbolname is not given  */
1988       /* synthesize a variable name */
1989       if (!val->sym)
1990         {
1991           SNPRINTF (val->name, sizeof(val->name), 
1992                     "_%s_PARM_%d", func->name, pNum++);
1993           val->sym = newSymbol (val->name, 1);
1994           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1995           val->sym->type = copyLinkChain (val->type);
1996           val->sym->etype = getSpec (val->sym->type);
1997           val->sym->_isparm = 1;
1998           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1999           if (IS_SPEC(func->etype)) {
2000             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2001               SPEC_STAT (func->etype);
2002           }
2003           addSymChain (val->sym);
2004
2005         }
2006       else                      /* symbol name given create synth name */
2007         {
2008
2009           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2010           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2011           val->sym->_isparm = 1;
2012           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2013             (options.model != MODEL_SMALL ? xdata : data);
2014           if (IS_SPEC(func->etype)) {
2015             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2016               SPEC_STAT (func->etype);
2017           }
2018         }
2019       if (!isinSet(operKeyReset, val->sym)) {
2020         addSet (&operKeyReset, val->sym);
2021         applyToSet (operKeyReset, resetParmKey);
2022       }
2023       val = val->next;
2024     }
2025 }
2026
2027 /*-----------------------------------------------------------------*/
2028 /* isSymbolEqual - compares two symbols return 1 if they match     */
2029 /*-----------------------------------------------------------------*/
2030 int 
2031 isSymbolEqual (symbol * dest, symbol * src)
2032 {
2033   /* if pointers match then equal */
2034   if (dest == src)
2035     return 1;
2036
2037   /* if one of them is null then don't match */
2038   if (!dest || !src)
2039     return 0;
2040
2041   /* if both of them have rname match on rname */
2042   if (dest->rname[0] && src->rname[0])
2043     return (!strcmp (dest->rname, src->rname));
2044
2045   /* otherwise match on name */
2046   return (!strcmp (dest->name, src->name));
2047 }
2048
2049 void PT(sym_link *type)
2050 {
2051         printTypeChain(type,0);
2052 }
2053 /*-----------------------------------------------------------------*/
2054 /* printTypeChain - prints the type chain in human readable form   */
2055 /*-----------------------------------------------------------------*/
2056 void
2057 printTypeChain (sym_link * start, FILE * of)
2058 {
2059   int nlr = 0;
2060   value *args;
2061   sym_link * type, * search;
2062   STORAGE_CLASS scls;
2063
2064   if (!of)
2065     {
2066       of = stdout;
2067       nlr = 1;
2068     }
2069
2070   if (start==NULL) {
2071     fprintf (of, "void");
2072     return;
2073   }
2074
2075   /* Print the chain as it is written in the source: */
2076   /* start with the last entry.                      */
2077   /* However, the storage class at the end of the    */
2078   /* chain reall applies to the first in the chain!  */
2079
2080   for (type = start; type && type->next; type = type->next)
2081     ;
2082   if (IS_SPEC (type))
2083     scls=SPEC_SCLS(type);
2084   else
2085     scls=0;
2086   while (type)
2087     {
2088       if (type==start) {
2089         switch (scls) 
2090           {
2091           case S_DATA: fprintf (of, "data-"); break;
2092           case S_XDATA: fprintf (of, "xdata-"); break;
2093           case S_SFR: fprintf (of, "sfr-"); break;
2094           case S_SBIT: fprintf (of, "sbit-"); break;
2095           case S_CODE: fprintf (of, "code-"); break;
2096           case S_IDATA: fprintf (of, "idata-"); break;
2097           case S_PDATA: fprintf (of, "pdata-"); break;
2098           case S_LITERAL: fprintf (of, "literal-"); break;
2099           case S_STACK: fprintf (of, "stack-"); break;
2100           case S_XSTACK: fprintf (of, "xstack-"); break;
2101           case S_BIT: fprintf (of, "bit-"); break;
2102           case S_EEPROM: fprintf (of, "eeprom-"); break;
2103           default: break;
2104           }
2105       }
2106
2107       if (IS_DECL (type))
2108         {
2109           if (!IS_FUNC(type)) {
2110             if (DCL_PTR_VOLATILE (type)) {
2111               fprintf (of, "volatile-");
2112             }
2113             if (DCL_PTR_CONST (type)) {
2114               fprintf (of, "const-");
2115             }
2116           }
2117           switch (DCL_TYPE (type))
2118             {
2119             case FUNCTION:
2120               fprintf (of, "function %s %s", 
2121                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2122                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2123               fprintf (of, "( ");
2124               for (args = FUNC_ARGS(type); 
2125                    args; 
2126                    args=args->next) {
2127                 printTypeChain(args->type, of);
2128                 if (args->next)
2129                   fprintf(of, ", ");
2130               }
2131               fprintf (of, ") ");
2132               break;
2133             case GPOINTER:
2134               fprintf (of, "generic* ");
2135               break;
2136             case CPOINTER:
2137               fprintf (of, "code* ");
2138               break;
2139             case FPOINTER:
2140               fprintf (of, "xdata* ");
2141               break;
2142             case EEPPOINTER:
2143               fprintf (of, "eeprom* ");
2144               break;
2145             case POINTER:
2146               fprintf (of, "near* ");
2147               break;
2148             case IPOINTER:
2149               fprintf (of, "idata* ");
2150               break;
2151             case PPOINTER:
2152               fprintf (of, "pdata* ");
2153               break;
2154             case UPOINTER:
2155               fprintf (of, "unknown* ");
2156               break;
2157             case ARRAY:
2158               if (DCL_ELEM(type)) {
2159                 fprintf (of, "[%d] ", DCL_ELEM(type));
2160               } else {
2161                 fprintf (of, "[] ");
2162               }
2163               break;
2164             }
2165         }
2166       else
2167         {
2168           if (SPEC_VOLATILE (type))
2169             fprintf (of, "volatile-");
2170           if (SPEC_CONST (type))
2171             fprintf (of, "const-");
2172           if (SPEC_USIGN (type))
2173             fprintf (of, "unsigned-");
2174           switch (SPEC_NOUN (type))
2175             {
2176             case V_INT:
2177               if (IS_LONG (type))
2178                 fprintf (of, "long-");
2179               fprintf (of, "int");
2180               break;
2181
2182             case V_CHAR:
2183               fprintf (of, "char");
2184               break;
2185
2186             case V_VOID:
2187               fprintf (of, "void");
2188               break;
2189
2190             case V_FLOAT:
2191               fprintf (of, "float");
2192               break;
2193
2194             case V_STRUCT:
2195               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2196               break;
2197
2198             case V_SBIT:
2199               fprintf (of, "sbit");
2200               break;
2201
2202             case V_BIT:
2203               fprintf (of, "bit");
2204               break;
2205
2206             case V_BITFIELD:
2207               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2208               break;
2209
2210             case V_DOUBLE:
2211               fprintf (of, "double");
2212               break;
2213
2214             default:
2215               fprintf (of, "unknown type");
2216               break;
2217             }
2218         }
2219       /* search entry in list before "type" */
2220       for (search = start; search && search->next != type;)
2221         search = search->next;
2222       type = search;
2223       if (type)
2224         fputc (' ', of);
2225     }
2226   if (nlr)
2227     fprintf (of, "\n");
2228 }
2229
2230 /*--------------------------------------------------------------------*/
2231 /* printTypeChainRaw - prints the type chain in human readable form   */
2232 /*                     in the raw data structure ordering             */
2233 /*--------------------------------------------------------------------*/
2234 void
2235 printTypeChainRaw (sym_link * start, FILE * of)
2236 {
2237   int nlr = 0;
2238   value *args;
2239   sym_link * type;
2240
2241   if (!of)
2242     {
2243       of = stdout;
2244       nlr = 1;
2245     }
2246
2247   if (start==NULL) {
2248     fprintf (of, "void");
2249     return;
2250   }
2251
2252   type = start;
2253   
2254   while (type)
2255     {
2256       if (IS_DECL (type))
2257         {
2258           if (!IS_FUNC(type)) {
2259             if (DCL_PTR_VOLATILE (type)) {
2260               fprintf (of, "volatile-");
2261             }
2262             if (DCL_PTR_CONST (type)) {
2263               fprintf (of, "const-");
2264             }
2265           }
2266           switch (DCL_TYPE (type))
2267             {
2268             case FUNCTION:
2269               fprintf (of, "function %s %s", 
2270                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2271                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2272               fprintf (of, "( ");
2273               for (args = FUNC_ARGS(type); 
2274                    args; 
2275                    args=args->next) {
2276                 printTypeChain(args->type, of);
2277                 if (args->next)
2278                   fprintf(of, ", ");
2279               }
2280               fprintf (of, ") ");
2281               break;
2282             case GPOINTER:
2283               fprintf (of, "generic* ");
2284               break;
2285             case CPOINTER:
2286               fprintf (of, "code* ");
2287               break;
2288             case FPOINTER:
2289               fprintf (of, "xdata* ");
2290               break;
2291             case EEPPOINTER:
2292               fprintf (of, "eeprom* ");
2293               break;
2294             case POINTER:
2295               fprintf (of, "near* ");
2296               break;
2297             case IPOINTER:
2298               fprintf (of, "idata* ");
2299               break;
2300             case PPOINTER:
2301               fprintf (of, "pdata* ");
2302               break;
2303             case UPOINTER:
2304               fprintf (of, "unknown* ");
2305               break;
2306             case ARRAY:
2307               if (DCL_ELEM(type)) {
2308                 fprintf (of, "[%d] ", DCL_ELEM(type));
2309               } else {
2310                 fprintf (of, "[] ");
2311               }
2312               break;
2313             }
2314           if (DCL_TSPEC(type))
2315             {
2316               fprintf (of, "{");
2317               printTypeChainRaw(DCL_TSPEC(type), of);
2318               fprintf (of, "}");
2319             }
2320         }
2321       else if (IS_SPEC (type))
2322         {
2323         switch (SPEC_SCLS (type)) 
2324           {
2325           case S_DATA: fprintf (of, "data-"); break;
2326           case S_XDATA: fprintf (of, "xdata-"); break;
2327           case S_SFR: fprintf (of, "sfr-"); break;
2328           case S_SBIT: fprintf (of, "sbit-"); break;
2329           case S_CODE: fprintf (of, "code-"); break;
2330           case S_IDATA: fprintf (of, "idata-"); break;
2331           case S_PDATA: fprintf (of, "pdata-"); break;
2332           case S_LITERAL: fprintf (of, "literal-"); break;
2333           case S_STACK: fprintf (of, "stack-"); break;
2334           case S_XSTACK: fprintf (of, "xstack-"); break;
2335           case S_BIT: fprintf (of, "bit-"); break;
2336           case S_EEPROM: fprintf (of, "eeprom-"); break;
2337           default: break;
2338           }
2339           if (SPEC_VOLATILE (type))
2340             fprintf (of, "volatile-");
2341           if (SPEC_CONST (type))
2342             fprintf (of, "const-");
2343           if (SPEC_USIGN (type))
2344             fprintf (of, "unsigned-");
2345           switch (SPEC_NOUN (type))
2346             {
2347             case V_INT:
2348               if (IS_LONG (type))
2349                 fprintf (of, "long-");
2350               fprintf (of, "int");
2351               break;
2352
2353             case V_CHAR:
2354               fprintf (of, "char");
2355               break;
2356
2357             case V_VOID:
2358               fprintf (of, "void");
2359               break;
2360
2361             case V_FLOAT:
2362               fprintf (of, "float");
2363               break;
2364
2365             case V_STRUCT:
2366               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2367               break;
2368
2369             case V_SBIT:
2370               fprintf (of, "sbit");
2371               break;
2372
2373             case V_BIT:
2374               fprintf (of, "bit");
2375               break;
2376
2377             case V_BITFIELD:
2378               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2379               break;
2380
2381             case V_DOUBLE:
2382               fprintf (of, "double");
2383               break;
2384
2385             default:
2386               fprintf (of, "unknown type");
2387               break;
2388             }
2389         }
2390       else
2391         fprintf (of, "NOT_SPEC_OR_DECL");
2392       type = type->next;
2393       if (type)
2394         fputc (' ', of);
2395     }
2396   if (nlr)
2397     fprintf (of, "\n");
2398 }
2399
2400
2401 /*-----------------------------------------------------------------*/
2402 /* powof2 - returns power of two for the number if number is pow 2 */
2403 /*-----------------------------------------------------------------*/
2404 int 
2405 powof2 (unsigned long num)
2406 {
2407   int nshifts = 0;
2408   int n1s = 0;
2409
2410   while (num)
2411     {
2412       if (num & 1)
2413         n1s++;
2414       num >>= 1;
2415       nshifts++;
2416     }
2417
2418   if (n1s > 1 || nshifts == 0)
2419     return 0;
2420   return nshifts - 1;
2421 }
2422
2423 symbol *__fsadd;
2424 symbol *__fssub;
2425 symbol *__fsmul;
2426 symbol *__fsdiv;
2427 symbol *__fseq;
2428 symbol *__fsneq;
2429 symbol *__fslt;
2430 symbol *__fslteq;
2431 symbol *__fsgt;
2432 symbol *__fsgteq;
2433
2434 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2435 symbol *__muldiv[3][3][2];
2436 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2437 sym_link *__multypes[3][2];
2438 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2439 symbol *__conv[2][3][2];
2440 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2441 symbol *__rlrr[2][3][2];
2442
2443 sym_link *floatType;
2444
2445 static char *
2446 _mangleFunctionName(char *in)
2447 {
2448   if (port->getMangledFunctionName) 
2449     {
2450       return port->getMangledFunctionName(in);
2451     }
2452   else
2453     {
2454       return in;
2455     }
2456 }
2457
2458 /*-----------------------------------------------------------------*/
2459 /* typeFromStr - create a typechain from an encoded string         */
2460 /* basic types -        'c' - char                                 */
2461 /*                      's' - short                                */
2462 /*                      'i' - int                                  */
2463 /*                      'l' - long                                 */
2464 /*                      'f' - float                                */
2465 /*                      'v' - void                                 */
2466 /*                      '*' - pointer - default (GPOINTER)         */
2467 /* modifiers -          'u' - unsigned                             */
2468 /* pointer modifiers -  'g' - generic                              */
2469 /*                      'x' - xdata                                */
2470 /*                      'p' - code                                 */
2471 /*                      'd' - data                                 */                     
2472 /*                      'F' - function                             */                     
2473 /* examples : "ig*" - generic int *                                */
2474 /*            "cx*" - char xdata *                                 */
2475 /*            "ui" -  unsigned int                                 */
2476 /*-----------------------------------------------------------------*/
2477 sym_link *typeFromStr (char *s)
2478 {
2479     sym_link *r = newLink(DECLARATOR);
2480     int usign = 0;
2481
2482     do {
2483         sym_link *nr;
2484         switch (*s) {
2485         case 'u' : 
2486             usign = 1;
2487             s++;
2488             continue ;
2489             break ;
2490         case 'c':
2491             r->class = SPECIFIER;
2492             SPEC_NOUN(r) = V_CHAR;
2493             break;
2494         case 's':
2495         case 'i':
2496             r->class = SPECIFIER;
2497             SPEC_NOUN(r) = V_INT;
2498             break;
2499         case 'l':
2500             r->class = SPECIFIER;
2501             SPEC_NOUN(r) = V_INT;
2502             SPEC_LONG(r) = 1;
2503             break;
2504         case 'f':
2505             r->class = SPECIFIER;
2506             SPEC_NOUN(r) = V_FLOAT;
2507             break;
2508         case 'v':
2509             r->class = SPECIFIER;
2510             SPEC_NOUN(r) = V_VOID;
2511             break;
2512         case '*':
2513             DCL_TYPE(r) = port->unqualified_pointer;
2514             break;
2515         case 'g':
2516         case 'x':
2517         case 'p':
2518         case 'd':
2519         case 'F':
2520             assert(*(s+1)=='*');
2521             nr = newLink(DECLARATOR);
2522             nr->next = r;
2523             r = nr;
2524             switch (*s) {
2525             case 'g':
2526                 DCL_TYPE(r) = GPOINTER;
2527                 break;
2528             case 'x':
2529                 DCL_TYPE(r) = FPOINTER;
2530                 break;
2531             case 'p':
2532                 DCL_TYPE(r) = CPOINTER;
2533                 break;
2534             case 'd':
2535                 DCL_TYPE(r) = POINTER;
2536                 break;
2537             case 'F':
2538                 DCL_TYPE(r) = FUNCTION;
2539                 nr = newLink(DECLARATOR);
2540                 nr->next = r;
2541                 r = nr;
2542                 DCL_TYPE(r) = CPOINTER;
2543                 break;
2544             }
2545             s++;
2546             break;
2547         default:
2548             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2549                    "typeFromStr: unknown type");
2550             break;
2551         }
2552         if (IS_SPEC(r) && usign) {
2553             SPEC_USIGN(r) = 1;
2554             usign = 0;
2555         }
2556         s++;
2557     } while (*s);
2558     return r;
2559 }
2560
2561 /*-----------------------------------------------------------------*/
2562 /* initCSupport - create functions for C support routines          */
2563 /*-----------------------------------------------------------------*/
2564 void 
2565 initCSupport ()
2566 {
2567   const char *smuldivmod[] =
2568   {
2569     "mul", "div", "mod"
2570   };
2571   const char *sbwd[] =
2572   {
2573     "char", "int", "long"
2574   };
2575   const char *ssu[] =
2576   {
2577     "s", "u"
2578   };
2579   const char *srlrr[] =
2580   {
2581     "rl", "rr"
2582   };
2583
2584   int bwd, su, muldivmod, tofrom, rlrr;
2585
2586   if (getenv("SDCC_NO_C_SUPPORT")) {
2587     /* for debugging only */
2588     return;
2589   }
2590
2591   floatType = newFloatLink ();
2592
2593   for (bwd = 0; bwd < 3; bwd++)
2594     {
2595       sym_link *l = NULL;
2596       switch (bwd)
2597         {
2598         case 0:
2599           l = newCharLink ();
2600           break;
2601         case 1:
2602           l = newIntLink ();
2603           break;
2604         case 2:
2605           l = newLongLink ();
2606           break;
2607         default:
2608           assert (0);
2609         }
2610       __multypes[bwd][0] = l;
2611       __multypes[bwd][1] = copyLinkChain (l);
2612       SPEC_USIGN (__multypes[bwd][1]) = 1;
2613     }
2614
2615   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2616   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2617   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2618   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2619   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2620   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2621   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2622   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2623   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2624   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2625
2626   for (tofrom = 0; tofrom < 2; tofrom++)
2627     {
2628       for (bwd = 0; bwd < 3; bwd++)
2629         {
2630           for (su = 0; su < 2; su++)
2631             {
2632               if (tofrom)
2633                 {
2634                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2635                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2636                 }
2637               else
2638                 {
2639                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2640                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2641                 }
2642             }
2643         }
2644     }
2645
2646 /*
2647   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2648     {
2649       for (bwd = 0; bwd < 3; bwd++)
2650         {
2651           for (su = 0; su < 2; su++)
2652             {
2653               SNPRINTF (buffer, sizeof(buffer),
2654                         "_%s%s%s",
2655                        smuldivmod[muldivmod],
2656                        ssu[su],
2657                        sbwd[bwd]);
2658               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2659               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2660             }
2661         }
2662     }
2663
2664   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2665   Therefore they've been merged into mulint() and mullong().
2666 */
2667
2668   for (bwd = 0; bwd < 3; bwd++)
2669     {
2670       for (su = 0; su < 2; su++)
2671         {
2672           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2673             {
2674               /* div and mod */
2675               SNPRINTF (buffer, sizeof(buffer),
2676                         "_%s%s%s",
2677                        smuldivmod[muldivmod],
2678                        ssu[su],
2679                        sbwd[bwd]);
2680               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2681               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2682             }
2683         }
2684     }
2685   /* mul only */
2686   muldivmod = 0;
2687   /* byte */
2688   bwd = 0;
2689   for (su = 0; su < 2; su++)
2690     {
2691       /* muluchar and mulschar are still separate functions, because e.g. the z80
2692          port is sign/zero-extending to int before calling mulint() */
2693       SNPRINTF (buffer, sizeof(buffer),
2694                 "_%s%s%s",
2695                 smuldivmod[muldivmod],
2696                 ssu[su],
2697                 sbwd[bwd]);
2698       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2699       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2700     }
2701   /* signed only */
2702   su = 0;
2703   /* word and doubleword */
2704   for (bwd = 1; bwd < 3; bwd++)
2705     {
2706       /* mul, int/long */
2707       SNPRINTF (buffer, sizeof(buffer),
2708                 "_%s%s",
2709                 smuldivmod[muldivmod],
2710                 sbwd[bwd]);
2711       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2712       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2713       /* signed = unsigned */
2714       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
2715     }
2716
2717   for (rlrr = 0; rlrr < 2; rlrr++)
2718     {
2719       for (bwd = 0; bwd < 3; bwd++)
2720         {
2721           for (su = 0; su < 2; su++)
2722             {
2723               SNPRINTF (buffer, sizeof(buffer),
2724                         "_%s%s%s",
2725                        srlrr[rlrr],
2726                        ssu[su],
2727                        sbwd[bwd]);
2728               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2729               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2730             }
2731         }
2732     }
2733 }
2734
2735 /*-----------------------------------------------------------------*/
2736 /* initBuiltIns - create prototypes for builtin functions          */
2737 /*-----------------------------------------------------------------*/
2738 void initBuiltIns()
2739 {
2740     int i;
2741     symbol *sym;
2742
2743     if (!port->builtintable) return ;
2744
2745     for (i = 0 ; port->builtintable[i].name ; i++) {
2746         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2747                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2748         FUNC_ISBUILTIN(sym->type) = 1;
2749         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2750     }
2751 }
2752
2753 sym_link *validateLink(sym_link         *l, 
2754                         const char      *macro,
2755                         const char      *args,
2756                         const char      select,
2757                         const char      *file, 
2758                         unsigned        line)
2759 {    
2760   if (l && l->class==select)
2761     {
2762         return l;
2763     }
2764     fprintf(stderr, 
2765             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2766             " expected %s, got %s\n",
2767             macro, args, file, line, 
2768             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2769     exit(-1);
2770     return l; // never reached, makes compiler happy.
2771 }