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