e563fa28fd932185f811048a84d935fa4acbc703
[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 value *aggregateToPointer (value *val);
28 void printTypeChainRaw (sym_link * start, FILE * of);
29
30 void printFromToType(sym_link *from, sym_link *to) {
31   fprintf (stderr, "from type '");
32   printTypeChain (from, stderr);
33   fprintf (stderr, "'\nto type '");
34   printTypeChain (to, stderr);
35   fprintf (stderr, "'\n");
36 }
37
38 /* noun strings */
39 char *nounName(sym_link *sl) {
40   switch (SPEC_NOUN(sl)) 
41     {
42     case V_INT: {
43       if (SPEC_LONG(sl)) return "long";
44       if (sl->select.s._short) return "short";
45       return "int";
46     }
47     case V_FLOAT: return "float";
48     case V_CHAR: return "char";
49     case V_VOID: return "void";
50     case V_STRUCT: return "struct";
51     case V_LABEL: return "label";
52     case V_BITFIELD: return "bitfield";
53     case V_BIT: return "bit";
54     case V_SBIT: return "sbit";
55     case V_DOUBLE: return "double";
56     }
57   return "unknown";
58 };
59
60 bucket *SymbolTab[256];         /* the symbol    table  */
61 bucket *StructTab[256];         /* the structure table  */
62 bucket *TypedefTab[256];        /* the typedef   table  */
63 bucket *LabelTab[256];          /* the Label     table  */
64 bucket *enumTab[256];           /* enumerated    table  */
65
66 /*------------------------------------------------------------------*/
67 /* initSymt () - initialises symbol table related stuff             */
68 /*------------------------------------------------------------------*/
69 void 
70 initSymt ()
71 {
72   int i = 0;
73
74   for (i = 0; i < 256; i++)
75     SymbolTab[i] = StructTab[i] = (void *) NULL;
76
77
78 }
79 /*-----------------------------------------------------------------*/
80 /* newBucket - allocates & returns a new bucket        */
81 /*-----------------------------------------------------------------*/
82 bucket *
83 newBucket ()
84 {
85   bucket *bp;
86
87   bp = Safe_alloc ( sizeof (bucket));
88
89   return bp;
90 }
91
92 /*-----------------------------------------------------------------*/
93 /* hashKey - computes the hashkey given a symbol name              */
94 /*-----------------------------------------------------------------*/
95 int 
96 hashKey (const char *s)
97 {
98   unsigned long key = 0;
99
100   while (*s)
101     key += *s++;
102   return key % 256;
103 }
104
105 /*-----------------------------------------------------------------*/
106 /* addSym - adds a symbol to the hash Table                        */
107 /*-----------------------------------------------------------------*/
108 void 
109 addSym (bucket ** stab,
110         void *sym,
111         char *sname,
112         int level,
113         int block,
114         int checkType)
115 {
116   int i;                        /* index into the hash Table */
117   bucket *bp;                   /* temp bucket    *         */
118
119   if (checkType) {
120     symbol *csym = (symbol *)sym;
121
122     if (getenv("DEBUG_SANITY")) {
123       fprintf (stderr, "addSym: %s ", sname);
124     }
125     /* make sure the type is complete and sane */
126     checkTypeSanity(csym->etype, csym->name);
127   }
128
129   /* prevent overflow of the (r)name buffers */
130   if (strlen(sname)>SDCC_SYMNAME_MAX) {
131     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
132     sname[SDCC_SYMNAME_MAX]='\0';
133   }
134
135   /* the symbols are always added at the head of the list  */
136   i = hashKey (sname);
137   /* get a free entry */
138   bp = Safe_alloc ( sizeof (bucket));
139
140   bp->sym = sym;                /* update the symbol pointer  */
141   bp->level = level;            /* update the nest level      */
142   bp->block = block;
143   strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
144
145   /* if this is the first entry */
146   if (stab[i] == NULL)
147     {
148       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
149       stab[i] = bp;
150     }
151   /* not first entry then add @ head of list */
152   else
153     {
154       bp->prev = NULL;
155       stab[i]->prev = bp;
156       bp->next = stab[i];
157       stab[i] = bp;
158     }
159 }
160
161 /*-----------------------------------------------------------------*/
162 /* deleteSym - deletes a symbol from the hash Table  entry     */
163 /*-----------------------------------------------------------------*/
164 void 
165 deleteSym (bucket ** stab, void *sym, char *sname)
166 {
167   int i = 0;
168   bucket *bp;
169
170   i = hashKey (sname);
171
172   bp = stab[i];
173   /* find the symbol */
174   while (bp)
175     {
176       if (bp->sym == sym)       /* found it then break out */
177         break;                  /* of the loop       */
178       bp = bp->next;
179     }
180
181   if (!bp)                      /* did not find it */
182     return;
183   /* if this is the first one in the chain */
184   if (!bp->prev)
185     {
186       stab[i] = bp->next;
187       if (stab[i])              /* if chain ! empty */
188         stab[i]->prev = (void *) NULL;
189     }
190   /* middle || end of chain */
191   else
192     {
193       if (bp->next)             /* if not end of chain */
194         bp->next->prev = bp->prev;
195
196       bp->prev->next = bp->next;
197     }
198
199 }
200
201 /*-----------------------------------------------------------------*/
202 /* findSym - finds a symbol in a table           */
203 /*-----------------------------------------------------------------*/
204 void *
205 findSym (bucket ** stab, void *sym, const char *sname)
206 {
207   bucket *bp;
208
209   bp = stab[hashKey (sname)];
210   while (bp)
211     {
212       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
213         break;
214       bp = bp->next;
215     }
216
217   return (bp ? bp->sym : (void *) NULL);
218 }
219
220 /*-----------------------------------------------------------------*/
221 /* findSymWithLevel - finds a symbol with a name & level           */
222 /*-----------------------------------------------------------------*/
223 void *
224 findSymWithLevel (bucket ** stab, symbol * sym)
225 {
226   bucket *bp;
227
228   bp = stab[hashKey (sym->name)];
229
230   /**
231    **  do the search from the head of the list since the
232    **  elements are added at the head it is ensured that
233    ** we will find the deeper definitions before we find
234    ** the global ones. we need to check for symbols with
235    ** level <= to the level given, if levels match then block
236    ** numbers need to match as well
237    **/
238   while (bp)
239     {
240       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
241         {
242           /* if this is parameter then nothing else need to be checked */
243           if (((symbol *) (bp->sym))->_isparm)
244             return (bp->sym);
245           /* if levels match then block numbers should also match */
246           if (bp->level && bp->level == sym->level && bp->block == sym->block)
247             return (bp->sym);
248           /* if levels don't match then we are okay */
249           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
250             return (bp->sym);
251           /* if this is a global variable then we are ok too */
252           if (bp->level == 0)
253             return (bp->sym);
254         }
255
256       bp = bp->next;
257     }
258
259   return (void *) NULL;
260 }
261
262 /*-----------------------------------------------------------------*/
263 /* findSymWithBlock - finds a symbol with name in with a block     */
264 /*-----------------------------------------------------------------*/
265 void *
266 findSymWithBlock (bucket ** stab, symbol * sym, int block)
267 {
268   bucket *bp;
269
270   bp = stab[hashKey (sym->name)];
271   while (bp)
272     {
273       if (strcmp (bp->name, sym->name) == 0 &&
274           bp->block <= block)
275         break;
276       bp = bp->next;
277     }
278
279   return (bp ? bp->sym : (void *) NULL);
280 }
281
282 /*------------------------------------------------------------------*/
283 /* newSymbol () - returns a new pointer to a symbol                 */
284 /*------------------------------------------------------------------*/
285 symbol *
286 newSymbol (char *name, int scope)
287 {
288   symbol *sym;
289
290   sym = Safe_alloc ( sizeof (symbol));
291
292   strncpyz (sym->name, name, sizeof(sym->name));        /* copy the name */
293   sym->level = scope;           /* set the level    */
294   sym->block = currBlockno;
295   sym->lineDef = mylineno;      /* set the line number */
296   return sym;
297 }
298
299 /*------------------------------------------------------------------*/
300 /* newLink - creates a new link (declarator,specifier)              */
301 /*------------------------------------------------------------------*/
302 sym_link *
303 newLink (SYM_LINK_CLASS select)
304 {
305   sym_link *p;
306
307   p = Safe_alloc ( sizeof (sym_link));
308   p->class=select;
309
310   return p;
311 }
312
313 /*------------------------------------------------------------------*/
314 /* newStruct - creats a new structdef from the free list            */
315 /*------------------------------------------------------------------*/
316 structdef *
317 newStruct (char *tag)
318 {
319   structdef *s;
320
321   s = Safe_alloc ( sizeof (structdef));
322
323   strncpyz (s->tag, tag, sizeof(s->tag));               /* copy the tag */
324   return s;
325 }
326
327 /*------------------------------------------------------------------*/
328 /* pointerTypes - do the computation for the pointer types          */
329 /*------------------------------------------------------------------*/
330 void 
331 pointerTypes (sym_link * ptr, sym_link * type)
332 {
333   if (IS_SPEC (ptr))
334     return;
335
336   /* find the first pointer type */
337   while (ptr && !IS_PTR (ptr))
338     ptr = ptr->next;
339
340   /* could not find it */
341   if (!ptr || IS_SPEC (ptr))
342     return;
343   
344   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
345     pointerTypes (ptr->next, type);
346     return;
347   }
348
349   /* change the pointer type depending on the
350      storage class of the type */
351   if (IS_SPEC (type))
352     {
353       switch (SPEC_SCLS (type))
354         {
355         case S_XDATA:
356           DCL_TYPE (ptr) = FPOINTER;
357           break;
358         case S_IDATA:
359           DCL_TYPE (ptr) = IPOINTER;
360           break;
361         case S_PDATA:
362           DCL_TYPE (ptr) = PPOINTER;
363           break;
364         case S_DATA:
365           DCL_TYPE (ptr) = POINTER;
366           break;
367         case S_CODE:
368           DCL_TYPE (ptr) = CPOINTER;
369           break;
370         case S_EEPROM:
371           DCL_TYPE (ptr) = EEPPOINTER;
372           break;
373         default:
374           DCL_TYPE (ptr) = port->unqualified_pointer;
375           break;
376         }
377       /* the storage class of type ends here */
378       SPEC_SCLS (type) = 0;
379     }
380
381   /* now change all the remaining unknown pointers
382      to generic pointers */
383   while (ptr)
384     {
385       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
386         DCL_TYPE (ptr) = port->unqualified_pointer;
387       ptr = ptr->next;
388     }
389
390   /* same for the type although it is highly unlikely that
391      type will have a pointer */
392   while (type)
393     {
394       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
395         DCL_TYPE (type) = port->unqualified_pointer;
396       type = type->next;
397     }
398 }
399
400 /*------------------------------------------------------------------*/
401 /* addDecl - adds a declarator @ the end of a chain                 */
402 /*------------------------------------------------------------------*/
403 void 
404 addDecl (symbol * sym, int type, sym_link * p)
405 {
406   sym_link *head;
407   sym_link *tail;
408   sym_link *t;
409
410   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
411     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
412
413   /* if we are passed a link then set head & tail */
414   if (p)
415     {
416       tail = head = p;
417       while (tail->next)
418         tail = tail->next;
419     }
420   else
421     {
422       head = tail = newLink (DECLARATOR);
423       DCL_TYPE (head) = type;
424     }
425
426   /* if this is the first entry   */
427   if (!sym->type)
428     {
429       sym->type = head;
430       sym->etype = tail;
431     }
432   else
433     {
434       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
435         {
436           sym->etype = mergeSpec (sym->etype, head, sym->name);
437         }
438       else
439         {
440           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
441             {
442               t = sym->type;
443               while (t->next != sym->etype)
444                 t = t->next;
445               t->next = head;
446               tail->next = sym->etype;
447             }
448           else
449             {
450               sym->etype->next = head;
451               sym->etype = tail;
452             }
453         }
454     }
455
456   /* if the type is an unknown pointer and has
457      a tspec then take the storage class const & volatile
458      attribute from the tspec & make it those of this
459      symbol */
460   if (p &&
461       !IS_SPEC (p) &&
462       //DCL_TYPE (p) == UPOINTER &&
463       DCL_TSPEC (p))
464     {
465       if (!IS_SPEC (sym->etype))
466         {
467           sym->etype = sym->etype->next = newLink (SPECIFIER);
468         }
469       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
470       DCL_TSPEC (p) = NULL;
471     }
472
473   // if there is a function in this type chain
474   if (p && funcInChain(sym->type)) {
475     processFuncArgs (sym);
476   }
477
478   return;
479 }
480
481 /*------------------------------------------------------------------
482   checkTypeSanity: prevent the user from doing e.g.:
483   unsigned float uf;
484   ------------------------------------------------------------------*/
485 void checkTypeSanity(sym_link *etype, char *name) {
486   char *noun;
487
488   if (!etype) {
489     if (getenv("DEBUG_SANITY")) {
490       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
491     }
492     return;
493   }
494
495   if (!IS_SPEC(etype)) {
496     if (getenv("DEBUG_SANITY")) {
497       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
498     }
499     return;
500   }
501
502   noun=nounName(etype);
503
504   if (getenv("DEBUG_SANITY")) {
505     fprintf (stderr, "checking sanity for %s %p\n", name, etype);
506   }
507
508   if ((SPEC_NOUN(etype)==V_CHAR || 
509        SPEC_NOUN(etype)==V_FLOAT || 
510        SPEC_NOUN(etype)==V_DOUBLE || 
511        SPEC_NOUN(etype)==V_VOID) &&
512       (etype->select.s._short || SPEC_LONG(etype))) {
513     // long or short for char float double or void
514     werror (E_LONG_OR_SHORT_INVALID, noun, name);
515   }
516   if ((SPEC_NOUN(etype)==V_FLOAT || 
517        SPEC_NOUN(etype)==V_DOUBLE || 
518        SPEC_NOUN(etype)==V_VOID) && 
519       (etype->select.s._signed || SPEC_USIGN(etype))) {
520     // signed or unsigned for float double or void
521     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
522   }
523
524   // special case for "short"
525   if (etype->select.s._short) {
526     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
527     etype->select.s._short = 0;
528   }
529
530   /* if no noun e.g. 
531      "const a;" or "data b;" or "signed s" or "long l"
532      assume an int */
533   if (!SPEC_NOUN(etype)) {
534     SPEC_NOUN(etype)=V_INT;
535   }
536
537   if (etype->select.s._signed && SPEC_USIGN(etype)) {
538     // signed AND unsigned 
539     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
540   }
541   if (etype->select.s._short && SPEC_LONG(etype)) {
542     // short AND long
543     werror (E_LONG_AND_SHORT_INVALID, noun, name);
544   }
545
546 }
547
548 /*------------------------------------------------------------------*/
549 /* mergeSpec - merges two specifiers and returns the new one        */
550 /*------------------------------------------------------------------*/
551 sym_link *
552 mergeSpec (sym_link * dest, sym_link * src, char *name)
553 {
554   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
555 #if 0
556     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
557     exit (1);
558 #else
559     werror (E_SYNTAX_ERROR, yytext);
560     // the show must go on
561     return newIntLink();
562 #endif
563   }
564
565   if (SPEC_NOUN(src)) {
566     if (!SPEC_NOUN(dest)) {
567       SPEC_NOUN(dest)=SPEC_NOUN(src);
568     } else {
569       /* we shouldn't redeclare the type */
570       if (getenv("DEBUG_SANITY")) {
571         fprintf (stderr, "mergeSpec: ");
572       }
573       werror(E_TWO_OR_MORE_DATA_TYPES, name);
574     }
575   }
576   
577   if (SPEC_SCLS(src)) {
578     /* if destination has no storage class */
579     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
580       SPEC_SCLS (dest) = SPEC_SCLS (src);
581     } else {
582       if (getenv("DEBUG_SANITY")) {
583         fprintf (stderr, "mergeSpec: ");
584       }
585       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
586     }
587   }
588
589   /* copy all the specifications  */
590
591   // we really should do: 
592 #if 0
593   if (SPEC_what(src)) {
594     if (SPEC_what(dest)) {
595       werror(W_DUPLICATE_SPEC, "what");
596     }
597     SPEC_what(dst)|=SPEC_what(src);
598   }
599 #endif
600   // but there are more important thing right now
601
602   SPEC_LONG (dest) |= SPEC_LONG (src);
603   dest->select.s._short|=src->select.s._short;
604   SPEC_USIGN (dest) |= SPEC_USIGN (src);
605   dest->select.s._signed|=src->select.s._signed;
606   SPEC_STAT (dest) |= SPEC_STAT (src);
607   SPEC_EXTR (dest) |= SPEC_EXTR (src);
608   SPEC_CONST(dest) |= SPEC_CONST (src);
609   SPEC_ABSA (dest) |= SPEC_ABSA (src);
610   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
611   SPEC_ADDR (dest) |= SPEC_ADDR (src);
612   SPEC_OCLS (dest) = SPEC_OCLS (src);
613   SPEC_BLEN (dest) |= SPEC_BLEN (src);
614   SPEC_BSTR (dest) |= SPEC_BSTR (src);
615   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
616   SPEC_ENUM (dest) |= SPEC_ENUM (src);
617   if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
618       SPEC_ARGREG(dest) = SPEC_ARGREG(src);
619   
620   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
621     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
622
623   /* these are the only function attributes that will be set 
624      in a specifier while parsing */
625   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
626   FUNC_BANKED(dest) |= FUNC_BANKED(src);
627   FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
628   FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
629   FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
630   FUNC_ISISR(dest) |= FUNC_ISISR(src);
631   FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
632   FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
633   FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
634   FUNC_INTNO(dest) |= FUNC_INTNO(src);
635   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
636
637   return dest;
638 }
639
640 /*------------------------------------------------------------------*/
641 /* genSymName - generates and returns a name used for anonymous vars */
642 /*------------------------------------------------------------------*/
643 char *
644 genSymName (int level)
645 {
646   static int gCount = 0;
647   static char gname[SDCC_NAME_MAX + 1];
648
649   SNPRINTF (gname, sizeof(gname), "__%04d%04d", level, gCount++);
650   return gname;
651 }
652
653 /*------------------------------------------------------------------*/
654 /* getSpec - returns the specifier part from a declaration chain    */
655 /*------------------------------------------------------------------*/
656 sym_link *
657 getSpec (sym_link * p)
658 {
659   sym_link *loop;
660
661   loop = p;
662   while (p && !(IS_SPEC (p)))
663     p = p->next;
664
665   return p;
666 }
667
668 /*------------------------------------------------------------------*/
669 /* newCharLink() - creates an char type                             */
670 /*------------------------------------------------------------------*/
671 sym_link *
672 newCharLink ()
673 {
674   sym_link *p;
675
676   p = newLink (SPECIFIER);
677   SPEC_NOUN (p) = V_CHAR;
678
679   return p;
680 }
681
682 /*------------------------------------------------------------------*/
683 /* newFloatLink - a new Float type                                  */
684 /*------------------------------------------------------------------*/
685 sym_link *
686 newFloatLink ()
687 {
688   sym_link *p;
689
690   p = newLink (SPECIFIER);
691   SPEC_NOUN (p) = V_FLOAT;
692
693   return p;
694 }
695
696 /*------------------------------------------------------------------*/
697 /* newLongLink() - new long type                                    */
698 /*------------------------------------------------------------------*/
699 sym_link *
700 newLongLink ()
701 {
702   sym_link *p;
703
704   p = newLink (SPECIFIER);
705   SPEC_NOUN (p) = V_INT;
706   SPEC_LONG (p) = 1;
707
708   return p;
709 }
710
711 /*------------------------------------------------------------------*/
712 /* newIntLink() - creates an int type                               */
713 /*------------------------------------------------------------------*/
714 sym_link *
715 newIntLink ()
716 {
717   sym_link *p;
718
719   p = newLink (SPECIFIER);
720   SPEC_NOUN (p) = V_INT;
721
722   return p;
723 }
724
725 /*------------------------------------------------------------------*/
726 /* getSize - returns size of a type chain in bits                   */
727 /*------------------------------------------------------------------*/
728 unsigned int 
729 getSize (sym_link * p)
730 {
731   /* if nothing return 0 */
732   if (!p)
733     return 0;
734   if (IS_SPEC (p))
735     {                           /* if this is the specifier then */
736       switch (SPEC_NOUN (p))
737         {                       /* depending on the specifier type */
738         case V_INT:
739           return (IS_LONG (p) ? LONGSIZE : INTSIZE);
740         case V_FLOAT:
741           return FLOATSIZE;
742         case V_CHAR:
743           return CHARSIZE;
744         case V_VOID:
745           return 0;
746         case V_STRUCT:
747           return SPEC_STRUCT (p)->size;
748         case V_LABEL:
749           return 0;
750         case V_SBIT:
751         case V_BIT:
752           return BITSIZE;
753         case V_BITFIELD:
754           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
755         default:
756           return 0;
757         }
758     }
759
760   /* this is a specifier  */
761   switch (DCL_TYPE (p))
762     {
763     case ARRAY:
764       if (DCL_ELEM(p)) {
765         return DCL_ELEM (p) * getSize (p->next);
766       } else {
767           //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
768           //    "can not tell the size of an array[]");
769         return 0;
770       }
771     case IPOINTER:
772     case PPOINTER:
773     case POINTER:
774       return (PTRSIZE);
775     case EEPPOINTER:
776     case FPOINTER:
777     case CPOINTER:
778     case FUNCTION:
779       return (FPTRSIZE);
780     case GPOINTER:
781       return (GPTRSIZE);
782
783     default:
784       return 0;
785     }
786 }
787
788 /*------------------------------------------------------------------*/
789 /* bitsForType - returns # of bits required to store this type      */
790 /*------------------------------------------------------------------*/
791 unsigned int 
792 bitsForType (sym_link * p)
793 {
794   /* if nothing return 0 */
795   if (!p)
796     return 0;
797
798   if (IS_SPEC (p))
799     {                           /* if this is the specifier then */
800
801       switch (SPEC_NOUN (p))
802         {                       /* depending on the specifier type */
803         case V_INT:
804           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
805         case V_FLOAT:
806           return FLOATSIZE * 8;
807         case V_CHAR:
808           return CHARSIZE * 8;
809         case V_VOID:
810           return 0;
811         case V_STRUCT:
812           return SPEC_STRUCT (p)->size * 8;
813         case V_LABEL:
814           return 0;
815         case V_SBIT:
816         case V_BIT:
817           return 1;
818         case V_BITFIELD:
819           return SPEC_BLEN (p);
820         default:
821           return 0;
822         }
823     }
824
825   /* this is a specifier  */
826   switch (DCL_TYPE (p))
827     {
828     case ARRAY:
829       return DCL_ELEM (p) * getSize (p->next) * 8;
830     case IPOINTER:
831     case PPOINTER:
832     case POINTER:
833       return (PTRSIZE * 8);
834     case EEPPOINTER:
835     case FPOINTER:
836     case CPOINTER:
837     case FUNCTION:
838       return (FPTRSIZE * 8);
839     case GPOINTER:
840       return (GPTRSIZE * 8);
841
842     default:
843       return 0;
844     }
845 }
846
847 /*------------------------------------------------------------------*/
848 /* copySymbolChain - copies a symbol chain                          */
849 /*------------------------------------------------------------------*/
850 symbol *
851 copySymbolChain (symbol * src)
852 {
853   symbol *dest;
854
855   if (!src)
856     return NULL;
857
858   dest = copySymbol (src);
859   dest->next = copySymbolChain (src->next);
860   return dest;
861 }
862
863 /*------------------------------------------------------------------*/
864 /* copySymbol - makes a copy of a symbol                            */
865 /*------------------------------------------------------------------*/
866 symbol *
867 copySymbol (symbol * src)
868 {
869   symbol *dest;
870
871   if (!src)
872     return NULL;
873
874   dest = newSymbol (src->name, src->level);
875   memcpy (dest, src, sizeof (symbol));
876   dest->level = src->level;
877   dest->block = src->block;
878   dest->ival = copyIlist (src->ival);
879   dest->type = copyLinkChain (src->type);
880   dest->etype = getSpec (dest->type);
881   dest->next = NULL;
882   dest->key = src->key;
883   dest->allocreq = src->allocreq;
884   return dest;
885 }
886
887 /*------------------------------------------------------------------*/
888 /* reverseSyms - reverses the links for a symbol chain      */
889 /*------------------------------------------------------------------*/
890 symbol *
891 reverseSyms (symbol * sym)
892 {
893   symbol *prev, *curr, *next;
894
895   if (!sym)
896     return NULL;
897
898   prev = sym;
899   curr = sym->next;
900
901   while (curr)
902     {
903       next = curr->next;
904       curr->next = prev;
905       prev = curr;
906       curr = next;
907     }
908   sym->next = (void *) NULL;
909   return prev;
910 }
911
912 /*------------------------------------------------------------------*/
913 /* reverseLink - reverses the links for a type chain        */
914 /*------------------------------------------------------------------*/
915 sym_link *
916 reverseLink (sym_link * type)
917 {
918   sym_link *prev, *curr, *next;
919
920   if (!type)
921     return NULL;
922
923   prev = type;
924   curr = type->next;
925
926   while (curr)
927     {
928       next = curr->next;
929       curr->next = prev;
930       prev = curr;
931       curr = next;
932     }
933   type->next = (void *) NULL;
934   return prev;
935 }
936
937 /*------------------------------------------------------------------*/
938 /* addSymChain - adds a symbol chain to the symboltable             */
939 /*------------------------------------------------------------------*/
940 void 
941 addSymChain (symbol * symHead)
942 {
943   symbol *sym = symHead;
944   symbol *csym = NULL;
945
946   for (; sym != NULL; sym = sym->next)
947     {
948       changePointer(sym);
949       checkTypeSanity(sym->etype, sym->name);
950
951       /* if already exists in the symbol table then check if
952          one of them is an extern definition if yes then
953          then check if the type match, if the types match then
954          delete the current entry and add the new entry      */
955       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
956           csym->level == sym->level) {
957         
958         /* one definition extern ? */
959         if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
960           /* do types match ? */
961           if (compareType (csym->type, sym->type) != 1) {
962             /* no then error */
963             werror (E_EXTERN_MISMATCH, csym->name);
964             continue;
965           }
966         } else {
967           /* not extern */
968           if (compareType (csym->type, sym->type) != 1) {
969             werror (E_DUPLICATE, sym->name);
970             continue;
971           }
972         }
973         /* delete current entry */
974         deleteSym (SymbolTab, csym, csym->name);
975         deleteFromSeg(csym);
976       }
977
978       /* add new entry */
979       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
980     }
981 }
982
983
984 /*------------------------------------------------------------------*/
985 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
986 /*------------------------------------------------------------------*/
987 int 
988 funcInChain (sym_link * lnk)
989 {
990   while (lnk)
991     {
992       if (IS_FUNC (lnk))
993         return 1;
994       lnk = lnk->next;
995     }
996   return 0;
997 }
998
999 /*------------------------------------------------------------------*/
1000 /* structElemType - returns the type info of a sturct member        */
1001 /*------------------------------------------------------------------*/
1002 sym_link *
1003 structElemType (sym_link * stype, value * id)
1004 {
1005   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1006   sym_link *type, *etype;
1007   sym_link *petype = getSpec (stype);
1008
1009   if (fields && id) {
1010     
1011     /* look for the id */
1012     while (fields)
1013       {
1014         if (strcmp (fields->rname, id->name) == 0)
1015           {
1016             type = copyLinkChain (fields->type);
1017             etype = getSpec (type);
1018             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1019                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
1020             return type;
1021           }
1022         fields = fields->next;
1023       }
1024   }
1025
1026   werror (E_NOT_MEMBER, id->name);
1027     
1028   // the show must go on
1029   return newIntLink();
1030 }
1031
1032 /*------------------------------------------------------------------*/
1033 /* getStructElement - returns element of a tructure definition      */
1034 /*------------------------------------------------------------------*/
1035 symbol *
1036 getStructElement (structdef * sdef, symbol * sym)
1037 {
1038   symbol *field;
1039
1040   for (field = sdef->fields; field; field = field->next)
1041     if (strcmp (field->name, sym->name) == 0)
1042       return field;
1043
1044   werror (E_NOT_MEMBER, sym->name);
1045
1046   return sdef->fields;
1047 }
1048
1049 /*------------------------------------------------------------------*/
1050 /* compStructSize - computes the size of a structure                */
1051 /*------------------------------------------------------------------*/
1052 int 
1053 compStructSize (int su, structdef * sdef)
1054 {
1055     int sum = 0, usum = 0;
1056     int bitOffset = 0;
1057     symbol *loop;
1058
1059     /* for the identifiers  */
1060     loop = sdef->fields;
1061     while (loop) {
1062
1063         /* create the internal name for this variable */
1064         SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1065         if (su == UNION) {
1066             sum = 0;
1067             bitOffset = 0;
1068         }
1069         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1070
1071         /* if this is a bit field  */
1072         if (loop->bitVar) {
1073
1074             /* change it to a unsigned bit */
1075             SPEC_NOUN (loop->etype) = V_BITFIELD;
1076             SPEC_USIGN (loop->etype) = 1;
1077             SPEC_BLEN (loop->etype) = loop->bitVar;
1078
1079             if (loop->bitVar == BITVAR_PAD) {
1080                 /* A zero length bitfield forces padding */
1081                 SPEC_BSTR (loop->etype) = bitOffset;
1082                 SPEC_BLEN (loop->etype) = 0;
1083                 bitOffset = 8;
1084                 loop->offset = sum;
1085             }
1086             else {
1087                 if (bitOffset == 8) {
1088                     bitOffset = 0;
1089                     sum++;
1090                 }
1091                 /* check if this fit into the remaining   */
1092                 /* bits of this byte else align it to the */
1093                 /* next byte boundary                     */
1094                 if (loop->bitVar <= (8 - bitOffset)) {
1095                     /* fits into current byte */
1096                     loop->offset = sum;
1097                     SPEC_BSTR (loop->etype) = bitOffset;
1098                     bitOffset += loop->bitVar;
1099                 }
1100                 else if (!bitOffset) {
1101                     /* does not fit, but is already byte aligned */
1102                     loop->offset = sum;
1103                     SPEC_BSTR (loop->etype) = bitOffset;
1104                     bitOffset += loop->bitVar;
1105                 } 
1106                 else {
1107                     /* does not fit; need to realign first */
1108                     sum++;
1109                     loop->offset = (su == UNION ? sum = 0 : sum);
1110                     bitOffset = 0;
1111                     SPEC_BSTR (loop->etype) = bitOffset;
1112                     bitOffset += loop->bitVar;
1113                 }
1114                 while (bitOffset>8) {
1115                     bitOffset -= 8;
1116                     sum++;
1117                 } 
1118             }
1119         }
1120         else {
1121             /* This is a non-bit field. Make sure we are */
1122             /* byte aligned first */
1123             if (bitOffset) {
1124                 sum++;
1125                 loop->offset = (su == UNION ? sum = 0 : sum);
1126                 bitOffset = 0;
1127             }
1128             loop->offset = sum;
1129             checkDecl (loop, 1);
1130             sum += getSize (loop->type);
1131         }
1132
1133         loop = loop->next;
1134
1135         /* if union then size = sizeof larget field */
1136         if (su == UNION) {
1137             /* For UNION, round up after each field */
1138             sum += ((bitOffset+7)/8);
1139             usum = max (usum, sum);
1140         }
1141
1142     }
1143     
1144     /* For STRUCT, round up after all fields processed */
1145     if (su != UNION)
1146         sum += ((bitOffset+7)/8);
1147
1148     return (su == UNION ? usum : sum);
1149 }
1150
1151 /*------------------------------------------------------------------*/
1152 /* checkSClass - check the storage class specification              */
1153 /*------------------------------------------------------------------*/
1154 static void 
1155 checkSClass (symbol * sym, int isProto)
1156 {
1157   sym_link *t;
1158   
1159   if (getenv("DEBUG_SANITY")) {
1160     fprintf (stderr, "checkSClass: %s \n", sym->name);
1161   }
1162   
1163   /* type is literal can happen for enums change
1164      to auto */
1165   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1166     SPEC_SCLS (sym->etype) = S_AUTO;
1167   
1168   /* if sfr or sbit then must also be volatile */
1169   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1170       SPEC_SCLS (sym->etype) == S_SFR)
1171     {
1172       SPEC_VOLATILE (sym->etype) = 1;
1173     }
1174   
1175   /* if absolute address given then it mark it as
1176      volatile -- except in the PIC port */
1177
1178 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1179   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1180   if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1181 #endif
1182
1183     if (IS_ABSOLUTE (sym->etype))
1184       SPEC_VOLATILE (sym->etype) = 1;
1185   
1186   /* If code memory is read only, then pointers to code memory */
1187   /* implicitly point to constants -- make this explicit       */
1188   t = sym->type;
1189   while (t && t->next) {
1190     if (IS_CODEPTR(t) && port->mem.code_ro) {
1191       if (IS_SPEC(t->next)) {
1192         SPEC_CONST (t->next) = 1;
1193       } else {
1194         DCL_PTR_CONST (t->next) = 1;
1195       }
1196     }
1197     t = t->next;
1198   }
1199
1200   /* global variables declared const put into code */
1201   /* if no other storage class specified */
1202   if (sym->level == 0 &&
1203       SPEC_SCLS(sym->etype) == S_FIXED &&
1204       !IS_FUNC(sym->type)) {
1205     /* find the first non-array link */
1206     t = sym->type;
1207     while (IS_ARRAY(t))
1208       t = t->next;
1209     if (IS_CONSTANT (t)) {
1210       SPEC_SCLS (sym->etype) = S_CODE;
1211     }
1212   }
1213
1214   /* global variable in code space is a constant */
1215   if (sym->level == 0 &&
1216       SPEC_SCLS (sym->etype) == S_CODE &&
1217       port->mem.code_ro) {
1218     /* find the first non-array link */
1219     t = sym->type;
1220     while (IS_ARRAY(t))
1221       t = t->next;
1222     if (IS_SPEC(t)) {
1223       SPEC_CONST (t) = 1;
1224     } else {
1225       DCL_PTR_CONST (t) = 1;
1226     }
1227   }
1228
1229   /* if bit variable then no storage class can be */
1230   /* specified since bit is already a storage */
1231   if (IS_BITVAR (sym->etype) &&
1232       (SPEC_SCLS (sym->etype) != S_FIXED &&
1233        SPEC_SCLS (sym->etype) != S_SBIT &&
1234        SPEC_SCLS (sym->etype) != S_BIT)
1235     )
1236     {
1237       werror (E_BITVAR_STORAGE, sym->name);
1238       SPEC_SCLS (sym->etype) = S_FIXED;
1239     }
1240
1241   /* extern variables cannot be initialized */
1242   if (IS_EXTERN (sym->etype) && sym->ival)
1243     {
1244       werror (E_EXTERN_INIT, sym->name);
1245       sym->ival = NULL;
1246     }
1247
1248   /* if this is an automatic symbol */
1249   if (sym->level && (options.stackAuto || reentrant)) {
1250     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1251          SPEC_SCLS (sym->etype) == S_FIXED ||
1252          SPEC_SCLS (sym->etype) == S_REGISTER ||
1253          SPEC_SCLS (sym->etype) == S_STACK ||
1254          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1255       SPEC_SCLS (sym->etype) = S_AUTO;
1256     } else {
1257       /* storage class may only be specified for statics */
1258       if (!IS_STATIC(sym->etype)) {
1259         werror (E_AUTO_ASSUMED, sym->name);
1260       }
1261     }
1262   }
1263   
1264   /* automatic symbols cannot be given   */
1265   /* an absolute address ignore it      */
1266   if (sym->level &&
1267       SPEC_ABSA (sym->etype) &&
1268       (options.stackAuto || reentrant))
1269     {
1270       werror (E_AUTO_ABSA, sym->name);
1271       SPEC_ABSA (sym->etype) = 0;
1272     }
1273
1274   /* arrays & pointers cannot be defined for bits   */
1275   /* SBITS or SFRs or BIT                           */
1276   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1277       (SPEC_NOUN (sym->etype) == V_BIT ||
1278        SPEC_NOUN (sym->etype) == V_SBIT ||
1279        SPEC_NOUN (sym->etype) == V_BITFIELD ||
1280        SPEC_SCLS (sym->etype) == S_SFR))
1281     werror (E_BIT_ARRAY, sym->name);
1282
1283   /* if this is a bit|sbit then set length & start  */
1284   if (SPEC_NOUN (sym->etype) == V_BIT ||
1285       SPEC_NOUN (sym->etype) == V_SBIT)
1286     {
1287       SPEC_BLEN (sym->etype) = 1;
1288       SPEC_BSTR (sym->etype) = 0;
1289     }
1290
1291   if (!isProto) {
1292     /* variables declared in CODE space must have */
1293     /* initializers if not an extern */
1294     if (SPEC_SCLS (sym->etype) == S_CODE &&
1295         sym->ival == NULL &&
1296         //!sym->level &&
1297         port->mem.code_ro &&
1298         !IS_EXTERN (sym->etype) &&
1299         !funcInChain (sym->type))
1300       werror (E_CODE_NO_INIT, sym->name);
1301   }
1302
1303   /* if parameter or local variable then change */
1304   /* the storage class to reflect where the var will go */
1305   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1306       !IS_STATIC(sym->etype))
1307     {
1308       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1309         {
1310           SPEC_SCLS (sym->etype) = (options.useXstack ?
1311                                     S_XSTACK : S_STACK);
1312         }
1313       else
1314         {
1315           /* hack-o-matic! I see no reason why the useXstack option should ever
1316            * control this allcoation, but the code was originally that way, and
1317            * changing it for non-390 ports breaks the compiler badly.
1318            */
1319           bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
1320                 1 : options.useXstack;
1321           SPEC_SCLS (sym->etype) = (useXdata ?
1322                                     S_XDATA : S_FIXED);
1323         }
1324     }
1325 }
1326
1327 /*------------------------------------------------------------------*/
1328 /* changePointer - change pointer to functions                      */
1329 /*------------------------------------------------------------------*/
1330 void 
1331 changePointer (symbol * sym)
1332 {
1333   sym_link *p;
1334
1335   /* go thru the chain of declarations   */
1336   /* if we find a pointer to a function  */
1337   /* unconditionally change it to a ptr  */
1338   /* to code area                        */
1339   for (p = sym->type; p; p = p->next)
1340     {
1341       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1342         DCL_TYPE (p) = port->unqualified_pointer;
1343       if (IS_PTR (p) && IS_FUNC (p->next))
1344         DCL_TYPE (p) = CPOINTER;
1345     }
1346 }
1347
1348 /*------------------------------------------------------------------*/
1349 /* checkDecl - does semantic validation of a declaration                   */
1350 /*------------------------------------------------------------------*/
1351 int 
1352 checkDecl (symbol * sym, int isProto)
1353 {
1354
1355   checkSClass (sym, isProto);           /* check the storage class      */
1356   changePointer (sym);          /* change pointers if required */
1357
1358   /* if this is an array without any dimension
1359      then update the dimension from the initial value */
1360   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1361     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1362
1363   return 0;
1364 }
1365
1366 /*------------------------------------------------------------------*/
1367 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1368 /*------------------------------------------------------------------*/
1369 sym_link *
1370 copyLinkChain (sym_link * p)
1371 {
1372   sym_link *head, *curr, *loop;
1373
1374   curr = p;
1375   head = loop = (curr ? newLink (p->class) : (void *) NULL);
1376   while (curr)
1377     {
1378       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1379       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1380       loop = loop->next;
1381       curr = curr->next;
1382     }
1383
1384   return head;
1385 }
1386
1387
1388 /*------------------------------------------------------------------*/
1389 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1390 /*                symbols in the given block                        */
1391 /*------------------------------------------------------------------*/
1392 void 
1393 cleanUpBlock (bucket ** table, int block)
1394 {
1395   int i;
1396   bucket *chain;
1397
1398   /* go thru the entire  table  */
1399   for (i = 0; i < 256; i++)
1400     {
1401       for (chain = table[i]; chain; chain = chain->next)
1402         {
1403           if (chain->block >= block)
1404             {
1405               deleteSym (table, chain->sym, chain->name);
1406             }
1407         }
1408     }
1409 }
1410
1411 /*------------------------------------------------------------------*/
1412 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1413 /*                symbols in the given level                        */
1414 /*------------------------------------------------------------------*/
1415 void 
1416 cleanUpLevel (bucket ** table, int level)
1417 {
1418   int i;
1419   bucket *chain;
1420
1421   /* go thru the entire  table  */
1422   for (i = 0; i < 256; i++)
1423     {
1424       for (chain = table[i]; chain; chain = chain->next)
1425         {
1426           if (chain->level >= level)
1427             {
1428               deleteSym (table, chain->sym, chain->name);
1429             }
1430         }
1431     }
1432 }
1433
1434 /*------------------------------------------------------------------*/
1435 /* computeType - computes the resultant type from two types         */
1436 /*------------------------------------------------------------------*/
1437 sym_link *
1438 computeType (sym_link * type1, sym_link * type2)
1439 {
1440   sym_link *rType;
1441   sym_link *reType;
1442   sym_link *etype1 = getSpec (type1);
1443   sym_link *etype2 = getSpec (type2);
1444
1445   /* if one of them is a float then result is a float */
1446   /* here we assume that the types passed are okay */
1447   /* and can be cast to one another                */
1448   /* which ever is greater in size */
1449   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1450     rType = newFloatLink ();
1451   else
1452     /* if only one of them is a bit variable
1453        then the other one prevails */
1454   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1455     rType = copyLinkChain (type2);
1456   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1457     rType = copyLinkChain (type1);
1458   else
1459     /* if one of them is a pointer or array then that
1460        prevails */
1461   if (IS_PTR (type1) || IS_ARRAY (type1))
1462     rType = copyLinkChain (type1);
1463   else if (IS_PTR (type2) || IS_ARRAY (type2))
1464     rType = copyLinkChain (type2);
1465   else if (getSize (type1) > getSize (type2))
1466     rType = copyLinkChain (type1);
1467   else
1468     rType = copyLinkChain (type2);
1469
1470   reType = getSpec (rType);
1471 #if 0
1472   if (SPEC_NOUN (reType) == V_CHAR)
1473     SPEC_NOUN (reType) = V_INT;
1474 #endif
1475
1476   /* if either of them unsigned but not val then make this unsigned */
1477   if (((/*!IS_LITERAL(type1) &&*/ SPEC_USIGN (etype1)) ||
1478        (/*!IS_LITERAL(type2) &&*/ SPEC_USIGN (etype2))) &&
1479       !IS_FLOAT (reType))
1480     SPEC_USIGN (reType) = 1;
1481   else
1482     SPEC_USIGN (reType) = 0;
1483
1484   /* if result is a literal then make not so */
1485   if (IS_LITERAL (reType))
1486     SPEC_SCLS (reType) = S_REGISTER;
1487
1488   return rType;
1489 }
1490
1491 /*--------------------------------------------------------------------*/
1492 /* compareType - will do type check return 1 if match, -1 if castable */
1493 /*--------------------------------------------------------------------*/
1494 int
1495 compareType (sym_link * dest, sym_link * src)
1496 {
1497   if (!dest && !src)
1498     return 1;
1499
1500   if (dest && !src)
1501     return 0;
1502
1503   if (src && !dest)
1504     return 0;
1505
1506   /* if dest is a declarator then */
1507   if (IS_DECL (dest))
1508     {
1509       if (IS_DECL (src))
1510         {
1511           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1512             if (IS_FUNC(src)) {
1513               //checkFunction(src,dest);
1514             }
1515             return compareType (dest->next, src->next);
1516           }
1517           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
1518             return 1;
1519           }
1520           if (IS_PTR (src) && IS_GENPTR (dest))
1521             return -1;
1522           if (IS_PTR (dest) && IS_ARRAY (src)) {
1523             value *val=aggregateToPointer (valFromType(src));
1524             int res=compareType (dest, val->type);
1525             Safe_free(val->type);
1526             Safe_free(val);
1527             return res;
1528           }
1529           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1530             return compareType (dest->next, src);
1531           return 0;
1532         }
1533       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1534         return -1;
1535       else
1536         return 0;
1537     }
1538
1539   /* if one is a specifier and the other is not */
1540   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1541       (IS_SPEC (dest) && !IS_SPEC (src)))
1542     return 0;
1543
1544   /* if one of them is a void then ok */
1545   if (SPEC_NOUN (dest) == V_VOID &&
1546       SPEC_NOUN (src) != V_VOID)
1547     return -1;
1548
1549   if (SPEC_NOUN (dest) != V_VOID &&
1550       SPEC_NOUN (src) == V_VOID)
1551     return -1;
1552
1553   /* if they are both bitfields then if the lengths
1554      and starts don't match */
1555   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1556       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1557        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1558     return -1;
1559
1560   /* it is a specifier */
1561   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1562     {
1563       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1564           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1565           getSize (dest) == getSize (src))
1566         return 1;
1567       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1568         return -1;
1569       else
1570         return 0;
1571     }
1572   else if (IS_STRUCT (dest))
1573     {
1574       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1575         return 0;
1576       else
1577         return 1;
1578     }
1579   if (SPEC_LONG (dest) != SPEC_LONG (src))
1580     return -1;
1581
1582   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1583     return -1;
1584
1585   return 1;
1586 }
1587
1588 /*------------------------------------------------------------------*/
1589 /* inCalleeSaveList - return 1 if found in callee save list          */
1590 /*------------------------------------------------------------------*/
1591 static int
1592 calleeCmp(void *p1, void *p2)
1593 {
1594   return (strcmp((char *)p1, (char *)(p2)) == 0);
1595 }
1596
1597 bool
1598 inCalleeSaveList(char *s)
1599 {
1600   if (options.all_callee_saves)
1601     return 1;
1602   return isinSetWith(options.calleeSavesSet, s, calleeCmp);
1603 }
1604
1605 /*-----------------------------------------------------------------*/
1606 /* aggregateToPointer:  change an agggregate type function      */
1607 /*         argument to a pointer to that type.     */
1608 /*-----------------------------------------------------------------*/
1609 value *
1610 aggregateToPointer (value * val)
1611 {
1612   if (IS_AGGREGATE (val->type))
1613     {
1614       /* if this is a structure */
1615       /* then we need to add a new link */
1616       if (IS_STRUCT (val->type))
1617         {
1618           /* first lets add DECLARATOR type */
1619           sym_link *p = val->type;
1620
1621           werror (W_STRUCT_AS_ARG, val->name);
1622           val->type = newLink (DECLARATOR);
1623           val->type->next = p;
1624         }
1625
1626       /* change to a pointer depending on the */
1627       /* storage class specified        */
1628       switch (SPEC_SCLS (val->etype))
1629         {
1630         case S_IDATA:
1631           DCL_TYPE (val->type) = IPOINTER;
1632           break;
1633         case S_PDATA:
1634           DCL_TYPE (val->type) = PPOINTER;
1635           break;
1636         case S_FIXED:
1637           if (SPEC_OCLS(val->etype)) {
1638             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1639           } else {
1640             // this happens for (external) function parameters
1641             DCL_TYPE (val->type) = port->unqualified_pointer;
1642           }
1643           break;
1644         case S_AUTO:
1645         case S_DATA:
1646         case S_REGISTER:
1647           DCL_TYPE (val->type) = POINTER;
1648           break;
1649         case S_CODE:
1650           DCL_TYPE (val->type) = CPOINTER;
1651           break;
1652         case S_XDATA:
1653           DCL_TYPE (val->type) = FPOINTER;
1654           break;
1655         case S_EEPROM:
1656           DCL_TYPE (val->type) = EEPPOINTER;
1657           break;
1658         default:
1659           DCL_TYPE (val->type) = port->unqualified_pointer;
1660         }
1661       
1662       /* is there is a symbol associated then */
1663       /* change the type of the symbol as well */
1664       if (val->sym)
1665         {
1666           val->sym->type = copyLinkChain (val->type);
1667           val->sym->etype = getSpec (val->sym->type);
1668         }
1669     }
1670   return val;
1671 }
1672 /*------------------------------------------------------------------*/
1673 /* checkFunction - does all kinds of check on a function            */
1674 /*------------------------------------------------------------------*/
1675 int 
1676 checkFunction (symbol * sym, symbol *csym)
1677 {
1678   value *exargs, *acargs;
1679   value *checkValue;
1680   int argCnt = 0;
1681
1682   if (getenv("DEBUG_SANITY")) {
1683     fprintf (stderr, "checkFunction: %s ", sym->name);
1684   }
1685
1686   /* make sure the type is complete and sane */
1687   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1688
1689   /* if not type then some kind of error */
1690   if (!sym->type)
1691     return 0;
1692
1693   /* if the function has no type then make it return int */
1694   if (!sym->type->next)
1695     sym->type->next = sym->etype = newIntLink ();
1696
1697   /* function cannot return aggregate */
1698   if (IS_AGGREGATE (sym->type->next))
1699     {
1700       werror (E_FUNC_AGGR, sym->name);
1701       return 0;
1702     }
1703
1704   /* function cannot return bit */
1705   if (IS_BITVAR (sym->type->next))
1706     {
1707       werror (E_FUNC_BIT, sym->name);
1708       return 0;
1709     }
1710
1711   /* check if this function is defined as calleeSaves
1712      then mark it as such */
1713   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1714
1715   /* if interrupt service routine  */
1716   /* then it cannot have arguments */
1717   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1718     {
1719       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1720         werror (E_INT_ARGS, sym->name);
1721         FUNC_ARGS(sym->type)=NULL;
1722       }
1723     }
1724
1725   for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
1726        acargs; 
1727        acargs=acargs->next, argCnt++) {
1728     if (!acargs->sym) { 
1729       // this can happen for reentrant functions
1730       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1731       // the show must go on: synthesize a name and symbol
1732       SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
1733       acargs->sym = newSymbol (acargs->name, 1);
1734       SPEC_OCLS (acargs->etype) = istack;
1735       acargs->sym->type = copyLinkChain (acargs->type);
1736       acargs->sym->etype = getSpec (acargs->sym->type);
1737       acargs->sym->_isparm = 1;
1738       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
1739     } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
1740       // synthesized name
1741       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
1742     }
1743   }
1744
1745   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1746     return 1;                   /* not defined nothing more to check  */
1747
1748   /* check if body already present */
1749   if (csym && IFFUNC_HASBODY(csym->type))
1750     {
1751       werror (E_FUNC_BODY, sym->name);
1752       return 0;
1753     }
1754
1755   /* check the return value type   */
1756   if (compareType (csym->type, sym->type) <= 0)
1757     {
1758       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1759       printFromToType(csym->type, sym->type);
1760       return 0;
1761     }
1762
1763   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1764     {
1765       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1766     }
1767
1768   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1769     {
1770       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1771     }
1772
1773   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1774     {
1775       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1776     }
1777
1778   /* compare expected args with actual args */
1779   exargs = FUNC_ARGS(csym->type);
1780   acargs = FUNC_ARGS(sym->type);
1781
1782   /* for all the expected args do */
1783   for (argCnt = 1;
1784        exargs && acargs;
1785        exargs = exargs->next, acargs = acargs->next, argCnt++)
1786     {
1787       if (getenv("DEBUG_SANITY")) {
1788         fprintf (stderr, "checkFunction: %s ", exargs->name);
1789       }
1790       /* make sure the type is complete and sane */
1791       checkTypeSanity(exargs->etype, exargs->name);
1792
1793       /* If the actual argument is an array, any prototype
1794        * will have modified it to a pointer. Duplicate that
1795        * change here.
1796        */
1797       if (IS_AGGREGATE (acargs->type))
1798         {
1799           checkValue = copyValue (acargs);
1800           aggregateToPointer (checkValue);
1801         }
1802       else
1803         {
1804           checkValue = acargs;
1805         }
1806
1807       if (compareType (exargs->type, checkValue->type) <= 0)
1808         {
1809           werror (E_ARG_TYPE, argCnt);
1810           printFromToType(exargs->type, checkValue->type);
1811           return 0;
1812         }
1813     }
1814
1815   /* if one them ended we have a problem */
1816   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1817       (!exargs && acargs && !IS_VOID (acargs->type)))
1818     werror (E_ARG_COUNT);
1819
1820   /* replace with this defition */
1821   sym->cdef = csym->cdef;
1822   deleteSym (SymbolTab, csym, csym->name);
1823   deleteFromSeg(csym);
1824   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1825   if (IS_EXTERN (csym->etype) && !
1826       IS_EXTERN (sym->etype))
1827     {
1828       addSet (&publics, sym);
1829     }
1830   return 1;
1831 }
1832
1833 /*------------------------------------------------------------------*/
1834 /* cdbStructBlock - calls struct printing for a blcks               */
1835 /*------------------------------------------------------------------*/
1836 void cdbStructBlock (int block)
1837 {
1838   int i;
1839   bucket **table = StructTab;
1840   bucket *chain;
1841
1842   /* go thru the entire  table  */
1843   for (i = 0; i < 256; i++)
1844     {
1845       for (chain = table[i]; chain; chain = chain->next)
1846         {
1847           if (chain->block >= block)
1848             {
1849               if(debugFile)
1850                 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
1851             }
1852         }
1853     }
1854 }
1855
1856 /*-----------------------------------------------------------------*/
1857 /* processFuncArgs - does some processing with function args       */
1858 /*-----------------------------------------------------------------*/
1859 void 
1860 processFuncArgs (symbol * func)
1861 {
1862   value *val;
1863   int pNum = 1;
1864   sym_link *funcType=func->type;
1865
1866   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1867     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1868
1869   // if this is a pointer to a function
1870   if (IS_PTR(funcType)) {
1871     funcType=funcType->next;
1872   }
1873
1874   /* if this function has variable argument list */
1875   /* then make the function a reentrant one    */
1876   if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
1877     FUNC_ISREENT(funcType)=1;
1878
1879   /* check if this function is defined as calleeSaves
1880      then mark it as such */
1881   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1882
1883   /* loop thru all the arguments   */
1884   val = FUNC_ARGS(funcType);
1885
1886   /* if it is void then remove parameters */
1887   if (val && IS_VOID (val->type))
1888     {
1889       FUNC_ARGS(funcType) = NULL;
1890       return;
1891     }
1892
1893   /* reset regparm for the port */
1894   (*port->reset_regparms) ();
1895   /* if any of the arguments is an aggregate */
1896   /* change it to pointer to the same type */
1897   while (val)
1898     {
1899         int argreg = 0;
1900       /* mark it as a register parameter if
1901          the function does not have VA_ARG
1902          and as port dictates */
1903       if (!IFFUNC_HASVARARGS(funcType) &&
1904           (argreg = (*port->reg_parm) (val->type)))
1905         {
1906           SPEC_REGPARM (val->etype) = 1;
1907           SPEC_ARGREG(val->etype) = argreg;
1908         } else if (IFFUNC_ISREENT(funcType)) {
1909             FUNC_HASSTACKPARM(funcType) = 1;
1910         }
1911
1912       if (IS_AGGREGATE (val->type))
1913         {
1914           aggregateToPointer (val);
1915         }
1916
1917       val = val->next;
1918       pNum++;
1919     }
1920
1921   /* if this is an internal generated function call */
1922   if (func->cdef) {
1923     /* ignore --stack-auto for this one, we don't know how it is compiled */
1924     /* simply trust on --int-long-reent or --float-reent */
1925     if (IFFUNC_ISREENT(funcType)) {
1926       return;
1927     }
1928   } else {
1929     /* if this function is reentrant or */
1930     /* automatics r 2b stacked then nothing */
1931     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1932       return;
1933   }
1934
1935   val = FUNC_ARGS(funcType);
1936   pNum = 1;
1937   while (val)
1938     {
1939
1940       /* if a symbolname is not given  */
1941       /* synthesize a variable name */
1942       if (!val->sym)
1943         {
1944           SNPRINTF (val->name, sizeof(val->name), 
1945                     "_%s_PARM_%d", func->name, pNum++);
1946           val->sym = newSymbol (val->name, 1);
1947           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1948           val->sym->type = copyLinkChain (val->type);
1949           val->sym->etype = getSpec (val->sym->type);
1950           val->sym->_isparm = 1;
1951           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1952           if (IS_SPEC(func->etype)) {
1953             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1954               SPEC_STAT (func->etype);
1955           }
1956           addSymChain (val->sym);
1957
1958         }
1959       else                      /* symbol name given create synth name */
1960         {
1961
1962           SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
1963           strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
1964           val->sym->_isparm = 1;
1965           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1966             (options.model != MODEL_SMALL ? xdata : data);
1967           if (IS_SPEC(func->etype)) {
1968             SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1969               SPEC_STAT (func->etype);
1970           }
1971         }
1972       if (!isinSet(operKeyReset, val->sym)) {
1973         addSet (&operKeyReset, val->sym);
1974         applyToSet (operKeyReset, resetParmKey);
1975       }
1976       val = val->next;
1977     }
1978 }
1979
1980 /*-----------------------------------------------------------------*/
1981 /* isSymbolEqual - compares two symbols return 1 if they match     */
1982 /*-----------------------------------------------------------------*/
1983 int 
1984 isSymbolEqual (symbol * dest, symbol * src)
1985 {
1986   /* if pointers match then equal */
1987   if (dest == src)
1988     return 1;
1989
1990   /* if one of them is null then don't match */
1991   if (!dest || !src)
1992     return 0;
1993
1994   /* if both of them have rname match on rname */
1995   if (dest->rname[0] && src->rname[0])
1996     return (!strcmp (dest->rname, src->rname));
1997
1998   /* otherwise match on name */
1999   return (!strcmp (dest->name, src->name));
2000 }
2001
2002 void PT(sym_link *type)
2003 {
2004         printTypeChain(type,0);
2005 }
2006 /*-----------------------------------------------------------------*/
2007 /* printTypeChain - prints the type chain in human readable form   */
2008 /*-----------------------------------------------------------------*/
2009 void
2010 printTypeChain (sym_link * start, FILE * of)
2011 {
2012   int nlr = 0;
2013   value *args;
2014   sym_link * type, * search;
2015   STORAGE_CLASS scls;
2016
2017   if (!of)
2018     {
2019       of = stdout;
2020       nlr = 1;
2021     }
2022
2023   if (start==NULL) {
2024     fprintf (of, "void");
2025     return;
2026   }
2027
2028   /* Print the chain as it is written in the source: */
2029   /* start with the last entry.                      */
2030   /* However, the storage class at the end of the    */
2031   /* chain reall applies to the first in the chain!  */
2032
2033   for (type = start; type && type->next; type = type->next)
2034     ;
2035   if (IS_SPEC (type))
2036     scls=SPEC_SCLS(type);
2037   else
2038     scls=0;
2039   while (type)
2040     {
2041       if (type==start) {
2042         switch (scls) 
2043           {
2044           case S_DATA: fprintf (of, "data-"); break;
2045           case S_XDATA: fprintf (of, "xdata-"); break;
2046           case S_SFR: fprintf (of, "sfr-"); break;
2047           case S_SBIT: fprintf (of, "sbit-"); break;
2048           case S_CODE: fprintf (of, "code-"); break;
2049           case S_IDATA: fprintf (of, "idata-"); break;
2050           case S_PDATA: fprintf (of, "pdata-"); break;
2051           case S_LITERAL: fprintf (of, "literal-"); break;
2052           case S_STACK: fprintf (of, "stack-"); break;
2053           case S_XSTACK: fprintf (of, "xstack-"); break;
2054           case S_BIT: fprintf (of, "bit-"); break;
2055           case S_EEPROM: fprintf (of, "eeprom-"); break;
2056           default: break;
2057           }
2058       }
2059
2060       if (IS_DECL (type))
2061         {
2062           if (!IS_FUNC(type)) {
2063             if (DCL_PTR_VOLATILE (type)) {
2064               fprintf (of, "volatile-");
2065             }
2066             if (DCL_PTR_CONST (type)) {
2067               fprintf (of, "const-");
2068             }
2069           }
2070           switch (DCL_TYPE (type))
2071             {
2072             case FUNCTION:
2073               fprintf (of, "function %s %s", 
2074                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2075                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2076               fprintf (of, "( ");
2077               for (args = FUNC_ARGS(type); 
2078                    args; 
2079                    args=args->next) {
2080                 printTypeChain(args->type, of);
2081                 if (args->next)
2082                   fprintf(of, ", ");
2083               }
2084               fprintf (of, ") ");
2085               break;
2086             case GPOINTER:
2087               fprintf (of, "generic* ");
2088               break;
2089             case CPOINTER:
2090               fprintf (of, "code* ");
2091               break;
2092             case FPOINTER:
2093               fprintf (of, "xdata* ");
2094               break;
2095             case EEPPOINTER:
2096               fprintf (of, "eeprom* ");
2097               break;
2098             case POINTER:
2099               fprintf (of, "near* ");
2100               break;
2101             case IPOINTER:
2102               fprintf (of, "idata* ");
2103               break;
2104             case PPOINTER:
2105               fprintf (of, "pdata* ");
2106               break;
2107             case UPOINTER:
2108               fprintf (of, "unknown* ");
2109               break;
2110             case ARRAY:
2111               if (DCL_ELEM(type)) {
2112                 fprintf (of, "[%d] ", DCL_ELEM(type));
2113               } else {
2114                 fprintf (of, "[] ");
2115               }
2116               break;
2117             }
2118         }
2119       else
2120         {
2121           if (SPEC_VOLATILE (type))
2122             fprintf (of, "volatile-");
2123           if (SPEC_CONST (type))
2124             fprintf (of, "const-");
2125           if (SPEC_USIGN (type))
2126             fprintf (of, "unsigned-");
2127           switch (SPEC_NOUN (type))
2128             {
2129             case V_INT:
2130               if (IS_LONG (type))
2131                 fprintf (of, "long-");
2132               fprintf (of, "int");
2133               break;
2134
2135             case V_CHAR:
2136               fprintf (of, "char");
2137               break;
2138
2139             case V_VOID:
2140               fprintf (of, "void");
2141               break;
2142
2143             case V_FLOAT:
2144               fprintf (of, "float");
2145               break;
2146
2147             case V_STRUCT:
2148               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2149               break;
2150
2151             case V_SBIT:
2152               fprintf (of, "sbit");
2153               break;
2154
2155             case V_BIT:
2156               fprintf (of, "bit");
2157               break;
2158
2159             case V_BITFIELD:
2160               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2161               break;
2162
2163             case V_DOUBLE:
2164               fprintf (of, "double");
2165               break;
2166
2167             default:
2168               fprintf (of, "unknown type");
2169               break;
2170             }
2171         }
2172       /* search entry in list before "type" */
2173       for (search = start; search && search->next != type;)
2174         search = search->next;
2175       type = search;
2176       if (type)
2177         fputc (' ', of);
2178     }
2179   if (nlr)
2180     fprintf (of, "\n");
2181 }
2182
2183 /*--------------------------------------------------------------------*/
2184 /* printTypeChainRaw - prints the type chain in human readable form   */
2185 /*                     in the raw data structure ordering             */
2186 /*--------------------------------------------------------------------*/
2187 void
2188 printTypeChainRaw (sym_link * start, FILE * of)
2189 {
2190   int nlr = 0;
2191   value *args;
2192   sym_link * type;
2193
2194   if (!of)
2195     {
2196       of = stdout;
2197       nlr = 1;
2198     }
2199
2200   if (start==NULL) {
2201     fprintf (of, "void");
2202     return;
2203   }
2204
2205   type = start;
2206   
2207   while (type)
2208     {
2209       if (IS_DECL (type))
2210         {
2211           if (!IS_FUNC(type)) {
2212             if (DCL_PTR_VOLATILE (type)) {
2213               fprintf (of, "volatile-");
2214             }
2215             if (DCL_PTR_CONST (type)) {
2216               fprintf (of, "const-");
2217             }
2218           }
2219           switch (DCL_TYPE (type))
2220             {
2221             case FUNCTION:
2222               fprintf (of, "function %s %s", 
2223                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2224                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2225               fprintf (of, "( ");
2226               for (args = FUNC_ARGS(type); 
2227                    args; 
2228                    args=args->next) {
2229                 printTypeChain(args->type, of);
2230                 if (args->next)
2231                   fprintf(of, ", ");
2232               }
2233               fprintf (of, ") ");
2234               break;
2235             case GPOINTER:
2236               fprintf (of, "generic* ");
2237               break;
2238             case CPOINTER:
2239               fprintf (of, "code* ");
2240               break;
2241             case FPOINTER:
2242               fprintf (of, "xdata* ");
2243               break;
2244             case EEPPOINTER:
2245               fprintf (of, "eeprom* ");
2246               break;
2247             case POINTER:
2248               fprintf (of, "near* ");
2249               break;
2250             case IPOINTER:
2251               fprintf (of, "idata* ");
2252               break;
2253             case PPOINTER:
2254               fprintf (of, "pdata* ");
2255               break;
2256             case UPOINTER:
2257               fprintf (of, "unknown* ");
2258               break;
2259             case ARRAY:
2260               if (DCL_ELEM(type)) {
2261                 fprintf (of, "[%d] ", DCL_ELEM(type));
2262               } else {
2263                 fprintf (of, "[] ");
2264               }
2265               break;
2266             }
2267           if (DCL_TSPEC(type))
2268             {
2269               fprintf (of, "{");
2270               printTypeChainRaw(DCL_TSPEC(type), of);
2271               fprintf (of, "}");
2272             }
2273         }
2274       else if (IS_SPEC (type))
2275         {
2276         switch (SPEC_SCLS (type)) 
2277           {
2278           case S_DATA: fprintf (of, "data-"); break;
2279           case S_XDATA: fprintf (of, "xdata-"); break;
2280           case S_SFR: fprintf (of, "sfr-"); break;
2281           case S_SBIT: fprintf (of, "sbit-"); break;
2282           case S_CODE: fprintf (of, "code-"); break;
2283           case S_IDATA: fprintf (of, "idata-"); break;
2284           case S_PDATA: fprintf (of, "pdata-"); break;
2285           case S_LITERAL: fprintf (of, "literal-"); break;
2286           case S_STACK: fprintf (of, "stack-"); break;
2287           case S_XSTACK: fprintf (of, "xstack-"); break;
2288           case S_BIT: fprintf (of, "bit-"); break;
2289           case S_EEPROM: fprintf (of, "eeprom-"); break;
2290           default: break;
2291           }
2292           if (SPEC_VOLATILE (type))
2293             fprintf (of, "volatile-");
2294           if (SPEC_CONST (type))
2295             fprintf (of, "const-");
2296           if (SPEC_USIGN (type))
2297             fprintf (of, "unsigned-");
2298           switch (SPEC_NOUN (type))
2299             {
2300             case V_INT:
2301               if (IS_LONG (type))
2302                 fprintf (of, "long-");
2303               fprintf (of, "int");
2304               break;
2305
2306             case V_CHAR:
2307               fprintf (of, "char");
2308               break;
2309
2310             case V_VOID:
2311               fprintf (of, "void");
2312               break;
2313
2314             case V_FLOAT:
2315               fprintf (of, "float");
2316               break;
2317
2318             case V_STRUCT:
2319               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2320               break;
2321
2322             case V_SBIT:
2323               fprintf (of, "sbit");
2324               break;
2325
2326             case V_BIT:
2327               fprintf (of, "bit");
2328               break;
2329
2330             case V_BITFIELD:
2331               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2332               break;
2333
2334             case V_DOUBLE:
2335               fprintf (of, "double");
2336               break;
2337
2338             default:
2339               fprintf (of, "unknown type");
2340               break;
2341             }
2342         }
2343       else
2344         fprintf (of, "NOT_SPEC_OR_DECL");
2345       type = type->next;
2346       if (type)
2347         fputc (' ', of);
2348     }
2349   if (nlr)
2350     fprintf (of, "\n");
2351 }
2352
2353
2354 /*-----------------------------------------------------------------*/
2355 /* powof2 - returns power of two for the number if number is pow 2 */
2356 /*-----------------------------------------------------------------*/
2357 int 
2358 powof2 (unsigned long num)
2359 {
2360   int nshifts = 0;
2361   int n1s = 0;
2362
2363   while (num)
2364     {
2365       if (num & 1)
2366         n1s++;
2367       num >>= 1;
2368       nshifts++;
2369     }
2370
2371   if (n1s > 1 || nshifts == 0)
2372     return 0;
2373   return nshifts - 1;
2374 }
2375
2376 symbol *__fsadd;
2377 symbol *__fssub;
2378 symbol *__fsmul;
2379 symbol *__fsdiv;
2380 symbol *__fseq;
2381 symbol *__fsneq;
2382 symbol *__fslt;
2383 symbol *__fslteq;
2384 symbol *__fsgt;
2385 symbol *__fsgteq;
2386
2387 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2388 symbol *__muldiv[3][3][2];
2389 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2390 sym_link *__multypes[3][2];
2391 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2392 symbol *__conv[2][3][2];
2393 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2394 symbol *__rlrr[2][3][2];
2395
2396 sym_link *floatType;
2397
2398 static char *
2399 _mangleFunctionName(char *in)
2400 {
2401   if (port->getMangledFunctionName) 
2402     {
2403       return port->getMangledFunctionName(in);
2404     }
2405   else
2406     {
2407       return in;
2408     }
2409 }
2410
2411 /*-----------------------------------------------------------------*/
2412 /* typeFromStr - create a typechain from an encoded string         */
2413 /* basic types -        'c' - char                                 */
2414 /*                      's' - short                                */
2415 /*                      'i' - int                                  */
2416 /*                      'l' - long                                 */
2417 /*                      'f' - float                                */
2418 /*                      'v' - void                                 */
2419 /*                      '*' - pointer - default (GPOINTER)         */
2420 /* modifiers -          'u' - unsigned                             */
2421 /* pointer modifiers -  'g' - generic                              */
2422 /*                      'x' - xdata                                */
2423 /*                      'p' - code                                 */
2424 /*                      'd' - data                                 */                     
2425 /*                      'F' - function                             */                     
2426 /* examples : "ig*" - generic int *                                */
2427 /*            "cx*" - char xdata *                                 */
2428 /*            "ui" -  unsigned int                                 */
2429 /*-----------------------------------------------------------------*/
2430 sym_link *typeFromStr (char *s)
2431 {
2432     sym_link *r = newLink(DECLARATOR);
2433     int usign = 0;
2434
2435     do {
2436         sym_link *nr;
2437         switch (*s) {
2438         case 'u' : 
2439             usign = 1;
2440             s++;
2441             continue ;
2442             break ;
2443         case 'c':
2444             r->class = SPECIFIER;
2445             SPEC_NOUN(r) = V_CHAR;
2446             break;
2447         case 's':
2448         case 'i':
2449             r->class = SPECIFIER;
2450             SPEC_NOUN(r) = V_INT;
2451             break;
2452         case 'l':
2453             r->class = SPECIFIER;
2454             SPEC_NOUN(r) = V_INT;
2455             SPEC_LONG(r) = 1;
2456             break;
2457         case 'f':
2458             r->class = SPECIFIER;
2459             SPEC_NOUN(r) = V_FLOAT;
2460             break;
2461         case 'v':
2462             r->class = SPECIFIER;
2463             SPEC_NOUN(r) = V_VOID;
2464             break;
2465         case '*':
2466             DCL_TYPE(r) = port->unqualified_pointer;
2467             break;
2468         case 'g':
2469         case 'x':
2470         case 'p':
2471         case 'd':
2472         case 'F':
2473             assert(*(s+1)=='*');
2474             nr = newLink(DECLARATOR);
2475             nr->next = r;
2476             r = nr;
2477             switch (*s) {
2478             case 'g':
2479                 DCL_TYPE(r) = GPOINTER;
2480                 break;
2481             case 'x':
2482                 DCL_TYPE(r) = FPOINTER;
2483                 break;
2484             case 'p':
2485                 DCL_TYPE(r) = CPOINTER;
2486                 break;
2487             case 'd':
2488                 DCL_TYPE(r) = POINTER;
2489                 break;
2490             case 'F':
2491                 DCL_TYPE(r) = FUNCTION;
2492                 nr = newLink(DECLARATOR);
2493                 nr->next = r;
2494                 r = nr;
2495                 DCL_TYPE(r) = CPOINTER;
2496                 break;
2497             }
2498             s++;
2499             break;
2500         default:
2501             werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
2502                    "typeFromStr: unknown type");
2503             break;
2504         }
2505         if (IS_SPEC(r) && usign) {
2506             SPEC_USIGN(r) = 1;
2507             usign = 0;
2508         }
2509         s++;
2510     } while (*s);
2511     return r;
2512 }
2513
2514 /*-----------------------------------------------------------------*/
2515 /* initCSupport - create functions for C support routines          */
2516 /*-----------------------------------------------------------------*/
2517 void 
2518 initCSupport ()
2519 {
2520   const char *smuldivmod[] =
2521   {
2522     "mul", "div", "mod"
2523   };
2524   const char *sbwd[] =
2525   {
2526     "char", "int", "long"
2527   };
2528   const char *ssu[] =
2529   {
2530     "s", "u"
2531   };
2532   const char *srlrr[] =
2533   {
2534     "rl", "rr"
2535   };
2536
2537   int bwd, su, muldivmod, tofrom, rlrr;
2538
2539   if (getenv("SDCC_NO_C_SUPPORT")) {
2540     /* for debugging only */
2541     return;
2542   }
2543
2544   floatType = newFloatLink ();
2545
2546   for (bwd = 0; bwd < 3; bwd++)
2547     {
2548       sym_link *l = NULL;
2549       switch (bwd)
2550         {
2551         case 0:
2552           l = newCharLink ();
2553           break;
2554         case 1:
2555           l = newIntLink ();
2556           break;
2557         case 2:
2558           l = newLongLink ();
2559           break;
2560         default:
2561           assert (0);
2562         }
2563       __multypes[bwd][0] = l;
2564       __multypes[bwd][1] = copyLinkChain (l);
2565       SPEC_USIGN (__multypes[bwd][1]) = 1;
2566     }
2567
2568   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2569   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2570   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2571   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2572   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2573   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2574   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2575   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2576   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2577   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2578
2579   for (tofrom = 0; tofrom < 2; tofrom++)
2580     {
2581       for (bwd = 0; bwd < 3; bwd++)
2582         {
2583           for (su = 0; su < 2; su++)
2584             {
2585               if (tofrom)
2586                 {
2587                   SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
2588                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2589                 }
2590               else
2591                 {
2592                   SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
2593                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2594                 }
2595             }
2596         }
2597     }
2598
2599 /*
2600   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2601     {
2602       for (bwd = 0; bwd < 3; bwd++)
2603         {
2604           for (su = 0; su < 2; su++)
2605             {
2606               SNPRINTF (buffer, sizeof(buffer),
2607                         "_%s%s%s",
2608                        smuldivmod[muldivmod],
2609                        ssu[su],
2610                        sbwd[bwd]);
2611               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2612               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2613             }
2614         }
2615     }
2616
2617   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
2618   Therefore they've been merged into mulint() and mullong().
2619 */
2620
2621   for (bwd = 0; bwd < 3; bwd++)
2622     {
2623       for (su = 0; su < 2; su++)
2624         {
2625           for (muldivmod = 1; muldivmod < 3; muldivmod++)
2626             {
2627               /* div and mod */
2628               SNPRINTF (buffer, sizeof(buffer),
2629                         "_%s%s%s",
2630                        smuldivmod[muldivmod],
2631                        ssu[su],
2632                        sbwd[bwd]);
2633               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2634               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2635             }
2636         }
2637     }
2638   /* mul only */
2639   muldivmod = 0;
2640   /* byte */
2641   bwd = 0;
2642   for (su = 0; su < 2; su++)
2643     {
2644       /* muluchar and mulschar are still separate functions, because e.g. the z80
2645          port is sign/zero-extending to int before calling mulint() */
2646       SNPRINTF (buffer, sizeof(buffer),
2647                 "_%s%s%s",
2648                 smuldivmod[muldivmod],
2649                 ssu[su],
2650                 sbwd[bwd]);
2651       __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2652       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2653     }
2654   /* signed only */
2655   su = 0;
2656   /* word and doubleword */
2657   for (bwd = 1; bwd < 3; bwd++)
2658     {
2659       /* mul, int/long */
2660       SNPRINTF (buffer, sizeof(buffer),
2661                 "_%s%s",
2662                 smuldivmod[muldivmod],
2663                 sbwd[bwd]);
2664       __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2665       FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
2666       /* signed = unsigned */
2667       __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
2668     }
2669
2670   for (rlrr = 0; rlrr < 2; rlrr++)
2671     {
2672       for (bwd = 0; bwd < 3; bwd++)
2673         {
2674           for (su = 0; su < 2; su++)
2675             {
2676               SNPRINTF (buffer, sizeof(buffer),
2677                         "_%s%s%s",
2678                        srlrr[rlrr],
2679                        ssu[su],
2680                        sbwd[bwd]);
2681               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2682               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2683             }
2684         }
2685     }
2686 }
2687
2688 /*-----------------------------------------------------------------*/
2689 /* initBuiltIns - create prototypes for builtin functions          */
2690 /*-----------------------------------------------------------------*/
2691 void initBuiltIns()
2692 {
2693     int i;
2694     symbol *sym;
2695
2696     if (!port->builtintable) return ;
2697
2698     for (i = 0 ; port->builtintable[i].name ; i++) {
2699         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2700                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2701         FUNC_ISBUILTIN(sym->type) = 1;
2702         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2703     }
2704 }
2705
2706 sym_link *validateLink(sym_link         *l, 
2707                         const char      *macro,
2708                         const char      *args,
2709                         const char      select,
2710                         const char      *file, 
2711                         unsigned        line)
2712 {    
2713   if (l && l->class==select)
2714     {
2715         return l;
2716     }
2717     fprintf(stderr, 
2718             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
2719             " expected %s, got %s\n",
2720             macro, args, file, line, 
2721             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
2722     exit(-1);
2723     return l; // never reached, makes compiler happy.
2724 }