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