* src/SDCCast.c (addCast): fixed bug #908454 by promoting bits to char
[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 specifier  */
803   switch (DCL_TYPE (p))
804     {
805     case ARRAY:
806       if (DCL_ELEM(p)) {
807         return DCL_ELEM (p) * getSize (p->next);
808       } else {
809           //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
810           //    "can not tell the size of an array[]");
811         return 0;
812       }
813     case IPOINTER:
814     case PPOINTER:
815     case POINTER:
816       return (PTRSIZE);
817     case EEPPOINTER:
818     case FPOINTER:
819     case CPOINTER:
820     case FUNCTION:
821       return (FPTRSIZE);
822     case GPOINTER:
823       return (GPTRSIZE);
824
825     default:
826       return 0;
827     }
828 }
829
830 /*------------------------------------------------------------------*/
831 /* bitsForType - returns # of bits required to store this type      */
832 /*------------------------------------------------------------------*/
833 unsigned int 
834 bitsForType (sym_link * p)
835 {
836   /* if nothing return 0 */
837   if (!p)
838     return 0;
839
840   if (IS_SPEC (p))
841     {                           /* if this is the specifier then */
842
843       switch (SPEC_NOUN (p))
844         {                       /* depending on the specifier type */
845         case V_INT:
846           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
847         case V_FLOAT:
848           return FLOATSIZE * 8;
849         case V_CHAR:
850           return CHARSIZE * 8;
851         case V_VOID:
852           return 0;
853         case V_STRUCT:
854           return SPEC_STRUCT (p)->size * 8;
855         case V_LABEL:
856           return 0;
857         case V_SBIT:
858         case V_BIT:
859           return 1;
860         case V_BITFIELD:
861           return SPEC_BLEN (p);
862         default:
863           return 0;
864         }
865     }
866
867   /* this is a specifier  */
868   switch (DCL_TYPE (p))
869     {
870     case ARRAY:
871       return DCL_ELEM (p) * getSize (p->next) * 8;
872     case IPOINTER:
873     case PPOINTER:
874     case POINTER:
875       return (PTRSIZE * 8);
876     case EEPPOINTER:
877     case FPOINTER:
878     case CPOINTER:
879     case FUNCTION:
880       return (FPTRSIZE * 8);
881     case GPOINTER:
882       return (GPTRSIZE * 8);
883
884     default:
885       return 0;
886     }
887 }
888
889 /*------------------------------------------------------------------*/
890 /* copySymbolChain - copies a symbol chain                          */
891 /*------------------------------------------------------------------*/
892 symbol *
893 copySymbolChain (symbol * src)
894 {
895   symbol *dest;
896
897   if (!src)
898     return NULL;
899
900   dest = copySymbol (src);
901   dest->next = copySymbolChain (src->next);
902   return dest;
903 }
904
905 /*------------------------------------------------------------------*/
906 /* copySymbol - makes a copy of a symbol                            */
907 /*------------------------------------------------------------------*/
908 symbol *
909 copySymbol (symbol * src)
910 {
911   symbol *dest;
912
913   if (!src)
914     return NULL;
915
916   dest = newSymbol (src->name, src->level);
917   memcpy (dest, src, sizeof (symbol));
918   dest->level = src->level;
919   dest->block = src->block;
920   dest->ival = copyIlist (src->ival);
921   dest->type = copyLinkChain (src->type);
922   dest->etype = getSpec (dest->type);
923   dest->next = NULL;
924   dest->key = src->key;
925   dest->allocreq = src->allocreq;
926   return dest;
927 }
928
929 /*------------------------------------------------------------------*/
930 /* reverseSyms - reverses the links for a symbol chain      */
931 /*------------------------------------------------------------------*/
932 symbol *
933 reverseSyms (symbol * sym)
934 {
935   symbol *prev, *curr, *next;
936
937   if (!sym)
938     return NULL;
939
940   prev = sym;
941   curr = sym->next;
942
943   while (curr)
944     {
945       next = curr->next;
946       curr->next = prev;
947       prev = curr;
948       curr = next;
949     }
950   sym->next = (void *) NULL;
951   return prev;
952 }
953
954 /*------------------------------------------------------------------*/
955 /* reverseLink - reverses the links for a type chain        */
956 /*------------------------------------------------------------------*/
957 sym_link *
958 reverseLink (sym_link * type)
959 {
960   sym_link *prev, *curr, *next;
961
962   if (!type)
963     return NULL;
964
965   prev = type;
966   curr = type->next;
967
968   while (curr)
969     {
970       next = curr->next;
971       curr->next = prev;
972       prev = curr;
973       curr = next;
974     }
975   type->next = (void *) NULL;
976   return prev;
977 }
978
979 /*------------------------------------------------------------------*/
980 /* addSymChain - adds a symbol chain to the symboltable             */
981 /*------------------------------------------------------------------*/
982 void 
983 addSymChain (symbol * symHead)
984 {
985   symbol *sym = symHead;
986   symbol *csym = NULL;
987   int error = 0;
988
989   for (; sym != NULL; sym = sym->next)
990     {
991       changePointer(sym);
992       checkTypeSanity(sym->etype, sym->name);
993
994       if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype)))
995         checkDecl (sym, 0);
996       
997       /* if already exists in the symbol table then check if
998          one of them is an extern definition if yes then
999          then check if the type match, if the types match then
1000          delete the current entry and add the new entry      */
1001       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
1002           csym->level == sym->level) {
1003
1004         /* If the previous definition was for an array with incomplete */
1005         /* type, and the new definition has completed the type, update */
1006         /* the original type to match */
1007         if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
1008             && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
1009           {
1010             if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
1011               DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
1012           }
1013
1014         #if 0
1015         /* If only one of the definitions used the "at" keyword, copy */
1016         /* the address to the other. */
1017         if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
1018             && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
1019           {
1020             SPEC_ABSA (sym->etype) = 1;
1021             SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1022           }
1023         if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
1024             && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
1025           {
1026             SPEC_ABSA (csym->etype) = 1;
1027             SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1028           }
1029         #endif
1030   
1031         error = 0;        
1032         if (csym->ival && sym->ival)
1033           error = 1;
1034         if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1035           error = 1;
1036         
1037         if (error) {
1038           /* one definition extern ? */
1039           if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1040             werror (E_EXTERN_MISMATCH, sym->name);
1041           else
1042             werror (E_DUPLICATE, sym->name);
1043           werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1044           #if 0
1045           fprintf (stderr, "from type '");
1046           printTypeChain (csym->type, stderr);
1047           if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1048             fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1049           fprintf (stderr, "'\nto type '");
1050           printTypeChain (sym->type, stderr);
1051           if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1052             fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1053           fprintf (stderr, "'\n");
1054           #endif
1055           continue;
1056         }
1057
1058         if (csym->ival && !sym->ival)
1059           sym->ival = csym->ival;
1060
1061         /* delete current entry */
1062         deleteSym (SymbolTab, csym, csym->name);
1063         deleteFromSeg(csym);
1064       }
1065       
1066       /* add new entry */
1067       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1068     }
1069 }
1070
1071
1072 /*------------------------------------------------------------------*/
1073 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1074 /*------------------------------------------------------------------*/
1075 int 
1076 funcInChain (sym_link * lnk)
1077 {
1078   while (lnk)
1079     {
1080       if (IS_FUNC (lnk))
1081         return 1;
1082       lnk = lnk->next;
1083     }
1084   return 0;
1085 }
1086
1087 /*------------------------------------------------------------------*/
1088 /* structElemType - returns the type info of a struct member        */
1089 /*------------------------------------------------------------------*/
1090 sym_link *
1091 structElemType (sym_link * stype, value * id)
1092 {
1093   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1094   sym_link *type, *etype;
1095   sym_link *petype = getSpec (stype);
1096
1097   if (fields && id) {
1098     
1099     /* look for the id */
1100     while (fields)
1101       {
1102         if (strcmp (fields->rname, id->name) == 0)
1103           {
1104             type = copyLinkChain (fields->type);
1105             etype = getSpec (type);
1106             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1107                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
1108             if (IS_SPEC (type))
1109               SPEC_CONST (type) |= SPEC_CONST (stype);
1110             else
1111               DCL_PTR_CONST (type) |= SPEC_CONST (stype);
1112             return type;
1113           }
1114         fields = fields->next;
1115       }
1116   }
1117
1118   werror (E_NOT_MEMBER, id->name);
1119     
1120   // the show must go on
1121   return newIntLink();
1122 }
1123
1124 /*------------------------------------------------------------------*/
1125 /* getStructElement - returns element of a tructure definition      */
1126 /*------------------------------------------------------------------*/
1127 symbol *
1128 getStructElement (structdef * sdef, symbol * sym)
1129 {
1130   symbol *field;
1131
1132   for (field = sdef->fields; field; field = field->next)
1133     if (strcmp (field->name, sym->name) == 0)
1134       return field;
1135
1136   werror (E_NOT_MEMBER, sym->name);
1137
1138   return sdef->fields;
1139 }
1140
1141 /*------------------------------------------------------------------*/
1142 /* compStructSize - computes the size of a structure                */
1143 /*------------------------------------------------------------------*/
1144 int 
1145 compStructSize (int su, structdef * sdef)
1146 {
1147     int sum = 0, usum = 0;
1148     int bitOffset = 0;
1149     symbol *loop;
1150
1151     /* for the identifiers  */
1152     loop = sdef->fields;
1153     while (loop) {
1154
1155         /* create the internal name for this variable */
1156         SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1157         if (su == UNION) {
1158             sum = 0;
1159             bitOffset = 0;
1160         }
1161         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1162
1163         /* if this is a bit field  */
1164         if (loop->bitVar) {
1165
1166             /* change it to a unsigned bit */
1167             SPEC_NOUN (loop->etype) = V_BITFIELD;
1168             SPEC_USIGN (loop->etype) = 1;
1169             SPEC_BLEN (loop->etype) = loop->bitVar;
1170
1171             if (loop->bitVar == BITVAR_PAD) {
1172                 /* A zero length bitfield forces padding */
1173                 SPEC_BSTR (loop->etype) = bitOffset;
1174                 SPEC_BLEN (loop->etype) = 0;
1175                 bitOffset = 8;
1176                 loop->offset = sum;
1177             }
1178             else {
1179                 if (bitOffset == 8) {
1180                     bitOffset = 0;
1181                     sum++;
1182                 }
1183                 /* check if this fit into the remaining   */
1184                 /* bits of this byte else align it to the */
1185                 /* next byte boundary                     */
1186                 if (loop->bitVar <= (8 - bitOffset)) {
1187                     /* fits into current byte */
1188                     loop->offset = sum;
1189                     SPEC_BSTR (loop->etype) = bitOffset;
1190                     bitOffset += loop->bitVar;
1191                 }
1192                 else if (!bitOffset) {
1193                     /* does not fit, but is already byte aligned */
1194                     loop->offset = sum;
1195                     SPEC_BSTR (loop->etype) = bitOffset;
1196                     bitOffset += loop->bitVar;
1197                 } 
1198                 else {
1199                     /* does not fit; need to realign first */
1200                     sum++;
1201                     loop->offset = (su == UNION ? sum = 0 : sum);
1202                     bitOffset = 0;
1203                     SPEC_BSTR (loop->etype) = bitOffset;
1204                     bitOffset += loop->bitVar;
1205                 }
1206                 while (bitOffset>8) {
1207                     bitOffset -= 8;
1208                     sum++;
1209                 } 
1210             }
1211         }
1212         else {
1213             /* This is a non-bit field. Make sure we are */
1214             /* byte aligned first */
1215             if (bitOffset) {
1216                 sum++;
1217                 loop->offset = (su == UNION ? sum = 0 : sum);
1218                 bitOffset = 0;
1219             }
1220             loop->offset = sum;
1221             checkDecl (loop, 1);
1222             sum += getSize (loop->type);
1223         }
1224
1225         loop = loop->next;
1226
1227         /* if union then size = sizeof larget field */
1228         if (su == UNION) {
1229             /* For UNION, round up after each field */
1230             sum += ((bitOffset+7)/8);
1231             usum = max (usum, sum);
1232         }
1233
1234     }
1235     
1236     /* For STRUCT, round up after all fields processed */
1237     if (su != UNION)
1238         sum += ((bitOffset+7)/8);
1239
1240     return (su == UNION ? usum : sum);
1241 }
1242
1243 /*-------------------------------------------------------------------*/
1244 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1245 /*                      an enclosing struct/union                    */
1246 /*-------------------------------------------------------------------*/
1247 void
1248 promoteAnonStructs (int su, structdef * sdef)
1249 {
1250   symbol *field;
1251   symbol *subfield;
1252   symbol **tofield;
1253   symbol *nextfield;
1254   symbol *dupfield;
1255   int base;
1256
1257   tofield = &sdef->fields;
1258   field = sdef->fields;
1259   while (field)
1260     {
1261       nextfield = field->next;
1262       if (!*field->name && IS_STRUCT (field->type))
1263         {
1264           /* Found an anonymous struct/union. Replace it */
1265           /* with the fields it contains and adjust all  */
1266           /* the offsets */
1267           
1268           base = field->offset;
1269           subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1270           if (!subfield)
1271             continue;           /* just in case it's empty */
1272           
1273           *tofield = subfield;
1274           for (;;)
1275             {
1276               /* check for field name conflicts resulting from promotion */
1277               dupfield = sdef->fields;
1278               while (dupfield && dupfield != subfield)
1279                 {
1280                   if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1281                     {
1282                       werrorfl (subfield->fileDef, subfield->lineDef,
1283                                 E_DUPLICATE_MEMBER,
1284                                 su==STRUCT ? "struct" : "union",
1285                                 subfield->name);
1286                       werrorfl (dupfield->fileDef, dupfield->lineDef,
1287                                 E_PREVIOUS_DEF);
1288                     }
1289                   dupfield = dupfield->next;
1290                 }
1291               
1292               subfield->offset += base;
1293               if (subfield->next)
1294                 subfield = subfield->next;
1295               else
1296                 break;
1297             }
1298           subfield->next = nextfield;
1299           tofield = &subfield->next;
1300         }
1301       else
1302         tofield = &field->next;
1303       field = nextfield;
1304     }
1305 }
1306
1307
1308 /*------------------------------------------------------------------*/
1309 /* checkSClass - check the storage class specification              */
1310 /*------------------------------------------------------------------*/
1311 static void 
1312 checkSClass (symbol * sym, int isProto)
1313 {
1314   sym_link *t;
1315   
1316   if (getenv("DEBUG_SANITY")) {
1317     fprintf (stderr, "checkSClass: %s \n", sym->name);
1318   }
1319   
1320   /* type is literal can happen for enums change
1321      to auto */
1322   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1323     SPEC_SCLS (sym->etype) = S_AUTO;
1324   
1325   /* if sfr or sbit then must also be volatile */
1326   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1327       SPEC_SCLS (sym->etype) == S_SFR)
1328     {
1329       SPEC_VOLATILE (sym->etype) = 1;
1330     }
1331   
1332   /* if absolute address given then it mark it as
1333      volatile -- except in the PIC port */
1334
1335 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1336   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1337   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1338 #endif
1339
1340     if (IS_ABSOLUTE (sym->etype))
1341       SPEC_VOLATILE (sym->etype) = 1;
1342   
1343   /* If code memory is read only, then pointers to code memory */
1344   /* implicitly point to constants -- make this explicit       */
1345   t = sym->type;
1346   while (t && t->next) {
1347     if (IS_CODEPTR(t) && port->mem.code_ro) {
1348       if (IS_SPEC(t->next)) {
1349         SPEC_CONST (t->next) = 1;
1350       } else {
1351         DCL_PTR_CONST (t->next) = 1;
1352       }
1353     }
1354     t = t->next;
1355   }
1356
1357   /* global variables declared const put into code */
1358   /* if no other storage class specified */
1359   if (sym->level == 0 &&
1360       SPEC_SCLS(sym->etype) == S_FIXED &&
1361       !IS_FUNC(sym->type)) {
1362     /* find the first non-array link */
1363     t = sym->type;
1364     while (IS_ARRAY(t))
1365       t = t->next;
1366     if (IS_CONSTANT (t)) {
1367       SPEC_SCLS (sym->etype) = S_CODE;
1368     }
1369   }
1370
1371   /* global variable in code space is a constant */
1372   if (sym->level == 0 &&
1373       SPEC_SCLS (sym->etype) == S_CODE &&
1374       port->mem.code_ro) {
1375     /* find the first non-array link */
1376     t = sym->type;
1377     while (IS_ARRAY(t))
1378       t = t->next;
1379     if (IS_SPEC(t)) {
1380       SPEC_CONST (t) = 1;
1381     } else {
1382       DCL_PTR_CONST (t) = 1;
1383     }
1384   }
1385
1386   /* if bit variable then no storage class can be */
1387   /* specified since bit is already a storage */
1388   if (IS_BITVAR (sym->etype) &&
1389       (SPEC_SCLS (sym->etype) != S_FIXED &&
1390        SPEC_SCLS (sym->etype) != S_SBIT &&
1391        SPEC_SCLS (sym->etype) != S_BIT)
1392     )
1393     {
1394       werror (E_BITVAR_STORAGE, sym->name);
1395       SPEC_SCLS (sym->etype) = S_FIXED;
1396     }
1397
1398   /* extern variables cannot be initialized */
1399   if (IS_EXTERN (sym->etype) && sym->ival)
1400     {
1401       werror (E_EXTERN_INIT, sym->name);
1402       sym->ival = NULL;
1403     }
1404
1405   /* if this is an automatic symbol */
1406   if (sym->level && (options.stackAuto || reentrant)) {
1407     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1408          SPEC_SCLS (sym->etype) == S_FIXED ||
1409          SPEC_SCLS (sym->etype) == S_REGISTER ||
1410          SPEC_SCLS (sym->etype) == S_STACK ||
1411          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1412       SPEC_SCLS (sym->etype) = S_AUTO;
1413     } else {
1414       /* storage class may only be specified for statics */
1415       if (!IS_STATIC(sym->etype)) {
1416         werror (E_AUTO_ASSUMED, sym->name);
1417       }
1418     }
1419   }
1420
1421   /* automatic symbols cannot be given   */
1422   /* an absolute address ignore it      */
1423   if (sym->level &&
1424       SPEC_ABSA (sym->etype) &&
1425       (options.stackAuto || reentrant))
1426     {
1427       werror (E_AUTO_ABSA, sym->name);
1428       SPEC_ABSA (sym->etype) = 0;
1429     }
1430
1431   /* arrays & pointers cannot be defined for bits   */
1432   /* SBITS or SFRs or BIT                           */
1433   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1434       (SPEC_NOUN (sym->etype) == V_BIT ||
1435        SPEC_NOUN (sym->etype) == V_SBIT ||
1436        SPEC_NOUN (sym->etype) == V_BITFIELD ||
1437        SPEC_SCLS (sym->etype) == S_SFR))
1438     werror (E_BIT_ARRAY, sym->name);
1439
1440   /* if this is a bit|sbit then set length & start  */
1441   if (SPEC_NOUN (sym->etype) == V_BIT ||
1442       SPEC_NOUN (sym->etype) == V_SBIT)
1443     {
1444       SPEC_BLEN (sym->etype) = 1;
1445       SPEC_BSTR (sym->etype) = 0;
1446     }
1447
1448   if (!isProto) {
1449     /* variables declared in CODE space must have */
1450     /* initializers if not an extern */
1451     if (SPEC_SCLS (sym->etype) == S_CODE &&
1452         sym->ival == NULL &&
1453         //!sym->level &&
1454         port->mem.code_ro &&
1455         !IS_EXTERN (sym->etype) &&
1456         !funcInChain (sym->type))
1457       werror (E_CODE_NO_INIT, sym->name);
1458   }
1459
1460   /* if parameter or local variable then change */
1461   /* the storage class to reflect where the var will go */
1462   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1463       !IS_STATIC(sym->etype))
1464     {
1465       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1466         {
1467           SPEC_SCLS (sym->etype) = (options.useXstack ?
1468                                     S_XSTACK : S_STACK);
1469         }
1470       else
1471         {
1472           /* hack-o-matic! I see no reason why the useXstack option should ever
1473            * control this allcoation, but the code was originally that way, and
1474            * changing it for non-390 ports breaks the compiler badly.
1475            */
1476           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1477                 1 : options.useXstack;
1478           SPEC_SCLS (sym->etype) = (useXdata ?
1479                                     S_XDATA : S_FIXED);
1480         }
1481     }
1482 }
1483
1484 /*------------------------------------------------------------------*/
1485 /* changePointer - change pointer to functions                      */
1486 /*------------------------------------------------------------------*/
1487 void 
1488 changePointer (symbol * sym)
1489 {
1490   sym_link *p;
1491
1492   /* go thru the chain of declarations   */
1493   /* if we find a pointer to a function  */
1494   /* unconditionally change it to a ptr  */
1495   /* to code area                        */
1496   for (p = sym->type; p; p = p->next)
1497     {
1498       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1499         DCL_TYPE (p) = port->unqualified_pointer;
1500       if (IS_PTR (p) && IS_FUNC (p->next))
1501         DCL_TYPE (p) = CPOINTER;
1502     }
1503 }
1504
1505 /*------------------------------------------------------------------*/
1506 /* checkDecl - does semantic validation of a declaration                   */
1507 /*------------------------------------------------------------------*/
1508 int 
1509 checkDecl (symbol * sym, int isProto)
1510 {
1511
1512   checkSClass (sym, isProto);           /* check the storage class      */
1513   changePointer (sym);          /* change pointers if required */
1514
1515   /* if this is an array without any dimension
1516      then update the dimension from the initial value */
1517   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1518     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1519
1520   return 0;
1521 }
1522
1523 /*------------------------------------------------------------------*/
1524 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1525 /*------------------------------------------------------------------*/
1526 sym_link *
1527 copyLinkChain (sym_link * p)
1528 {
1529   sym_link *head, *curr, *loop;
1530
1531   curr = p;
1532   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1533   while (curr)
1534     {
1535       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1536       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1537       loop = loop->next;
1538       curr = curr->next;
1539     }
1540
1541   return head;
1542 }
1543
1544
1545 /*------------------------------------------------------------------*/
1546 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1547 /*                symbols in the given block                        */
1548 /*------------------------------------------------------------------*/
1549 void 
1550 cleanUpBlock (bucket ** table, int block)
1551 {
1552   int i;
1553   bucket *chain;
1554
1555   /* go thru the entire  table  */
1556   for (i = 0; i < 256; i++)
1557     {
1558       for (chain = table[i]; chain; chain = chain->next)
1559         {
1560           if (chain->block >= block)
1561             {
1562               deleteSym (table, chain->sym, chain->name);
1563             }
1564         }
1565     }
1566 }
1567
1568 /*------------------------------------------------------------------*/
1569 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1570 /*                symbols in the given level                        */
1571 /*------------------------------------------------------------------*/
1572 void 
1573 cleanUpLevel (bucket ** table, int level)
1574 {
1575   int i;
1576   bucket *chain;
1577
1578   /* go thru the entire  table  */
1579   for (i = 0; i < 256; i++)
1580     {
1581       for (chain = table[i]; chain; chain = chain->next)
1582         {
1583           if (chain->level >= level)
1584             {
1585               deleteSym (table, chain->sym, chain->name);
1586             }
1587         }
1588     }
1589 }
1590
1591 /*------------------------------------------------------------------*/
1592 /* computeTypeOr - computes the resultant type from two types       */
1593 /*------------------------------------------------------------------*/
1594 static sym_link *
1595 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1596 {
1597   /* sanity check */
1598   assert (   (IS_CHAR (etype1) || IS_BIT (etype1))
1599           && (IS_CHAR (etype2) || IS_BIT (etype2)));
1600
1601   if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1602     {
1603       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1604       return reType;
1605     }
1606   
1607   if (SPEC_USIGN (etype1))
1608     {
1609       if (   IS_LITERAL (etype2)
1610           && floatFromVal (valFromType (etype2)) >= 0)
1611         SPEC_USIGN (reType) = 1;
1612       else
1613         {
1614           /* promote to int */
1615           SPEC_USIGN (reType) = 0;
1616           SPEC_NOUN (reType) = V_INT;
1617         }
1618     }
1619   else /* etype1 signed */
1620     {
1621       if (   IS_LITERAL (etype2)
1622           && floatFromVal (valFromType (etype2)) <= 127)
1623         SPEC_USIGN (reType) = 0;
1624       else
1625         {
1626           /* promote to int */
1627           SPEC_USIGN (reType) = 0;
1628           SPEC_NOUN (reType) = V_INT;
1629         }
1630     }
1631
1632   if (SPEC_USIGN (etype2))
1633     {
1634       if (   IS_LITERAL (etype1)
1635           && floatFromVal (valFromType (etype1)) >= 0)
1636         SPEC_USIGN (reType) = 1;
1637       else
1638         {
1639           /* promote to int */
1640           SPEC_USIGN (reType) = 0;
1641           SPEC_NOUN (reType) = V_INT;
1642         }
1643     }
1644   else /* etype2 signed */
1645     {
1646       if (   IS_LITERAL (etype1)
1647           && floatFromVal (valFromType (etype1)) <= 127)
1648         SPEC_USIGN (reType) = 0;
1649       else
1650         {
1651           /* promote to int */
1652           SPEC_USIGN (reType) = 0;
1653           SPEC_NOUN (reType) = V_INT;
1654         }
1655     }
1656   return reType;
1657 }
1658
1659 /*------------------------------------------------------------------*/
1660 /* computeType - computes the resultant type from two types         */
1661 /*------------------------------------------------------------------*/
1662 sym_link *
1663 computeType (sym_link * type1, sym_link * type2,
1664              RESULT_TYPE resultType, char op)
1665 {
1666   sym_link *rType;
1667   sym_link *reType;
1668   sym_link *etype1 = getSpec (type1);
1669   sym_link *etype2;
1670
1671   etype2 = type2 ? getSpec (type2) : type1;
1672
1673   /* if one of them is a float then result is a float */
1674   /* here we assume that the types passed are okay */
1675   /* and can be cast to one another                */
1676   /* which ever is greater in size */
1677   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1678     rType = newFloatLink ();
1679   else
1680     /* if both are bitvars choose the larger one */
1681   if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1682     {
1683       rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1684                 copyLinkChain (type1) : copyLinkChain (type1);
1685     }
1686     /* if only one of them is a bit variable
1687        then the other one prevails */
1688   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1689     {
1690       rType = copyLinkChain (type2);
1691       /* bitfield can have up to 16 bits */
1692       if (getSize (etype1) > 1)
1693         SPEC_NOUN (getSpec (rType)) = V_INT;
1694     }
1695   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1696     {
1697       rType = copyLinkChain (type1);
1698       /* bitfield can have up to 16 bits */
1699       if (getSize (etype2) > 1)
1700         SPEC_NOUN (getSpec (rType)) = V_INT;
1701     }
1702   else
1703     /* if one of them is a pointer or array then that
1704        prevails */
1705   if (IS_PTR (type1) || IS_ARRAY (type1))
1706     rType = copyLinkChain (type1);
1707   else if (IS_PTR (type2) || IS_ARRAY (type2))
1708     rType = copyLinkChain (type2);
1709   else if (getSize (type1) > getSize (type2))
1710     rType = copyLinkChain (type1);
1711   else
1712     rType = copyLinkChain (type2);
1713
1714   reType = getSpec (rType);
1715
1716   /* avoid conflicting types */
1717   reType->select.s._signed = 0;
1718
1719   /* if result is a literal then make not so */
1720   if (IS_LITERAL (reType))
1721     SPEC_SCLS (reType) = S_REGISTER;
1722
1723   switch (resultType)
1724     {
1725       case RESULT_TYPE_CHAR:
1726         if (IS_BITVAR (reType))
1727           {
1728             SPEC_NOUN (reType) = V_CHAR;
1729             SPEC_SCLS (reType) = 0;
1730             SPEC_USIGN (reType) = 0;
1731             return rType;
1732           }
1733         break;
1734       case RESULT_TYPE_INT:
1735       case RESULT_TYPE_NONE:
1736         if (IS_BIT (reType))
1737           {
1738             SPEC_NOUN (reType) = V_CHAR;
1739             SPEC_SCLS (reType) = 0;
1740             SPEC_USIGN (reType) = 0;
1741             return rType;
1742           }
1743         else if (IS_BITFIELD (reType))
1744           {
1745             /* could be smarter, but it depends on the op */
1746             /* this is for the worst case: a multiplication of 4 * 4 bit */
1747             SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1748             SPEC_SCLS (reType) = 0;
1749             SPEC_USIGN (reType) = 0;
1750             return rType;
1751           }
1752         else if (IS_CHAR (reType))
1753           {
1754             if (op == '|' || op == '^')
1755               return computeTypeOr (etype1, etype2, reType);
1756             else if (   op == '&'
1757                      && SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1758               {
1759                 SPEC_USIGN (reType) = 1;
1760                 return rType;
1761               }
1762             else
1763               {
1764                 SPEC_NOUN (reType) = V_INT;
1765                 SPEC_USIGN (reType) = 0;
1766                 return rType;
1767               }
1768           }
1769         break;
1770       default:
1771         break;
1772     }
1773
1774   /* SDCC's sign promotion:
1775      - if one or both operands are unsigned, the resultant type will be unsigned
1776        (except char, see below)
1777      - if an operand is promoted to a larger type (char -> int, int -> long),
1778        the larger type will be signed
1779
1780      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1781      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1782      the standard. The standard demands, that the result has to be the same
1783      "as if" the promotion would have been performed:
1784
1785      - if the result of an operation with two char's is promoted to a
1786        larger type, the result will be signed.
1787
1788      More sophisticated are these:
1789      - if the result of an operation with two char's is a char again,
1790        the result will only then be unsigned, if both operands are
1791        unsigned. In all other cases the result will be signed.
1792
1793        This seems to be contradictionary to the first two rules, but it makes
1794        real sense (all types are char's):
1795
1796         A signed char can be negative; this must be preserved in the result
1797                 -1 * 100 = -100;
1798
1799         Only if both operands are unsigned it's safe to make the result
1800         unsigned; this helps to avoid overflow:
1801                 2 * 100 =  200;
1802
1803      - ToDo: document '|', '^' and '&'
1804      
1805      Homework: - why is (200 * 200 < 0) true?
1806                - why is { char l = 200, r = 200; (r * l > 0) } true?
1807   */
1808
1809   if (!IS_FLOAT (reType)
1810       && (   (SPEC_USIGN (etype1)
1811               /* if this operand is promoted to a larger type,
1812                  then it will be promoted to a signed type */
1813               && !(getSize (etype1) < getSize (reType))
1814               /* char require special handling */
1815               && !IS_CHAR (etype1))
1816           || /* same for 2nd operand */  
1817              (SPEC_USIGN (etype2)
1818               && !(getSize (etype2) < getSize (reType))
1819               && !IS_CHAR (etype2))
1820           || /* if both are 'unsigned char' and not promoted
1821                 let the result be unsigned too */
1822              (   SPEC_USIGN (etype1)
1823               && SPEC_USIGN (etype2)
1824               && IS_CHAR (etype1)
1825               && IS_CHAR (etype2)
1826               && IS_CHAR (reType))))
1827     SPEC_USIGN (reType) = 1;
1828   else
1829     SPEC_USIGN (reType) = 0;
1830
1831   return rType;
1832 }
1833
1834 /*--------------------------------------------------------------------*/
1835 /* compareType - will do type check return 1 if match, -1 if castable */
1836 /*--------------------------------------------------------------------*/
1837 int
1838 compareType (sym_link * dest, sym_link * src)
1839 {
1840   if (!dest && !src)
1841     return 1;
1842
1843   if (dest && !src)
1844     return 0;
1845
1846   if (src && !dest)
1847     return 0;
1848
1849   /* if dest is a declarator then */
1850   if (IS_DECL (dest))
1851     {
1852       if (IS_DECL (src))
1853         {
1854           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1855             if (IS_FUNC(src)) {
1856               //checkFunction(src,dest);
1857             }
1858             return compareType (dest->next, src->next);
1859           }
1860           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1861             return 1;
1862           }
1863           if (IS_PTR (src) && IS_GENPTR (dest))
1864             return -1;
1865           if (IS_PTR (dest) && IS_ARRAY (src)) {
1866             value *val=aggregateToPointer (valFromType(src));
1867             int res=compareType (dest, val->type);
1868             Safe_free(val->type);
1869             Safe_free(val);
1870             return res;
1871           }
1872           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1873             return compareType (dest->next, src);
1874           return 0;
1875         }
1876       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1877         return -1;
1878       else
1879         return 0;
1880     }
1881
1882   /* if one is a specifier and the other is not */
1883   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1884       (IS_SPEC (dest) && !IS_SPEC (src)))
1885     return 0;
1886
1887   /* if one of them is a void then ok */
1888   if (SPEC_NOUN (dest) == V_VOID &&
1889       SPEC_NOUN (src) != V_VOID)
1890     return -1;
1891
1892   if (SPEC_NOUN (dest) != V_VOID &&
1893       SPEC_NOUN (src) == V_VOID)
1894     return -1;
1895
1896   /* if they are both bitfields then if the lengths
1897      and starts don't match */
1898   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1899       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1900        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1901     return -1;
1902
1903   /* it is a specifier */
1904   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1905     {
1906       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1907           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1908           /* I would prefer
1909           bitsForType (dest) == bitsForType (src))
1910              instead of the next two lines, but the regression tests fail with
1911              them; I guess it's a problem with replaceCheaperOp  */
1912           getSize (dest) == getSize (src) &&
1913           !(!IS_BIT (dest) && IS_BIT (src)))
1914         return 1;
1915       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1916         return -1;
1917       else
1918         return 0;
1919     }
1920   else if (IS_STRUCT (dest))
1921     {
1922       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1923         return 0;
1924       else
1925         return 1;
1926     }
1927   if (SPEC_LONG (dest) != SPEC_LONG (src))
1928     return -1;
1929
1930   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1931     return -1;
1932
1933   return 1;
1934 }
1935
1936 /*--------------------------------------------------------------------*/
1937 /* compareTypeExact - will do type check return 1 if match exactly    */
1938 /*--------------------------------------------------------------------*/
1939 int
1940 compareTypeExact (sym_link * dest, sym_link * src, int level)
1941 {
1942   STORAGE_CLASS srcScls, destScls;
1943   
1944   if (!dest && !src)
1945     return 1;
1946
1947   if (dest && !src)
1948     return 0;
1949
1950   if (src && !dest)
1951     return 0;
1952
1953   /* if dest is a declarator then */
1954   if (IS_DECL (dest))
1955     {
1956       if (IS_DECL (src))
1957         {
1958           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1959             if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
1960               return 0;
1961             if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
1962               return 0;
1963             if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
1964               return 0;
1965             if (IS_FUNC(src))
1966               {
1967                 value *exargs, *acargs, *checkValue;
1968
1969                 /* verify function return type */
1970                 if (!compareTypeExact (dest->next, src->next, -1))
1971                   return 0;
1972                 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
1973                   return 0;
1974                 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
1975                   return 0;
1976                 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
1977                   return 0;
1978                 #if 0
1979                 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
1980                   return 0;
1981                 #endif
1982
1983                 /* compare expected args with actual args */
1984                 exargs = FUNC_ARGS(dest);
1985                 acargs = FUNC_ARGS(src);
1986
1987                 /* for all the expected args do */
1988                 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
1989                   {
1990                     //checkTypeSanity(acargs->etype, acargs->name);
1991
1992                     if (IS_AGGREGATE (acargs->type))
1993                       {
1994                         checkValue = copyValue (acargs);
1995                         aggregateToPointer (checkValue);
1996                       }
1997                     else
1998                       checkValue = acargs;
1999
2000                     #if 0
2001                     if (!compareTypeExact (exargs->type, checkValue->type, -1))
2002                       return 0;
2003                     #endif
2004                   }
2005
2006                   /* if one them ended we have a problem */
2007                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2008                       (!exargs && acargs && !IS_VOID (acargs->type)))
2009                     return 0;                  
2010                   return 1;
2011               }
2012             return compareTypeExact (dest->next, src->next, level);
2013           }
2014           return 0;
2015         }
2016       return 0;
2017     }
2018
2019   /* if one is a specifier and the other is not */
2020   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2021       (IS_SPEC (dest) && !IS_SPEC (src)))
2022     return 0;
2023
2024   /* if one of them is a void then ok */
2025   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2026     return 0;
2027
2028   /* if they are both bitfields then if the lengths
2029      and starts don't match */
2030   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2031       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2032        SPEC_BSTR (dest) != SPEC_BSTR (src)))
2033     return 0;
2034
2035   if (IS_INTEGRAL (dest))
2036     {
2037       /* signedness must match */
2038       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2039         return 0;
2040       /* size must match */
2041       if (SPEC_LONG (dest) != SPEC_LONG (src))
2042         return 0;
2043       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2044         return 0;
2045     }
2046   
2047   if (IS_STRUCT (dest))
2048     {
2049       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2050         return 0;
2051     }
2052
2053   if (SPEC_CONST (dest) != SPEC_CONST (src))
2054     return 0;
2055   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2056     return 0;
2057   if (SPEC_STAT (dest) != SPEC_STAT (src))
2058     return 0;
2059   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2060     return 0;
2061   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2062     return 0;
2063       
2064   destScls = SPEC_SCLS (dest);
2065   srcScls = SPEC_SCLS (src);
2066   
2067   /* Compensate for const to const code change in checkSClass() */
2068   if (!level & port->mem.code_ro && SPEC_CONST (dest))
2069     {
2070       if (srcScls == S_CODE && destScls == S_FIXED)
2071         destScls = S_CODE;
2072       if (destScls == S_CODE && srcScls == S_FIXED)
2073         srcScls = S_CODE;
2074     }
2075
2076   /* compensate for allocGlobal() */  
2077   if ((srcScls == S_FIXED || srcScls == S_AUTO)
2078       && port->mem.default_globl_map == xdata
2079       && !level)
2080     srcScls = S_XDATA;
2081   
2082   if (level>0 && !SPEC_STAT (dest))
2083     {
2084       /* Compensate for hack-o-matic in checkSClass() */
2085       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2086         {
2087           if (destScls == S_FIXED)
2088             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2089           if (srcScls == S_FIXED)
2090             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2091         }
2092       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2093         {
2094           if (destScls == S_FIXED)
2095             destScls = S_XDATA;
2096           if (srcScls == S_FIXED)
2097             srcScls = S_XDATA;
2098         }
2099     }
2100
2101   if (srcScls != destScls)
2102     {
2103       #if 0
2104       printf ("level = %d\n", level);
2105       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2106                 SPEC_SCLS (src), SPEC_SCLS (dest));
2107       printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2108       #endif
2109       return 0;
2110     }
2111   
2112   return 1;
2113 }
2114
2115 /*------------------------------------------------------------------*/
2116 /* inCalleeSaveList - return 1 if found in callee save list          */
2117 /*------------------------------------------------------------------*/
2118 static int
2119 calleeCmp(void *p1, void *p2)
2120 {
2121   return (strcmp((char *)p1, (char *)(p2)) == 0);
2122 }
2123
2124 bool
2125 inCalleeSaveList(char *s)
2126 {
2127   if (options.all_callee_saves)
2128     return 1;
2129   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2130 }
2131
2132 /*-----------------------------------------------------------------*/
2133 /* aggregateToPointer:  change an agggregate type function      */
2134 /*         argument to a pointer to that type.     */
2135 /*-----------------------------------------------------------------*/
2136 value *
2137 aggregateToPointer (value * val)
2138 {
2139   if (IS_AGGREGATE (val->type))
2140     {
2141       /* if this is a structure */
2142       /* then we need to add a new link */
2143       if (IS_STRUCT (val->type))
2144         {
2145           /* first lets add DECLARATOR type */
2146           sym_link *p = val->type;
2147
2148           werror (W_STRUCT_AS_ARG, val->name);
2149           val->type = newLink (DECLARATOR);
2150           val->type->next = p;
2151         }
2152
2153       /* change to a pointer depending on the */
2154       /* storage class specified        */
2155       switch (SPEC_SCLS (val->etype))
2156         {
2157         case S_IDATA:
2158           DCL_TYPE (val->type) = IPOINTER;
2159           break;
2160         case S_PDATA:
2161           DCL_TYPE (val->type) = PPOINTER;
2162           break;
2163         case S_FIXED:
2164           if (SPEC_OCLS(val->etype)) {
2165             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2166           } else {
2167             // this happens for (external) function parameters
2168             DCL_TYPE (val->type) = port->unqualified_pointer;
2169           }
2170           break;
2171         case S_AUTO:
2172         case S_DATA:
2173         case S_REGISTER:
2174           DCL_TYPE (val->type) = POINTER;
2175           break;
2176         case S_CODE:
2177           DCL_TYPE (val->type) = CPOINTER;
2178           break;
2179         case S_XDATA:
2180           DCL_TYPE (val->type) = FPOINTER;
2181           break;
2182         case S_EEPROM:
2183           DCL_TYPE (val->type) = EEPPOINTER;
2184           break;
2185         default:
2186           DCL_TYPE (val->type) = port->unqualified_pointer;
2187         }
2188       
2189       /* is there is a symbol associated then */
2190       /* change the type of the symbol as well */
2191       if (val->sym)
2192         {
2193           val->sym->type = copyLinkChain (val->type);
2194           val->sym->etype = getSpec (val->sym->type);
2195         }
2196     }
2197   return val;
2198 }
2199 /*------------------------------------------------------------------*/
2200 /* checkFunction - does all kinds of check on a function            */
2201 /*------------------------------------------------------------------*/
2202 int 
2203 checkFunction (symbol * sym, symbol *csym)
2204 {
2205   value *exargs, *acargs;
2206   value *checkValue;
2207   int argCnt = 0;
2208
2209   if (getenv("DEBUG_SANITY")) {
2210     fprintf (stderr, "checkFunction: %s ", sym->name);
2211   }
2212
2213   if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2214     {
2215       werror(E_SYNTAX_ERROR, sym->name);
2216       return 0;
2217     }
2218     
2219   /* make sure the type is complete and sane */
2220   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2221
2222   /* if not type then some kind of error */
2223   if (!sym->type)
2224     return 0;
2225
2226   /* if the function has no type then make it return int */
2227   if (!sym->type->next)
2228     sym->type->next = sym->etype = newIntLink ();
2229
2230   /* function cannot return aggregate */
2231   if (IS_AGGREGATE (sym->type->next))
2232     {
2233       werror (E_FUNC_AGGR, sym->name);
2234       return 0;
2235     }
2236
2237   /* function cannot return bit */
2238   if (IS_BITVAR (sym->type->next))
2239     {
2240       werror (E_FUNC_BIT, sym->name);
2241       return 0;
2242     }
2243
2244   /* check if this function is defined as calleeSaves
2245      then mark it as such */
2246   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2247
2248   /* if interrupt service routine  */
2249   /* then it cannot have arguments */
2250   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2251     {
2252       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2253         werror (E_INT_ARGS, sym->name);
2254         FUNC_ARGS(sym->type)=NULL;
2255       }
2256     }
2257
2258   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
2259        acargs; 
2260        acargs=acargs->next, argCnt++) {
2261     if (!acargs->sym) { 
2262       // this can happen for reentrant functions
2263       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2264       // the show must go on: synthesize a name and symbol
2265       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2266       acargs->sym = newSymbol (acargs->name, 1);
2267       SPEC_OCLS (acargs->etype) = istack;
2268       acargs->sym->type = copyLinkChain (acargs->type);
2269       acargs->sym->etype = getSpec (acargs->sym->type);
2270       acargs->sym->_isparm = 1;
2271       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2272     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
2273       // synthesized name
2274       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2275     }
2276   }
2277   argCnt--;
2278
2279   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2280     return 1;                   /* not defined nothing more to check  */
2281
2282   /* check if body already present */
2283   if (csym && IFFUNC_HASBODY(csym->type))
2284     {
2285       werror (E_FUNC_BODY, sym->name);
2286       return 0;
2287     }
2288
2289   /* check the return value type   */
2290   if (compareType (csym->type, sym->type) <= 0)
2291     {
2292       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2293       printFromToType(csym->type, sym->type);
2294       return 0;
2295     }
2296
2297   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2298     {
2299       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2300     }
2301
2302   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
2303     {
2304       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2305     }
2306
2307   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2308     {
2309       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2310     }
2311   
2312   /* Really, reentrant should match regardless of argCnt, but     */
2313   /* this breaks some existing code (the fp lib functions). If    */
2314   /* the first argument is always passed the same way, this       */
2315   /* lax checking is ok (but may not be true for in future ports) */
2316   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2317       && argCnt>1)
2318     {
2319       //printf("argCnt = %d\n",argCnt);
2320       werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2321     }
2322
2323   /* compare expected args with actual args */
2324   exargs = FUNC_ARGS(csym->type);
2325   acargs = FUNC_ARGS(sym->type);
2326
2327   /* for all the expected args do */
2328   for (argCnt = 1;
2329        exargs && acargs;
2330        exargs = exargs->next, acargs = acargs->next, argCnt++)
2331     {
2332       if (getenv("DEBUG_SANITY")) {
2333         fprintf (stderr, "checkFunction: %s ", exargs->name);
2334       }
2335       /* make sure the type is complete and sane */
2336       checkTypeSanity(exargs->etype, exargs->name);
2337
2338       /* If the actual argument is an array, any prototype
2339        * will have modified it to a pointer. Duplicate that
2340        * change here.
2341        */
2342       if (IS_AGGREGATE (acargs->type))
2343         {
2344           checkValue = copyValue (acargs);
2345           aggregateToPointer (checkValue);
2346         }
2347       else
2348         {
2349           checkValue = acargs;
2350         }
2351
2352       if (compareType (exargs->type, checkValue->type) <= 0)
2353         {
2354           werror (E_ARG_TYPE, argCnt);
2355           printFromToType(exargs->type, checkValue->type);
2356           return 0;
2357         }
2358     }
2359
2360   /* if one them ended we have a problem */
2361   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2362       (!exargs && acargs && !IS_VOID (acargs->type)))
2363     werror (E_ARG_COUNT);
2364
2365   /* replace with this defition */
2366   sym->cdef = csym->cdef;
2367   deleteSym (SymbolTab, csym, csym->name);
2368   deleteFromSeg(csym);
2369   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2370   if (IS_EXTERN (csym->etype) && !
2371       IS_EXTERN (sym->etype))
2372     {
2373       addSet (&publics, sym);
2374     }
2375   return 1;
2376 }
2377
2378 /*------------------------------------------------------------------*/
2379 /* cdbStructBlock - calls struct printing for a blcks               */
2380 /*------------------------------------------------------------------*/
2381 void cdbStructBlock (int block)
2382 {
2383   int i;
2384   bucket **table = StructTab;
2385   bucket *chain;
2386
2387   /* go thru the entire  table  */
2388   for (i = 0; i < 256; i++)
2389     {
2390       for (chain = table[i]; chain; chain = chain->next)
2391         {
2392           if (chain->block >= block)
2393             {
2394               if(debugFile)
2395                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2396             }
2397         }
2398     }
2399 }
2400
2401 /*-----------------------------------------------------------------*/
2402 /* processFuncArgs - does some processing with function args       */
2403 /*-----------------------------------------------------------------*/
2404 void 
2405 processFuncArgs (symbol * func)
2406 {
2407   value *val;
2408   int pNum = 1;
2409   sym_link *funcType=func->type;
2410
2411   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2412     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2413
2414   /* find the function declaration within the type */
2415   while (funcType && !IS_FUNC(funcType))
2416     funcType=funcType->next;
2417
2418   /* if this function has variable argument list */
2419   /* then make the function a reentrant one    */
2420   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2421     FUNC_ISREENT(funcType)=1;
2422
2423   /* check if this function is defined as calleeSaves
2424      then mark it as such */
2425   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2426
2427   /* loop thru all the arguments   */
2428   val = FUNC_ARGS(funcType);
2429
2430   /* if it is void then remove parameters */
2431   if (val && IS_VOID (val->type))
2432     {
2433       FUNC_ARGS(funcType) = NULL;
2434       return;
2435     }
2436
2437   /* reset regparm for the port */
2438   (*port->reset_regparms) ();
2439   /* if any of the arguments is an aggregate */
2440   /* change it to pointer to the same type */
2441   while (val)
2442     {
2443         int argreg = 0;
2444       /* mark it as a register parameter if
2445          the function does not have VA_ARG
2446          and as port dictates */
2447       if (!IFFUNC_HASVARARGS(funcType) &&
2448           (argreg = (*port->reg_parm) (val->type)))
2449         {
2450           SPEC_REGPARM (val->etype) = 1;
2451           SPEC_ARGREG(val->etype) = argreg;
2452         } else if (IFFUNC_ISREENT(funcType)) {
2453             FUNC_HASSTACKPARM(funcType) = 1;
2454         }
2455
2456       if (IS_AGGREGATE (val->type))
2457         {
2458           aggregateToPointer (val);
2459         }
2460
2461       val = val->next;
2462       pNum++;
2463     }
2464
2465   /* if this is an internal generated function call */
2466   if (func->cdef) {
2467     /* ignore --stack-auto for this one, we don't know how it is compiled */
2468     /* simply trust on --int-long-reent or --float-reent */
2469     if (IFFUNC_ISREENT(funcType)) {
2470       return;
2471     }
2472   } else {
2473     /* if this function is reentrant or */
2474     /* automatics r 2b stacked then nothing */
2475     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2476       return;
2477   }
2478
2479   val = FUNC_ARGS(funcType);
2480   pNum = 1;
2481   while (val)
2482     {
2483
2484       /* if a symbolname is not given  */
2485       /* synthesize a variable name */
2486       if (!val->sym)
2487         {
2488           SNPRINTF (val->name, sizeof(val->name), 
2489                     "_%s_PARM_%d", func->name, pNum++);
2490           val->sym = newSymbol (val->name, 1);
2491           SPEC_OCLS (val->etype) = port->mem.default_local_map;
2492           val->sym->type = copyLinkChain (val->type);
2493           val->sym->etype = getSpec (val->sym->type);
2494           val->sym->_isparm = 1;
2495           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2496           #if 0
2497           /* ?? static functions shouldn't imply static parameters - EEP */
2498           if (IS_SPEC(func->etype)) {
2499             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2500               SPEC_STAT (func->etype);
2501           }
2502           #endif
2503           addSymChain (val->sym);
2504
2505         }
2506       else                      /* symbol name given create synth name */
2507         {
2508
2509           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2510           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2511           val->sym->_isparm = 1;
2512           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2513             (options.model != MODEL_SMALL ? xdata : data);
2514           
2515           #if 0
2516           /* ?? static functions shouldn't imply static parameters - EEP */
2517           if (IS_SPEC(func->etype)) {
2518             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2519               SPEC_STAT (func->etype);
2520           }
2521           #endif
2522         }
2523       if (!isinSet(operKeyReset, val->sym)) {
2524         addSet (&operKeyReset, val->sym);
2525         applyToSet (operKeyReset, resetParmKey);
2526       }
2527       val = val->next;
2528     }
2529 }
2530
2531 /*-----------------------------------------------------------------*/
2532 /* isSymbolEqual - compares two symbols return 1 if they match     */
2533 /*-----------------------------------------------------------------*/
2534 int 
2535 isSymbolEqual (symbol * dest, symbol * src)
2536 {
2537   /* if pointers match then equal */
2538   if (dest == src)
2539     return 1;
2540
2541   /* if one of them is null then don't match */
2542   if (!dest || !src)
2543     return 0;
2544
2545   /* if both of them have rname match on rname */
2546   if (dest->rname[0] && src->rname[0])
2547     return (!strcmp (dest->rname, src->rname));
2548
2549   /* otherwise match on name */
2550   return (!strcmp (dest->name, src->name));
2551 }
2552
2553 void PT(sym_link *type)
2554 {
2555         printTypeChain(type,0);
2556 }
2557 /*-----------------------------------------------------------------*/
2558 /* printTypeChain - prints the type chain in human readable form   */
2559 /*-----------------------------------------------------------------*/
2560 void
2561 printTypeChain (sym_link * start, FILE * of)
2562 {
2563   int nlr = 0;
2564   value *args;
2565   sym_link * type, * search;
2566   STORAGE_CLASS scls;
2567
2568   if (!of)
2569     {
2570       of = stdout;
2571       nlr = 1;
2572     }
2573
2574   if (start==NULL) {
2575     fprintf (of, "void");
2576     return;
2577   }
2578
2579   /* Print the chain as it is written in the source: */
2580   /* start with the last entry.                      */
2581   /* However, the storage class at the end of the    */
2582   /* chain reall applies to the first in the chain!  */
2583
2584   for (type = start; type && type->next; type = type->next)
2585     ;
2586   if (IS_SPEC (type))
2587     scls=SPEC_SCLS(type);
2588   else
2589     scls=0;
2590   while (type)
2591     {
2592       if (type==start) {
2593         switch (scls) 
2594           {
2595           case S_DATA: fprintf (of, "data-"); break;
2596           case S_XDATA: fprintf (of, "xdata-"); break;
2597           case S_SFR: fprintf (of, "sfr-"); break;
2598           case S_SBIT: fprintf (of, "sbit-"); break;
2599           case S_CODE: fprintf (of, "code-"); break;
2600           case S_IDATA: fprintf (of, "idata-"); break;
2601           case S_PDATA: fprintf (of, "pdata-"); break;
2602           case S_LITERAL: fprintf (of, "literal-"); break;
2603           case S_STACK: fprintf (of, "stack-"); break;
2604           case S_XSTACK: fprintf (of, "xstack-"); break;
2605           case S_BIT: fprintf (of, "bit-"); break;
2606           case S_EEPROM: fprintf (of, "eeprom-"); break;
2607           default: break;
2608           }
2609       }
2610
2611       if (IS_DECL (type))
2612         {
2613           if (!IS_FUNC(type)) {
2614             if (DCL_PTR_VOLATILE (type)) {
2615               fprintf (of, "volatile-");
2616             }
2617             if (DCL_PTR_CONST (type)) {
2618               fprintf (of, "const-");
2619             }
2620           }
2621           switch (DCL_TYPE (type))
2622             {
2623             case FUNCTION:
2624               fprintf (of, "function %s %s", 
2625                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2626                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2627               fprintf (of, "( ");
2628               for (args = FUNC_ARGS(type); 
2629                    args; 
2630                    args=args->next) {
2631                 printTypeChain(args->type, of);
2632                 if (args->next)
2633                   fprintf(of, ", ");
2634               }
2635               fprintf (of, ") ");
2636               break;
2637             case GPOINTER:
2638               fprintf (of, "generic* ");
2639               break;
2640             case CPOINTER:
2641               fprintf (of, "code* ");
2642               break;
2643             case FPOINTER:
2644               fprintf (of, "xdata* ");
2645               break;
2646             case EEPPOINTER:
2647               fprintf (of, "eeprom* ");
2648               break;
2649             case POINTER:
2650               fprintf (of, "near* ");
2651               break;
2652             case IPOINTER:
2653               fprintf (of, "idata* ");
2654               break;
2655             case PPOINTER:
2656               fprintf (of, "pdata* ");
2657               break;
2658             case UPOINTER:
2659               fprintf (of, "unknown* ");
2660               break;
2661             case ARRAY:
2662               if (DCL_ELEM(type)) {
2663                 fprintf (of, "[%d] ", DCL_ELEM(type));
2664               } else {
2665                 fprintf (of, "[] ");
2666               }
2667               break;
2668             }
2669         }
2670       else
2671         {
2672           if (SPEC_VOLATILE (type))
2673             fprintf (of, "volatile-");
2674           if (SPEC_CONST (type))
2675             fprintf (of, "const-");
2676           if (SPEC_USIGN (type))
2677             fprintf (of, "unsigned-");
2678           switch (SPEC_NOUN (type))
2679             {
2680             case V_INT:
2681               if (IS_LONG (type))
2682                 fprintf (of, "long-");
2683               fprintf (of, "int");
2684               break;
2685
2686             case V_CHAR:
2687               fprintf (of, "char");
2688               break;
2689
2690             case V_VOID:
2691               fprintf (of, "void");
2692               break;
2693
2694             case V_FLOAT:
2695               fprintf (of, "float");
2696               break;
2697
2698             case V_STRUCT:
2699               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2700               break;
2701
2702             case V_SBIT:
2703               fprintf (of, "sbit");
2704               break;
2705
2706             case V_BIT:
2707               fprintf (of, "bit");
2708               break;
2709
2710             case V_BITFIELD:
2711               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2712               break;
2713
2714             case V_DOUBLE:
2715               fprintf (of, "double");
2716               break;
2717
2718             default:
2719               fprintf (of, "unknown type");
2720               break;
2721             }
2722         }
2723       /* search entry in list before "type" */
2724       for (search = start; search && search->next != type;)
2725         search = search->next;
2726       type = search;
2727       if (type)
2728         fputc (' ', of);
2729     }
2730   if (nlr)
2731     fprintf (of, "\n");
2732 }
2733
2734 /*--------------------------------------------------------------------*/
2735 /* printTypeChainRaw - prints the type chain in human readable form   */
2736 /*                     in the raw data structure ordering             */
2737 /*--------------------------------------------------------------------*/
2738 void
2739 printTypeChainRaw (sym_link * start, FILE * of)
2740 {
2741   int nlr = 0;
2742   value *args;
2743   sym_link * type;
2744
2745   if (!of)
2746     {
2747       of = stdout;
2748       nlr = 1;
2749     }
2750
2751   if (start==NULL) {
2752     fprintf (of, "void");
2753     return;
2754   }
2755
2756   type = start;
2757   
2758   while (type)
2759     {
2760       if (IS_DECL (type))
2761         {
2762           if (!IS_FUNC(type)) {
2763             if (DCL_PTR_VOLATILE (type)) {
2764               fprintf (of, "volatile-");
2765             }
2766             if (DCL_PTR_CONST (type)) {
2767               fprintf (of, "const-");
2768             }
2769           }
2770           switch (DCL_TYPE (type))
2771             {
2772             case FUNCTION:
2773               fprintf (of, "function %s %s", 
2774                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2775                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2776               fprintf (of, "( ");
2777               for (args = FUNC_ARGS(type); 
2778                    args; 
2779                    args=args->next) {
2780                 printTypeChain(args->type, of);
2781                 if (args->next)
2782                   fprintf(of, ", ");
2783               }
2784               fprintf (of, ") ");
2785               break;
2786             case GPOINTER:
2787               fprintf (of, "generic* ");
2788               break;
2789             case CPOINTER:
2790               fprintf (of, "code* ");
2791               break;
2792             case FPOINTER:
2793               fprintf (of, "xdata* ");
2794               break;
2795             case EEPPOINTER:
2796               fprintf (of, "eeprom* ");
2797               break;
2798             case POINTER:
2799               fprintf (of, "near* ");
2800               break;
2801             case IPOINTER:
2802               fprintf (of, "idata* ");
2803               break;
2804             case PPOINTER:
2805               fprintf (of, "pdata* ");
2806               break;
2807             case UPOINTER:
2808               fprintf (of, "unknown* ");
2809               break;
2810             case ARRAY:
2811               if (DCL_ELEM(type)) {
2812                 fprintf (of, "[%d] ", DCL_ELEM(type));
2813               } else {
2814                 fprintf (of, "[] ");
2815               }
2816               break;
2817             }
2818           if (DCL_TSPEC(type))
2819             {
2820               fprintf (of, "{");
2821               printTypeChainRaw(DCL_TSPEC(type), of);
2822               fprintf (of, "}");
2823             }
2824         }
2825       else if (IS_SPEC (type))
2826         {
2827         switch (SPEC_SCLS (type)) 
2828           {
2829           case S_DATA: fprintf (of, "data-"); break;
2830           case S_XDATA: fprintf (of, "xdata-"); break;
2831           case S_SFR: fprintf (of, "sfr-"); break;
2832           case S_SBIT: fprintf (of, "sbit-"); break;
2833           case S_CODE: fprintf (of, "code-"); break;
2834           case S_IDATA: fprintf (of, "idata-"); break;
2835           case S_PDATA: fprintf (of, "pdata-"); break;
2836           case S_LITERAL: fprintf (of, "literal-"); break;
2837           case S_STACK: fprintf (of, "stack-"); break;
2838           case S_XSTACK: fprintf (of, "xstack-"); break;
2839           case S_BIT: fprintf (of, "bit-"); break;
2840           case S_EEPROM: fprintf (of, "eeprom-"); break;
2841           default: break;
2842           }
2843           if (SPEC_VOLATILE (type))
2844             fprintf (of, "volatile-");
2845           if (SPEC_CONST (type))
2846             fprintf (of, "const-");
2847           if (SPEC_USIGN (type))
2848             fprintf (of, "unsigned-");
2849           switch (SPEC_NOUN (type))
2850             {
2851             case V_INT:
2852               if (IS_LONG (type))
2853                 fprintf (of, "long-");
2854               fprintf (of, "int");
2855               break;
2856
2857             case V_CHAR:
2858               fprintf (of, "char");
2859               break;
2860
2861             case V_VOID:
2862               fprintf (of, "void");
2863               break;
2864
2865             case V_FLOAT:
2866               fprintf (of, "float");
2867               break;
2868
2869             case V_STRUCT:
2870               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2871               break;
2872
2873             case V_SBIT:
2874               fprintf (of, "sbit");
2875               break;
2876
2877             case V_BIT:
2878               fprintf (of, "bit");
2879               break;
2880
2881             case V_BITFIELD:
2882               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2883               break;
2884
2885             case V_DOUBLE:
2886               fprintf (of, "double");
2887               break;
2888
2889             default:
2890               fprintf (of, "unknown type");
2891               break;
2892             }
2893         }
2894       else
2895         fprintf (of, "NOT_SPEC_OR_DECL");
2896       type = type->next;
2897       if (type)
2898         fputc (' ', of);
2899     }
2900   if (nlr)
2901     fprintf (of, "\n");
2902 }
2903
2904
2905 /*-----------------------------------------------------------------*/
2906 /* powof2 - returns power of two for the number if number is pow 2 */
2907 /*-----------------------------------------------------------------*/
2908 int
2909 powof2 (TYPE_UDWORD num)
2910 {
2911   int nshifts = 0;
2912   int n1s = 0;
2913
2914   while (num)
2915     {
2916       if (num & 1)
2917         n1s++;
2918       num >>= 1;
2919       nshifts++;
2920     }
2921
2922   if (n1s > 1 || nshifts == 0)
2923     return 0;
2924   return nshifts - 1;
2925 }
2926
2927 symbol *__fsadd;
2928 symbol *__fssub;
2929 symbol *__fsmul;
2930 symbol *__fsdiv;
2931 symbol *__fseq;
2932 symbol *__fsneq;
2933 symbol *__fslt;
2934 symbol *__fslteq;
2935 symbol *__fsgt;
2936 symbol *__fsgteq;
2937
2938 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2939 symbol *__muldiv[3][3][2];
2940 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2941 sym_link *__multypes[3][2];
2942 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2943 symbol *__conv[2][3][2];
2944 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2945 symbol *__rlrr[2][3][2];
2946
2947 sym_link *floatType;
2948
2949 static char *
2950 _mangleFunctionName(char *in)
2951 {
2952   if (port->getMangledFunctionName)
2953     {
2954       return port->getMangledFunctionName(in);
2955     }
2956   else
2957     {
2958       return in;
2959     }
2960 }
2961
2962 /*-----------------------------------------------------------------*/
2963 /* typeFromStr - create a typechain from an encoded string         */
2964 /* basic types -        'c' - char                                 */
2965 /*                      's' - short                                */
2966 /*                      'i' - int                                  */
2967 /*                      'l' - long                                 */
2968 /*                      'f' - float                                */
2969 /*                      'v' - void                                 */
2970 /*                      '*' - pointer - default (GPOINTER)         */
2971 /* modifiers -          'u' - unsigned                             */
2972 /* pointer modifiers -  'g' - generic                              */
2973 /*                      'x' - xdata                                */
2974 /*                      'p' - code                                 */
2975 /*                      'd' - data                                 */                     
2976 /*                      'F' - function                             */                     
2977 /* examples : "ig*" - generic int *                                */
2978 /*            "cx*" - char xdata *                                 */
2979 /*            "ui" -  unsigned int                                 */
2980 /*-----------------------------------------------------------------*/
2981 sym_link *typeFromStr (char *s)
2982 {
2983     sym_link *r = newLink(DECLARATOR);
2984     int usign = 0;
2985
2986     do {
2987         sym_link *nr;
2988         switch (*s) {
2989         case 'u' : 
2990             usign = 1;
2991             s++;
2992             continue ;
2993             break ;
2994         case 'c':
2995             r->class = SPECIFIER;
2996             SPEC_NOUN(r) = V_CHAR;
2997             break;
2998         case 's':
2999         case 'i':
3000             r->class = SPECIFIER;
3001             SPEC_NOUN(r) = V_INT;
3002             break;
3003         case 'l':
3004             r->class = SPECIFIER;
3005             SPEC_NOUN(r) = V_INT;
3006             SPEC_LONG(r) = 1;
3007             break;
3008         case 'f':
3009             r->class = SPECIFIER;
3010             SPEC_NOUN(r) = V_FLOAT;
3011             break;
3012         case 'v':
3013             r->class = SPECIFIER;
3014             SPEC_NOUN(r) = V_VOID;
3015             break;
3016         case '*':
3017             DCL_TYPE(r) = port->unqualified_pointer;
3018             break;
3019         case 'g':
3020         case 'x':
3021         case 'p':
3022         case 'd':
3023         case 'F':
3024             assert(*(s+1)=='*');
3025             nr = newLink(DECLARATOR);
3026             nr->next = r;
3027             r = nr;
3028             switch (*s) {
3029             case 'g':
3030                 DCL_TYPE(r) = GPOINTER;
3031                 break;
3032             case 'x':
3033                 DCL_TYPE(r) = FPOINTER;
3034                 break;
3035             case 'p':
3036                 DCL_TYPE(r) = CPOINTER;
3037                 break;
3038             case 'd':
3039                 DCL_TYPE(r) = POINTER;
3040                 break;
3041             case 'F':
3042                 DCL_TYPE(r) = FUNCTION;
3043                 nr = newLink(DECLARATOR);
3044                 nr->next = r;
3045                 r = nr;
3046                 DCL_TYPE(r) = CPOINTER;
3047                 break;
3048             }
3049             s++;
3050             break;
3051         default:
3052             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
3053                    "typeFromStr: unknown type");
3054             break;
3055         }
3056         if (IS_SPEC(r) && usign) {
3057             SPEC_USIGN(r) = 1;
3058             usign = 0;
3059         }
3060         s++;
3061     } while (*s);
3062     return r;
3063 }
3064
3065 /*-----------------------------------------------------------------*/
3066 /* initCSupport - create functions for C support routines          */
3067 /*-----------------------------------------------------------------*/
3068 void 
3069 initCSupport ()
3070 {
3071   const char *smuldivmod[] =
3072   {
3073     "mul", "div", "mod"
3074   };
3075   const char *sbwd[] =
3076   {
3077     "char", "int", "long"
3078   };
3079   const char *ssu[] =
3080   {
3081     "s", "u"
3082   };
3083   const char *srlrr[] =
3084   {
3085     "rl", "rr"
3086   };
3087
3088   int bwd, su, muldivmod, tofrom, rlrr;
3089
3090   if (getenv("SDCC_NO_C_SUPPORT")) {
3091     /* for debugging only */
3092     return;
3093   }
3094
3095   floatType = newFloatLink ();
3096
3097   for (bwd = 0; bwd < 3; bwd++)
3098     {
3099       sym_link *l = NULL;
3100       switch (bwd)
3101         {
3102         case 0:
3103           l = newCharLink ();
3104           break;
3105         case 1:
3106           l = newIntLink ();
3107           break;
3108         case 2:
3109           l = newLongLink ();
3110           break;
3111         default:
3112           assert (0);
3113         }
3114       __multypes[bwd][0] = l;
3115       __multypes[bwd][1] = copyLinkChain (l);
3116       SPEC_USIGN (__multypes[bwd][1]) = 1;
3117     }
3118
3119   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3120   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3121   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3122   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3123   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3124   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3125   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3126   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3127   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3128   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3129
3130   for (tofrom = 0; tofrom < 2; tofrom++)
3131     {
3132       for (bwd = 0; bwd < 3; bwd++)
3133         {
3134           for (su = 0; su < 2; su++)
3135             {
3136               if (tofrom)
3137                 {
3138                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3139                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3140                 }
3141               else
3142                 {
3143                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3144                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3145                 }
3146             }
3147         }
3148     }
3149
3150 /*
3151   for (muldivmod = 0; muldivmod < 3; muldivmod++)
3152     {
3153       for (bwd = 0; bwd < 3; bwd++)
3154         {
3155           for (su = 0; su < 2; su++)
3156             {
3157               SNPRINTF (buffer, sizeof(buffer),
3158                         "_%s%s%s",
3159                        smuldivmod[muldivmod],
3160                        ssu[su],
3161                        sbwd[bwd]);
3162               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3163               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3164             }
3165         }
3166     }
3167
3168   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3169   Therefore they've been merged into mulint() and mullong().
3170 */
3171
3172   for (bwd = 0; bwd < 3; bwd++)
3173     {
3174       for (su = 0; su < 2; su++)
3175         {
3176           for (muldivmod = 1; muldivmod < 3; muldivmod++)
3177             {
3178               /* div and mod */
3179               SNPRINTF (buffer, sizeof(buffer),
3180                         "_%s%s%s",
3181                        smuldivmod[muldivmod],
3182                        ssu[su],
3183                        sbwd[bwd]);
3184               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3185               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3186             }
3187         }
3188     }
3189   /* mul only */
3190   muldivmod = 0;
3191   /* byte */
3192   bwd = 0;
3193   for (su = 0; su < 2; su++)
3194     {
3195       /* muluchar and mulschar are still separate functions, because e.g. the z80
3196          port is sign/zero-extending to int before calling mulint() */
3197       SNPRINTF (buffer, sizeof(buffer),
3198                 "_%s%s%s",
3199                 smuldivmod[muldivmod],
3200                 ssu[su],
3201                 sbwd[bwd]);
3202       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3203       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3204     }
3205   /* signed only */
3206   su = 0;
3207   /* word and doubleword */
3208   for (bwd = 1; bwd < 3; bwd++)
3209     {
3210       /* mul, int/long */
3211       SNPRINTF (buffer, sizeof(buffer),
3212                 "_%s%s",
3213                 smuldivmod[muldivmod],
3214                 sbwd[bwd]);
3215       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3216       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3217       /* signed = unsigned */
3218       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3219     }
3220
3221   for (rlrr = 0; rlrr < 2; rlrr++)
3222     {
3223       for (bwd = 0; bwd < 3; bwd++)
3224         {
3225           for (su = 0; su < 2; su++)
3226             {
3227               SNPRINTF (buffer, sizeof(buffer),
3228                         "_%s%s%s",
3229                        srlrr[rlrr],
3230                        ssu[su],
3231                        sbwd[bwd]);
3232               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3233               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3234             }
3235         }
3236     }
3237 }
3238
3239 /*-----------------------------------------------------------------*/
3240 /* initBuiltIns - create prototypes for builtin functions          */
3241 /*-----------------------------------------------------------------*/
3242 void initBuiltIns()
3243 {
3244     int i;
3245     symbol *sym;
3246
3247     if (!port->builtintable) return ;
3248
3249     for (i = 0 ; port->builtintable[i].name ; i++) {
3250         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3251                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
3252         FUNC_ISBUILTIN(sym->type) = 1;
3253         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
3254     }
3255 }
3256
3257 sym_link *validateLink(sym_link         *l, 
3258                         const char      *macro,
3259                         const char      *args,
3260                         const char      select,
3261                         const char      *file, 
3262                         unsigned        line)
3263 {    
3264   if (l && l->class==select)
3265     {
3266         return l;
3267     }
3268     fprintf(stderr, 
3269             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3270             " expected %s, got %s\n",
3271             macro, args, file, line, 
3272             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3273     exit(-1);
3274     return l; // never reached, makes compiler happy.
3275 }
3276
3277 /*--------------------------------------------------------------------*/
3278 /* newEnumType - create an integer type compatible with enumerations  */
3279 /*--------------------------------------------------------------------*/
3280 sym_link *
3281 newEnumType (symbol *enumlist)
3282 {
3283   int min, max, v;
3284   symbol *sym;
3285   sym_link *type;
3286
3287   if (!enumlist)
3288     {
3289       type = newLink (SPECIFIER);
3290       SPEC_NOUN (type) = V_INT;
3291       return type;
3292     }
3293       
3294   /* Determine the range of the enumerated values */
3295   sym = enumlist;
3296   min = max = (int) floatFromVal (valFromType (sym->type));
3297   for (sym = sym->next; sym; sym = sym->next)
3298     {
3299       v = (int) floatFromVal (valFromType (sym->type));
3300       if (v<min)
3301         min = v;
3302       if (v>max)
3303         max = v;
3304     }
3305
3306   /* Determine the smallest integer type that is compatible with this range */
3307   type = newLink (SPECIFIER);
3308   if (min>=0 && max<=255)
3309     {
3310       SPEC_NOUN (type) = V_CHAR;
3311       SPEC_USIGN (type) = 1;
3312     }
3313   else if (min>=-128 && max<=127)
3314     {
3315       SPEC_NOUN (type) = V_CHAR;
3316     }
3317   else if (min>=0 && max<=65535)
3318     {
3319       SPEC_NOUN (type) = V_INT;
3320       SPEC_USIGN (type) = 1;
3321     }
3322   else if (min>=-32768 && max<=32767)
3323     {
3324       SPEC_NOUN (type) = V_INT;
3325     }
3326   else
3327     {
3328       SPEC_NOUN (type) = V_INT;
3329       SPEC_LONG (type) = 1;
3330       if (min>=0)
3331         SPEC_USIGN (type) = 1;
3332     }
3333   
3334   return type;    
3335 }