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