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