If a variable/function is declared as extern then declared in a file then delete
[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           deleteFromSeg(csym);
994         } else {
995           /* not extern */
996           werror (E_DUPLICATE, sym->name);
997           continue;
998         }
999       }
1000
1001       /* add new entry */
1002       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1003     }
1004 }
1005
1006
1007 /*------------------------------------------------------------------*/
1008 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1009 /*------------------------------------------------------------------*/
1010 int 
1011 funcInChain (sym_link * lnk)
1012 {
1013   while (lnk)
1014     {
1015       if (IS_FUNC (lnk))
1016         return 1;
1017       lnk = lnk->next;
1018     }
1019   return 0;
1020 }
1021
1022 /*------------------------------------------------------------------*/
1023 /* structElemType - returns the type info of a sturct member        */
1024 /*------------------------------------------------------------------*/
1025 sym_link *
1026 structElemType (sym_link * stype, value * id)
1027 {
1028   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1029   sym_link *type, *etype;
1030   sym_link *petype = getSpec (stype);
1031
1032   if (!fields || !id)
1033     return NULL;
1034
1035   /* look for the id */
1036   while (fields)
1037     {
1038       if (strcmp (fields->rname, id->name) == 0)
1039         {
1040           type = copyLinkChain (fields->type);
1041           etype = getSpec (type);
1042           SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1043                                SPEC_SCLS (etype) : SPEC_SCLS (petype));
1044           return type;
1045         }
1046       fields = fields->next;
1047     }
1048   werror (E_NOT_MEMBER, id->name);
1049
1050   return NULL;
1051 }
1052
1053 /*------------------------------------------------------------------*/
1054 /* getStructElement - returns element of a tructure definition      */
1055 /*------------------------------------------------------------------*/
1056 symbol *
1057 getStructElement (structdef * sdef, symbol * sym)
1058 {
1059   symbol *field;
1060
1061   for (field = sdef->fields; field; field = field->next)
1062     if (strcmp (field->name, sym->name) == 0)
1063       return field;
1064
1065   werror (E_NOT_MEMBER, sym->name);
1066
1067   return sdef->fields;
1068 }
1069
1070 /*------------------------------------------------------------------*/
1071 /* compStructSize - computes the size of a structure                */
1072 /*------------------------------------------------------------------*/
1073 int 
1074 compStructSize (int su, structdef * sdef)
1075 {
1076     int sum = 0, usum = 0;
1077     int bitOffset = 0;
1078     symbol *loop;
1079
1080     /* for the identifiers  */
1081     loop = sdef->fields;
1082     while (loop) {
1083
1084         /* create the internal name for this variable */
1085         sprintf (loop->rname, "_%s", loop->name);
1086         loop->offset = (su == UNION ? sum = 0 : sum);
1087         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1088
1089         /* if this is a bit field  */
1090         if (loop->bitVar) {
1091
1092             /* change it to a unsigned bit */
1093             SPEC_NOUN (loop->etype) = V_BIT;
1094             SPEC_USIGN (loop->etype) = 1;
1095             /* check if this fit into the remaining   */
1096             /* bits of this byte else align it to the */
1097             /* next byte boundary                     */
1098             if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
1099                 SPEC_BSTR (loop->etype) = bitOffset;
1100                 if ((bitOffset += (loop->bitVar % 8)) == 8)
1101                     sum++;
1102             }
1103             else /* does not fit */ {
1104                 bitOffset = 0;
1105                 SPEC_BSTR (loop->etype) = bitOffset;
1106                 sum += (loop->bitVar / 8);
1107                 bitOffset += (loop->bitVar % 8);
1108             }
1109             /* if this is the last field then pad */
1110             if (!loop->next && bitOffset && bitOffset != 8) {
1111                 bitOffset = 0;
1112                 sum++;
1113             }
1114         }
1115         else {
1116             checkDecl (loop, 1);
1117             sum += getSize (loop->type);
1118         }
1119
1120 #if 0 // jwk: this is done now in addDecl()
1121         /* if function then do the arguments for it */
1122         if (funcInChain (loop->type)) {
1123             processFuncArgs (loop);
1124         }
1125 #endif
1126
1127         loop = loop->next;
1128
1129         /* if this is not a bitfield but the */
1130         /* previous one was and did not take */
1131         /* the whole byte then pad the rest  */
1132         if ((loop && !loop->bitVar) && bitOffset) {
1133             bitOffset = 0;
1134             sum++;
1135         }
1136
1137         /* if union then size = sizeof larget field */
1138         if (su == UNION)
1139             usum = max (usum, sum);
1140
1141     }
1142
1143     return (su == UNION ? usum : sum);
1144 }
1145
1146 /*------------------------------------------------------------------*/
1147 /* checkSClass - check the storage class specification              */
1148 /*------------------------------------------------------------------*/
1149 static void 
1150 checkSClass (symbol * sym, int isProto)
1151 {
1152   if (getenv("DEBUG_SANITY")) {
1153     fprintf (stderr, "checkSClass: %s \n", sym->name);
1154   }
1155   
1156   /* type is literal can happen foe enums change
1157      to auto */
1158   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1159     SPEC_SCLS (sym->etype) = S_AUTO;
1160   
1161   /* if sfr or sbit then must also be */
1162   /* volatile the initial value will be xlated */
1163   /* to an absolute address */
1164   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1165       SPEC_SCLS (sym->etype) == S_SFR)
1166     {
1167       SPEC_VOLATILE (sym->etype) = 1;
1168       /* if initial value given */
1169       if (sym->ival)
1170         {
1171           SPEC_ABSA (sym->etype) = 1;
1172           SPEC_ADDR (sym->etype) =
1173             (int) list2int (sym->ival);
1174           sym->ival = NULL;
1175         }
1176     }
1177   
1178   /* if absolute address given then it mark it as
1179      volatile */
1180   if (IS_ABSOLUTE (sym->etype))
1181     SPEC_VOLATILE (sym->etype) = 1;
1182   
1183   /* global variables declared const put into code */
1184   if (sym->level == 0 &&
1185       SPEC_CONST (sym->etype)) {
1186     SPEC_SCLS (sym->etype) = S_CODE;
1187   }
1188   
1189   /* global variable in code space is a constant */
1190   if (sym->level == 0 &&
1191       SPEC_SCLS (sym->etype) == S_CODE &&
1192       port->mem.code_ro)
1193     SPEC_CONST (sym->etype) = 1;
1194   
1195
1196   /* if bit variable then no storage class can be */
1197   /* specified since bit is already a storage */
1198   if (IS_BITVAR (sym->etype) &&
1199       (SPEC_SCLS (sym->etype) != S_FIXED &&
1200        SPEC_SCLS (sym->etype) != S_SBIT &&
1201        SPEC_SCLS (sym->etype) != S_BIT)
1202     )
1203     {
1204       werror (E_BITVAR_STORAGE, sym->name);
1205       SPEC_SCLS (sym->etype) = S_FIXED;
1206     }
1207
1208   /* extern variables cannot be initialized */
1209   if (IS_EXTERN (sym->etype) && sym->ival)
1210     {
1211       werror (E_EXTERN_INIT, sym->name);
1212       sym->ival = NULL;
1213     }
1214
1215   /* if this is an atomatic symbol */
1216   if (sym->level && (options.stackAuto || reentrant)) {
1217     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1218          SPEC_SCLS (sym->etype) == S_FIXED ||
1219          SPEC_SCLS (sym->etype) == S_REGISTER ||
1220          SPEC_SCLS (sym->etype) == S_STACK ||
1221          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1222       SPEC_SCLS (sym->etype) = S_AUTO;
1223     } else {
1224       /* storage class may only be specified for statics */
1225       if (!IS_STATIC(sym->etype)) {
1226         werror (E_AUTO_ASSUMED, sym->name);
1227       }
1228     }
1229   }
1230   
1231   /* automatic symbols cannot be given   */
1232   /* an absolute address ignore it      */
1233   if (sym->level &&
1234       SPEC_ABSA (sym->etype) &&
1235       (options.stackAuto || reentrant))
1236     {
1237       werror (E_AUTO_ABSA, sym->name);
1238       SPEC_ABSA (sym->etype) = 0;
1239     }
1240
1241   /* arrays & pointers cannot be defined for bits   */
1242   /* SBITS or SFRs or BIT                           */
1243   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1244       (SPEC_NOUN (sym->etype) == V_BIT ||
1245        SPEC_NOUN (sym->etype) == V_SBIT ||
1246        SPEC_SCLS (sym->etype) == S_SFR))
1247     werror (E_BIT_ARRAY, sym->name);
1248
1249   /* if this is a bit|sbit then set length & start  */
1250   if (SPEC_NOUN (sym->etype) == V_BIT ||
1251       SPEC_NOUN (sym->etype) == V_SBIT)
1252     {
1253       SPEC_BLEN (sym->etype) = 1;
1254       SPEC_BSTR (sym->etype) = 0;
1255     }
1256
1257   if (!isProto) {
1258     /* variables declared in CODE space must have */
1259     /* initializers if not an extern */
1260     if (SPEC_SCLS (sym->etype) == S_CODE &&
1261         sym->ival == NULL &&
1262         //!sym->level &&
1263         port->mem.code_ro &&
1264         !IS_EXTERN (sym->etype) &&
1265         !funcInChain (sym->type))
1266       werror (E_CODE_NO_INIT, sym->name);
1267   }
1268
1269   /* if parameter or local variable then change */
1270   /* the storage class to reflect where the var will go */
1271   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1272       !IS_STATIC(sym->etype))
1273     {
1274       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1275         {
1276           SPEC_SCLS (sym->etype) = (options.useXstack ?
1277                                     S_XSTACK : S_STACK);
1278         }
1279       else
1280         {
1281           /* hack-o-matic! I see no reason why the useXstack option should ever
1282            * control this allcoation, but the code was originally that way, and
1283            * changing it for non-390 ports breaks the compiler badly.
1284            */
1285           bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1286           SPEC_SCLS (sym->etype) = (useXdata ?
1287                                     S_XDATA : S_FIXED);
1288         }
1289     }
1290 }
1291
1292 /*------------------------------------------------------------------*/
1293 /* changePointer - change pointer to functions                      */
1294 /*------------------------------------------------------------------*/
1295 void 
1296 changePointer (symbol * sym)
1297 {
1298   sym_link *p;
1299
1300   /* go thru the chain of declarations   */
1301   /* if we find a pointer to a function  */
1302   /* unconditionally change it to a ptr  */
1303   /* to code area                        */
1304   for (p = sym->type; p; p = p->next)
1305     {
1306       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1307         DCL_TYPE (p) = port->unqualified_pointer;
1308       if (IS_PTR (p) && IS_FUNC (p->next))
1309         DCL_TYPE (p) = CPOINTER;
1310     }
1311 }
1312
1313 /*------------------------------------------------------------------*/
1314 /* checkDecl - does semantic validation of a declaration                   */
1315 /*------------------------------------------------------------------*/
1316 int 
1317 checkDecl (symbol * sym, int isProto)
1318 {
1319
1320   checkSClass (sym, isProto);           /* check the storage class      */
1321   changePointer (sym);          /* change pointers if required */
1322
1323   /* if this is an array without any dimension
1324      then update the dimension from the initial value */
1325   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1326     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1327
1328   return 0;
1329 }
1330
1331 /*------------------------------------------------------------------*/
1332 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1333 /*------------------------------------------------------------------*/
1334 sym_link *
1335 copyLinkChain (sym_link * p)
1336 {
1337   sym_link *head, *curr, *loop;
1338
1339   curr = p;
1340   head = loop = (curr ? newLink () : (void *) NULL);
1341   while (curr)
1342     {
1343       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1344       loop->next = (curr->next ? newLink () : (void *) NULL);
1345       loop = loop->next;
1346       curr = curr->next;
1347     }
1348
1349   return head;
1350 }
1351
1352
1353 /*------------------------------------------------------------------*/
1354 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1355 /*                symbols in the given block                        */
1356 /*------------------------------------------------------------------*/
1357 void 
1358 cleanUpBlock (bucket ** table, int block)
1359 {
1360   int i;
1361   bucket *chain;
1362
1363   /* go thru the entire  table  */
1364   for (i = 0; i < 256; i++)
1365     {
1366       for (chain = table[i]; chain; chain = chain->next)
1367         {
1368           if (chain->block >= block)
1369             {
1370               deleteSym (table, chain->sym, chain->name);
1371             }
1372         }
1373     }
1374 }
1375
1376 /*------------------------------------------------------------------*/
1377 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1378 /*                symbols in the given level                        */
1379 /*------------------------------------------------------------------*/
1380 void 
1381 cleanUpLevel (bucket ** table, int level)
1382 {
1383   int i;
1384   bucket *chain;
1385
1386   /* go thru the entire  table  */
1387   for (i = 0; i < 256; i++)
1388     {
1389       for (chain = table[i]; chain; chain = chain->next)
1390         {
1391           if (chain->level >= level)
1392             {
1393               deleteSym (table, chain->sym, chain->name);
1394             }
1395         }
1396     }
1397 }
1398
1399 /*------------------------------------------------------------------*/
1400 /* computeType - computes the resultant type from two types         */
1401 /*------------------------------------------------------------------*/
1402 sym_link *
1403 computeType (sym_link * type1, sym_link * type2)
1404 {
1405   sym_link *rType;
1406   sym_link *reType;
1407   sym_link *etype1 = getSpec (type1);
1408   sym_link *etype2 = getSpec (type2);
1409
1410   /* if one of them is a float then result is a float */
1411   /* here we assume that the types passed are okay */
1412   /* and can be cast to one another                */
1413   /* which ever is greater in size */
1414   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1415     rType = newFloatLink ();
1416   else
1417     /* if only one of them is a bit variable
1418        then the other one prevails */
1419   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1420     rType = copyLinkChain (type2);
1421   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1422     rType = copyLinkChain (type1);
1423   else
1424     /* if one of them is a pointer or array then that
1425        prevails */
1426   if (IS_PTR (type1) || IS_ARRAY (type1))
1427     rType = copyLinkChain (type1);
1428   else if (IS_PTR (type2) || IS_ARRAY (type2))
1429     rType = copyLinkChain (type2);
1430   else if (getSize (type1) > getSize (type2))
1431     rType = copyLinkChain (type1);
1432   else
1433     rType = copyLinkChain (type2);
1434
1435   reType = getSpec (rType);
1436
1437   /* if either of them unsigned but not val then make this unsigned */
1438   if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || 
1439        (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && 
1440       !IS_FLOAT (reType))
1441     SPEC_USIGN (reType) = 1;
1442   else
1443     SPEC_USIGN (reType) = 0;
1444   
1445   /* if result is a literal then make not so */
1446   if (IS_LITERAL (reType))
1447     SPEC_SCLS (reType) = S_REGISTER;
1448
1449   return rType;
1450 }
1451
1452 /*--------------------------------------------------------------------*/
1453 /* compareType - will do type check return 1 if match, -1 if castable */
1454 /*--------------------------------------------------------------------*/
1455 int 
1456 compareType (sym_link * dest, sym_link * src)
1457 {
1458   if (!dest && !src)
1459     return 1;
1460
1461   if (dest && !src)
1462     return 0;
1463
1464   if (src && !dest)
1465     return 0;
1466
1467   /* if dest is a declarator then */
1468   if (IS_DECL (dest))
1469     {
1470       if (IS_DECL (src))
1471         {
1472           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1473             if (IS_FUNC(src)) {
1474               //checkFunction(src,dest);
1475             }
1476             return compareType (dest->next, src->next);
1477           }
1478           if (IS_PTR (src) && IS_GENPTR (dest))
1479             return -1;
1480           if (IS_PTR (dest) && IS_ARRAY (src)) {
1481             value *val=aggregateToPointer (valFromType(src));
1482             int res=compareType (dest, val->type);
1483             Safe_free(val->type);
1484             Safe_free(val);
1485             //return res ? -1 : 0;
1486             return res;
1487           }
1488           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1489             return compareType (dest->next, src);
1490           return 0;
1491         }
1492       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1493         return -1;
1494       else
1495         return 0;
1496     }
1497
1498   /* if one is a specifier and the other is not */
1499   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1500       (IS_SPEC (dest) && !IS_SPEC (src)))
1501     return 0;
1502
1503   /* if one of them is a void then ok */
1504   if (SPEC_NOUN (dest) == V_VOID &&
1505       SPEC_NOUN (src) != V_VOID)
1506     return -1;
1507
1508   if (SPEC_NOUN (dest) != V_VOID &&
1509       SPEC_NOUN (src) == V_VOID)
1510     return -1;
1511
1512   /* if they are both bitfields then if the lengths
1513      and starts don't match */
1514   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1515       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1516        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1517     return -1;
1518
1519   /* it is a specifier */
1520   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1521     {
1522       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1523           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1524           getSize (dest) == getSize (src))
1525         return 1;
1526       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1527         return -1;
1528       else
1529         return 0;
1530     }
1531   else if (IS_STRUCT (dest))
1532     {
1533       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1534         return 0;
1535       else
1536         return 1;
1537     }
1538   if (SPEC_LONG (dest) != SPEC_LONG (src))
1539     return -1;
1540
1541   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1542     return -1;
1543
1544   return 1;
1545 }
1546
1547 /*------------------------------------------------------------------*/
1548 /* inCalleeSaveList - return 1 if found in callee save list          */
1549 /*------------------------------------------------------------------*/
1550 bool 
1551 inCalleeSaveList (char *s)
1552 {
1553   int i;
1554
1555   if (options.all_callee_saves) return 1;
1556   for (i = 0; options.calleeSaves[i]; i++)
1557     if (strcmp (options.calleeSaves[i], s) == 0)
1558       return 1;
1559
1560   return 0;
1561 }
1562
1563 /*-----------------------------------------------------------------*/
1564 /* aggregateToPointer:  change an agggregate type function      */
1565 /*         argument to a pointer to that type.     */
1566 /*-----------------------------------------------------------------*/
1567 value *
1568 aggregateToPointer (value * val)
1569 {
1570   if (IS_AGGREGATE (val->type))
1571     {
1572       /* if this is a structure */
1573       /* then we need to add a new link */
1574       if (IS_STRUCT (val->type))
1575         {
1576           /* first lets add DECLARATOR type */
1577           sym_link *p = val->type;
1578
1579           werror (W_STRUCT_AS_ARG, val->name);
1580           val->type = newLink ();
1581           val->type->next = p;
1582         }
1583
1584       /* change to a pointer depending on the */
1585       /* storage class specified        */
1586       switch (SPEC_SCLS (val->etype))
1587         {
1588         case S_IDATA:
1589           DCL_TYPE (val->type) = IPOINTER;
1590           break;
1591         case S_PDATA:
1592           DCL_TYPE (val->type) = PPOINTER;
1593           break;
1594         case S_FIXED:
1595           if (SPEC_OCLS(val->etype)) {
1596             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1597           } else {
1598 #if 1
1599             // this happens for (external) function parameters
1600             DCL_TYPE (val->type) = port->unqualified_pointer;
1601 #else
1602             if (TARGET_IS_DS390) {
1603               /* The AUTO and REGISTER classes should probably
1604                * also become generic pointers, but I haven't yet
1605                * devised a test case for that.
1606                */
1607               DCL_TYPE (val->type) = port->unqualified_pointer;
1608               break;
1609             }
1610             if (options.model==MODEL_LARGE) {
1611               DCL_TYPE (val->type) = FPOINTER;
1612               break;
1613             }
1614 #endif
1615           }
1616           break;
1617         case S_AUTO:
1618         case S_DATA:
1619         case S_REGISTER:
1620           DCL_TYPE (val->type) = POINTER;
1621           break;
1622         case S_CODE:
1623           DCL_TYPE (val->type) = CPOINTER;
1624           break;
1625         case S_XDATA:
1626           DCL_TYPE (val->type) = FPOINTER;
1627           break;
1628         case S_EEPROM:
1629           DCL_TYPE (val->type) = EEPPOINTER;
1630           break;
1631         default:
1632           DCL_TYPE (val->type) = port->unqualified_pointer;
1633         }
1634       
1635       /* is there is a symbol associated then */
1636       /* change the type of the symbol as well */
1637       if (val->sym)
1638         {
1639           val->sym->type = copyLinkChain (val->type);
1640           val->sym->etype = getSpec (val->sym->type);
1641         }
1642     }
1643   return val;
1644 }
1645 /*------------------------------------------------------------------*/
1646 /* checkFunction - does all kinds of check on a function            */
1647 /*------------------------------------------------------------------*/
1648 int 
1649 checkFunction (symbol * sym, symbol *csym)
1650 {
1651   value *exargs, *acargs;
1652   value *checkValue;
1653   int argCnt = 0;
1654
1655   if (getenv("DEBUG_SANITY")) {
1656     fprintf (stderr, "checkFunction: %s ", sym->name);
1657   }
1658
1659   /* make sure the type is complete and sane */
1660   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1661
1662   /* if not type then some kind of error */
1663   if (!sym->type)
1664     return 0;
1665
1666   /* if the function has no type then make it return int */
1667   if (!sym->type->next)
1668     sym->type->next = sym->etype = newIntLink ();
1669
1670   /* function cannot return aggregate */
1671   if (IS_AGGREGATE (sym->type->next))
1672     {
1673       werror (E_FUNC_AGGR, sym->name);
1674       return 0;
1675     }
1676
1677   /* function cannot return bit */
1678   if (IS_BITVAR (sym->type->next))
1679     {
1680       werror (E_FUNC_BIT, sym->name);
1681       return 0;
1682     }
1683
1684   /* check if this function is defined as calleeSaves
1685      then mark it as such */
1686     FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1687
1688   /* if interrupt service routine  */
1689   /* then it cannot have arguments */
1690   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1691     {
1692       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1693         werror (E_INT_ARGS, sym->name);
1694         FUNC_ARGS(sym->type)=NULL;
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))
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       /* mark it as a register parameter if
1830          the function does not have VA_ARG
1831          and as port dictates */
1832       if (!IFFUNC_HASVARARGS(funcType) &&
1833           (*port->reg_parm) (val->type))
1834         {
1835           SPEC_REGPARM (val->etype) = 1;
1836         }
1837
1838       if (IS_AGGREGATE (val->type))
1839         {
1840           aggregateToPointer (val);
1841         }
1842
1843       val = val->next;
1844       pNum++;
1845     }
1846
1847   /* if this is an internal generated function call */
1848   if (func->cdef) {
1849     /* ignore --stack-auto for this one, we don't know how it is compiled */
1850     /* simply trust on --int-long-reent or --float-reent */
1851     if (IFFUNC_ISREENT(funcType)) {
1852       return;
1853     }
1854   } else {
1855     /* if this function is reentrant or */
1856     /* automatics r 2b stacked then nothing */
1857     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1858       return;
1859   }
1860
1861   val = FUNC_ARGS(funcType);
1862   pNum = 1;
1863   while (val)
1864     {
1865
1866       /* if a symbolname is not given  */
1867       /* synthesize a variable name */
1868       if (!val->sym)
1869         {
1870
1871           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1872           val->sym = newSymbol (val->name, 1);
1873           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1874           val->sym->type = copyLinkChain (val->type);
1875           val->sym->etype = getSpec (val->sym->type);
1876           val->sym->_isparm = 1;
1877           strcpy (val->sym->rname, val->name);
1878           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1879             SPEC_STAT (func->etype);
1880           addSymChain (val->sym);
1881
1882         }
1883       else                      /* symbol name given create synth name */
1884         {
1885
1886           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1887           strcpy (val->sym->rname, val->name);
1888           val->sym->_isparm = 1;
1889           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1890             (options.model != MODEL_SMALL ? xdata : data);
1891           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1892             SPEC_STAT (func->etype);
1893         }
1894       val = val->next;
1895     }
1896 }
1897
1898 /*-----------------------------------------------------------------*/
1899 /* isSymbolEqual - compares two symbols return 1 if they match     */
1900 /*-----------------------------------------------------------------*/
1901 int 
1902 isSymbolEqual (symbol * dest, symbol * src)
1903 {
1904   /* if pointers match then equal */
1905   if (dest == src)
1906     return 1;
1907
1908   /* if one of them is null then don't match */
1909   if (!dest || !src)
1910     return 0;
1911
1912   /* if both of them have rname match on rname */
1913   if (dest->rname[0] && src->rname[0])
1914     return (!strcmp (dest->rname, src->rname));
1915
1916   /* otherwise match on name */
1917   return (!strcmp (dest->name, src->name));
1918 }
1919
1920 void PT(sym_link *type)
1921 {
1922         printTypeChain(type,0);
1923 }
1924 /*-----------------------------------------------------------------*/
1925 /* printTypeChain - prints the type chain in human readable form   */
1926 /*-----------------------------------------------------------------*/
1927 void
1928 printTypeChain (sym_link * start, FILE * of)
1929 {
1930   int nlr = 0;
1931   sym_link * type, * search;
1932
1933   if (!of)
1934     {
1935       of = stdout;
1936       nlr = 1;
1937     }
1938
1939   if (start==NULL) {
1940     fprintf (of, "void");
1941     return;
1942   }
1943
1944   /* print the chain as it is written in the source: */
1945   /* start with the last entry                       */
1946   for (type = start; type && type->next; type = type->next)
1947     ;
1948   while (type)
1949     {
1950       if (IS_DECL (type))
1951         {
1952           if (DCL_PTR_VOLATILE (type)) {
1953             fprintf (of, "volatile ");
1954           }
1955           switch (DCL_TYPE (type))
1956             {
1957             case FUNCTION:
1958               fprintf (of, "function %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "));
1959               break;
1960             case GPOINTER:
1961               if (DCL_PTR_CONST (type))
1962                 fprintf (of, "const ");
1963               fprintf (of, "generic * ");
1964               break;
1965             case CPOINTER:
1966               if (DCL_PTR_CONST (type))
1967                 fprintf (of, "const ");
1968               fprintf (of, "code * ");
1969               break;
1970             case FPOINTER:
1971               if (DCL_PTR_CONST (type))
1972                 fprintf (of, "const ");
1973               fprintf (of, "xdata * ");
1974               break;
1975             case EEPPOINTER:
1976               if (DCL_PTR_CONST (type))
1977                 fprintf (of, "const ");
1978               fprintf (of, "eeprom * ");
1979               break;
1980
1981             case POINTER:
1982               if (DCL_PTR_CONST (type))
1983                 fprintf (of, "const ");
1984               fprintf (of, "near *");
1985               break;
1986             case IPOINTER:
1987               if (DCL_PTR_CONST (type))
1988                 fprintf (of, "const ");
1989               fprintf (of, "idata * ");
1990               break;
1991             case PPOINTER:
1992               if (DCL_PTR_CONST (type))
1993                 fprintf (of, "const ");
1994               fprintf (of, "pdata * ");
1995               break;
1996             case UPOINTER:
1997               if (DCL_PTR_CONST (type))
1998                 fprintf (of, "const ");
1999               fprintf (of, "unkown * ");
2000               break;
2001             case ARRAY:
2002               fprintf (of, "[] ");
2003               break;
2004             }
2005         }
2006       else
2007         {
2008           switch (SPEC_SCLS(type)) 
2009             {
2010             case S_DATA: fprintf (of, "data "); break;
2011             case S_XDATA: fprintf (of, "xdata "); break;
2012             case S_SFR: fprintf (of, "sfr "); break;
2013             case S_SBIT: fprintf (of, "sbit "); break;
2014             case S_CODE: fprintf (of, "code "); break;
2015             case S_IDATA: fprintf (of, "idata "); break;
2016             case S_PDATA: fprintf (of, "pdata "); break;
2017             case S_LITERAL: fprintf (of, "literal "); break;
2018             case S_STACK: fprintf (of, "stack "); break;
2019             case S_XSTACK: fprintf (of, "xstack "); break;
2020             case S_BIT: fprintf (of, "bit "); break;
2021             case S_EEPROM: fprintf (of, "eeprom "); break;
2022             default: break;
2023             }
2024
2025           if (SPEC_VOLATILE (type))
2026             fprintf (of, "volatile ");
2027           if (SPEC_USIGN (type))
2028             fprintf (of, "unsigned ");
2029           if (SPEC_CONST (type))
2030             fprintf (of, "const ");
2031
2032           switch (SPEC_NOUN (type))
2033             {
2034             case V_INT:
2035               if (IS_LONG (type))
2036                 fprintf (of, "long ");
2037               fprintf (of, "int");
2038               break;
2039
2040             case V_CHAR:
2041               fprintf (of, "char");
2042               break;
2043
2044             case V_VOID:
2045               fprintf (of, "void");
2046               break;
2047
2048             case V_FLOAT:
2049               fprintf (of, "float");
2050               break;
2051
2052             case V_STRUCT:
2053               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2054               break;
2055
2056             case V_SBIT:
2057               fprintf (of, "sbit");
2058               break;
2059
2060             case V_BIT:
2061               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2062               break;
2063
2064             case V_DOUBLE:
2065               fprintf (of, "double");
2066               break;
2067
2068             default:
2069               fprintf (of, "unknown type");
2070               break;
2071             }
2072         }
2073         /* search entry in list before "type" */
2074     for (search = start; search && search->next != type;)
2075        search = search->next;
2076     type = search;
2077     if (type)
2078       fputc (' ', of);
2079     }
2080   if (nlr)
2081     fprintf (of, "\n");
2082 }
2083
2084 /*-----------------------------------------------------------------*/
2085 /* cdbTypeInfo - print the type information for debugger           */
2086 /*-----------------------------------------------------------------*/
2087 void
2088 cdbTypeInfo (sym_link * type, FILE * of)
2089 {
2090   fprintf (of, "{%d}", getSize (type));
2091   while (type)
2092     {
2093       if (IS_DECL (type))
2094         {
2095           switch (DCL_TYPE (type))
2096             {
2097             case FUNCTION:
2098               fprintf (of, "DF,");
2099               break;
2100             case GPOINTER:
2101               fprintf (of, "DG,");
2102               break;
2103             case CPOINTER:
2104               fprintf (of, "DC,");
2105               break;
2106             case FPOINTER:
2107               fprintf (of, "DX,");
2108               break;
2109             case POINTER:
2110               fprintf (of, "DD,");
2111               break;
2112             case IPOINTER:
2113               fprintf (of, "DI,");
2114               break;
2115             case PPOINTER:
2116               fprintf (of, "DP,");
2117               break;
2118             case EEPPOINTER:
2119               fprintf (of, "DA,");
2120               break;
2121             case ARRAY:
2122               fprintf (of, "DA%d,", DCL_ELEM (type));
2123               break;
2124             default:
2125               break;
2126             }
2127         }
2128       else
2129         {
2130           switch (SPEC_NOUN (type))
2131             {
2132             case V_INT:
2133               if (IS_LONG (type))
2134                 fprintf (of, "SL");
2135               else
2136                 fprintf (of, "SI");
2137               break;
2138
2139             case V_CHAR:
2140               fprintf (of, "SC");
2141               break;
2142
2143             case V_VOID:
2144               fprintf (of, "SV");
2145               break;
2146
2147             case V_FLOAT:
2148               fprintf (of, "SF");
2149               break;
2150
2151             case V_STRUCT:
2152               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2153               break;
2154
2155             case V_SBIT:
2156               fprintf (of, "SX");
2157               break;
2158
2159             case V_BIT:
2160               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2161               break;
2162
2163             default:
2164               break;
2165             }
2166           fputs (":", of);
2167           if (SPEC_USIGN (type))
2168             fputs ("U", of);
2169           else
2170             fputs ("S", of);
2171         }
2172       type = type->next;
2173     }
2174 }
2175 /*-----------------------------------------------------------------*/
2176 /* cdbSymbol - prints a symbol & its type information for debugger */
2177 /*-----------------------------------------------------------------*/
2178 void 
2179 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2180 {
2181   memmap *map;
2182
2183   if (!sym)
2184     return;
2185   if (!of)
2186     of = stdout;
2187
2188   if (isFunc)
2189     fprintf (of, "F:");
2190   else
2191     fprintf (of, "S:");         /* symbol record */
2192   /* if this is not a structure symbol then
2193      we need to figure out the scope information */
2194   if (!isStructSym)
2195     {
2196       if (!sym->level)
2197         {
2198           /* global */
2199           if (IS_STATIC (sym->etype))
2200             fprintf (of, "F%s$", moduleName);   /* scope is file */
2201           else
2202             fprintf (of, "G$"); /* scope is global */
2203         }
2204       else
2205         /* symbol is local */
2206         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2207     }
2208   else
2209     fprintf (of, "S$");         /* scope is structure */
2210
2211   /* print the name, & mangled name */
2212   fprintf (of, "%s$%d$%d(", sym->name,
2213            sym->level, sym->block);
2214
2215   cdbTypeInfo (sym->type, of);
2216   fprintf (of, "),");
2217
2218   /* print the address space */
2219   map = SPEC_OCLS (sym->etype);
2220   fprintf (of, "%c,%d,%d",
2221            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2222
2223   /* if assigned to registers then output register names */
2224   /* if this is a function then print
2225      if is it an interrupt routine & interrupt number
2226      and the register bank it is using */
2227   if (isFunc)
2228     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2229              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2230   /* alternate location to find this symbol @ : eg registers
2231      or spillication */
2232
2233   if (!isStructSym)
2234     fprintf (of, "\n");
2235 }
2236
2237 /*-----------------------------------------------------------------*/
2238 /* cdbStruct - print a structure for debugger                      */
2239 /*-----------------------------------------------------------------*/
2240 void 
2241 cdbStruct (structdef * sdef, int block, FILE * of,
2242            int inStruct, char *tag)
2243 {
2244   symbol *sym;
2245
2246   fprintf (of, "T:");
2247   /* if block # then must have function scope */
2248   fprintf (of, "F%s$", moduleName);
2249   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2250   for (sym = sdef->fields; sym; sym = sym->next)
2251     {
2252       fprintf (of, "({%d}", sym->offset);
2253       cdbSymbol (sym, of, TRUE, FALSE);
2254       fprintf (of, ")");
2255     }
2256   fprintf (of, "]");
2257   if (!inStruct)
2258     fprintf (of, "\n");
2259 }
2260
2261 /*------------------------------------------------------------------*/
2262 /* cdbStructBlock - calls struct printing for a blcks               */
2263 /*------------------------------------------------------------------*/
2264 void 
2265 cdbStructBlock (int block, FILE * of)
2266 {
2267   int i;
2268   bucket **table = StructTab;
2269   bucket *chain;
2270   wassert (of);
2271
2272   /* go thru the entire  table  */
2273   for (i = 0; i < 256; i++)
2274     {
2275       for (chain = table[i]; chain; chain = chain->next)
2276         {
2277           if (chain->block >= block)
2278             {
2279               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2280             }
2281         }
2282     }
2283 }
2284
2285 /*-----------------------------------------------------------------*/
2286 /* powof2 - returns power of two for the number if number is pow 2 */
2287 /*-----------------------------------------------------------------*/
2288 int 
2289 powof2 (unsigned long num)
2290 {
2291   int nshifts = 0;
2292   int n1s = 0;
2293
2294   while (num)
2295     {
2296       if (num & 1)
2297         n1s++;
2298       num >>= 1;
2299       nshifts++;
2300     }
2301
2302   if (n1s > 1 || nshifts == 0)
2303     return 0;
2304   return nshifts - 1;
2305 }
2306
2307 symbol *__fsadd;
2308 symbol *__fssub;
2309 symbol *__fsmul;
2310 symbol *__fsdiv;
2311 symbol *__fseq;
2312 symbol *__fsneq;
2313 symbol *__fslt;
2314 symbol *__fslteq;
2315 symbol *__fsgt;
2316 symbol *__fsgteq;
2317
2318 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2319 symbol *__muldiv[3][3][2];
2320 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2321 sym_link *__multypes[3][2];
2322 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2323 symbol *__conv[2][3][2];
2324 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2325 symbol *__rlrr[2][3][2];
2326
2327 sym_link *floatType;
2328
2329 static char *
2330 _mangleFunctionName(char *in)
2331 {
2332   if (port->getMangledFunctionName) 
2333     {
2334       return port->getMangledFunctionName(in);
2335     }
2336   else
2337     {
2338       return in;
2339     }
2340 }
2341
2342 /*-----------------------------------------------------------------*/
2343 /* typeFromStr - create a typechain from an encoded string         */
2344 /* basic types -        'c' - char                                 */
2345 /*                      's' - short                                */
2346 /*                      'i' - int                                  */
2347 /*                      'l' - long                                 */
2348 /*                      'f' - float                                */
2349 /*                      'v' - void                                 */
2350 /*                      '*' - pointer - default (GPOINTER)         */
2351 /* modifiers -          'u' - unsigned                             */
2352 /* pointer modifiers -  'g' - generic                              */
2353 /*                      'x' - xdata                                */
2354 /*                      'p' - code                                 */
2355 /*                      'd' - data                                 */                     
2356 /* examples : "ig*" - generic int *                                */
2357 /*            "cx*" - char xdata *                                 */
2358 /*            "ui" -  unsigned int                                 */
2359 /*-----------------------------------------------------------------*/
2360 sym_link *typeFromStr (char *s)
2361 {
2362     sym_link *r = newLink();
2363     int usign = 0;
2364
2365     do {
2366         sym_link *nr;
2367         switch (*s) {
2368         case 'u' : 
2369             usign = 1;
2370             s++;
2371             continue ;
2372             break ;
2373         case 'c':
2374             r->class = SPECIFIER;
2375             SPEC_NOUN(r) = V_CHAR;
2376             break;
2377         case 's':
2378         case 'i':
2379             r->class = SPECIFIER;
2380             SPEC_NOUN(r) = V_INT;
2381             break;
2382         case 'l':
2383             r->class = SPECIFIER;
2384             SPEC_NOUN(r) = V_INT;
2385             SPEC_LONG(r) = 1;
2386             break;
2387         case 'f':
2388             r->class = SPECIFIER;
2389             SPEC_NOUN(r) = V_FLOAT;
2390             break;
2391         case 'v':
2392             r->class = SPECIFIER;
2393             SPEC_NOUN(r) = V_VOID;
2394             break;
2395         case '*':
2396             DCL_TYPE(r) = port->unqualified_pointer;
2397             break;
2398         case 'g':
2399         case 'x':
2400         case 'p':
2401         case 'd':
2402             assert(*(s+1)=='*');
2403             nr = newLink();
2404             nr->next = r;
2405             r = nr;
2406             r->class = DECLARATOR ;
2407             switch (*s) {
2408             case 'g':
2409                 DCL_TYPE(r) = GPOINTER;
2410                 break;
2411             case 'x':
2412                 DCL_TYPE(r) = FPOINTER;
2413                 break;
2414             case 'p':
2415                 DCL_TYPE(r) = CPOINTER;
2416                 break;
2417             case 'd':
2418                 DCL_TYPE(r) = POINTER;
2419                 break;
2420             }
2421             s++;
2422             break;
2423         default:
2424             werror(E_INTERNAL_ERROR,"typeFromStr");
2425             break;
2426         }
2427         if (IS_SPEC(r) && usign) {
2428             SPEC_USIGN(r) = 1;
2429             usign = 0;
2430         }
2431         s++;
2432     } while (*s);
2433     return r;
2434 }
2435
2436 /*-----------------------------------------------------------------*/
2437 /* initCSupport - create functions for C support routines          */
2438 /*-----------------------------------------------------------------*/
2439 void 
2440 initCSupport ()
2441 {
2442   const char *smuldivmod[] =
2443   {
2444     "mul", "div", "mod"
2445   };
2446   const char *sbwd[] =
2447   {
2448     "char", "int", "long"
2449   };
2450   const char *ssu[] =
2451   {
2452     "s", "u"
2453   };
2454   const char *srlrr[] =
2455   {
2456     "rl", "rr"
2457   };
2458
2459   int bwd, su, muldivmod, tofrom, rlrr;
2460
2461   if (getenv("SDCC_NO_C_SUPPORT")) {
2462     /* for debugging only */
2463     return;
2464   }
2465
2466   floatType = newFloatLink ();
2467
2468   for (bwd = 0; bwd < 3; bwd++)
2469     {
2470       sym_link *l;
2471       switch (bwd)
2472         {
2473         case 0:
2474           l = newCharLink ();
2475           break;
2476         case 1:
2477           l = newIntLink ();
2478           break;
2479         case 2:
2480           l = newLongLink ();
2481           break;
2482         default:
2483           assert (0);
2484         }
2485       __multypes[bwd][0] = l;
2486       __multypes[bwd][1] = copyLinkChain (l);
2487       SPEC_USIGN (__multypes[bwd][1]) = 1;
2488     }
2489
2490   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2491   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2492   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2493   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2494   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2495   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2496   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2497   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2498   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2499   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2500
2501   for (tofrom = 0; tofrom < 2; tofrom++)
2502     {
2503       for (bwd = 0; bwd < 3; bwd++)
2504         {
2505           for (su = 0; su < 2; su++)
2506             {
2507               if (tofrom)
2508                 {
2509                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2510                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
2511                 }
2512               else
2513                 {
2514                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2515                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
2516                 }
2517             }
2518         }
2519     }
2520
2521   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2522     {
2523       for (bwd = 0; bwd < 3; bwd++)
2524         {
2525           for (su = 0; su < 2; su++)
2526             {
2527               sprintf (buffer, "_%s%s%s",
2528                        smuldivmod[muldivmod],
2529                        ssu[su],
2530                        sbwd[bwd]);
2531               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2532               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2533             }
2534         }
2535     }
2536
2537   for (rlrr = 0; rlrr < 2; rlrr++)
2538     {
2539       for (bwd = 0; bwd < 3; bwd++)
2540         {
2541           for (su = 0; su < 2; su++)
2542             {
2543               sprintf (buffer, "_%s%s%s",
2544                        srlrr[rlrr],
2545                        ssu[su],
2546                        sbwd[bwd]);
2547               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2548               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2549             }
2550         }
2551     }
2552 }
2553
2554 /*-----------------------------------------------------------------*/
2555 /* initBuiltIns - create prototypes for builtin functions          */
2556 /*-----------------------------------------------------------------*/
2557 void initBuiltIns()
2558 {
2559     int i;
2560     symbol *sym;
2561
2562     if (!port->builtintable) return ;
2563
2564     for (i = 0 ; port->builtintable[i].name ; i++) {
2565         sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
2566                              port->builtintable[i].nParms,port->builtintable[i].parm_types);
2567         FUNC_ISBUILTIN(sym->type) = 1;
2568         FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
2569     }
2570 }