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