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