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