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