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