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