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