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