Update svn merge history.
[sdcc.git] / sdcc / src / SDCCsymt.c
blob3aaaa049f379848bf47b7a24d672bfcf14511b0e
1 /*-------------------------------------------------------------------------
2 SDCCsymt.c - Code file for Symbols table related structures and MACRO's.
3 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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.
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.
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.
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 -------------------------------------------------------------------------*/
24 #include "common.h"
25 #include "newalloc.h"
26 #include "dbuf_string.h"
28 #include "SDCCsymt.h"
30 value *aggregateToPointer (value * val);
31 void printTypeChainRaw (sym_link * start, FILE * of);
33 void
34 printFromToType (sym_link * from, sym_link * to)
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);
46 /* noun strings */
47 char *
48 nounName (sym_link * sl)
50 switch (SPEC_NOUN (sl))
52 case V_INT:
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";
62 case V_BITINT:
63 return "_BitInt";
64 case V_FLOAT:
65 return "float";
66 case V_FIXED16X16:
67 return "fixed16x16";
68 case V_BOOL:
69 return "_Bool";
70 case V_CHAR:
71 return "char";
72 case V_NULLPTR:
73 return "nullptr_t";
74 case V_VOID:
75 return "void";
76 case V_STRUCT:
77 return "struct";
78 case V_LABEL:
79 return "label";
80 case V_BITFIELD:
81 return "bitfield";
82 case V_BBITFIELD:
83 return "_Boolbitfield";
84 case V_BITINTBITFIELD:
85 return "_BitIntbitfield";
86 case V_BIT:
87 return "bit";
88 case V_SBIT:
89 return "sbit";
90 case V_DOUBLE:
91 return "double";
93 return "unknown";
96 bucket *SymbolTab[HASHTAB_SIZE]; /* the symbol table */
97 bucket *StructTab[HASHTAB_SIZE]; /* the structure table */
98 bucket *TypedefTab[HASHTAB_SIZE]; /* the typedef table */
99 bucket *LabelTab[HASHTAB_SIZE]; /* the Label table */
100 bucket *enumTab[HASHTAB_SIZE]; /* enumerated table */
101 bucket *AddrspaceTab[HASHTAB_SIZE]; /* the named address space table */
103 /*------------------------------------------------------------------*/
104 /* initSymt () - initialises symbol table related stuff */
105 /*------------------------------------------------------------------*/
106 void
107 initSymt (void)
109 int i = 0;
111 for (i = 0; i < HASHTAB_SIZE; i++)
112 SymbolTab[i] = StructTab[i] = (void *) NULL;
115 /*-----------------------------------------------------------------*/
116 /* newBucket - allocates & returns a new bucket */
117 /*-----------------------------------------------------------------*/
118 bucket *
119 newBucket (void)
121 bucket *bp;
123 bp = Safe_alloc (sizeof (bucket));
125 return bp;
128 /*-----------------------------------------------------------------*/
129 /* hashKey - computes the hashkey given a symbol name */
130 /*-----------------------------------------------------------------*/
132 hashKey (const char *s)
134 unsigned long key = 0;
136 while (*s)
137 key += *s++;
138 return key % HASHTAB_SIZE;
141 /*-----------------------------------------------------------------*/
142 /* addSym - adds a symbol to the hash Table */
143 /*-----------------------------------------------------------------*/
144 void
145 addSym (bucket ** stab, void *sym, char *sname, long level, int block, int checkType)
147 int i; /* index into the hash Table */
148 bucket *bp; /* temp bucket * */
150 if (checkType)
152 symbol *csym = (symbol *) sym;
154 if (getenv ("DEBUG_SANITY"))
156 fprintf (stderr, "addSym: %s ", sname);
158 /* make sure the type is complete and sane */
159 checkTypeSanity (csym->etype, csym->name);
162 /* prevent overflow of the (r)name buffers */
163 if (strlen (sname) > SDCC_SYMNAME_MAX)
165 werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
166 sname[SDCC_SYMNAME_MAX] = '\0';
169 /* the symbols are always added at the head of the list */
170 i = hashKey (sname);
171 /* get a free entry */
172 bp = Safe_alloc (sizeof (bucket));
174 bp->sym = sym; /* update the symbol pointer */
175 bp->level = level; /* update the nest level */
176 bp->block = block;
177 strncpyz (bp->name, sname, sizeof (bp->name)); /* copy the name into place */
179 /* if this is the first entry */
180 if (stab[i] == NULL)
182 bp->prev = bp->next = (void *) NULL; /* point to nothing */
183 stab[i] = bp;
185 /* not first entry then add @ head of list */
186 else
188 bp->prev = NULL;
189 stab[i]->prev = bp;
190 bp->next = stab[i];
191 stab[i] = bp;
195 /*-----------------------------------------------------------------*/
196 /* deleteSym - deletes a symbol from the hash Table entry */
197 /*-----------------------------------------------------------------*/
198 void
199 deleteSym (bucket ** stab, void *sym, const char *sname)
201 int i = 0;
202 bucket *bp;
204 i = hashKey (sname);
206 bp = stab[i];
207 /* find the symbol */
208 while (bp)
210 if (bp->sym == sym) /* found it then break out */
211 break; /* of the loop */
212 bp = bp->next;
215 if (!bp) /* did not find it */
216 return;
218 /* if this is the first one in the chain */
219 if (!bp->prev)
221 stab[i] = bp->next;
222 if (stab[i]) /* if chain ! empty */
223 stab[i]->prev = (void *) NULL;
225 /* middle || end of chain */
226 else
228 if (bp->next) /* if not end of chain */
229 bp->next->prev = bp->prev;
231 bp->prev->next = bp->next;
235 /*-----------------------------------------------------------------*/
236 /* findSym - finds a symbol in a table */
237 /*-----------------------------------------------------------------*/
238 void *
239 findSym (bucket ** stab, void *sym, const char *sname)
241 bucket *bp;
243 bp = stab[hashKey (sname)];
244 while (bp)
246 if (bp->sym == sym || strcmp (bp->name, sname) == 0)
247 break;
248 bp = bp->next;
251 return (bp ? bp->sym : (void *) NULL);
254 /*-----------------------------------------------------------------*/
255 /* findSymWithLevel - finds a symbol with a name & level */
256 /*-----------------------------------------------------------------*/
257 void *
258 findSymWithLevel (bucket ** stab, symbol * sym)
260 bucket *bp;
262 if (!sym)
263 return sym;
265 bp = stab[hashKey (sym->name)];
268 ** do the search from the head of the list since the
269 ** elements are added at the head it is ensured that
270 ** we will find the deeper definitions before we find
271 ** the global ones. we need to check for symbols with
272 ** level <= to the level given, if levels match then block
273 ** numbers need to match as well
275 while (bp)
277 if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
279 /* if this is parameter then nothing else need to be checked */
280 if (((symbol *) (bp->sym))->_isparm)
281 return (bp->sym);
282 /* if levels match then block numbers should also match */
283 if (bp->level && bp->level == sym->level && bp->block == sym->block
284 && ((symbol *)(bp->sym))->seqPoint <= sym->seqPoint)
285 return (bp->sym);
286 /* if levels don't match then we are okay if the symbol is in scope */
287 if (bp->level && bp->level != sym->level && bp->block <= sym->block
288 && ((symbol *) (bp->sym))->isinscope
289 && (stab == LabelTab || ((symbol *)(bp->sym))->seqPoint <= sym->seqPoint))
290 return (bp->sym);
291 /* if this is a global variable then we are ok too */
292 if (bp->level == 0)
293 return (bp->sym);
296 bp = bp->next;
299 return (void *) NULL;
302 /*-----------------------------------------------------------------*/
303 /* findSymWithBlock - finds a symbol with name in a block */
304 /*-----------------------------------------------------------------*/
305 void *
306 findSymWithBlock (bucket ** stab, symbol * sym, int block, long level)
308 bucket *bp;
310 if (!sym)
311 return sym;
313 bp = stab[hashKey (sym->name)];
314 while (bp)
316 if (strcmp (bp->name, sym->name) == 0 && (bp->block == block || (bp->block < block && bp->level < level)))
317 break;
318 bp = bp->next;
321 return (bp ? bp->sym : (void *) NULL);
324 /*------------------------------------------------------------------*/
325 /* newSymbol () - returns a new pointer to a symbol */
326 /*------------------------------------------------------------------*/
327 symbol *
328 newSymbol (const char *name, long scope)
330 symbol *sym;
332 sym = Safe_alloc (sizeof (symbol));
334 strncpyz (sym->name, name, sizeof (sym->name)); /* copy the name */
335 sym->level = scope; /* set the level */
336 sym->block = currBlockno;
337 sym->seqPoint = seqPointNo;
338 sym->lineDef = lexLineno; /* set the line number */
339 sym->fileDef = lexFilename;
340 sym->for_newralloc = 0;
341 sym->isinscope = 1;
342 sym->usl.spillLoc = 0;
344 // Err on the safe side, when in doubt disabling optimizations.
345 sym->funcDivFlagSafe = false;
346 sym->funcUsesVolatile = true;
347 sym->funcRestartAtomicSupport = true; //options.std_c11;
349 return sym;
352 /*------------------------------------------------------------------*/
353 /* newLink - creates a new link (declarator,specifier) */
354 /*------------------------------------------------------------------*/
355 sym_link *
356 newLink (SYM_LINK_CLASS select)
358 sym_link *p;
360 p = Safe_alloc (sizeof (sym_link));
361 p->xclass = select;
362 p->funcAttrs.z88dk_params_offset = 0;
363 FUNC_SDCCCALL (p) = -1;
365 return p;
368 /*------------------------------------------------------------------*/
369 /* newStruct - creats a new structdef from the free list */
370 /*------------------------------------------------------------------*/
371 structdef *
372 newStruct (const char *tag)
374 structdef *s;
376 s = Safe_alloc (sizeof (structdef));
378 strncpyz (s->tag, tag, sizeof (s->tag)); /* copy the tag */
379 return s;
382 /*------------------------------------------------------------------*/
383 /* sclsFromPtr - Return the storage class a pointer points into. */
384 /* S_FIXED is returned for generic pointers or other */
385 /* unexpected cases */
386 /*------------------------------------------------------------------*/
387 STORAGE_CLASS
388 sclsFromPtr (sym_link * ptr)
390 switch (DCL_TYPE (ptr))
392 case POINTER:
393 return S_DATA;
394 case GPOINTER:
395 return S_FIXED;
396 case FPOINTER:
397 return S_XDATA;
398 case CPOINTER:
399 return S_CODE;
400 case IPOINTER:
401 return S_IDATA;
402 case PPOINTER:
403 return S_PDATA;
404 case EEPPOINTER:
405 return S_EEPROM;
406 case FUNCTION:
407 return S_CODE;
408 default:
409 return S_FIXED;
413 /*------------------------------------------------------------------*/
414 /* pointerTypes - do the computation for the pointer types */
415 /*------------------------------------------------------------------*/
416 void
417 pointerTypes (sym_link * ptr, sym_link * type)
419 sym_link *p;
420 sym_link *etype;
422 sym_link *otype = type;
423 sym_link *optr = ptr;
425 if (IS_SPEC (ptr))
426 return;
428 /* find the last unknown pointer type */
429 p = ptr;
430 while (p)
432 if (IS_PTR (p) && DCL_TYPE (p) == UPOINTER)
433 ptr = p;
434 p = p->next;
437 /* could not find it */
438 if (!ptr || IS_SPEC (ptr) || !IS_PTR (ptr))
439 return;
441 if (IS_PTR (ptr) && DCL_TYPE (ptr) != UPOINTER)
443 pointerTypes (ptr->next, type);
444 return;
447 /* change the pointer type depending on the
448 storage class of the etype */
449 etype = getSpec (type);
450 if (IS_SPEC (etype))
452 switch (SPEC_SCLS (etype))
454 case S_XDATA:
455 DCL_TYPE (ptr) = FPOINTER;
456 break;
457 case S_IDATA:
458 DCL_TYPE (ptr) = IPOINTER;
459 break;
460 case S_PDATA:
461 DCL_TYPE (ptr) = PPOINTER;
462 break;
463 case S_DATA:
464 DCL_TYPE (ptr) = POINTER;
465 break;
466 case S_CODE:
467 DCL_TYPE (ptr) = CPOINTER;
468 break;
469 case S_EEPROM:
470 DCL_TYPE (ptr) = EEPPOINTER;
471 break;
472 case S_SFR:
473 if (!port->mem.sfrupointer)
474 werror (E_SFR_POINTER);
475 default:
476 DCL_TYPE (ptr) = port->unqualified_pointer;
477 break;
479 /* the storage class of etype ends here */
480 SPEC_SCLS (etype) = 0;
483 /* now change all the remaining unknown pointers
484 to generic pointers */
485 while (optr)
487 if (!IS_SPEC (optr) && DCL_TYPE (optr) == UPOINTER)
488 DCL_TYPE (optr) = port->unqualified_pointer;
489 optr = optr->next;
492 /* same for the type although it is highly unlikely that
493 type will have a pointer */
494 while (otype)
496 if (!IS_SPEC (otype) && DCL_TYPE (otype) == UPOINTER)
497 DCL_TYPE (otype) = port->unqualified_pointer;
498 otype = otype->next;
502 /*------------------------------------------------------------------*/
503 /* addDecl - adds a declarator @ the end of a chain */
504 /*------------------------------------------------------------------*/
505 void
506 addDecl (symbol *sym, int type, sym_link *p)
508 sym_link *head;
509 sym_link *tail;
510 sym_link *t;
512 if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
513 fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, (void *)p);
515 /* if we are passed a link then set head & tail */
516 if (p)
518 tail = head = p;
519 while (tail->next)
520 tail = tail->next;
522 else
524 head = tail = newLink (DECLARATOR);
525 DCL_TYPE (head) = type;
528 // no type yet: make p the type
529 if (!sym->type)
531 sym->type = head;
532 sym->etype = tail;
534 // type ends in spec, p is single spec element: merge specs
535 else if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
537 sym->etype = mergeSpec (sym->etype, head, sym->name);
539 // type ends in spec, p is single decl element: p goes before spec
540 else if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
542 t = sym->type;
543 while (t->next != sym->etype)
544 t = t->next;
545 t->next = head;
546 tail->next = sym->etype;
548 // type ends in spec, p ends in spec: merge specs, p's decls go before spec
549 else if (IS_SPEC (sym->etype) && IS_SPEC (tail))
551 sym->etype = mergeSpec (sym->etype, tail, sym->name);
553 // cut off p's spec
554 t = head;
555 while (t->next != tail)
556 t = t->next;
557 tail = t;
559 // splice p's decls
560 t = sym->type;
561 while (t->next != sym->etype)
562 t = t->next;
563 t->next = head;
564 tail->next = sym->etype;
566 // append p to the type
567 else
569 sym->etype->next = head;
570 sym->etype = tail;
573 /* if the type is an unknown pointer and has
574 a tspec then take the storage class and address
575 attribute from the tspec & make it those of this
576 symbol */
577 if (p && !IS_SPEC (p) &&
578 //DCL_TYPE (p) == UPOINTER &&
579 DCL_TSPEC (p))
581 if (!IS_SPEC (sym->etype))
583 sym->etype = sym->etype->next = newLink (SPECIFIER);
585 SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
586 SPEC_ABSA (sym->etype) |= SPEC_ABSA (DCL_TSPEC (p));
587 SPEC_ADDR (sym->etype) |= SPEC_ADDR (DCL_TSPEC (p));
588 DCL_TSPEC (p) = NULL;
591 // if there is a function in this type chain
592 if (p && funcInChain (sym->type))
594 processFuncArgs (sym, NULL);
597 return;
600 /*------------------------------------------------------------------
601 checkTypeSanity: prevent the user from doing e.g.:
602 unsigned float uf;
603 ------------------------------------------------------------------*/
604 void
605 checkTypeSanity (sym_link *etype, const char *name)
607 char *noun;
609 if (!etype)
611 if (getenv ("DEBUG_SANITY"))
613 fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
615 return;
618 if (!IS_SPEC (etype))
620 if (getenv ("DEBUG_SANITY"))
622 fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
624 return;
627 noun = nounName (etype);
629 if (getenv ("DEBUG_SANITY"))
631 fprintf (stderr, "checking sanity for %s %p\n", name, (void *)etype);
634 /* transitional support for double and long double as aliases for float */
635 if (SPEC_NOUN (etype) == V_DOUBLE)
637 SPEC_NOUN (etype) = V_FLOAT;
638 SPEC_LONG (etype) = 0;
639 werror (W_DOUBLE_UNSUPPORTED);
642 if ((SPEC_NOUN (etype) == V_BITINT ||
643 SPEC_NOUN (etype) == V_BOOL ||
644 SPEC_NOUN (etype) == V_CHAR ||
645 SPEC_NOUN (etype) == V_FLOAT ||
646 SPEC_NOUN (etype) == V_FIXED16X16 ||
647 SPEC_NOUN (etype) == V_DOUBLE ||
648 SPEC_NOUN (etype) == V_VOID)
649 && (SPEC_SHORT (etype) || SPEC_LONG (etype) || SPEC_LONGLONG (etype)))
650 { // long or short for char float double or void
651 werror (E_LONG_OR_SHORT_INVALID, noun, name);
653 if ((SPEC_NOUN (etype) == V_BOOL ||
654 SPEC_NOUN (etype) == V_FLOAT ||
655 SPEC_NOUN (etype) == V_FIXED16X16 ||
656 SPEC_NOUN (etype) == V_DOUBLE || SPEC_NOUN (etype) == V_VOID) && (etype->select.s.b_signed || SPEC_USIGN (etype)))
657 { // signed or unsigned for float double or void
658 werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
661 /* if no noun e.g.
662 "const a;" or "data b;" or "signed s" or "long l"
663 assume an int */
664 if (!SPEC_NOUN (etype))
666 SPEC_NOUN (etype) = V_INT;
667 if (!(SPEC_SHORT (etype) || SPEC_LONG (etype) || SPEC_LONGLONG (etype) || SPEC_SIGN (etype) || SPEC_USIGN (etype)))
668 werror (options.std_c99 ? E_NO_TYPE_SPECIFIER : W_NO_TYPE_SPECIFIER, name);
671 /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
672 /* a "plain" int bitfield is unsigned */
673 if (SPEC_NOUN (etype) == V_BIT || SPEC_NOUN (etype) == V_SBIT)
675 if (!etype->select.s.b_signed)
676 SPEC_USIGN (etype) = 1;
679 if (etype->select.s.b_signed && SPEC_USIGN (etype))
680 { // signed AND unsigned
681 werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
683 if (SPEC_SHORT (etype) && SPEC_LONG (etype))
684 { // short AND long
685 werror (E_LONG_AND_SHORT_INVALID, noun, name);
688 if (SPEC_NOUN (etype) == V_BITINT)
690 if (SPEC_BITINTWIDTH (etype) > port->s.bitint_maxwidth || // Check that port supports bit-precise integers this wide.
691 SPEC_BITINTWIDTH (etype) < (SPEC_USIGN (etype) ? 1 : 2)) // Check minimum width mandated by standard.
692 werror (E_INVALID_BITINTWIDTH);
696 /*------------------------------------------------------------------*/
697 /* finalizeSpec */
698 /* currently just a V_CHAR is forced to be unsigned */
699 /* when it's neither signed nor unsigned */
700 /* unless the --fsigned-char command line switch is active */
701 /*------------------------------------------------------------------*/
702 sym_link *
703 finalizeSpec (sym_link * lnk)
705 sym_link *p = lnk;
706 while (p && !IS_SPEC (p))
707 p = p->next;
708 if (SPEC_NOUN (p) == V_CHAR && !SPEC_USIGN (p) && !p->select.s.b_signed)
710 SPEC_USIGN (p) = !options.signed_char;
711 p->select.s.b_implicit_sign = true;
713 return lnk;
716 /*------------------------------------------------------------------*/
717 /* mergeSpec - merges two specifiers and returns the new one */
718 /*------------------------------------------------------------------*/
719 sym_link *
720 mergeSpec (sym_link * dest, sym_link * src, const char *name)
722 unsigned int i;
724 if (!IS_SPEC (dest) || !IS_SPEC (src))
726 #if 0
727 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
728 exit (1);
729 #else
730 werror (E_SYNTAX_ERROR, yytext);
731 // the show must go on
732 return newIntLink ();
733 #endif
736 if (!options.std_c11 && !options.std_c99)
738 if (SPEC_SIGN (dest) && SPEC_SIGN (src))
739 werror (W_REPEAT_QUALIFIER, "signed");
740 if (SPEC_USIGN (dest) && SPEC_USIGN (src))
741 werror (W_REPEAT_QUALIFIER, "unsigned");
742 if (SPEC_CONST (dest) && SPEC_CONST (src))
743 werror (W_REPEAT_QUALIFIER, "const");
744 if (SPEC_VOLATILE (dest) && SPEC_VOLATILE (src))
745 werror (W_REPEAT_QUALIFIER, "volatile");
746 if (SPEC_STAT (dest) && SPEC_STAT (src))
747 werror (W_REPEAT_QUALIFIER, "static");
748 if (SPEC_EXTR (dest) && SPEC_EXTR (src))
749 werror (W_REPEAT_QUALIFIER, "extern");
750 if (SPEC_TYPEDEF (dest) && SPEC_TYPEDEF (src))
751 werror (W_REPEAT_QUALIFIER, "typedef");
752 if (SPEC_SCLS (dest) == S_REGISTER && SPEC_SCLS (src) == S_REGISTER)
753 werror (W_REPEAT_QUALIFIER, "register");
754 if (SPEC_SCLS (dest) == S_AUTO && SPEC_SCLS (src) == S_AUTO)
755 werror (W_REPEAT_QUALIFIER, "auto");
758 if (SPEC_NOUN (src))
760 if (!SPEC_NOUN (dest))
762 SPEC_NOUN (dest) = SPEC_NOUN (src);
764 else
766 /* we shouldn't redeclare the type */
767 if (getenv ("DEBUG_SANITY"))
769 fprintf (stderr, "mergeSpec: ");
771 werror (E_TWO_OR_MORE_DATA_TYPES, name);
775 if ((SPEC_SHORT (src) || SPEC_LONG (src) || SPEC_LONGLONG (src)) &&
776 (SPEC_SHORT (dest) || SPEC_LONG (dest) || SPEC_LONGLONG (dest)))
778 if (!(options.std_c99 && SPEC_LONG (src) && SPEC_LONG (dest) && !TARGET_IS_PIC14)) /* C99 has long long */
779 werror (E_SHORTLONG, name);
782 if (SPEC_SCLS (src))
784 /* if destination has no storage class */
785 if (!SPEC_SCLS (dest))
787 SPEC_SCLS (dest) = SPEC_SCLS (src);
789 else if (SPEC_SCLS (dest) == S_REGISTER && SPEC_SCLS (src) != S_AUTO)
791 SPEC_SCLS (dest) = SPEC_SCLS (src);
793 else
795 if (getenv ("DEBUG_SANITY"))
797 fprintf (stderr, "mergeSpec: ");
799 werror (E_TWO_OR_MORE_STORAGE_CLASSES, name);
803 /* copy all the specifications */
805 // we really should do:
806 #if 0
807 if (SPEC_what (src))
809 if (SPEC_what (dest))
811 werror (W_DUPLICATE_SPEC, "what");
813 SPEC_what (dst) |= SPEC_what (src);
815 #endif
816 // but there are more important thing right now
818 if (options.std_c99 && SPEC_LONG (src) && SPEC_LONG (dest))
820 SPEC_LONG (dest) = 0;
821 SPEC_LONGLONG (dest) = 1;
823 else
824 SPEC_LONG (dest) |= SPEC_LONG (src);
825 SPEC_LONGLONG (dest) |= SPEC_LONGLONG (src);
826 SPEC_SHORT (dest) |= SPEC_SHORT (src);
827 SPEC_USIGN (dest) |= SPEC_USIGN (src);
828 SPEC_BITINTWIDTH (dest) |= SPEC_BITINTWIDTH (src);
829 dest->select.s.b_signed |= src->select.s.b_signed;
830 SPEC_STAT (dest) |= SPEC_STAT (src);
831 SPEC_EXTR (dest) |= SPEC_EXTR (src);
832 SPEC_INLINE (dest) |= SPEC_INLINE (src);
833 SPEC_NORETURN (dest) |= SPEC_NORETURN(src);
834 SPEC_CONST (dest) |= SPEC_CONST (src);
835 SPEC_ABSA (dest) |= SPEC_ABSA (src);
836 SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
837 SPEC_RESTRICT (dest) |= SPEC_RESTRICT (src);
838 SPEC_ADDR (dest) |= SPEC_ADDR (src);
839 SPEC_OCLS (dest) = SPEC_OCLS (src);
840 SPEC_BLEN (dest) |= SPEC_BLEN (src);
841 SPEC_BSTR (dest) |= SPEC_BSTR (src);
842 SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
843 SPEC_ENUM (dest) |= SPEC_ENUM (src);
844 if (SPEC_ARGREG (src) && !SPEC_ARGREG (dest))
845 SPEC_ARGREG (dest) = SPEC_ARGREG (src);
847 if (SPEC_STAT (dest) && SPEC_EXTR (dest))
848 werror (E_TWO_OR_MORE_STORAGE_CLASSES, name);
850 if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
851 SPEC_STRUCT (dest) = SPEC_STRUCT (src);
853 if (FUNC_ISISR (dest) && FUNC_ISISR (src))
854 werror (E_INT_MULTIPLE, name);
856 /* these are the only function attributes that will be set
857 in a specifier while parsing */
858 FUNC_NONBANKED (dest) |= FUNC_NONBANKED (src);
859 FUNC_BANKED (dest) |= FUNC_BANKED (src);
860 FUNC_ISCRITICAL (dest) |= FUNC_ISCRITICAL (src);
861 FUNC_ISREENT (dest) |= FUNC_ISREENT (src);
862 FUNC_ISNAKED (dest) |= FUNC_ISNAKED (src);
863 FUNC_ISISR (dest) |= FUNC_ISISR (src);
864 FUNC_ISJAVANATIVE (dest) |= FUNC_ISJAVANATIVE (src);
865 FUNC_ISBUILTIN (dest) |= FUNC_ISBUILTIN (src);
866 FUNC_ISOVERLAY (dest) |= FUNC_ISOVERLAY (src);
867 FUNC_INTNO (dest) |= FUNC_INTNO (src);
868 FUNC_REGBANK (dest) |= FUNC_REGBANK (src);
869 FUNC_ISINLINE (dest) |= FUNC_ISINLINE (src);
870 FUNC_ISNORETURN (dest) |= FUNC_ISNORETURN (src);
871 if (FUNC_ISRAISONANCE (dest) && (FUNC_ISIAR (src) || FUNC_ISCOSMIC (src) || FUNC_SDCCCALL (src) >= 0 || FUNC_ISZ88DK_CALLEE (src)) ||
872 FUNC_ISIAR (dest) && (FUNC_ISRAISONANCE (src) || FUNC_ISCOSMIC (src) || FUNC_SDCCCALL (src) >= 0 || FUNC_ISZ88DK_CALLEE (src)) ||
873 FUNC_ISCOSMIC (dest) && (FUNC_ISRAISONANCE (src) || FUNC_ISIAR (src) || FUNC_SDCCCALL (src) >= 0 || FUNC_ISZ88DK_CALLEE (src)) ||
874 FUNC_SDCCCALL (dest) >= 0 && (FUNC_ISRAISONANCE (src) || FUNC_ISIAR (src) || FUNC_ISCOSMIC (src) || FUNC_SDCCCALL (src) >= 0 && FUNC_SDCCCALL (dest) != FUNC_SDCCCALL (src)) || // __sdcccall can be combined with __z88dk_callee.
875 FUNC_ISZ88DK_CALLEE (src) && (FUNC_ISRAISONANCE (src) || FUNC_ISIAR (dest) || FUNC_ISCOSMIC (dest)))
876 werror (E_MULTIPLE_CALLINGCONVENTIONS, name);
877 if (FUNC_SDCCCALL (dest) == -1)
878 FUNC_SDCCCALL (dest) = FUNC_SDCCCALL (src);
879 FUNC_ISSMALLC (dest) |= FUNC_ISSMALLC (src);
880 FUNC_ISRAISONANCE (dest) |= FUNC_ISRAISONANCE (src);
881 FUNC_ISIAR (dest) |= FUNC_ISIAR (src);
882 FUNC_ISCOSMIC (dest) |= FUNC_ISCOSMIC (src);
883 FUNC_ISZ88DK_FASTCALL (dest) |= FUNC_ISZ88DK_FASTCALL (src);
884 FUNC_ISZ88DK_CALLEE (dest) |= FUNC_ISZ88DK_CALLEE (src);
885 for (i = 0; i < 9; i++)
886 dest->funcAttrs.preserved_regs[i] |= src->funcAttrs.preserved_regs[i];
888 if (SPEC_ADDRSPACE (src) && SPEC_ADDRSPACE (dest))
889 werror (E_TWO_OR_MORE_STORAGE_CLASSES, name);
890 if (SPEC_ADDRSPACE (src))
891 SPEC_ADDRSPACE (dest) = SPEC_ADDRSPACE (src);
893 if (SPEC_ALIGNAS (src) > SPEC_ALIGNAS (dest))
894 SPEC_ALIGNAS (dest) = SPEC_ALIGNAS (src);
895 if (SPEC_SCLS (dest) == S_REGISTER && SPEC_ALIGNAS (dest))
896 werror (E_ALIGNAS, SPEC_ALIGNAS (dest));
898 return dest;
901 /*------------------------------------------------------------------*/
902 /* mergeDeclSpec - merges a specifier and a declarator */
903 /*------------------------------------------------------------------*/
904 sym_link *
905 mergeDeclSpec (sym_link * dest, sym_link * src, const char *name)
907 sym_link *decl, *spec, *lnk;
909 if (IS_SPEC (src))
911 if (IS_SPEC (dest))
913 return mergeSpec (dest, src, name);
915 else
917 decl = dest;
918 spec = src;
921 else
923 if (IS_SPEC (dest))
925 decl = src;
926 spec = dest;
928 else
930 werror (E_SYNTAX_ERROR, yytext);
931 // the show must go on
932 return newIntLink ();
936 // for pointers, type qualifiers go in the declarator
937 if (DCL_TYPE (decl) != ARRAY && DCL_TYPE (decl) != FUNCTION)
939 DCL_PTR_CONST (decl) |= SPEC_CONST (spec);
940 DCL_PTR_VOLATILE (decl) |= SPEC_VOLATILE (spec);
941 DCL_PTR_RESTRICT (decl) |= SPEC_RESTRICT (spec);
942 if (DCL_PTR_ADDRSPACE (decl) && SPEC_ADDRSPACE (spec) &&
943 strcmp (DCL_PTR_ADDRSPACE (decl)->name, SPEC_ADDRSPACE (spec)->name))
944 werror (E_SYNTAX_ERROR, yytext);
945 if (SPEC_ADDRSPACE (spec))
946 DCL_PTR_ADDRSPACE (decl) = SPEC_ADDRSPACE (spec);
948 SPEC_CONST (spec) = 0;
949 SPEC_VOLATILE (spec) = 0;
950 SPEC_RESTRICT (spec) = 0;
951 SPEC_ADDRSPACE (spec) = 0;
954 lnk = decl;
955 while (lnk && !IS_SPEC (lnk->next))
956 lnk = lnk->next;
957 lnk->next = mergeSpec (spec, lnk->next, name);
958 return decl;
961 /*-------------------------------------------------------------------*/
962 /* genSymName - generates and returns a name used for anonymous vars */
963 /*-------------------------------------------------------------------*/
964 char *
965 genSymName (long level)
967 static int gCount = 0;
968 static char gname[SDCC_NAME_MAX + 1];
970 SNPRINTF (gname, sizeof (gname), "__%04d%04d", level, gCount++);
971 return gname;
974 /*------------------------------------------------------------------*/
975 /* getSpec - returns the specifier part from a declaration chain */
976 /*------------------------------------------------------------------*/
977 sym_link *
978 getSpec (sym_link *p)
980 while (p && !(IS_SPEC (p)))
981 p = p->next;
983 return p;
986 /*------------------------------------------------------------------*/
987 /* newCharLink() - creates an char type */
988 /*------------------------------------------------------------------*/
989 sym_link *
990 newCharLink ()
992 sym_link *p;
994 p = newLink (SPECIFIER);
995 SPEC_NOUN (p) = V_CHAR;
996 SPEC_USIGN (p) = 1;
998 return p;
1001 /*------------------------------------------------------------------*/
1002 /* newFloatLink - a new Float type */
1003 /*------------------------------------------------------------------*/
1004 sym_link *
1005 newFloatLink ()
1007 sym_link *p;
1009 p = newLink (SPECIFIER);
1010 SPEC_NOUN (p) = V_FLOAT;
1012 return p;
1015 /*------------------------------------------------------------------*/
1016 /* newFixed16x16Link - a new Float type */
1017 /*------------------------------------------------------------------*/
1018 sym_link *
1019 newFixed16x16Link ()
1021 sym_link *p;
1023 p = newLink (SPECIFIER);
1024 SPEC_NOUN (p) = V_FIXED16X16;
1026 return p;
1029 /*------------------------------------------------------------------*/
1030 /* newLongLink() - new long type */
1031 /*------------------------------------------------------------------*/
1032 sym_link *
1033 newLongLink ()
1035 sym_link *p;
1037 p = newLink (SPECIFIER);
1038 SPEC_NOUN (p) = V_INT;
1039 SPEC_LONG (p) = 1;
1041 return p;
1044 /*------------------------------------------------------------------*/
1045 /* newLongLongLink() - new long long type */
1046 /*------------------------------------------------------------------*/
1047 sym_link *
1048 newLongLongLink ()
1050 sym_link *p;
1052 p = newLink (SPECIFIER);
1053 SPEC_NOUN (p) = V_INT;
1054 SPEC_LONGLONG (p) = 1;
1056 return p;
1059 /*------------------------------------------------------------------*/
1060 /* newBitIntLink() - creates a BitInt type */
1061 /*------------------------------------------------------------------*/
1062 sym_link *
1063 newBitIntLink (unsigned int width)
1065 wassert (width <= port->s.bitint_maxwidth);
1067 sym_link *p;
1069 p = newLink (SPECIFIER);
1070 SPEC_NOUN (p) = V_BITINT;
1071 SPEC_BITINTWIDTH (p) = width;
1073 return p;
1076 /*------------------------------------------------------------------*/
1077 /* newIntLink() - creates an int type */
1078 /*------------------------------------------------------------------*/
1079 sym_link *
1080 newIntLink ()
1082 sym_link *p;
1084 p = newLink (SPECIFIER);
1085 SPEC_NOUN (p) = V_INT;
1087 return p;
1090 /*------------------------------------------------------------------*/
1091 /* newBoolLink() - creates an bool type */
1092 /*------------------------------------------------------------------*/
1093 sym_link *
1094 newBoolLink ()
1096 sym_link *p;
1098 p = newLink (SPECIFIER);
1099 if (bit)
1100 SPEC_NOUN (p) = V_BIT;
1101 else
1102 SPEC_NOUN (p) = V_BOOL;
1104 return p;
1107 /*------------------------------------------------------------------*/
1108 /* newPtrDiffLink() - creates a ptrdiff type */
1109 /*------------------------------------------------------------------*/
1110 sym_link *
1111 newPtrDiffLink ()
1113 if (GPTRSIZE <= INTSIZE)
1114 return newIntLink ();
1115 else if (GPTRSIZE <= LONGSIZE)
1116 return newLongLink ();
1117 else if (GPTRSIZE <= LONGLONGSIZE)
1118 return newLongLongLink();
1119 else
1121 assert (0);
1122 return NULL;
1126 /*------------------------------------------------------------------*/
1127 /* newVoidLink() - creates an void type */
1128 /*------------------------------------------------------------------*/
1129 sym_link *
1130 newVoidLink ()
1132 sym_link *p;
1134 p = newLink (SPECIFIER);
1135 SPEC_NOUN (p) = V_VOID;
1137 return p;
1140 /*------------------------------------------------------------------*/
1141 /* getSize - returns size of a type chain in bytes */
1142 /*------------------------------------------------------------------*/
1143 unsigned int
1144 getSize (sym_link * p)
1146 /* if nothing return 0 */
1147 if (!p)
1148 return 0;
1149 if (IS_SPEC (p))
1150 { /* if this is the specifier then */
1151 switch (SPEC_NOUN (p))
1152 { /* depending on the specifier type */
1153 case V_INT:
1154 return (IS_LONGLONG (p) ? LONGLONGSIZE : (IS_LONG (p) ? LONGSIZE : INTSIZE));
1155 case V_BITINT:
1156 return ((SPEC_BITINTWIDTH (p) / 8) + (SPEC_BITINTWIDTH (p) % 8 ? 1 : 0));
1157 case V_FLOAT:
1158 return FLOATSIZE;
1159 case V_FIXED16X16:
1160 return (4);
1161 case V_BOOL:
1162 return BOOLSIZE;
1163 case V_CHAR:
1164 return CHARSIZE;
1165 case V_NULLPTR:
1166 return (GPTRSIZE);
1167 case V_VOID:
1168 return 0;
1169 case V_STRUCT:
1170 return SPEC_STRUCT (p)->size;
1171 case V_LABEL:
1172 return 0;
1173 case V_SBIT:
1174 case V_BIT:
1175 return BITSIZE;
1176 case V_BITFIELD:
1177 case V_BBITFIELD:
1178 case V_BITINTBITFIELD:
1179 return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
1180 default:
1181 return 0;
1185 /* this is a declarator */
1186 switch (DCL_TYPE (p))
1188 case ARRAY:
1189 if (DCL_ELEM (p))
1191 return DCL_ELEM (p) * getSize (p->next);
1193 else
1195 return 0;
1197 case IPOINTER:
1198 case PPOINTER:
1199 case POINTER:
1200 return (NEARPTRSIZE);
1201 case EEPPOINTER:
1202 case FPOINTER:
1203 case CPOINTER:
1204 if (!IS_FUNCPTR(p))
1205 return (FARPTRSIZE);
1206 case GPOINTER:
1207 if (!IS_FUNCPTR(p))
1208 return (GPTRSIZE);
1209 case FUNCTION:
1210 if (IS_FUNCPTR(p))
1211 return ((IFFUNC_ISBANKEDCALL (p->next) || TARGET_IS_STM8 && IFFUNC_ISCOSMIC (p->next)) ? BFUNCPTRSIZE : FUNCPTRSIZE);
1212 return ((IFFUNC_ISBANKEDCALL (p) || TARGET_IS_STM8 && IFFUNC_ISCOSMIC (p)) ? BFUNCPTRSIZE : FUNCPTRSIZE);
1214 default:
1215 return 0;
1219 #define FLEXARRAY 1
1220 #define INCOMPLETE 2
1222 /*------------------------------------------------------------------*/
1223 /* checkStructFlexArray - check tree behind a struct */
1224 /*------------------------------------------------------------------*/
1225 static int
1226 checkStructFlexArray (symbol * sym, sym_link * p)
1228 /* if nothing return FALSE */
1229 if (!p)
1230 return 0;
1232 if (IS_SPEC (p))
1234 /* (nested) struct with flexible array member? */
1235 if (IS_STRUCT (p) && SPEC_STRUCT (p)->b_flexArrayMember)
1237 werror (W_INVALID_FLEXARRAY);
1238 return INCOMPLETE;
1240 /* or otherwise incomplete (nested) struct? */
1241 if (IS_STRUCT (p) && ((SPEC_STRUCT (p)->size == 0) || !SPEC_STRUCT (p)->fields))
1243 return INCOMPLETE;
1245 return 0;
1248 /* this is a declarator */
1249 if (IS_ARRAY (p))
1251 /* flexible array member? */
1252 if (!DCL_ELEM (p))
1254 if (!options.std_c99)
1255 werror (W_C89_NO_FLEXARRAY);
1256 if (checkStructFlexArray (sym, p->next) == INCOMPLETE)
1257 werror (E_INCOMPLETE_FIELD, sym->name);
1258 return FLEXARRAY;
1260 /* walk tree */
1261 return checkStructFlexArray (sym, p->next);
1263 return 0;
1266 /*------------------------------------------------------------------*/
1267 /* bitsForType - returns # of bits required to store this type */
1268 /*------------------------------------------------------------------*/
1269 unsigned int
1270 bitsForType (sym_link *p)
1272 /* if nothing return 0 */
1273 if (!p)
1274 return 0;
1276 if (IS_SPEC (p))
1277 { /* if this is the specifier then */
1278 switch (SPEC_NOUN (p))
1279 { /* depending on the specifier type */
1280 case V_INT:
1281 if (IS_LONGLONG (p))
1282 return LONGLONGSIZE * 8;
1283 if (IS_LONG (p))
1284 return LONGSIZE * 8;
1285 return INTSIZE * 8;
1286 case V_BITINT:
1287 return SPEC_BITINTWIDTH (p);
1288 case V_FLOAT:
1289 return FLOATSIZE * 8;
1290 case V_FIXED16X16:
1291 return (32);
1292 case V_BOOL:
1293 return BOOLSIZE * 8;
1294 case V_CHAR:
1295 return CHARSIZE * 8;
1296 case V_VOID:
1297 return 0;
1298 case V_STRUCT:
1299 return SPEC_STRUCT (p)->size * 8;
1300 case V_LABEL:
1301 return 0;
1302 case V_SBIT:
1303 case V_BIT:
1304 return 1;
1305 case V_BITFIELD:
1306 case V_BBITFIELD:
1307 case V_BITINTBITFIELD:
1308 return SPEC_BLEN (p);
1309 default:
1310 return 0;
1314 /* this is a specifier */
1315 switch (DCL_TYPE (p))
1317 case ARRAY:
1318 return DCL_ELEM (p) * getSize (p->next) * 8;
1319 case IPOINTER:
1320 case PPOINTER:
1321 case POINTER:
1322 return (NEARPTRSIZE * 8);
1323 case EEPPOINTER:
1324 case FPOINTER:
1325 case CPOINTER:
1326 case FUNCTION:
1327 return (FARPTRSIZE * 8);
1328 case GPOINTER:
1329 return (GPTRSIZE * 8);
1330 default:
1331 return 0;
1335 /*------------------------------------------------------------------*/
1336 /* copySymbolChain - copies a symbol chain */
1337 /*------------------------------------------------------------------*/
1338 symbol *
1339 copySymbolChain (const symbol * src)
1341 symbol *dest;
1343 if (!src)
1344 return NULL;
1346 dest = copySymbol (src);
1347 dest->next = copySymbolChain (src->next);
1348 return dest;
1351 /*------------------------------------------------------------------*/
1352 /* copySymbol - makes a copy of a symbol */
1353 /*------------------------------------------------------------------*/
1354 symbol *
1355 copySymbol (const symbol * src)
1357 symbol *dest;
1359 if (!src)
1360 return NULL;
1362 dest = newSymbol (src->name, src->level);
1363 memcpy (dest, src, sizeof (symbol));
1364 dest->level = src->level;
1365 dest->block = src->block;
1366 dest->ival = copyIlist (src->ival);
1367 dest->type = copyLinkChain (src->type);
1368 dest->etype = getSpec (dest->type);
1369 dest->next = NULL;
1370 dest->key = src->key;
1371 dest->allocreq = src->allocreq;
1372 return dest;
1375 /*------------------------------------------------------------------*/
1376 /* reverseSyms - reverses the links for a symbol chain */
1377 /*------------------------------------------------------------------*/
1378 symbol *
1379 reverseSyms (symbol * sym)
1381 symbol *prev, *curr, *next;
1383 if (!sym)
1384 return NULL;
1386 prev = sym;
1387 curr = sym->next;
1389 while (curr)
1391 next = curr->next;
1392 curr->next = prev;
1393 prev = curr;
1394 curr = next;
1396 sym->next = (void *) NULL;
1397 return prev;
1400 /*------------------------------------------------------------------*/
1401 /* reverseLink - reverses the links for a type chain */
1402 /*------------------------------------------------------------------*/
1403 sym_link *
1404 reverseLink (sym_link * type)
1406 sym_link *prev, *curr, *next;
1408 if (!type)
1409 return NULL;
1411 prev = type;
1412 curr = type->next;
1414 while (curr)
1416 next = curr->next;
1417 curr->next = prev;
1418 prev = curr;
1419 curr = next;
1421 type->next = (void *) NULL;
1422 return prev;
1425 /*------------------------------------------------------------------*/
1426 /*arraySizes - fill in missing known array sizes */
1427 /*------------------------------------------------------------------*/
1428 static void
1429 arraySizes (sym_link *type, const char *name)
1431 // Recurse
1432 if (IS_DECL(type) && type->select.d.vla_check_visited)
1433 return;
1435 if (IS_ARRAY (type) && !DCL_ELEM (type) && DCL_ELEM_AST (type))
1437 value *tval = constExprValue(DCL_ELEM_AST (type), true);
1438 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL))
1440 if (!options.std_c99)
1441 werror(E_VLA_TYPE_C99);
1442 DCL_ARRAY_VLA(type) = true;
1444 else
1446 int size = ulFromVal(tval);
1447 if (floatFromVal(tval) < 0.0)
1449 werror(E_NEGATIVE_ARRAY_SIZE, name);
1450 size = 1;
1452 DCL_ELEM(type) = size;
1455 if (IS_DECL(type))
1456 type->select.d.vla_check_visited = true;
1458 if (IS_DECL(type))
1459 arraySizes (type->next, name);
1460 else if (IS_STRUCT (type))
1461 for(symbol *fields = SPEC_STRUCT (type)->fields; fields; fields = fields->next)
1462 arraySizes (fields->type, name);
1465 /*------------------------------------------------------------------*/
1466 /* addSymChain - adds a symbol chain to the symboltable */
1467 /*------------------------------------------------------------------*/
1468 void
1469 addSymChain (symbol ** symHead)
1471 symbol *sym;
1472 symbol *csym = NULL;
1473 symbol **symPtrPtr;
1474 int error = 0;
1475 int elemsFromIval = 0;
1477 for (sym = *symHead; sym; sym = sym->next)
1479 changePointer (sym->type);
1480 checkTypeSanity (sym->etype, sym->name);
1481 #if 0
1482 printf("addSymChain for %p %s level %ld\n", sym, sym->name, sym->level);
1483 #endif
1484 arraySizes (sym->type, sym->name);
1485 if (IS_NORETURN (sym->etype))
1487 SPEC_NORETURN (sym->etype) = 0;
1488 FUNC_ISNORETURN (sym->type) = 1;
1491 if (!sym->level && IS_ARRAY (sym->type) && IS_ARRAY (sym->type) && DCL_ARRAY_VLA (sym->type))
1493 werror (E_VLA_SCOPE);
1494 continue;
1497 if (!sym->level && !(IS_SPEC (sym->etype) && IS_TYPEDEF (sym->etype)))
1498 elemsFromIval = checkDecl (sym, 0);
1499 else
1501 if (IS_ARRAY (sym->type) && DCL_ELEM_AST (sym->type))
1502 arraySizes (sym->type, sym->name);
1503 // if this is an array without any dimension then update the dimension from the initial value
1504 else if (IS_ARRAY (sym->type) && !DCL_ELEM_AST (sym->type) && !DCL_ELEM (sym->type))
1505 elemsFromIval = DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1508 /* if already exists in the symbol table on the same level, ignoring sublevels */
1509 if ((csym = findSymWithLevel (SymbolTab, sym)) && csym->level / LEVEL_UNIT == sym->level / LEVEL_UNIT)
1511 /* if not formal parameter and not in file scope
1512 then show symbol redefined error
1513 else check if symbols have compatible types */
1514 if (!sym->_isparm && sym->level > 0)
1515 error = 1;
1516 else
1518 /* If the previous definition was for an array with incomplete
1519 type, and the new definition has completed the type, update
1520 the original type to match (or the otehr way round) */
1521 if (IS_ARRAY (csym->type) && IS_ARRAY (sym->type))
1523 if (!DCL_ELEM (csym->type) && DCL_ELEM (sym->type))
1524 DCL_ELEM (csym->type) = DCL_ELEM (sym->type);
1525 else if (DCL_ELEM (csym->type) && !DCL_ELEM (sym->type))
1526 DCL_ELEM (sym->type) = DCL_ELEM (csym->type);
1527 if ((DCL_ELEM (csym->type) > DCL_ELEM (sym->type)) && elemsFromIval)
1528 DCL_ELEM (sym->type) = DCL_ELEM (csym->type);
1530 // Is one is a function declarator without a prototype (valid up to C17), and the other one with a prototype, use the prototype for both. */
1531 if (IS_FUNC (csym->type) && IS_FUNC (sym->type) && (FUNC_NOPROTOTYPE (csym->type) ^ FUNC_NOPROTOTYPE (sym->type)))
1533 if (FUNC_NOPROTOTYPE (csym->type))
1534 FUNC_ARGS(csym->type) = FUNC_ARGS(sym->type);
1535 else
1536 FUNC_ARGS(sym->type) = FUNC_ARGS(csym->type);
1537 FUNC_NOPROTOTYPE (csym->type) = false;
1538 FUNC_NOPROTOTYPE (sym->type) = false;
1541 #if 0
1542 /* If only one of the definitions used the "at" keyword, copy */
1543 /* the address to the other. */
1544 if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype) && IS_SPEC (sym->etype) && !SPEC_ABSA (sym->etype))
1546 SPEC_ABSA (sym->etype) = 1;
1547 SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1549 if (IS_SPEC (csym->etype) && !SPEC_ABSA (csym->etype) && IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1551 SPEC_ABSA (csym->etype) = 1;
1552 SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1554 #endif
1556 error = 0;
1557 if (csym->ival && sym->ival)
1558 error = 1;
1559 if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1560 error = 1;
1563 if (error)
1565 /* one definition extern ? */
1566 if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1567 werror (E_EXTERN_MISMATCH, sym->name);
1568 else
1569 werror (E_DUPLICATE, sym->name);
1570 werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1571 #if 0
1572 fprintf (stderr, "from type '");
1573 printTypeChain (csym->type, stderr);
1574 if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1575 fprintf (stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1576 fprintf (stderr, "'\nto type '");
1577 printTypeChain (sym->type, stderr);
1578 if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1579 fprintf (stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1580 fprintf (stderr, "'\n");
1581 #endif
1582 continue;
1585 if (FUNC_BANKED (csym->type) || FUNC_BANKED (sym->type))
1587 if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
1589 werror (W_BANKED_WITH_NONBANKED);
1590 FUNC_BANKED (sym->type) = 0;
1591 FUNC_NONBANKED (sym->type) = 1;
1593 else
1595 FUNC_BANKED (sym->type) = 1;
1598 else
1600 if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
1602 FUNC_NONBANKED (sym->type) = 1;
1606 if (csym->ival && !sym->ival)
1607 sym->ival = csym->ival;
1609 if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype))
1611 /* if none of symbols is a compiler defined function
1612 and at least one is not extern
1613 then set the new symbol to non extern */
1614 SPEC_EXTR (sym->etype) = SPEC_EXTR (csym->etype);
1617 /* delete current entry */
1618 deleteSym (SymbolTab, csym, csym->name);
1619 deleteFromSeg (csym);
1621 symPtrPtr = symHead;
1622 while (*symPtrPtr && *symPtrPtr != csym)
1623 symPtrPtr = &(*symPtrPtr)->next;
1624 if (*symPtrPtr == csym)
1625 *symPtrPtr = csym->next;
1628 /* add new entry */
1629 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1634 /*------------------------------------------------------------------*/
1635 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
1636 /*------------------------------------------------------------------*/
1638 funcInChain (sym_link * lnk)
1640 while (lnk)
1642 if (IS_FUNC (lnk))
1643 return 1;
1644 lnk = lnk->next;
1646 return 0;
1649 /*------------------------------------------------------------------*/
1650 /* structElemType - returns the type info of a struct member */
1651 /*------------------------------------------------------------------*/
1652 sym_link *
1653 structElemType (sym_link * stype, value * id)
1655 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1656 sym_link *type, *etype;
1657 sym_link *petype = getSpec (stype);
1659 if (fields && id)
1661 /* look for the id */
1662 while (fields)
1664 if (strcmp (fields->rname, id->name) == 0)
1666 sym_link *t;
1667 type = copyLinkChain (fields->type);
1668 etype = getSpec (type);
1669 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? SPEC_SCLS (etype) : SPEC_SCLS (petype));
1670 SPEC_OCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? SPEC_OCLS (etype) : SPEC_OCLS (petype));
1671 /* find the first non-array link */
1672 t = type;
1673 while (IS_ARRAY (t))
1674 t = t->next;
1675 if (IS_SPEC (t))
1676 SPEC_CONST (t) |= SPEC_CONST (stype);
1677 else
1678 DCL_PTR_CONST (t) |= SPEC_CONST (stype);
1679 return type;
1681 fields = fields->next;
1685 werror (E_NOT_MEMBER, id->name);
1687 // the show must go on
1688 return newIntLink ();
1691 /*------------------------------------------------------------------*/
1692 /* getStructElement - returns element of a tructure definition */
1693 /*------------------------------------------------------------------*/
1694 symbol *
1695 getStructElement (structdef * sdef, symbol * sym)
1697 symbol *field;
1699 for (field = sdef->fields; field; field = field->next)
1700 if (strcmp (field->name, sym->name) == 0)
1701 return field;
1703 werror (E_NOT_MEMBER, sym->name);
1705 return sdef->fields;
1708 /*------------------------------------------------------------------*/
1709 /* compStructSize - computes the size of a structure */
1710 /*------------------------------------------------------------------*/
1712 compStructSize (int su, structdef * sdef)
1714 int sum = 0, usum = 0;
1715 int bitOffset = 0;
1716 symbol *loop;
1717 const int oldlineno = lineno;
1719 if (!sdef->fields)
1721 werror (E_UNKNOWN_SIZE, sdef->tag);
1724 /* for the identifiers */
1725 loop = sdef->fields;
1726 while (loop)
1728 lineno = loop->lineDef;
1730 /* create the internal name for this variable */
1731 SNPRINTF (loop->rname, sizeof (loop->rname), "_%s", loop->name);
1732 if (su == UNION)
1734 sum = 0;
1735 bitOffset = 0;
1737 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1739 /* if this is a bit field */
1740 if (loop->bitVar)
1742 SPEC_BUNNAMED (loop->etype) = loop->bitUnnamed;
1744 /* change it to a unsigned bit */
1745 switch (SPEC_NOUN (loop->etype))
1747 case V_BOOL:
1748 SPEC_NOUN( loop->etype) = V_BBITFIELD;
1749 if (loop->bitVar > 1)
1750 werror (E_BITFLD_SIZE, 1);
1751 break;
1752 case V_CHAR:
1753 SPEC_NOUN (loop->etype) = V_BITFIELD;
1754 if (loop->bitVar > 8)
1755 werror (E_BITFLD_SIZE , 8);
1756 break;
1757 case V_INT:
1758 SPEC_NOUN (loop->etype) = V_BITFIELD;
1759 if (loop->bitVar > port->s.int_size * 8)
1760 werror (E_BITFLD_SIZE , port->s.int_size * 8);
1761 break;
1762 case V_BITINT:
1763 SPEC_NOUN (loop->etype) = V_BITINTBITFIELD;
1764 if (loop->bitVar > SPEC_BITINTWIDTH (loop->etype))
1765 werror (E_BITFLD_SIZE , SPEC_BITINTWIDTH (loop->etype));
1766 break;
1767 default:
1768 werror (E_BITFLD_TYPE);
1771 /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
1772 /* a "plain" int bitfield is unsigned */
1773 if (!loop->etype->select.s.b_signed && SPEC_NOUN (loop->etype) != V_BITINTBITFIELD)
1774 SPEC_USIGN (loop->etype) = 1;
1776 if (loop->bitVar == BITVAR_PAD)
1778 /* A zero length bitfield forces padding */
1779 SPEC_BLEN (loop->etype) = 0;
1780 SPEC_BSTR (loop->etype) = bitOffset;
1781 if (bitOffset > 0)
1782 bitOffset = 8; /* padding is not needed when at bit 0 */
1783 loop->offset = sum;
1785 else
1787 SPEC_BLEN (loop->etype) = loop->bitVar;
1789 if (bitOffset == 8)
1791 bitOffset = 0;
1792 sum++;
1794 /* check if this fit into the remaining */
1795 /* bits of this byte else align it to the */
1796 /* next byte boundary */
1797 if (loop->bitVar <= (8 - bitOffset))
1799 /* fits into current byte */
1800 loop->offset = sum;
1801 SPEC_BSTR (loop->etype) = bitOffset;
1802 bitOffset += loop->bitVar;
1804 else if (!bitOffset)
1806 /* does not fit, but is already byte aligned */
1807 loop->offset = sum;
1808 SPEC_BSTR (loop->etype) = bitOffset;
1809 bitOffset += loop->bitVar;
1811 else
1813 if (TARGET_IS_PIC16 && getenv ("PIC16_PACKED_BITFIELDS"))
1815 /* if PIC16 && environment variable is set, then
1816 * tightly pack bitfields, this means that when a
1817 * bitfield goes beyond byte alignment, do not
1818 * automatically start allocatint from next byte,
1819 * but also use the available bits first */
1820 fprintf (stderr, ": packing bitfields in structures\n");
1821 SPEC_BSTR (loop->etype) = bitOffset;
1822 bitOffset += loop->bitVar;
1823 loop->offset = (su == UNION ? sum = 0 : sum);
1825 else
1827 /* does not fit; need to realign first */
1828 sum++;
1829 loop->offset = (su == UNION ? sum = 0 : sum);
1830 bitOffset = 0;
1831 SPEC_BSTR (loop->etype) = bitOffset;
1832 bitOffset += loop->bitVar;
1835 while (bitOffset > 8)
1837 bitOffset -= 8;
1838 sum++;
1842 else
1844 /* This is a non-bit field. Make sure we are */
1845 /* byte aligned first */
1846 if (bitOffset)
1848 sum++;
1849 loop->offset = (su == UNION ? sum = 0 : sum);
1850 bitOffset = 0;
1852 loop->offset = sum;
1853 checkDecl (loop, 1);
1854 sum += getSize (loop->type);
1856 /* search for "flexible array members" */
1857 /* and do some syntax checks */
1858 if (su == STRUCT)
1860 int ret = checkStructFlexArray (loop, loop->type);
1861 if (ret == FLEXARRAY)
1863 /* found a "flexible array member" */
1864 sdef->b_flexArrayMember = TRUE;
1865 /* is another struct-member following? */
1866 if (loop->next)
1867 werror (E_FLEXARRAY_NOTATEND, loop->name);
1868 /* is it the first struct-member? */
1869 else if (loop == sdef->fields)
1870 werror (E_FLEXARRAY_INEMPTYSTRCT, loop->name);
1872 else if (ret == INCOMPLETE)
1874 werror (E_INCOMPLETE_FIELD, loop->name);
1879 loop = loop->next;
1881 /* if union then size = sizeof largest field */
1882 if (su == UNION)
1884 /* For UNION, round up after each field */
1885 sum += ((bitOffset + 7) / 8);
1886 usum = max (usum, sum);
1890 /* For STRUCT, round up after all fields processed */
1891 if (su != UNION)
1892 sum += ((bitOffset + 7) / 8);
1894 lineno = oldlineno;
1896 return (su == UNION ? usum : sum);
1899 /*-------------------------------------------------------------------*/
1900 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1901 /* an enclosing struct/union */
1902 /*-------------------------------------------------------------------*/
1903 void
1904 promoteAnonStructs (int su, structdef * sdef)
1906 symbol *field;
1907 symbol *subfield;
1908 symbol **tofield;
1909 symbol *nextfield;
1910 symbol *dupfield;
1911 int base;
1913 tofield = &sdef->fields;
1914 for (field = sdef->fields; field; field = nextfield)
1916 nextfield = field->next;
1917 if (!*field->name && IS_STRUCT (field->type))
1919 /* Found an anonymous struct/union. Replace it */
1920 /* with the fields it contains and adjust all */
1921 /* the offsets */
1923 /* tagged anonymous struct/union is rejected here, though gcc allow it */
1924 if (SPEC_STRUCT (field->type)->tagsym != NULL)
1925 werrorfl (field->fileDef, field->lineDef, E_ANONYMOUS_STRUCT_TAG, SPEC_STRUCT (field->type)->tag);
1927 base = field->offset;
1928 subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1929 if (!subfield)
1930 continue; /* just in case it's empty */
1932 *tofield = subfield;
1933 for (;;)
1935 /* check for field name conflicts resulting from promotion */
1936 dupfield = sdef->fields;
1937 while (dupfield && dupfield != subfield)
1939 if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1941 werrorfl (subfield->fileDef, subfield->lineDef,
1942 E_DUPLICATE_MEMBER, su == STRUCT ? "struct" : "union", subfield->name);
1943 werrorfl (dupfield->fileDef, dupfield->lineDef, E_PREVIOUS_DEF);
1945 dupfield = dupfield->next;
1948 subfield->offset += base;
1949 if (subfield->next)
1950 subfield = subfield->next;
1951 else
1952 break;
1954 subfield->next = nextfield;
1955 tofield = &subfield->next;
1957 else
1958 tofield = &field->next;
1963 /*------------------------------------------------------------------*/
1964 /* checkSClass - check the storage class specification */
1965 /*------------------------------------------------------------------*/
1966 static void
1967 checkSClass (symbol *sym, int isProto)
1969 sym_link *t;
1971 if (getenv ("DEBUG_SANITY"))
1973 fprintf (stderr, "checkSClass: %s \n", sym->name);
1976 if (!sym->level && SPEC_SCLS (sym->etype) == S_AUTO)
1978 werrorfl (sym->fileDef, sym->lineDef, E_AUTO_FILE_SCOPE);
1979 SPEC_SCLS (sym->etype) = S_FIXED;
1982 if (SPEC_SCLS (sym->etype) == S_AUTO && SPEC_EXTR(sym->etype) ||
1983 SPEC_SCLS (sym->etype) == S_AUTO && SPEC_STAT(sym->etype))
1985 werrorfl (sym->fileDef, sym->lineDef, E_TWO_OR_MORE_STORAGE_CLASSES, sym->name);
1988 /* type is literal can happen for enums change to auto */
1989 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1990 SPEC_SCLS (sym->etype) = S_AUTO;
1992 /* if sfr or sbit then must also be volatile */
1993 if (SPEC_SCLS (sym->etype) == S_SBIT || SPEC_SCLS (sym->etype) == S_SFR)
1995 SPEC_VOLATILE (sym->etype) = 1;
1998 if (SPEC_NEEDSPAR (sym->etype))
2000 werrorfl (sym->fileDef, sym->lineDef, E_QUALIFIED_ARRAY_NOPARAM);
2001 SPEC_NEEDSPAR (sym->etype) = 0;
2004 /* make sure restrict is only used with pointers */
2005 if (SPEC_RESTRICT (sym->etype))
2007 werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
2008 SPEC_RESTRICT (sym->etype) = 0;
2011 t = sym->type;
2012 while (t)
2014 if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !(IS_PTR (t) && !IS_FUNCPTR(t)))
2016 werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
2017 DCL_PTR_RESTRICT (t) = 0;
2018 break;
2020 t = t->next;
2023 /* if absolute address given then it mark it as
2024 volatile -- except in the PIC port */
2026 #if !OPT_DISABLE_PIC14 || !OPT_DISABLE_PIC16
2027 /* The PIC port uses a different peep hole optimizer based on "pCode" */
2028 if (!TARGET_PIC_LIKE)
2029 #endif
2031 if (IS_ABSOLUTE (sym->etype))
2032 SPEC_VOLATILE (sym->etype) = 1;
2034 if (TARGET_IS_MCS51 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2036 int n, size;
2037 unsigned addr;
2039 if (SPEC_NOUN (sym->etype) == V_CHAR)
2040 size = 8;
2041 else if (SPEC_LONG (sym->etype) == 0)
2042 size = 16;
2043 else if (SPEC_LONGLONG (sym->etype) == 0)
2044 size = 32;
2045 else
2046 size = 64;
2048 addr = SPEC_ADDR (sym->etype);
2049 for (n = 0; n < size; n += 8)
2050 if (((addr >> n) & 0xFF) < 0x80)
2051 werror (W_SFR_ABSRANGE, sym->name);
2053 else if (TARGET_IS_MCS51 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_DATA)
2055 if (SPEC_ADDR (sym->etype) + getSize (sym->type) - 1 > 0x7f)
2056 werror (W_DATA_ABSRANGE, sym->name);
2058 else if (TARGET_IS_MCS51 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_IDATA)
2060 if (SPEC_ADDR (sym->etype) + getSize (sym->type) - 1 > 0xff)
2061 werror (W_IDATA_ABSRANGE, sym->name);
2063 else if ((TARGET_HC08_LIKE || TARGET_MOS6502_LIKE) && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_DATA)
2065 if (SPEC_ADDR (sym->etype) + getSize (sym->type) - 1 > 0xff)
2066 werror (W_DATA_ABSRANGE, sym->name);
2068 else if (TARGET_IS_SM83 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2069 {// Unlike the other z80-like ports, sm83 has memory mapped I/O in the 0xff00-0xffff range.
2070 if (SPEC_ADDR (sym->etype) < 0xff00 || SPEC_ADDR (sym->etype) > 0xffff)
2071 werror (W_SFR_ABSRANGE, sym->name);
2073 else if (TARGET_Z80_LIKE && !TARGET_IS_SM83 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2075 if (SPEC_ADDR (sym->etype) > (FUNC_REGBANK (sym->type) ? 0xffff : 0xff))
2076 werror (W_SFR_ABSRANGE, sym->name);
2078 else if (TARGET_IS_PDK13 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2080 if (SPEC_ADDR (sym->etype) > 0x1f)
2081 werror (W_SFR_ABSRANGE, sym->name);
2083 else if (TARGET_IS_PDK14 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2085 if (SPEC_ADDR (sym->etype) > 0x3f)
2086 werror (W_SFR_ABSRANGE, sym->name);
2088 else if (TARGET_IS_PDK15 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2090 if (SPEC_ADDR (sym->etype) > 0x7f)
2091 werror (W_SFR_ABSRANGE, sym->name);
2093 else if (TARGET_IS_PDK16 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR)
2095 if (SPEC_ADDR (sym->etype) > 0x1f)
2096 werror (W_SFR_ABSRANGE, sym->name);
2099 /* If code memory is read only, then pointers to code memory */
2100 /* implicitly point to constants -- make this explicit */
2101 CodePtrPointsToConst (sym->type);
2103 /* global variables declared const put into code */
2104 /* if no other storage class specified */
2105 if ((sym->level == 0 || SPEC_STAT(sym->etype)) && SPEC_SCLS (sym->etype) == S_FIXED && !IS_FUNC (sym->type))
2107 /* find the first non-array link */
2108 t = sym->type;
2109 while (IS_ARRAY (t))
2110 t = t->next;
2111 if (IS_CONSTANT (t))
2113 SPEC_SCLS (sym->etype) = S_CODE;
2114 SPEC_SCLS_IMPLICITINTRINSIC (sym->etype) = true;
2118 /* global variable in code space is a constant */
2119 if ((sym->level == 0 || SPEC_STAT(sym->etype)) && SPEC_SCLS (sym->etype) == S_CODE && port->mem.code_ro)
2121 /* find the first non-array link */
2122 t = sym->type;
2123 while (IS_ARRAY (t))
2124 t = t->next;
2125 if (IS_SPEC (t))
2126 SPEC_CONST (t) = 1;
2127 else
2128 DCL_PTR_CONST (t) = 1;
2131 /* if bit variable then no storage class can be */
2132 /* specified since bit is already a storage */
2133 if (IS_BITVAR (sym->etype) &&
2134 (SPEC_SCLS (sym->etype) != S_FIXED && SPEC_SCLS (sym->etype) != S_SBIT && SPEC_SCLS (sym->etype) != S_BIT))
2136 /* find out if this is the return type of a function */
2137 t = sym->type;
2138 while (t && t->next != sym->etype)
2139 t = t->next;
2140 if (!t || t->next != sym->etype || !IS_FUNC (t))
2142 werror (E_BITVAR_STORAGE, sym->name);
2143 SPEC_SCLS (sym->etype) = S_FIXED;
2147 /* if this is an automatic symbol */
2148 if (sym->level && (options.stackAuto || reentrant))
2150 if (SPEC_SCLS (sym->etype) != S_BIT &&
2151 SPEC_SCLS (sym->etype) != S_REGISTER)
2153 if ((SPEC_SCLS (sym->etype) == S_AUTO ||
2154 SPEC_SCLS (sym->etype) == S_FIXED ||
2155 SPEC_SCLS (sym->etype) == S_STACK ||
2156 SPEC_SCLS (sym->etype) == S_XSTACK))
2158 SPEC_SCLS (sym->etype) = S_AUTO;
2160 else
2162 /* storage class may only be specified for statics */
2163 if (!IS_STATIC (sym->etype))
2165 werror (E_AUTO_ASSUMED, sym->name);
2171 /* automatic symbols cannot be given */
2172 /* an absolute address ignore it */
2173 if (sym->level && !IS_STATIC (sym->etype) && SPEC_ABSA (sym->etype) && (options.stackAuto || reentrant))
2175 werror (E_AUTO_ABSA, sym->name);
2176 SPEC_ABSA (sym->etype) = 0;
2179 if (sym->level && !IS_STATIC (sym->etype) && (IS_DECL (sym->type) ? DCL_PTR_ADDRSPACE (sym->type) : SPEC_ADDRSPACE (sym->type)) && (options.stackAuto || reentrant))
2181 werror (E_AUTO_ADDRSPACE, sym->name);
2182 if (IS_DECL (sym->type))
2183 DCL_PTR_ADDRSPACE (sym->type) = 0;
2184 else
2185 SPEC_ADDRSPACE (sym->type) = 0;
2188 /* arrays & pointers cannot be defined for bits */
2189 /* SBITS or SFRs or BIT */
2190 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
2191 (SPEC_NOUN (sym->etype) == V_BIT || SPEC_NOUN (sym->etype) == V_SBIT ||
2192 SPEC_NOUN (sym->etype) == V_BITFIELD || SPEC_NOUN (sym->etype) == V_BBITFIELD || SPEC_NOUN (sym->etype) == V_BITINTBITFIELD ||
2193 SPEC_SCLS (sym->etype) == S_SFR))
2195 /* find out if this is the return type of a function */
2196 t = sym->type;
2197 while (t && t->next != sym->etype)
2198 t = t->next;
2199 if (t->next != sym->etype || !IS_FUNC (t))
2201 werror (E_BIT_ARRAY, sym->name);
2205 /* if this is a bit|sbit then set length & start */
2206 if (SPEC_NOUN (sym->etype) == V_BIT || SPEC_NOUN (sym->etype) == V_SBIT)
2208 SPEC_BLEN (sym->etype) = 1;
2209 SPEC_BSTR (sym->etype) = 0;
2212 if (!isProto)
2214 /* variables declared in CODE space must have */
2215 /* initializers if not an extern, a global or a static */
2216 if (SPEC_SCLS (sym->etype) == S_CODE && sym->ival == NULL && !sym->_isparm &&
2217 IS_AUTO(sym) &&
2218 port->mem.code_ro && !SPEC_ABSA (sym->etype) && !funcInChain (sym->type))
2219 werror (E_CODE_NO_INIT, sym->name);
2222 /* if parameter or local variable then change */
2223 /* the storage class to reflect where the var will go */
2224 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED && !IS_STATIC (sym->etype))
2226 if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2228 SPEC_SCLS (sym->etype) = (options.useXstack ? S_XSTACK : S_STACK);
2233 /*------------------------------------------------------------------*/
2234 /* changePointer - change pointer to functions */
2235 /*------------------------------------------------------------------*/
2236 void
2237 changePointer (sym_link * p)
2239 /* go thru the chain of declarations */
2240 /* if we find a pointer to a function */
2241 /* change it to a ptr to code area */
2242 /* unless the function is banked. */
2243 for (; p; p = p->next)
2245 if (IS_DECL (p) && DCL_TYPE (p) == UPOINTER)
2246 DCL_TYPE (p) = port->unqualified_pointer;
2247 if (IS_PTR (p) && IS_FUNC (p->next))
2248 if (!IFFUNC_ISBANKEDCALL (p->next))
2249 DCL_TYPE (p) = CPOINTER;
2253 /*------------------------------------------------------------------*/
2254 /* checkDecl - does semantic validation of a declaration */
2255 /*------------------------------------------------------------------*/
2257 checkDecl (symbol * sym, int isProto)
2259 checkSClass (sym, isProto); /* check the storage class */
2260 changePointer (sym->type); /* change pointers if required */
2261 arraySizes (sym->type, sym->name);
2263 if (IS_ARRAY (sym->type) && DCL_ARRAY_VLA (sym->type) && sym->ival && !sym->ival->isempty)
2264 werror (E_VLA_INIT);
2265 /* if this is an array without any dimension
2266 then update the dimension from the initial value */
2267 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
2268 if (sym->ival && sym->ival->isempty)
2269 werror (E_EMPTY_INIT_UNKNOWN_SIZE);
2270 else
2271 return DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
2273 return 0;
2276 /*------------------------------------------------------------------*/
2277 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
2278 /*------------------------------------------------------------------*/
2279 sym_link *
2280 copyLinkChain (const sym_link *p)
2282 sym_link *head, *loop;
2283 const sym_link *curr;
2285 /* note: v_struct and v_struct->fields are not copied! */
2286 curr = p;
2287 head = loop = (curr ? newLink (p->xclass) : (void *) NULL);
2288 while (curr)
2290 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
2291 loop->next = (curr->next ? newLink (curr->next->xclass) : (void *) NULL);
2292 loop = loop->next;
2293 curr = curr->next;
2296 return head;
2299 /*------------------------------------------------------------------*/
2300 /* cleanUpBlock - cleansup the symbol table specified for all the */
2301 /* symbols in the given block */
2302 /*------------------------------------------------------------------*/
2303 void
2304 cleanUpBlock (bucket ** table, int block)
2306 int i;
2307 bucket *chain;
2309 /* go thru the entire table */
2310 for (i = 0; i < HASHTAB_SIZE; i++)
2312 for (chain = table[i]; chain; chain = chain->next)
2314 if (chain->block >= block)
2316 deleteSym (table, chain->sym, chain->name);
2322 /*------------------------------------------------------------------*/
2323 /* cleanUpLevel - cleans up the symbol table specified for all the */
2324 /* symbols in the given level */
2325 /*------------------------------------------------------------------*/
2326 void
2327 cleanUpLevel (bucket ** table, long level)
2329 int i;
2330 bucket *chain;
2332 /* go thru the entire table */
2333 for (i = 0; i < HASHTAB_SIZE; i++)
2335 for (chain = table[i]; chain; chain = chain->next)
2337 if (chain->level >= level)
2339 deleteSym (table, chain->sym, chain->name);
2345 /*------------------------------------------------------------------*/
2346 /* leaveBlockScope - mark items in SymbolTab from a particular */
2347 /* block as out-of-scope */
2348 /*------------------------------------------------------------------*/
2349 void
2350 leaveBlockScope (int block)
2352 int i;
2353 bucket *chain;
2355 /* go thru the entire table */
2356 for (i = 0; i < HASHTAB_SIZE; i++)
2358 for (chain = SymbolTab[i]; chain; chain = chain->next)
2360 if (chain->block == block)
2362 symbol *sym = (symbol *)chain->sym;
2364 /* Temporary fix for bug #3289 - leave enums in scope. */
2365 /* This is also buggy but compatible with 4.1.0 and */
2366 /* earlier behavior and less likely to trigger errors. */
2367 if (sym->etype && SPEC_ENUM(sym->etype))
2368 continue;
2369 /* Everything else, mark as out of scope. */
2370 sym->isinscope = 0;
2376 symbol *
2377 getAddrspace (sym_link *type)
2379 while(IS_ARRAY (type))
2380 type = type->next;
2382 if (IS_DECL (type))
2383 return (DCL_PTR_ADDRSPACE (type));
2384 return (SPEC_ADDRSPACE (type));
2387 /*------------------------------------------------------------------*/
2388 /* computeTypeOr - computes the resultant type from two types */
2389 /*------------------------------------------------------------------*/
2390 static sym_link *
2391 computeTypeOr (sym_link *etype1, sym_link *etype2, sym_link *reType)
2393 /* sanity check */
2394 wassert ((IS_CHAR (etype1) || IS_BOOLEAN (etype1)) &&
2395 (IS_CHAR (etype2) || IS_BOOLEAN (etype2)));
2397 if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
2399 SPEC_USIGN (reType) = SPEC_USIGN (etype1);
2400 return reType;
2403 if (SPEC_USIGN (etype1))
2405 if (IS_LITERAL (etype2) && floatFromVal (valFromType (etype2)) >= 0)
2406 SPEC_USIGN (reType) = 1;
2407 else
2409 /* promote to int */
2410 SPEC_USIGN (reType) = 0;
2411 SPEC_NOUN (reType) = V_INT;
2414 else /* etype1 signed */
2416 if (IS_LITERAL (etype2) && floatFromVal (valFromType (etype2)) <= 127)
2417 SPEC_USIGN (reType) = 0;
2418 else
2420 /* promote to int */
2421 SPEC_USIGN (reType) = 0;
2422 SPEC_NOUN (reType) = V_INT;
2426 if (SPEC_USIGN (etype2))
2428 if (IS_LITERAL (etype1) && floatFromVal (valFromType (etype1)) >= 0)
2429 SPEC_USIGN (reType) = 1;
2430 else
2432 /* promote to int */
2433 SPEC_USIGN (reType) = 0;
2434 SPEC_NOUN (reType) = V_INT;
2437 else /* etype2 signed */
2439 if (IS_LITERAL (etype1) && floatFromVal (valFromType (etype1)) <= 127)
2440 SPEC_USIGN (reType) = 0;
2441 else
2443 /* promote to int */
2444 SPEC_USIGN (reType) = 0;
2445 SPEC_NOUN (reType) = V_INT;
2448 return reType;
2451 /*------------------------------------------------------------------*/
2452 /* computeType - computes the resultant type from two types */
2453 /*------------------------------------------------------------------*/
2454 sym_link *
2455 computeType (sym_link * type1, sym_link * type2, RESULT_TYPE resultType, int op)
2457 sym_link *rType;
2458 sym_link *reType;
2459 sym_link *etype1 = getSpec (type1);
2460 sym_link *etype2;
2462 etype2 = type2 ? getSpec (type2) : type1;
2464 #if 0
2465 printf("computeType %d types ", op); printTypeChain (type1, stdout); printf (" vs. "); printTypeChain (type2, 0);
2466 #endif
2468 /* Conditional operator has some special type conversion rules */
2469 if (op == ':')
2471 /* Function types are really pointers to functions */
2472 if (IS_FUNC (type1))
2474 sym_link *fptr;
2475 fptr = newLink (DECLARATOR);
2476 DCL_TYPE (fptr) = CPOINTER;
2477 fptr->next = type1;
2478 type1 = fptr;
2480 if (IS_FUNC (type2))
2482 sym_link *fptr;
2483 fptr = newLink (DECLARATOR);
2484 DCL_TYPE (fptr) = CPOINTER;
2485 fptr->next = type2;
2486 type2 = fptr;
2488 /* If either type is an array, convert to pointer */
2489 if (IS_ARRAY(type1))
2491 value * val = aggregateToPointer (valFromType (type1));
2492 type1 = val->type;
2493 Safe_free (val);
2494 etype1 = getSpec (type1);
2496 if (IS_ARRAY(type2))
2498 value * val = aggregateToPointer (valFromType (type2));
2499 type2 = val->type;
2500 Safe_free (val);
2501 etype2 = getSpec (type2);
2504 /* If NULL and another pointer, use the non-NULL pointer type. */
2505 /* Note that NULL can be defined as either 0 or (void *)0. */
2506 if (IS_LITERAL (etype1) &&
2507 ((IS_PTR (type1) && IS_VOID (type1->next)) || IS_INTEGRAL (type1)) &&
2508 (floatFromVal (valFromType (etype1)) == 0) &&
2509 IS_PTR (type2))
2510 return copyLinkChain (type2);
2511 else if (IS_LITERAL (etype2) &&
2512 ((IS_PTR (type2) && IS_VOID (type2->next)) || IS_INTEGRAL (type2)) &&
2513 (floatFromVal (valFromType (etype2)) == 0) &&
2514 IS_PTR (type1))
2515 return copyLinkChain (type1);
2517 /* If a void pointer, use the void pointer type */
2518 else if (IS_PTR(type1) && IS_VOID(type1->next))
2519 return copyLinkChain (type1);
2520 else if (IS_PTR(type2) && IS_VOID(type2->next))
2521 return copyLinkChain (type2);
2523 /* Otherwise fall through to the general case */
2526 /* shift operators have the important type in the left operand */
2527 if (op == LEFT_OP || op == RIGHT_OP || op == ROT)
2528 rType = copyLinkChain(type1);
2529 /* If difference between pointers or arrays then the result is a ptrdiff */
2530 else if ((op == '-') && (IS_PTR (type1) || IS_ARRAY (type1)) && (IS_PTR (type2) || IS_ARRAY (type2)))
2531 rType = newPtrDiffLink();
2532 /* if one of them is a pointer or array then that prevails */
2533 else if (IS_PTR (type1) || IS_ARRAY (type1))
2534 rType = copyLinkChain (type1);
2535 else if (IS_PTR (type2) || IS_ARRAY (type2))
2536 rType = copyLinkChain (type2);
2538 /* if one of them is a float then result is a float */
2539 /* here we assume that the types passed are okay */
2540 /* and can be cast to one another */
2541 /* which ever is greater in size */
2542 else if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
2543 rType = newFloatLink ();
2544 /* if both are fixed16x16 then result is float */
2545 else if (IS_FIXED16X16 (etype1) && IS_FIXED16X16 (etype2))
2546 rType = newFixed16x16Link ();
2547 else if (IS_FIXED16X16 (etype1) && IS_FLOAT (etype2))
2548 rType = newFloatLink ();
2549 else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2))
2550 rType = newFloatLink ();
2552 /* if only one of them is a bool variable then the other one prevails */
2553 else if (IS_BOOLEAN (etype1) && !IS_BOOLEAN (etype2))
2555 rType = copyLinkChain (type2);
2557 else if (IS_BOOLEAN (etype2) && !IS_BOOLEAN (etype1))
2559 rType = copyLinkChain (type1);
2562 /* if both are bitvars choose the larger one */
2563 else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
2564 rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ? copyLinkChain (type1) : copyLinkChain (type2);
2566 /* otherwise if only one of them is a bit variable then the other one prevails
2567 exceptions for _BitInt apply */
2568 else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
2570 if (SPEC_NOUN (etype1) == V_BITINTBITFIELD && SPEC_BITINTWIDTH(etype1) > bitsForType (type2))
2572 rType = copyLinkChain (type1);
2574 else
2576 rType = copyLinkChain (type2);
2577 /* int bitfield can have up to 16 bits */
2578 if (getSize (etype1) > 1)
2579 SPEC_NOUN (getSpec (rType)) = V_INT;
2582 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
2584 if (SPEC_NOUN (etype2) == V_BITINTBITFIELD && SPEC_BITINTWIDTH(etype2) > bitsForType (type1))
2586 rType = copyLinkChain (type2);
2588 else
2590 rType = copyLinkChain (type1);
2591 /* int bitfield can have up to 16 bits */
2592 if (getSize (etype2) > 1)
2593 SPEC_NOUN (getSpec (rType)) = V_INT;
2596 else if (bitsForType (type1) > bitsForType (type2))
2597 rType = copyLinkChain (type1);
2598 else
2599 rType = copyLinkChain (type2);
2601 reType = getSpec (rType);
2603 /* avoid conflicting types */
2604 reType->select.s.b_signed = 0;
2606 /* if result is a literal then make not so */
2607 if (IS_LITERAL (reType))
2609 SPEC_SCLS (reType) = S_REGISTER;
2610 SPEC_CONST (reType) = 0;
2613 switch (resultType)
2615 case RESULT_TYPE_IFX:
2616 if (TARGET_HC08_LIKE)
2617 break;
2618 //fallthrough
2619 case RESULT_TYPE_BOOL:
2620 if (op == ':')
2622 SPEC_NOUN (reType) = TARGET_MCS51_LIKE ? V_BIT : V_BOOL;
2623 return rType;
2625 break;
2626 case RESULT_TYPE_CHAR:
2627 if (IS_BOOL (reType) || IS_BITVAR (reType))
2629 SPEC_NOUN (reType) = V_CHAR;
2630 SPEC_SCLS (reType) = 0;
2631 SPEC_USIGN (reType) = 0;
2632 return rType;
2634 break;
2635 case RESULT_TYPE_INT:
2636 case RESULT_TYPE_NONE:
2637 case RESULT_TYPE_OTHER:
2638 case RESULT_TYPE_GPTR:
2639 if (!IS_SPEC (rType))
2641 return rType;
2643 if (IS_BOOLEAN (reType))
2645 SPEC_NOUN (reType) = V_CHAR;
2646 SPEC_SCLS (reType) = 0;
2647 SPEC_USIGN (reType) = 0;
2648 return rType;
2650 else if (SPEC_NOUN (reType) == V_BITINTBITFIELD) // _BitInt(N) bit-field promotes to _BitInt(N).
2652 SPEC_NOUN (reType) = V_BITINT;
2654 else if (IS_BITFIELD (reType))
2656 /* could be smarter, but it depends on the op */
2657 /* this is for the worst case: a multiplication of 4 * 4 bit */
2658 SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
2659 SPEC_SCLS (reType) = 0;
2660 SPEC_USIGN (reType) = 0;
2661 return rType;
2663 else if (IS_CHAR (reType))
2665 /* promotion of some special cases */
2666 switch (op)
2668 case '|':
2669 case '^':
2670 case ':':
2671 if (!IS_BITFIELD (etype1) && !IS_BITFIELD (etype2))
2672 return computeTypeOr (etype1, etype2, reType);
2673 case '&':
2674 case BITWISEAND:
2675 if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
2677 SPEC_USIGN (reType) = 1;
2678 return rType;
2680 break;
2681 case '*':
2682 SPEC_NOUN (reType) = V_INT;
2683 SPEC_USIGN (reType) = 0;
2684 return rType;
2685 case '/':
2686 /* if both are unsigned char then no promotion required */
2687 if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
2689 SPEC_NOUN (reType) = V_INT;
2690 SPEC_USIGN (reType) = 0;
2691 return rType;
2693 break;
2694 default:
2695 break;
2698 break;
2699 default:
2700 break;
2703 /* SDCC's sign promotion:
2704 - if one or both operands are unsigned, the resultant type will be unsigned
2705 (except char, see below)
2706 - if an operand is promoted to a larger type (char -> int, int -> long),
2707 the larger type will be signed
2709 SDCC tries hard to avoid promotion to int and does 8 bit calculation as
2710 much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
2711 the standard. The standard demands, that the result has to be the same
2712 "as if" the promotion would have been performed:
2714 - if the result of an operation with two char's is promoted to a
2715 larger type, the result will be signed.
2717 More sophisticated are these:
2718 - if the result of an operation with two char's is a char again,
2719 the result will only then be unsigned, if both operands are
2720 unsigned. In all other cases the result will be signed.
2722 This seems to be contradictionary to the first two rules, but it makes
2723 real sense (all types are char's):
2725 A signed char can be negative; this must be preserved in the result
2726 -1 * 100 = -100;
2728 Only if both operands are unsigned it's safe to make the result
2729 unsigned; this helps to avoid overflow:
2730 2 * 100 = 200;
2732 - ToDo: document '|', '^' and '&'
2734 Homework: - why is (200 * 200 < 0) true?
2735 - why is { char l = 200, r = 200; (r * l > 0) } true?
2738 if (!IS_FLOAT (reType) && ((SPEC_USIGN (etype1)
2739 /* if this operand is promoted to a larger type,
2740 then it will be promoted to a signed type */
2741 && !(bitsForType (etype1) < bitsForType (reType))
2742 /* char require special handling */
2743 && !IS_CHAR (etype1)) || /* same for 2nd operand */
2744 (SPEC_USIGN (etype2) && !(bitsForType (etype2) < bitsForType (reType)) && !IS_CHAR (etype2)) || /* if both are 'unsigned char' and not promoted
2745 let the result be unsigned too */
2746 (SPEC_USIGN (etype1) && IS_CHAR (etype1)
2747 && (SPEC_USIGN (etype2) && IS_CHAR (etype2) || op == LEFT_OP || op == RIGHT_OP || op == ROT) && IS_CHAR (reType))) ||
2748 SPEC_USIGN (etype1) && SPEC_USIGN (etype2) && IS_BITINT (rType) || // unsigned _BitInt stays unsigned.
2749 SPEC_USIGN (etype1) && SPEC_USIGN (etype2) && bitsForType (etype1) <= bitsForType (reType) && bitsForType (etype2) < bitsForType (reType)) // keep operations on small unsigned bit-fields unsigned.
2750 SPEC_USIGN (reType) = 1;
2751 else
2752 SPEC_USIGN (reType) = 0;
2754 return rType;
2757 /*------------------------------------------------------------------*/
2758 /* compareFuncType - compare function prototypes */
2759 /*------------------------------------------------------------------*/
2761 compareFuncType (sym_link * dest, sym_link * src)
2763 value *exargs, *acargs;
2764 value *checkValue;
2765 int argCnt = 0;
2766 int i;
2768 /* if not type then some kind of error */
2769 if (!dest || !src)
2770 return 0;
2772 /* check the return value type */
2773 if (compareType (dest->next, src->next, false) <= 0)
2774 return 0;
2776 /* Really, reentrant should match regardless of argCnt, but */
2777 /* this breaks some existing code (the fp lib functions). If */
2778 /* the first argument is always passed the same way, this */
2779 /* lax checking is ok (but may not be true for in future ports) */
2780 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt > 1)
2782 //printf("argCnt = %d\n",argCnt);
2783 return 0;
2786 if (IFFUNC_ISBANKEDCALL (dest) != IFFUNC_ISBANKEDCALL (src))
2787 return 0;
2789 if (IFFUNC_ISWPARAM (dest) != IFFUNC_ISWPARAM (src))
2791 return 0;
2794 if (IFFUNC_ISSHADOWREGS (dest) != IFFUNC_ISSHADOWREGS (src))
2796 return 0;
2799 if (IFFUNC_ISZ88DK_FASTCALL (dest) != IFFUNC_ISZ88DK_FASTCALL (src) ||
2800 IFFUNC_ISZ88DK_CALLEE (dest) != IFFUNC_ISZ88DK_CALLEE (src))
2801 return 0;
2803 if (IFFUNC_ISRAISONANCE (dest) != IFFUNC_ISRAISONANCE (src) ||
2804 IFFUNC_ISCOSMIC (dest) != IFFUNC_ISCOSMIC (src) ||
2805 IFFUNC_ISIAR (dest) != IFFUNC_ISIAR (src))
2806 return 0;
2808 if (FUNC_SDCCCALL (dest) >= 0 && FUNC_SDCCCALL (src) >= 0 &&
2809 FUNC_SDCCCALL (dest) != FUNC_SDCCCALL (src))
2810 return 0;
2812 for (i = 0; i < 9; i++)
2813 if (dest->funcAttrs.preserved_regs[i] > src->funcAttrs.preserved_regs[i])
2814 return 0;
2816 /* compare register bank */
2817 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2818 { /* except for ISR's whose prototype need not match
2819 since they are the top of a call-tree and
2820 the prototype is only necessary for its vector in main */
2821 if (!IFFUNC_ISISR (dest) || !IFFUNC_ISISR (src))
2823 return 0;
2827 /* compare expected args with actual args */
2828 exargs = FUNC_ARGS (dest);
2829 acargs = FUNC_ARGS (src);
2831 /* for all the expected args do */
2832 for (argCnt = 1; exargs && acargs; exargs = exargs->next, acargs = acargs->next, argCnt++)
2834 /* If the actual argument is an array, any prototype
2835 * will have modified it to a pointer. Duplicate that
2836 * change here.
2838 if (IS_AGGREGATE (acargs->type))
2840 checkValue = copyValue (acargs);
2841 aggregateToPointer (checkValue);
2843 else
2845 checkValue = acargs;
2847 if (IFFUNC_ISREENT (dest) && compareType (exargs->type, checkValue->type, false) <= 0)
2849 return 0;
2851 if (!IFFUNC_ISREENT (dest) && compareTypeExact (exargs->type, checkValue->type, 1) <= 0)
2853 return 0;
2857 /* if one them ended we have a problem */
2858 if ((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type)))
2860 return 0;
2863 return 1;
2867 comparePtrType (sym_link *dest, sym_link *src, bool mustCast, bool ignoreimplicitintrinsic)
2869 int res;
2871 #if 0
2872 printf("comparePtrType (must cast %d): ", mustCast); printTypeChain (dest, stdout); printf(" vs. "); printTypeChain (src, 0);
2873 #endif
2875 if (getAddrspace (src->next) != getAddrspace (dest->next))
2876 mustCast = 1;
2878 if (IS_VOID (src->next) && IS_VOID (dest->next))
2879 return mustCast ? -1 : 1;
2880 if ((IS_VOID (src->next) && !IS_VOID (dest->next)) || (!IS_VOID (src->next) && IS_VOID (dest->next)))
2881 return -1;
2882 if (IS_STRUCT (src->next) && IS_STRUCT (dest->next) && SPEC_STRUCT (src->next) == SPEC_STRUCT (dest->next))
2883 return mustCast ? -1 : 1;
2884 res = compareType (dest->next, src->next, ignoreimplicitintrinsic);
2886 /* All function pointers can be cast (6.3.2.3 in the ISO C23 standard), similar for objects. TODO: What about address spaces? */
2887 if (res == 0 && !mustCast && IS_DECL (src) && IS_DECL (dest) && (IS_FUNC (src->next) == IS_FUNC (dest->next)))
2888 return -1;
2889 else if (res == 1)
2890 return mustCast ? -1 : 1;
2891 else if (res == -2)
2892 return mustCast ? -1 : -2;
2893 else
2894 return res;
2897 /*--------------------------------------------------------------------*/
2898 /* compareType - will do type check return 1 if match, 0 if no match, */
2899 /* -1 if castable, -2 if only signedness differs */
2900 /* ignoreimplicitintrinsic - ignore implicitly assigned intrinsic named address spaces */
2901 /*--------------------------------------------------------------------*/
2903 compareType (sym_link *dest, sym_link *src, bool ignoreimplicitintrinsic)
2905 if (!dest && !src)
2906 return 1;
2908 if (dest && !src)
2909 return 0;
2911 if (src && !dest)
2912 return 0;
2914 #if 0
2915 printf("compareType: "); printTypeChain (dest, stdout); printf(" vs. "); printTypeChain (src, 0);
2916 #endif
2918 /* if dest is a declarator then */
2919 if (IS_DECL (dest))
2921 if (IS_DECL (src))
2923 // UPOINTER results in false negatives if it reaches here.
2924 wassertl (!IS_PTR (dest) || dest->select.d.dcl_type != UPOINTER, "UPOINTER is only for use during parsing");
2926 if (IS_GENPTR (dest) && IS_GENPTR (src))
2928 /* banked function pointer */
2929 if (IS_FUNC (src->next) && IS_VOID (dest->next))
2930 return -1;
2931 if (IS_FUNC (dest->next) && IS_VOID (src->next))
2932 return -1;
2933 return comparePtrType (dest, src, false, ignoreimplicitintrinsic);
2936 if (DCL_TYPE (src) == DCL_TYPE (dest) ||
2937 (IS_PTR (src) && ignoreimplicitintrinsic && DCL_TYPE_IMPLICITINTRINSIC (src) || IS_GENPTR (src)) &&
2938 (IS_PTR (dest) && ignoreimplicitintrinsic && DCL_TYPE_IMPLICITINTRINSIC (dest) || IS_GENPTR (dest)))
2940 if (IS_FUNC (src))
2942 return compareFuncType (dest, src);
2944 return comparePtrType (dest, src, false, ignoreimplicitintrinsic);
2946 if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID (src->next))
2948 return -1;
2950 if (IS_PTR (src) && (IS_GENPTR (dest) || ((DCL_TYPE (src) == POINTER) && (DCL_TYPE (dest) == IPOINTER))))
2952 return comparePtrType (dest, src, true, ignoreimplicitintrinsic);
2954 if (IS_PTR (dest) && IS_ARRAY (src))
2956 value *val = aggregateToPointer (valFromType (src));
2957 int res = compareType (dest, val->type, ignoreimplicitintrinsic);
2958 Safe_free (val->type);
2959 Safe_free (val);
2960 return res;
2962 if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2964 return compareType (dest->next, src, ignoreimplicitintrinsic);
2966 if (IS_PTR (dest) && IS_VOID (dest->next) && IS_FUNC (src))
2967 return -1;
2969 return 0;
2971 else if (IS_PTR (dest) && (IS_INTEGRAL (src) || IS_NULLPTR (src)))
2972 return -1;
2973 else
2974 return 0;
2977 if (IS_PTR (src) && (IS_INTEGRAL (dest) || IS_VOID (dest)))
2978 return -1;
2980 if (IS_NULLPTR (src) && IS_BOOL (dest))
2981 return -1;
2983 /* if one is a specifier and the other is not */
2984 if ((IS_SPEC (src) && !IS_SPEC (dest)) || (IS_SPEC (dest) && !IS_SPEC (src)))
2985 return 0;
2987 /* if one of them is a void then ok */
2988 if (SPEC_NOUN (dest) == V_VOID && SPEC_NOUN (src) != V_VOID)
2989 return -1;
2991 if (SPEC_NOUN (dest) != V_VOID && SPEC_NOUN (src) == V_VOID)
2992 return -1;
2994 if (SPEC_NOUN (src) == V_BBITFIELD && SPEC_NOUN (dest) != V_BBITFIELD || SPEC_NOUN (src) != V_BBITFIELD && SPEC_NOUN (dest) == V_BBITFIELD)
2995 return -1;
2997 /* if they are both bitfields then if the lengths
2998 and starts don't match */
2999 if (IS_BITFIELD (dest) && IS_BITFIELD (src) && (SPEC_BLEN (dest) != SPEC_BLEN (src) || SPEC_BSTR (dest) != SPEC_BSTR (src)))
3000 return -1;
3002 if ((SPEC_NOUN (dest) == V_BITINT || SPEC_NOUN (dest) == V_BITINTBITFIELD) && (SPEC_NOUN (src) == V_BITINT || SPEC_NOUN (src) == V_BITINTBITFIELD))
3004 if (SPEC_BITINTWIDTH (dest) != SPEC_BITINTWIDTH (src) ||
3005 SPEC_USIGN (dest) && !SPEC_USIGN (src) && SPEC_BITINTWIDTH (dest) % 8) // Cast from sgined to unsigned type cannot be omitted, since it requires masking top bits.
3006 return -1;
3007 return (SPEC_USIGN (dest) == SPEC_USIGN (src) ? 1 : -2);
3009 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src) &&
3010 ((SPEC_NOUN (dest) == V_BITINT) ^ (SPEC_NOUN (src) == V_BITINT)))
3011 return -1;
3013 /* it is a specifier */
3014 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
3016 if ((SPEC_USIGN (dest) == SPEC_USIGN (src)) &&
3017 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
3018 /* I would prefer
3019 bitsForType (dest) == bitsForType (src))
3020 instead of the next two lines, but the regression tests fail with
3021 them; I guess it's a problem with replaceCheaperOp */
3022 (getSize (dest) == getSize (src)) &&
3023 (IS_BOOLEAN (dest) == IS_BOOLEAN (src)))
3024 return 1;
3025 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
3026 return -1;
3027 else
3028 return 0;
3030 else if (IS_STRUCT (dest))
3032 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
3033 return 0;
3035 structdef *destsdef = SPEC_STRUCT (dest);
3036 structdef *srcsdef = SPEC_STRUCT (src);
3038 for (symbol *dstfieldsym = destsdef->fields, *srcfieldsym = srcsdef->fields; srcfieldsym || dstfieldsym; dstfieldsym = dstfieldsym->next, srcfieldsym = srcfieldsym->next)
3040 if (!srcfieldsym || !dstfieldsym)
3041 return 0;
3042 if (compareType (srcfieldsym->type, dstfieldsym->type, ignoreimplicitintrinsic) <= 0)
3043 return 0;
3046 return 1;
3049 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
3050 return -1;
3052 if (SPEC_LONG (dest) != SPEC_LONG (src))
3053 return -1;
3055 if (SPEC_LONGLONG (dest) != SPEC_LONGLONG (src))
3056 return -1;
3058 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
3059 return -2;
3061 return 1;
3064 /*--------------------------------------------------------------------*/
3065 /* compareTypeExact - will do type check return 1 if match exactly */
3066 /*--------------------------------------------------------------------*/
3068 compareTypeExact (sym_link * dest, sym_link * src, long level)
3070 STORAGE_CLASS srcScls, destScls;
3072 if (!dest && !src)
3073 return 1;
3075 if (dest && !src)
3076 return 0;
3078 if (src && !dest)
3079 return 0;
3081 /* if dest is a declarator then */
3082 if (IS_DECL (dest))
3084 if (IS_DECL (src))
3086 if (DCL_TYPE (src) == DCL_TYPE (dest))
3088 if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
3089 return 0;
3090 if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
3091 return 0;
3092 if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
3093 return 0;
3094 if (IS_FUNC (src))
3096 value *exargs, *acargs, *checkValue;
3098 /* verify function return type */
3099 if (!compareTypeExact (dest->next, src->next, -1))
3100 return 0;
3101 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
3102 return 0;
3103 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
3104 return 0;
3105 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
3106 return 0;
3107 if (IFFUNC_ISBANKEDCALL (dest) != IFFUNC_ISBANKEDCALL (src))
3108 return 0;
3109 if (IFFUNC_ISZ88DK_FASTCALL (dest) != IFFUNC_ISZ88DK_FASTCALL (src))
3110 return 0;
3111 if (IFFUNC_ISRAISONANCE (dest) != IFFUNC_ISRAISONANCE (src))
3112 return 0;
3113 if (IFFUNC_ISCOSMIC (dest) != IFFUNC_ISCOSMIC (src))
3114 return 0;
3115 if (IFFUNC_ISIAR (dest) != IFFUNC_ISIAR (src))
3116 return 0;
3117 if (FUNC_SDCCCALL (dest) >= 0 && FUNC_SDCCCALL (src) >= 0 &&
3118 FUNC_SDCCCALL (dest) != FUNC_SDCCCALL (src))
3119 return 0;
3121 #if 0
3122 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt > 1)
3123 return 0;
3124 #endif
3126 /* compare expected args with actual args */
3127 exargs = FUNC_ARGS (dest);
3128 acargs = FUNC_ARGS (src);
3130 /* for all the expected args do */
3131 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
3133 //checkTypeSanity(acargs->etype, acargs->name);
3135 if (IS_AGGREGATE (acargs->type))
3137 checkValue = copyValue (acargs);
3138 aggregateToPointer (checkValue);
3140 else
3141 checkValue = acargs;
3143 #if 0
3144 if (!compareTypeExact (exargs->type, checkValue->type, -1))
3145 return 0;
3146 #endif
3149 /* if one them ended we have a problem */
3150 if ((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type)))
3151 return 0;
3152 return 1;
3154 return compareTypeExact (dest->next, src->next, level);
3156 return 0;
3158 return 0;
3161 /* if one is a specifier and the other is not */
3162 if ((IS_SPEC (src) && !IS_SPEC (dest)) || (IS_SPEC (dest) && !IS_SPEC (src)))
3163 return 0;
3165 /* if they have a different noun */
3166 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
3167 return 0;
3168 /* if they are both bitfields then if the lengths
3169 and starts don't match */
3170 if (IS_BITFIELD (dest) && IS_BITFIELD (src) && (SPEC_BLEN (dest) != SPEC_BLEN (src) || SPEC_BSTR (dest) != SPEC_BSTR (src)))
3171 return 0;
3173 if (IS_INTEGRAL (dest))
3175 /* signedness must match */
3176 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
3177 return 0;
3178 /* size must match */
3179 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
3180 return 0;
3181 if (SPEC_LONG (dest) != SPEC_LONG (src))
3182 return 0;
3183 if (SPEC_LONGLONG (dest) != SPEC_LONGLONG (src))
3184 return 0;
3185 // width must be the same for bit-precise types
3186 if (SPEC_NOUN (dest) == V_BITINT && SPEC_BITINTWIDTH (dest) != SPEC_BITINTWIDTH (src))
3187 return 0;
3190 if (IS_STRUCT (dest))
3192 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
3193 return 0;
3196 if (SPEC_CONST (dest) != SPEC_CONST (src))
3197 return 0;
3198 if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
3199 return 0;
3200 if (SPEC_STAT (dest) != SPEC_STAT (src))
3201 return 0;
3202 if (SPEC_ABSA (dest) != SPEC_ABSA (src))
3203 return 0;
3204 if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
3205 return 0;
3207 destScls = SPEC_SCLS (dest);
3208 srcScls = SPEC_SCLS (src);
3210 /* Compensate for const to const code change in checkSClass() */
3211 if (((!level) & port->mem.code_ro) && SPEC_CONST (dest))
3213 if (srcScls == S_CODE && destScls == S_FIXED)
3214 destScls = S_CODE;
3215 if (destScls == S_CODE && srcScls == S_FIXED)
3216 srcScls = S_CODE;
3219 /* compensate for allocGlobal() */
3220 if ((srcScls == S_FIXED || srcScls == S_AUTO) &&
3221 (port->mem.default_globl_map == xdata) && (destScls == S_XDATA) && (level <= 0))
3223 srcScls = S_XDATA;
3226 if ((level > 0) && !SPEC_STAT (dest))
3228 /* Compensate for hack-o-matic in checkSClass() */
3229 if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
3231 if (destScls == S_FIXED)
3232 destScls = (options.useXstack ? S_XSTACK : S_STACK);
3233 if (srcScls == S_FIXED)
3234 srcScls = (options.useXstack ? S_XSTACK : S_STACK);
3236 else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack || TARGET_IS_HC08 || TARGET_IS_S08)
3238 if (destScls == S_FIXED)
3239 destScls = S_XDATA;
3240 if (srcScls == S_FIXED)
3241 srcScls = S_XDATA;
3245 if (srcScls != destScls)
3247 #if 0
3248 printf ("level = %ld:%ld\n", level / LEVEL_UNIT, level % LEVEL_UNIT);
3249 printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n", SPEC_SCLS (src), SPEC_SCLS (dest));
3250 printf ("srcScls = %d, destScls = %d\n", srcScls, destScls);
3251 #endif
3252 return 0;
3255 return 1;
3258 /*---------------------------------------------------------------------------*/
3259 /* compareTypeInexact - will do type check return 1 if representation is same. */
3260 /* Useful for redundancy elimination. */
3261 /*---------------------------------------------------------------------------*/
3263 compareTypeInexact (sym_link *dest, sym_link *src)
3265 if (!dest && !src)
3266 return 1;
3268 if (dest && !src)
3269 return 0;
3271 if (src && !dest)
3272 return 0;
3274 if (IS_BITFIELD (dest) != IS_BITFIELD (src))
3275 return 0;
3277 if (IS_BITFIELD (dest) && IS_BITFIELD (src) && (SPEC_BLEN (dest) != SPEC_BLEN (src) || SPEC_BSTR (dest) != SPEC_BSTR (src)))
3278 return 0;
3280 if (getSize (dest) != getSize (src))
3281 return 0;
3283 return 1;
3286 /*------------------------------------------------------------------*/
3287 /* inCalleeSaveList - return 1 if found in callee save list */
3288 /*------------------------------------------------------------------*/
3289 static int
3290 calleeCmp (void *p1, void *p2)
3292 return (strcmp ((char *) p1, (char *) (p2)) == 0);
3295 bool
3296 inCalleeSaveList (char *s)
3298 if (options.all_callee_saves)
3299 return 1;
3300 return isinSetWith (options.calleeSavesSet, s, calleeCmp);
3303 /*-----------------------------------------------------------------*/
3304 /* aggregateToPointer: change an aggregate type function */
3305 /* argument to a pointer to that type. */
3306 /*-----------------------------------------------------------------*/
3307 value *
3308 aggregateToPointer (value *val)
3310 if (IS_ARRAY (val->type))
3312 /* change to a pointer depending on the */
3313 /* storage class specified */
3314 switch (SPEC_SCLS (val->etype))
3316 case S_IDATA:
3317 DCL_TYPE (val->type) = IPOINTER;
3318 break;
3319 case S_PDATA:
3320 DCL_TYPE (val->type) = PPOINTER;
3321 break;
3322 case S_FIXED:
3323 if (SPEC_OCLS (val->etype))
3325 DCL_TYPE (val->type) = PTR_TYPE (SPEC_OCLS (val->etype));
3327 else
3328 { // this happens for (external) function parameters
3329 DCL_TYPE (val->type) = port->unqualified_pointer;
3331 break;
3332 case S_AUTO:
3333 DCL_TYPE (val->type) = PTR_TYPE (SPEC_OCLS (val->etype));
3334 break;
3335 case S_DATA:
3336 case S_REGISTER:
3337 DCL_TYPE (val->type) = POINTER;
3338 break;
3339 case S_CODE:
3340 DCL_TYPE (val->type) = CPOINTER;
3341 break;
3342 case S_XDATA:
3343 DCL_TYPE (val->type) = FPOINTER;
3344 break;
3345 case S_EEPROM:
3346 DCL_TYPE (val->type) = EEPPOINTER;
3347 break;
3348 default:
3349 DCL_TYPE (val->type) = port->unqualified_pointer;
3351 DCL_TYPE_IMPLICITINTRINSIC (val->type) = SPEC_SCLS_IMPLICITINTRINSIC (val->etype);
3353 /* is there is a symbol associated then */
3354 /* change the type of the symbol as well */
3355 if (val->sym)
3357 val->sym->type = copyLinkChain (val->type);
3358 val->sym->etype = getSpec (val->sym->type);
3361 return val;
3364 /*------------------------------------------------------------------*/
3365 /* checkFunction - does all kinds of check on a function */
3366 /*------------------------------------------------------------------*/
3368 checkFunction (symbol * sym, symbol * csym)
3370 value *exargs, *acargs;
3371 value *checkValue;
3372 int argCnt = 0;
3374 if (getenv ("DEBUG_SANITY"))
3376 fprintf (stderr, "checkFunction: %s ", sym->name);
3379 if (!IS_FUNC (sym->type))
3381 werrorfl (sym->fileDef, sym->lineDef, E_SYNTAX_ERROR, sym->name);
3382 return 0;
3385 /* move function specifier from return type to function attributes */
3386 if (IS_INLINE (sym->etype))
3388 SPEC_INLINE (sym->etype) = 0;
3389 FUNC_ISINLINE (sym->type) = 1;
3391 if (IS_NORETURN (sym->etype))
3393 SPEC_NORETURN (sym->etype) = 0;
3394 FUNC_ISNORETURN (sym->type) = 1;
3397 /* If no ABI version specified, use port default */
3398 if (FUNC_SDCCCALL (sym->type) < 0)
3399 FUNC_SDCCCALL (sym->type) = options.sdcccall;
3401 /* make sure the type is complete and sane */
3402 checkTypeSanity (sym->etype, sym->name);
3404 /* if not type then some kind of error */
3405 if (!sym->type)
3406 return 0;
3408 /* if the function has no type then make it return int */
3409 if (!sym->type->next)
3410 sym->type->next = sym->etype = newIntLink ();
3412 /* function cannot return aggregate */
3413 if ((TARGET_IS_DS390) && IS_AGGREGATE (sym->type->next))
3415 werrorfl (sym->fileDef, sym->lineDef, E_FUNC_AGGR, sym->name);
3416 return 0;
3419 /* check if this function is defined as calleeSaves
3420 then mark it as such */
3421 FUNC_CALLEESAVES (sym->type) = inCalleeSaveList (sym->name);
3423 /* if interrupt service routine */
3424 /* then it cannot have arguments */
3425 if (IFFUNC_ARGS (sym->type) && FUNC_ISISR (sym->type))
3427 if (!IS_VOID (FUNC_ARGS (sym->type)->type))
3429 werrorfl (sym->fileDef, sym->lineDef, E_INT_ARGS, sym->name);
3430 FUNC_ARGS (sym->type) = NULL;
3434 if (IFFUNC_ISSHADOWREGS (sym->type) && !FUNC_ISISR (sym->type))
3436 werrorfl (sym->fileDef, sym->lineDef, E_SHADOWREGS_NO_ISR, sym->name);
3439 for (argCnt = 1, acargs = FUNC_ARGS (sym->type); acargs; acargs = acargs->next, argCnt++)
3441 if (!acargs->sym)
3443 // this can happen for reentrant functions
3444 werrorfl (sym->fileDef, sym->lineDef, E_PARAM_NAME_OMITTED, sym->name, argCnt);
3445 // the show must go on: synthesize a name and symbol
3446 SNPRINTF (acargs->name, sizeof (acargs->name), "_%s_PARM_%d", sym->name, argCnt);
3447 acargs->sym = newSymbol (acargs->name, 1);
3448 SPEC_OCLS (acargs->etype) = istack;
3449 acargs->sym->type = copyLinkChain (acargs->type);
3450 acargs->sym->etype = getSpec (acargs->sym->type);
3451 acargs->sym->_isparm = 1;
3452 strncpyz (acargs->sym->rname, acargs->name, sizeof (acargs->sym->rname));
3454 else if (strcmp (acargs->sym->name, acargs->sym->rname) == 0)
3456 // synthesized name
3457 werrorfl (sym->fileDef, sym->lineDef, E_PARAM_NAME_OMITTED, sym->name, argCnt);
3460 argCnt--;
3462 /*JCF: Mark the register bank as used */
3463 RegBankUsed[FUNC_REGBANK (sym->type)] = 1;
3465 if (!csym && !(csym = findSymWithLevel (SymbolTab, sym)))
3466 return 1; /* not defined nothing more to check */
3468 /* check if body already present */
3469 if (csym && IFFUNC_HASBODY (csym->type))
3471 werrorfl (sym->fileDef, sym->lineDef, E_FUNC_BODY, sym->name);
3472 return 0;
3475 /* check the return value type */
3476 if (FUNC_NOPROTOTYPE (csym->type))
3478 if (compareType (csym->type->next, sym->type->next, false) <= 0)
3480 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "return type", csym->fileDef, csym->lineDef);
3481 printFromToType (csym->type->next, sym->type->next);
3482 return 0;
3485 else if (compareType (csym->type, sym->type, false) <= 0)
3487 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "type", csym->fileDef, csym->lineDef);
3488 printFromToType (csym->type, sym->type);
3489 return 0;
3492 if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
3493 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "interrupt", csym->fileDef, csym->lineDef);
3495 /* I don't think this is necessary for interrupts. An isr is a */
3496 /* root in the calling tree. */
3497 if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) && (!FUNC_ISISR (sym->type)))
3498 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "using", csym->fileDef, csym->lineDef);
3500 if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
3502 // disabled since __naked has no influence on the calling convention
3503 // werror (E_PREV_DECL_CONFLICT, csym->name, "__naked", csym->fileDef, csym->lineDef);
3504 FUNC_ISNAKED (sym->type) = 1;
3507 if (FUNC_BANKED (csym->type) || FUNC_BANKED (sym->type))
3509 if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
3511 werrorfl (sym->fileDef, sym->lineDef, W_BANKED_WITH_NONBANKED);
3512 FUNC_BANKED (sym->type) = 0;
3513 FUNC_NONBANKED (sym->type) = 1;
3515 else
3517 FUNC_BANKED (sym->type) = 1;
3520 else
3522 if (FUNC_NONBANKED (csym->type) || FUNC_NONBANKED (sym->type))
3524 FUNC_NONBANKED (sym->type) = 1;
3528 /* Really, reentrant should match regardless of argCnt, but */
3529 /* this breaks some existing code (the fp lib functions). If */
3530 /* the first argument is always passed the same way, this */
3531 /* lax checking is ok (but may not be true for in future backends) */
3532 if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type) && argCnt > 1)
3534 //printf("argCnt = %d\n",argCnt);
3535 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "reentrant", csym->fileDef, csym->lineDef);
3538 if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
3539 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "wparam", csym->fileDef, csym->lineDef);
3541 if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
3542 werrorfl (sym->fileDef, sym->lineDef, E_PREV_DECL_CONFLICT, csym->name, "shadowregs", csym->fileDef, csym->lineDef);
3544 /* compare expected args with actual args */
3545 exargs = FUNC_ARGS (csym->type);
3546 acargs = FUNC_ARGS (sym->type);
3548 /* for all the expected args do */
3549 for (argCnt = 1; exargs && acargs; exargs = exargs->next, acargs = acargs->next, argCnt++)
3551 if (getenv ("DEBUG_SANITY"))
3553 fprintf (stderr, "checkFunction: %s ", exargs->name);
3555 /* make sure the type is complete and sane */
3556 checkTypeSanity (exargs->etype, exargs->name);
3558 /* If the actual argument is an array, any prototype
3559 * will have modified it to a pointer. Duplicate that
3560 * change here.
3562 if (IS_AGGREGATE (acargs->type))
3564 checkValue = copyValue (acargs);
3565 aggregateToPointer (checkValue);
3567 else
3569 checkValue = acargs;
3572 if (compareType (exargs->type, checkValue->type, false) <= 0)
3574 werror (E_ARG_TYPE, argCnt);
3575 printFromToType (exargs->type, checkValue->type);
3576 return 0;
3580 /* if one of them ended we have a problem */
3581 if (((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type))) && !FUNC_NOPROTOTYPE (csym->type))
3582 werror (E_ARG_COUNT);
3584 /* replace with this definition */
3585 sym->cdef = csym->cdef;
3586 deleteSym (SymbolTab, csym, csym->name);
3587 deleteFromSeg (csym);
3588 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
3589 if (IS_EXTERN (csym->etype) && !IS_EXTERN (sym->etype))
3591 SPEC_EXTR (sym->etype) = 1;
3592 addSet (&publics, sym);
3595 SPEC_STAT (sym->etype) |= SPEC_STAT (csym->etype);
3596 if (SPEC_STAT (sym->etype) && SPEC_EXTR (sym->etype))
3598 werrorfl (sym->fileDef, sym->lineDef, E_TWO_OR_MORE_STORAGE_CLASSES, sym->name);
3601 return 1;
3604 /*------------------------------------------------------------------*/
3605 /* cdbStructBlock - calls struct printing for a blocks */
3606 /*------------------------------------------------------------------*/
3607 void
3608 cdbStructBlock (int block)
3610 int i;
3611 bucket **table = StructTab;
3612 bucket *chain;
3614 /* go thru the entire table */
3615 for (i = 0; i < HASHTAB_SIZE; i++)
3617 for (chain = table[i]; chain; chain = chain->next)
3619 if (chain->block >= block)
3621 if (debugFile)
3622 debugFile->writeType ((structdef *) chain->sym, chain->block, 0, NULL);
3628 /*-----------------------------------------------------------------*/
3629 /* processFuncPtrArgs - does some processing with args of func ptrs*/
3630 /*-----------------------------------------------------------------*/
3631 void
3632 processFuncPtrArgs (sym_link * funcType)
3634 processFuncArgs (NULL, funcType);
3637 /*-----------------------------------------------------------------*/
3638 /* processFuncArgs - does some processing with function args */
3639 /* */
3640 /* Leave func NULL if processing a type rather than a symbol */
3641 /*-----------------------------------------------------------------*/
3642 void
3643 processFuncArgs (symbol *func, sym_link *funcType)
3645 value *val;
3646 int pNum = 1;
3647 char *funcName = NULL;
3648 int funcCdef = 0;
3650 if (func && !funcType)
3651 funcType = func->type;
3652 if (func)
3654 funcCdef = func->cdef;
3655 funcName = func->name;
3657 else
3659 funcCdef = 0;
3660 funcName = "unnamed function type";
3663 if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
3664 fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", funcName);
3666 /* find the function declaration within the type */
3667 while (funcType && !IS_FUNC (funcType))
3668 funcType = funcType->next;
3670 /* Nothing to do if no function type found */
3671 if (!funcType)
3672 return;
3674 /* if this function has variable argument list */
3675 /* then make the function a reentrant one */
3676 if (IFFUNC_HASVARARGS (funcType) || (options.stackAuto && !funcCdef))
3677 FUNC_ISREENT (funcType) = 1;
3679 /* check if this function is defined as calleeSaves
3680 then mark it as such */
3681 FUNC_CALLEESAVES (funcType) = inCalleeSaveList (funcName);
3683 /* If no ABI version specified, use port default */
3684 if (FUNC_SDCCCALL (funcType) < 0)
3685 FUNC_SDCCCALL (funcType) = options.sdcccall;
3687 /* loop thru all the arguments */
3688 val = FUNC_ARGS (funcType);
3690 /* if it is void then remove parameters */
3691 if (val && IS_VOID (val->type))
3693 FUNC_ARGS (funcType) = NULL;
3694 return;
3697 /* reset regparm for the port */
3698 (*port->reset_regparms) (funcType);
3700 /* if any of the arguments is an aggregate */
3701 /* change it to pointer to the same type */
3702 for (; val; val=val->next, pNum++)
3704 int argreg = 0;
3705 struct dbuf_s dbuf;
3707 if (val->sym)
3708 for (value *val2 = val->next; val2; val2 = val2->next)
3709 if (val2->sym && !strcmp (val->sym->name, val2->sym->name))
3710 werror (E_DUPLICATE_PARAMTER_NAME, val->sym->name, funcName);
3712 dbuf_init (&dbuf, 128);
3713 dbuf_printf (&dbuf, "%s parameter %d", funcName, pNum);
3714 checkTypeSanity (val->etype, dbuf_c_str (&dbuf));
3715 dbuf_destroy (&dbuf);
3717 if (IS_AGGREGATE (val->type))
3719 aggregateToPointer (val);
3722 /* mark it as a register parameter if
3723 the function does not have VA_ARG
3724 and as port dictates */
3725 if (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT (funcType)))
3727 SPEC_REGPARM (val->etype) = 1;
3728 SPEC_ARGREG (val->etype) = argreg;
3730 /* is there is a symbol associated then */
3731 /* change the type of the symbol as well */
3732 if (val->sym)
3734 SPEC_REGPARM (val->sym->etype) = 1;
3735 SPEC_ARGREG (val->sym->etype) = argreg;
3738 else if (IFFUNC_ISREENT (funcType))
3740 FUNC_HASSTACKPARM (funcType) = 1;
3743 /* if this is an internal generated function call */
3744 if (funcCdef)
3746 /* ignore --stack-auto for this one, we don't know how it is compiled */
3747 /* simply trust on --int-long-reent or --float-reent */
3748 if (IFFUNC_ISREENT (funcType))
3749 continue;
3751 else
3753 /* if this function is reentrant or */
3754 /* automatics r 2b stacked then nothing */
3755 if (IFFUNC_ISREENT (funcType) || options.stackAuto)
3756 continue;
3759 /* Don't create parameter symbols without a function symbol */
3760 if (!func)
3761 continue;
3763 /* if a symbolname is not given */
3764 /* synthesize a variable name */
3765 if (!val->sym)
3767 SNPRINTF (val->name, sizeof (val->name), "_%s_PARM_%d", func->name, pNum);
3768 val->sym = newSymbol (val->name, 1);
3769 val->sym->type = copyLinkChain (val->type);
3770 val->sym->etype = getSpec (val->sym->type);
3771 val->sym->_isparm = 1;
3772 if (!defaultOClass (val->sym))
3773 SPEC_OCLS (val->sym->etype) = port->mem.default_local_map;
3774 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype);
3775 strncpyz (val->sym->rname, val->name, sizeof (val->sym->rname));
3776 addSymChain (&val->sym);
3778 else /* symbol name given create synth name */
3780 SNPRINTF (val->name, sizeof (val->name), "_%s_PARM_%d", func->name, pNum);
3781 strncpyz (val->sym->rname, val->name, sizeof (val->sym->rname));
3782 val->sym->_isparm = 1;
3783 if (!defaultOClass (val->sym))
3784 SPEC_OCLS (val->sym->etype) = port->mem.default_local_map;
3785 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype);
3787 if (SPEC_OCLS (val->sym->etype) == pdata)
3788 val->sym->iaccess = 1;
3789 if (!isinSet (operKeyReset, val->sym))
3791 addSet (&operKeyReset, val->sym);
3792 applyToSet (operKeyReset, resetParmKey);
3797 /*-----------------------------------------------------------------*/
3798 /* isSymbolEqual - compares two symbols return 1 if they match */
3799 /*-----------------------------------------------------------------*/
3801 isSymbolEqual (const symbol * dest, const symbol * src)
3803 /* if pointers match then equal */
3804 if (dest == src)
3805 return 1;
3807 /* if one of them is null then don't match */
3808 if (!dest || !src)
3809 return 0;
3811 /* if both of them have rname match on rname */
3812 if (dest->rname[0] && src->rname[0])
3813 return (!strcmp (dest->rname, src->rname));
3815 /* otherwise match on name */
3816 return (!strcmp (dest->name, src->name));
3819 void
3820 PT (sym_link * type)
3822 printTypeChain (type, 0);
3825 /*-----------------------------------------------------------------*/
3826 /* printTypeChain - prints the type chain in human readable form */
3827 /*-----------------------------------------------------------------*/
3828 void
3829 printTypeChain (sym_link * start, FILE * of)
3831 struct dbuf_s dbuf;
3832 int nlr = 0;
3834 if (!of)
3836 of = stdout;
3837 nlr = 1;
3840 dbuf_init (&dbuf, 1024);
3841 dbuf_printTypeChain (start, &dbuf);
3842 dbuf_write_and_destroy (&dbuf, of);
3844 if (nlr)
3845 putc ('\n', of);
3848 void
3849 dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
3851 value *args;
3852 sym_link *type, *search;
3853 STORAGE_CLASS scls;
3854 static struct dbuf_s dbuf2;
3856 if (start == NULL)
3858 dbuf_append_str (dbuf, "void");
3859 return;
3862 /* Print the chain as it is written in the source: */
3863 /* start with the last entry. */
3864 /* However, the storage class at the end of the */
3865 /* chain really applies to the first in the chain! */
3867 for (type = start; type && type->next; type = type->next)
3869 if (IS_SPEC (type))
3870 scls = SPEC_SCLS (type);
3871 else
3872 scls = 0;
3873 while (type)
3875 if (IS_DECL (type))
3877 switch (DCL_TYPE (type))
3879 case FUNCTION:
3880 dbuf_printf (dbuf, "function %s%s",
3881 (IFFUNC_ISBUILTIN (type) ? "__builtin__ " : ""),
3882 (IFFUNC_ISJAVANATIVE (type) ? "_JavaNative " : ""));
3883 dbuf_append_str (dbuf, "( ");
3884 if (!FUNC_ARGS (type) && !FUNC_HASVARARGS(type) && !FUNC_NOPROTOTYPE(type))
3885 dbuf_append_str (dbuf, "void ");
3886 for (args = FUNC_ARGS (type); args; args = args->next)
3888 dbuf_printTypeChain (args->type, dbuf);
3889 if (args->next || FUNC_HASVARARGS(type))
3890 dbuf_append_str (dbuf, ", ");
3892 if (FUNC_HASVARARGS(type))
3893 dbuf_append_str (dbuf, "...");
3894 dbuf_append_str (dbuf, ")");
3895 if (IFFUNC_ISREENT (type) && isTargetKeyword("__reentrant"))
3896 dbuf_append_str (dbuf, " __reentrant");
3897 if (FUNC_REGBANK (type))
3899 dbuf_set_length (&dbuf2, 0);
3900 dbuf_printf (&dbuf2, " __using(%d)", FUNC_REGBANK (type));
3901 dbuf_append_str (dbuf, dbuf_c_str (&dbuf2));
3903 if (IFFUNC_ISBANKEDCALL (type))
3904 dbuf_append_str (dbuf, " __banked");
3905 if (IFFUNC_ISSMALLC (type))
3906 dbuf_append_str (dbuf, " __smallc");
3907 if (IFFUNC_ISRAISONANCE (type))
3908 dbuf_append_str (dbuf, " __raisonance");
3909 if (IFFUNC_ISIAR (type))
3910 dbuf_append_str (dbuf, " __iar");
3911 if (IFFUNC_ISCOSMIC (type))
3912 dbuf_append_str (dbuf, " __cosmic");
3913 if (IFFUNC_ISZ88DK_CALLEE (type))
3914 dbuf_append_str (dbuf, " __z88dk_callee");
3915 if (IFFUNC_ISZ88DK_FASTCALL (type))
3916 dbuf_append_str (dbuf, " __z88dk_fastcall");
3917 if (FUNC_SDCCCALL (type) >= 0 && FUNC_SDCCCALL (type) != options.sdcccall)
3918 dbuf_printf (dbuf, " __sdcccall(%d)", FUNC_SDCCCALL (type));
3919 for (unsigned char i = 0; i < 9; i++)
3920 if (type->funcAttrs.preserved_regs[i])
3922 dbuf_append_str (dbuf, " __preserves_regs(");
3923 for (; i < 9; i++)
3924 if (type->funcAttrs.preserved_regs[i])
3925 dbuf_printf (dbuf, " %d", i);
3926 dbuf_append_str (dbuf, " )");
3927 break;
3929 break;
3930 case GPOINTER:
3931 if (type->next && !IS_DECL (type->next) && SPEC_ADDRSPACE (type->next))
3932 dbuf_printf (dbuf, "%s*", SPEC_ADDRSPACE (type->next)->name);
3933 else
3934 dbuf_append_str (dbuf, "generic*");
3935 break;
3936 case CPOINTER:
3937 dbuf_append_str (dbuf, "__code*");
3938 break;
3939 case FPOINTER:
3940 dbuf_append_str (dbuf, "__xdata*");
3941 break;
3942 case EEPPOINTER:
3943 dbuf_append_str (dbuf, "eeprom*");
3944 break;
3945 case POINTER:
3946 dbuf_append_str (dbuf, "near*");
3947 break;
3948 case IPOINTER:
3949 dbuf_append_str (dbuf, "__idata*");
3950 break;
3951 case PPOINTER:
3952 dbuf_append_str (dbuf, "__pdata*");
3953 break;
3954 case UPOINTER:
3955 dbuf_append_str (dbuf, "unknown*");
3956 break;
3957 case ARRAY:
3958 if (DCL_ELEM (type))
3960 dbuf_printf (dbuf, "[%u]", (unsigned int) DCL_ELEM (type));
3962 else
3964 dbuf_append_str (dbuf, "[]");
3966 break;
3967 default:
3968 dbuf_append_str (dbuf, "unknown?");
3969 break;
3971 if (!IS_FUNC (type))
3973 if (DCL_PTR_VOLATILE (type))
3975 dbuf_append_str (dbuf, " volatile");
3977 if (DCL_PTR_CONST (type))
3979 dbuf_append_str (dbuf, " const");
3981 if (DCL_PTR_RESTRICT (type))
3983 dbuf_append_str (dbuf, " restrict");
3987 else
3989 if (SPEC_VOLATILE (type))
3990 dbuf_append_str (dbuf, "volatile-");
3991 if (SPEC_CONST (type))
3992 dbuf_append_str (dbuf, "const-");
3993 if (SPEC_NOUN (type) == V_CHAR) // char is a different type from both unsigned char and signed char
3995 if (!getSpec (type)->select.s.b_implicit_sign)
3996 dbuf_append_str (dbuf, SPEC_USIGN (type) ? "unsigned-" : "signed-");
3998 else if (SPEC_USIGN (type))
3999 dbuf_append_str (dbuf, "unsigned-");
4000 switch (SPEC_NOUN (type))
4002 case V_INT:
4003 if (IS_LONGLONG (type))
4004 dbuf_append_str (dbuf, "longlong-");
4005 else if (IS_LONG (type))
4006 dbuf_append_str (dbuf, "long-");
4007 dbuf_append_str (dbuf, "int");
4008 break;
4010 case V_BITINT:
4011 dbuf_printf (dbuf, "_BitInt(%u)", SPEC_BITINTWIDTH (type));
4012 break;
4014 case V_BOOL:
4015 dbuf_append_str (dbuf, "_Bool");
4016 break;
4018 case V_CHAR:
4019 dbuf_append_str (dbuf, "char");
4020 break;
4022 case V_VOID:
4023 dbuf_append_str (dbuf, "void");
4024 break;
4026 case V_FLOAT:
4027 dbuf_append_str (dbuf, "float");
4028 break;
4030 case V_FIXED16X16:
4031 dbuf_append_str (dbuf, "fixed16x16");
4032 break;
4034 case V_STRUCT:
4035 dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
4036 break;
4038 case V_SBIT:
4039 dbuf_append_str (dbuf, "sbit");
4040 break;
4042 case V_BIT:
4043 dbuf_append_str (dbuf, "bit");
4044 break;
4046 case V_BITFIELD:
4047 dbuf_printf (dbuf, "int-bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
4048 break;
4050 case V_BBITFIELD:
4051 dbuf_printf (dbuf, "_Bool-bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
4052 break;
4054 case V_BITINTBITFIELD:
4055 dbuf_printf (dbuf, "_BitInt(%d)-bitfield {%d,%d}", SPEC_BITINTWIDTH (type), SPEC_BSTR (type), SPEC_BLEN (type));
4056 break;
4058 case V_DOUBLE:
4059 dbuf_append_str (dbuf, "double");
4060 break;
4062 case V_NULLPTR:
4063 dbuf_append_str (dbuf, "nullptr_t");
4064 break;
4066 default:
4067 dbuf_append_str (dbuf, "unknown type");
4068 break;
4071 if (type == start)
4073 switch (scls)
4075 case S_FIXED:
4076 dbuf_append_str (dbuf, " fixed");
4077 break;
4078 case S_AUTO:
4079 dbuf_append_str (dbuf, " auto");
4080 break;
4081 case S_REGISTER:
4082 dbuf_append_str (dbuf, " register");
4083 break;
4084 case S_DATA:
4085 dbuf_append_str (dbuf, " data");
4086 break;
4087 case S_XDATA:
4088 dbuf_append_str (dbuf, " __xdata");
4089 break;
4090 case S_SFR:
4091 dbuf_append_str (dbuf, " sfr");
4092 break;
4093 case S_SBIT:
4094 dbuf_append_str (dbuf, " __sbit");
4095 break;
4096 case S_CODE:
4097 dbuf_append_str (dbuf, " __code");
4098 break;
4099 case S_IDATA:
4100 dbuf_append_str (dbuf, " __idata");
4101 break;
4102 case S_PDATA:
4103 dbuf_append_str (dbuf, " __pdata");
4104 break;
4105 case S_LITERAL:
4106 dbuf_append_str (dbuf, " literal");
4107 break;
4108 case S_STACK:
4109 dbuf_append_str (dbuf, " stack");
4110 break;
4111 case S_XSTACK:
4112 dbuf_append_str (dbuf, " xstack");
4113 break;
4114 case S_BIT:
4115 dbuf_append_str (dbuf, " __bit");
4116 break;
4117 case S_EEPROM:
4118 dbuf_append_str (dbuf, " eeprom");
4119 break;
4120 default:
4121 break;
4125 /* search entry in list before "type" */
4126 for (search = start; search && search->next != type;)
4127 search = search->next;
4128 type = search;
4129 if (type)
4130 dbuf_append_char (dbuf, ' ');
4134 /*--------------------------------------------------------------------*/
4135 /* printTypeChainRaw - prints the type chain in human readable form */
4136 /* in the raw data structure ordering */
4137 /*--------------------------------------------------------------------*/
4138 void
4139 printTypeChainRaw (sym_link * start, FILE * of)
4141 int nlr = 0;
4142 value *args;
4143 sym_link *type;
4145 if (!of)
4147 of = stdout;
4148 nlr = 1;
4151 if (start == NULL)
4153 fprintf (of, "void");
4154 return;
4157 type = start;
4159 while (type)
4161 if (IS_DECL (type))
4163 if (!IS_FUNC (type))
4165 if (DCL_PTR_VOLATILE (type))
4167 fprintf (of, "volatile-");
4169 if (DCL_PTR_CONST (type))
4171 fprintf (of, "const-");
4173 if (DCL_PTR_RESTRICT (type))
4175 fprintf (of, "restrict-");
4178 switch (DCL_TYPE (type))
4180 case FUNCTION:
4181 if (IFFUNC_ISINLINE (type))
4183 fprintf (of, "inline-");
4185 if (IFFUNC_ISNORETURN (type))
4187 fprintf (of, "_Noreturn-");
4189 fprintf (of, "function %s %s",
4190 (IFFUNC_ISBUILTIN (type) ? "__builtin__" : " "), (IFFUNC_ISJAVANATIVE (type) ? "_JavaNative" : " "));
4191 fprintf (of, "( ");
4192 for (args = FUNC_ARGS (type); args; args = args->next)
4194 printTypeChain (args->type, of);
4195 if (args->next)
4196 fprintf (of, ", ");
4198 fprintf (of, ") ");
4199 break;
4200 case GPOINTER:
4201 fprintf (of, "generic* ");
4202 break;
4203 case CPOINTER:
4204 fprintf (of, "code* ");
4205 break;
4206 case FPOINTER:
4207 fprintf (of, "xdata* ");
4208 break;
4209 case EEPPOINTER:
4210 fprintf (of, "eeprom* ");
4211 break;
4212 case POINTER:
4213 fprintf (of, "near* ");
4214 break;
4215 case IPOINTER:
4216 fprintf (of, "idata* ");
4217 break;
4218 case PPOINTER:
4219 fprintf (of, "pdata* ");
4220 break;
4221 case UPOINTER:
4222 fprintf (of, "unknown* ");
4223 break;
4224 case ARRAY:
4225 if (DCL_ELEM (type))
4227 fprintf (of, "[%ud] ", (unsigned int) DCL_ELEM (type));
4229 else
4231 fprintf (of, "[] ");
4233 break;
4235 if (DCL_TSPEC (type))
4237 fprintf (of, "{");
4238 printTypeChainRaw (DCL_TSPEC (type), of);
4239 fprintf (of, "}");
4242 else if (IS_SPEC (type))
4244 switch (SPEC_SCLS (type))
4246 case S_DATA:
4247 fprintf (of, "data-");
4248 break;
4249 case S_XDATA:
4250 fprintf (of, "xdata-");
4251 break;
4252 case S_SFR:
4253 fprintf (of, "sfr-");
4254 break;
4255 case S_SBIT:
4256 fprintf (of, "sbit-");
4257 break;
4258 case S_CODE:
4259 fprintf (of, "code-");
4260 break;
4261 case S_IDATA:
4262 fprintf (of, "idata-");
4263 break;
4264 case S_PDATA:
4265 fprintf (of, "pdata-");
4266 break;
4267 case S_LITERAL:
4268 fprintf (of, "literal-");
4269 break;
4270 case S_STACK:
4271 fprintf (of, "stack-");
4272 break;
4273 case S_XSTACK:
4274 fprintf (of, "xstack-");
4275 break;
4276 case S_BIT:
4277 fprintf (of, "bit-");
4278 break;
4279 case S_EEPROM:
4280 fprintf (of, "eeprom-");
4281 break;
4282 default:
4283 break;
4285 if (SPEC_VOLATILE (type))
4286 fprintf (of, "volatile-");
4287 if (SPEC_CONST (type))
4288 fprintf (of, "const-");
4289 if (SPEC_USIGN (type))
4290 fprintf (of, "unsigned-");
4291 switch (SPEC_NOUN (type))
4293 case V_INT:
4294 if (IS_LONGLONG (type))
4295 fprintf (of, "longlong-");
4296 else if (IS_LONG (type))
4297 fprintf (of, "long-");
4298 fprintf (of, "int");
4299 break;
4301 case V_BOOL:
4302 fprintf (of, "_Bool");
4303 break;
4305 case V_CHAR:
4306 fprintf (of, "char");
4307 break;
4309 case V_VOID:
4310 fprintf (of, "void");
4311 break;
4313 case V_FLOAT:
4314 fprintf (of, "float");
4315 break;
4317 case V_FIXED16X16:
4318 fprintf (of, "fixed16x16");
4319 break;
4321 case V_STRUCT:
4322 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
4323 break;
4325 case V_SBIT:
4326 fprintf (of, "sbit");
4327 break;
4329 case V_BIT:
4330 fprintf (of, "bit");
4331 break;
4333 case V_BITFIELD:
4334 fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
4335 break;
4337 case V_BBITFIELD:
4338 fprintf (of, "_Boolbitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
4339 break;
4341 case V_BITINTBITFIELD:
4342 fprintf (of, "_BitIntbitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
4343 break;
4345 case V_DOUBLE:
4346 fprintf (of, "double");
4347 break;
4349 default:
4350 fprintf (of, "unknown type");
4351 break;
4354 else
4355 fprintf (of, "NOT_SPEC_OR_DECL");
4356 type = type->next;
4357 if (type)
4358 fputc (' ', of);
4360 if (nlr)
4361 fprintf (of, "\n");
4365 /*-----------------------------------------------------------------*/
4366 /* powof2 - returns power of two for the number if number is pow 2 */
4367 /*-----------------------------------------------------------------*/
4369 powof2 (TYPE_TARGET_ULONGLONG num)
4371 int nshifts = 0;
4372 int n1s = 0;
4374 while (num)
4376 if (num & 1)
4377 n1s++;
4378 num >>= 1;
4379 nshifts++;
4382 if (n1s > 1 || nshifts == 0)
4383 return -1;
4384 return nshifts - 1;
4387 symbol *fsadd;
4388 symbol *fssub;
4389 symbol *fsmul;
4390 symbol *fsdiv;
4391 symbol *fseq;
4392 symbol *fsneq;
4393 symbol *fslt;
4395 symbol *fps16x16_add;
4396 symbol *fps16x16_sub;
4397 symbol *fps16x16_mul;
4398 symbol *fps16x16_div;
4399 symbol *fps16x16_eq;
4400 symbol *fps16x16_neq;
4401 symbol *fps16x16_lt;
4402 symbol *fps16x16_lteq;
4403 symbol *fps16x16_gt;
4404 symbol *fps16x16_gteq;
4406 /* Dims: mul/div/mod, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED/BOTH */
4407 symbol *muldiv[3][4][4];
4408 symbol *muls16tos32[2];
4409 symbol *mulu32u8tou64;
4410 /* Dims: BYTE/WORD/DWORD/QWORD SIGNED/UNSIGNED */
4411 sym_link *multypes[4][2];
4412 /* Dims: to/from float, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED */
4413 symbol *conv[2][4][2];
4414 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/QWORD/FLOAT, SIGNED/UNSIGNED */
4415 symbol *fp16x16conv[2][5][2];
4416 /* Dims: shift left/shift right, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED */
4417 symbol *rlrr[2][4][2];
4419 sym_link *floatType;
4420 sym_link *fixed16x16Type;
4422 symbol *builtin_memcpy;
4423 symbol *nonbuiltin_memcpy;
4424 symbol *builtin_unreachable;
4426 static const char *
4427 _mangleFunctionName (const char *in)
4429 if (port->getMangledFunctionName)
4431 return port->getMangledFunctionName (in);
4433 else
4435 return in;
4439 /*-----------------------------------------------------------------*/
4440 /* typeFromStr - create a typechain from an encoded string */
4441 /* basic types - 'b' - bool */
4442 /* 'c' - char */
4443 /* 's' - short */
4444 /* 'i' - int */
4445 /* 'l' - long */
4446 /* 'L' - long long */
4447 /* 'f' - float */
4448 /* 'q' - fixed16x16 */
4449 /* 'v' - void */
4450 /* '*' - pointer - default (GPOINTER) */
4451 /* modifiers - 'S' - signed */
4452 /* 'U' - unsigned */
4453 /* 'C' - const */
4454 /* pointer modifiers - 'g' - generic */
4455 /* 'x' - xdata */
4456 /* 'p' - code */
4457 /* 'd' - data */
4458 /* 'F' - function */
4459 /* examples : "ig*" - generic int * */
4460 /* "cx*" - char xdata * */
4461 /* "Ui" - unsigned int */
4462 /* "Sc" - signed char */
4463 /*-----------------------------------------------------------------*/
4464 sym_link *
4465 typeFromStr (const char *s)
4467 sym_link *r = newLink (DECLARATOR);
4468 int sign = 0;
4469 int usign = 0;
4470 int constant = 0;
4474 sym_link *nr;
4475 switch (*s)
4477 case 'S':
4478 sign = 1;
4479 break;
4480 case 'U':
4481 usign = 1;
4482 break;
4483 case 'C':
4484 constant = 1;
4485 break;
4486 case 'b':
4487 r->xclass = SPECIFIER;
4488 SPEC_NOUN (r) = V_BOOL;
4489 break;
4490 case 'c':
4491 r->xclass = SPECIFIER;
4492 SPEC_NOUN (r) = V_CHAR;
4493 if (!sign && !usign)
4494 r->select.s.b_implicit_sign = true;
4495 if (usign)
4497 SPEC_USIGN (r) = 1;
4498 usign = 0;
4500 else if (!sign && !options.signed_char)
4501 SPEC_USIGN (r) = 1;
4502 break;
4503 case 's':
4504 case 'i':
4505 r->xclass = SPECIFIER;
4506 SPEC_NOUN (r) = V_INT;
4507 break;
4508 case 'l':
4509 r->xclass = SPECIFIER;
4510 SPEC_NOUN (r) = V_INT;
4511 SPEC_LONG (r) = 1;
4512 break;
4513 case 'L':
4514 r->xclass = SPECIFIER;
4515 SPEC_NOUN (r) = V_INT;
4516 SPEC_LONGLONG (r) = 1;
4517 break;
4518 case 'f':
4519 r->xclass = SPECIFIER;
4520 SPEC_NOUN (r) = V_FLOAT;
4521 break;
4522 case 'q':
4523 r->xclass = SPECIFIER;
4524 SPEC_NOUN (r) = V_FIXED16X16;
4525 break;
4526 case 'v':
4527 r->xclass = SPECIFIER;
4528 SPEC_NOUN (r) = V_VOID;
4529 break;
4530 case '*':
4531 DCL_TYPE (r) = port->unqualified_pointer;
4532 break;
4533 case 'g':
4534 case 'x':
4535 case 'p':
4536 case 'd':
4537 case 'F':
4538 assert (*(s + 1) == '*');
4539 nr = newLink (DECLARATOR);
4540 nr->next = r;
4541 r = nr;
4542 switch (*s)
4544 case 'g':
4545 DCL_TYPE (r) = GPOINTER;
4546 break;
4547 case 'x':
4548 DCL_TYPE (r) = FPOINTER;
4549 break;
4550 case 'p':
4551 DCL_TYPE (r) = CPOINTER;
4552 break;
4553 case 'd':
4554 DCL_TYPE (r) = POINTER;
4555 break;
4556 case 'F':
4557 DCL_TYPE (r) = FUNCTION;
4558 nr = newLink (DECLARATOR);
4559 nr->next = r;
4560 r = nr;
4561 DCL_TYPE (r) = CPOINTER;
4562 break;
4564 s++;
4565 break;
4566 default:
4567 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "typeFromStr: unknown type");
4568 fprintf(stderr, "unknown: %s\n", s);
4569 break;
4571 if (usign && sign)
4572 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "typeFromStr: both signed and unsigned specified");
4573 if (IS_SPEC (r) && usign)
4575 SPEC_USIGN (r) = 1;
4576 usign = 0;
4578 if (IS_SPEC (r) && constant)
4580 SPEC_CONST (r) = 1;
4581 constant = 0;
4583 s++;
4585 while (*s);
4586 return r;
4589 /*-----------------------------------------------------------------*/
4590 /* initCSupport - create functions for C support routines */
4591 /*-----------------------------------------------------------------*/
4592 void
4593 initCSupport (void)
4595 const char *smuldivmod[] = {
4596 "mul", "div", "mod"
4598 const char *sbwd[] = {
4599 "char", "int", "long", "longlong", "fixed16x16",
4601 const char *fp16x16sbwd[] = {
4602 "char", "int", "long", "longlong", "float",
4604 const char *ssu[] = {
4605 "s", "su", "us", "u"
4607 const char *srlrr[] = {
4608 "sl", "sr"
4610 /* type as character codes for typeFromStr() */
4611 const char *sbwdCodes[] = {
4612 "c", "i", "l", "L",
4613 "Uc", "Ui", "Ul", "UL"
4616 int bwd, su, muldivmod, tofrom, slsr;
4618 if (getenv ("SDCC_NO_C_SUPPORT"))
4620 /* for debugging only */
4621 return;
4624 for (bwd = 0; bwd < 4; bwd++)
4626 sym_link *l = NULL;
4627 switch (bwd)
4629 case 0:
4630 l = newCharLink ();
4631 break;
4632 case 1:
4633 l = newIntLink ();
4634 break;
4635 case 2:
4636 l = newLongLink ();
4637 break;
4638 case 3:
4639 l = newLongLongLink ();
4640 break;
4641 default:
4642 assert (0);
4644 multypes[bwd][0] = l;
4645 multypes[bwd][1] = copyLinkChain (l);
4646 SPEC_USIGN (multypes[bwd][0]) = 0;
4647 SPEC_USIGN (multypes[bwd][1]) = 1;
4650 floatType = newFloatLink ();
4651 fixed16x16Type = newFixed16x16Link ();
4652 sym_link *boolType = newLink (SPECIFIER); SPEC_NOUN (boolType) = V_BOOL; // Can't use newBoolLink, as it might give us a __bit.
4653 sym_link *charType = (options.signed_char) ? SCHARTYPE : UCHARTYPE;
4655 fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
4656 fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
4657 fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
4658 fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
4659 fseq = funcOfType ("__fseq", boolType, floatType, 2, options.float_rent);
4660 fsneq = funcOfType ("__fsneq", boolType, floatType, 2, options.float_rent);
4661 fslt = funcOfType ("__fslt", boolType, floatType, 2, options.float_rent);
4663 fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4664 fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4665 fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4666 fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
4667 fps16x16_eq = funcOfType ("__fps16x16_eq", charType, fixed16x16Type, 2, options.float_rent);
4668 fps16x16_neq = funcOfType ("__fps16x16_neq", charType, fixed16x16Type, 2, options.float_rent);
4669 fps16x16_lt = funcOfType ("__fps16x16_lt", charType, fixed16x16Type, 2, options.float_rent);
4670 fps16x16_lteq = funcOfType ("__fps16x16_lteq", charType, fixed16x16Type, 2, options.float_rent);
4671 fps16x16_gt = funcOfType ("__fps16x16_gt", charType, fixed16x16Type, 2, options.float_rent);
4672 fps16x16_gteq = funcOfType ("__fps16x16_gteq", charType, fixed16x16Type, 2, options.float_rent);
4674 for (tofrom = 0; tofrom < 2; tofrom++)
4676 for (bwd = 0; bwd < 4; bwd++)
4678 for (su = 0; su < 2; su++)
4680 struct dbuf_s dbuf;
4682 dbuf_init (&dbuf, 128);
4683 if (tofrom)
4685 dbuf_printf (&dbuf, "__fs2%s%s", ssu[su * 3], sbwd[bwd]);
4686 conv[tofrom][bwd][su] = funcOfType (dbuf_c_str (&dbuf), multypes[bwd][su], floatType, 1, options.float_rent);
4688 else
4690 dbuf_printf (&dbuf, "__%s%s2fs", ssu[su * 3], sbwd[bwd]);
4691 conv[tofrom][bwd][su] = funcOfType (dbuf_c_str (&dbuf), floatType, multypes[bwd][su], 1, options.float_rent);
4693 dbuf_destroy (&dbuf);
4698 for (tofrom = 0; tofrom < 2; tofrom++)
4700 for (bwd = 0; bwd < 5; bwd++)
4702 for (su = 0; su < 2; su++)
4704 struct dbuf_s dbuf;
4706 dbuf_init (&dbuf, 128);
4707 if (tofrom)
4709 dbuf_printf (&dbuf, "__fps16x162%s%s", ssu[su * 3], fp16x16sbwd[bwd]);
4710 if (bwd == 4)
4711 fp16x16conv[tofrom][bwd][su] =
4712 funcOfType (dbuf_c_str (&dbuf), floatType, fixed16x16Type, 1, options.float_rent);
4713 else
4714 fp16x16conv[tofrom][bwd][su] =
4715 funcOfType (dbuf_c_str (&dbuf), multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
4717 else
4719 dbuf_printf (&dbuf, "__%s%s2fps16x16", ssu[su * 3], fp16x16sbwd[bwd]);
4720 if (bwd == 4)
4721 fp16x16conv[tofrom][bwd][su] =
4722 funcOfType (dbuf_c_str (&dbuf), fixed16x16Type, floatType, 1, options.float_rent);
4723 else
4724 fp16x16conv[tofrom][bwd][su] =
4725 funcOfType (dbuf_c_str (&dbuf), fixed16x16Type, multypes[bwd][su], 1, options.float_rent);
4727 dbuf_destroy (&dbuf);
4733 for (muldivmod = 0; muldivmod < 3; muldivmod++)
4735 for (bwd = 0; bwd < 4; bwd++)
4737 for (su = 0; su < 2; su++)
4739 struct dbuf_s dbuf;
4741 dbuf_init (&dbuf, 128);
4742 dbuf_printf (&dbuf, "_%s%s%s", smuldivmod[muldivmod], ssu[su*3], sbwd[bwd]);
4743 muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(dbuf_c_str (&dbuf)), multypes[bwd][su], multypes[bwd][su], 2, options.intlong_rent);
4744 dbuf_destroy (&dbuf);
4745 FUNC_NONBANKED (muldiv[muldivmod][bwd][su]->type) = 1;
4750 muluint() and mulsint() resp. mululong() and mulslong() return the same result.
4751 Therefore they've been merged into mulint() and mullong().
4754 /* byte */
4756 /* _divschar/_modschar return int, so that both
4757 * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
4758 * (first one would have to be sign extended, second one must not be).
4759 * Similarly, modschar should be handled, but the iCode introduces cast
4760 * here and forces '% : s8 x s8 -> s8' ... */
4761 bwd = 0;
4762 for (su = 0; su < 4; su++)
4764 for (muldivmod = 0; muldivmod < 3; muldivmod++)
4766 /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80
4767 port is sign/zero-extending to int before calling mulint() */
4768 /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
4769 struct dbuf_s dbuf;
4771 dbuf_init (&dbuf, 128);
4772 dbuf_printf (&dbuf, "_%s%s%s", smuldivmod[muldivmod], ssu[su], sbwd[bwd]);
4773 muldiv[muldivmod][bwd][su] =
4774 funcOfType (_mangleFunctionName (dbuf_c_str (&dbuf)),
4775 multypes[(TARGET_IS_PIC16 && muldivmod == 1 && bwd == 0 && su == 0 || (TARGET_IS_PIC14 || TARGET_IS_STM8 || TARGET_Z80_LIKE || TARGET_PDK_LIKE || TARGET_MOS6502_LIKE || TARGET_IS_F8) && bwd == 0) ? 1 : bwd][su % 2],
4776 multypes[bwd][su / 2],
4778 options.intlong_rent);
4779 dbuf_destroy (&dbuf);
4783 for (bwd = 1; bwd < 4; bwd++)
4785 for (su = 0; su < 2; su++)
4787 for (muldivmod = 1; muldivmod < 3; muldivmod++)
4789 struct dbuf_s dbuf;
4791 dbuf_init (&dbuf, 128);
4792 dbuf_printf (&dbuf, "_%s%s%s", smuldivmod[muldivmod], ssu[su * 3], sbwd[bwd]);
4793 muldiv[muldivmod][bwd][su] =
4794 funcOfType (_mangleFunctionName (dbuf_c_str (&dbuf)),
4795 multypes[(TARGET_IS_PIC16 && muldivmod == 1 && bwd == 0 && su == 0 || (TARGET_IS_STM8 || TARGET_Z80_LIKE || TARGET_PDK_LIKE || TARGET_IS_F8) && bwd == 0) ? 1 : bwd][su],
4796 multypes[bwd][su],
4798 options.intlong_rent);
4799 dbuf_destroy (&dbuf);
4804 /* mul only */
4805 muldivmod = 0;
4806 /* signed only */
4807 su = 0;
4808 /* word, doubleword, and quadword */
4809 for (bwd = 1; bwd < 4; bwd++)
4811 /* mul, int/long */
4812 struct dbuf_s dbuf;
4814 dbuf_init (&dbuf, 128);
4815 dbuf_printf (&dbuf, "_%s%s", smuldivmod[muldivmod], sbwd[bwd]);
4816 muldiv[muldivmod][bwd][0] =
4817 funcOfType (_mangleFunctionName (dbuf_c_str (&dbuf)), multypes[bwd][su], multypes[bwd][su], 2, options.intlong_rent);
4818 dbuf_destroy (&dbuf);
4819 /* signed = unsigned */
4820 muldiv[muldivmod][bwd][1] = muldiv[muldivmod][bwd][0];
4823 for (slsr = 0; slsr < 2; slsr++)
4825 for (bwd = 0; bwd < 4; bwd++)
4827 for (su = 0; su < 2; su++)
4829 struct dbuf_s dbuf;
4830 symbol *sym;
4831 const char *params[2];
4833 params[0] = sbwdCodes[bwd + 4*su];
4834 params[1] = sbwdCodes[0];
4836 dbuf_init (&dbuf, 128);
4837 dbuf_printf (&dbuf, "_%s%s%s", srlrr[slsr], ssu[su * 3], sbwd[bwd]);
4838 rlrr[slsr][bwd][su] = sym =
4839 funcOfTypeVarg (_mangleFunctionName (dbuf_c_str (&dbuf)),
4840 sbwdCodes[bwd + 4*su], 2, &params[0]);
4841 FUNC_ISREENT (sym->type) = options.intlong_rent ? 1 : 0;
4842 FUNC_NONBANKED (sym->type) = 1;
4843 dbuf_destroy (&dbuf);
4849 const char *iparams[] = {"i", "i"};
4850 const char *uiparams[] = {"Ui", "Ui"};
4851 muls16tos32[0] = port->support.has_mulint2long ? funcOfTypeVarg ("__mulsint2slong", "l", 2, iparams) : 0;
4852 muls16tos32[1] = port->support.has_mulint2long ? funcOfTypeVarg ("__muluint2ulong", "Ul", 2, uiparams) : 0;
4855 const char *uiparams[] = {"Ul", "Uc"};
4856 mulu32u8tou64 = port->support.has_mululonguchar2ulonglong ? funcOfTypeVarg ("__mululonguchar2ulonglong", "UL", 2, uiparams) : 0;
4860 /*-----------------------------------------------------------------*/
4861 /* initBuiltIns - create prototypes for builtin functions */
4862 /*-----------------------------------------------------------------*/
4863 void
4864 initBuiltIns ()
4866 int i;
4867 symbol *sym;
4869 if (port->builtintable)
4871 for (i = 0; port->builtintable[i].name; i++)
4873 sym = funcOfTypeVarg (port->builtintable[i].name, port->builtintable[i].rtype,
4874 port->builtintable[i].nParms, (const char **)port->builtintable[i].parm_types);
4875 FUNC_ISBUILTIN (sym->type) = 1;
4876 FUNC_ISREENT (sym->type) = 0; /* can never be reentrant */
4880 /* initialize memcpy symbol for struct assignment */
4881 builtin_memcpy = findSym (SymbolTab, NULL, "__builtin_memcpy");
4882 nonbuiltin_memcpy = findSym (SymbolTab, NULL, "__memcpy");
4884 if (!nonbuiltin_memcpy)
4886 const char *argTypeStrs[] = {"vg*", "Cvg*", "Ui"};
4887 nonbuiltin_memcpy = funcOfTypeVarg ("__memcpy", "vg*", 3, argTypeStrs);
4888 FUNC_ISBUILTIN (nonbuiltin_memcpy->type) = 0;
4889 FUNC_ISREENT (nonbuiltin_memcpy->type) = options.stackAuto;
4891 /* if there is no __builtin_memcpy, use __memcpy instead of an actual builtin */
4892 if (!builtin_memcpy)
4893 builtin_memcpy = nonbuiltin_memcpy;
4895 builtin_unreachable = funcOfTypeVarg ("__builtin_unreachable", "v", 0, 0);
4898 sym_link *
4899 validateLink (sym_link * l, const char *macro, const char *args, const char select, const char *file, unsigned line)
4901 if (l && l->xclass == select)
4903 return l;
4905 fprintf (stderr,
4906 "Internal error: validateLink failed in %s(%s) @ %s:%u:"
4907 " expected %s, got %s\n",
4908 macro, args, file, line, DECLSPEC2TXT (select), l ? DECLSPEC2TXT (l->xclass) : "null-link");
4909 exit (EXIT_FAILURE);
4910 return l; // never reached, makes compiler happy.
4913 static bool
4914 llFitsInIntType (long long ll, sym_link *type)
4916 long long min = 0, max = 0;
4918 // determine min and max values for explicitly or implicitly unsigned integers
4919 if (SPEC_USIGN (type) || SPEC_NOUN (type) == V_BOOL)
4921 switch (SPEC_NOUN (type))
4923 case V_BOOL:
4924 max = 1ll;
4925 break;
4926 case V_CHAR:
4927 max = 0xffll;
4928 break;
4929 case V_INT:
4930 if (SPEC_LONGLONG (type))
4931 max = 0x7fffffffffffffffll; // actual ull max would not fit and input is ll, anyway
4932 else if (SPEC_LONG (type))
4933 max = 0xffffffffll;
4934 else
4935 max = 0xffffll;
4936 break;
4937 default:
4938 assert (0); // not implemented for non-integer types
4941 else // determine min and max values for signed integers
4943 switch (SPEC_NOUN (type))
4945 case V_CHAR:
4946 min = -128ll;
4947 max = 127ll;
4948 break;
4949 case V_INT:
4950 if (SPEC_LONGLONG (type))
4952 min = -9223372036854775808ull; // the "-" is not part of the literal, which does not fit in ll
4953 max = 9223372036854775807ll;
4955 else if (SPEC_LONG (type))
4957 min = -2147483648ll;
4958 max = 2147483647ll;
4960 else
4962 min = -32768ll;
4963 max = 32767ll;
4965 break;
4966 default:
4967 assert (0); // not implemented for non-integer types
4971 return ll >= min && ll <= max;
4974 /*--------------------------------------------------------------------*/
4975 /* newEnumType - create an integer type compatible with enumerations */
4976 /*--------------------------------------------------------------------*/
4977 sym_link *
4978 newEnumType (symbol *enumlist, sym_link *userRequestedType)
4980 long long int min, max, v;
4981 symbol *sym;
4982 sym_link *type = newLink (SPECIFIER);
4983 SPEC_ENUM (type) = 1;
4985 /* Catch user-requested types that make no sense for an enum; provide fallback if none specified */
4986 if (userRequestedType)
4988 checkTypeSanity (userRequestedType, NULL);
4989 if ((SPEC_NOUN (userRequestedType) != V_INT && SPEC_NOUN (userRequestedType) != V_CHAR && SPEC_NOUN (userRequestedType) != V_BOOL) || SPEC_ENUM (userRequestedType))
4991 werror (E_ENUM_UNDERLYING_TYPE);
4992 /* try to keep going */
4993 SPEC_NOUN (type) = V_INT;
4994 return type;
4997 SPEC_NOUN (type) = SPEC_NOUN (userRequestedType);
4998 SPEC_SIGN (type) = SPEC_SIGN (userRequestedType);
4999 SPEC_USIGN (type) = SPEC_USIGN (userRequestedType);
5000 SPEC_LONG (type) = SPEC_LONG (userRequestedType);
5001 SPEC_LONGLONG (type) = SPEC_LONGLONG (userRequestedType);
5003 else
5005 SPEC_NOUN (type) = V_INT;
5008 if (!enumlist)
5010 return type;
5013 /* Determine the range of the enumerated values */
5014 sym = enumlist;
5015 min = max = (long long int) ullFromVal (valFromType (sym->type));
5016 for (sym = sym->next; sym; sym = sym->next)
5018 v = (long long int) ullFromVal (valFromType (sym->type));
5019 if (v < min)
5020 min = v;
5021 if (v > max)
5022 max = v;
5025 /* Figure out if everything fits in the user requested (or default int) type */
5026 if (!llFitsInIntType (min, type) || !llFitsInIntType (max, type))
5027 werror (userRequestedType ? E_ENUM_TYPE_RANGE_TOO_SMALL : W_ENUM_INT_RANGE_C23);
5029 /* It does: If the type was explicitly requested, return it! */
5030 if (userRequestedType)
5031 return type;
5033 /* Otherwise: Use the smallest integer type that is compatible with this range and not a bit-precise type. */
5034 if (min >= 0 && max <= 1)
5036 SPEC_NOUN (type) = V_BOOL;
5038 else if (min >= 0 && max <= 255)
5040 SPEC_NOUN (type) = V_CHAR;
5041 SPEC_USIGN (type) = 1;
5043 else if (min >= -128 && max <= 127)
5045 SPEC_NOUN (type) = V_CHAR;
5046 SPEC_SIGN (type) = 1;
5048 else if (min >= 0 && max <= 65535)
5050 SPEC_NOUN (type) = V_INT;
5051 SPEC_USIGN (type) = 1;
5053 else if (min >= -32768 && max <= 32767)
5055 SPEC_NOUN (type) = V_INT;
5057 else if (min >= 0 && max <= 4294967295)
5059 SPEC_NOUN (type) = V_INT;
5060 SPEC_LONG (type) = 1;
5061 SPEC_USIGN (type) = 1;
5063 else if (min >= -2147483648 && max <= 2147483647)
5065 SPEC_NOUN (type) = V_INT;
5066 SPEC_LONG (type) = 1;
5068 else
5070 SPEC_NOUN (type) = V_INT;
5071 SPEC_LONGLONG (type) = 1;
5072 if (min >= 0)
5073 SPEC_USIGN (type) = 1;
5076 return type;
5079 /*-------------------------------------------------------------------*/
5080 /* isConstant - check if the type is constant */
5081 /*-------------------------------------------------------------------*/
5083 isConstant (sym_link * type)
5085 if (!type)
5086 return 0;
5088 while (IS_ARRAY (type))
5089 type = type->next;
5091 if (IS_SPEC (type))
5092 return SPEC_CONST (type);
5093 else
5094 return DCL_PTR_CONST (type);
5097 /*-------------------------------------------------------------------*/
5098 /* isVolatile - check if the type is volatile */
5099 /*-------------------------------------------------------------------*/
5101 isVolatile (sym_link * type)
5103 if (!type)
5104 return 0;
5106 while (IS_ARRAY (type))
5107 type = type->next;
5109 if (IS_SPEC (type))
5110 return SPEC_VOLATILE (type);
5111 else
5112 return DCL_PTR_VOLATILE (type);
5115 /*-------------------------------------------------------------------*/
5116 /* isRestrict - check if the type is restricted */
5117 /*-------------------------------------------------------------------*/
5119 isRestrict (sym_link * type)
5121 if (!type)
5122 return 0;
5124 while (IS_ARRAY (type))
5125 type = type->next;
5127 if (IS_SPEC (type))
5128 return SPEC_RESTRICT (type);
5129 else
5130 return DCL_PTR_RESTRICT (type);
5133 /*-------------------------------------------------------------------*/
5134 /* mergeKRDeclListIntoFuncDecl - merge the type information from the */
5135 /* declaration list between function declaration and body into */
5136 /* the function declaration, replacing the default type int */
5137 /*-------------------------------------------------------------------*/
5138 void
5139 mergeKRDeclListIntoFuncDecl (symbol *funcDecl, symbol *kr_decls)
5141 if (kr_decls != NULL)
5143 if (options.std_c23)
5145 werror (E_OLD_STYLE, (funcDecl ? funcDecl->name: ""));
5146 exit (1);
5149 symbol *declLoop;
5150 value *parLoop;
5152 sym_link *funcType;
5154 funcType = funcDecl->type;
5155 while (funcType && !IS_FUNC (funcType))
5156 funcType = funcType->next;
5158 assert (funcType);
5160 /* TODO:
5161 * use FUNC_NOPROTOTYPE, once prototype-less functions are fully
5162 * supported and K&R functions can be treated as such, because
5163 * a function with prototype cannot have been declared in K&R style
5165 if (!funcType->funcAttrs.oldStyle)
5166 werror (E_MIXED_FUNCTION_STYLES, (funcDecl ? funcDecl->name: ""));
5168 /* iterate over members of declaration list */
5169 for (declLoop = kr_decls; declLoop; declLoop = declLoop->next)
5171 bool found = false;
5172 /* iterate over parameters */
5173 for (parLoop = FUNC_ARGS (funcType); parLoop; parLoop = parLoop->next)
5175 if (strcmp (declLoop->name, parLoop->sym->name) == 0)
5176 found = true;
5178 if (!found)
5179 werror (E_ID_UNDEF, declLoop->name);
5182 /* iterate over parameters */
5183 for (parLoop = FUNC_ARGS (funcType); parLoop; parLoop = parLoop->next)
5185 bool found = false;
5186 /* iterate over members of declaration list */
5187 for (declLoop = kr_decls; declLoop; declLoop = declLoop->next)
5189 if (strcmp (declLoop->name, parLoop->sym->name) == 0)
5191 if (found)
5193 werror (E_DUPLICATE, declLoop->name);
5194 continue;
5196 found = true;
5197 /* delete default int type */
5198 Safe_free (parLoop->type);
5199 /* propagate type */
5200 parLoop->type = declLoop->type;
5201 parLoop->etype = declLoop->etype;
5202 parLoop->sym->type = copyLinkChain (parLoop->type);
5203 parLoop->sym->etype = getSpec (parLoop->sym->type);