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
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 -------------------------------------------------------------------------*/
26 #include "dbuf_string.h"
30 value *aggregateToPointer (value *val);
31 void printTypeChainRaw (sym_link * start, FILE * of);
33 void printFromToType(sym_link *from, sym_link *to) {
34 fprintf (stderr, "from type '");
35 printTypeChain (from, stderr);
36 fprintf (stderr, "'\nto type '");
37 printTypeChain (to, stderr);
38 fprintf (stderr, "'\n");
42 char *nounName(sym_link *sl) {
43 switch (SPEC_NOUN(sl))
46 if (SPEC_LONG(sl)) return "long";
47 if (SPEC_SHORT(sl)) return "short";
50 case V_FLOAT: return "float";
51 case V_FIXED16X16: return "fixed16x16";
52 case V_CHAR: return "char";
53 case V_VOID: return "void";
54 case V_STRUCT: return "struct";
55 case V_LABEL: return "label";
56 case V_BITFIELD: return "bitfield";
57 case V_BIT: return "bit";
58 case V_SBIT: return "sbit";
59 case V_DOUBLE: return "double";
64 bucket *SymbolTab[256]; /* the symbol table */
65 bucket *StructTab[256]; /* the structure table */
66 bucket *TypedefTab[256]; /* the typedef table */
67 bucket *LabelTab[256]; /* the Label table */
68 bucket *enumTab[256]; /* enumerated table */
70 /*------------------------------------------------------------------*/
71 /* initSymt () - initialises symbol table related stuff */
72 /*------------------------------------------------------------------*/
78 for (i = 0; i < 256; i++)
79 SymbolTab[i] = StructTab[i] = (void *) NULL;
83 /*-----------------------------------------------------------------*/
84 /* newBucket - allocates & returns a new bucket */
85 /*-----------------------------------------------------------------*/
91 bp = Safe_alloc ( sizeof (bucket));
96 /*-----------------------------------------------------------------*/
97 /* hashKey - computes the hashkey given a symbol name */
98 /*-----------------------------------------------------------------*/
100 hashKey (const char *s)
102 unsigned long key = 0;
109 /*-----------------------------------------------------------------*/
110 /* addSym - adds a symbol to the hash Table */
111 /*-----------------------------------------------------------------*/
113 addSym (bucket ** stab,
120 int i; /* index into the hash Table */
121 bucket *bp; /* temp bucket * */
124 symbol *csym = (symbol *)sym;
126 if (getenv("DEBUG_SANITY")) {
127 fprintf (stderr, "addSym: %s ", sname);
129 /* make sure the type is complete and sane */
130 checkTypeSanity(csym->etype, csym->name);
133 /* prevent overflow of the (r)name buffers */
134 if (strlen(sname)>SDCC_SYMNAME_MAX) {
135 werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
136 sname[SDCC_SYMNAME_MAX]='\0';
139 /* the symbols are always added at the head of the list */
141 /* get a free entry */
142 bp = Safe_alloc ( sizeof (bucket));
144 bp->sym = sym; /* update the symbol pointer */
145 bp->level = level; /* update the nest level */
147 strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
149 /* if this is the first entry */
152 bp->prev = bp->next = (void *) NULL; /* point to nothing */
155 /* not first entry then add @ head of list */
165 /*-----------------------------------------------------------------*/
166 /* deleteSym - deletes a symbol from the hash Table entry */
167 /*-----------------------------------------------------------------*/
169 deleteSym (bucket ** stab, void *sym, char *sname)
177 /* find the symbol */
180 if (bp->sym == sym) /* found it then break out */
181 break; /* of the loop */
185 if (!bp) /* did not find it */
187 /* if this is the first one in the chain */
191 if (stab[i]) /* if chain ! empty */
192 stab[i]->prev = (void *) NULL;
194 /* middle || end of chain */
197 if (bp->next) /* if not end of chain */
198 bp->next->prev = bp->prev;
200 bp->prev->next = bp->next;
205 /*-----------------------------------------------------------------*/
206 /* findSym - finds a symbol in a table */
207 /*-----------------------------------------------------------------*/
209 findSym (bucket ** stab, void *sym, const char *sname)
213 bp = stab[hashKey (sname)];
216 if (bp->sym == sym || strcmp (bp->name, sname) == 0)
221 return (bp ? bp->sym : (void *) NULL);
224 /*-----------------------------------------------------------------*/
225 /* findSymWithLevel - finds a symbol with a name & level */
226 /*-----------------------------------------------------------------*/
228 findSymWithLevel (bucket ** stab, symbol * sym)
232 bp = stab[hashKey (sym->name)];
235 ** do the search from the head of the list since the
236 ** elements are added at the head it is ensured that
237 ** we will find the deeper definitions before we find
238 ** the global ones. we need to check for symbols with
239 ** level <= to the level given, if levels match then block
240 ** numbers need to match as well
244 if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
246 /* if this is parameter then nothing else need to be checked */
247 if (((symbol *) (bp->sym))->_isparm)
249 /* if levels match then block numbers should also match */
250 if (bp->level && bp->level == sym->level && bp->block == sym->block)
252 /* if levels don't match then we are okay */
253 if (bp->level && bp->level != sym->level && bp->block <= sym->block)
255 /* if this is a global variable then we are ok too */
263 return (void *) NULL;
266 /*-----------------------------------------------------------------*/
267 /* findSymWithBlock - finds a symbol with name in with a block */
268 /*-----------------------------------------------------------------*/
270 findSymWithBlock (bucket ** stab, symbol * sym, int block)
274 bp = stab[hashKey (sym->name)];
277 if (strcmp (bp->name, sym->name) == 0 &&
283 return (bp ? bp->sym : (void *) NULL);
286 /*------------------------------------------------------------------*/
287 /* newSymbol () - returns a new pointer to a symbol */
288 /*------------------------------------------------------------------*/
290 newSymbol (char *name, int scope)
294 sym = Safe_alloc ( sizeof (symbol));
296 strncpyz (sym->name, name, sizeof(sym->name)); /* copy the name */
297 sym->level = scope; /* set the level */
298 sym->block = currBlockno;
299 sym->lineDef = lexLineno; /* set the line number */
300 sym->fileDef = lexFilename;
304 /*------------------------------------------------------------------*/
305 /* newLink - creates a new link (declarator,specifier) */
306 /*------------------------------------------------------------------*/
308 newLink (SYM_LINK_CLASS select)
312 p = Safe_alloc ( sizeof (sym_link));
318 /*------------------------------------------------------------------*/
319 /* newStruct - creats a new structdef from the free list */
320 /*------------------------------------------------------------------*/
322 newStruct (char *tag)
326 s = Safe_alloc ( sizeof (structdef));
328 strncpyz (s->tag, tag, sizeof(s->tag)); /* copy the tag */
332 /*------------------------------------------------------------------*/
333 /* sclsFromPtr - Return the storage class a pointer points into. */
334 /* S_FIXED is returned for generic pointers or other */
335 /* unexpected cases */
336 /*------------------------------------------------------------------*/
338 sclsFromPtr(sym_link *ptr)
340 switch (DCL_TYPE (ptr))
363 /*------------------------------------------------------------------*/
364 /* pointerTypes - do the computation for the pointer types */
365 /*------------------------------------------------------------------*/
367 pointerTypes (sym_link * ptr, sym_link * type)
372 /* find the first pointer type */
373 while (ptr && !IS_PTR (ptr))
376 /* could not find it */
377 if (!ptr || IS_SPEC (ptr))
380 if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
381 pointerTypes (ptr->next, type);
385 /* change the pointer type depending on the
386 storage class of the type */
389 switch (SPEC_SCLS (type))
392 DCL_TYPE (ptr) = FPOINTER;
395 DCL_TYPE (ptr) = IPOINTER;
398 DCL_TYPE (ptr) = PPOINTER;
401 DCL_TYPE (ptr) = POINTER;
404 DCL_TYPE (ptr) = CPOINTER;
407 DCL_TYPE (ptr) = EEPPOINTER;
410 DCL_TYPE (ptr) = port->unqualified_pointer;
413 /* the storage class of type ends here */
414 SPEC_SCLS (type) = 0;
417 /* now change all the remaining unknown pointers
418 to generic pointers */
421 if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
422 DCL_TYPE (ptr) = port->unqualified_pointer;
426 /* same for the type although it is highly unlikely that
427 type will have a pointer */
430 if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
431 DCL_TYPE (type) = port->unqualified_pointer;
436 /*------------------------------------------------------------------*/
437 /* addDecl - adds a declarator @ the end of a chain */
438 /*------------------------------------------------------------------*/
440 addDecl (symbol * sym, int type, sym_link * p)
442 static sym_link *empty = NULL;
447 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
448 fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
451 empty = newLink(SPECIFIER);
453 /* if we are passed a link then set head & tail */
462 head = tail = newLink (DECLARATOR);
463 DCL_TYPE (head) = type;
466 /* if this is the first entry */
472 else if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
474 sym->etype = mergeSpec (sym->etype, head, sym->name);
476 else if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
479 while (t->next != sym->etype)
482 tail->next = sym->etype;
484 else if (IS_FUNC (sym->type) && IS_SPEC (sym->type->next) &&
485 !memcmp(sym->type->next, empty, sizeof(sym_link)))
487 sym->type->next = head;
492 sym->etype->next = head;
496 /* if the type is an unknown pointer and has
497 a tspec then take the storage class const & volatile
498 attribute from the tspec & make it those of this
502 //DCL_TYPE (p) == UPOINTER &&
505 if (!IS_SPEC (sym->etype))
507 sym->etype = sym->etype->next = newLink (SPECIFIER);
509 SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
510 DCL_TSPEC (p) = NULL;
513 // if there is a function in this type chain
514 if (p && funcInChain(sym->type)) {
515 processFuncArgs (sym);
521 /*------------------------------------------------------------------
522 checkTypeSanity: prevent the user from doing e.g.:
524 ------------------------------------------------------------------*/
525 void checkTypeSanity(sym_link *etype, char *name) {
529 if (getenv("DEBUG_SANITY")) {
530 fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
535 if (!IS_SPEC(etype)) {
536 if (getenv("DEBUG_SANITY")) {
537 fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
542 noun=nounName(etype);
544 if (getenv("DEBUG_SANITY")) {
545 fprintf (stderr, "checking sanity for %s %p\n", name, etype);
548 if ((SPEC_NOUN(etype)==V_CHAR ||
549 SPEC_NOUN(etype)==V_FLOAT ||
550 SPEC_NOUN(etype)==V_FIXED16X16 ||
551 SPEC_NOUN(etype)==V_DOUBLE ||
552 SPEC_NOUN(etype)==V_VOID) &&
553 (SPEC_SHORT(etype) || SPEC_LONG(etype))) {
554 // long or short for char float double or void
555 werror (E_LONG_OR_SHORT_INVALID, noun, name);
557 if ((SPEC_NOUN(etype)==V_FLOAT ||
558 SPEC_NOUN(etype)==V_FIXED16X16 ||
559 SPEC_NOUN(etype)==V_DOUBLE ||
560 SPEC_NOUN(etype)==V_VOID) &&
561 (etype->select.s.b_signed || SPEC_USIGN(etype))) {
562 // signed or unsigned for float double or void
563 werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
566 // special case for "short"
567 if (SPEC_SHORT(etype)) {
568 SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
569 SPEC_SHORT(etype) = 0;
573 "const a;" or "data b;" or "signed s" or "long l"
575 if (!SPEC_NOUN(etype)) {
576 SPEC_NOUN(etype)=V_INT;
579 /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
580 /* a "plain" int bitfield is unsigned */
581 if (SPEC_NOUN(etype)==V_BIT ||
582 SPEC_NOUN(etype)==V_SBIT) {
583 if (!etype->select.s.b_signed)
584 SPEC_USIGN(etype) = 1;
587 if (etype->select.s.b_signed && SPEC_USIGN(etype)) {
588 // signed AND unsigned
589 werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
591 if (SPEC_SHORT(etype) && SPEC_LONG(etype)) {
593 werror (E_LONG_AND_SHORT_INVALID, noun, name);
598 /*------------------------------------------------------------------*/
599 /* mergeSpec - merges two specifiers and returns the new one */
600 /*------------------------------------------------------------------*/
602 mergeSpec (sym_link * dest, sym_link * src, char *name)
604 if (!IS_SPEC(dest) || !IS_SPEC(src)) {
606 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
609 werror (E_SYNTAX_ERROR, yytext);
610 // the show must go on
615 if (SPEC_NOUN(src)) {
616 if (!SPEC_NOUN(dest)) {
617 SPEC_NOUN(dest)=SPEC_NOUN(src);
619 /* we shouldn't redeclare the type */
620 if (getenv("DEBUG_SANITY")) {
621 fprintf (stderr, "mergeSpec: ");
623 werror(E_TWO_OR_MORE_DATA_TYPES, name);
627 if (SPEC_SCLS(src)) {
628 /* if destination has no storage class */
629 if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
630 SPEC_SCLS (dest) = SPEC_SCLS (src);
632 if (getenv("DEBUG_SANITY")) {
633 fprintf (stderr, "mergeSpec: ");
635 werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
639 /* copy all the specifications */
641 // we really should do:
643 if (SPEC_what(src)) {
644 if (SPEC_what(dest)) {
645 werror(W_DUPLICATE_SPEC, "what");
647 SPEC_what(dst)|=SPEC_what(src);
650 // but there are more important thing right now
652 SPEC_LONG (dest) |= SPEC_LONG (src);
653 SPEC_SHORT(dest) |= SPEC_SHORT(src);
654 SPEC_USIGN (dest) |= SPEC_USIGN (src);
655 dest->select.s.b_signed|=src->select.s.b_signed;
656 SPEC_STAT (dest) |= SPEC_STAT (src);
657 SPEC_EXTR (dest) |= SPEC_EXTR (src);
658 SPEC_INLINE (dest) |= SPEC_INLINE (src);
659 SPEC_CONST(dest) |= SPEC_CONST (src);
660 SPEC_ABSA (dest) |= SPEC_ABSA (src);
661 SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
662 SPEC_RESTRICT (dest) |= SPEC_RESTRICT (src);
663 SPEC_ADDR (dest) |= SPEC_ADDR (src);
664 SPEC_OCLS (dest) = SPEC_OCLS (src);
665 SPEC_BLEN (dest) |= SPEC_BLEN (src);
666 SPEC_BSTR (dest) |= SPEC_BSTR (src);
667 SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
668 SPEC_ENUM (dest) |= SPEC_ENUM (src);
669 if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
670 SPEC_ARGREG(dest) = SPEC_ARGREG(src);
672 if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
673 SPEC_STRUCT (dest) = SPEC_STRUCT (src);
675 /* these are the only function attributes that will be set
676 in a specifier while parsing */
677 FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
678 FUNC_BANKED(dest) |= FUNC_BANKED(src);
679 FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
680 FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
681 FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
682 FUNC_ISISR(dest) |= FUNC_ISISR(src);
683 FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
684 FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
685 FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
686 FUNC_INTNO(dest) |= FUNC_INTNO(src);
687 FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
688 FUNC_ISINLINE (dest) |= FUNC_ISINLINE (src);
693 /*-------------------------------------------------------------------*/
694 /* genSymName - generates and returns a name used for anonymous vars */
695 /*-------------------------------------------------------------------*/
697 genSymName (int level)
699 static int gCount = 0;
700 static char gname[SDCC_NAME_MAX + 1];
702 SNPRINTF (gname, sizeof(gname), "__%04d%04d", level, gCount++);
706 /*------------------------------------------------------------------*/
707 /* getSpec - returns the specifier part from a declaration chain */
708 /*------------------------------------------------------------------*/
710 getSpec (sym_link * p)
715 while (p && !(IS_SPEC (p)))
721 /*------------------------------------------------------------------*/
722 /* newCharLink() - creates an char type */
723 /*------------------------------------------------------------------*/
729 p = newLink (SPECIFIER);
730 SPEC_NOUN (p) = V_CHAR;
735 /*------------------------------------------------------------------*/
736 /* newFloatLink - a new Float type */
737 /*------------------------------------------------------------------*/
743 p = newLink (SPECIFIER);
744 SPEC_NOUN (p) = V_FLOAT;
749 /*------------------------------------------------------------------*/
750 /* newFixed16x16Link - a new Float type */
751 /*------------------------------------------------------------------*/
757 p = newLink (SPECIFIER);
758 SPEC_NOUN (p) = V_FIXED16X16;
763 /*------------------------------------------------------------------*/
764 /* newLongLink() - new long type */
765 /*------------------------------------------------------------------*/
771 p = newLink (SPECIFIER);
772 SPEC_NOUN (p) = V_INT;
778 /*------------------------------------------------------------------*/
779 /* newIntLink() - creates an int type */
780 /*------------------------------------------------------------------*/
786 p = newLink (SPECIFIER);
787 SPEC_NOUN (p) = V_INT;
792 /*------------------------------------------------------------------*/
793 /* newBoolLink() - creates an bool type */
794 /*------------------------------------------------------------------*/
800 p = newLink (SPECIFIER);
801 SPEC_NOUN (p) = V_BIT;
806 /*------------------------------------------------------------------*/
807 /* getSize - returns size of a type chain in bytes */
808 /*------------------------------------------------------------------*/
810 getSize (sym_link * p)
812 /* if nothing return 0 */
816 { /* if this is the specifier then */
817 switch (SPEC_NOUN (p))
818 { /* depending on the specifier type */
820 return (IS_LONG (p) ? LONGSIZE : INTSIZE);
830 return SPEC_STRUCT (p)->size;
837 return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
843 /* this is a declarator */
844 switch (DCL_TYPE (p))
848 return DCL_ELEM (p) * getSize (p->next);
850 // werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
851 // "can not tell the size of an array[]");
862 return (IFFUNC_BANKED (p) ? GPTRSIZE : FPTRSIZE);
871 /*------------------------------------------------------------------*/
872 /* checkStructFlexArray - check tree behind a struct */
873 /*------------------------------------------------------------------*/
875 checkStructFlexArray (symbol *sym, sym_link *p)
877 /* if nothing return FALSE */
883 /* (nested) struct with flexible array member? */
884 if (IS_STRUCT (p) && SPEC_STRUCT (p)->b_flexArrayMember)
886 werror (W_INVALID_FLEXARRAY);
892 /* this is a declarator */
895 /* flexible array member? */
898 if (!options.std_c99)
899 werror (W_C89_NO_FLEXARRAY);
903 return checkStructFlexArray (sym, p->next);
908 /*------------------------------------------------------------------*/
909 /* bitsForType - returns # of bits required to store this type */
910 /*------------------------------------------------------------------*/
912 bitsForType (sym_link * p)
914 /* if nothing return 0 */
919 { /* if this is the specifier then */
921 switch (SPEC_NOUN (p))
922 { /* depending on the specifier type */
924 return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
926 return FLOATSIZE * 8;
934 return SPEC_STRUCT (p)->size * 8;
941 return SPEC_BLEN (p);
947 /* this is a specifier */
948 switch (DCL_TYPE (p))
951 return DCL_ELEM (p) * getSize (p->next) * 8;
955 return (PTRSIZE * 8);
960 return (FPTRSIZE * 8);
962 return (GPTRSIZE * 8);
969 /*------------------------------------------------------------------*/
970 /* copySymbolChain - copies a symbol chain */
971 /*------------------------------------------------------------------*/
973 copySymbolChain (symbol * src)
980 dest = copySymbol (src);
981 dest->next = copySymbolChain (src->next);
985 /*------------------------------------------------------------------*/
986 /* copySymbol - makes a copy of a symbol */
987 /*------------------------------------------------------------------*/
989 copySymbol (symbol * src)
996 dest = newSymbol (src->name, src->level);
997 memcpy (dest, src, sizeof (symbol));
998 dest->level = src->level;
999 dest->block = src->block;
1000 dest->ival = copyIlist (src->ival);
1001 dest->type = copyLinkChain (src->type);
1002 dest->etype = getSpec (dest->type);
1004 dest->key = src->key;
1005 dest->allocreq = src->allocreq;
1009 /*------------------------------------------------------------------*/
1010 /* reverseSyms - reverses the links for a symbol chain */
1011 /*------------------------------------------------------------------*/
1013 reverseSyms (symbol * sym)
1015 symbol *prev, *curr, *next;
1030 sym->next = (void *) NULL;
1034 /*------------------------------------------------------------------*/
1035 /* reverseLink - reverses the links for a type chain */
1036 /*------------------------------------------------------------------*/
1038 reverseLink (sym_link * type)
1040 sym_link *prev, *curr, *next;
1055 type->next = (void *) NULL;
1059 /*------------------------------------------------------------------*/
1060 /* addSymChain - adds a symbol chain to the symboltable */
1061 /*------------------------------------------------------------------*/
1063 addSymChain (symbol ** symHead)
1065 symbol *sym = *symHead;
1066 symbol *csym = NULL;
1070 for (; sym != NULL; sym = sym->next)
1072 changePointer(sym->type);
1073 checkTypeSanity(sym->etype, sym->name);
1075 if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype)))
1079 /* if this is an array without any dimension
1080 then update the dimension from the initial value */
1081 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1082 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1085 /* if already exists in the symbol table on the same level */
1086 if ((csym = findSymWithLevel (SymbolTab, sym)) &&
1087 csym->level == sym->level)
1089 /* if not formal parameter and not in file scope
1090 then show symbol redefined error
1091 else check if symbols have conpatible types */
1092 if (!sym->_isparm && sym->level > 0)
1096 /* If the previous definition was for an array with incomplete
1097 type, and the new definition has completed the type, update
1098 the original type to match */
1099 if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
1100 && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
1102 if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
1103 DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
1107 /* If only one of the definitions used the "at" keyword, copy */
1108 /* the address to the other. */
1109 if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
1110 && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
1112 SPEC_ABSA (sym->etype) = 1;
1113 SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1115 if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
1116 && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
1118 SPEC_ABSA (csym->etype) = 1;
1119 SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1124 if (csym->ival && sym->ival)
1126 if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1132 /* one definition extern ? */
1133 if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1134 werror (E_EXTERN_MISMATCH, sym->name);
1136 werror (E_DUPLICATE, sym->name);
1137 werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1139 fprintf (stderr, "from type '");
1140 printTypeChain (csym->type, stderr);
1141 if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1142 fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1143 fprintf (stderr, "'\nto type '");
1144 printTypeChain (sym->type, stderr);
1145 if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1146 fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1147 fprintf (stderr, "'\n");
1152 if (csym->ival && !sym->ival)
1153 sym->ival = csym->ival;
1155 if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype))
1157 /* if none of symbols is a compiler defined function
1158 and at least one is not extern
1159 then set the new symbol to non extern */
1160 SPEC_EXTR(sym->etype) = SPEC_EXTR(csym->etype);
1163 /* delete current entry */
1164 deleteSym (SymbolTab, csym, csym->name);
1165 deleteFromSeg(csym);
1167 symPtrPtr = symHead;
1168 while (*symPtrPtr && *symPtrPtr != csym)
1169 symPtrPtr = &(*symPtrPtr)->next;
1170 if (*symPtrPtr == csym)
1171 *symPtrPtr = csym->next;
1175 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1180 /*------------------------------------------------------------------*/
1181 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
1182 /*------------------------------------------------------------------*/
1184 funcInChain (sym_link * lnk)
1195 /*------------------------------------------------------------------*/
1196 /* structElemType - returns the type info of a struct member */
1197 /*------------------------------------------------------------------*/
1199 structElemType (sym_link * stype, value * id)
1201 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1202 sym_link *type, *etype;
1203 sym_link *petype = getSpec (stype);
1207 /* look for the id */
1210 if (strcmp (fields->rname, id->name) == 0)
1212 type = copyLinkChain (fields->type);
1213 etype = getSpec (type);
1214 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1215 SPEC_SCLS (etype) : SPEC_SCLS (petype));
1217 SPEC_CONST (type) |= SPEC_CONST (stype);
1219 DCL_PTR_CONST (type) |= SPEC_CONST (stype);
1222 fields = fields->next;
1226 werror (E_NOT_MEMBER, id->name);
1228 // the show must go on
1229 return newIntLink();
1232 /*------------------------------------------------------------------*/
1233 /* getStructElement - returns element of a tructure definition */
1234 /*------------------------------------------------------------------*/
1236 getStructElement (structdef * sdef, symbol * sym)
1240 for (field = sdef->fields; field; field = field->next)
1241 if (strcmp (field->name, sym->name) == 0)
1244 werror (E_NOT_MEMBER, sym->name);
1246 return sdef->fields;
1249 /*------------------------------------------------------------------*/
1250 /* compStructSize - computes the size of a structure */
1251 /*------------------------------------------------------------------*/
1253 compStructSize (int su, structdef * sdef)
1255 int sum = 0, usum = 0;
1259 /* for the identifiers */
1260 loop = sdef->fields;
1263 /* create the internal name for this variable */
1264 SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1269 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1271 /* if this is a bit field */
1274 /* change it to a unsigned bit */
1275 SPEC_NOUN (loop->etype) = V_BITFIELD;
1276 /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
1277 /* a "plain" int bitfield is unsigned */
1278 if (!loop->etype->select.s.b_signed)
1279 SPEC_USIGN(loop->etype) = 1;
1281 SPEC_BLEN (loop->etype) = loop->bitVar;
1283 if (loop->bitVar == BITVAR_PAD) {
1284 /* A zero length bitfield forces padding */
1285 SPEC_BSTR (loop->etype) = bitOffset;
1286 SPEC_BLEN (loop->etype) = 0;
1291 if (bitOffset == 8) {
1295 /* check if this fit into the remaining */
1296 /* bits of this byte else align it to the */
1297 /* next byte boundary */
1298 if (loop->bitVar <= (8 - bitOffset)) {
1299 /* fits into current byte */
1301 SPEC_BSTR (loop->etype) = bitOffset;
1302 bitOffset += loop->bitVar;
1304 else if (!bitOffset) {
1305 /* does not fit, but is already byte aligned */
1307 SPEC_BSTR (loop->etype) = bitOffset;
1308 bitOffset += loop->bitVar;
1311 if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
1312 /* if PIC16 && enviroment variable is set, then
1313 * tightly pack bitfields, this means that when a
1314 * bitfield goes beyond byte alignment, do not
1315 * automatically start allocatint from next byte,
1316 * but also use the available bits first */
1317 fprintf(stderr, ": packing bitfields in structures\n");
1318 SPEC_BSTR (loop->etype) = bitOffset;
1319 bitOffset += loop->bitVar;
1320 loop->offset = (su == UNION ? sum = 0 : sum);
1322 /* does not fit; need to realign first */
1324 loop->offset = (su == UNION ? sum = 0 : sum);
1326 SPEC_BSTR (loop->etype) = bitOffset;
1327 bitOffset += loop->bitVar;
1330 while (bitOffset>8) {
1337 /* This is a non-bit field. Make sure we are */
1338 /* byte aligned first */
1341 loop->offset = (su == UNION ? sum = 0 : sum);
1345 checkDecl (loop, 1);
1346 sum += getSize (loop->type);
1348 /* search for "flexibel array members" */
1349 /* and do some syntax checks */
1351 && checkStructFlexArray (loop, loop->type))
1353 /* found a "flexible array member" */
1354 sdef->b_flexArrayMember = TRUE;
1355 /* is another struct-member following? */
1357 werror (E_FLEXARRAY_NOTATEND);
1358 /* is it the first struct-member? */
1359 else if (loop == sdef->fields)
1360 werror (E_FLEXARRAY_INEMPTYSTRCT);
1366 /* if union then size = sizeof largest field */
1368 /* For UNION, round up after each field */
1369 sum += ((bitOffset+7)/8);
1370 usum = max (usum, sum);
1375 /* For STRUCT, round up after all fields processed */
1377 sum += ((bitOffset+7)/8);
1379 return (su == UNION ? usum : sum);
1382 /*-------------------------------------------------------------------*/
1383 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1384 /* an enclosing struct/union */
1385 /*-------------------------------------------------------------------*/
1387 promoteAnonStructs (int su, structdef * sdef)
1396 tofield = &sdef->fields;
1397 field = sdef->fields;
1400 nextfield = field->next;
1401 if (!*field->name && IS_STRUCT (field->type))
1403 /* Found an anonymous struct/union. Replace it */
1404 /* with the fields it contains and adjust all */
1407 base = field->offset;
1408 subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1410 continue; /* just in case it's empty */
1412 *tofield = subfield;
1415 /* check for field name conflicts resulting from promotion */
1416 dupfield = sdef->fields;
1417 while (dupfield && dupfield != subfield)
1419 if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1421 werrorfl (subfield->fileDef, subfield->lineDef,
1423 su==STRUCT ? "struct" : "union",
1425 werrorfl (dupfield->fileDef, dupfield->lineDef,
1428 dupfield = dupfield->next;
1431 subfield->offset += base;
1433 subfield = subfield->next;
1437 subfield->next = nextfield;
1438 tofield = &subfield->next;
1441 tofield = &field->next;
1447 /*------------------------------------------------------------------*/
1448 /* checkSClass - check the storage class specification */
1449 /*------------------------------------------------------------------*/
1451 checkSClass (symbol * sym, int isProto)
1455 if (getenv("DEBUG_SANITY")) {
1456 fprintf (stderr, "checkSClass: %s \n", sym->name);
1459 /* type is literal can happen for enums change to auto */
1460 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1461 SPEC_SCLS (sym->etype) = S_AUTO;
1463 /* if sfr or sbit then must also be volatile */
1464 if (SPEC_SCLS (sym->etype) == S_SBIT ||
1465 SPEC_SCLS (sym->etype) == S_SFR)
1467 SPEC_VOLATILE (sym->etype) = 1;
1470 /* make sure restrict is only used with pointers */
1471 if (SPEC_RESTRICT (sym->etype))
1473 werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1474 SPEC_RESTRICT (sym->etype) = 0;
1479 if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !IS_PTR (t))
1481 werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1482 DCL_PTR_RESTRICT (t) = 0;
1488 /* if absolute address given then it mark it as
1489 volatile -- except in the PIC port */
1491 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1492 /* The PIC port uses a different peep hole optimizer based on "pCode" */
1493 if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1496 if (IS_ABSOLUTE (sym->etype))
1497 SPEC_VOLATILE (sym->etype) = 1;
1499 if (TARGET_IS_MCS51 &&
1500 IS_ABSOLUTE (sym->etype) &&
1501 SPEC_SCLS (sym->etype) == S_SFR)
1506 if (SPEC_NOUN (sym->etype) == V_CHAR)
1508 else if (SPEC_LONG (sym->etype) == 0)
1513 addr = SPEC_ADDR (sym->etype);
1514 for (n=0; n<size; n+=8)
1515 if (((addr >> n) & 0xFF) < 0x80)
1516 werror (W_SFR_ABSRANGE, sym->name);
1519 /* If code memory is read only, then pointers to code memory */
1520 /* implicitly point to constants -- make this explicit */
1522 while (t && t->next) {
1523 if (IS_CODEPTR(t) && port->mem.code_ro) {
1524 if (IS_SPEC(t->next)) {
1525 SPEC_CONST (t->next) = 1;
1527 DCL_PTR_CONST (t->next) = 1;
1533 /* global variables declared const put into code */
1534 /* if no other storage class specified */
1535 if (sym->level == 0 &&
1536 SPEC_SCLS(sym->etype) == S_FIXED &&
1537 !IS_FUNC(sym->type)) {
1538 /* find the first non-array link */
1542 if (IS_CONSTANT (t)) {
1543 SPEC_SCLS (sym->etype) = S_CODE;
1547 /* global variable in code space is a constant */
1548 if (sym->level == 0 &&
1549 SPEC_SCLS (sym->etype) == S_CODE &&
1550 port->mem.code_ro) {
1551 /* find the first non-array link */
1558 DCL_PTR_CONST (t) = 1;
1562 /* if bit variable then no storage class can be */
1563 /* specified since bit is already a storage */
1564 if (IS_BITVAR (sym->etype) &&
1565 (SPEC_SCLS (sym->etype) != S_FIXED &&
1566 SPEC_SCLS (sym->etype) != S_SBIT &&
1567 SPEC_SCLS (sym->etype) != S_BIT)
1570 werror (E_BITVAR_STORAGE, sym->name);
1571 SPEC_SCLS (sym->etype) = S_FIXED;
1574 /* extern variables cannot be initialized */
1575 if (IS_EXTERN (sym->etype) && sym->ival)
1577 werror (E_EXTERN_INIT, sym->name);
1581 /* if this is an automatic symbol */
1582 if (sym->level && (options.stackAuto || reentrant)) {
1583 if (SPEC_SCLS (sym->etype) != S_BIT) {
1584 if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1585 SPEC_SCLS (sym->etype) == S_FIXED ||
1586 SPEC_SCLS (sym->etype) == S_REGISTER ||
1587 SPEC_SCLS (sym->etype) == S_STACK ||
1588 SPEC_SCLS (sym->etype) == S_XSTACK)) {
1589 SPEC_SCLS (sym->etype) = S_AUTO;
1591 /* storage class may only be specified for statics */
1592 if (!IS_STATIC(sym->etype)) {
1593 werror (E_AUTO_ASSUMED, sym->name);
1599 /* automatic symbols cannot be given */
1600 /* an absolute address ignore it */
1601 if (sym->level && !IS_STATIC(sym->etype) &&
1602 SPEC_ABSA (sym->etype) &&
1603 (options.stackAuto || reentrant))
1605 werror (E_AUTO_ABSA, sym->name);
1606 SPEC_ABSA (sym->etype) = 0;
1609 /* arrays & pointers cannot be defined for bits */
1610 /* SBITS or SFRs or BIT */
1611 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1612 !IS_FUNCPTR (sym->type) &&
1613 (SPEC_NOUN (sym->etype) == V_BIT ||
1614 SPEC_NOUN (sym->etype) == V_SBIT ||
1615 SPEC_NOUN (sym->etype) == V_BITFIELD ||
1616 SPEC_SCLS (sym->etype) == S_SFR))
1617 werror (E_BIT_ARRAY, sym->name);
1619 /* if this is a bit|sbit then set length & start */
1620 if (SPEC_NOUN (sym->etype) == V_BIT ||
1621 SPEC_NOUN (sym->etype) == V_SBIT)
1623 SPEC_BLEN (sym->etype) = 1;
1624 SPEC_BSTR (sym->etype) = 0;
1628 /* variables declared in CODE space must have */
1629 /* initializers if not an extern */
1630 if (SPEC_SCLS (sym->etype) == S_CODE &&
1631 sym->ival == NULL &&
1634 port->mem.code_ro &&
1635 !IS_EXTERN (sym->etype) &&
1636 !SPEC_ABSA (sym->etype) &&
1637 !funcInChain (sym->type))
1638 werror (E_CODE_NO_INIT, sym->name);
1641 /* if parameter or local variable then change */
1642 /* the storage class to reflect where the var will go */
1643 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
1644 && !IS_STATIC(sym->etype)
1647 if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1649 SPEC_SCLS (sym->etype) = (options.useXstack ?
1650 S_XSTACK : S_STACK);
1654 /* hack-o-matic! I see no reason why the useXstack option should ever
1655 * control this allocation, but the code was originally that way, and
1656 * changing it for non-390 ports breaks the compiler badly.
1658 bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ?
1659 1 : options.useXstack;
1660 SPEC_SCLS (sym->etype) = (useXdata ?
1666 /*------------------------------------------------------------------*/
1667 /* changePointer - change pointer to functions */
1668 /*------------------------------------------------------------------*/
1670 changePointer (sym_link * p)
1673 /* go thru the chain of declarations */
1674 /* if we find a pointer to a function */
1675 /* change it to a ptr to code area */
1676 /* unless the function is banked. */
1677 for (; p; p = p->next)
1679 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1680 DCL_TYPE (p) = port->unqualified_pointer;
1681 if (IS_PTR (p) && IS_FUNC (p->next))
1682 if (!IFFUNC_BANKED(p->next))
1683 DCL_TYPE (p) = CPOINTER;
1687 /*------------------------------------------------------------------*/
1688 /* checkDecl - does semantic validation of a declaration */
1689 /*------------------------------------------------------------------*/
1691 checkDecl (symbol * sym, int isProto)
1694 checkSClass (sym, isProto); /* check the storage class */
1695 changePointer (sym->type); /* change pointers if required */
1697 /* if this is an array without any dimension
1698 then update the dimension from the initial value */
1699 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1700 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1705 /*------------------------------------------------------------------*/
1706 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1707 /*------------------------------------------------------------------*/
1709 copyLinkChain (sym_link * p)
1711 sym_link *head, *curr, *loop;
1713 /* note: v_struct and v_struct->fields are not copied! */
1715 head = loop = (curr ? newLink (p->class) : (void *) NULL);
1718 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1719 loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1727 /*------------------------------------------------------------------*/
1728 /* cleanUpBlock - cleansup the symbol table specified for all the */
1729 /* symbols in the given block */
1730 /*------------------------------------------------------------------*/
1732 cleanUpBlock (bucket ** table, int block)
1737 /* go thru the entire table */
1738 for (i = 0; i < 256; i++)
1740 for (chain = table[i]; chain; chain = chain->next)
1742 if (chain->block >= block)
1744 deleteSym (table, chain->sym, chain->name);
1750 /*------------------------------------------------------------------*/
1751 /* cleanUpLevel - cleansup the symbol table specified for all the */
1752 /* symbols in the given level */
1753 /*------------------------------------------------------------------*/
1755 cleanUpLevel (bucket ** table, int level)
1760 /* go thru the entire table */
1761 for (i = 0; i < 256; i++)
1763 for (chain = table[i]; chain; chain = chain->next)
1765 if (chain->level >= level)
1767 deleteSym (table, chain->sym, chain->name);
1773 /*------------------------------------------------------------------*/
1774 /* computeTypeOr - computes the resultant type from two types */
1775 /*------------------------------------------------------------------*/
1777 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1780 assert ( (IS_CHAR (etype1) || IS_BIT (etype1))
1781 && (IS_CHAR (etype2) || IS_BIT (etype2)));
1783 if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1785 SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1789 if (SPEC_USIGN (etype1))
1791 if ( IS_LITERAL (etype2)
1792 && floatFromVal (valFromType (etype2)) >= 0)
1793 SPEC_USIGN (reType) = 1;
1796 /* promote to int */
1797 SPEC_USIGN (reType) = 0;
1798 SPEC_NOUN (reType) = V_INT;
1801 else /* etype1 signed */
1803 if ( IS_LITERAL (etype2)
1804 && floatFromVal (valFromType (etype2)) <= 127)
1805 SPEC_USIGN (reType) = 0;
1808 /* promote to int */
1809 SPEC_USIGN (reType) = 0;
1810 SPEC_NOUN (reType) = V_INT;
1814 if (SPEC_USIGN (etype2))
1816 if ( IS_LITERAL (etype1)
1817 && floatFromVal (valFromType (etype1)) >= 0)
1818 SPEC_USIGN (reType) = 1;
1821 /* promote to int */
1822 SPEC_USIGN (reType) = 0;
1823 SPEC_NOUN (reType) = V_INT;
1826 else /* etype2 signed */
1828 if ( IS_LITERAL (etype1)
1829 && floatFromVal (valFromType (etype1)) <= 127)
1830 SPEC_USIGN (reType) = 0;
1833 /* promote to int */
1834 SPEC_USIGN (reType) = 0;
1835 SPEC_NOUN (reType) = V_INT;
1841 /*------------------------------------------------------------------*/
1842 /* computeType - computes the resultant type from two types */
1843 /*------------------------------------------------------------------*/
1845 computeType (sym_link * type1, sym_link * type2,
1846 RESULT_TYPE resultType, int op)
1850 sym_link *etype1 = getSpec (type1);
1853 etype2 = type2 ? getSpec (type2) : type1;
1855 /* if one of them is a float then result is a float */
1856 /* here we assume that the types passed are okay */
1857 /* and can be cast to one another */
1858 /* which ever is greater in size */
1859 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1860 rType = newFloatLink ();
1861 /* if both are fixed16x16 then result is float */
1862 else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
1863 rType = newFixed16x16Link();
1864 else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
1865 rType = newFloatLink ();
1866 else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
1867 rType = newFloatLink ();
1869 /* if both are bitvars choose the larger one */
1870 else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1871 rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1872 copyLinkChain (type1) : copyLinkChain (type2);
1874 /* if only one of them is a bit variable then the other one prevails */
1875 else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1877 rType = copyLinkChain (type2);
1878 /* bitfield can have up to 16 bits */
1879 if (getSize (etype1) > 1)
1880 SPEC_NOUN (getSpec (rType)) = V_INT;
1882 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1884 rType = copyLinkChain (type1);
1885 /* bitfield can have up to 16 bits */
1886 if (getSize (etype2) > 1)
1887 SPEC_NOUN (getSpec (rType)) = V_INT;
1889 /* if one of them is a pointer or array then that
1891 else if (IS_PTR (type1) || IS_ARRAY (type1))
1892 rType = copyLinkChain (type1);
1893 else if (IS_PTR (type2) || IS_ARRAY (type2))
1894 rType = copyLinkChain (type2);
1895 else if (getSize (type1) > getSize (type2))
1896 rType = copyLinkChain (type1);
1898 rType = copyLinkChain (type2);
1900 reType = getSpec (rType);
1902 /* avoid conflicting types */
1903 reType->select.s.b_signed = 0;
1905 /* if result is a literal then make not so */
1906 if (IS_LITERAL (reType))
1907 SPEC_SCLS (reType) = S_REGISTER;
1911 case RESULT_TYPE_IFX:
1915 case RESULT_TYPE_BIT:
1918 SPEC_NOUN (reType) = V_BIT;
1922 case RESULT_TYPE_CHAR:
1923 if (IS_BITVAR (reType))
1925 SPEC_NOUN (reType) = V_CHAR;
1926 SPEC_SCLS (reType) = 0;
1927 SPEC_USIGN (reType) = 0;
1931 case RESULT_TYPE_INT:
1932 case RESULT_TYPE_NONE:
1933 case RESULT_TYPE_OTHER:
1934 if (IS_BIT (reType))
1936 SPEC_NOUN (reType) = V_CHAR;
1937 SPEC_SCLS (reType) = 0;
1938 SPEC_USIGN (reType) = 0;
1941 else if (IS_BITFIELD (reType))
1943 /* could be smarter, but it depends on the op */
1944 /* this is for the worst case: a multiplication of 4 * 4 bit */
1945 SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1946 SPEC_SCLS (reType) = 0;
1947 SPEC_USIGN (reType) = 0;
1950 else if (IS_CHAR (reType))
1952 /* promotion of some special cases */
1957 return computeTypeOr (etype1, etype2, reType);
1959 if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1961 SPEC_USIGN (reType) = 1;
1966 SPEC_NOUN (reType) = V_INT;
1967 SPEC_USIGN (reType) = 0;
1970 /* if both are unsigned char then no promotion required */
1971 if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
1973 SPEC_NOUN (reType) = V_INT;
1974 SPEC_USIGN (reType) = 0;
1987 /* SDCC's sign promotion:
1988 - if one or both operands are unsigned, the resultant type will be unsigned
1989 (except char, see below)
1990 - if an operand is promoted to a larger type (char -> int, int -> long),
1991 the larger type will be signed
1993 SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1994 much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1995 the standard. The standard demands, that the result has to be the same
1996 "as if" the promotion would have been performed:
1998 - if the result of an operation with two char's is promoted to a
1999 larger type, the result will be signed.
2001 More sophisticated are these:
2002 - if the result of an operation with two char's is a char again,
2003 the result will only then be unsigned, if both operands are
2004 unsigned. In all other cases the result will be signed.
2006 This seems to be contradictionary to the first two rules, but it makes
2007 real sense (all types are char's):
2009 A signed char can be negative; this must be preserved in the result
2012 Only if both operands are unsigned it's safe to make the result
2013 unsigned; this helps to avoid overflow:
2016 - ToDo: document '|', '^' and '&'
2018 Homework: - why is (200 * 200 < 0) true?
2019 - why is { char l = 200, r = 200; (r * l > 0) } true?
2022 if (!IS_FLOAT (reType)
2023 && ( (SPEC_USIGN (etype1)
2024 /* if this operand is promoted to a larger type,
2025 then it will be promoted to a signed type */
2026 && !(bitsForType (etype1) < bitsForType (reType))
2027 /* char require special handling */
2028 && !IS_CHAR (etype1))
2029 || /* same for 2nd operand */
2030 (SPEC_USIGN (etype2)
2031 && !(bitsForType (etype2) < bitsForType (reType))
2032 && !IS_CHAR (etype2))
2033 || /* if both are 'unsigned char' and not promoted
2034 let the result be unsigned too */
2035 ( SPEC_USIGN (etype1)
2036 && SPEC_USIGN (etype2)
2039 && IS_CHAR (reType))))
2040 SPEC_USIGN (reType) = 1;
2042 SPEC_USIGN (reType) = 0;
2047 /*--------------------------------------------------------------------*/
2048 /* compareType - will do type check return 1 if match, -1 if castable */
2049 /*--------------------------------------------------------------------*/
2051 compareType (sym_link * dest, sym_link * src)
2062 /* if dest is a declarator then */
2067 /* banked function pointer */
2068 if (IS_GENPTR (dest) && IS_GENPTR (src))
2070 if (IS_FUNC (src->next) && IS_VOID(dest->next))
2072 if (IS_FUNC (dest->next) && IS_VOID(src->next))
2074 return compareType (dest->next, src->next);
2077 if (DCL_TYPE (src) == DCL_TYPE (dest))
2081 //checkFunction(src,dest);
2083 return compareType (dest->next, src->next);
2085 if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
2090 (IS_GENPTR (dest) ||
2091 ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
2094 if (compareType (dest->next, src->next))
2099 if (IS_PTR (dest) && IS_ARRAY (src))
2101 value *val=aggregateToPointer (valFromType(src));
2102 int res=compareType (dest, val->type);
2103 Safe_free(val->type);
2107 if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2108 return compareType (dest->next, src);
2111 else if (IS_PTR (dest) && IS_INTEGRAL (src))
2117 if (IS_PTR (src) && IS_VOID (dest))
2120 /* if one is a specifier and the other is not */
2121 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2122 (IS_SPEC (dest) && !IS_SPEC (src)))
2125 /* if one of them is a void then ok */
2126 if (SPEC_NOUN (dest) == V_VOID &&
2127 SPEC_NOUN (src) != V_VOID)
2130 if (SPEC_NOUN (dest) != V_VOID &&
2131 SPEC_NOUN (src) == V_VOID)
2134 /* if they are both bitfields then if the lengths
2135 and starts don't match */
2136 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2137 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2138 SPEC_BSTR (dest) != SPEC_BSTR (src)))
2141 /* it is a specifier */
2142 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2144 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
2145 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2147 bitsForType (dest) == bitsForType (src))
2148 instead of the next two lines, but the regression tests fail with
2149 them; I guess it's a problem with replaceCheaperOp */
2150 getSize (dest) == getSize (src) &&
2151 (IS_BIT (dest) == IS_BIT (src)))
2153 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2158 else if (IS_STRUCT (dest))
2160 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2165 if (SPEC_LONG (dest) != SPEC_LONG (src))
2168 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2174 /*--------------------------------------------------------------------*/
2175 /* compareTypeExact - will do type check return 1 if match exactly */
2176 /*--------------------------------------------------------------------*/
2178 compareTypeExact (sym_link * dest, sym_link * src, int level)
2180 STORAGE_CLASS srcScls, destScls;
2191 /* if dest is a declarator then */
2196 if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2197 if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2199 if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2201 if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2205 value *exargs, *acargs, *checkValue;
2207 /* verify function return type */
2208 if (!compareTypeExact (dest->next, src->next, -1))
2210 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2212 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2214 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2217 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2221 /* compare expected args with actual args */
2222 exargs = FUNC_ARGS(dest);
2223 acargs = FUNC_ARGS(src);
2225 /* for all the expected args do */
2226 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2228 //checkTypeSanity(acargs->etype, acargs->name);
2230 if (IS_AGGREGATE (acargs->type))
2232 checkValue = copyValue (acargs);
2233 aggregateToPointer (checkValue);
2236 checkValue = acargs;
2239 if (!compareTypeExact (exargs->type, checkValue->type, -1))
2244 /* if one them ended we have a problem */
2245 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2246 (!exargs && acargs && !IS_VOID (acargs->type)))
2250 return compareTypeExact (dest->next, src->next, level);
2257 /* if one is a specifier and the other is not */
2258 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2259 (IS_SPEC (dest) && !IS_SPEC (src)))
2262 /* if one of them is a void then ok */
2263 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2266 /* if they are both bitfields then if the lengths
2267 and starts don't match */
2268 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2269 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2270 SPEC_BSTR (dest) != SPEC_BSTR (src)))
2273 if (IS_INTEGRAL (dest))
2275 /* signedness must match */
2276 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2278 /* size must match */
2279 if (SPEC_LONG (dest) != SPEC_LONG (src))
2281 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2285 if (IS_STRUCT (dest))
2287 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2291 if (SPEC_CONST (dest) != SPEC_CONST (src))
2293 if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2295 if (SPEC_STAT (dest) != SPEC_STAT (src))
2297 if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2299 if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2302 destScls = SPEC_SCLS (dest);
2303 srcScls = SPEC_SCLS (src);
2305 /* Compensate for const to const code change in checkSClass() */
2306 if (!level & port->mem.code_ro && SPEC_CONST (dest))
2308 if (srcScls == S_CODE && destScls == S_FIXED)
2310 if (destScls == S_CODE && srcScls == S_FIXED)
2314 /* compensate for allocGlobal() */
2315 if ((srcScls == S_FIXED || srcScls == S_AUTO)
2316 && port->mem.default_globl_map == xdata
2320 if (level>0 && !SPEC_STAT (dest))
2322 /* Compensate for hack-o-matic in checkSClass() */
2323 if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2325 if (destScls == S_FIXED)
2326 destScls = (options.useXstack ? S_XSTACK : S_STACK);
2327 if (srcScls == S_FIXED)
2328 srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2330 else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2332 if (destScls == S_FIXED)
2334 if (srcScls == S_FIXED)
2339 if (srcScls != destScls)
2342 printf ("level = %d\n", level);
2343 printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2344 SPEC_SCLS (src), SPEC_SCLS (dest));
2345 printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2353 /*------------------------------------------------------------------*/
2354 /* inCalleeSaveList - return 1 if found in callee save list */
2355 /*------------------------------------------------------------------*/
2357 calleeCmp(void *p1, void *p2)
2359 return (strcmp((char *)p1, (char *)(p2)) == 0);
2363 inCalleeSaveList(char *s)
2365 if (options.all_callee_saves)
2367 return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2370 /*-----------------------------------------------------------------*/
2371 /* aggregateToPointer: change an aggregate type function */
2372 /* argument to a pointer to that type. */
2373 /*-----------------------------------------------------------------*/
2375 aggregateToPointer (value * val)
2377 if (IS_AGGREGATE (val->type))
2379 /* if this is a structure */
2380 /* then we need to add a new link */
2381 if (IS_STRUCT (val->type))
2383 /* first lets add DECLARATOR type */
2384 sym_link *p = val->type;
2386 werror (W_STRUCT_AS_ARG, val->name);
2387 val->type = newLink (DECLARATOR);
2388 val->type->next = p;
2391 /* change to a pointer depending on the */
2392 /* storage class specified */
2393 switch (SPEC_SCLS (val->etype))
2396 DCL_TYPE (val->type) = IPOINTER;
2399 DCL_TYPE (val->type) = PPOINTER;
2402 if (SPEC_OCLS(val->etype)) {
2403 DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2405 // this happens for (external) function parameters
2406 DCL_TYPE (val->type) = port->unqualified_pointer;
2412 DCL_TYPE (val->type) = POINTER;
2415 DCL_TYPE (val->type) = CPOINTER;
2418 DCL_TYPE (val->type) = FPOINTER;
2421 DCL_TYPE (val->type) = EEPPOINTER;
2424 DCL_TYPE (val->type) = port->unqualified_pointer;
2427 /* is there is a symbol associated then */
2428 /* change the type of the symbol as well */
2431 val->sym->type = copyLinkChain (val->type);
2432 val->sym->etype = getSpec (val->sym->type);
2437 /*------------------------------------------------------------------*/
2438 /* checkFunction - does all kinds of check on a function */
2439 /*------------------------------------------------------------------*/
2441 checkFunction (symbol * sym, symbol *csym)
2443 value *exargs, *acargs;
2447 if (getenv("DEBUG_SANITY")) {
2448 fprintf (stderr, "checkFunction: %s ", sym->name);
2451 if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2453 werror(E_SYNTAX_ERROR, sym->name);
2457 /* move inline specifier from return type to function attributes */
2458 if (IS_INLINE (sym->etype))
2460 SPEC_INLINE (sym->etype) = 0;
2461 FUNC_ISINLINE (sym->type) = 1;
2464 /* make sure the type is complete and sane */
2465 checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2467 /* if not type then some kind of error */
2471 /* if the function has no type then make it return int */
2472 if (!sym->type->next)
2473 sym->type->next = sym->etype = newIntLink ();
2475 /* function cannot return aggregate */
2476 if (IS_AGGREGATE (sym->type->next))
2478 werror (E_FUNC_AGGR, sym->name);
2482 /* check if this function is defined as calleeSaves
2483 then mark it as such */
2484 FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2486 /* if interrupt service routine */
2487 /* then it cannot have arguments */
2488 if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2490 if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2491 werror (E_INT_ARGS, sym->name);
2492 FUNC_ARGS(sym->type)=NULL;
2496 if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2498 werror (E_SHADOWREGS_NO_ISR, sym->name);
2501 for (argCnt=1, acargs = FUNC_ARGS(sym->type);
2503 acargs=acargs->next, argCnt++) {
2505 // this can happen for reentrant functions
2506 werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2507 // the show must go on: synthesize a name and symbol
2508 SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2509 acargs->sym = newSymbol (acargs->name, 1);
2510 SPEC_OCLS (acargs->etype) = istack;
2511 acargs->sym->type = copyLinkChain (acargs->type);
2512 acargs->sym->etype = getSpec (acargs->sym->type);
2513 acargs->sym->_isparm = 1;
2514 strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2515 } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) {
2517 werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2522 /*JCF: Mark the register bank as used*/
2523 RegBankUsed[FUNC_REGBANK (sym->type)] = 1;
2525 if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2526 return 1; /* not defined nothing more to check */
2528 /* check if body already present */
2529 if (csym && IFFUNC_HASBODY(csym->type))
2531 werror (E_FUNC_BODY, sym->name);
2535 /* check the return value type */
2536 if (compareType (csym->type, sym->type) <= 0)
2538 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2539 printFromToType(csym->type, sym->type);
2543 if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2545 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2548 /* I don't think this is necessary for interrupts. An isr is a */
2549 /* root in the calling tree. */
2550 if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2551 (!FUNC_ISISR (sym->type)))
2553 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2556 if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2558 werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2561 /* Really, reentrant should match regardless of argCnt, but */
2562 /* this breaks some existing code (the fp lib functions). If */
2563 /* the first argument is always passed the same way, this */
2564 /* lax checking is ok (but may not be true for in future ports) */
2565 if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2568 //printf("argCnt = %d\n",argCnt);
2569 werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2572 if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2574 werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2577 if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2579 werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2583 /* compare expected args with actual args */
2584 exargs = FUNC_ARGS(csym->type);
2585 acargs = FUNC_ARGS(sym->type);
2587 /* for all the expected args do */
2590 exargs = exargs->next, acargs = acargs->next, argCnt++)
2592 if (getenv("DEBUG_SANITY")) {
2593 fprintf (stderr, "checkFunction: %s ", exargs->name);
2595 /* make sure the type is complete and sane */
2596 checkTypeSanity(exargs->etype, exargs->name);
2598 /* If the actual argument is an array, any prototype
2599 * will have modified it to a pointer. Duplicate that
2602 if (IS_AGGREGATE (acargs->type))
2604 checkValue = copyValue (acargs);
2605 aggregateToPointer (checkValue);
2609 checkValue = acargs;
2612 if (compareType (exargs->type, checkValue->type) <= 0)
2614 werror (E_ARG_TYPE, argCnt);
2615 printFromToType(exargs->type, checkValue->type);
2620 /* if one them ended we have a problem */
2621 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2622 (!exargs && acargs && !IS_VOID (acargs->type)))
2623 werror (E_ARG_COUNT);
2625 /* replace with this defition */
2626 sym->cdef = csym->cdef;
2627 deleteSym (SymbolTab, csym, csym->name);
2628 deleteFromSeg(csym);
2629 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2630 if (IS_EXTERN (csym->etype) && !
2631 IS_EXTERN (sym->etype))
2633 addSet (&publics, sym);
2638 /*------------------------------------------------------------------*/
2639 /* cdbStructBlock - calls struct printing for a blcks */
2640 /*------------------------------------------------------------------*/
2641 void cdbStructBlock (int block)
2644 bucket **table = StructTab;
2647 /* go thru the entire table */
2648 for (i = 0; i < 256; i++)
2650 for (chain = table[i]; chain; chain = chain->next)
2652 if (chain->block >= block)
2655 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2661 /*-----------------------------------------------------------------*/
2662 /* processFuncPtrArgs - does some processing with args of func ptrs*/
2663 /*-----------------------------------------------------------------*/
2665 processFuncPtrArgs (sym_link * funcType)
2667 value *val = FUNC_ARGS(funcType);
2669 /* if it is void then remove parameters */
2670 if (val && IS_VOID (val->type))
2672 FUNC_ARGS(funcType) = NULL;
2677 /*-----------------------------------------------------------------*/
2678 /* processFuncArgs - does some processing with function args */
2679 /*-----------------------------------------------------------------*/
2681 processFuncArgs (symbol * func)
2685 sym_link *funcType=func->type;
2687 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2688 fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2690 /* find the function declaration within the type */
2691 while (funcType && !IS_FUNC(funcType))
2692 funcType=funcType->next;
2694 /* if this function has variable argument list */
2695 /* then make the function a reentrant one */
2696 if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2697 FUNC_ISREENT(funcType)=1;
2699 /* check if this function is defined as calleeSaves
2700 then mark it as such */
2701 FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2703 /* loop thru all the arguments */
2704 val = FUNC_ARGS(funcType);
2706 /* if it is void then remove parameters */
2707 if (val && IS_VOID (val->type))
2709 FUNC_ARGS(funcType) = NULL;
2713 /* reset regparm for the port */
2714 (*port->reset_regparms) ();
2716 /* if any of the arguments is an aggregate */
2717 /* change it to pointer to the same type */
2721 char buffer[SDCC_NAME_MAX+1];
2723 SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2724 checkTypeSanity (val->etype, buffer);
2726 /* mark it as a register parameter if
2727 the function does not have VA_ARG
2728 and as port dictates */
2729 if (!IFFUNC_HASVARARGS(funcType) &&
2730 (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
2732 SPEC_REGPARM (val->etype) = 1;
2733 SPEC_ARGREG(val->etype) = argreg;
2734 } else if (IFFUNC_ISREENT(funcType)) {
2735 FUNC_HASSTACKPARM(funcType) = 1;
2738 if (IS_AGGREGATE (val->type))
2740 aggregateToPointer (val);
2747 /* if this is an internal generated function call */
2749 /* ignore --stack-auto for this one, we don't know how it is compiled */
2750 /* simply trust on --int-long-reent or --float-reent */
2751 if (IFFUNC_ISREENT(funcType)) {
2755 /* if this function is reentrant or */
2756 /* automatics r 2b stacked then nothing */
2757 if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2761 val = FUNC_ARGS(funcType);
2766 /* if a symbolname is not given */
2767 /* synthesize a variable name */
2770 SNPRINTF (val->name, sizeof(val->name),
2771 "_%s_PARM_%d", func->name, pNum++);
2772 val->sym = newSymbol (val->name, 1);
2773 if (SPEC_SCLS(val->etype) == S_BIT)
2774 SPEC_OCLS (val->etype) = bit;
2776 SPEC_OCLS (val->etype) = port->mem.default_local_map;
2777 val->sym->type = copyLinkChain (val->type);
2778 val->sym->etype = getSpec (val->sym->type);
2779 val->sym->_isparm = 1;
2780 strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2782 /* ?? static functions shouldn't imply static parameters - EEP */
2783 if (IS_SPEC(func->etype)) {
2784 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2785 SPEC_STAT (func->etype);
2788 addSymChain (&val->sym);
2791 else /* symbol name given create synth name */
2794 SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2795 strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2796 val->sym->_isparm = 1;
2797 if (SPEC_SCLS(val->etype) == S_BIT)
2798 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2800 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2801 port->mem.default_local_map;
2804 /* ?? static functions shouldn't imply static parameters - EEP */
2805 if (IS_SPEC(func->etype)) {
2806 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2807 SPEC_STAT (func->etype);
2811 if (SPEC_OCLS (val->sym->etype) == pdata)
2812 val->sym->iaccess = 1;
2813 if (!isinSet(operKeyReset, val->sym)) {
2814 addSet (&operKeyReset, val->sym);
2815 applyToSet (operKeyReset, resetParmKey);
2821 /*-----------------------------------------------------------------*/
2822 /* isSymbolEqual - compares two symbols return 1 if they match */
2823 /*-----------------------------------------------------------------*/
2825 isSymbolEqual (symbol * dest, symbol * src)
2827 /* if pointers match then equal */
2831 /* if one of them is null then don't match */
2835 /* if both of them have rname match on rname */
2836 if (dest->rname[0] && src->rname[0])
2837 return (!strcmp (dest->rname, src->rname));
2839 /* otherwise match on name */
2840 return (!strcmp (dest->name, src->name));
2843 void PT(sym_link *type)
2845 printTypeChain(type,0);
2847 /*-----------------------------------------------------------------*/
2848 /* printTypeChain - prints the type chain in human readable form */
2849 /*-----------------------------------------------------------------*/
2851 printTypeChain (sym_link * start, FILE * of)
2862 dbuf_init (&dbuf, 1024);
2863 dbuf_printTypeChain (start, &dbuf);
2864 dbuf_write_and_destroy (&dbuf, of);
2871 dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
2874 sym_link * type, * search;
2878 dbuf_append_str (dbuf, "void");
2882 /* Print the chain as it is written in the source: */
2883 /* start with the last entry. */
2884 /* However, the storage class at the end of the */
2885 /* chain reall applies to the first in the chain! */
2887 for (type = start; type && type->next; type = type->next)
2890 scls=SPEC_SCLS(type);
2898 case S_DATA: dbuf_append_str (dbuf, "data-"); break;
2899 case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break;
2900 case S_SFR: dbuf_append_str (dbuf, "sfr-"); break;
2901 case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break;
2902 case S_CODE: dbuf_append_str (dbuf, "code-"); break;
2903 case S_IDATA: dbuf_append_str (dbuf, "idata-"); break;
2904 case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break;
2905 case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break;
2906 case S_STACK: dbuf_append_str (dbuf, "stack-"); break;
2907 case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break;
2908 case S_BIT: dbuf_append_str (dbuf, "bit-"); break;
2909 case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break;
2916 if (!IS_FUNC(type)) {
2917 if (DCL_PTR_VOLATILE (type)) {
2918 dbuf_append_str (dbuf, "volatile-");
2920 if (DCL_PTR_CONST (type)) {
2921 dbuf_append_str (dbuf, "const-");
2923 if (DCL_PTR_RESTRICT (type)) {
2924 dbuf_append_str (dbuf, "restrict-");
2927 switch (DCL_TYPE (type))
2930 dbuf_printf (dbuf, "function %s %s",
2931 (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2932 (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2933 dbuf_append_str (dbuf, "( ");
2934 for (args = FUNC_ARGS(type);
2937 dbuf_printTypeChain(args->type, dbuf);
2939 dbuf_append_str (dbuf, ", ");
2941 dbuf_append_str (dbuf, ") ");
2944 dbuf_append_str (dbuf, "generic* ");
2947 dbuf_append_str (dbuf, "code* ");
2950 dbuf_append_str (dbuf, "xdata* ");
2953 dbuf_append_str (dbuf, "eeprom* ");
2956 dbuf_append_str (dbuf, "near* ");
2959 dbuf_append_str (dbuf, "idata* ");
2962 dbuf_append_str (dbuf, "pdata* ");
2965 dbuf_append_str (dbuf, "unknown* ");
2968 if (DCL_ELEM(type)) {
2969 dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type));
2971 dbuf_append_str (dbuf, "[] ");
2978 if (SPEC_VOLATILE (type))
2979 dbuf_append_str (dbuf, "volatile-");
2980 if (SPEC_CONST (type))
2981 dbuf_append_str (dbuf, "const-");
2982 if (SPEC_USIGN (type))
2983 dbuf_append_str (dbuf, "unsigned-");
2984 switch (SPEC_NOUN (type))
2988 dbuf_append_str (dbuf, "long-");
2989 dbuf_append_str (dbuf, "int");
2993 dbuf_append_str (dbuf, "char");
2997 dbuf_append_str (dbuf, "void");
3001 dbuf_append_str (dbuf, "float");
3005 dbuf_append_str (dbuf, "fixed16x16");
3009 dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
3013 dbuf_append_str (dbuf, "sbit");
3017 dbuf_append_str (dbuf, "bit");
3021 dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3025 dbuf_append_str (dbuf, "double");
3029 dbuf_append_str (dbuf, "unknown type");
3033 /* search entry in list before "type" */
3034 for (search = start; search && search->next != type;)
3035 search = search->next;
3038 dbuf_append_char(dbuf, ' ');
3042 /*--------------------------------------------------------------------*/
3043 /* printTypeChainRaw - prints the type chain in human readable form */
3044 /* in the raw data structure ordering */
3045 /*--------------------------------------------------------------------*/
3047 printTypeChainRaw (sym_link * start, FILE * of)
3060 fprintf (of, "void");
3070 if (!IS_FUNC(type)) {
3071 if (DCL_PTR_VOLATILE (type)) {
3072 fprintf (of, "volatile-");
3074 if (DCL_PTR_CONST (type)) {
3075 fprintf (of, "const-");
3077 if (DCL_PTR_RESTRICT (type)) {
3078 fprintf (of, "restrict-");
3081 switch (DCL_TYPE (type))
3084 if (IFFUNC_ISINLINE(type)) {
3085 fprintf (of, "inline-");
3087 fprintf (of, "function %s %s",
3088 (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
3089 (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
3091 for (args = FUNC_ARGS(type);
3094 printTypeChain(args->type, of);
3101 fprintf (of, "generic* ");
3104 fprintf (of, "code* ");
3107 fprintf (of, "xdata* ");
3110 fprintf (of, "eeprom* ");
3113 fprintf (of, "near* ");
3116 fprintf (of, "idata* ");
3119 fprintf (of, "pdata* ");
3122 fprintf (of, "unknown* ");
3125 if (DCL_ELEM(type)) {
3126 fprintf (of, "[%d] ", DCL_ELEM(type));
3128 fprintf (of, "[] ");
3132 if (DCL_TSPEC(type))
3135 printTypeChainRaw(DCL_TSPEC(type), of);
3139 else if (IS_SPEC (type))
3141 switch (SPEC_SCLS (type))
3143 case S_DATA: fprintf (of, "data-"); break;
3144 case S_XDATA: fprintf (of, "xdata-"); break;
3145 case S_SFR: fprintf (of, "sfr-"); break;
3146 case S_SBIT: fprintf (of, "sbit-"); break;
3147 case S_CODE: fprintf (of, "code-"); break;
3148 case S_IDATA: fprintf (of, "idata-"); break;
3149 case S_PDATA: fprintf (of, "pdata-"); break;
3150 case S_LITERAL: fprintf (of, "literal-"); break;
3151 case S_STACK: fprintf (of, "stack-"); break;
3152 case S_XSTACK: fprintf (of, "xstack-"); break;
3153 case S_BIT: fprintf (of, "bit-"); break;
3154 case S_EEPROM: fprintf (of, "eeprom-"); break;
3157 if (SPEC_VOLATILE (type))
3158 fprintf (of, "volatile-");
3159 if (SPEC_CONST (type))
3160 fprintf (of, "const-");
3161 if (SPEC_USIGN (type))
3162 fprintf (of, "unsigned-");
3163 switch (SPEC_NOUN (type))
3167 fprintf (of, "long-");
3168 fprintf (of, "int");
3172 fprintf (of, "char");
3176 fprintf (of, "void");
3180 fprintf (of, "float");
3184 fprintf (of, "fixed16x16");
3188 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3192 fprintf (of, "sbit");
3196 fprintf (of, "bit");
3200 fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3204 fprintf (of, "double");
3208 fprintf (of, "unknown type");
3213 fprintf (of, "NOT_SPEC_OR_DECL");
3223 /*-----------------------------------------------------------------*/
3224 /* powof2 - returns power of two for the number if number is pow 2 */
3225 /*-----------------------------------------------------------------*/
3227 powof2 (TYPE_TARGET_ULONG num)
3240 if (n1s > 1 || nshifts == 0)
3256 symbol *__fps16x16_add;
3257 symbol *__fps16x16_sub;
3258 symbol *__fps16x16_mul;
3259 symbol *__fps16x16_div;
3260 symbol *__fps16x16_eq;
3261 symbol *__fps16x16_neq;
3262 symbol *__fps16x16_lt;
3263 symbol *__fps16x16_lteq;
3264 symbol *__fps16x16_gt;
3265 symbol *__fps16x16_gteq;
3267 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3268 symbol *__muldiv[3][3][2];
3269 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3270 sym_link *__multypes[3][2];
3271 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3272 symbol *__conv[2][3][2];
3273 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
3274 symbol *__fp16x16conv[2][4][2];
3275 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3276 symbol *__rlrr[2][3][2];
3278 sym_link *floatType;
3279 sym_link *fixed16x16Type;
3282 _mangleFunctionName(char *in)
3284 if (port->getMangledFunctionName)
3286 return port->getMangledFunctionName(in);
3294 /*-----------------------------------------------------------------*/
3295 /* typeFromStr - create a typechain from an encoded string */
3296 /* basic types - 'c' - char */
3301 /* 'q' - fixed16x16 */
3303 /* '*' - pointer - default (GPOINTER) */
3304 /* modifiers - 'u' - unsigned */
3305 /* pointer modifiers - 'g' - generic */
3309 /* 'F' - function */
3310 /* examples : "ig*" - generic int * */
3311 /* "cx*" - char xdata * */
3312 /* "ui" - unsigned int */
3313 /*-----------------------------------------------------------------*/
3314 sym_link *typeFromStr (char *s)
3316 sym_link *r = newLink(DECLARATOR);
3328 r->class = SPECIFIER;
3329 SPEC_NOUN(r) = V_CHAR;
3333 r->class = SPECIFIER;
3334 SPEC_NOUN(r) = V_INT;
3337 r->class = SPECIFIER;
3338 SPEC_NOUN(r) = V_INT;
3342 r->class = SPECIFIER;
3343 SPEC_NOUN(r) = V_FLOAT;
3346 r->class = SPECIFIER;
3347 SPEC_NOUN(r) = V_FIXED16X16;
3350 r->class = SPECIFIER;
3351 SPEC_NOUN(r) = V_VOID;
3354 DCL_TYPE(r) = port->unqualified_pointer;
3361 assert(*(s+1)=='*');
3362 nr = newLink(DECLARATOR);
3367 DCL_TYPE(r) = GPOINTER;
3370 DCL_TYPE(r) = FPOINTER;
3373 DCL_TYPE(r) = CPOINTER;
3376 DCL_TYPE(r) = POINTER;
3379 DCL_TYPE(r) = FUNCTION;
3380 nr = newLink(DECLARATOR);
3383 DCL_TYPE(r) = CPOINTER;
3389 werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
3390 "typeFromStr: unknown type");
3393 if (IS_SPEC(r) && usign) {
3402 /*-----------------------------------------------------------------*/
3403 /* initCSupport - create functions for C support routines */
3404 /*-----------------------------------------------------------------*/
3408 const char *smuldivmod[] =
3412 const char *sbwd[] =
3414 "char", "int", "long", "fixed16x16",
3416 const char *fp16x16sbwd[] =
3418 "char", "int", "long", "float",
3424 const char *srlrr[] =
3429 int bwd, su, muldivmod, tofrom, rlrr;
3431 if (getenv("SDCC_NO_C_SUPPORT")) {
3432 /* for debugging only */
3436 floatType = newFloatLink ();
3437 fixed16x16Type = newFixed16x16Link ();
3439 for (bwd = 0; bwd < 3; bwd++)
3456 __multypes[bwd][0] = l;
3457 __multypes[bwd][1] = copyLinkChain (l);
3458 SPEC_USIGN (__multypes[bwd][1]) = 1;
3461 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3462 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3463 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3464 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3465 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3466 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3467 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3468 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3469 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3470 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3472 __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3473 __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3474 __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3475 __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3476 __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3477 __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3478 __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3479 __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3480 __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3481 __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3484 for (tofrom = 0; tofrom < 2; tofrom++)
3486 for (bwd = 0; bwd < 3; bwd++)
3488 for (su = 0; su < 2; su++)
3492 SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3493 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3497 SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3498 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3504 for (tofrom = 0; tofrom < 2; tofrom++)
3506 for (bwd = 0; bwd < 4; bwd++)
3508 for (su = 0; su < 2; su++)
3512 SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
3514 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
3516 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
3520 SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
3522 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
3524 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
3531 for (muldivmod = 0; muldivmod < 3; muldivmod++)
3533 for (bwd = 0; bwd < 3; bwd++)
3535 for (su = 0; su < 2; su++)
3537 SNPRINTF (buffer, sizeof(buffer),
3539 smuldivmod[muldivmod],
3542 __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3543 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3548 muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3549 Therefore they've been merged into mulint() and mullong().
3552 for (bwd = 0; bwd < 3; bwd++)
3554 for (su = 0; su < 2; su++)
3556 for (muldivmod = 1; muldivmod < 3; muldivmod++)
3558 /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
3559 if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0)
3561 SNPRINTF (buffer, sizeof(buffer),
3563 smuldivmod[muldivmod],
3566 __muldiv[muldivmod][bwd][su] = funcOfType (
3567 _mangleFunctionName(buffer),
3568 __multypes[bwd][su],
3569 __multypes[bwd][su],
3571 options.intlong_rent);
3572 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3578 if (TARGET_IS_PIC16)
3580 /* PIC16 port wants __divschar/__modschar to return an int, so that both
3581 * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
3582 * (first one would have to be sign extended, second one must not be).
3583 * Similarly, modschar should be handled, but the iCode introduces cast
3584 * here and forces '% : s8 x s8 -> s8' ... */
3586 for (muldivmod = 1; muldivmod < 2; muldivmod++) {
3587 SNPRINTF (buffer, sizeof(buffer),
3589 smuldivmod[muldivmod],
3592 __muldiv[muldivmod][bwd][su] = funcOfType (
3593 _mangleFunctionName(buffer),
3595 __multypes[bwd][su],
3597 options.intlong_rent);
3598 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3606 for (su = 0; su < 2; su++)
3608 /* muluchar and mulschar are still separate functions, because e.g. the z80
3609 port is sign/zero-extending to int before calling mulint() */
3610 SNPRINTF (buffer, sizeof(buffer),
3612 smuldivmod[muldivmod],
3615 __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3616 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3620 /* word and doubleword */
3621 for (bwd = 1; bwd < 3; bwd++)
3624 SNPRINTF (buffer, sizeof(buffer),
3626 smuldivmod[muldivmod],
3628 __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3629 FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3630 /* signed = unsigned */
3631 __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3634 for (rlrr = 0; rlrr < 2; rlrr++)
3636 for (bwd = 0; bwd < 3; bwd++)
3638 for (su = 0; su < 2; su++)
3640 SNPRINTF (buffer, sizeof(buffer),
3645 __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3646 FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3652 /*-----------------------------------------------------------------*/
3653 /* initBuiltIns - create prototypes for builtin functions */
3654 /*-----------------------------------------------------------------*/
3660 if (!port->builtintable) return ;
3662 for (i = 0 ; port->builtintable[i].name ; i++) {
3663 sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3664 port->builtintable[i].nParms,port->builtintable[i].parm_types);
3665 FUNC_ISBUILTIN(sym->type) = 1;
3666 FUNC_ISREENT(sym->type) = 0; /* can never be reentrant */
3670 sym_link *validateLink(sym_link *l,
3677 if (l && l->class==select)
3682 "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3683 " expected %s, got %s\n",
3684 macro, args, file, line,
3685 DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3687 return l; // never reached, makes compiler happy.
3690 /*--------------------------------------------------------------------*/
3691 /* newEnumType - create an integer type compatible with enumerations */
3692 /*--------------------------------------------------------------------*/
3694 newEnumType (symbol *enumlist)
3702 type = newLink (SPECIFIER);
3703 SPEC_NOUN (type) = V_INT;
3707 /* Determine the range of the enumerated values */
3709 min = max = (int) ulFromVal (valFromType (sym->type));
3710 for (sym = sym->next; sym; sym = sym->next)
3712 v = (int) ulFromVal (valFromType (sym->type));
3719 /* Determine the smallest integer type that is compatible with this range */
3720 type = newLink (SPECIFIER);
3721 if (min>=0 && max<=255)
3723 SPEC_NOUN (type) = V_CHAR;
3724 SPEC_USIGN (type) = 1;
3726 else if (min>=-128 && max<=127)
3728 SPEC_NOUN (type) = V_CHAR;
3730 else if (min>=0 && max<=65535)
3732 SPEC_NOUN (type) = V_INT;
3733 SPEC_USIGN (type) = 1;
3735 else if (min>=-32768 && max<=32767)
3737 SPEC_NOUN (type) = V_INT;
3741 SPEC_NOUN (type) = V_INT;
3742 SPEC_LONG (type) = 1;
3744 SPEC_USIGN (type) = 1;