* as/mcs51/lkarea.c (lnkarea, lnkarea2): improved BSEG size calculation,
[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 (IFFUNC_BANKED (p) ? GPTRSIZE : 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   /* change it to a ptr to code area     */
1549   /* unless the function is banked.      */
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         if (!IFFUNC_BANKED(p->next))
1556         DCL_TYPE (p) = CPOINTER;
1557     }
1558 }
1559
1560 /*------------------------------------------------------------------*/
1561 /* checkDecl - does semantic validation of a declaration                   */
1562 /*------------------------------------------------------------------*/
1563 int 
1564 checkDecl (symbol * sym, int isProto)
1565 {
1566
1567   checkSClass (sym, isProto);           /* check the storage class      */
1568   changePointer (sym->type);          /* change pointers if required */
1569
1570   /* if this is an array without any dimension
1571      then update the dimension from the initial value */
1572   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1573     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1574
1575   return 0;
1576 }
1577
1578 /*------------------------------------------------------------------*/
1579 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1580 /*------------------------------------------------------------------*/
1581 sym_link *
1582 copyLinkChain (sym_link * p)
1583 {
1584   sym_link *head, *curr, *loop;
1585
1586   curr = p;
1587   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1588   while (curr)
1589     {
1590       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1591       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1592       loop = loop->next;
1593       curr = curr->next;
1594     }
1595
1596   return head;
1597 }
1598
1599 /*------------------------------------------------------------------*/
1600 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1601 /*                symbols in the given block                        */
1602 /*------------------------------------------------------------------*/
1603 void 
1604 cleanUpBlock (bucket ** table, int block)
1605 {
1606   int i;
1607   bucket *chain;
1608
1609   /* go thru the entire  table  */
1610   for (i = 0; i < 256; i++)
1611     {
1612       for (chain = table[i]; chain; chain = chain->next)
1613         {
1614           if (chain->block >= block)
1615             {
1616               deleteSym (table, chain->sym, chain->name);
1617             }
1618         }
1619     }
1620 }
1621
1622 /*------------------------------------------------------------------*/
1623 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1624 /*                symbols in the given level                        */
1625 /*------------------------------------------------------------------*/
1626 void 
1627 cleanUpLevel (bucket ** table, int level)
1628 {
1629   int i;
1630   bucket *chain;
1631
1632   /* go thru the entire  table  */
1633   for (i = 0; i < 256; i++)
1634     {
1635       for (chain = table[i]; chain; chain = chain->next)
1636         {
1637           if (chain->level >= level)
1638             {
1639               deleteSym (table, chain->sym, chain->name);
1640             }
1641         }
1642     }
1643 }
1644
1645 /*------------------------------------------------------------------*/
1646 /* computeTypeOr - computes the resultant type from two types       */
1647 /*------------------------------------------------------------------*/
1648 static sym_link *
1649 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1650 {
1651   /* sanity check */
1652   assert (   (IS_CHAR (etype1) || IS_BIT (etype1))
1653           && (IS_CHAR (etype2) || IS_BIT (etype2)));
1654
1655   if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1656     {
1657       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1658       return reType;
1659     }
1660   
1661   if (SPEC_USIGN (etype1))
1662     {
1663       if (   IS_LITERAL (etype2)
1664           && floatFromVal (valFromType (etype2)) >= 0)
1665         SPEC_USIGN (reType) = 1;
1666       else
1667         {
1668           /* promote to int */
1669           SPEC_USIGN (reType) = 0;
1670           SPEC_NOUN (reType) = V_INT;
1671         }
1672     }
1673   else /* etype1 signed */
1674     {
1675       if (   IS_LITERAL (etype2)
1676           && floatFromVal (valFromType (etype2)) <= 127)
1677         SPEC_USIGN (reType) = 0;
1678       else
1679         {
1680           /* promote to int */
1681           SPEC_USIGN (reType) = 0;
1682           SPEC_NOUN (reType) = V_INT;
1683         }
1684     }
1685
1686   if (SPEC_USIGN (etype2))
1687     {
1688       if (   IS_LITERAL (etype1)
1689           && floatFromVal (valFromType (etype1)) >= 0)
1690         SPEC_USIGN (reType) = 1;
1691       else
1692         {
1693           /* promote to int */
1694           SPEC_USIGN (reType) = 0;
1695           SPEC_NOUN (reType) = V_INT;
1696         }
1697     }
1698   else /* etype2 signed */
1699     {
1700       if (   IS_LITERAL (etype1)
1701           && floatFromVal (valFromType (etype1)) <= 127)
1702         SPEC_USIGN (reType) = 0;
1703       else
1704         {
1705           /* promote to int */
1706           SPEC_USIGN (reType) = 0;
1707           SPEC_NOUN (reType) = V_INT;
1708         }
1709     }
1710   return reType;
1711 }
1712
1713 /*------------------------------------------------------------------*/
1714 /* computeType - computes the resultant type from two types         */
1715 /*------------------------------------------------------------------*/
1716 sym_link *
1717 computeType (sym_link * type1, sym_link * type2,
1718              RESULT_TYPE resultType, int op)
1719 {
1720   sym_link *rType;
1721   sym_link *reType;
1722   sym_link *etype1 = getSpec (type1);
1723   sym_link *etype2;
1724
1725   etype2 = type2 ? getSpec (type2) : type1;
1726
1727   /* if one of them is a float then result is a float */
1728   /* here we assume that the types passed are okay */
1729   /* and can be cast to one another                */
1730   /* which ever is greater in size */
1731   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1732     rType = newFloatLink ();
1733   else
1734     /* if both are bitvars choose the larger one */
1735   if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1736     {
1737       rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1738                 copyLinkChain (type1) : copyLinkChain (type1);
1739     }
1740     /* if only one of them is a bit variable
1741        then the other one prevails */
1742   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1743     {
1744       rType = copyLinkChain (type2);
1745       /* bitfield can have up to 16 bits */
1746       if (getSize (etype1) > 1)
1747         SPEC_NOUN (getSpec (rType)) = V_INT;
1748     }
1749   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1750     {
1751       rType = copyLinkChain (type1);
1752       /* bitfield can have up to 16 bits */
1753       if (getSize (etype2) > 1)
1754         SPEC_NOUN (getSpec (rType)) = V_INT;
1755     }
1756   else
1757     /* if one of them is a pointer or array then that
1758        prevails */
1759   if (IS_PTR (type1) || IS_ARRAY (type1))
1760     rType = copyLinkChain (type1);
1761   else if (IS_PTR (type2) || IS_ARRAY (type2))
1762     rType = copyLinkChain (type2);
1763   else if (getSize (type1) > getSize (type2))
1764     rType = copyLinkChain (type1);
1765   else
1766     rType = copyLinkChain (type2);
1767
1768   reType = getSpec (rType);
1769
1770   /* avoid conflicting types */
1771   reType->select.s._signed = 0;
1772
1773   /* if result is a literal then make not so */
1774   if (IS_LITERAL (reType))
1775     SPEC_SCLS (reType) = S_REGISTER;
1776
1777   switch (resultType)
1778     {
1779       case RESULT_TYPE_CHAR:
1780         if (IS_BITVAR (reType))
1781           {
1782             SPEC_NOUN (reType) = V_CHAR;
1783             SPEC_SCLS (reType) = 0;
1784             SPEC_USIGN (reType) = 0;
1785             return rType;
1786           }
1787         break;
1788       case RESULT_TYPE_INT:
1789       case RESULT_TYPE_NONE:
1790       case RESULT_TYPE_OTHER:
1791         if (IS_BIT (reType))
1792           {
1793             SPEC_NOUN (reType) = V_CHAR;
1794             SPEC_SCLS (reType) = 0;
1795             SPEC_USIGN (reType) = 0;
1796             return rType;
1797           }
1798         else if (IS_BITFIELD (reType))
1799           {
1800             /* could be smarter, but it depends on the op */
1801             /* this is for the worst case: a multiplication of 4 * 4 bit */
1802             SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1803             SPEC_SCLS (reType) = 0;
1804             SPEC_USIGN (reType) = 0;
1805             return rType;
1806           }
1807         else if (IS_CHAR (reType))
1808           {
1809             if (op == '|' || op == '^')
1810               return computeTypeOr (etype1, etype2, reType);
1811             else if (   op == '&'
1812                      && SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1813               {
1814                 SPEC_USIGN (reType) = 1;
1815                 return rType;
1816               }
1817             else if (op == '*')
1818               {
1819                 SPEC_NOUN (reType) = V_INT;
1820                 SPEC_USIGN (reType) = 0;
1821                 return rType;
1822               }
1823             /* TODO: should be in SDCCast.c */
1824             else if (   op == '/'
1825                      && (   !SPEC_USIGN (etype1)
1826                          || !SPEC_USIGN (etype2)))
1827               {
1828                 SPEC_NOUN (reType) = V_INT;
1829                 SPEC_USIGN (reType) = 0;
1830                 return rType;
1831               }
1832           }
1833         break;
1834       default:
1835         break;
1836     }
1837
1838   /* SDCC's sign promotion:
1839      - if one or both operands are unsigned, the resultant type will be unsigned
1840        (except char, see below)
1841      - if an operand is promoted to a larger type (char -> int, int -> long),
1842        the larger type will be signed
1843
1844      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1845      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1846      the standard. The standard demands, that the result has to be the same
1847      "as if" the promotion would have been performed:
1848
1849      - if the result of an operation with two char's is promoted to a
1850        larger type, the result will be signed.
1851
1852      More sophisticated are these:
1853      - if the result of an operation with two char's is a char again,
1854        the result will only then be unsigned, if both operands are
1855        unsigned. In all other cases the result will be signed.
1856
1857        This seems to be contradictionary to the first two rules, but it makes
1858        real sense (all types are char's):
1859
1860         A signed char can be negative; this must be preserved in the result
1861                 -1 * 100 = -100;
1862
1863         Only if both operands are unsigned it's safe to make the result
1864         unsigned; this helps to avoid overflow:
1865                 2 * 100 =  200;
1866
1867      - ToDo: document '|', '^' and '&'
1868      
1869      Homework: - why is (200 * 200 < 0) true?
1870                - why is { char l = 200, r = 200; (r * l > 0) } true?
1871   */
1872
1873   if (!IS_FLOAT (reType)
1874       && (   (SPEC_USIGN (etype1)
1875               /* if this operand is promoted to a larger type,
1876                  then it will be promoted to a signed type */
1877               && !(getSize (etype1) < getSize (reType))
1878               /* char require special handling */
1879               && !IS_CHAR (etype1))
1880           || /* same for 2nd operand */  
1881              (SPEC_USIGN (etype2)
1882               && !(getSize (etype2) < getSize (reType))
1883               && !IS_CHAR (etype2))
1884           || /* if both are 'unsigned char' and not promoted
1885                 let the result be unsigned too */
1886              (   SPEC_USIGN (etype1)
1887               && SPEC_USIGN (etype2)
1888               && IS_CHAR (etype1)
1889               && IS_CHAR (etype2)
1890               && IS_CHAR (reType))))
1891     SPEC_USIGN (reType) = 1;
1892   else
1893     SPEC_USIGN (reType) = 0;
1894
1895   return rType;
1896 }
1897
1898 /*--------------------------------------------------------------------*/
1899 /* compareType - will do type check return 1 if match, -1 if castable */
1900 /*--------------------------------------------------------------------*/
1901 int
1902 compareType (sym_link * dest, sym_link * src)
1903 {
1904   if (!dest && !src)
1905     return 1;
1906
1907   if (dest && !src)
1908     return 0;
1909
1910   if (src && !dest)
1911     return 0;
1912
1913   /* if dest is a declarator then */
1914   if (IS_DECL (dest))
1915     {
1916       if (IS_DECL (src))
1917         {
1918           /* banked function pointer */
1919           if (IS_GENPTR (dest) && IS_GENPTR (src))
1920             {
1921               if (IS_FUNC (src->next) && IS_VOID(dest->next))
1922                 return -1;
1923               if (IS_FUNC (dest->next) && IS_VOID(src->next))
1924                 return -1;
1925               return compareType (dest->next, src->next);
1926             }
1927
1928           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1929             if (IS_FUNC(src)) {
1930               //checkFunction(src,dest);
1931             }
1932             return compareType (dest->next, src->next);
1933           }
1934           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1935             return -1;
1936           }
1937           if (IS_PTR (src) && 
1938               (IS_GENPTR (dest) ||
1939                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
1940              ))
1941             return -1;
1942           if (IS_PTR (dest) && IS_ARRAY (src)) {
1943             value *val=aggregateToPointer (valFromType(src));
1944             int res=compareType (dest, val->type);
1945             Safe_free(val->type);
1946             Safe_free(val);
1947             return res;
1948           }
1949           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1950             return compareType (dest->next, src);
1951           return 0;
1952         }
1953       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1954         return -1;
1955       else
1956         return 0;
1957     }
1958
1959   /* if one is a specifier and the other is not */
1960   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1961       (IS_SPEC (dest) && !IS_SPEC (src)))
1962     return 0;
1963
1964   /* if one of them is a void then ok */
1965   if (SPEC_NOUN (dest) == V_VOID &&
1966       SPEC_NOUN (src) != V_VOID)
1967     return -1;
1968
1969   if (SPEC_NOUN (dest) != V_VOID &&
1970       SPEC_NOUN (src) == V_VOID)
1971     return -1;
1972
1973   /* if they are both bitfields then if the lengths
1974      and starts don't match */
1975   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1976       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1977        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1978     return -1;
1979
1980   /* it is a specifier */
1981   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1982     {
1983       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1984           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1985           /* I would prefer
1986           bitsForType (dest) == bitsForType (src))
1987              instead of the next two lines, but the regression tests fail with
1988              them; I guess it's a problem with replaceCheaperOp  */
1989           getSize (dest) == getSize (src) &&
1990           !(!IS_BIT (dest) && IS_BIT (src)))
1991         return 1;
1992       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1993         return -1;
1994       else
1995         return 0;
1996     }
1997   else if (IS_STRUCT (dest))
1998     {
1999       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2000         return 0;
2001       else
2002         return 1;
2003     }
2004   if (SPEC_LONG (dest) != SPEC_LONG (src))
2005     return -1;
2006
2007   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2008     return -1;
2009
2010   return 1;
2011 }
2012
2013 /*--------------------------------------------------------------------*/
2014 /* compareTypeExact - will do type check return 1 if match exactly    */
2015 /*--------------------------------------------------------------------*/
2016 int
2017 compareTypeExact (sym_link * dest, sym_link * src, int level)
2018 {
2019   STORAGE_CLASS srcScls, destScls;
2020   
2021   if (!dest && !src)
2022     return 1;
2023
2024   if (dest && !src)
2025     return 0;
2026
2027   if (src && !dest)
2028     return 0;
2029
2030   /* if dest is a declarator then */
2031   if (IS_DECL (dest))
2032     {
2033       if (IS_DECL (src))
2034         {
2035           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2036             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2037               return 0;
2038             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2039               return 0;
2040             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2041               return 0;
2042             if (IS_FUNC(src))
2043               {
2044                 value *exargs, *acargs, *checkValue;
2045
2046                 /* verify function return type */
2047                 if (!compareTypeExact (dest->next, src->next, -1))
2048                   return 0;
2049                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2050                   return 0;
2051                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2052                   return 0;
2053                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2054                   return 0;
2055                 #if 0
2056                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2057                   return 0;
2058                 #endif
2059
2060                 /* compare expected args with actual args */
2061                 exargs = FUNC_ARGS(dest);
2062                 acargs = FUNC_ARGS(src);
2063
2064                 /* for all the expected args do */
2065                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2066                   {
2067                     //checkTypeSanity(acargs->etype, acargs->name);
2068
2069                     if (IS_AGGREGATE (acargs->type))
2070                       {
2071                         checkValue = copyValue (acargs);
2072                         aggregateToPointer (checkValue);
2073                       }
2074                     else
2075                       checkValue = acargs;
2076
2077                     #if 0
2078                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
2079                       return 0;
2080                     #endif
2081                   }
2082
2083                   /* if one them ended we have a problem */
2084                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2085                       (!exargs && acargs && !IS_VOID (acargs->type)))
2086                     return 0;                  
2087                   return 1;
2088               }
2089             return compareTypeExact (dest->next, src->next, level);
2090           }
2091           return 0;
2092         }
2093       return 0;
2094     }
2095
2096   /* if one is a specifier and the other is not */
2097   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2098       (IS_SPEC (dest) && !IS_SPEC (src)))
2099     return 0;
2100
2101   /* if one of them is a void then ok */
2102   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2103     return 0;
2104
2105   /* if they are both bitfields then if the lengths
2106      and starts don't match */
2107   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2108       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2109        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2110     return 0;
2111
2112   if (IS_INTEGRAL (dest))
2113     {
2114       /* signedness must match */
2115       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2116         return 0;
2117       /* size must match */
2118       if (SPEC_LONG (dest) != SPEC_LONG (src))
2119         return 0;
2120       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2121         return 0;
2122     }
2123   
2124   if (IS_STRUCT (dest))
2125     {
2126       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2127         return 0;
2128     }
2129
2130   if (SPEC_CONST (dest) != SPEC_CONST (src))
2131     return 0;
2132   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2133     return 0;
2134   if (SPEC_STAT (dest) != SPEC_STAT (src))
2135     return 0;
2136   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2137     return 0;
2138   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2139     return 0;
2140       
2141   destScls = SPEC_SCLS (dest);
2142   srcScls = SPEC_SCLS (src);
2143   
2144   /* Compensate for const to const code change in checkSClass() */
2145   if (!level & port->mem.code_ro && SPEC_CONST (dest))
2146     {
2147       if (srcScls == S_CODE && destScls == S_FIXED)
2148         destScls = S_CODE;
2149       if (destScls == S_CODE && srcScls == S_FIXED)
2150         srcScls = S_CODE;
2151     }
2152
2153   /* compensate for allocGlobal() */  
2154   if ((srcScls == S_FIXED || srcScls == S_AUTO)
2155       && port->mem.default_globl_map == xdata
2156       && !level)
2157     srcScls = S_XDATA;
2158   
2159   if (level>0 && !SPEC_STAT (dest))
2160     {
2161       /* Compensate for hack-o-matic in checkSClass() */
2162       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2163         {
2164           if (destScls == S_FIXED)
2165             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2166           if (srcScls == S_FIXED)
2167             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2168         }
2169       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2170         {
2171           if (destScls == S_FIXED)
2172             destScls = S_XDATA;
2173           if (srcScls == S_FIXED)
2174             srcScls = S_XDATA;
2175         }
2176     }
2177
2178   if (srcScls != destScls)
2179     {
2180       #if 0
2181       printf ("level = %d\n", level);
2182       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2183                 SPEC_SCLS (src), SPEC_SCLS (dest));
2184       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2185       #endif
2186       return 0;
2187     }
2188   
2189   return 1;
2190 }
2191
2192 /*------------------------------------------------------------------*/
2193 /* inCalleeSaveList - return 1 if found in callee save list          */
2194 /*------------------------------------------------------------------*/
2195 static int
2196 calleeCmp(void *p1, void *p2)
2197 {
2198   return (strcmp((char *)p1, (char *)(p2)) == 0);
2199 }
2200
2201 bool
2202 inCalleeSaveList(char *s)
2203 {
2204   if (options.all_callee_saves)
2205     return 1;
2206   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2207 }
2208
2209 /*-----------------------------------------------------------------*/
2210 /* aggregateToPointer:  change an agggregate type function      */
2211 /*         argument to a pointer to that type.     */
2212 /*-----------------------------------------------------------------*/
2213 value *
2214 aggregateToPointer (value * val)
2215 {
2216   if (IS_AGGREGATE (val->type))
2217     {
2218       /* if this is a structure */
2219       /* then we need to add a new link */
2220       if (IS_STRUCT (val->type))
2221         {
2222           /* first lets add DECLARATOR type */
2223           sym_link *p = val->type;
2224
2225           werror (W_STRUCT_AS_ARG, val->name);
2226           val->type = newLink (DECLARATOR);
2227           val->type->next = p;
2228         }
2229
2230       /* change to a pointer depending on the */
2231       /* storage class specified        */
2232       switch (SPEC_SCLS (val->etype))
2233         {
2234         case S_IDATA:
2235           DCL_TYPE (val->type) = IPOINTER;
2236           break;
2237         case S_PDATA:
2238           DCL_TYPE (val->type) = PPOINTER;
2239           break;
2240         case S_FIXED:
2241           if (SPEC_OCLS(val->etype)) {
2242             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2243           } else {
2244             // this happens for (external) function parameters
2245             DCL_TYPE (val->type) = port->unqualified_pointer;
2246           }
2247           break;
2248         case S_AUTO:
2249         case S_DATA:
2250         case S_REGISTER:
2251           DCL_TYPE (val->type) = POINTER;
2252           break;
2253         case S_CODE:
2254           DCL_TYPE (val->type) = CPOINTER;
2255           break;
2256         case S_XDATA:
2257           DCL_TYPE (val->type) = FPOINTER;
2258           break;
2259         case S_EEPROM:
2260           DCL_TYPE (val->type) = EEPPOINTER;
2261           break;
2262         default:
2263           DCL_TYPE (val->type) = port->unqualified_pointer;
2264         }
2265       
2266       /* is there is a symbol associated then */
2267       /* change the type of the symbol as well */
2268       if (val->sym)
2269         {
2270           val->sym->type = copyLinkChain (val->type);
2271           val->sym->etype = getSpec (val->sym->type);
2272         }
2273     }
2274   return val;
2275 }
2276 /*------------------------------------------------------------------*/
2277 /* checkFunction - does all kinds of check on a function            */
2278 /*------------------------------------------------------------------*/
2279 int 
2280 checkFunction (symbol * sym, symbol *csym)
2281 {
2282   value *exargs, *acargs;
2283   value *checkValue;
2284   int argCnt = 0;
2285
2286   if (getenv("DEBUG_SANITY")) {
2287     fprintf (stderr, "checkFunction: %s ", sym->name);
2288   }
2289
2290   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2291     {
2292       werror(E_SYNTAX_ERROR, sym->name);
2293       return 0;
2294     }
2295     
2296   /* make sure the type is complete and sane */
2297   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2298
2299   /* if not type then some kind of error */
2300   if (!sym->type)
2301     return 0;
2302
2303   /* if the function has no type then make it return int */
2304   if (!sym->type->next)
2305     sym->type->next = sym->etype = newIntLink ();
2306
2307   /* function cannot return aggregate */
2308   if (IS_AGGREGATE (sym->type->next))
2309     {
2310       werror (E_FUNC_AGGR, sym->name);
2311       return 0;
2312     }
2313
2314   /* function cannot return bit */
2315   if (IS_BITVAR (sym->type->next))
2316     {
2317       werror (E_FUNC_BIT, sym->name);
2318       return 0;
2319     }
2320
2321   /* check if this function is defined as calleeSaves
2322      then mark it as such */
2323   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2324
2325   /* if interrupt service routine  */
2326   /* then it cannot have arguments */
2327   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2328     {
2329       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2330         werror (E_INT_ARGS, sym->name);
2331         FUNC_ARGS(sym->type)=NULL;
2332       }
2333     }
2334
2335   if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2336     {
2337       werror (E_SHADOWREGS_NO_ISR, sym->name);
2338     }
2339
2340
2341   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
2342        acargs; 
2343        acargs=acargs->next, argCnt++) {
2344     if (!acargs->sym) { 
2345       // this can happen for reentrant functions
2346       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2347       // the show must go on: synthesize a name and symbol
2348       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2349       acargs->sym = newSymbol (acargs->name, 1);
2350       SPEC_OCLS (acargs->etype) = istack;
2351       acargs->sym->type = copyLinkChain (acargs->type);
2352       acargs->sym->etype = getSpec (acargs->sym->type);
2353       acargs->sym->_isparm = 1;
2354       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2355     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2356       // synthesized name
2357       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2358     }
2359   }
2360   argCnt--;
2361
2362   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2363     return 1;                   /* not defined nothing more to check  */
2364
2365   /* check if body already present */
2366   if (csym && IFFUNC_HASBODY(csym->type))
2367     {
2368       werror (E_FUNC_BODY, sym->name);
2369       return 0;
2370     }
2371
2372   /* check the return value type   */
2373   if (compareType (csym->type, sym->type) <= 0)
2374     {
2375       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2376       printFromToType(csym->type, sym->type);
2377       return 0;
2378     }
2379
2380   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2381     {
2382       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2383     }
2384
2385   /* I don't think this is necessary for interrupts. An isr is a  */
2386   /* root in the calling tree.                                    */
2387   if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2388       (!FUNC_ISISR (sym->type)))
2389     {
2390       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2391     }
2392
2393   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2394     {
2395       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2396     }
2397
2398   /* Really, reentrant should match regardless of argCnt, but     */
2399   /* this breaks some existing code (the fp lib functions). If    */
2400   /* the first argument is always passed the same way, this       */
2401   /* lax checking is ok (but may not be true for in future ports) */
2402   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2403       && argCnt>1)
2404     {
2405       //printf("argCnt = %d\n",argCnt);
2406       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2407     }
2408
2409   if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2410     {
2411       werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2412     }
2413
2414   if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2415     {
2416       werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2417     }
2418   
2419
2420   /* compare expected args with actual args */
2421   exargs = FUNC_ARGS(csym->type);
2422   acargs = FUNC_ARGS(sym->type);
2423
2424   /* for all the expected args do */
2425   for (argCnt = 1;
2426        exargs && acargs;
2427        exargs = exargs->next, acargs = acargs->next, argCnt++)
2428     {
2429       if (getenv("DEBUG_SANITY")) {
2430         fprintf (stderr, "checkFunction: %s ", exargs->name);
2431       }
2432       /* make sure the type is complete and sane */
2433       checkTypeSanity(exargs->etype, exargs->name);
2434
2435       /* If the actual argument is an array, any prototype
2436        * will have modified it to a pointer. Duplicate that
2437        * change here.
2438        */
2439       if (IS_AGGREGATE (acargs->type))
2440         {
2441           checkValue = copyValue (acargs);
2442           aggregateToPointer (checkValue);
2443         }
2444       else
2445         {
2446           checkValue = acargs;
2447         }
2448
2449       if (compareType (exargs->type, checkValue->type) <= 0)
2450         {
2451           werror (E_ARG_TYPE, argCnt);
2452           printFromToType(exargs->type, checkValue->type);
2453           return 0;
2454         }
2455     }
2456
2457   /* if one them ended we have a problem */
2458   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2459       (!exargs && acargs && !IS_VOID (acargs->type)))
2460     werror (E_ARG_COUNT);
2461
2462   /* replace with this defition */
2463   sym->cdef = csym->cdef;
2464   deleteSym (SymbolTab, csym, csym->name);
2465   deleteFromSeg(csym);
2466   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2467   if (IS_EXTERN (csym->etype) && !
2468       IS_EXTERN (sym->etype))
2469     {
2470       addSet (&publics, sym);
2471     }
2472   return 1;
2473 }
2474
2475 /*------------------------------------------------------------------*/
2476 /* cdbStructBlock - calls struct printing for a blcks               */
2477 /*------------------------------------------------------------------*/
2478 void cdbStructBlock (int block)
2479 {
2480   int i;
2481   bucket **table = StructTab;
2482   bucket *chain;
2483
2484   /* go thru the entire  table  */
2485   for (i = 0; i < 256; i++)
2486     {
2487       for (chain = table[i]; chain; chain = chain->next)
2488         {
2489           if (chain->block >= block)
2490             {
2491               if(debugFile)
2492                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2493             }
2494         }
2495     }
2496 }
2497
2498 /*-----------------------------------------------------------------*/
2499 /* processFuncArgs - does some processing with function args       */
2500 /*-----------------------------------------------------------------*/
2501 void 
2502 processFuncArgs (symbol * func)
2503 {
2504   value *val;
2505   int pNum = 1;
2506   sym_link *funcType=func->type;
2507
2508   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2509     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2510
2511   /* find the function declaration within the type */
2512   while (funcType && !IS_FUNC(funcType))
2513     funcType=funcType->next;
2514
2515   /* if this function has variable argument list */
2516   /* then make the function a reentrant one    */
2517   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2518     FUNC_ISREENT(funcType)=1;
2519
2520   /* check if this function is defined as calleeSaves
2521      then mark it as such */
2522   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2523
2524   /* loop thru all the arguments   */
2525   val = FUNC_ARGS(funcType);
2526
2527   /* if it is void then remove parameters */
2528   if (val && IS_VOID (val->type))
2529     {
2530       FUNC_ARGS(funcType) = NULL;
2531       return;
2532     }
2533
2534   /* reset regparm for the port */
2535   (*port->reset_regparms) ();
2536
2537   /* if any of the arguments is an aggregate */
2538   /* change it to pointer to the same type */
2539   while (val)
2540     {
2541       int argreg = 0;
2542       char buffer[SDCC_NAME_MAX+1];
2543       
2544       SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2545       checkTypeSanity (val->etype, buffer);
2546       
2547       /* mark it as a register parameter if
2548          the function does not have VA_ARG
2549          and as port dictates */
2550       if (!IFFUNC_HASVARARGS(funcType) &&
2551           (argreg = (*port->reg_parm) (val->type)))
2552         {
2553           SPEC_REGPARM (val->etype) = 1;
2554           SPEC_ARGREG(val->etype) = argreg;
2555         } else if (IFFUNC_ISREENT(funcType)) {
2556             FUNC_HASSTACKPARM(funcType) = 1;
2557         }
2558
2559       if (IS_AGGREGATE (val->type))
2560         {
2561           aggregateToPointer (val);
2562         }
2563
2564       val = val->next;
2565       pNum++;
2566     }
2567
2568   /* if this is an internal generated function call */
2569   if (func->cdef) {
2570     /* ignore --stack-auto for this one, we don't know how it is compiled */
2571     /* simply trust on --int-long-reent or --float-reent */
2572     if (IFFUNC_ISREENT(funcType)) {
2573       return;
2574     }
2575   } else {
2576     /* if this function is reentrant or */
2577     /* automatics r 2b stacked then nothing */
2578     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2579       return;
2580   }
2581
2582   val = FUNC_ARGS(funcType);
2583   pNum = 1;
2584   while (val)
2585     {
2586
2587       /* if a symbolname is not given  */
2588       /* synthesize a variable name */
2589       if (!val->sym)
2590         {
2591           SNPRINTF (val->name, sizeof(val->name), 
2592                     "_%s_PARM_%d", func->name, pNum++);
2593           val->sym = newSymbol (val->name, 1);
2594           if (SPEC_SCLS(val->etype) == S_BIT)
2595             SPEC_OCLS (val->etype) = bit;
2596           else
2597             SPEC_OCLS (val->etype) = port->mem.default_local_map;
2598           val->sym->type = copyLinkChain (val->type);
2599           val->sym->etype = getSpec (val->sym->type);
2600           val->sym->_isparm = 1;
2601           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2602           #if 0
2603           /* ?? static functions shouldn't imply static parameters - EEP */
2604           if (IS_SPEC(func->etype)) {
2605             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2606               SPEC_STAT (func->etype);
2607           }
2608           #endif
2609           addSymChain (&val->sym);
2610
2611         }
2612       else                      /* symbol name given create synth name */
2613         {
2614
2615           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2616           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2617           val->sym->_isparm = 1;
2618           if (SPEC_SCLS(val->etype) == S_BIT)
2619             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2620           else
2621             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2622               (options.model != MODEL_SMALL ? xdata : data);
2623           
2624           #if 0
2625           /* ?? static functions shouldn't imply static parameters - EEP */
2626           if (IS_SPEC(func->etype)) {
2627             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2628               SPEC_STAT (func->etype);
2629           }
2630           #endif
2631         }
2632       if (!isinSet(operKeyReset, val->sym)) {
2633         addSet (&operKeyReset, val->sym);
2634         applyToSet (operKeyReset, resetParmKey);
2635       }
2636       val = val->next;
2637     }
2638 }
2639
2640 /*-----------------------------------------------------------------*/
2641 /* isSymbolEqual - compares two symbols return 1 if they match     */
2642 /*-----------------------------------------------------------------*/
2643 int 
2644 isSymbolEqual (symbol * dest, symbol * src)
2645 {
2646   /* if pointers match then equal */
2647   if (dest == src)
2648     return 1;
2649
2650   /* if one of them is null then don't match */
2651   if (!dest || !src)
2652     return 0;
2653
2654   /* if both of them have rname match on rname */
2655   if (dest->rname[0] && src->rname[0])
2656     return (!strcmp (dest->rname, src->rname));
2657
2658   /* otherwise match on name */
2659   return (!strcmp (dest->name, src->name));
2660 }
2661
2662 void PT(sym_link *type)
2663 {
2664         printTypeChain(type,0);
2665 }
2666 /*-----------------------------------------------------------------*/
2667 /* printTypeChain - prints the type chain in human readable form   */
2668 /*-----------------------------------------------------------------*/
2669 void
2670 printTypeChain (sym_link * start, FILE * of)
2671 {
2672   int nlr = 0;
2673   value *args;
2674   sym_link * type, * search;
2675   STORAGE_CLASS scls;
2676
2677   if (!of)
2678     {
2679       of = stdout;
2680       nlr = 1;
2681     }
2682
2683   if (start==NULL) {
2684     fprintf (of, "void");
2685     return;
2686   }
2687
2688   /* Print the chain as it is written in the source: */
2689   /* start with the last entry.                      */
2690   /* However, the storage class at the end of the    */
2691   /* chain reall applies to the first in the chain!  */
2692
2693   for (type = start; type && type->next; type = type->next)
2694     ;
2695   if (IS_SPEC (type))
2696     scls=SPEC_SCLS(type);
2697   else
2698     scls=0;
2699   while (type)
2700     {
2701       if (type==start) {
2702         switch (scls) 
2703           {
2704           case S_DATA: fprintf (of, "data-"); break;
2705           case S_XDATA: fprintf (of, "xdata-"); break;
2706           case S_SFR: fprintf (of, "sfr-"); break;
2707           case S_SBIT: fprintf (of, "sbit-"); break;
2708           case S_CODE: fprintf (of, "code-"); break;
2709           case S_IDATA: fprintf (of, "idata-"); break;
2710           case S_PDATA: fprintf (of, "pdata-"); break;
2711           case S_LITERAL: fprintf (of, "literal-"); break;
2712           case S_STACK: fprintf (of, "stack-"); break;
2713           case S_XSTACK: fprintf (of, "xstack-"); break;
2714           case S_BIT: fprintf (of, "bit-"); break;
2715           case S_EEPROM: fprintf (of, "eeprom-"); break;
2716           default: break;
2717           }
2718       }
2719
2720       if (IS_DECL (type))
2721         {
2722           if (!IS_FUNC(type)) {
2723             if (DCL_PTR_VOLATILE (type)) {
2724               fprintf (of, "volatile-");
2725             }
2726             if (DCL_PTR_CONST (type)) {
2727               fprintf (of, "const-");
2728             }
2729           }
2730           switch (DCL_TYPE (type))
2731             {
2732             case FUNCTION:
2733               fprintf (of, "function %s %s", 
2734                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2735                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2736               fprintf (of, "( ");
2737               for (args = FUNC_ARGS(type); 
2738                    args; 
2739                    args=args->next) {
2740                 printTypeChain(args->type, of);
2741                 if (args->next)
2742                   fprintf(of, ", ");
2743               }
2744               fprintf (of, ") ");
2745               break;
2746             case GPOINTER:
2747               fprintf (of, "generic* ");
2748               break;
2749             case CPOINTER:
2750               fprintf (of, "code* ");
2751               break;
2752             case FPOINTER:
2753               fprintf (of, "xdata* ");
2754               break;
2755             case EEPPOINTER:
2756               fprintf (of, "eeprom* ");
2757               break;
2758             case POINTER:
2759               fprintf (of, "near* ");
2760               break;
2761             case IPOINTER:
2762               fprintf (of, "idata* ");
2763               break;
2764             case PPOINTER:
2765               fprintf (of, "pdata* ");
2766               break;
2767             case UPOINTER:
2768               fprintf (of, "unknown* ");
2769               break;
2770             case ARRAY:
2771               if (DCL_ELEM(type)) {
2772                 fprintf (of, "[%d] ", DCL_ELEM(type));
2773               } else {
2774                 fprintf (of, "[] ");
2775               }
2776               break;
2777             }
2778         }
2779       else
2780         {
2781           if (SPEC_VOLATILE (type))
2782             fprintf (of, "volatile-");
2783           if (SPEC_CONST (type))
2784             fprintf (of, "const-");
2785           if (SPEC_USIGN (type))
2786             fprintf (of, "unsigned-");
2787           switch (SPEC_NOUN (type))
2788             {
2789             case V_INT:
2790               if (IS_LONG (type))
2791                 fprintf (of, "long-");
2792               fprintf (of, "int");
2793               break;
2794
2795             case V_CHAR:
2796               fprintf (of, "char");
2797               break;
2798
2799             case V_VOID:
2800               fprintf (of, "void");
2801               break;
2802
2803             case V_FLOAT:
2804               fprintf (of, "float");
2805               break;
2806
2807             case V_STRUCT:
2808               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2809               break;
2810
2811             case V_SBIT:
2812               fprintf (of, "sbit");
2813               break;
2814
2815             case V_BIT:
2816               fprintf (of, "bit");
2817               break;
2818
2819             case V_BITFIELD:
2820               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2821               break;
2822
2823             case V_DOUBLE:
2824               fprintf (of, "double");
2825               break;
2826
2827             default:
2828               fprintf (of, "unknown type");
2829               break;
2830             }
2831         }
2832       /* search entry in list before "type" */
2833       for (search = start; search && search->next != type;)
2834         search = search->next;
2835       type = search;
2836       if (type)
2837         fputc (' ', of);
2838     }
2839   if (nlr)
2840     fprintf (of, "\n");
2841 }
2842
2843 /*--------------------------------------------------------------------*/
2844 /* printTypeChainRaw - prints the type chain in human readable form   */
2845 /*                     in the raw data structure ordering             */
2846 /*--------------------------------------------------------------------*/
2847 void
2848 printTypeChainRaw (sym_link * start, FILE * of)
2849 {
2850   int nlr = 0;
2851   value *args;
2852   sym_link * type;
2853
2854   if (!of)
2855     {
2856       of = stdout;
2857       nlr = 1;
2858     }
2859
2860   if (start==NULL) {
2861     fprintf (of, "void");
2862     return;
2863   }
2864
2865   type = start;
2866   
2867   while (type)
2868     {
2869       if (IS_DECL (type))
2870         {
2871           if (!IS_FUNC(type)) {
2872             if (DCL_PTR_VOLATILE (type)) {
2873               fprintf (of, "volatile-");
2874             }
2875             if (DCL_PTR_CONST (type)) {
2876               fprintf (of, "const-");
2877             }
2878           }
2879           switch (DCL_TYPE (type))
2880             {
2881             case FUNCTION:
2882               fprintf (of, "function %s %s", 
2883                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2884                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2885               fprintf (of, "( ");
2886               for (args = FUNC_ARGS(type); 
2887                    args; 
2888                    args=args->next) {
2889                 printTypeChain(args->type, of);
2890                 if (args->next)
2891                   fprintf(of, ", ");
2892               }
2893               fprintf (of, ") ");
2894               break;
2895             case GPOINTER:
2896               fprintf (of, "generic* ");
2897               break;
2898             case CPOINTER:
2899               fprintf (of, "code* ");
2900               break;
2901             case FPOINTER:
2902               fprintf (of, "xdata* ");
2903               break;
2904             case EEPPOINTER:
2905               fprintf (of, "eeprom* ");
2906               break;
2907             case POINTER:
2908               fprintf (of, "near* ");
2909               break;
2910             case IPOINTER:
2911               fprintf (of, "idata* ");
2912               break;
2913             case PPOINTER:
2914               fprintf (of, "pdata* ");
2915               break;
2916             case UPOINTER:
2917               fprintf (of, "unknown* ");
2918               break;
2919             case ARRAY:
2920               if (DCL_ELEM(type)) {
2921                 fprintf (of, "[%d] ", DCL_ELEM(type));
2922               } else {
2923                 fprintf (of, "[] ");
2924               }
2925               break;
2926             }
2927           if (DCL_TSPEC(type))
2928             {
2929               fprintf (of, "{");
2930               printTypeChainRaw(DCL_TSPEC(type), of);
2931               fprintf (of, "}");
2932             }
2933         }
2934       else if (IS_SPEC (type))
2935         {
2936         switch (SPEC_SCLS (type)) 
2937           {
2938           case S_DATA: fprintf (of, "data-"); break;
2939           case S_XDATA: fprintf (of, "xdata-"); break;
2940           case S_SFR: fprintf (of, "sfr-"); break;
2941           case S_SBIT: fprintf (of, "sbit-"); break;
2942           case S_CODE: fprintf (of, "code-"); break;
2943           case S_IDATA: fprintf (of, "idata-"); break;
2944           case S_PDATA: fprintf (of, "pdata-"); break;
2945           case S_LITERAL: fprintf (of, "literal-"); break;
2946           case S_STACK: fprintf (of, "stack-"); break;
2947           case S_XSTACK: fprintf (of, "xstack-"); break;
2948           case S_BIT: fprintf (of, "bit-"); break;
2949           case S_EEPROM: fprintf (of, "eeprom-"); break;
2950           default: break;
2951           }
2952           if (SPEC_VOLATILE (type))
2953             fprintf (of, "volatile-");
2954           if (SPEC_CONST (type))
2955             fprintf (of, "const-");
2956           if (SPEC_USIGN (type))
2957             fprintf (of, "unsigned-");
2958           switch (SPEC_NOUN (type))
2959             {
2960             case V_INT:
2961               if (IS_LONG (type))
2962                 fprintf (of, "long-");
2963               fprintf (of, "int");
2964               break;
2965
2966             case V_CHAR:
2967               fprintf (of, "char");
2968               break;
2969
2970             case V_VOID:
2971               fprintf (of, "void");
2972               break;
2973
2974             case V_FLOAT:
2975               fprintf (of, "float");
2976               break;
2977
2978             case V_STRUCT:
2979               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2980               break;
2981
2982             case V_SBIT:
2983               fprintf (of, "sbit");
2984               break;
2985
2986             case V_BIT:
2987               fprintf (of, "bit");
2988               break;
2989
2990             case V_BITFIELD:
2991               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2992               break;
2993
2994             case V_DOUBLE:
2995               fprintf (of, "double");
2996               break;
2997
2998             default:
2999               fprintf (of, "unknown type");
3000               break;
3001             }
3002         }
3003       else
3004         fprintf (of, "NOT_SPEC_OR_DECL");
3005       type = type->next;
3006       if (type)
3007         fputc (' ', of);
3008     }
3009   if (nlr)
3010     fprintf (of, "\n");
3011 }
3012
3013
3014 /*-----------------------------------------------------------------*/
3015 /* powof2 - returns power of two for the number if number is pow 2 */
3016 /*-----------------------------------------------------------------*/
3017 int
3018 powof2 (TYPE_UDWORD num)
3019 {
3020   int nshifts = 0;
3021   int n1s = 0;
3022
3023   while (num)
3024     {
3025       if (num & 1)
3026         n1s++;
3027       num >>= 1;
3028       nshifts++;
3029     }
3030
3031   if (n1s > 1 || nshifts == 0)
3032     return 0;
3033   return nshifts - 1;
3034 }
3035
3036 symbol *__fsadd;
3037 symbol *__fssub;
3038 symbol *__fsmul;
3039 symbol *__fsdiv;
3040 symbol *__fseq;
3041 symbol *__fsneq;
3042 symbol *__fslt;
3043 symbol *__fslteq;
3044 symbol *__fsgt;
3045 symbol *__fsgteq;
3046
3047 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3048 symbol *__muldiv[3][3][2];
3049 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3050 sym_link *__multypes[3][2];
3051 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3052 symbol *__conv[2][3][2];
3053 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3054 symbol *__rlrr[2][3][2];
3055
3056 sym_link *floatType;
3057
3058 static char *
3059 _mangleFunctionName(char *in)
3060 {
3061   if (port->getMangledFunctionName)
3062     {
3063       return port->getMangledFunctionName(in);
3064     }
3065   else
3066     {
3067       return in;
3068     }
3069 }
3070
3071 /*-----------------------------------------------------------------*/
3072 /* typeFromStr - create a typechain from an encoded string         */
3073 /* basic types -        'c' - char                                 */
3074 /*                      's' - short                                */
3075 /*                      'i' - int                                  */
3076 /*                      'l' - long                                 */
3077 /*                      'f' - float                                */
3078 /*                      'v' - void                                 */
3079 /*                      '*' - pointer - default (GPOINTER)         */
3080 /* modifiers -          'u' - unsigned                             */
3081 /* pointer modifiers -  'g' - generic                              */
3082 /*                      'x' - xdata                                */
3083 /*                      'p' - code                                 */
3084 /*                      'd' - data                                 */                     
3085 /*                      'F' - function                             */                     
3086 /* examples : "ig*" - generic int *                                */
3087 /*            "cx*" - char xdata *                                 */
3088 /*            "ui" -  unsigned int                                 */
3089 /*-----------------------------------------------------------------*/
3090 sym_link *typeFromStr (char *s)
3091 {
3092     sym_link *r = newLink(DECLARATOR);
3093     int usign = 0;
3094
3095     do {
3096         sym_link *nr;
3097         switch (*s) {
3098         case 'u' : 
3099             usign = 1;
3100             s++;
3101             continue ;
3102             break ;
3103         case 'c':
3104             r->class = SPECIFIER;
3105             SPEC_NOUN(r) = V_CHAR;
3106             break;
3107         case 's':
3108         case 'i':
3109             r->class = SPECIFIER;
3110             SPEC_NOUN(r) = V_INT;
3111             break;
3112         case 'l':
3113             r->class = SPECIFIER;
3114             SPEC_NOUN(r) = V_INT;
3115             SPEC_LONG(r) = 1;
3116             break;
3117         case 'f':
3118             r->class = SPECIFIER;
3119             SPEC_NOUN(r) = V_FLOAT;
3120             break;
3121         case 'v':
3122             r->class = SPECIFIER;
3123             SPEC_NOUN(r) = V_VOID;
3124             break;
3125         case '*':
3126             DCL_TYPE(r) = port->unqualified_pointer;
3127             break;
3128         case 'g':
3129         case 'x':
3130         case 'p':
3131         case 'd':
3132         case 'F':
3133             assert(*(s+1)=='*');
3134             nr = newLink(DECLARATOR);
3135             nr->next = r;
3136             r = nr;
3137             switch (*s) {
3138             case 'g':
3139                 DCL_TYPE(r) = GPOINTER;
3140                 break;
3141             case 'x':
3142                 DCL_TYPE(r) = FPOINTER;
3143                 break;
3144             case 'p':
3145                 DCL_TYPE(r) = CPOINTER;
3146                 break;
3147             case 'd':
3148                 DCL_TYPE(r) = POINTER;
3149                 break;
3150             case 'F':
3151                 DCL_TYPE(r) = FUNCTION;
3152                 nr = newLink(DECLARATOR);
3153                 nr->next = r;
3154                 r = nr;
3155                 DCL_TYPE(r) = CPOINTER;
3156                 break;
3157             }
3158             s++;
3159             break;
3160         default:
3161             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
3162                    "typeFromStr: unknown type");
3163             break;
3164         }
3165         if (IS_SPEC(r) && usign) {
3166             SPEC_USIGN(r) = 1;
3167             usign = 0;
3168         }
3169         s++;
3170     } while (*s);
3171     return r;
3172 }
3173
3174 /*-----------------------------------------------------------------*/
3175 /* initCSupport - create functions for C support routines          */
3176 /*-----------------------------------------------------------------*/
3177 void 
3178 initCSupport ()
3179 {
3180   const char *smuldivmod[] =
3181   {
3182     "mul", "div", "mod"
3183   };
3184   const char *sbwd[] =
3185   {
3186     "char", "int", "long"
3187   };
3188   const char *ssu[] =
3189   {
3190     "s", "u"
3191   };
3192   const char *srlrr[] =
3193   {
3194     "rl", "rr"
3195   };
3196
3197   int bwd, su, muldivmod, tofrom, rlrr;
3198
3199   if (getenv("SDCC_NO_C_SUPPORT")) {
3200     /* for debugging only */
3201     return;
3202   }
3203
3204   floatType = newFloatLink ();
3205
3206   for (bwd = 0; bwd < 3; bwd++)
3207     {
3208       sym_link *l = NULL;
3209       switch (bwd)
3210         {
3211         case 0:
3212           l = newCharLink ();
3213           break;
3214         case 1:
3215           l = newIntLink ();
3216           break;
3217         case 2:
3218           l = newLongLink ();
3219           break;
3220         default:
3221           assert (0);
3222         }
3223       __multypes[bwd][0] = l;
3224       __multypes[bwd][1] = copyLinkChain (l);
3225       SPEC_USIGN (__multypes[bwd][1]) = 1;
3226     }
3227
3228   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3229   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3230   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3231   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3232   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3233   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3234   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3235   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3236   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3237   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3238
3239   for (tofrom = 0; tofrom < 2; tofrom++)
3240     {
3241       for (bwd = 0; bwd < 3; bwd++)
3242         {
3243           for (su = 0; su < 2; su++)
3244             {
3245               if (tofrom)
3246                 {
3247                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3248                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3249                 }
3250               else
3251                 {
3252                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3253                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3254                 }
3255             }
3256         }
3257     }
3258
3259 /*
3260   for (muldivmod = 0; muldivmod < 3; muldivmod++)
3261     {
3262       for (bwd = 0; bwd < 3; bwd++)
3263         {
3264           for (su = 0; su < 2; su++)
3265             {
3266               SNPRINTF (buffer, sizeof(buffer),
3267                         "_%s%s%s",
3268                        smuldivmod[muldivmod],
3269                        ssu[su],
3270                        sbwd[bwd]);
3271               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3272               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3273             }
3274         }
3275     }
3276
3277   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3278   Therefore they've been merged into mulint() and mullong().
3279 */
3280
3281   for (bwd = 0; bwd < 3; bwd++)
3282     {
3283       for (su = 0; su < 2; su++)
3284         {
3285           for (muldivmod = 1; muldivmod < 3; muldivmod++)
3286             {
3287               /* div and mod */
3288               SNPRINTF (buffer, sizeof(buffer),
3289                         "_%s%s%s",
3290                        smuldivmod[muldivmod],
3291                        ssu[su],
3292                        sbwd[bwd]);
3293               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3294               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3295             }
3296         }
3297     }
3298   /* mul only */
3299   muldivmod = 0;
3300   /* byte */
3301   bwd = 0;
3302   for (su = 0; su < 2; su++)
3303     {
3304       /* muluchar and mulschar are still separate functions, because e.g. the z80
3305          port is sign/zero-extending to int before calling mulint() */
3306       SNPRINTF (buffer, sizeof(buffer),
3307                 "_%s%s%s",
3308                 smuldivmod[muldivmod],
3309                 ssu[su],
3310                 sbwd[bwd]);
3311       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3312       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3313     }
3314   /* signed only */
3315   su = 0;
3316   /* word and doubleword */
3317   for (bwd = 1; bwd < 3; bwd++)
3318     {
3319       /* mul, int/long */
3320       SNPRINTF (buffer, sizeof(buffer),
3321                 "_%s%s",
3322                 smuldivmod[muldivmod],
3323                 sbwd[bwd]);
3324       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3325       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3326       /* signed = unsigned */
3327       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3328     }
3329
3330   for (rlrr = 0; rlrr < 2; rlrr++)
3331     {
3332       for (bwd = 0; bwd < 3; bwd++)
3333         {
3334           for (su = 0; su < 2; su++)
3335             {
3336               SNPRINTF (buffer, sizeof(buffer),
3337                         "_%s%s%s",
3338                        srlrr[rlrr],
3339                        ssu[su],
3340                        sbwd[bwd]);
3341               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3342               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3343             }
3344         }
3345     }
3346 }
3347
3348 /*-----------------------------------------------------------------*/
3349 /* initBuiltIns - create prototypes for builtin functions          */
3350 /*-----------------------------------------------------------------*/
3351 void initBuiltIns()
3352 {
3353     int i;
3354     symbol *sym;
3355
3356     if (!port->builtintable) return ;
3357
3358     for (i = 0 ; port->builtintable[i].name ; i++) {
3359         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3360                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3361         FUNC_ISBUILTIN(sym->type) = 1;
3362         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3363     }
3364 }
3365
3366 sym_link *validateLink(sym_link         *l, 
3367                         const char      *macro,
3368                         const char      *args,
3369                         const char      select,
3370                         const char      *file, 
3371                         unsigned        line)
3372 {    
3373   if (l && l->class==select)
3374     {
3375         return l;
3376     }
3377     fprintf(stderr, 
3378             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3379             " expected %s, got %s\n",
3380             macro, args, file, line, 
3381             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3382     exit(-1);
3383     return l; // never reached, makes compiler happy.
3384 }
3385
3386 /*--------------------------------------------------------------------*/
3387 /* newEnumType - create an integer type compatible with enumerations  */
3388 /*--------------------------------------------------------------------*/
3389 sym_link *
3390 newEnumType (symbol *enumlist)
3391 {
3392   int min, max, v;
3393   symbol *sym;
3394   sym_link *type;
3395
3396   if (!enumlist)
3397     {
3398       type = newLink (SPECIFIER);
3399       SPEC_NOUN (type) = V_INT;
3400       return type;
3401     }
3402       
3403   /* Determine the range of the enumerated values */
3404   sym = enumlist;
3405   min = max = (int) floatFromVal (valFromType (sym->type));
3406   for (sym = sym->next; sym; sym = sym->next)
3407     {
3408       v = (int) floatFromVal (valFromType (sym->type));
3409       if (v<min)
3410         min = v;
3411       if (v>max)
3412         max = v;
3413     }
3414
3415   /* Determine the smallest integer type that is compatible with this range */
3416   type = newLink (SPECIFIER);
3417   if (min>=0 && max<=255)
3418     {
3419       SPEC_NOUN (type) = V_CHAR;
3420       SPEC_USIGN (type) = 1;
3421     }
3422   else if (min>=-128 && max<=127)
3423     {
3424       SPEC_NOUN (type) = V_CHAR;
3425     }
3426   else if (min>=0 && max<=65535)
3427     {
3428       SPEC_NOUN (type) = V_INT;
3429       SPEC_USIGN (type) = 1;
3430     }
3431   else if (min>=-32768 && max<=32767)
3432     {
3433       SPEC_NOUN (type) = V_INT;
3434     }
3435   else
3436     {
3437       SPEC_NOUN (type) = V_INT;
3438       SPEC_LONG (type) = 1;
3439       if (min>=0)
3440         SPEC_USIGN (type) = 1;
3441     }
3442   
3443   return type;    
3444 }