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 #include "dbuf_string.h"
27 
28 #include "SDCCsymt.h"
29 
30 value *aggregateToPointer (value * val);
31 void printTypeChainRaw (sym_link * start, FILE * of);
32 
33 void
printFromToType(sym_link * from,sym_link * to)34 printFromToType (sym_link * from, sym_link * to)
35 {
36   struct dbuf_s dbuf;
37   dbuf_init (&dbuf, 1024);
38   dbuf_append_str (&dbuf, "from type '");
39   dbuf_printTypeChain (from, &dbuf);
40   dbuf_append_str (&dbuf, "'\n  to type '");
41   dbuf_printTypeChain (to, &dbuf);
42   dbuf_append_str (&dbuf, "'\n");
43   dbuf_write_and_destroy (&dbuf, stderr);
44 }
45 
46 /* noun strings */
47 char *
nounName(sym_link * sl)48 nounName (sym_link * sl)
49 {
50   switch (SPEC_NOUN (sl))
51     {
52     case V_INT:
53       {
54         if (SPEC_LONGLONG (sl))
55           return "long long";
56         if (SPEC_LONG (sl))
57           return "long";
58         if (SPEC_SHORT (sl))
59           return "short";
60         return "int";
61       }
62     case V_FLOAT:
63       return "float";
64     case V_FIXED16X16:
65       return "fixed16x16";
66     case V_BOOL:
67       return "_Bool";
68     case V_CHAR:
69       return "char";
70     case V_VOID:
71       return "void";
72     case V_STRUCT:
73       return "struct";
74     case V_LABEL:
75       return "label";
76     case V_BITFIELD:
77       return "bitfield";
78     case V_BBITFIELD:
79       return "_Boolbitfield";
80     case V_BIT:
81       return "bit";
82     case V_SBIT:
83       return "sbit";
84     case V_DOUBLE:
85       return "double";
86     }
87   return "unknown";
88 }
89 
90 bucket *SymbolTab[256];         /* the symbol    table  */
91 bucket *StructTab[256];         /* the structure table  */
92 bucket *TypedefTab[256];        /* the typedef   table  */
93 bucket *LabelTab[256];          /* the Label     table  */
94 bucket *enumTab[256];           /* enumerated    table  */
95 bucket *AddrspaceTab[256];      /* the named address space table  */
96 
97 /*------------------------------------------------------------------*/
98 /* initSymt () - initialises symbol table related stuff             */
99 /*------------------------------------------------------------------*/
100 void
initSymt(void)101 initSymt (void)
102 {
103   int i = 0;
104 
105   for (i = 0; i < 256; i++)
106     SymbolTab[i] = StructTab[i] = (void *) NULL;
107 }
108 
109 /*-----------------------------------------------------------------*/
110 /* newBucket - allocates & returns a new bucket                    */
111 /*-----------------------------------------------------------------*/
112 bucket *
newBucket(void)113 newBucket (void)
114 {
115   bucket *bp;
116 
117   bp = Safe_alloc (sizeof (bucket));
118 
119   return bp;
120 }
121 
122 /*-----------------------------------------------------------------*/
123 /* hashKey - computes the hashkey given a symbol name              */
124 /*-----------------------------------------------------------------*/
125 int
hashKey(const char * s)126 hashKey (const char *s)
127 {
128   unsigned long key = 0;
129 
130   while (*s)
131     key += *s++;
132   return key % 256;
133 }
134 
135 /*-----------------------------------------------------------------*/
136 /* addSym - adds a symbol to the hash Table                        */
137 /*-----------------------------------------------------------------*/
138 void
addSym(bucket ** stab,void * sym,char * sname,long level,int block,int checkType)139 addSym (bucket ** stab, void *sym, char *sname, long level, int block, int checkType)
140 {
141   int i;                        /* index into the hash Table */
142   bucket *bp;                   /* temp bucket    *          */
143 
144   if (checkType)
145     {
146       symbol *csym = (symbol *) sym;
147 
148       if (getenv ("DEBUG_SANITY"))
149         {
150           fprintf (stderr, "addSym: %s ", sname);
151         }
152       /* make sure the type is complete and sane */
153       checkTypeSanity (csym->etype, csym->name);
154     }
155 
156   /* prevent overflow of the (r)name buffers */
157   if (strlen (sname) > SDCC_SYMNAME_MAX)
158     {
159       werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
160       sname[SDCC_SYMNAME_MAX] = '\0';
161     }
162 
163   /* the symbols are always added at the head of the list  */
164   i = hashKey (sname);
165   /* get a free entry */
166   bp = Safe_alloc (sizeof (bucket));
167 
168   bp->sym = sym;                /* update the symbol pointer */
169   bp->level = level;            /* update the nest level     */
170   bp->block = block;
171   strncpyz (bp->name, sname, sizeof (bp->name));        /* copy the name into place */
172 
173   /* if this is the first entry */
174   if (stab[i] == NULL)
175     {
176       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
177       stab[i] = bp;
178     }
179   /* not first entry then add @ head of list */
180   else
181     {
182       bp->prev = NULL;
183       stab[i]->prev = bp;
184       bp->next = stab[i];
185       stab[i] = bp;
186     }
187 }
188 
189 /*-----------------------------------------------------------------*/
190 /* deleteSym - deletes a symbol from the hash Table entry          */
191 /*-----------------------------------------------------------------*/
192 void
deleteSym(bucket ** stab,void * sym,const char * sname)193 deleteSym (bucket ** stab, void *sym, const char *sname)
194 {
195   int i = 0;
196   bucket *bp;
197 
198   i = hashKey (sname);
199 
200   bp = stab[i];
201   /* find the symbol */
202   while (bp)
203     {
204       if (bp->sym == sym)       /* found it then break out */
205         break;                  /* of the loop       */
206       bp = bp->next;
207     }
208 
209   if (!bp)                      /* did not find it */
210     return;
211 
212   /* if this is the first one in the chain */
213   if (!bp->prev)
214     {
215       stab[i] = bp->next;
216       if (stab[i])              /* if chain ! empty */
217         stab[i]->prev = (void *) NULL;
218     }
219   /* middle || end of chain */
220   else
221     {
222       if (bp->next)             /* if not end of chain */
223         bp->next->prev = bp->prev;
224 
225       bp->prev->next = bp->next;
226     }
227 }
228 
229 /*-----------------------------------------------------------------*/
230 /* findSym - finds a symbol in a table                             */
231 /*-----------------------------------------------------------------*/
232 void *
findSym(bucket ** stab,void * sym,const char * sname)233 findSym (bucket ** stab, void *sym, const char *sname)
234 {
235   bucket *bp;
236 
237   bp = stab[hashKey (sname)];
238   while (bp)
239     {
240       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
241         break;
242       bp = bp->next;
243     }
244 
245   return (bp ? bp->sym : (void *) NULL);
246 }
247 
248 /*-----------------------------------------------------------------*/
249 /* findSymWithLevel - finds a symbol with a name & level           */
250 /*-----------------------------------------------------------------*/
251 void *
findSymWithLevel(bucket ** stab,symbol * sym)252 findSymWithLevel (bucket ** stab, symbol * sym)
253 {
254   bucket *bp;
255 
256   if (!sym)
257     return sym;
258 
259   bp = stab[hashKey (sym->name)];
260 
261   /**
262    **  do the search from the head of the list since the
263    **  elements are added at the head it is ensured that
264    ** we will find the deeper definitions before we find
265    ** the global ones. we need to check for symbols with
266    ** level <= to the level given, if levels match then block
267    ** numbers need to match as well
268    **/
269   while (bp)
270     {
271       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
272         {
273           /* if this is parameter then nothing else need to be checked */
274           if (((symbol *) (bp->sym))->_isparm)
275             return (bp->sym);
276           /* if levels match then block numbers should also match */
277           if (bp->level && bp->level == sym->level && bp->block == sym->block
278               && ((symbol *)(bp->sym))->seqPoint <= sym->seqPoint)
279             return (bp->sym);
280           /* if levels don't match then we are okay if the symbol is in scope */
281           if (bp->level && bp->level != sym->level && bp->block <= sym->block
282               && ((symbol *) (bp->sym))->isinscope
283               && (stab == LabelTab || ((symbol *)(bp->sym))->seqPoint <= sym->seqPoint))
284             return (bp->sym);
285           /* if this is a global variable then we are ok too */
286           if (bp->level == 0)
287             return (bp->sym);
288         }
289 
290       bp = bp->next;
291     }
292 
293   return (void *) NULL;
294 }
295 
296 /*-----------------------------------------------------------------*/
297 /* findSymWithBlock - finds a symbol with name in a block          */
298 /*-----------------------------------------------------------------*/
299 void *
findSymWithBlock(bucket ** stab,symbol * sym,int block,long level)300 findSymWithBlock (bucket ** stab, symbol * sym, int block, long level)
301 {
302   bucket *bp;
303 
304   if (!sym)
305     return sym;
306 
307   bp = stab[hashKey (sym->name)];
308   while (bp)
309     {
310       if (strcmp (bp->name, sym->name) == 0 && (bp->block == block || (bp->block < block && bp->level < level)))
311         break;
312       bp = bp->next;
313     }
314 
315   return (bp ? bp->sym : (void *) NULL);
316 }
317 
318 /*------------------------------------------------------------------*/
319 /* newSymbol () - returns a new pointer to a symbol                 */
320 /*------------------------------------------------------------------*/
321 symbol *
newSymbol(const char * name,long scope)322 newSymbol (const char *name, long scope)
323 {
324   symbol *sym;
325 
326   sym = Safe_alloc (sizeof (symbol));
327 
328   strncpyz (sym->name, name, sizeof (sym->name));       /* copy the name */
329   sym->level = scope;           /* set the level */
330   sym->block = currBlockno;
331   sym->seqPoint = seqPointNo;
332   sym->lineDef = lexLineno;     /* set the line number */
333   sym->fileDef = lexFilename;
334   sym->for_newralloc = 0;
335   sym->isinscope = 1;
336   sym->usl.spillLoc = 0;
337 
338   // Err on the safe side, when in doubt disabling optimizations.
339   sym->funcDivFlagSafe = 0;
340   sym->funcUsesVolatile = 1;
341 
342   return sym;
343 }
344 
345 /*------------------------------------------------------------------*/
346 /* newLink - creates a new link (declarator,specifier)              */
347 /*------------------------------------------------------------------*/
348 sym_link *
newLink(SYM_LINK_CLASS select)349 newLink (SYM_LINK_CLASS select)
350 {
351   sym_link *p;
352 
353   p = Safe_alloc (sizeof (sym_link));
354   p->xclass = select;
355   p->funcAttrs.z88dk_params_offset = 0;
356 
357   return p;
358 }
359 
360 /*------------------------------------------------------------------*/
361 /* newStruct - creats a new structdef from the free list            */
362 /*------------------------------------------------------------------*/
363 structdef *
newStruct(const char * tag)364 newStruct (const char *tag)
365 {
366   structdef *s;
367 
368   s = Safe_alloc (sizeof (structdef));
369 
370   strncpyz (s->tag, tag, sizeof (s->tag));      /* copy the tag */
371   return s;
372 }
373 
374 /*------------------------------------------------------------------*/
375 /* sclsFromPtr - Return the storage class a pointer points into.    */
376 /*               S_FIXED is returned for generic pointers or other  */
377 /*               unexpected cases                                   */
378 /*------------------------------------------------------------------*/
379 STORAGE_CLASS
sclsFromPtr(sym_link * ptr)380 sclsFromPtr (sym_link * ptr)
381 {
382   switch (DCL_TYPE (ptr))
383     {
384     case POINTER:
385       return S_DATA;
386     case GPOINTER:
387       return S_FIXED;
388     case FPOINTER:
389       return S_XDATA;
390     case CPOINTER:
391       return S_CODE;
392     case IPOINTER:
393       return S_IDATA;
394     case PPOINTER:
395       return S_PDATA;
396     case EEPPOINTER:
397       return S_EEPROM;
398     case FUNCTION:
399       return S_CODE;
400     default:
401       return S_FIXED;
402     }
403 }
404 
405 /*------------------------------------------------------------------*/
406 /* pointerTypes - do the computation for the pointer types          */
407 /*------------------------------------------------------------------*/
408 void
pointerTypes(sym_link * ptr,sym_link * type)409 pointerTypes (sym_link * ptr, sym_link * type)
410 {
411   sym_link *p;
412   sym_link *etype;
413 
414   if (IS_SPEC (ptr))
415     return;
416 
417   /* find the last unknown pointer type */
418   p = ptr;
419   while (p)
420     {
421       if (IS_PTR (p) && DCL_TYPE (p) == UPOINTER)
422         ptr = p;
423       p = p->next;
424     }
425 
426   /* could not find it */
427   if (!ptr || IS_SPEC (ptr) || !IS_PTR (ptr))
428     return;
429 
430   if (IS_PTR (ptr) && DCL_TYPE (ptr) != UPOINTER)
431     {
432       pointerTypes (ptr->next, type);
433       return;
434     }
435 
436   /* change the pointer type depending on the
437      storage class of the etype */
438   etype = getSpec (type);
439   if (IS_SPEC (etype))
440     {
441       switch (SPEC_SCLS (etype))
442         {
443         case S_XDATA:
444           DCL_TYPE (ptr) = FPOINTER;
445           break;
446         case S_IDATA:
447           DCL_TYPE (ptr) = IPOINTER;
448           break;
449         case S_PDATA:
450           DCL_TYPE (ptr) = PPOINTER;
451           break;
452         case S_DATA:
453           DCL_TYPE (ptr) = POINTER;
454           break;
455         case S_CODE:
456           DCL_TYPE (ptr) = CPOINTER;
457           break;
458         case S_EEPROM:
459           DCL_TYPE (ptr) = EEPPOINTER;
460           break;
461         default:
462           DCL_TYPE (ptr) = port->unqualified_pointer;
463           break;
464         }
465       /* the storage class of etype ends here */
466       SPEC_SCLS (etype) = 0;
467     }
468 
469   /* now change all the remaining unknown pointers
470      to generic pointers */
471   while (ptr)
472     {
473       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
474         DCL_TYPE (ptr) = port->unqualified_pointer;
475       ptr = ptr->next;
476     }
477 
478   /* same for the type although it is highly unlikely that
479      type will have a pointer */
480   while (type)
481     {
482       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
483         DCL_TYPE (type) = port->unqualified_pointer;
484       type = type->next;
485     }
486 }
487 
488 /*------------------------------------------------------------------*/
489 /* addDecl - adds a declarator @ the end of a chain                 */
490 /*------------------------------------------------------------------*/
491 void
addDecl(symbol * sym,int type,sym_link * p)492 addDecl (symbol * sym, int type, sym_link * p)
493 {
494   static sym_link *empty = NULL;
495   sym_link *head;
496   sym_link *tail;
497   sym_link *t;
498 
499   if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
500     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, (void *)p);
501 
502   if (empty == NULL)
503     empty = newLink (SPECIFIER);
504 
505   /* if we are passed a link then set head & tail */
506   if (p)
507     {
508       tail = head = p;
509       while (tail->next)
510         tail = tail->next;
511     }
512   else
513     {
514       head = tail = newLink (DECLARATOR);
515       DCL_TYPE (head) = type;
516     }
517 
518   /* if this is the first entry   */
519   if (!sym->type)
520     {
521       sym->type = head;
522       sym->etype = tail;
523     }
524   else if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
525     {
526       sym->etype = mergeSpec (sym->etype, head, sym->name);
527     }
528   else if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
529     {
530       t = sym->type;
531       while (t->next != sym->etype)
532         t = t->next;
533       t->next = head;
534       tail->next = sym->etype;
535     }
536   else if (IS_FUNC (sym->type) && IS_SPEC (sym->type->next) && !memcmp (sym->type->next, empty, sizeof (sym_link)))
537     {
538       sym->type->next = head;
539       sym->etype = tail;
540     }
541   else
542     {
543       sym->etype->next = head;
544       sym->etype = tail;
545     }
546 
547   /* if the type is an unknown pointer and has
548      a tspec then take the storage class const & volatile
549      attribute from the tspec & make it those of this
550      symbol */
551   if (p && !IS_SPEC (p) &&
552       //DCL_TYPE (p) == UPOINTER &&
553       DCL_TSPEC (p))
554     {
555       if (!IS_SPEC (sym->etype))
556         {
557           sym->etype = sym->etype->next = newLink (SPECIFIER);
558         }
559       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
560       SPEC_ABSA (sym->etype) |= SPEC_ABSA (DCL_TSPEC (p));
561       SPEC_ADDR (sym->etype) |= SPEC_ADDR (DCL_TSPEC (p));
562       DCL_TSPEC (p) = NULL;
563     }
564 
565   // if there is a function in this type chain
566   if (p && funcInChain (sym->type))
567     {
568       processFuncArgs (sym);
569     }
570 
571   return;
572 }
573 
574 /*------------------------------------------------------------------
575   checkTypeSanity: prevent the user from doing e.g.:
576   unsigned float uf;
577   ------------------------------------------------------------------*/
578 void
checkTypeSanity(sym_link * etype,const char * name)579 checkTypeSanity (sym_link *etype, const char *name)
580 {
581   char *noun;
582 
583   if (!etype)
584     {
585       if (getenv ("DEBUG_SANITY"))
586         {
587           fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
588         }
589       return;
590     }
591 
592   if (!IS_SPEC (etype))
593     {
594       if (getenv ("DEBUG_SANITY"))
595         {
596           fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
597         }
598       return;
599     }
600 
601   noun = nounName (etype);
602 
603   if (getenv ("DEBUG_SANITY"))
604     {
605       fprintf (stderr, "checking sanity for %s %p\n", name, (void *)etype);
606     }
607 
608   if ((SPEC_NOUN (etype) == V_BOOL ||
609        SPEC_NOUN (etype) == V_CHAR ||
610        SPEC_NOUN (etype) == V_FLOAT ||
611        SPEC_NOUN (etype) == V_FIXED16X16 ||
612        SPEC_NOUN (etype) == V_DOUBLE || SPEC_NOUN (etype) == V_VOID) && (SPEC_SHORT (etype) || SPEC_LONG (etype) || SPEC_LONGLONG (etype)))
613     {                           // long or short for char float double or void
614       werror (E_LONG_OR_SHORT_INVALID, noun, name);
615     }
616   if ((SPEC_NOUN (etype) == V_BOOL ||
617        SPEC_NOUN (etype) == V_FLOAT ||
618        SPEC_NOUN (etype) == V_FIXED16X16 ||
619        SPEC_NOUN (etype) == V_DOUBLE || SPEC_NOUN (etype) == V_VOID) && (etype->select.s.b_signed || SPEC_USIGN (etype)))
620     {                           // signed or unsigned for float double or void
621       werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
622     }
623 
624   /* if no noun e.g.
625      "const a;" or "data b;" or "signed s" or "long l"
626      assume an int */
627   if (!SPEC_NOUN (etype))
628     {
629       SPEC_NOUN (etype) = V_INT;
630       if (!(SPEC_SHORT (etype) || SPEC_LONG (etype) || SPEC_LONGLONG (etype) || SPEC_SIGN (etype) || SPEC_USIGN (etype)))
631         werror (options.std_c99 ? E_NO_TYPE_SPECIFIER : W_NO_TYPE_SPECIFIER, name);
632     }
633 
634   /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
635   /* a "plain" int bitfield is unsigned */
636   if (SPEC_NOUN (etype) == V_BIT || SPEC_NOUN (etype) == V_SBIT)
637     {
638       if (!etype->select.s.b_signed)
639         SPEC_USIGN (etype) = 1;
640     }
641 
642   if (etype->select.s.b_signed && SPEC_USIGN (etype))
643     {                           // signed AND unsigned
644       werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
645     }
646   if (SPEC_SHORT (etype) && SPEC_LONG (etype))
647     {                           // short AND long
648       werror (E_LONG_AND_SHORT_INVALID, noun, name);
649     }
650 }
651 
652 /*------------------------------------------------------------------*/
653 /* finalizeSpec                                                     */
654 /*    currently just a V_CHAR is forced to be unsigned              */
655 /*      when it's neither signed nor unsigned                       */
656 /*      unless the --fsigned-char command line switch is active     */
657 /*------------------------------------------------------------------*/
658 sym_link *
finalizeSpec(sym_link * lnk)659 finalizeSpec (sym_link * lnk)
660 {
661   sym_link *p = lnk;
662   while (p && !IS_SPEC (p))
663     p = p->next;
664   if (SPEC_NOUN (p) == V_CHAR && !SPEC_USIGN (p) && !p->select.s.b_signed)
665     {
666       SPEC_USIGN (p) = !options.signed_char;
667       p->select.s.b_implicit_sign = true;
668     }
669   return lnk;
670 }
671 
672 /*------------------------------------------------------------------*/
673 /* mergeSpec - merges two specifiers and returns the new one        */
674 /*------------------------------------------------------------------*/
675 sym_link *
mergeSpec(sym_link * dest,sym_link * src,const char * name)676 mergeSpec (sym_link * dest, sym_link * src, const char *name)
677 {
678   unsigned int i;
679 
680   if (!IS_SPEC (dest) || !IS_SPEC (src))
681     {
682 #if 0
683       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
684       exit (1);
685 #else
686       werror (E_SYNTAX_ERROR, yytext);
687       // the show must go on
688       return newIntLink ();
689 #endif
690     }
691 
692   if (!options.std_c11 && !options.std_c99)
693     {
694       if (SPEC_SIGN (dest) && SPEC_SIGN (src))
695         werror (W_REPEAT_QUALIFIER, "signed");
696       if (SPEC_USIGN (dest) && SPEC_USIGN (src))
697         werror (W_REPEAT_QUALIFIER, "unsigned");
698       if (SPEC_CONST (dest) && SPEC_CONST (src))
699         werror (W_REPEAT_QUALIFIER, "const");
700       if (SPEC_VOLATILE (dest) && SPEC_VOLATILE (src))
701         werror (W_REPEAT_QUALIFIER, "volatile");
702       if (SPEC_STAT (dest) && SPEC_STAT (src))
703         werror (W_REPEAT_QUALIFIER, "static");
704       if (SPEC_EXTR (dest) && SPEC_EXTR (src))
705         werror (W_REPEAT_QUALIFIER, "extern");
706       if (SPEC_TYPEDEF (dest) && SPEC_TYPEDEF (src))
707         werror (W_REPEAT_QUALIFIER, "typedef");
708       if (SPEC_SCLS (dest) == S_REGISTER && SPEC_SCLS (src) == S_REGISTER)
709         werror (W_REPEAT_QUALIFIER, "register");
710       if (SPEC_SCLS (dest) == S_AUTO && SPEC_SCLS (src) == S_AUTO)
711         werror (W_REPEAT_QUALIFIER, "auto");
712     }
713 
714   if (SPEC_NOUN (src))
715     {
716       if (!SPEC_NOUN (dest))
717         {
718           SPEC_NOUN (dest) = SPEC_NOUN (src);
719         }
720       else
721         {
722           /* we shouldn't redeclare the type */
723           if (getenv ("DEBUG_SANITY"))
724             {
725               fprintf (stderr, "mergeSpec: ");
726             }
727           werror (E_TWO_OR_MORE_DATA_TYPES, name);
728         }
729     }
730 
731   if ((SPEC_SHORT (src)  || SPEC_LONG (src)  || SPEC_LONGLONG (src)) &&
732       (SPEC_SHORT (dest) || SPEC_LONG (dest) || SPEC_LONGLONG (dest)))
733     {
734       if (!(options.std_c99 && SPEC_LONG (src) && SPEC_LONG (dest) && !TARGET_PIC_LIKE)) /* C99 has long long */
735         werror (E_SHORTLONG, name);
736     }
737 
738   if (SPEC_SCLS (src))
739     {
740       /* if destination has no storage class */
741       if (!SPEC_SCLS (dest))
742         {
743           SPEC_SCLS (dest) = SPEC_SCLS (src);
744         }
745       else if (SPEC_SCLS (dest) == S_REGISTER && SPEC_SCLS (src) != S_AUTO)
746         {
747           SPEC_SCLS (dest) = SPEC_SCLS (src);
748         }
749       else
750         {
751           if (getenv ("DEBUG_SANITY"))
752             {
753               fprintf (stderr, "mergeSpec: ");
754             }
755           werror (E_TWO_OR_MORE_STORAGE_CLASSES, name);
756         }
757     }
758 
759   /* copy all the specifications  */
760 
761   // we really should do:
762 #if 0
763   if (SPEC_what (src))
764     {
765       if (SPEC_what (dest))
766         {
767           werror (W_DUPLICATE_SPEC, "what");
768         }
769       SPEC_what (dst) |= SPEC_what (src);
770     }
771 #endif
772   // but there are more important thing right now
773 
774   if (options.std_c99 && SPEC_LONG (src) && SPEC_LONG (dest))
775     {
776       SPEC_LONG (dest) = 0;
777       SPEC_LONGLONG (dest) = 1;
778     }
779   else
780     SPEC_LONG (dest) |= SPEC_LONG (src);
781   SPEC_LONGLONG (dest) |= SPEC_LONGLONG (src);
782   SPEC_SHORT (dest) |= SPEC_SHORT (src);
783   SPEC_USIGN (dest) |= SPEC_USIGN (src);
784   dest->select.s.b_signed |= src->select.s.b_signed;
785   SPEC_STAT (dest) |= SPEC_STAT (src);
786   SPEC_EXTR (dest) |= SPEC_EXTR (src);
787   SPEC_INLINE (dest) |= SPEC_INLINE (src);
788   SPEC_NORETURN (dest) |= SPEC_NORETURN(src);
789   SPEC_CONST (dest) |= SPEC_CONST (src);
790   SPEC_ABSA (dest) |= SPEC_ABSA (src);
791   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
792   SPEC_RESTRICT (dest) |= SPEC_RESTRICT (src);
793   SPEC_ADDR (dest) |= SPEC_ADDR (src);
794   SPEC_OCLS (dest) = SPEC_OCLS (src);
795   SPEC_BLEN (dest) |= SPEC_BLEN (src);
796   SPEC_BSTR (dest) |= SPEC_BSTR (src);
797   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
798   SPEC_ENUM (dest) |= SPEC_ENUM (src);
799   if (SPEC_ARGREG (src) && !SPEC_ARGREG (dest))
800     SPEC_ARGREG (dest) = SPEC_ARGREG (src);
801 
802   if (SPEC_STAT (dest) && SPEC_EXTR (dest))
803     werror (E_TWO_OR_MORE_STORAGE_CLASSES, name);
804 
805   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
806     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
807 
808   if (FUNC_ISISR (dest) && FUNC_ISISR (src))
809     werror (E_INT_MULTIPLE, name);
810 
811   /* these are the only function attributes that will be set
812      in a specifier while parsing */
813   FUNC_NONBANKED (dest) |= FUNC_NONBANKED (src);
814   FUNC_BANKED (dest) |= FUNC_BANKED (src);
815   FUNC_ISCRITICAL (dest) |= FUNC_ISCRITICAL (src);
816   FUNC_ISREENT (dest) |= FUNC_ISREENT (src);
817   FUNC_ISNAKED (dest) |= FUNC_ISNAKED (src);
818   FUNC_ISISR (dest) |= FUNC_ISISR (src);
819   FUNC_ISJAVANATIVE (dest) |= FUNC_ISJAVANATIVE (src);
820   FUNC_ISBUILTIN (dest) |= FUNC_ISBUILTIN (src);
821   FUNC_ISOVERLAY (dest) |= FUNC_ISOVERLAY (src);
822   FUNC_INTNO (dest) |= FUNC_INTNO (src);
823   FUNC_REGBANK (dest) |= FUNC_REGBANK (src);
824   FUNC_ISINLINE (dest) |= FUNC_ISINLINE (src);
825   FUNC_ISNORETURN (dest) |= FUNC_ISNORETURN (src);
826   FUNC_ISSMALLC (dest) |= FUNC_ISSMALLC (src);
827   FUNC_ISZ88DK_FASTCALL (dest) |= FUNC_ISZ88DK_FASTCALL (src);
828   FUNC_ISZ88DK_CALLEE (dest) |= FUNC_ISZ88DK_CALLEE (src);
829   for (i = 0; i < 9; i++)
830     dest->funcAttrs.preserved_regs[i] |= src->funcAttrs.preserved_regs[i];
831 
832   if (SPEC_ADDRSPACE (src) && SPEC_ADDRSPACE (dest))
833     werror (E_TWO_OR_MORE_STORAGE_CLASSES, name);
834   if (SPEC_ADDRSPACE (src))
835     SPEC_ADDRSPACE (dest) = SPEC_ADDRSPACE (src);
836 
837   if (SPEC_ALIGNAS (src) > SPEC_ALIGNAS (dest))
838     SPEC_ALIGNAS (dest) = SPEC_ALIGNAS (src);
839   if (SPEC_SCLS (dest) == S_REGISTER && SPEC_ALIGNAS (dest))
840     werror (E_ALIGNAS, SPEC_ALIGNAS (dest));
841 
842   return dest;
843 }
844 
845 /*------------------------------------------------------------------*/
846 /* mergeDeclSpec - merges a specifier and a declarator              */
847 /*------------------------------------------------------------------*/
848 sym_link *
mergeDeclSpec(sym_link * dest,sym_link * src,const char * name)849 mergeDeclSpec (sym_link * dest, sym_link * src, const char *name)
850 {
851   sym_link *decl, *spec, *lnk;
852 
853   if (IS_SPEC (src))
854     {
855       if (IS_SPEC (dest))
856         {
857           return mergeSpec (dest, src, name);
858         }
859       else
860         {
861           decl = dest;
862           spec = src;
863         }
864     }
865   else
866     {
867       if (IS_SPEC (dest))
868         {
869           decl = src;
870           spec = dest;
871         }
872       else
873         {
874           werror (E_SYNTAX_ERROR, yytext);
875           // the show must go on
876           return newIntLink ();
877         }
878     }
879 
880   DCL_PTR_CONST (decl) |= SPEC_CONST (spec);
881   DCL_PTR_VOLATILE (decl) |= SPEC_VOLATILE (spec);
882   DCL_PTR_RESTRICT (decl) |= SPEC_RESTRICT (spec);
883   if (DCL_PTR_ADDRSPACE (decl) && SPEC_ADDRSPACE (spec) &&
884     strcmp (DCL_PTR_ADDRSPACE (decl)->name, SPEC_ADDRSPACE (spec)->name))
885     werror (E_SYNTAX_ERROR, yytext);
886   if (SPEC_ADDRSPACE (spec))
887     DCL_PTR_ADDRSPACE (decl) = SPEC_ADDRSPACE (spec);
888 
889   lnk = decl;
890   while (lnk && !IS_SPEC (lnk->next))
891     lnk = lnk->next;
892   lnk->next = mergeSpec (spec, lnk->next, name);
893   return decl;
894 }
895 
896 /*-------------------------------------------------------------------*/
897 /* genSymName - generates and returns a name used for anonymous vars */
898 /*-------------------------------------------------------------------*/
899 char *
genSymName(long level)900 genSymName (long level)
901 {
902   static int gCount = 0;
903   static char gname[SDCC_NAME_MAX + 1];
904 
905   SNPRINTF (gname, sizeof (gname), "__%04d%04d", level, gCount++);
906   return gname;
907 }
908 
909 /*------------------------------------------------------------------*/
910 /* getSpec - returns the specifier part from a declaration chain    */
911 /*------------------------------------------------------------------*/
912 sym_link *
getSpec(sym_link * p)913 getSpec (sym_link * p)
914 {
915   while (p && !(IS_SPEC (p)))
916     p = p->next;
917 
918   return p;
919 }
920 
921 /*------------------------------------------------------------------*/
922 /* newCharLink() - creates an char type                             */
923 /*------------------------------------------------------------------*/
924 sym_link *
newCharLink()925 newCharLink ()
926 {
927   sym_link *p;
928 
929   p = newLink (SPECIFIER);
930   SPEC_NOUN (p) = V_CHAR;
931   SPEC_USIGN (p) = 1;
932 
933   return p;
934 }
935 
936 /*------------------------------------------------------------------*/
937 /* newFloatLink - a new Float type                                  */
938 /*------------------------------------------------------------------*/
939 sym_link *
newFloatLink()940 newFloatLink ()
941 {
942   sym_link *p;
943 
944   p = newLink (SPECIFIER);
945   SPEC_NOUN (p) = V_FLOAT;
946 
947   return p;
948 }
949 
950 /*------------------------------------------------------------------*/
951 /* newFixed16x16Link - a new Float type                             */
952 /*------------------------------------------------------------------*/
953 sym_link *
newFixed16x16Link()954 newFixed16x16Link ()
955 {
956   sym_link *p;
957 
958   p = newLink (SPECIFIER);
959   SPEC_NOUN (p) = V_FIXED16X16;
960 
961   return p;
962 }
963 
964 /*------------------------------------------------------------------*/
965 /* newLongLink() - new long type                                    */
966 /*------------------------------------------------------------------*/
967 sym_link *
newLongLink()968 newLongLink ()
969 {
970   sym_link *p;
971 
972   p = newLink (SPECIFIER);
973   SPEC_NOUN (p) = V_INT;
974   SPEC_LONG (p) = 1;
975 
976   return p;
977 }
978 
979 /*------------------------------------------------------------------*/
980 /* newLongLongLink() - new long long type                           */
981 /*------------------------------------------------------------------*/
982 sym_link *
newLongLongLink()983 newLongLongLink ()
984 {
985   sym_link *p;
986 
987   p = newLink (SPECIFIER);
988   SPEC_NOUN (p) = V_INT;
989   SPEC_LONGLONG (p) = 1;
990 
991   return p;
992 }
993 
994 /*------------------------------------------------------------------*/
995 /* newIntLink() - creates an int type                               */
996 /*------------------------------------------------------------------*/
997 sym_link *
newIntLink()998 newIntLink ()
999 {
1000   sym_link *p;
1001 
1002   p = newLink (SPECIFIER);
1003   SPEC_NOUN (p) = V_INT;
1004 
1005   return p;
1006 }
1007 
1008 /*------------------------------------------------------------------*/
1009 /* newBoolLink() - creates an bool type                             */
1010 /*------------------------------------------------------------------*/
1011 sym_link *
newBoolLink()1012 newBoolLink ()
1013 {
1014   sym_link *p;
1015 
1016   p = newLink (SPECIFIER);
1017   if (bit)
1018     SPEC_NOUN (p) = V_BIT;
1019   else
1020     SPEC_NOUN (p) = V_BOOL;
1021 
1022   return p;
1023 }
1024 
1025 /*------------------------------------------------------------------*/
1026 /* newVoidLink() - creates an void type                             */
1027 /*------------------------------------------------------------------*/
1028 sym_link *
newVoidLink()1029 newVoidLink ()
1030 {
1031   sym_link *p;
1032 
1033   p = newLink (SPECIFIER);
1034   SPEC_NOUN (p) = V_VOID;
1035 
1036   return p;
1037 }
1038 
1039 /*------------------------------------------------------------------*/
1040 /* getSize - returns size of a type chain in bytes                  */
1041 /*------------------------------------------------------------------*/
1042 unsigned int
getSize(sym_link * p)1043 getSize (sym_link * p)
1044 {
1045   /* if nothing return 0 */
1046   if (!p)
1047     return 0;
1048   if (IS_SPEC (p))
1049     {                           /* if this is the specifier then */
1050       switch (SPEC_NOUN (p))
1051         {                       /* depending on the specifier type */
1052         case V_INT:
1053           return (IS_LONGLONG (p) ? LONGLONGSIZE : (IS_LONG (p) ? LONGSIZE : INTSIZE));
1054         case V_FLOAT:
1055           return FLOATSIZE;
1056         case V_FIXED16X16:
1057           return (4);
1058         case V_BOOL:
1059           return BOOLSIZE;
1060         case V_CHAR:
1061           return CHARSIZE;
1062         case V_VOID:
1063           return 0;
1064         case V_STRUCT:
1065           return SPEC_STRUCT (p)->size;
1066         case V_LABEL:
1067           return 0;
1068         case V_SBIT:
1069         case V_BIT:
1070           return BITSIZE;
1071         case V_BITFIELD:
1072         case V_BBITFIELD:
1073           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
1074         default:
1075           return 0;
1076         }
1077     }
1078 
1079   /* this is a declarator */
1080   switch (DCL_TYPE (p))
1081     {
1082     case ARRAY:
1083       if (DCL_ELEM (p))
1084         {
1085           return DCL_ELEM (p) * getSize (p->next);
1086         }
1087       else
1088         {
1089           return 0;
1090         }
1091     case IPOINTER:
1092     case PPOINTER:
1093     case POINTER:
1094       return (NEARPTRSIZE);
1095     case EEPPOINTER:
1096     case FPOINTER:
1097     case CPOINTER:
1098       if (!IS_FUNCPTR(p))
1099         return (FARPTRSIZE);
1100     case FUNCTION:
1101       return (IFFUNC_ISBANKEDCALL (p) ? BFUNCPTRSIZE : FUNCPTRSIZE);
1102     case GPOINTER:
1103       return (GPTRSIZE);
1104 
1105     default:
1106       return 0;
1107     }
1108 }
1109 
1110 #define FLEXARRAY   1
1111 #define INCOMPLETE  2
1112 
1113 /*------------------------------------------------------------------*/
1114 /* checkStructFlexArray - check tree behind a struct                */
1115 /*------------------------------------------------------------------*/
1116 static int
checkStructFlexArray(symbol * sym,sym_link * p)1117 checkStructFlexArray (symbol * sym, sym_link * p)
1118 {
1119   /* if nothing return FALSE */
1120   if (!p)
1121     return 0;
1122 
1123   if (IS_SPEC (p))
1124     {
1125       /* (nested) struct with flexible array member? */
1126       if (IS_STRUCT (p) && SPEC_STRUCT (p)->b_flexArrayMember)
1127         {
1128           werror (W_INVALID_FLEXARRAY);
1129           return INCOMPLETE;
1130         }
1131       /* or otherwise incomplete (nested) struct? */
1132       if (IS_STRUCT (p) && ((SPEC_STRUCT (p)->size == 0) || !SPEC_STRUCT (p)->fields))
1133         {
1134           return INCOMPLETE;
1135         }
1136       return 0;
1137     }
1138 
1139   /* this is a declarator */
1140   if (IS_ARRAY (p))
1141     {
1142       /* flexible array member? */
1143       if (!DCL_ELEM (p))
1144         {
1145           if (!options.std_c99)
1146             werror (W_C89_NO_FLEXARRAY);
1147           if (checkStructFlexArray (sym, p->next) == INCOMPLETE)
1148             werror (E_INCOMPLETE_FIELD, sym->name);
1149           return FLEXARRAY;
1150         }
1151       /* walk tree */
1152       return checkStructFlexArray (sym, p->next);
1153     }
1154   return 0;
1155 }
1156 
1157 /*------------------------------------------------------------------*/
1158 /* bitsForType - returns # of bits required to store this type      */
1159 /*------------------------------------------------------------------*/
1160 unsigned int
bitsForType(sym_link * p)1161 bitsForType (sym_link * p)
1162 {
1163   /* if nothing return 0 */
1164   if (!p)
1165     return 0;
1166 
1167   if (IS_SPEC (p))
1168     {                           /* if this is the specifier then */
1169       switch (SPEC_NOUN (p))
1170         {                       /* depending on the specifier type */
1171         case V_INT:
1172           if (IS_LONGLONG (p))
1173             return LONGLONGSIZE * 8;
1174           if (IS_LONG (p))
1175             return LONGSIZE * 8;
1176           return INTSIZE * 8;
1177         case V_FLOAT:
1178           return FLOATSIZE * 8;
1179         case V_FIXED16X16:
1180           return (32);
1181         case V_BOOL:
1182           return BOOLSIZE * 8;
1183         case V_CHAR:
1184           return CHARSIZE * 8;
1185         case V_VOID:
1186           return 0;
1187         case V_STRUCT:
1188           return SPEC_STRUCT (p)->size * 8;
1189         case V_LABEL:
1190           return 0;
1191         case V_SBIT:
1192         case V_BIT:
1193           return 1;
1194         case V_BITFIELD:
1195         case V_BBITFIELD:
1196           return SPEC_BLEN (p);
1197         default:
1198           return 0;
1199         }
1200     }
1201 
1202   /* this is a specifier  */
1203   switch (DCL_TYPE (p))
1204     {
1205     case ARRAY:
1206       return DCL_ELEM (p) * getSize (p->next) * 8;
1207     case IPOINTER:
1208     case PPOINTER:
1209     case POINTER:
1210       return (NEARPTRSIZE * 8);
1211     case EEPPOINTER:
1212     case FPOINTER:
1213     case CPOINTER:
1214     case FUNCTION:
1215       return (FARPTRSIZE * 8);
1216     case GPOINTER:
1217       return (GPTRSIZE * 8);
1218     default:
1219       return 0;
1220     }
1221 }
1222 
1223 /*------------------------------------------------------------------*/
1224 /* copySymbolChain - copies a symbol chain                          */
1225 /*------------------------------------------------------------------*/
1226 symbol *
copySymbolChain(const symbol * src)1227 copySymbolChain (const symbol * src)
1228 {
1229   symbol *dest;
1230 
1231   if (!src)
1232     return NULL;
1233 
1234   dest = copySymbol (src);
1235   dest->next = copySymbolChain (src->next);
1236   return dest;
1237 }
1238 
1239 /*------------------------------------------------------------------*/
1240 /* copySymbol - makes a copy of a symbol                            */
1241 /*------------------------------------------------------------------*/
1242 symbol *
copySymbol(const symbol * src)1243 copySymbol (const symbol * src)
1244 {
1245   symbol *dest;
1246 
1247   if (!src)
1248     return NULL;
1249 
1250   dest = newSymbol (src->name, src->level);
1251   memcpy (dest, src, sizeof (symbol));
1252   dest->level = src->level;
1253   dest->block = src->block;
1254   dest->ival = copyIlist (src->ival);
1255   dest->type = copyLinkChain (src->type);
1256   dest->etype = getSpec (dest->type);
1257   dest->next = NULL;
1258   dest->key = src->key;
1259   dest->allocreq = src->allocreq;
1260   return dest;
1261 }
1262 
1263 /*------------------------------------------------------------------*/
1264 /* reverseSyms - reverses the links for a symbol chain              */
1265 /*------------------------------------------------------------------*/
1266 symbol *
reverseSyms(symbol * sym)1267 reverseSyms (symbol * sym)
1268 {
1269   symbol *prev, *curr, *next;
1270 
1271   if (!sym)
1272     return NULL;
1273 
1274   prev = sym;
1275   curr = sym->next;
1276 
1277   while (curr)
1278     {
1279       next = curr->next;
1280       curr->next = prev;
1281       prev = curr;
1282       curr = next;
1283     }
1284   sym->next = (void *) NULL;
1285   return prev;
1286 }
1287 
1288 /*------------------------------------------------------------------*/
1289 /* reverseLink - reverses the links for a type chain                */
1290 /*------------------------------------------------------------------*/
1291 sym_link *
reverseLink(sym_link * type)1292 reverseLink (sym_link * type)
1293 {
1294   sym_link *prev, *curr, *next;
1295 
1296   if (!type)
1297     return NULL;
1298 
1299   prev = type;
1300   curr = type->next;
1301 
1302   while (curr)
1303     {
1304       next = curr->next;
1305       curr->next = prev;
1306       prev = curr;
1307       curr = next;
1308     }
1309   type->next = (void *) NULL;
1310   return prev;
1311 }
1312 
1313 /*------------------------------------------------------------------*/
1314 /* addSymChain - adds a symbol chain to the symboltable             */
1315 /*------------------------------------------------------------------*/
1316 void
addSymChain(symbol ** symHead)1317 addSymChain (symbol ** symHead)
1318 {
1319   symbol *sym;
1320   symbol *csym = NULL;
1321   symbol **symPtrPtr;
1322   int error = 0;
1323   int elemsFromIval = 0;
1324 
1325   for (sym = *symHead; sym != NULL; sym = sym->next)
1326     {
1327       changePointer (sym->type);
1328       checkTypeSanity (sym->etype, sym->name);
1329 
1330       if (IS_NORETURN (sym->etype))
1331         {
1332           SPEC_NORETURN (sym->etype) = 0;
1333           FUNC_ISNORETURN (sym->type) = 1;
1334         }
1335 
1336       if (!sym->level && !(IS_SPEC (sym->etype) && IS_TYPEDEF (sym->etype)))
1337         elemsFromIval = checkDecl (sym, 0);
1338       else
1339         {
1340           /* if this is an array without any dimension
1341              then update the dimension from the initial value */
1342           if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1343             elemsFromIval = DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1344         }
1345 
1346       /* if already exists in the symbol table on the same level, ignoring sublevels */
1347       if ((csym = findSymWithLevel (SymbolTab, sym)) && csym->level / LEVEL_UNIT == sym->level / LEVEL_UNIT)
1348         {
1349           /* if not formal parameter and not in file scope
1350              then show symbol redefined error
1351              else check if symbols have compatible types */
1352           if (!sym->_isparm && sym->level > 0)
1353             error = 1;
1354           else
1355             {
1356               /* If the previous definition was for an array with incomplete
1357                  type, and the new definition has completed the type, update
1358                  the original type to match */
1359               if (IS_ARRAY (csym->type) && IS_ARRAY (sym->type))
1360                 {
1361                   if (!DCL_ELEM (csym->type) && DCL_ELEM (sym->type))
1362                     DCL_ELEM (csym->type) = DCL_ELEM (sym->type);
1363                   if ((DCL_ELEM (csym->type) > DCL_ELEM (sym->type)) && elemsFromIval)
1364                     DCL_ELEM (sym->type) = DCL_ELEM (csym->type);
1365                 }
1366 
1367 #if 0
1368               /* If only one of the definitions used the "at" keyword, copy */
1369               /* the address to the other. */
1370               if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype) && IS_SPEC (sym->etype) && !SPEC_ABSA (sym->etype))
1371                 {
1372                   SPEC_ABSA (sym->etype) = 1;
1373                   SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1374                 }
1375               if (IS_SPEC (csym->etype) && !SPEC_ABSA (csym->etype) && IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1376                 {
1377                   SPEC_ABSA (csym->etype) = 1;
1378                   SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1379                 }
1380 #endif
1381 
1382               error = 0;
1383               if (csym->ival && sym->ival)
1384                 error = 1;
1385               if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1386                 error = 1;
1387             }
1388 
1389           if (error)
1390             {
1391               /* one definition extern ? */
1392               if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1393                 werror (E_EXTERN_MISMATCH, sym->name);
1394               else
1395                 werror (E_DUPLICATE, sym->name);
1396               werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1397 #if 0
1398               fprintf (stderr, "from type '");
1399               printTypeChain (csym->type, stderr);
1400               if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1401                 fprintf (stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1402               fprintf (stderr, "'\nto type '");
1403               printTypeChain (sym->type, stderr);
1404               if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1405                 fprintf (stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1406               fprintf (stderr, "'\n");
1407 #endif
1408               continue;
1409             }
1410 
1411           if (FUNC_BANKED (csym->type) || FUNC_BANKED (sym->type))
1412             {
1413               if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
1414                 {
1415                   werror (W_BANKED_WITH_NONBANKED);
1416                   FUNC_BANKED (sym->type) = 0;
1417                   FUNC_NONBANKED (sym->type) = 1;
1418                 }
1419               else
1420                 {
1421                   FUNC_BANKED (sym->type) = 1;
1422                 }
1423             }
1424           else
1425             {
1426               if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
1427                 {
1428                   FUNC_NONBANKED (sym->type) = 1;
1429                 }
1430             }
1431 
1432           if (csym->ival && !sym->ival)
1433             sym->ival = csym->ival;
1434 
1435           if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype))
1436             {
1437               /* if none of symbols is a compiler defined function
1438                  and at least one is not extern
1439                  then set the new symbol to non extern */
1440               SPEC_EXTR (sym->etype) = SPEC_EXTR (csym->etype);
1441             }
1442 
1443           /* delete current entry */
1444           deleteSym (SymbolTab, csym, csym->name);
1445           deleteFromSeg (csym);
1446 
1447           symPtrPtr = symHead;
1448           while (*symPtrPtr && *symPtrPtr != csym)
1449             symPtrPtr = &(*symPtrPtr)->next;
1450           if (*symPtrPtr == csym)
1451             *symPtrPtr = csym->next;
1452         }
1453 
1454       /* add new entry */
1455       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1456     }
1457 }
1458 
1459 
1460 /*------------------------------------------------------------------*/
1461 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1462 /*------------------------------------------------------------------*/
1463 int
funcInChain(sym_link * lnk)1464 funcInChain (sym_link * lnk)
1465 {
1466   while (lnk)
1467     {
1468       if (IS_FUNC (lnk))
1469         return 1;
1470       lnk = lnk->next;
1471     }
1472   return 0;
1473 }
1474 
1475 /*------------------------------------------------------------------*/
1476 /* structElemType - returns the type info of a struct member        */
1477 /*------------------------------------------------------------------*/
1478 sym_link *
structElemType(sym_link * stype,value * id)1479 structElemType (sym_link * stype, value * id)
1480 {
1481   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1482   sym_link *type, *etype;
1483   sym_link *petype = getSpec (stype);
1484 
1485   if (fields && id)
1486     {
1487       /* look for the id */
1488       while (fields)
1489         {
1490           if (strcmp (fields->rname, id->name) == 0)
1491             {
1492               sym_link *t;
1493               type = copyLinkChain (fields->type);
1494               etype = getSpec (type);
1495               SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? SPEC_SCLS (etype) : SPEC_SCLS (petype));
1496               SPEC_OCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? SPEC_OCLS (etype) : SPEC_OCLS (petype));
1497               /* find the first non-array link */
1498               t = type;
1499               while (IS_ARRAY (t))
1500                 t = t->next;
1501               if (IS_SPEC (t))
1502                 SPEC_CONST (t) |= SPEC_CONST (stype);
1503               else
1504                 DCL_PTR_CONST (t) |= SPEC_CONST (stype);
1505               return type;
1506             }
1507           fields = fields->next;
1508         }
1509     }
1510 
1511   werror (E_NOT_MEMBER, id->name);
1512 
1513   // the show must go on
1514   return newIntLink ();
1515 }
1516 
1517 /*------------------------------------------------------------------*/
1518 /* getStructElement - returns element of a tructure definition      */
1519 /*------------------------------------------------------------------*/
1520 symbol *
getStructElement(structdef * sdef,symbol * sym)1521 getStructElement (structdef * sdef, symbol * sym)
1522 {
1523   symbol *field;
1524 
1525   for (field = sdef->fields; field; field = field->next)
1526     if (strcmp (field->name, sym->name) == 0)
1527       return field;
1528 
1529   werror (E_NOT_MEMBER, sym->name);
1530 
1531   return sdef->fields;
1532 }
1533 
1534 /*------------------------------------------------------------------*/
1535 /* compStructSize - computes the size of a structure                */
1536 /*------------------------------------------------------------------*/
1537 int
compStructSize(int su,structdef * sdef)1538 compStructSize (int su, structdef * sdef)
1539 {
1540   int sum = 0, usum = 0;
1541   int bitOffset = 0;
1542   symbol *loop;
1543   const int oldlineno = lineno;
1544 
1545   if (!sdef->fields)
1546     {
1547       werror (E_UNKNOWN_SIZE, sdef->tag);
1548     }
1549 
1550   /* for the identifiers  */
1551   loop = sdef->fields;
1552   while (loop)
1553     {
1554       lineno = loop->lineDef;
1555 
1556       /* create the internal name for this variable */
1557       SNPRINTF (loop->rname, sizeof (loop->rname), "_%s", loop->name);
1558       if (su == UNION)
1559         {
1560           sum = 0;
1561           bitOffset = 0;
1562         }
1563       SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1564 
1565       /* if this is a bit field  */
1566       if (loop->bitVar)
1567         {
1568           SPEC_BUNNAMED (loop->etype) = loop->bitUnnamed;
1569 
1570           /* change it to a unsigned bit */
1571           switch (SPEC_NOUN (loop->etype))
1572             {
1573             case V_BOOL:
1574               SPEC_NOUN( loop->etype) = V_BBITFIELD;
1575               if (loop->bitVar > 1)
1576                 werror (E_BITFLD_SIZE, 1);
1577               break;
1578             case V_CHAR:
1579               SPEC_NOUN (loop->etype) = V_BITFIELD;
1580               if (loop->bitVar > 8)
1581                 werror (E_BITFLD_SIZE , 8);
1582               break;
1583             case V_INT:
1584               SPEC_NOUN (loop->etype) = V_BITFIELD;
1585               if (loop->bitVar > port->s.int_size * 8)
1586                 werror (E_BITFLD_SIZE , port->s.int_size * 8);
1587               break;
1588             default:
1589               werror (E_BITFLD_TYPE);
1590             }
1591 
1592           /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
1593           /* a "plain" int bitfield is unsigned */
1594           if (!loop->etype->select.s.b_signed)
1595             SPEC_USIGN (loop->etype) = 1;
1596 
1597           if (loop->bitVar == BITVAR_PAD)
1598             {
1599               /* A zero length bitfield forces padding */
1600               SPEC_BLEN (loop->etype) = 0;
1601               SPEC_BSTR (loop->etype) = bitOffset;
1602               if (bitOffset > 0)
1603                 bitOffset = 8;  /* padding is not needed when at bit 0 */
1604               loop->offset = sum;
1605             }
1606           else
1607             {
1608               SPEC_BLEN (loop->etype) = loop->bitVar;
1609 
1610               if (bitOffset == 8)
1611                 {
1612                   bitOffset = 0;
1613                   sum++;
1614                 }
1615               /* check if this fit into the remaining   */
1616               /* bits of this byte else align it to the */
1617               /* next byte boundary                     */
1618               if (loop->bitVar <= (8 - bitOffset))
1619                 {
1620                   /* fits into current byte */
1621                   loop->offset = sum;
1622                   SPEC_BSTR (loop->etype) = bitOffset;
1623                   bitOffset += loop->bitVar;
1624                 }
1625               else if (!bitOffset)
1626                 {
1627                   /* does not fit, but is already byte aligned */
1628                   loop->offset = sum;
1629                   SPEC_BSTR (loop->etype) = bitOffset;
1630                   bitOffset += loop->bitVar;
1631                 }
1632               else
1633                 {
1634                   if (TARGET_IS_PIC16 && getenv ("PIC16_PACKED_BITFIELDS"))
1635                     {
1636                       /* if PIC16 && enviroment variable is set, then
1637                        * tightly pack bitfields, this means that when a
1638                        * bitfield goes beyond byte alignment, do not
1639                        * automatically start allocatint from next byte,
1640                        * but also use the available bits first */
1641                       fprintf (stderr, ": packing bitfields in structures\n");
1642                       SPEC_BSTR (loop->etype) = bitOffset;
1643                       bitOffset += loop->bitVar;
1644                       loop->offset = (su == UNION ? sum = 0 : sum);
1645                     }
1646                   else
1647                     {
1648                       /* does not fit; need to realign first */
1649                       sum++;
1650                       loop->offset = (su == UNION ? sum = 0 : sum);
1651                       bitOffset = 0;
1652                       SPEC_BSTR (loop->etype) = bitOffset;
1653                       bitOffset += loop->bitVar;
1654                     }
1655                 }
1656               while (bitOffset > 8)
1657                 {
1658                   bitOffset -= 8;
1659                   sum++;
1660                 }
1661             }
1662         }
1663       else
1664         {
1665           /* This is a non-bit field. Make sure we are */
1666           /* byte aligned first */
1667           if (bitOffset)
1668             {
1669               sum++;
1670               loop->offset = (su == UNION ? sum = 0 : sum);
1671               bitOffset = 0;
1672             }
1673           loop->offset = sum;
1674           checkDecl (loop, 1);
1675           sum += getSize (loop->type);
1676 
1677           /* search for "flexible array members" */
1678           /* and do some syntax checks */
1679           if (su == STRUCT)
1680             {
1681               int ret = checkStructFlexArray (loop, loop->type);
1682               if (ret == FLEXARRAY)
1683                 {
1684                   /* found a "flexible array member" */
1685                   sdef->b_flexArrayMember = TRUE;
1686                   /* is another struct-member following? */
1687                   if (loop->next)
1688                     werror (E_FLEXARRAY_NOTATEND, loop->name);
1689                   /* is it the first struct-member? */
1690                   else if (loop == sdef->fields)
1691                     werror (E_FLEXARRAY_INEMPTYSTRCT, loop->name);
1692                 }
1693               else if (ret == INCOMPLETE)
1694                 {
1695                   werror (E_INCOMPLETE_FIELD, loop->name);
1696                 }
1697             }
1698         }
1699 
1700       loop = loop->next;
1701 
1702       /* if union then size = sizeof largest field */
1703       if (su == UNION)
1704         {
1705           /* For UNION, round up after each field */
1706           sum += ((bitOffset + 7) / 8);
1707           usum = max (usum, sum);
1708         }
1709     }
1710 
1711   /* For STRUCT, round up after all fields processed */
1712   if (su != UNION)
1713     sum += ((bitOffset + 7) / 8);
1714 
1715   lineno = oldlineno;
1716 
1717   return (su == UNION ? usum : sum);
1718 }
1719 
1720 /*-------------------------------------------------------------------*/
1721 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1722 /*                      an enclosing struct/union                    */
1723 /*-------------------------------------------------------------------*/
1724 void
promoteAnonStructs(int su,structdef * sdef)1725 promoteAnonStructs (int su, structdef * sdef)
1726 {
1727   symbol *field;
1728   symbol *subfield;
1729   symbol **tofield;
1730   symbol *nextfield;
1731   symbol *dupfield;
1732   int base;
1733 
1734   tofield = &sdef->fields;
1735   field = sdef->fields;
1736   while (field)
1737     {
1738       nextfield = field->next;
1739       if (!*field->name && IS_STRUCT (field->type))
1740         {
1741           /* Found an anonymous struct/union. Replace it */
1742           /* with the fields it contains and adjust all  */
1743           /* the offsets */
1744 
1745           /* tagged anonymous struct/union is rejected here, though gcc allow it */
1746           if (SPEC_STRUCT (field->type)->tagsym != NULL)
1747             werrorfl (field->fileDef, field->lineDef, E_ANONYMOUS_STRUCT_TAG, SPEC_STRUCT (field->type)->tag);
1748 
1749           base = field->offset;
1750           subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1751           if (!subfield)
1752             continue;           /* just in case it's empty */
1753 
1754           *tofield = subfield;
1755           for (;;)
1756             {
1757               /* check for field name conflicts resulting from promotion */
1758               dupfield = sdef->fields;
1759               while (dupfield && dupfield != subfield)
1760                 {
1761                   if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1762                     {
1763                       werrorfl (subfield->fileDef, subfield->lineDef,
1764                                 E_DUPLICATE_MEMBER, su == STRUCT ? "struct" : "union", subfield->name);
1765                       werrorfl (dupfield->fileDef, dupfield->lineDef, E_PREVIOUS_DEF);
1766                     }
1767                   dupfield = dupfield->next;
1768                 }
1769 
1770               subfield->offset += base;
1771               if (subfield->next)
1772                 subfield = subfield->next;
1773               else
1774                 break;
1775             }
1776           subfield->next = nextfield;
1777           tofield = &subfield->next;
1778         }
1779       else
1780         tofield = &field->next;
1781       field = nextfield;
1782     }
1783 }
1784 
1785 
1786 /*------------------------------------------------------------------*/
1787 /* checkSClass - check the storage class specification              */
1788 /*------------------------------------------------------------------*/
1789 static void
checkSClass(symbol * sym,int isProto)1790 checkSClass (symbol *sym, int isProto)
1791 {
1792   sym_link *t;
1793 
1794   if (getenv ("DEBUG_SANITY"))
1795     {
1796       fprintf (stderr, "checkSClass: %s \n", sym->name);
1797     }
1798 
1799   if (!sym->level && SPEC_SCLS (sym->etype) == S_AUTO)
1800    {
1801      werrorfl (sym->fileDef, sym->lineDef, E_AUTO_FILE_SCOPE);
1802      SPEC_SCLS (sym->etype) = S_FIXED;
1803    }
1804 
1805   /* type is literal can happen for enums change to auto */
1806   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1807     SPEC_SCLS (sym->etype) = S_AUTO;
1808 
1809   /* if sfr or sbit then must also be volatile */
1810   if (SPEC_SCLS (sym->etype) == S_SBIT || SPEC_SCLS (sym->etype) == S_SFR)
1811     {
1812       SPEC_VOLATILE (sym->etype) = 1;
1813     }
1814 
1815   if (SPEC_NEEDSPAR (sym->etype))
1816     {
1817       werrorfl (sym->fileDef, sym->lineDef, E_QUALIFIED_ARRAY_NOPARAM);
1818       SPEC_NEEDSPAR (sym->etype) = 0;
1819     }
1820 
1821   /* make sure restrict is only used with pointers */
1822   if (SPEC_RESTRICT (sym->etype))
1823     {
1824       werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1825       SPEC_RESTRICT (sym->etype) = 0;
1826     }
1827 
1828   t = sym->type;
1829   while (t)
1830     {
1831       if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !(IS_PTR (t) && !IS_FUNCPTR(t)))
1832         {
1833           werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1834           DCL_PTR_RESTRICT (t) = 0;
1835           break;
1836         }
1837       t = t->next;
1838     }
1839 
1840   /* if absolute address given then it mark it as
1841      volatile -- except in the PIC port */
1842 
1843 #if !OPT_DISABLE_PIC14 || !OPT_DISABLE_PIC16
1844   /* The PIC port uses a different peep hole optimizer based on "pCode" */
1845   if (!TARGET_PIC_LIKE)
1846 #endif
1847 
1848   if (IS_ABSOLUTE (sym->etype))
1849     SPEC_VOLATILE (sym->etype) = 1;
1850 
1851   if (TARGET_IS_MCS51 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
1852     {
1853       int n, size;
1854       unsigned addr;
1855 
1856       if (SPEC_NOUN (sym->etype) == V_CHAR)
1857         size = 8;
1858       else if (SPEC_LONG (sym->etype) == 0)
1859         size = 16;
1860       else if (SPEC_LONGLONG (sym->etype) == 0)
1861         size = 32;
1862       else
1863         size = 64;
1864 
1865       addr = SPEC_ADDR (sym->etype);
1866       for (n = 0; n < size; n += 8)
1867         if (((addr >> n) & 0xFF) < 0x80)
1868           werror (W_SFR_ABSRANGE, sym->name);
1869     }
1870   else if (TARGET_Z80_LIKE && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
1871     {
1872       if (SPEC_ADDR (sym->etype) > (FUNC_REGBANK (sym->type) ? 0xffff : 0xff))
1873         werror (W_SFR_ABSRANGE, sym->name);
1874     }
1875   else if (TARGET_IS_PDK13 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
1876    {
1877      if (SPEC_ADDR (sym->etype) > 0x1f)
1878         werror (W_SFR_ABSRANGE, sym->name);
1879    }
1880   else if (TARGET_IS_PDK14 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
1881    {
1882      if (SPEC_ADDR (sym->etype) > 0x3f)
1883         werror (W_SFR_ABSRANGE, sym->name);
1884    }
1885   else if (TARGET_IS_PDK15 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
1886    {
1887      if (SPEC_ADDR (sym->etype) > 0x7f)
1888         werror (W_SFR_ABSRANGE, sym->name);
1889    }
1890   else if (TARGET_IS_PDK16 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
1891    {
1892      if (SPEC_ADDR (sym->etype) > 0x1f)
1893         werror (W_SFR_ABSRANGE, sym->name);
1894    }
1895 
1896   /* If code memory is read only, then pointers to code memory */
1897   /* implicitly point to constants -- make this explicit       */
1898   CodePtrPointsToConst (sym->type);
1899 
1900   /* global variables declared const put into code */
1901   /* if no other storage class specified */
1902   if ((sym->level == 0 || SPEC_STAT(sym->etype)) && SPEC_SCLS (sym->etype) == S_FIXED && !IS_FUNC (sym->type))
1903     {
1904       /* find the first non-array link */
1905       t = sym->type;
1906       while (IS_ARRAY (t))
1907         t = t->next;
1908       if (IS_CONSTANT (t))
1909         SPEC_SCLS (sym->etype) = S_CODE;
1910     }
1911 
1912   /* global variable in code space is a constant */
1913   if ((sym->level == 0 || SPEC_STAT(sym->etype)) && SPEC_SCLS (sym->etype) == S_CODE && port->mem.code_ro)
1914     {
1915       /* find the first non-array link */
1916       t = sym->type;
1917       while (IS_ARRAY (t))
1918         t = t->next;
1919       if (IS_SPEC (t))
1920         SPEC_CONST (t) = 1;
1921       else
1922         DCL_PTR_CONST (t) = 1;
1923     }
1924 
1925   /* if bit variable then no storage class can be */
1926   /* specified since bit is already a storage */
1927   if (IS_BITVAR (sym->etype) &&
1928       (SPEC_SCLS (sym->etype) != S_FIXED && SPEC_SCLS (sym->etype) != S_SBIT && SPEC_SCLS (sym->etype) != S_BIT))
1929     {
1930       /* find out if this is the return type of a function */
1931       t = sym->type;
1932       while (t && t->next != sym->etype)
1933         t = t->next;
1934       if (!t || t->next != sym->etype || !IS_FUNC (t))
1935         {
1936           werror (E_BITVAR_STORAGE, sym->name);
1937           SPEC_SCLS (sym->etype) = S_FIXED;
1938         }
1939     }
1940 
1941   /* if this is an automatic symbol */
1942   if (sym->level && (options.stackAuto || reentrant))
1943     {
1944       if (SPEC_SCLS (sym->etype) != S_BIT &&
1945           SPEC_SCLS (sym->etype) != S_REGISTER)
1946         {
1947           if ((SPEC_SCLS (sym->etype) == S_AUTO     ||
1948                SPEC_SCLS (sym->etype) == S_FIXED    ||
1949                SPEC_SCLS (sym->etype) == S_STACK    ||
1950                SPEC_SCLS (sym->etype) == S_XSTACK))
1951             {
1952               SPEC_SCLS (sym->etype) = S_AUTO;
1953             }
1954           else
1955             {
1956               /* storage class may only be specified for statics */
1957               if (!IS_STATIC (sym->etype))
1958                 {
1959                   werror (E_AUTO_ASSUMED, sym->name);
1960                 }
1961             }
1962         }
1963     }
1964 
1965   /* automatic symbols cannot be given   */
1966   /* an absolute address ignore it      */
1967   if (sym->level && !IS_STATIC (sym->etype) && SPEC_ABSA (sym->etype) && (options.stackAuto || reentrant))
1968     {
1969       werror (E_AUTO_ABSA, sym->name);
1970       SPEC_ABSA (sym->etype) = 0;
1971     }
1972 
1973   if (sym->level && !IS_STATIC (sym->etype) && (IS_DECL (sym->type) ? DCL_PTR_ADDRSPACE (sym->type) : SPEC_ADDRSPACE (sym->type)) && (options.stackAuto || reentrant))
1974     {
1975       werror (E_AUTO_ADDRSPACE, sym->name);
1976       if (IS_DECL (sym->type))
1977         DCL_PTR_ADDRSPACE (sym->type) = 0;
1978       else
1979         SPEC_ADDRSPACE (sym->type) = 0;
1980     }
1981 
1982   /* arrays & pointers cannot be defined for bits   */
1983   /* SBITS or SFRs or BIT                           */
1984   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1985       (SPEC_NOUN (sym->etype) == V_BIT      || SPEC_NOUN (sym->etype) == V_SBIT      ||
1986        SPEC_NOUN (sym->etype) == V_BITFIELD || SPEC_NOUN (sym->etype) == V_BBITFIELD ||
1987        SPEC_SCLS (sym->etype) == S_SFR))
1988     {
1989       /* find out if this is the return type of a function */
1990       t = sym->type;
1991       while (t && t->next != sym->etype)
1992         t = t->next;
1993       if (t->next != sym->etype || !IS_FUNC (t))
1994         {
1995           werror (E_BIT_ARRAY, sym->name);
1996         }
1997     }
1998 
1999   /* if this is a bit|sbit then set length & start  */
2000   if (SPEC_NOUN (sym->etype) == V_BIT || SPEC_NOUN (sym->etype) == V_SBIT)
2001     {
2002       SPEC_BLEN (sym->etype) = 1;
2003       SPEC_BSTR (sym->etype) = 0;
2004     }
2005 
2006   if (!isProto)
2007     {
2008       /* variables declared in CODE space must have */
2009       /* initializers if not an extern, a global or a static */
2010       if (SPEC_SCLS (sym->etype) == S_CODE && sym->ival == NULL && !sym->_isparm &&
2011           IS_AUTO(sym) &&
2012           port->mem.code_ro && !SPEC_ABSA (sym->etype) && !funcInChain (sym->type))
2013         werror (E_CODE_NO_INIT, sym->name);
2014     }
2015 
2016   /* if parameter or local variable then change */
2017   /* the storage class to reflect where the var will go */
2018   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED && !IS_STATIC (sym->etype))
2019     {
2020       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2021         {
2022           SPEC_SCLS (sym->etype) = (options.useXstack ? S_XSTACK : S_STACK);
2023         }
2024     }
2025 }
2026 
2027 /*------------------------------------------------------------------*/
2028 /* changePointer - change pointer to functions                      */
2029 /*------------------------------------------------------------------*/
2030 void
changePointer(sym_link * p)2031 changePointer (sym_link * p)
2032 {
2033   /* go thru the chain of declarations   */
2034   /* if we find a pointer to a function  */
2035   /* change it to a ptr to code area     */
2036   /* unless the function is banked.      */
2037   for (; p; p = p->next)
2038     {
2039       if (IS_DECL (p) && DCL_TYPE (p) == UPOINTER)
2040         DCL_TYPE (p) = port->unqualified_pointer;
2041       if (IS_PTR (p) && IS_FUNC (p->next))
2042         if (!IFFUNC_ISBANKEDCALL (p->next))
2043           DCL_TYPE (p) = CPOINTER;
2044     }
2045 }
2046 
2047 /*------------------------------------------------------------------*/
2048 /* checkDecl - does semantic validation of a declaration            */
2049 /*------------------------------------------------------------------*/
2050 int
checkDecl(symbol * sym,int isProto)2051 checkDecl (symbol * sym, int isProto)
2052 {
2053   checkSClass (sym, isProto);   /* check the storage class     */
2054   changePointer (sym->type);    /* change pointers if required */
2055 
2056   /* if this is an array without any dimension
2057      then update the dimension from the initial value */
2058   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
2059     return DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
2060 
2061   return 0;
2062 }
2063 
2064 /*------------------------------------------------------------------*/
2065 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
2066 /*------------------------------------------------------------------*/
2067 sym_link *
copyLinkChain(const sym_link * p)2068 copyLinkChain (const sym_link *p)
2069 {
2070   sym_link *head, *loop;
2071   const sym_link *curr;
2072 
2073   /* note: v_struct and v_struct->fields are not copied! */
2074   curr = p;
2075   head = loop = (curr ? newLink (p->xclass) : (void *) NULL);
2076   while (curr)
2077     {
2078       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
2079       loop->next = (curr->next ? newLink (curr->next->xclass) : (void *) NULL);
2080       loop = loop->next;
2081       curr = curr->next;
2082     }
2083 
2084   return head;
2085 }
2086 
2087 /*------------------------------------------------------------------*/
2088 /* cleanUpBlock - cleansup the symbol table specified for all the   */
2089 /*                symbols in the given block                        */
2090 /*------------------------------------------------------------------*/
2091 void
cleanUpBlock(bucket ** table,int block)2092 cleanUpBlock (bucket ** table, int block)
2093 {
2094   int i;
2095   bucket *chain;
2096 
2097   /* go thru the entire  table  */
2098   for (i = 0; i < 256; i++)
2099     {
2100       for (chain = table[i]; chain; chain = chain->next)
2101         {
2102           if (chain->block >= block)
2103             {
2104               deleteSym (table, chain->sym, chain->name);
2105             }
2106         }
2107     }
2108 }
2109 
2110 /*------------------------------------------------------------------*/
2111 /* cleanUpLevel - cleans up the symbol table specified for all the  */
2112 /*                symbols in the given level                        */
2113 /*------------------------------------------------------------------*/
2114 void
cleanUpLevel(bucket ** table,long level)2115 cleanUpLevel (bucket ** table, long level)
2116 {
2117   int i;
2118   bucket *chain;
2119 
2120   /* go thru the entire  table  */
2121   for (i = 0; i < 256; i++)
2122     {
2123       for (chain = table[i]; chain; chain = chain->next)
2124         {
2125           if (chain->level >= level)
2126             {
2127               deleteSym (table, chain->sym, chain->name);
2128             }
2129         }
2130     }
2131 }
2132 
2133 symbol *
getAddrspace(sym_link * type)2134 getAddrspace (sym_link *type)
2135 {
2136   if (IS_DECL (type))
2137     return (DCL_PTR_ADDRSPACE (type));
2138   return (SPEC_ADDRSPACE (type));
2139 }
2140 
2141 /*------------------------------------------------------------------*/
2142 /* computeTypeOr - computes the resultant type from two types       */
2143 /*------------------------------------------------------------------*/
2144 static sym_link *
computeTypeOr(sym_link * etype1,sym_link * etype2,sym_link * reType)2145 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
2146 {
2147   /* sanity check */
2148   assert ((IS_CHAR (etype1) || IS_BOOLEAN (etype1)) &&
2149           (IS_CHAR (etype2) || IS_BOOLEAN (etype2)));
2150 
2151   if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
2152     {
2153       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
2154       return reType;
2155     }
2156 
2157   if (SPEC_USIGN (etype1))
2158     {
2159       if (IS_LITERAL (etype2) && floatFromVal (valFromType (etype2)) >= 0)
2160         SPEC_USIGN (reType) = 1;
2161       else
2162         {
2163           /* promote to int */
2164           SPEC_USIGN (reType) = 0;
2165           SPEC_NOUN (reType) = V_INT;
2166         }
2167     }
2168   else                          /* etype1 signed */
2169     {
2170       if (IS_LITERAL (etype2) && floatFromVal (valFromType (etype2)) <= 127)
2171         SPEC_USIGN (reType) = 0;
2172       else
2173         {
2174           /* promote to int */
2175           SPEC_USIGN (reType) = 0;
2176           SPEC_NOUN (reType) = V_INT;
2177         }
2178     }
2179 
2180   if (SPEC_USIGN (etype2))
2181     {
2182       if (IS_LITERAL (etype1) && floatFromVal (valFromType (etype1)) >= 0)
2183         SPEC_USIGN (reType) = 1;
2184       else
2185         {
2186           /* promote to int */
2187           SPEC_USIGN (reType) = 0;
2188           SPEC_NOUN (reType) = V_INT;
2189         }
2190     }
2191   else                          /* etype2 signed */
2192     {
2193       if (IS_LITERAL (etype1) && floatFromVal (valFromType (etype1)) <= 127)
2194         SPEC_USIGN (reType) = 0;
2195       else
2196         {
2197           /* promote to int */
2198           SPEC_USIGN (reType) = 0;
2199           SPEC_NOUN (reType) = V_INT;
2200         }
2201     }
2202   return reType;
2203 }
2204 
2205 /*------------------------------------------------------------------*/
2206 /* computeType - computes the resultant type from two types         */
2207 /*------------------------------------------------------------------*/
2208 sym_link *
computeType(sym_link * type1,sym_link * type2,RESULT_TYPE resultType,int op)2209 computeType (sym_link * type1, sym_link * type2, RESULT_TYPE resultType, int op)
2210 {
2211   sym_link *rType;
2212   sym_link *reType;
2213   sym_link *etype1 = getSpec (type1);
2214   sym_link *etype2;
2215 
2216   etype2 = type2 ? getSpec (type2) : type1;
2217 
2218   /* Conditional operator has some special type conversion rules */
2219   if (op == ':')
2220     {
2221       /* If either type is an array, convert to pointer */
2222       if (IS_ARRAY(type1))
2223         {
2224           value * val = aggregateToPointer (valFromType (type1));
2225           type1 = val->type;
2226           Safe_free (val);
2227           etype1 = getSpec (type1);
2228         }
2229       if (IS_ARRAY(type2))
2230         {
2231           value * val = aggregateToPointer (valFromType (type2));
2232           type2 = val->type;
2233           Safe_free (val);
2234           etype2 = getSpec (type2);
2235         }
2236 
2237       /* If NULL and another pointer, use the non-NULL pointer type. */
2238       /* Note that NULL can be defined as either 0 or (void *)0. */
2239       if (IS_LITERAL (etype1) &&
2240           ((IS_PTR (type1) && IS_VOID (type1->next)) || IS_INTEGRAL (type1)) &&
2241           (floatFromVal (valFromType (etype1)) == 0) &&
2242           IS_PTR (type2))
2243         return copyLinkChain (type2);
2244       else if (IS_LITERAL (etype2) &&
2245                ((IS_PTR (type2) && IS_VOID (type2->next)) || IS_INTEGRAL (type2)) &&
2246                (floatFromVal (valFromType (etype2)) == 0) &&
2247                IS_PTR (type1))
2248         return copyLinkChain (type1);
2249 
2250       /* If a void pointer, use the void pointer type */
2251       else if (IS_PTR(type1) && IS_VOID(type1->next))
2252         return copyLinkChain (type1);
2253       else if (IS_PTR(type2) && IS_VOID(type2->next))
2254         return copyLinkChain (type2);
2255 
2256       /* Otherwise fall through to the general case */
2257     }
2258 
2259   /* shift operators have the important type in the left operand */
2260   if (op == LEFT_OP || op == RIGHT_OP)
2261     rType = copyLinkChain(type1);
2262 
2263   /* if one of them is a pointer or array then that prevails */
2264   else if (IS_PTR (type1) || IS_ARRAY (type1))
2265     rType = copyLinkChain (type1);
2266   else if (IS_PTR (type2) || IS_ARRAY (type2))
2267     rType = copyLinkChain (type2);
2268 
2269   /* if one of them is a float then result is a float */
2270   /* here we assume that the types passed are okay */
2271   /* and can be cast to one another                */
2272   /* which ever is greater in size */
2273   else if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
2274     rType = newFloatLink ();
2275   /* if both are fixed16x16 then result is float */
2276   else if (IS_FIXED16X16 (etype1) && IS_FIXED16X16 (etype2))
2277     rType = newFixed16x16Link ();
2278   else if (IS_FIXED16X16 (etype1) && IS_FLOAT (etype2))
2279     rType = newFloatLink ();
2280   else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2))
2281     rType = newFloatLink ();
2282 
2283   /* if only one of them is a bool variable then the other one prevails */
2284   else if (IS_BOOLEAN (etype1) && !IS_BOOLEAN (etype2))
2285     {
2286       rType = copyLinkChain (type2);
2287     }
2288   else if (IS_BOOLEAN (etype2) && !IS_BOOLEAN (etype1))
2289     {
2290       rType = copyLinkChain (type1);
2291     }
2292 
2293   /* if both are bitvars choose the larger one */
2294   else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
2295     rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ? copyLinkChain (type1) : copyLinkChain (type2);
2296 
2297   /* if only one of them is a bit variable then the other one prevails */
2298   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
2299     {
2300       rType = copyLinkChain (type2);
2301       /* bitfield can have up to 16 bits */
2302       if (getSize (etype1) > 1)
2303         SPEC_NOUN (getSpec (rType)) = V_INT;
2304     }
2305   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
2306     {
2307       rType = copyLinkChain (type1);
2308       /* bitfield can have up to 16 bits */
2309       if (getSize (etype2) > 1)
2310         SPEC_NOUN (getSpec (rType)) = V_INT;
2311     }
2312 
2313   else if (bitsForType (type1) > bitsForType (type2))
2314     rType = copyLinkChain (type1);
2315   else
2316     rType = copyLinkChain (type2);
2317 
2318   reType = getSpec (rType);
2319 
2320   /* avoid conflicting types */
2321   reType->select.s.b_signed = 0;
2322 
2323   /* if result is a literal then make not so */
2324   if (IS_LITERAL (reType))
2325     {
2326       SPEC_SCLS (reType) = S_REGISTER;
2327       SPEC_CONST (reType) = 0;
2328     }
2329 
2330   switch (resultType)
2331     {
2332     case RESULT_TYPE_IFX:
2333       if (TARGET_HC08_LIKE)
2334         break;
2335       //fallthrough
2336     case RESULT_TYPE_BOOL:
2337       if (op == ':')
2338         {
2339           SPEC_NOUN (reType) = V_BIT;
2340           return rType;
2341         }
2342       break;
2343     case RESULT_TYPE_CHAR:
2344       if (IS_BOOL (reType) || IS_BITVAR (reType))
2345         {
2346           SPEC_NOUN (reType) = V_CHAR;
2347           SPEC_SCLS (reType) = 0;
2348           SPEC_USIGN (reType) = 0;
2349           return rType;
2350         }
2351       break;
2352     case RESULT_TYPE_INT:
2353     case RESULT_TYPE_NONE:
2354     case RESULT_TYPE_OTHER:
2355     case RESULT_TYPE_GPTR:
2356       if (!IS_SPEC (rType))
2357         {
2358           return rType;
2359         }
2360       if (IS_BOOLEAN (reType))
2361         {
2362           SPEC_NOUN (reType) = V_CHAR;
2363           SPEC_SCLS (reType) = 0;
2364           SPEC_USIGN (reType) = 0;
2365           return rType;
2366         }
2367       else if (IS_BITFIELD (reType))
2368         {
2369           /* could be smarter, but it depends on the op */
2370           /* this is for the worst case: a multiplication of 4 * 4 bit */
2371           SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
2372           SPEC_SCLS (reType) = 0;
2373           SPEC_USIGN (reType) = 0;
2374           return rType;
2375         }
2376       else if (IS_CHAR (reType))
2377         {
2378           /* promotion of some special cases */
2379           switch (op)
2380             {
2381             case '|':
2382             case '^':
2383               return computeTypeOr (etype1, etype2, reType);
2384             case '&':
2385             case BITWISEAND:
2386               if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
2387                 {
2388                   SPEC_USIGN (reType) = 1;
2389                   return rType;
2390                 }
2391               break;
2392             case '*':
2393               SPEC_NOUN (reType) = V_INT;
2394               SPEC_USIGN (reType) = 0;
2395               return rType;
2396             case '/':
2397               /* if both are unsigned char then no promotion required */
2398               if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
2399                 {
2400                   SPEC_NOUN (reType) = V_INT;
2401                   SPEC_USIGN (reType) = 0;
2402                   return rType;
2403                 }
2404               break;
2405             default:
2406               break;
2407             }
2408         }
2409       break;
2410     default:
2411       break;
2412     }
2413 
2414   /* SDCC's sign promotion:
2415      - if one or both operands are unsigned, the resultant type will be unsigned
2416      (except char, see below)
2417      - if an operand is promoted to a larger type (char -> int, int -> long),
2418      the larger type will be signed
2419 
2420      SDCC tries hard to avoid promotion to int and does 8 bit calculation as
2421      much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
2422      the standard. The standard demands, that the result has to be the same
2423      "as if" the promotion would have been performed:
2424 
2425      - if the result of an operation with two char's is promoted to a
2426      larger type, the result will be signed.
2427 
2428      More sophisticated are these:
2429      - if the result of an operation with two char's is a char again,
2430      the result will only then be unsigned, if both operands are
2431      unsigned. In all other cases the result will be signed.
2432 
2433      This seems to be contradictionary to the first two rules, but it makes
2434      real sense (all types are char's):
2435 
2436      A signed char can be negative; this must be preserved in the result
2437      -1 * 100 = -100;
2438 
2439      Only if both operands are unsigned it's safe to make the result
2440      unsigned; this helps to avoid overflow:
2441      2 * 100 =  200;
2442 
2443      - ToDo: document '|', '^' and '&'
2444 
2445      Homework: - why is (200 * 200 < 0) true?
2446      - why is { char l = 200, r = 200; (r * l > 0) } true?
2447    */
2448 
2449   if (!IS_FLOAT (reType) && ((SPEC_USIGN (etype1)
2450                               /* if this operand is promoted to a larger type,
2451                                  then it will be promoted to a signed type */
2452                               && !(bitsForType (etype1) < bitsForType (reType))
2453                               /* char require special handling */
2454                               && !IS_CHAR (etype1)) ||  /* same for 2nd operand */
2455                              (SPEC_USIGN (etype2) && !(bitsForType (etype2) < bitsForType (reType)) && !IS_CHAR (etype2)) ||    /* if both are 'unsigned char' and not promoted
2456                                                                                                                                    let the result be unsigned too */
2457                              (SPEC_USIGN (etype1)
2458                               && SPEC_USIGN (etype2) && IS_CHAR (etype1) && IS_CHAR (etype2) && IS_CHAR (reType))))
2459     SPEC_USIGN (reType) = 1;
2460   else
2461     SPEC_USIGN (reType) = 0;
2462 
2463   return rType;
2464 }
2465 
2466 /*------------------------------------------------------------------*/
2467 /* compareFuncType - compare function prototypes                    */
2468 /*------------------------------------------------------------------*/
2469 int
compareFuncType(sym_link * dest,sym_link * src)2470 compareFuncType (sym_link * dest, sym_link * src)
2471 {
2472   value *exargs, *acargs;
2473   value *checkValue;
2474   int argCnt = 0;
2475   int i;
2476 
2477   /* if not type then some kind of error */
2478   if (!dest || !src)
2479     return 0;
2480 
2481   /* check the return value type   */
2482   if (compareType (dest->next, src->next) <= 0)
2483     return 0;
2484 
2485   /* Really, reentrant should match regardless of argCnt, but     */
2486   /* this breaks some existing code (the fp lib functions). If    */
2487   /* the first argument is always passed the same way, this       */
2488   /* lax checking is ok (but may not be true for in future ports) */
2489   if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt > 1)
2490     {
2491       //printf("argCnt = %d\n",argCnt);
2492       return 0;
2493     }
2494 
2495   if (IFFUNC_ISWPARAM (dest) != IFFUNC_ISWPARAM (src))
2496     {
2497       return 0;
2498     }
2499 
2500   if (IFFUNC_ISSHADOWREGS (dest) != IFFUNC_ISSHADOWREGS (src))
2501     {
2502       return 0;
2503     }
2504 
2505   if (IFFUNC_ISZ88DK_FASTCALL (dest) != IFFUNC_ISZ88DK_FASTCALL (src) ||
2506     IFFUNC_ISZ88DK_CALLEE (dest) != IFFUNC_ISZ88DK_CALLEE (src))
2507     return 0;
2508 
2509   for (i = 0; i < 9; i++)
2510     if (dest->funcAttrs.preserved_regs[i] > src->funcAttrs.preserved_regs[i])
2511       return 0;
2512 
2513   /* compare register bank */
2514   if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2515     { /* except for ISR's whose prototype need not match
2516          since they are the top of a call-tree and
2517          the prototype is only necessary for its vector in main */
2518       if (!IFFUNC_ISISR (dest) || !IFFUNC_ISISR (src))
2519         {
2520           return 0;
2521         }
2522     }
2523 
2524   /* compare expected args with actual args */
2525   exargs = FUNC_ARGS (dest);
2526   acargs = FUNC_ARGS (src);
2527 
2528   /* for all the expected args do */
2529   for (argCnt = 1; exargs && acargs; exargs = exargs->next, acargs = acargs->next, argCnt++)
2530     {
2531       /* If the actual argument is an array, any prototype
2532        * will have modified it to a pointer. Duplicate that
2533        * change here.
2534        */
2535       if (IS_AGGREGATE (acargs->type))
2536         {
2537           checkValue = copyValue (acargs);
2538           aggregateToPointer (checkValue);
2539         }
2540       else
2541         {
2542           checkValue = acargs;
2543         }
2544       if (IFFUNC_ISREENT (dest) && compareType (exargs->type, checkValue->type) <= 0)
2545         {
2546           return 0;
2547         }
2548       if (!IFFUNC_ISREENT (dest) && compareTypeExact (exargs->type, checkValue->type, 1) <= 0)
2549         {
2550           return 0;
2551         }
2552     }
2553 
2554   /* if one them ended we have a problem */
2555   if ((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type)))
2556     {
2557       return 0;
2558     }
2559 
2560   return 1;
2561 }
2562 
2563 int
comparePtrType(sym_link * dest,sym_link * src,bool bMustCast)2564 comparePtrType (sym_link *dest, sym_link *src, bool bMustCast)
2565 {
2566   int res;
2567 
2568   if (getAddrspace (src->next) != getAddrspace (dest->next))
2569     bMustCast = 1;
2570 
2571   if (IS_VOID (src->next) && IS_VOID (dest->next))
2572     return bMustCast ? -1 : 1;
2573   if ((IS_VOID (src->next) && !IS_VOID (dest->next)) || (!IS_VOID (src->next) && IS_VOID (dest->next)))
2574     return -1;
2575   res = compareType (dest->next, src->next);
2576 
2577   /* All function pointers can be cast (6.6 in the ISO C11 standard) TODO: What about address spaces? */
2578   if (res == 0 && !bMustCast && IS_DECL (src) && IS_FUNC (src->next) && IS_DECL (dest) && IS_FUNC (dest->next))
2579     return -1;
2580   else if (res == 1)
2581     return bMustCast ? -1 : 1;
2582   else if (res == -2)
2583     return bMustCast ? -1 : -2;
2584   else
2585     return res;
2586 }
2587 
2588 /*--------------------------------------------------------------------*/
2589 /* compareType - will do type check return 1 if match, 0 if no match, */
2590 /*               -1 if castable, -2 if only signedness differs        */
2591 /*--------------------------------------------------------------------*/
2592 int
compareType(sym_link * dest,sym_link * src)2593 compareType (sym_link *dest, sym_link *src)
2594 {
2595   if (!dest && !src)
2596     return 1;
2597 
2598   if (dest && !src)
2599     return 0;
2600 
2601   if (src && !dest)
2602     return 0;
2603 
2604   /* if dest is a declarator then */
2605   if (IS_DECL (dest))
2606     {
2607       if (IS_DECL (src))
2608         {
2609           if (IS_GENPTR (dest) && IS_GENPTR (src))
2610             {
2611               /* banked function pointer */
2612               if (IS_FUNC (src->next) && IS_VOID (dest->next))
2613                 return -1;
2614               if (IS_FUNC (dest->next) && IS_VOID (src->next))
2615                 return -1;
2616               return comparePtrType (dest, src, FALSE);
2617             }
2618 
2619           if (DCL_TYPE (src) == DCL_TYPE (dest))
2620             {
2621               if (IS_FUNC (src))
2622                 {
2623                   return compareFuncType (dest, src);
2624                 }
2625               return comparePtrType (dest, src, FALSE);
2626             }
2627           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID (src->next))
2628             {
2629               return -1;
2630             }
2631           if (IS_PTR (src) && (IS_GENPTR (dest) || ((DCL_TYPE (src) == POINTER) && (DCL_TYPE (dest) == IPOINTER))))
2632             {
2633               return comparePtrType (dest, src, TRUE);
2634             }
2635           if (IS_PTR (dest) && IS_ARRAY (src))
2636             {
2637               value *val = aggregateToPointer (valFromType (src));
2638               int res = compareType (dest, val->type);
2639               Safe_free (val->type);
2640               Safe_free (val);
2641               return res;
2642             }
2643           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2644             {
2645               return compareType (dest->next, src);
2646             }
2647           if (IS_PTR (dest) && IS_VOID (dest->next) && IS_FUNC (src))
2648             return -1;
2649 
2650           return 0;
2651         }
2652       else if (IS_PTR (dest) && IS_INTEGRAL (src))
2653         return -1;
2654       else
2655         return 0;
2656     }
2657 
2658   if (IS_PTR (src) && IS_VOID (dest))
2659     return -1;
2660 
2661   /* if one is a specifier and the other is not */
2662   if ((IS_SPEC (src) && !IS_SPEC (dest)) || (IS_SPEC (dest) && !IS_SPEC (src)))
2663     return 0;
2664 
2665   /* if one of them is a void then ok */
2666   if (SPEC_NOUN (dest) == V_VOID && SPEC_NOUN (src) != V_VOID)
2667     return -1;
2668 
2669   if (SPEC_NOUN (dest) != V_VOID && SPEC_NOUN (src) == V_VOID)
2670     return -1;
2671 
2672   if (SPEC_NOUN (src) == V_BBITFIELD && SPEC_NOUN (dest) != V_BBITFIELD || SPEC_NOUN (src) != V_BBITFIELD && SPEC_NOUN (dest) == V_BBITFIELD)
2673     return -1;
2674 
2675   /* if they are both bitfields then if the lengths
2676      and starts don't match */
2677   if (IS_BITFIELD (dest) && IS_BITFIELD (src) && (SPEC_BLEN (dest) != SPEC_BLEN (src) || SPEC_BSTR (dest) != SPEC_BSTR (src)))
2678     return -1;
2679 
2680   /* it is a specifier */
2681   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2682     {
2683       if ((SPEC_USIGN (dest) == SPEC_USIGN (src)) &&
2684           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2685           /* I would prefer
2686              bitsForType (dest) == bitsForType (src))
2687              instead of the next two lines, but the regression tests fail with
2688              them; I guess it's a problem with replaceCheaperOp  */
2689           (getSize (dest) == getSize (src)) &&
2690           (IS_BOOLEAN (dest) == IS_BOOLEAN (src)))
2691         return 1;
2692       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2693         return -1;
2694       else
2695         return 0;
2696     }
2697   else if (IS_STRUCT (dest))
2698     {
2699       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2700         return 0;
2701       else
2702         return 1;
2703     }
2704 
2705   if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2706     return -1;
2707 
2708   if (SPEC_LONG (dest) != SPEC_LONG (src))
2709     return -1;
2710 
2711   if (SPEC_LONGLONG (dest) != SPEC_LONGLONG (src))
2712     return -1;
2713 
2714   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2715     return -2;
2716 
2717   return 1;
2718 }
2719 
2720 /*--------------------------------------------------------------------*/
2721 /* compareTypeExact - will do type check return 1 if match exactly    */
2722 /*--------------------------------------------------------------------*/
2723 int
compareTypeExact(sym_link * dest,sym_link * src,long level)2724 compareTypeExact (sym_link * dest, sym_link * src, long level)
2725 {
2726   STORAGE_CLASS srcScls, destScls;
2727 
2728   if (!dest && !src)
2729     return 1;
2730 
2731   if (dest && !src)
2732     return 0;
2733 
2734   if (src && !dest)
2735     return 0;
2736 
2737   /* if dest is a declarator then */
2738   if (IS_DECL (dest))
2739     {
2740       if (IS_DECL (src))
2741         {
2742           if (DCL_TYPE (src) == DCL_TYPE (dest))
2743             {
2744               if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2745                 return 0;
2746               if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2747                 return 0;
2748               if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2749                 return 0;
2750               if (IS_FUNC (src))
2751                 {
2752                   value *exargs, *acargs, *checkValue;
2753 
2754                   /* verify function return type */
2755                   if (!compareTypeExact (dest->next, src->next, -1))
2756                     return 0;
2757                   if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2758                     return 0;
2759                   if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2760                     return 0;
2761                   if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2762                     return 0;
2763 #if 0
2764                   if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt > 1)
2765                     return 0;
2766 #endif
2767 
2768                   /* compare expected args with actual args */
2769                   exargs = FUNC_ARGS (dest);
2770                   acargs = FUNC_ARGS (src);
2771 
2772                   /* for all the expected args do */
2773                   for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2774                     {
2775                       //checkTypeSanity(acargs->etype, acargs->name);
2776 
2777                       if (IS_AGGREGATE (acargs->type))
2778                         {
2779                           checkValue = copyValue (acargs);
2780                           aggregateToPointer (checkValue);
2781                         }
2782                       else
2783                         checkValue = acargs;
2784 
2785 #if 0
2786                       if (!compareTypeExact (exargs->type, checkValue->type, -1))
2787                         return 0;
2788 #endif
2789                     }
2790 
2791                   /* if one them ended we have a problem */
2792                   if ((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type)))
2793                     return 0;
2794                   return 1;
2795                 }
2796               return compareTypeExact (dest->next, src->next, level);
2797             }
2798           return 0;
2799         }
2800       return 0;
2801     }
2802 
2803   /* if one is a specifier and the other is not */
2804   if ((IS_SPEC (src) && !IS_SPEC (dest)) || (IS_SPEC (dest) && !IS_SPEC (src)))
2805     return 0;
2806 
2807   /* if they have a different noun */
2808   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2809     return 0;
2810 
2811   /* if they are both bitfields then if the lengths
2812      and starts don't match */
2813   if (IS_BITFIELD (dest) && IS_BITFIELD (src) && (SPEC_BLEN (dest) != SPEC_BLEN (src) || SPEC_BSTR (dest) != SPEC_BSTR (src)))
2814     return 0;
2815 
2816   if (IS_INTEGRAL (dest))
2817     {
2818       /* signedness must match */
2819       if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2820         return 0;
2821       /* size must match */
2822       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2823         return 0;
2824       if (SPEC_LONG (dest) != SPEC_LONG (src))
2825         return 0;
2826       if (SPEC_LONGLONG (dest) != SPEC_LONGLONG (src))
2827         return 0;
2828     }
2829 
2830   if (IS_STRUCT (dest))
2831     {
2832       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2833         return 0;
2834     }
2835 
2836   if (SPEC_CONST (dest) != SPEC_CONST (src))
2837     return 0;
2838   if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2839     return 0;
2840   if (SPEC_STAT (dest) != SPEC_STAT (src))
2841     return 0;
2842   if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2843     return 0;
2844   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2845     return 0;
2846 
2847   destScls = SPEC_SCLS (dest);
2848   srcScls = SPEC_SCLS (src);
2849 
2850   /* Compensate for const to const code change in checkSClass() */
2851   if (((!level) & port->mem.code_ro) && SPEC_CONST (dest))
2852     {
2853       if (srcScls == S_CODE && destScls == S_FIXED)
2854         destScls = S_CODE;
2855       if (destScls == S_CODE && srcScls == S_FIXED)
2856         srcScls = S_CODE;
2857     }
2858 
2859   /* compensate for allocGlobal() */
2860   if ((srcScls == S_FIXED || srcScls == S_AUTO) &&
2861       (port->mem.default_globl_map == xdata) && (destScls == S_XDATA) && (level <= 0))
2862     {
2863       srcScls = S_XDATA;
2864     }
2865 
2866   if ((level > 0) && !SPEC_STAT (dest))
2867     {
2868       /* Compensate for hack-o-matic in checkSClass() */
2869       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2870         {
2871           if (destScls == S_FIXED)
2872             destScls = (options.useXstack ? S_XSTACK : S_STACK);
2873           if (srcScls == S_FIXED)
2874             srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2875         }
2876       else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack || TARGET_IS_HC08 || TARGET_IS_S08)
2877         {
2878           if (destScls == S_FIXED)
2879             destScls = S_XDATA;
2880           if (srcScls == S_FIXED)
2881             srcScls = S_XDATA;
2882         }
2883     }
2884 
2885   if (srcScls != destScls)
2886     {
2887 #if 0
2888       printf ("level = %ld:%ld\n", level / LEVEL_UNIT, level % LEVEL_UNIT);
2889       printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n", SPEC_SCLS (src), SPEC_SCLS (dest));
2890       printf ("srcScls = %d, destScls = %d\n", srcScls, destScls);
2891 #endif
2892       return 0;
2893     }
2894 
2895   return 1;
2896 }
2897 
2898 /*---------------------------------------------------------------------------*/
2899 /* compareTypeInexact - will do type check return 1 if representation is same. */
2900 /* Useful for redundancy elimination.                                        */
2901 /*---------------------------------------------------------------------------*/
2902 int
compareTypeInexact(sym_link * dest,sym_link * src)2903 compareTypeInexact (sym_link *dest, sym_link *src)
2904 {
2905   if (!dest && !src)
2906     return 1;
2907 
2908   if (dest && !src)
2909     return 0;
2910 
2911   if (src && !dest)
2912     return 0;
2913 
2914   if (IS_BITFIELD (dest) != IS_BITFIELD (src))
2915     return 0;
2916 
2917   if (IS_BITFIELD (dest) && IS_BITFIELD (src) && (SPEC_BLEN (dest) != SPEC_BLEN (src) || SPEC_BSTR (dest) != SPEC_BSTR (src)))
2918     return 0;
2919 
2920   if (getSize (dest) != getSize (src))
2921     return 0;
2922 
2923   return 1;
2924 }
2925 
2926 /*------------------------------------------------------------------*/
2927 /* inCalleeSaveList - return 1 if found in callee save list         */
2928 /*------------------------------------------------------------------*/
2929 static int
calleeCmp(void * p1,void * p2)2930 calleeCmp (void *p1, void *p2)
2931 {
2932   return (strcmp ((char *) p1, (char *) (p2)) == 0);
2933 }
2934 
2935 bool
inCalleeSaveList(char * s)2936 inCalleeSaveList (char *s)
2937 {
2938   if (options.all_callee_saves)
2939     return 1;
2940   return isinSetWith (options.calleeSavesSet, s, calleeCmp);
2941 }
2942 
2943 /*-----------------------------------------------------------------*/
2944 /* aggregateToPointer:     change an aggregate type function       */
2945 /*                         argument to a pointer to that type.     */
2946 /*-----------------------------------------------------------------*/
2947 value *
aggregateToPointer(value * val)2948 aggregateToPointer (value * val)
2949 {
2950   if (IS_AGGREGATE (val->type))
2951     {
2952       /* if this is a structure */
2953       if (IS_STRUCT (val->type))
2954         {
2955           werror (E_STRUCT_AS_ARG, val->name);
2956           return NULL;
2957         }
2958 
2959       /* change to a pointer depending on the */
2960       /* storage class specified        */
2961       switch (SPEC_SCLS (val->etype))
2962         {
2963         case S_IDATA:
2964           DCL_TYPE (val->type) = IPOINTER;
2965           break;
2966         case S_PDATA:
2967           DCL_TYPE (val->type) = PPOINTER;
2968           break;
2969         case S_FIXED:
2970           if (SPEC_OCLS (val->etype))
2971             {
2972               DCL_TYPE (val->type) = PTR_TYPE (SPEC_OCLS (val->etype));
2973             }
2974           else
2975             {                   // this happens for (external) function parameters
2976               DCL_TYPE (val->type) = port->unqualified_pointer;
2977             }
2978           break;
2979         case S_AUTO:
2980           DCL_TYPE (val->type) = PTR_TYPE (SPEC_OCLS (val->etype));
2981           break;
2982         case S_DATA:
2983         case S_REGISTER:
2984           DCL_TYPE (val->type) = POINTER;
2985           break;
2986         case S_CODE:
2987           DCL_TYPE (val->type) = CPOINTER;
2988           break;
2989         case S_XDATA:
2990           DCL_TYPE (val->type) = FPOINTER;
2991           break;
2992         case S_EEPROM:
2993           DCL_TYPE (val->type) = EEPPOINTER;
2994           break;
2995         default:
2996           DCL_TYPE (val->type) = port->unqualified_pointer;
2997         }
2998 
2999       /* is there is a symbol associated then */
3000       /* change the type of the symbol as well */
3001       if (val->sym)
3002         {
3003           val->sym->type = copyLinkChain (val->type);
3004           val->sym->etype = getSpec (val->sym->type);
3005         }
3006     }
3007   return val;
3008 }
3009 
3010 /*------------------------------------------------------------------*/
3011 /* checkFunction - does all kinds of check on a function            */
3012 /*------------------------------------------------------------------*/
3013 int
checkFunction(symbol * sym,symbol * csym)3014 checkFunction (symbol * sym, symbol * csym)
3015 {
3016   value *exargs, *acargs;
3017   value *checkValue;
3018   int argCnt = 0;
3019 
3020   if (getenv ("DEBUG_SANITY"))
3021     {
3022       fprintf (stderr, "checkFunction: %s ", sym->name);
3023     }
3024 
3025   if (!IS_FUNC (sym->type))
3026     {
3027       werrorfl (sym->fileDef, sym->lineDef, E_SYNTAX_ERROR, sym->name);
3028       return 0;
3029     }
3030 
3031   /* move function specifier from return type to function attributes */
3032   if (IS_INLINE (sym->etype))
3033     {
3034       SPEC_INLINE (sym->etype) = 0;
3035       FUNC_ISINLINE (sym->type) = 1;
3036     }
3037   if (IS_NORETURN (sym->etype))
3038     {
3039       SPEC_NORETURN (sym->etype) = 0;
3040       FUNC_ISNORETURN (sym->type) = 1;
3041     }
3042 
3043   /* make sure the type is complete and sane */
3044   checkTypeSanity (sym->etype, sym->name);
3045 
3046   /* if not type then some kind of error */
3047   if (!sym->type)
3048     return 0;
3049 
3050   /* if the function has no type then make it return int */
3051   if (!sym->type->next)
3052     sym->type->next = sym->etype = newIntLink ();
3053 
3054   /* function cannot return aggregate */
3055   if (IS_AGGREGATE (sym->type->next))
3056     {
3057       werrorfl (sym->fileDef, sym->lineDef, E_FUNC_AGGR, sym->name);
3058       return 0;
3059     }
3060 
3061   /* check if this function is defined as calleeSaves
3062      then mark it as such */
3063   FUNC_CALLEESAVES (sym->type) = inCalleeSaveList (sym->name);
3064 
3065   /* if interrupt service routine  */
3066   /* then it cannot have arguments */
3067   if (IFFUNC_ARGS (sym->type) && FUNC_ISISR (sym->type))
3068     {
3069       if (!IS_VOID (FUNC_ARGS (sym->type)->type))
3070         {
3071           werrorfl (sym->fileDef, sym->lineDef, E_INT_ARGS, sym->name);
3072           FUNC_ARGS (sym->type) = NULL;
3073         }
3074     }
3075 
3076   if (IFFUNC_ISSHADOWREGS (sym->type) && !FUNC_ISISR (sym->type))
3077     {
3078       werrorfl (sym->fileDef, sym->lineDef, E_SHADOWREGS_NO_ISR, sym->name);
3079     }
3080 
3081   for (argCnt = 1, acargs = FUNC_ARGS (sym->type); acargs; acargs = acargs->next, argCnt++)
3082     {
3083       if (!acargs->sym)
3084         {
3085           // this can happen for reentrant functions
3086           werrorfl (sym->fileDef, sym->lineDef, E_PARAM_NAME_OMITTED, sym->name, argCnt);
3087           // the show must go on: synthesize a name and symbol
3088           SNPRINTF (acargs->name, sizeof (acargs->name), "_%s_PARM_%d", sym->name, argCnt);
3089           acargs->sym = newSymbol (acargs->name, 1);
3090           SPEC_OCLS (acargs->etype) = istack;
3091           acargs->sym->type = copyLinkChain (acargs->type);
3092           acargs->sym->etype = getSpec (acargs->sym->type);
3093           acargs->sym->_isparm = 1;
3094           strncpyz (acargs->sym->rname, acargs->name, sizeof (acargs->sym->rname));
3095         }
3096       else if (strcmp (acargs->sym->name, acargs->sym->rname) == 0)
3097         {
3098           // synthesized name
3099           werrorfl (sym->fileDef, sym->lineDef, E_PARAM_NAME_OMITTED, sym->name, argCnt);
3100         }
3101     }
3102   argCnt--;
3103 
3104   /*JCF: Mark the register bank as used */
3105   RegBankUsed[FUNC_REGBANK (sym->type)] = 1;
3106 
3107   if (!csym && !(csym = findSymWithLevel (SymbolTab, sym)))
3108     return 1;                   /* not defined nothing more to check  */
3109 
3110   /* check if body already present */
3111   if (csym && IFFUNC_HASBODY (csym->type))
3112     {
3113       werrorfl (sym->fileDef, sym->lineDef, E_FUNC_BODY, sym->name);
3114       return 0;
3115     }
3116 
3117   /* check the return value type   */
3118   if (compareType (csym->type, sym->type) <= 0)
3119     {
3120       werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "type", csym->fileDef, csym->lineDef);
3121       printFromToType (csym->type, sym->type);
3122       return 0;
3123     }
3124 
3125   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
3126     werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "interrupt", csym->fileDef, csym->lineDef);
3127 
3128   /* I don't think this is necessary for interrupts. An isr is a  */
3129   /* root in the calling tree.                                    */
3130   if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) && (!FUNC_ISISR (sym->type)))
3131     werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "using", csym->fileDef, csym->lineDef);
3132 
3133   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
3134     {
3135 // disabled since __naked has no influence on the calling convention
3136 //      werror (E_PREV_DECL_CONFLICT, csym->name, "__naked", csym->fileDef, csym->lineDef);
3137       FUNC_ISNAKED (sym->type) = 1;
3138     }
3139 
3140   if (FUNC_BANKED (csym->type) || FUNC_BANKED (sym->type))
3141     {
3142       if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
3143         {
3144           werrorfl (sym->fileDef, sym->lineDef, W_BANKED_WITH_NONBANKED);
3145           FUNC_BANKED (sym->type) = 0;
3146           FUNC_NONBANKED (sym->type) = 1;
3147         }
3148       else
3149         {
3150           FUNC_BANKED (sym->type) = 1;
3151         }
3152     }
3153   else
3154     {
3155       if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
3156         {
3157           FUNC_NONBANKED (sym->type) = 1;
3158         }
3159     }
3160 
3161   /* Really, reentrant should match regardless of argCnt, but     */
3162   /* this breaks some existing code (the fp lib functions). If    */
3163   /* the first argument is always passed the same way, this       */
3164   /* lax checking is ok (but may not be true for in future backends) */
3165   if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type) && argCnt > 1)
3166     {
3167       //printf("argCnt = %d\n",argCnt);
3168       werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "reentrant", csym->fileDef, csym->lineDef);
3169     }
3170 
3171   if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
3172     werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "wparam", csym->fileDef, csym->lineDef);
3173 
3174   if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
3175     werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "shadowregs", csym->fileDef, csym->lineDef);
3176 
3177   /* compare expected args with actual args */
3178   exargs = FUNC_ARGS (csym->type);
3179   acargs = FUNC_ARGS (sym->type);
3180 
3181   /* for all the expected args do */
3182   for (argCnt = 1; exargs && acargs; exargs = exargs->next, acargs = acargs->next, argCnt++)
3183     {
3184       if (getenv ("DEBUG_SANITY"))
3185         {
3186           fprintf (stderr, "checkFunction: %s ", exargs->name);
3187         }
3188       /* make sure the type is complete and sane */
3189       checkTypeSanity (exargs->etype, exargs->name);
3190 
3191       /* If the actual argument is an array, any prototype
3192        * will have modified it to a pointer. Duplicate that
3193        * change here.
3194        */
3195       if (IS_AGGREGATE (acargs->type))
3196         {
3197           checkValue = copyValue (acargs);
3198           aggregateToPointer (checkValue);
3199         }
3200       else
3201         {
3202           checkValue = acargs;
3203         }
3204 
3205       if (compareType (exargs->type, checkValue->type) <= 0)
3206         {
3207           werror (E_ARG_TYPE, argCnt);
3208           printFromToType (exargs->type, checkValue->type);
3209           return 0;
3210         }
3211     }
3212 
3213   /* if one of them ended we have a problem */
3214   if ((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type)))
3215     werror (E_ARG_COUNT);
3216 
3217   /* replace with this definition */
3218   sym->cdef = csym->cdef;
3219   deleteSym (SymbolTab, csym, csym->name);
3220   deleteFromSeg (csym);
3221   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
3222   if (IS_EXTERN (csym->etype) && !IS_EXTERN (sym->etype))
3223     {
3224       SPEC_EXTR (sym->etype) = 1;
3225       addSet (&publics, sym);
3226     }
3227 
3228   SPEC_STAT (sym->etype) |= SPEC_STAT (csym->etype);
3229   if (SPEC_STAT (sym->etype) && SPEC_EXTR (sym->etype))
3230     {
3231       werrorfl (sym->fileDef, sym->lineDef, E_TWO_OR_MORE_STORAGE_CLASSES, sym->name);
3232     }
3233 
3234   return 1;
3235 }
3236 
3237 /*------------------------------------------------------------------*/
3238 /* cdbStructBlock - calls struct printing for a blocks              */
3239 /*------------------------------------------------------------------*/
3240 void
cdbStructBlock(int block)3241 cdbStructBlock (int block)
3242 {
3243   int i;
3244   bucket **table = StructTab;
3245   bucket *chain;
3246 
3247   /* go thru the entire  table  */
3248   for (i = 0; i < 256; i++)
3249     {
3250       for (chain = table[i]; chain; chain = chain->next)
3251         {
3252           if (chain->block >= block)
3253             {
3254               if (debugFile)
3255                 debugFile->writeType ((structdef *) chain->sym, chain->block, 0, NULL);
3256             }
3257         }
3258     }
3259 }
3260 
3261 /*-----------------------------------------------------------------*/
3262 /* processFuncPtrArgs - does some processing with args of func ptrs*/
3263 /*-----------------------------------------------------------------*/
3264 void
processFuncPtrArgs(sym_link * funcType)3265 processFuncPtrArgs (sym_link * funcType)
3266 {
3267   value *val = FUNC_ARGS (funcType);
3268 
3269   /* if it is void then remove parameters */
3270   if (val && IS_VOID (val->type))
3271     {
3272       FUNC_ARGS (funcType) = NULL;
3273       return;
3274     }
3275 }
3276 
3277 /*-----------------------------------------------------------------*/
3278 /* processFuncArgs - does some processing with function args       */
3279 /*-----------------------------------------------------------------*/
3280 void
processFuncArgs(symbol * func)3281 processFuncArgs (symbol *func)
3282 {
3283   value *val;
3284   int pNum = 1;
3285   sym_link *funcType = func->type;
3286 
3287   if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
3288     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
3289 
3290   /* find the function declaration within the type */
3291   while (funcType && !IS_FUNC (funcType))
3292     funcType = funcType->next;
3293 
3294   /* if this function has variable argument list */
3295   /* then make the function a reentrant one    */
3296   if (IFFUNC_HASVARARGS (funcType) || (options.stackAuto && !func->cdef))
3297     FUNC_ISREENT (funcType) = 1;
3298 
3299   /* check if this function is defined as calleeSaves
3300      then mark it as such */
3301   FUNC_CALLEESAVES (funcType) = inCalleeSaveList (func->name);
3302 
3303   /* loop thru all the arguments   */
3304   val = FUNC_ARGS (funcType);
3305 
3306   /* if it is void then remove parameters */
3307   if (val && IS_VOID (val->type))
3308     {
3309       FUNC_ARGS (funcType) = NULL;
3310       return;
3311     }
3312 
3313   /* reset regparm for the port */
3314   (*port->reset_regparms) (funcType);
3315 
3316   /* if any of the arguments is an aggregate */
3317   /* change it to pointer to the same type */
3318   while (val)
3319     {
3320       int argreg = 0;
3321       struct dbuf_s dbuf;
3322 
3323       if (val->sym && val->sym->name)
3324         for (value *val2 = val->next; val2; val2 = val2->next)
3325           if (val2->sym && val2->sym->name && !strcmp (val->sym->name, val2->sym->name))
3326             werror (E_DUPLICATE_PARAMTER_NAME, val->sym->name, func->name);
3327 
3328       dbuf_init (&dbuf, 128);
3329       dbuf_printf (&dbuf, "%s parameter %d", func->name, pNum);
3330       checkTypeSanity (val->etype, dbuf_c_str (&dbuf));
3331       dbuf_destroy (&dbuf);
3332 
3333       if (IS_AGGREGATE (val->type))
3334         {
3335           aggregateToPointer (val);
3336         }
3337 
3338       /* mark it as a register parameter if
3339          the function does not have VA_ARG
3340          and as port dictates */
3341       if (!IFFUNC_HASVARARGS (funcType) && (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT (funcType))))
3342         {
3343           SPEC_REGPARM (val->etype) = 1;
3344           SPEC_ARGREG (val->etype) = argreg;
3345 
3346           /* is there is a symbol associated then */
3347           /* change the type of the symbol as well */
3348           if (val->sym)
3349             {
3350               SPEC_REGPARM (val->sym->etype) = 1;
3351               SPEC_ARGREG (val->sym->etype) = argreg;
3352             }
3353         }
3354       else if (IFFUNC_ISREENT (funcType))
3355         {
3356           FUNC_HASSTACKPARM (funcType) = 1;
3357         }
3358 
3359       val = val->next;
3360       pNum++;
3361     }
3362 
3363   /* if this is an internal generated function call */
3364   if (func->cdef)
3365     {
3366       /* ignore --stack-auto for this one, we don't know how it is compiled */
3367       /* simply trust on --int-long-reent or --float-reent */
3368       if (IFFUNC_ISREENT (funcType))
3369         {
3370           return;
3371         }
3372     }
3373   else
3374     {
3375       /* if this function is reentrant or */
3376       /* automatics r 2b stacked then nothing */
3377       if (IFFUNC_ISREENT (funcType) || options.stackAuto)
3378         return;
3379     }
3380 
3381   val = FUNC_ARGS (funcType);
3382   pNum = 1;
3383   while (val)
3384     {
3385       /* if a symbolname is not given  */
3386       /* synthesize a variable name */
3387       if (!val->sym)
3388         {
3389           SNPRINTF (val->name, sizeof (val->name), "_%s_PARM_%d", func->name, pNum++);
3390           val->sym = newSymbol (val->name, 1);
3391           val->sym->type = copyLinkChain (val->type);
3392           val->sym->etype = getSpec (val->sym->type);
3393           val->sym->_isparm = 1;
3394           if (!defaultOClass (val->sym))
3395             SPEC_OCLS (val->sym->etype) = port->mem.default_local_map;
3396           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype);
3397           strncpyz (val->sym->rname, val->name, sizeof (val->sym->rname));
3398           addSymChain (&val->sym);
3399         }
3400       else                      /* symbol name given create synth name */
3401         {
3402           SNPRINTF (val->name, sizeof (val->name), "_%s_PARM_%d", func->name, pNum++);
3403           strncpyz (val->sym->rname, val->name, sizeof (val->sym->rname));
3404           val->sym->_isparm = 1;
3405           if (!defaultOClass (val->sym))
3406             SPEC_OCLS (val->sym->etype) = port->mem.default_local_map;
3407           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype);
3408         }
3409       if (SPEC_OCLS (val->sym->etype) == pdata)
3410         val->sym->iaccess = 1;
3411       if (!isinSet (operKeyReset, val->sym))
3412         {
3413           addSet (&operKeyReset, val->sym);
3414           applyToSet (operKeyReset, resetParmKey);
3415         }
3416       val = val->next;
3417     }
3418 }
3419 
3420 /*-----------------------------------------------------------------*/
3421 /* isSymbolEqual - compares two symbols return 1 if they match     */
3422 /*-----------------------------------------------------------------*/
3423 int
isSymbolEqual(const symbol * dest,const symbol * src)3424 isSymbolEqual (const symbol * dest, const symbol * src)
3425 {
3426   /* if pointers match then equal */
3427   if (dest == src)
3428     return 1;
3429 
3430   /* if one of them is null then don't match */
3431   if (!dest || !src)
3432     return 0;
3433 
3434   /* if both of them have rname match on rname */
3435   if (dest->rname[0] && src->rname[0])
3436     return (!strcmp (dest->rname, src->rname));
3437 
3438   /* otherwise match on name */
3439   return (!strcmp (dest->name, src->name));
3440 }
3441 
3442 void
PT(sym_link * type)3443 PT (sym_link * type)
3444 {
3445   printTypeChain (type, 0);
3446 }
3447 
3448 /*-----------------------------------------------------------------*/
3449 /* printTypeChain - prints the type chain in human readable form   */
3450 /*-----------------------------------------------------------------*/
3451 void
printTypeChain(sym_link * start,FILE * of)3452 printTypeChain (sym_link * start, FILE * of)
3453 {
3454   struct dbuf_s dbuf;
3455   int nlr = 0;
3456 
3457   if (!of)
3458     {
3459       of = stdout;
3460       nlr = 1;
3461     }
3462 
3463   dbuf_init (&dbuf, 1024);
3464   dbuf_printTypeChain (start, &dbuf);
3465   dbuf_write_and_destroy (&dbuf, of);
3466 
3467   if (nlr)
3468     putc ('\n', of);
3469 }
3470 
3471 void
dbuf_printTypeChain(sym_link * start,struct dbuf_s * dbuf)3472 dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
3473 {
3474   value *args;
3475   sym_link *type, *search;
3476   STORAGE_CLASS scls;
3477   static struct dbuf_s dbuf2;
3478 
3479   if (start == NULL)
3480     {
3481       dbuf_append_str (dbuf, "void");
3482       return;
3483     }
3484 
3485   /* Print the chain as it is written in the source: */
3486   /* start with the last entry.                      */
3487   /* However, the storage class at the end of the    */
3488   /* chain really applies to the first in the chain! */
3489 
3490   for (type = start; type && type->next; type = type->next)
3491     ;
3492   if (IS_SPEC (type))
3493     scls = SPEC_SCLS (type);
3494   else
3495     scls = 0;
3496   while (type)
3497     {
3498       if (IS_DECL (type))
3499         {
3500           switch (DCL_TYPE (type))
3501             {
3502             case FUNCTION:
3503               dbuf_printf (dbuf, "function %s%s",
3504                            (IFFUNC_ISBUILTIN (type) ? "__builtin__ " : ""),
3505                            (IFFUNC_ISJAVANATIVE (type) ? "_JavaNative " : ""));
3506               dbuf_append_str (dbuf, "( ");
3507               for (args = FUNC_ARGS (type); args; args = args->next)
3508                 {
3509                   dbuf_printTypeChain (args->type, dbuf);
3510                   if (args->next)
3511                     dbuf_append_str (dbuf, ", ");
3512                 }
3513               dbuf_append_str (dbuf, ")");
3514               if (IFFUNC_ISREENT (type) && isTargetKeyword("__reentrant"))
3515                 dbuf_append_str (dbuf, " __reentrant");
3516               if (FUNC_REGBANK (type))
3517                 {
3518                   dbuf_set_length (&dbuf2, 0);
3519                   dbuf_printf (&dbuf2, " __using(%d)", FUNC_REGBANK (type));
3520                   dbuf_append_str (dbuf, dbuf_c_str (&dbuf2));
3521                 }
3522               if (IFFUNC_ISBANKEDCALL (type))
3523                 dbuf_append_str (dbuf, " __banked");
3524               if (IFFUNC_ISZ88DK_CALLEE (type))
3525                 dbuf_append_str (dbuf, " __z88dk_callee");
3526               if (IFFUNC_ISZ88DK_FASTCALL (type))
3527                 dbuf_append_str (dbuf, " __z88dk_fastcall");
3528               for (unsigned char i = 0; i < 9; i++)
3529                   if (type->funcAttrs.preserved_regs[i])
3530                   {
3531                     dbuf_append_str (dbuf, " __preserves_regs(");
3532                     for (; i < 9; i++)
3533                       if (type->funcAttrs.preserved_regs[i])
3534                         dbuf_printf (dbuf, " %d", i);
3535                     dbuf_append_str (dbuf, " )");
3536                     break;
3537                   }
3538               break;
3539             case GPOINTER:
3540               dbuf_append_str (dbuf, "generic*");
3541               break;
3542             case CPOINTER:
3543               dbuf_append_str (dbuf, "code*");
3544               break;
3545             case FPOINTER:
3546               dbuf_append_str (dbuf, "xdata*");
3547               break;
3548             case EEPPOINTER:
3549               dbuf_append_str (dbuf, "eeprom*");
3550               break;
3551             case POINTER:
3552               dbuf_append_str (dbuf, "near*");
3553               break;
3554             case IPOINTER:
3555               dbuf_append_str (dbuf, "idata*");
3556               break;
3557             case PPOINTER:
3558               dbuf_append_str (dbuf, "pdata*");
3559               break;
3560             case UPOINTER:
3561               dbuf_append_str (dbuf, "unknown*");
3562               break;
3563             case ARRAY:
3564               if (DCL_ELEM (type))
3565                 {
3566                   dbuf_printf (dbuf, "[%u]", (unsigned int) DCL_ELEM (type));
3567                 }
3568               else
3569                 {
3570                   dbuf_append_str (dbuf, "[]");
3571                 }
3572               break;
3573             default:
3574               dbuf_append_str (dbuf, "unknown?");
3575               break;
3576             }
3577           if (!IS_FUNC (type))
3578             {
3579               if (DCL_PTR_VOLATILE (type))
3580                 {
3581                   dbuf_append_str (dbuf, " volatile");
3582                 }
3583               if (DCL_PTR_CONST (type))
3584                 {
3585                   dbuf_append_str (dbuf, " const");
3586                 }
3587               if (DCL_PTR_RESTRICT (type))
3588                 {
3589                   dbuf_append_str (dbuf, " restrict");
3590                 }
3591             }
3592         }
3593       else
3594         {
3595           if (SPEC_VOLATILE (type))
3596             dbuf_append_str (dbuf, "volatile-");
3597           if (SPEC_CONST (type))
3598             dbuf_append_str (dbuf, "const-");
3599           if (SPEC_USIGN (type))
3600             dbuf_append_str (dbuf, "unsigned-");
3601           else if (SPEC_NOUN (type) == V_CHAR)
3602             dbuf_append_str (dbuf, "signed-");
3603           switch (SPEC_NOUN (type))
3604             {
3605             case V_INT:
3606               if (IS_LONGLONG (type))
3607                 dbuf_append_str (dbuf, "longlong-");
3608               else if (IS_LONG (type))
3609                 dbuf_append_str (dbuf, "long-");
3610               dbuf_append_str (dbuf, "int");
3611               break;
3612 
3613             case V_BOOL:
3614               dbuf_append_str (dbuf, "_Bool");
3615               break;
3616 
3617             case V_CHAR:
3618               dbuf_append_str (dbuf, "char");
3619               break;
3620 
3621             case V_VOID:
3622               dbuf_append_str (dbuf, "void");
3623               break;
3624 
3625             case V_FLOAT:
3626               dbuf_append_str (dbuf, "float");
3627               break;
3628 
3629             case V_FIXED16X16:
3630               dbuf_append_str (dbuf, "fixed16x16");
3631               break;
3632 
3633             case V_STRUCT:
3634               dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
3635               break;
3636 
3637             case V_SBIT:
3638               dbuf_append_str (dbuf, "sbit");
3639               break;
3640 
3641             case V_BIT:
3642               dbuf_append_str (dbuf, "bit");
3643               break;
3644 
3645             case V_BITFIELD:
3646               dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3647               break;
3648 
3649             case V_BBITFIELD:
3650               dbuf_printf (dbuf, "_Boolbitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3651               break;
3652 
3653             case V_DOUBLE:
3654               dbuf_append_str (dbuf, "double");
3655               break;
3656 
3657             default:
3658               dbuf_append_str (dbuf, "unknown type");
3659               break;
3660             }
3661         }
3662       if (type == start)
3663         {
3664           switch (scls)
3665             {
3666             case S_FIXED:
3667               dbuf_append_str (dbuf, " fixed");
3668               break;
3669             case S_AUTO:
3670               dbuf_append_str (dbuf, " auto");
3671               break;
3672             case S_REGISTER:
3673               dbuf_append_str (dbuf, " register");
3674               break;
3675             case S_DATA:
3676               dbuf_append_str (dbuf, " data");
3677               break;
3678             case S_XDATA:
3679               dbuf_append_str (dbuf, " xdata");
3680               break;
3681             case S_SFR:
3682               dbuf_append_str (dbuf, " sfr");
3683               break;
3684             case S_SBIT:
3685               dbuf_append_str (dbuf, " sbit");
3686               break;
3687             case S_CODE:
3688               dbuf_append_str (dbuf, " code");
3689               break;
3690             case S_IDATA:
3691               dbuf_append_str (dbuf, " idata");
3692               break;
3693             case S_PDATA:
3694               dbuf_append_str (dbuf, " pdata");
3695               break;
3696             case S_LITERAL:
3697               dbuf_append_str (dbuf, " literal");
3698               break;
3699             case S_STACK:
3700               dbuf_append_str (dbuf, " stack");
3701               break;
3702             case S_XSTACK:
3703               dbuf_append_str (dbuf, " xstack");
3704               break;
3705             case S_BIT:
3706               dbuf_append_str (dbuf, " bit");
3707               break;
3708             case S_EEPROM:
3709               dbuf_append_str (dbuf, " eeprom");
3710               break;
3711             default:
3712               break;
3713             }
3714         }
3715 
3716       /* search entry in list before "type" */
3717       for (search = start; search && search->next != type;)
3718         search = search->next;
3719       type = search;
3720       if (type)
3721         dbuf_append_char (dbuf, ' ');
3722     }
3723 }
3724 
3725 /*--------------------------------------------------------------------*/
3726 /* printTypeChainRaw - prints the type chain in human readable form   */
3727 /*                     in the raw data structure ordering             */
3728 /*--------------------------------------------------------------------*/
3729 void
printTypeChainRaw(sym_link * start,FILE * of)3730 printTypeChainRaw (sym_link * start, FILE * of)
3731 {
3732   int nlr = 0;
3733   value *args;
3734   sym_link *type;
3735 
3736   if (!of)
3737     {
3738       of = stdout;
3739       nlr = 1;
3740     }
3741 
3742   if (start == NULL)
3743     {
3744       fprintf (of, "void");
3745       return;
3746     }
3747 
3748   type = start;
3749 
3750   while (type)
3751     {
3752       if (IS_DECL (type))
3753         {
3754           if (!IS_FUNC (type))
3755             {
3756               if (DCL_PTR_VOLATILE (type))
3757                 {
3758                   fprintf (of, "volatile-");
3759                 }
3760               if (DCL_PTR_CONST (type))
3761                 {
3762                   fprintf (of, "const-");
3763                 }
3764               if (DCL_PTR_RESTRICT (type))
3765                 {
3766                   fprintf (of, "restrict-");
3767                 }
3768             }
3769           switch (DCL_TYPE (type))
3770             {
3771             case FUNCTION:
3772               if (IFFUNC_ISINLINE (type))
3773                 {
3774                   fprintf (of, "inline-");
3775                 }
3776               if (IFFUNC_ISNORETURN (type))
3777                 {
3778                   fprintf (of, "_Noreturn-");
3779                 }
3780               fprintf (of, "function %s %s",
3781                        (IFFUNC_ISBUILTIN (type) ? "__builtin__" : " "), (IFFUNC_ISJAVANATIVE (type) ? "_JavaNative" : " "));
3782               fprintf (of, "( ");
3783               for (args = FUNC_ARGS (type); args; args = args->next)
3784                 {
3785                   printTypeChain (args->type, of);
3786                   if (args->next)
3787                     fprintf (of, ", ");
3788                 }
3789               fprintf (of, ") ");
3790               break;
3791             case GPOINTER:
3792               fprintf (of, "generic* ");
3793               break;
3794             case CPOINTER:
3795               fprintf (of, "code* ");
3796               break;
3797             case FPOINTER:
3798               fprintf (of, "xdata* ");
3799               break;
3800             case EEPPOINTER:
3801               fprintf (of, "eeprom* ");
3802               break;
3803             case POINTER:
3804               fprintf (of, "near* ");
3805               break;
3806             case IPOINTER:
3807               fprintf (of, "idata* ");
3808               break;
3809             case PPOINTER:
3810               fprintf (of, "pdata* ");
3811               break;
3812             case UPOINTER:
3813               fprintf (of, "unknown* ");
3814               break;
3815             case ARRAY:
3816               if (DCL_ELEM (type))
3817                 {
3818                   fprintf (of, "[%ud] ", (unsigned int) DCL_ELEM (type));
3819                 }
3820               else
3821                 {
3822                   fprintf (of, "[] ");
3823                 }
3824               break;
3825             }
3826           if (DCL_TSPEC (type))
3827             {
3828               fprintf (of, "{");
3829               printTypeChainRaw (DCL_TSPEC (type), of);
3830               fprintf (of, "}");
3831             }
3832         }
3833       else if (IS_SPEC (type))
3834         {
3835           switch (SPEC_SCLS (type))
3836             {
3837             case S_DATA:
3838               fprintf (of, "data-");
3839               break;
3840             case S_XDATA:
3841               fprintf (of, "xdata-");
3842               break;
3843             case S_SFR:
3844               fprintf (of, "sfr-");
3845               break;
3846             case S_SBIT:
3847               fprintf (of, "sbit-");
3848               break;
3849             case S_CODE:
3850               fprintf (of, "code-");
3851               break;
3852             case S_IDATA:
3853               fprintf (of, "idata-");
3854               break;
3855             case S_PDATA:
3856               fprintf (of, "pdata-");
3857               break;
3858             case S_LITERAL:
3859               fprintf (of, "literal-");
3860               break;
3861             case S_STACK:
3862               fprintf (of, "stack-");
3863               break;
3864             case S_XSTACK:
3865               fprintf (of, "xstack-");
3866               break;
3867             case S_BIT:
3868               fprintf (of, "bit-");
3869               break;
3870             case S_EEPROM:
3871               fprintf (of, "eeprom-");
3872               break;
3873             default:
3874               break;
3875             }
3876           if (SPEC_VOLATILE (type))
3877             fprintf (of, "volatile-");
3878           if (SPEC_CONST (type))
3879             fprintf (of, "const-");
3880           if (SPEC_USIGN (type))
3881             fprintf (of, "unsigned-");
3882           switch (SPEC_NOUN (type))
3883             {
3884             case V_INT:
3885               if (IS_LONGLONG (type))
3886                 fprintf (of, "longlong-");
3887               else if (IS_LONG (type))
3888                 fprintf (of, "long-");
3889               fprintf (of, "int");
3890               break;
3891 
3892             case V_BOOL:
3893               fprintf (of, "_Bool");
3894               break;
3895 
3896             case V_CHAR:
3897               fprintf (of, "char");
3898               break;
3899 
3900             case V_VOID:
3901               fprintf (of, "void");
3902               break;
3903 
3904             case V_FLOAT:
3905               fprintf (of, "float");
3906               break;
3907 
3908             case V_FIXED16X16:
3909               fprintf (of, "fixed16x16");
3910               break;
3911 
3912             case V_STRUCT:
3913               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3914               break;
3915 
3916             case V_SBIT:
3917               fprintf (of, "sbit");
3918               break;
3919 
3920             case V_BIT:
3921               fprintf (of, "bit");
3922               break;
3923 
3924             case V_BITFIELD:
3925               fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3926               break;
3927 
3928             case V_BBITFIELD:
3929               fprintf (of, "_Boolbitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3930               break;
3931 
3932             case V_DOUBLE:
3933               fprintf (of, "double");
3934               break;
3935 
3936             default:
3937               fprintf (of, "unknown type");
3938               break;
3939             }
3940         }
3941       else
3942         fprintf (of, "NOT_SPEC_OR_DECL");
3943       type = type->next;
3944       if (type)
3945         fputc (' ', of);
3946     }
3947   if (nlr)
3948     fprintf (of, "\n");
3949 }
3950 
3951 
3952 /*-----------------------------------------------------------------*/
3953 /* powof2 - returns power of two for the number if number is pow 2 */
3954 /*-----------------------------------------------------------------*/
3955 int
powof2(TYPE_TARGET_ULONG num)3956 powof2 (TYPE_TARGET_ULONG num)
3957 {
3958   int nshifts = 0;
3959   int n1s = 0;
3960 
3961   while (num)
3962     {
3963       if (num & 1)
3964         n1s++;
3965       num >>= 1;
3966       nshifts++;
3967     }
3968 
3969   if (n1s > 1 || nshifts == 0)
3970     return -1;
3971   return nshifts - 1;
3972 }
3973 
3974 symbol *fsadd;
3975 symbol *fssub;
3976 symbol *fsmul;
3977 symbol *fsdiv;
3978 symbol *fseq;
3979 symbol *fsneq;
3980 symbol *fslt;
3981 
3982 symbol *fps16x16_add;
3983 symbol *fps16x16_sub;
3984 symbol *fps16x16_mul;
3985 symbol *fps16x16_div;
3986 symbol *fps16x16_eq;
3987 symbol *fps16x16_neq;
3988 symbol *fps16x16_lt;
3989 symbol *fps16x16_lteq;
3990 symbol *fps16x16_gt;
3991 symbol *fps16x16_gteq;
3992 
3993 /* Dims: mul/div/mod, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED/BOTH */
3994 symbol *muldiv[3][4][4];
3995 symbol *muls16tos32[2];
3996 /* Dims: BYTE/WORD/DWORD/QWORD SIGNED/UNSIGNED */
3997 sym_link *multypes[4][2];
3998 /* Dims: to/from float, BYTE/WORD/DWORD/QWORD, SIGNED/USIGNED */
3999 symbol *conv[2][4][2];
4000 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/QWORD/FLOAT, SIGNED/USIGNED */
4001 symbol *fp16x16conv[2][5][2];
4002 /* Dims: shift left/shift right, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED */
4003 symbol *rlrr[2][4][2];
4004 
4005 sym_link *charType;
4006 sym_link *floatType;
4007 sym_link *fixed16x16Type;
4008 
4009 symbol *memcpy_builtin;
4010 
4011 static const char *
_mangleFunctionName(const char * in)4012 _mangleFunctionName (const char *in)
4013 {
4014   if (port->getMangledFunctionName)
4015     {
4016       return port->getMangledFunctionName (in);
4017     }
4018   else
4019     {
4020       return in;
4021     }
4022 }
4023 
4024 /*-----------------------------------------------------------------*/
4025 /* typeFromStr - create a typechain from an encoded string         */
4026 /* basic types -        'b' - bool                                 */
4027 /*                      'c' - char                                 */
4028 /*                      's' - short                                */
4029 /*                      'i' - int                                  */
4030 /*                      'l' - long                                 */
4031 /*                      'L' - long long                            */
4032 /*                      'f' - float                                */
4033 /*                      'q' - fixed16x16                           */
4034 /*                      'v' - void                                 */
4035 /*                      '*' - pointer - default (GPOINTER)         */
4036 /* modifiers -          'S' - signed                               */
4037 /*                      'U' - unsigned                             */
4038 /*                      'C' - const                                */
4039 /* pointer modifiers -  'g' - generic                              */
4040 /*                      'x' - xdata                                */
4041 /*                      'p' - code                                 */
4042 /*                      'd' - data                                 */
4043 /*                      'F' - function                             */
4044 /* examples : "ig*" - generic int *                                */
4045 /*            "cx*" - char xdata *                                 */
4046 /*            "Ui" -  unsigned int                                 */
4047 /*            "Sc" -  signed char                                  */
4048 /*-----------------------------------------------------------------*/
4049 sym_link *
typeFromStr(const char * s)4050 typeFromStr (const char *s)
4051 {
4052   sym_link *r = newLink (DECLARATOR);
4053   int sign = 0;
4054   int usign = 0;
4055   int constant = 0;
4056 
4057   do
4058     {
4059       sym_link *nr;
4060       switch (*s)
4061         {
4062         case 'S':
4063           sign = 1;
4064           break;
4065         case 'U':
4066           usign = 1;
4067           break;
4068         case 'C':
4069           constant = 1;
4070           break;
4071         case 'b':
4072           r->xclass = SPECIFIER;
4073           SPEC_NOUN (r) = V_BOOL;
4074           break;
4075         case 'c':
4076           r->xclass = SPECIFIER;
4077           SPEC_NOUN (r) = V_CHAR;
4078           if (!sign && !usign)
4079             r->select.s.b_implicit_sign = true;
4080           if (usign)
4081             {
4082               SPEC_USIGN (r) = 1;
4083               usign = 0;
4084             }
4085           else if (!sign && !options.signed_char)
4086             SPEC_USIGN (r) = 1;
4087           break;
4088         case 's':
4089         case 'i':
4090           r->xclass = SPECIFIER;
4091           SPEC_NOUN (r) = V_INT;
4092           break;
4093         case 'l':
4094           r->xclass = SPECIFIER;
4095           SPEC_NOUN (r) = V_INT;
4096           SPEC_LONG (r) = 1;
4097           break;
4098         case 'L':
4099           r->xclass = SPECIFIER;
4100           SPEC_NOUN (r) = V_INT;
4101           SPEC_LONGLONG (r) = 1;
4102           break;
4103         case 'f':
4104           r->xclass = SPECIFIER;
4105           SPEC_NOUN (r) = V_FLOAT;
4106           break;
4107         case 'q':
4108           r->xclass = SPECIFIER;
4109           SPEC_NOUN (r) = V_FIXED16X16;
4110           break;
4111         case 'v':
4112           r->xclass = SPECIFIER;
4113           SPEC_NOUN (r) = V_VOID;
4114           break;
4115         case '*':
4116           DCL_TYPE (r) = port->unqualified_pointer;
4117           break;
4118         case 'g':
4119         case 'x':
4120         case 'p':
4121         case 'd':
4122         case 'F':
4123           assert (*(s + 1) == '*');
4124           nr = newLink (DECLARATOR);
4125           nr->next = r;
4126           r = nr;
4127           switch (*s)
4128             {
4129             case 'g':
4130               DCL_TYPE (r) = GPOINTER;
4131               break;
4132             case 'x':
4133               DCL_TYPE (r) = FPOINTER;
4134               break;
4135             case 'p':
4136               DCL_TYPE (r) = CPOINTER;
4137               break;
4138             case 'd':
4139               DCL_TYPE (r) = POINTER;
4140               break;
4141             case 'F':
4142               DCL_TYPE (r) = FUNCTION;
4143               nr = newLink (DECLARATOR);
4144               nr->next = r;
4145               r = nr;
4146               DCL_TYPE (r) = CPOINTER;
4147               break;
4148             }
4149           s++;
4150           break;
4151         default:
4152           werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "typeFromStr: unknown type");
4153           fprintf(stderr, "unknown: %s\n", s);
4154           break;
4155         }
4156       if (usign && sign)
4157         werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "typeFromStr: both signed and unsigned specified");
4158       if (IS_SPEC (r) && usign)
4159         {
4160           SPEC_USIGN (r) = 1;
4161           usign = 0;
4162         }
4163       if (IS_SPEC (r) && constant)
4164         {
4165           SPEC_CONST (r) = 1;
4166           constant = 0;
4167         }
4168       s++;
4169     }
4170   while (*s);
4171   return r;
4172 }
4173 
4174 /*-----------------------------------------------------------------*/
4175 /* initCSupport - create functions for C support routines          */
4176 /*-----------------------------------------------------------------*/
4177 void
initCSupport(void)4178 initCSupport (void)
4179 {
4180   const char *smuldivmod[] = {
4181     "mul", "div", "mod"
4182   };
4183   const char *sbwd[] = {
4184     "char", "int", "long", "longlong", "fixed16x16",
4185   };
4186   const char *fp16x16sbwd[] = {
4187     "char", "int", "long", "longlong", "float",
4188   };
4189   const char *ssu[] = {
4190     "s", "su", "us", "u"
4191   };
4192   const char *srlrr[] = {
4193     "rl", "rr"
4194   };
4195   /* type as character codes for typeFromStr() */
4196   const char *sbwdCodes[] = {
4197     "c",  "i",  "l",  "L",
4198     "Uc", "Ui", "Ul", "UL"
4199   };
4200 
4201   int bwd, su, muldivmod, tofrom, slsr;
4202 
4203   if (getenv ("SDCC_NO_C_SUPPORT"))
4204     {
4205       /* for debugging only */
4206       return;
4207     }
4208 
4209   for (bwd = 0; bwd < 4; bwd++)
4210     {
4211       sym_link *l = NULL;
4212       switch (bwd)
4213         {
4214         case 0:
4215           l = newCharLink ();
4216           break;
4217         case 1:
4218           l = newIntLink ();
4219           break;
4220         case 2:
4221           l = newLongLink ();
4222           break;
4223         case 3:
4224           l = newLongLongLink ();
4225           break;
4226         default:
4227           assert (0);
4228         }
4229       multypes[bwd][0] = l;
4230       multypes[bwd][1] = copyLinkChain (l);
4231       SPEC_USIGN (multypes[bwd][0]) = 0;
4232       SPEC_USIGN (multypes[bwd][1]) = 1;
4233     }
4234 
4235   floatType = newFloatLink ();
4236   fixed16x16Type = newFixed16x16Link ();
4237   charType = (options.signed_char) ? SCHARTYPE : UCHARTYPE;
4238 
4239   fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
4240   fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
4241   fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
4242   fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
4243   fseq = funcOfType ("__fseq", charType, floatType, 2, options.float_rent);
4244   fsneq = funcOfType ("__fsneq", charType, floatType, 2, options.float_rent);
4245   fslt = funcOfType ("__fslt", charType, floatType, 2, options.float_rent);
4246 
4247   fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4248   fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4249   fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4250   fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4251   fps16x16_eq = funcOfType ("__fps16x16_eq", charType, fixed16x16Type, 2, options.float_rent);
4252   fps16x16_neq = funcOfType ("__fps16x16_neq", charType, fixed16x16Type, 2, options.float_rent);
4253   fps16x16_lt = funcOfType ("__fps16x16_lt", charType, fixed16x16Type, 2, options.float_rent);
4254   fps16x16_lteq = funcOfType ("__fps16x16_lteq", charType, fixed16x16Type, 2, options.float_rent);
4255   fps16x16_gt = funcOfType ("__fps16x16_gt", charType, fixed16x16Type, 2, options.float_rent);
4256   fps16x16_gteq = funcOfType ("__fps16x16_gteq", charType, fixed16x16Type, 2, options.float_rent);
4257 
4258   for (tofrom = 0; tofrom < 2; tofrom++)
4259     {
4260       for (bwd = 0; bwd < 4; bwd++)
4261         {
4262           for (su = 0; su < 2; su++)
4263             {
4264               struct dbuf_s dbuf;
4265 
4266               dbuf_init (&dbuf, 128);
4267               if (tofrom)
4268                 {
4269                   dbuf_printf (&dbuf, "__fs2%s%s", ssu[su * 3], sbwd[bwd]);
4270                   conv[tofrom][bwd][su] = funcOfType (dbuf_c_str (&dbuf), multypes[bwd][su], floatType, 1, options.float_rent);
4271                 }
4272               else
4273                 {
4274                   dbuf_printf (&dbuf, "__%s%s2fs", ssu[su * 3], sbwd[bwd]);
4275                   conv[tofrom][bwd][su] = funcOfType (dbuf_c_str (&dbuf), floatType, multypes[bwd][su], 1, options.float_rent);
4276                 }
4277               dbuf_destroy (&dbuf);
4278             }
4279         }
4280     }
4281 
4282   for (tofrom = 0; tofrom < 2; tofrom++)
4283     {
4284       for (bwd = 0; bwd < 5; bwd++)
4285         {
4286           for (su = 0; su < 2; su++)
4287             {
4288               struct dbuf_s dbuf;
4289 
4290               dbuf_init (&dbuf, 128);
4291               if (tofrom)
4292                 {
4293                   dbuf_printf (&dbuf, "__fps16x162%s%s", ssu[su * 3], fp16x16sbwd[bwd]);
4294                   if (bwd == 4)
4295                     fp16x16conv[tofrom][bwd][su] =
4296                       funcOfType (dbuf_c_str (&dbuf), floatType, fixed16x16Type, 1, options.float_rent);
4297                   else
4298                     fp16x16conv[tofrom][bwd][su] =
4299                       funcOfType (dbuf_c_str (&dbuf), multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
4300                 }
4301               else
4302                 {
4303                   dbuf_printf (&dbuf, "__%s%s2fps16x16", ssu[su * 3], fp16x16sbwd[bwd]);
4304                   if (bwd == 4)
4305                     fp16x16conv[tofrom][bwd][su] =
4306                       funcOfType (dbuf_c_str (&dbuf), fixed16x16Type, floatType, 1, options.float_rent);
4307                   else
4308                     fp16x16conv[tofrom][bwd][su] =
4309                       funcOfType (dbuf_c_str (&dbuf), fixed16x16Type, multypes[bwd][su], 1, options.float_rent);
4310                 }
4311               dbuf_destroy (&dbuf);
4312             }
4313         }
4314     }
4315 
4316 /*
4317   for (muldivmod = 0; muldivmod < 3; muldivmod++)
4318     {
4319       for (bwd = 0; bwd < 4; bwd++)
4320         {
4321           for (su = 0; su < 2; su++)
4322             {
4323               struct dbuf_s dbuf;
4324 
4325               dbuf_init (&dbuf, 128);
4326               dbuf_printf (&dbuf, "_%s%s%s", smuldivmod[muldivmod], ssu[su*3], sbwd[bwd]);
4327               muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(dbuf_c_str (&dbuf)), multypes[bwd][su], multypes[bwd][su], 2, options.intlong_rent);
4328               dbuf_destroy (&dbuf);
4329               FUNC_NONBANKED (muldiv[muldivmod][bwd][su]->type) = 1;
4330             }
4331         }
4332     }
4333 
4334   muluint() and mulsint() resp. mululong() and mulslong() return the same result.
4335   Therefore they've been merged into mulint() and mullong().
4336 */
4337 
4338   /* byte */
4339 
4340   /* _divschar/_modschar return int, so that both
4341    * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
4342    * (first one would have to be sign extended, second one must not be).
4343    * Similarly, modschar should be handled, but the iCode introduces cast
4344    * here and forces '% : s8 x s8 -> s8' ... */
4345   bwd = 0;
4346   for (su = 0; su < 4; su++)
4347     {
4348       for (muldivmod = 0; muldivmod < 3; muldivmod++)
4349         {
4350           /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80
4351              port is sign/zero-extending to int before calling mulint() */
4352           /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
4353           struct dbuf_s dbuf;
4354 
4355           dbuf_init (&dbuf, 128);
4356           dbuf_printf (&dbuf, "_%s%s%s", smuldivmod[muldivmod], ssu[su], sbwd[bwd]);
4357           muldiv[muldivmod][bwd][su] =
4358             funcOfType (_mangleFunctionName (dbuf_c_str (&dbuf)), multypes[(TARGET_IS_PIC16 && muldivmod == 1 && bwd == 0 && su == 0 || (TARGET_IS_PIC14 || TARGET_IS_STM8 || TARGET_Z80_LIKE || TARGET_PDK_LIKE) && bwd == 0) ? 1 : bwd][su % 2], multypes[bwd][su / 2], 2,
4359                         options.intlong_rent);
4360           dbuf_destroy (&dbuf);
4361         }
4362     }
4363 
4364   for (bwd = 1; bwd < 4; bwd++)
4365     {
4366       for (su = 0; su < 2; su++)
4367         {
4368           for (muldivmod = 1; muldivmod < 3; muldivmod++)
4369             {
4370               struct dbuf_s dbuf;
4371 
4372               dbuf_init (&dbuf, 128);
4373               dbuf_printf (&dbuf, "_%s%s%s", smuldivmod[muldivmod], ssu[su * 3], sbwd[bwd]);
4374               muldiv[muldivmod][bwd][su] =
4375                 funcOfType (_mangleFunctionName (dbuf_c_str (&dbuf)), multypes[(TARGET_IS_PIC16 && muldivmod == 1 && bwd == 0 && su == 0 || (TARGET_IS_STM8 || TARGET_Z80_LIKE || TARGET_PDK_LIKE) && bwd == 0) ? 1 : bwd][su], multypes[bwd][su], 2,
4376                             options.intlong_rent);
4377               dbuf_destroy (&dbuf);
4378             }
4379         }
4380     }
4381 
4382   /* mul only */
4383   muldivmod = 0;
4384   /* signed only */
4385   su = 0;
4386   /* word, doubleword, and quadword */
4387   for (bwd = 1; bwd < 4; bwd++)
4388     {
4389       /* mul, int/long */
4390       struct dbuf_s dbuf;
4391 
4392       dbuf_init (&dbuf, 128);
4393       dbuf_printf (&dbuf, "_%s%s", smuldivmod[muldivmod], sbwd[bwd]);
4394       muldiv[muldivmod][bwd][0] =
4395         funcOfType (_mangleFunctionName (dbuf_c_str (&dbuf)), multypes[bwd][su], multypes[bwd][su], 2, options.intlong_rent);
4396       dbuf_destroy (&dbuf);
4397       /* signed = unsigned */
4398       muldiv[muldivmod][bwd][1] = muldiv[muldivmod][bwd][0];
4399     }
4400 
4401   for (slsr = 0; slsr < 2; slsr++)
4402     {
4403       for (bwd = 0; bwd < 4; bwd++)
4404         {
4405           for (su = 0; su < 2; su++)
4406             {
4407               struct dbuf_s dbuf;
4408               symbol *sym;
4409               const char *params[2];
4410 
4411               params[0] = sbwdCodes[bwd + 4*su];
4412               params[1] = sbwdCodes[0];
4413 
4414               dbuf_init (&dbuf, 128);
4415               dbuf_printf (&dbuf, "_%s%s%s", srlrr[slsr], ssu[su * 3], sbwd[bwd]);
4416               rlrr[slsr][bwd][su] = sym =
4417                 funcOfTypeVarg (_mangleFunctionName (dbuf_c_str (&dbuf)),
4418                                 sbwdCodes[bwd + 4*su], 2, &params[0]);
4419               FUNC_ISREENT (sym->type) = options.intlong_rent ? 1 : 0;
4420               FUNC_NONBANKED (sym->type) = 1;
4421               dbuf_destroy (&dbuf);
4422             }
4423         }
4424     }
4425 
4426   {
4427     const char *iparams[] = {"i", "i"};
4428     const char *uiparams[] = {"Ui", "Ui"};
4429     muls16tos32[0] = port->support.has_mulint2long ? funcOfTypeVarg ("__mulsint2slong", "l", 2, iparams) : 0;
4430     muls16tos32[1] = port->support.has_mulint2long ? funcOfTypeVarg ("__muluint2ulong", "Ul", 2, uiparams) : 0;
4431   }
4432 }
4433 
4434 /*-----------------------------------------------------------------*/
4435 /* initBuiltIns - create prototypes for builtin functions          */
4436 /*-----------------------------------------------------------------*/
4437 void
initBuiltIns()4438 initBuiltIns ()
4439 {
4440   int i;
4441   symbol *sym;
4442 
4443   if (port->builtintable)
4444     {
4445       for (i = 0; port->builtintable[i].name; i++)
4446         {
4447           sym = funcOfTypeVarg (port->builtintable[i].name, port->builtintable[i].rtype,
4448                                 port->builtintable[i].nParms, (const char **)port->builtintable[i].parm_types);
4449           FUNC_ISBUILTIN (sym->type) = 1;
4450           FUNC_ISREENT (sym->type) = 0;     /* can never be reentrant */
4451         }
4452     }
4453 
4454   /* initialize memcpy symbol for struct assignment */
4455   memcpy_builtin = findSym (SymbolTab, NULL, "__builtin_memcpy");
4456   /* if there is no __builtin_memcpy, use __memcpy instead of an actual builtin */
4457   if (!memcpy_builtin)
4458     {
4459       const char *argTypeStrs[] = {"vg*", "Cvg*", "Ui"};
4460       memcpy_builtin = funcOfTypeVarg ("__memcpy", "vg*", 3, argTypeStrs);
4461       FUNC_ISBUILTIN (memcpy_builtin->type) = 0;
4462       FUNC_ISREENT (memcpy_builtin->type) = options.stackAuto;
4463     }
4464 }
4465 
4466 sym_link *
validateLink(sym_link * l,const char * macro,const char * args,const char select,const char * file,unsigned line)4467 validateLink (sym_link * l, const char *macro, const char *args, const char select, const char *file, unsigned line)
4468 {
4469   if (l && l->xclass == select)
4470     {
4471       return l;
4472     }
4473   fprintf (stderr,
4474            "Internal error: validateLink failed in %s(%s) @ %s:%u:"
4475            " expected %s, got %s\n",
4476            macro, args, file, line, DECLSPEC2TXT (select), l ? DECLSPEC2TXT (l->xclass) : "null-link");
4477   exit (EXIT_FAILURE);
4478   return l;                     // never reached, makes compiler happy.
4479 }
4480 
4481 /*--------------------------------------------------------------------*/
4482 /* newEnumType - create an integer type compatible with enumerations  */
4483 /*--------------------------------------------------------------------*/
4484 sym_link *
newEnumType(symbol * enumlist)4485 newEnumType (symbol * enumlist)
4486 {
4487   int min, max, v;
4488   symbol *sym;
4489   sym_link *type;
4490 
4491   if (!enumlist)
4492     {
4493       type = newLink (SPECIFIER);
4494       SPEC_NOUN (type) = V_INT;
4495       return type;
4496     }
4497 
4498   /* Determine the range of the enumerated values */
4499   sym = enumlist;
4500   min = max = (int) ulFromVal (valFromType (sym->type));
4501   for (sym = sym->next; sym; sym = sym->next)
4502     {
4503       v = (int) ulFromVal (valFromType (sym->type));
4504       if (v < min)
4505         min = v;
4506       if (v > max)
4507         max = v;
4508     }
4509 
4510   /* Determine the smallest integer type that is compatible with this range */
4511   type = newLink (SPECIFIER);
4512   if (min >= 0 && max <= 255)
4513     {
4514       SPEC_NOUN (type) = V_CHAR;
4515       SPEC_USIGN (type) = 1;
4516     }
4517   else if (min >= -128 && max <= 127)
4518     {
4519       SPEC_NOUN (type) = V_CHAR;
4520       SPEC_SIGN (type) = 1;
4521     }
4522   else if (min >= 0 && max <= 65535)
4523     {
4524       SPEC_NOUN (type) = V_INT;
4525       SPEC_USIGN (type) = 1;
4526     }
4527   else if (min >= -32768 && max <= 32767)
4528     {
4529       SPEC_NOUN (type) = V_INT;
4530     }
4531   else
4532     {
4533       SPEC_NOUN (type) = V_INT;
4534       SPEC_LONG (type) = 1;
4535       if (min >= 0)
4536         SPEC_USIGN (type) = 1;
4537     }
4538 
4539   return type;
4540 }
4541 
4542 /*-------------------------------------------------------------------*/
4543 /* isConstant - check if the type is constant                        */
4544 /*-------------------------------------------------------------------*/
4545 int
isConstant(sym_link * type)4546 isConstant (sym_link * type)
4547 {
4548   if (!type)
4549     return 0;
4550 
4551   while (IS_ARRAY (type))
4552     type = type->next;
4553 
4554   if (IS_SPEC (type))
4555     return SPEC_CONST (type);
4556   else
4557     return DCL_PTR_CONST (type);
4558 }
4559 
4560 /*-------------------------------------------------------------------*/
4561 /* isVolatile - check if the type is volatile                        */
4562 /*-------------------------------------------------------------------*/
4563 int
isVolatile(sym_link * type)4564 isVolatile (sym_link * type)
4565 {
4566   if (!type)
4567     return 0;
4568 
4569   while (IS_ARRAY (type))
4570     type = type->next;
4571 
4572   if (IS_SPEC (type))
4573     return SPEC_VOLATILE (type);
4574   else
4575     return DCL_PTR_VOLATILE (type);
4576 }
4577 
4578 /*-------------------------------------------------------------------*/
4579 /* isRestrict - check if the type is restricted                      */
4580 /*-------------------------------------------------------------------*/
4581 int
isRestrict(sym_link * type)4582 isRestrict (sym_link * type)
4583 {
4584   if (!type)
4585     return 0;
4586 
4587   while (IS_ARRAY (type))
4588     type = type->next;
4589 
4590   if (IS_SPEC (type))
4591     return SPEC_RESTRICT (type);
4592   else
4593     return DCL_PTR_RESTRICT (type);
4594 }
4595