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 then check if
1086 one of them is an extern definition;
1087 if yes then then check if the type match;
1088 if the types match then delete the current entry and
1089 add the new entry */
1090 if ((csym = findSymWithLevel (SymbolTab, sym)) &&
1091 csym->level == sym->level)
1093 /* if not formal parameter and not in file scope
1094 then show symbol redefined error
1095 else check if symbols have conpatible types */
1096 if (!sym->_isparm && sym->level > 0)
1100 /* If the previous definition was for an array with incomplete */
1101 /* type, and the new definition has completed the type, update */
1102 /* the original type to match */
1103 if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
1104 && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
1106 if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
1107 DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
1111 /* If only one of the definitions used the "at" keyword, copy */
1112 /* the address to the other. */
1113 if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
1114 && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
1116 SPEC_ABSA (sym->etype) = 1;
1117 SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
1119 if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
1120 && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
1122 SPEC_ABSA (csym->etype) = 1;
1123 SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
1128 if (csym->ival && sym->ival)
1130 if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
1136 /* one definition extern ? */
1137 if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
1138 werror (E_EXTERN_MISMATCH, sym->name);
1140 werror (E_DUPLICATE, sym->name);
1141 werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1143 fprintf (stderr, "from type '");
1144 printTypeChain (csym->type, stderr);
1145 if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
1146 fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
1147 fprintf (stderr, "'\nto type '");
1148 printTypeChain (sym->type, stderr);
1149 if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
1150 fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
1151 fprintf (stderr, "'\n");
1156 if (csym->ival && !sym->ival)
1157 sym->ival = csym->ival;
1159 /* delete current entry */
1160 deleteSym (SymbolTab, csym, csym->name);
1161 deleteFromSeg(csym);
1163 symPtrPtr = symHead;
1164 while (*symPtrPtr && *symPtrPtr != csym)
1165 symPtrPtr = &(*symPtrPtr)->next;
1166 if (*symPtrPtr == csym)
1167 *symPtrPtr = csym->next;
1171 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1176 /*------------------------------------------------------------------*/
1177 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
1178 /*------------------------------------------------------------------*/
1180 funcInChain (sym_link * lnk)
1191 /*------------------------------------------------------------------*/
1192 /* structElemType - returns the type info of a struct member */
1193 /*------------------------------------------------------------------*/
1195 structElemType (sym_link * stype, value * id)
1197 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1198 sym_link *type, *etype;
1199 sym_link *petype = getSpec (stype);
1203 /* look for the id */
1206 if (strcmp (fields->rname, id->name) == 0)
1208 type = copyLinkChain (fields->type);
1209 etype = getSpec (type);
1210 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1211 SPEC_SCLS (etype) : SPEC_SCLS (petype));
1213 SPEC_CONST (type) |= SPEC_CONST (stype);
1215 DCL_PTR_CONST (type) |= SPEC_CONST (stype);
1218 fields = fields->next;
1222 werror (E_NOT_MEMBER, id->name);
1224 // the show must go on
1225 return newIntLink();
1228 /*------------------------------------------------------------------*/
1229 /* getStructElement - returns element of a tructure definition */
1230 /*------------------------------------------------------------------*/
1232 getStructElement (structdef * sdef, symbol * sym)
1236 for (field = sdef->fields; field; field = field->next)
1237 if (strcmp (field->name, sym->name) == 0)
1240 werror (E_NOT_MEMBER, sym->name);
1242 return sdef->fields;
1245 /*------------------------------------------------------------------*/
1246 /* compStructSize - computes the size of a structure */
1247 /*------------------------------------------------------------------*/
1249 compStructSize (int su, structdef * sdef)
1251 int sum = 0, usum = 0;
1255 /* for the identifiers */
1256 loop = sdef->fields;
1259 /* create the internal name for this variable */
1260 SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
1265 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1267 /* if this is a bit field */
1270 /* change it to a unsigned bit */
1271 SPEC_NOUN (loop->etype) = V_BITFIELD;
1272 /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
1273 /* a "plain" int bitfield is unsigned */
1274 if (!loop->etype->select.s.b_signed)
1275 SPEC_USIGN(loop->etype) = 1;
1277 SPEC_BLEN (loop->etype) = loop->bitVar;
1279 if (loop->bitVar == BITVAR_PAD) {
1280 /* A zero length bitfield forces padding */
1281 SPEC_BSTR (loop->etype) = bitOffset;
1282 SPEC_BLEN (loop->etype) = 0;
1287 if (bitOffset == 8) {
1291 /* check if this fit into the remaining */
1292 /* bits of this byte else align it to the */
1293 /* next byte boundary */
1294 if (loop->bitVar <= (8 - bitOffset)) {
1295 /* fits into current byte */
1297 SPEC_BSTR (loop->etype) = bitOffset;
1298 bitOffset += loop->bitVar;
1300 else if (!bitOffset) {
1301 /* does not fit, but is already byte aligned */
1303 SPEC_BSTR (loop->etype) = bitOffset;
1304 bitOffset += loop->bitVar;
1307 if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
1308 /* if PIC16 && enviroment variable is set, then
1309 * tightly pack bitfields, this means that when a
1310 * bitfield goes beyond byte alignment, do not
1311 * automatically start allocatint from next byte,
1312 * but also use the available bits first */
1313 fprintf(stderr, ": packing bitfields in structures\n");
1314 SPEC_BSTR (loop->etype) = bitOffset;
1315 bitOffset += loop->bitVar;
1316 loop->offset = (su == UNION ? sum = 0 : sum);
1318 /* does not fit; need to realign first */
1320 loop->offset = (su == UNION ? sum = 0 : sum);
1322 SPEC_BSTR (loop->etype) = bitOffset;
1323 bitOffset += loop->bitVar;
1326 while (bitOffset>8) {
1333 /* This is a non-bit field. Make sure we are */
1334 /* byte aligned first */
1337 loop->offset = (su == UNION ? sum = 0 : sum);
1341 checkDecl (loop, 1);
1342 sum += getSize (loop->type);
1344 /* search for "flexibel array members" */
1345 /* and do some syntax checks */
1347 && checkStructFlexArray (loop, loop->type))
1349 /* found a "flexible array member" */
1350 sdef->b_flexArrayMember = TRUE;
1351 /* is another struct-member following? */
1353 werror (E_FLEXARRAY_NOTATEND);
1354 /* is it the first struct-member? */
1355 else if (loop == sdef->fields)
1356 werror (E_FLEXARRAY_INEMPTYSTRCT);
1362 /* if union then size = sizeof largest field */
1364 /* For UNION, round up after each field */
1365 sum += ((bitOffset+7)/8);
1366 usum = max (usum, sum);
1371 /* For STRUCT, round up after all fields processed */
1373 sum += ((bitOffset+7)/8);
1375 return (su == UNION ? usum : sum);
1378 /*-------------------------------------------------------------------*/
1379 /* promoteAnonStructs - promote anonymous struct/union's fields into */
1380 /* an enclosing struct/union */
1381 /*-------------------------------------------------------------------*/
1383 promoteAnonStructs (int su, structdef * sdef)
1392 tofield = &sdef->fields;
1393 field = sdef->fields;
1396 nextfield = field->next;
1397 if (!*field->name && IS_STRUCT (field->type))
1399 /* Found an anonymous struct/union. Replace it */
1400 /* with the fields it contains and adjust all */
1403 base = field->offset;
1404 subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
1406 continue; /* just in case it's empty */
1408 *tofield = subfield;
1411 /* check for field name conflicts resulting from promotion */
1412 dupfield = sdef->fields;
1413 while (dupfield && dupfield != subfield)
1415 if (*subfield->name && !strcmp (dupfield->name, subfield->name))
1417 werrorfl (subfield->fileDef, subfield->lineDef,
1419 su==STRUCT ? "struct" : "union",
1421 werrorfl (dupfield->fileDef, dupfield->lineDef,
1424 dupfield = dupfield->next;
1427 subfield->offset += base;
1429 subfield = subfield->next;
1433 subfield->next = nextfield;
1434 tofield = &subfield->next;
1437 tofield = &field->next;
1443 /*------------------------------------------------------------------*/
1444 /* checkSClass - check the storage class specification */
1445 /*------------------------------------------------------------------*/
1447 checkSClass (symbol * sym, int isProto)
1451 if (getenv("DEBUG_SANITY")) {
1452 fprintf (stderr, "checkSClass: %s \n", sym->name);
1455 /* type is literal can happen for enums change to auto */
1456 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1457 SPEC_SCLS (sym->etype) = S_AUTO;
1459 /* if sfr or sbit then must also be volatile */
1460 if (SPEC_SCLS (sym->etype) == S_SBIT ||
1461 SPEC_SCLS (sym->etype) == S_SFR)
1463 SPEC_VOLATILE (sym->etype) = 1;
1466 /* make sure restrict is only used with pointers */
1467 if (SPEC_RESTRICT (sym->etype))
1469 werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1470 SPEC_RESTRICT (sym->etype) = 0;
1475 if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !IS_PTR (t))
1477 werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
1478 DCL_PTR_RESTRICT (t) = 0;
1484 /* if absolute address given then it mark it as
1485 volatile -- except in the PIC port */
1487 #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
1488 /* The PIC port uses a different peep hole optimizer based on "pCode" */
1489 if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
1492 if (IS_ABSOLUTE (sym->etype))
1493 SPEC_VOLATILE (sym->etype) = 1;
1495 if (TARGET_IS_MCS51 &&
1496 IS_ABSOLUTE (sym->etype) &&
1497 SPEC_SCLS (sym->etype) == S_SFR)
1502 if (SPEC_NOUN (sym->etype) == V_CHAR)
1504 else if (SPEC_LONG (sym->etype) == 0)
1509 addr = SPEC_ADDR (sym->etype);
1510 for (n=0; n<size; n+=8)
1511 if (((addr >> n) & 0xFF) < 0x80)
1512 werror (W_SFR_ABSRANGE, sym->name);
1515 /* If code memory is read only, then pointers to code memory */
1516 /* implicitly point to constants -- make this explicit */
1518 while (t && t->next) {
1519 if (IS_CODEPTR(t) && port->mem.code_ro) {
1520 if (IS_SPEC(t->next)) {
1521 SPEC_CONST (t->next) = 1;
1523 DCL_PTR_CONST (t->next) = 1;
1529 /* global variables declared const put into code */
1530 /* if no other storage class specified */
1531 if (sym->level == 0 &&
1532 SPEC_SCLS(sym->etype) == S_FIXED &&
1533 !IS_FUNC(sym->type)) {
1534 /* find the first non-array link */
1538 if (IS_CONSTANT (t)) {
1539 SPEC_SCLS (sym->etype) = S_CODE;
1543 /* global variable in code space is a constant */
1544 if (sym->level == 0 &&
1545 SPEC_SCLS (sym->etype) == S_CODE &&
1546 port->mem.code_ro) {
1547 /* find the first non-array link */
1554 DCL_PTR_CONST (t) = 1;
1558 /* if bit variable then no storage class can be */
1559 /* specified since bit is already a storage */
1560 if (IS_BITVAR (sym->etype) &&
1561 (SPEC_SCLS (sym->etype) != S_FIXED &&
1562 SPEC_SCLS (sym->etype) != S_SBIT &&
1563 SPEC_SCLS (sym->etype) != S_BIT)
1566 werror (E_BITVAR_STORAGE, sym->name);
1567 SPEC_SCLS (sym->etype) = S_FIXED;
1570 /* extern variables cannot be initialized */
1571 if (IS_EXTERN (sym->etype) && sym->ival)
1573 werror (E_EXTERN_INIT, sym->name);
1577 /* if this is an automatic symbol */
1578 if (sym->level && (options.stackAuto || reentrant)) {
1579 if (SPEC_SCLS (sym->etype) != S_BIT) {
1580 if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1581 SPEC_SCLS (sym->etype) == S_FIXED ||
1582 SPEC_SCLS (sym->etype) == S_REGISTER ||
1583 SPEC_SCLS (sym->etype) == S_STACK ||
1584 SPEC_SCLS (sym->etype) == S_XSTACK)) {
1585 SPEC_SCLS (sym->etype) = S_AUTO;
1587 /* storage class may only be specified for statics */
1588 if (!IS_STATIC(sym->etype)) {
1589 werror (E_AUTO_ASSUMED, sym->name);
1595 /* automatic symbols cannot be given */
1596 /* an absolute address ignore it */
1597 if (sym->level && !IS_STATIC(sym->etype) &&
1598 SPEC_ABSA (sym->etype) &&
1599 (options.stackAuto || reentrant))
1601 werror (E_AUTO_ABSA, sym->name);
1602 SPEC_ABSA (sym->etype) = 0;
1605 /* arrays & pointers cannot be defined for bits */
1606 /* SBITS or SFRs or BIT */
1607 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1608 !IS_FUNCPTR (sym->type) &&
1609 (SPEC_NOUN (sym->etype) == V_BIT ||
1610 SPEC_NOUN (sym->etype) == V_SBIT ||
1611 SPEC_NOUN (sym->etype) == V_BITFIELD ||
1612 SPEC_SCLS (sym->etype) == S_SFR))
1613 werror (E_BIT_ARRAY, sym->name);
1615 /* if this is a bit|sbit then set length & start */
1616 if (SPEC_NOUN (sym->etype) == V_BIT ||
1617 SPEC_NOUN (sym->etype) == V_SBIT)
1619 SPEC_BLEN (sym->etype) = 1;
1620 SPEC_BSTR (sym->etype) = 0;
1624 /* variables declared in CODE space must have */
1625 /* initializers if not an extern */
1626 if (SPEC_SCLS (sym->etype) == S_CODE &&
1627 sym->ival == NULL &&
1630 port->mem.code_ro &&
1631 !IS_EXTERN (sym->etype) &&
1632 !SPEC_ABSA (sym->etype) &&
1633 !funcInChain (sym->type))
1634 werror (E_CODE_NO_INIT, sym->name);
1637 /* if parameter or local variable then change */
1638 /* the storage class to reflect where the var will go */
1639 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
1640 && !IS_STATIC(sym->etype)
1643 if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1645 SPEC_SCLS (sym->etype) = (options.useXstack ?
1646 S_XSTACK : S_STACK);
1650 /* hack-o-matic! I see no reason why the useXstack option should ever
1651 * control this allocation, but the code was originally that way, and
1652 * changing it for non-390 ports breaks the compiler badly.
1654 bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ?
1655 1 : options.useXstack;
1656 SPEC_SCLS (sym->etype) = (useXdata ?
1662 /*------------------------------------------------------------------*/
1663 /* changePointer - change pointer to functions */
1664 /*------------------------------------------------------------------*/
1666 changePointer (sym_link * p)
1669 /* go thru the chain of declarations */
1670 /* if we find a pointer to a function */
1671 /* change it to a ptr to code area */
1672 /* unless the function is banked. */
1673 for (; p; p = p->next)
1675 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1676 DCL_TYPE (p) = port->unqualified_pointer;
1677 if (IS_PTR (p) && IS_FUNC (p->next))
1678 if (!IFFUNC_BANKED(p->next))
1679 DCL_TYPE (p) = CPOINTER;
1683 /*------------------------------------------------------------------*/
1684 /* checkDecl - does semantic validation of a declaration */
1685 /*------------------------------------------------------------------*/
1687 checkDecl (symbol * sym, int isProto)
1690 checkSClass (sym, isProto); /* check the storage class */
1691 changePointer (sym->type); /* change pointers if required */
1693 /* if this is an array without any dimension
1694 then update the dimension from the initial value */
1695 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1696 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1701 /*------------------------------------------------------------------*/
1702 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1703 /*------------------------------------------------------------------*/
1705 copyLinkChain (sym_link * p)
1707 sym_link *head, *curr, *loop;
1709 /* note: v_struct and v_struct->fields are not copied! */
1711 head = loop = (curr ? newLink (p->class) : (void *) NULL);
1714 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1715 loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
1723 /*------------------------------------------------------------------*/
1724 /* cleanUpBlock - cleansup the symbol table specified for all the */
1725 /* symbols in the given block */
1726 /*------------------------------------------------------------------*/
1728 cleanUpBlock (bucket ** table, int block)
1733 /* go thru the entire table */
1734 for (i = 0; i < 256; i++)
1736 for (chain = table[i]; chain; chain = chain->next)
1738 if (chain->block >= block)
1740 deleteSym (table, chain->sym, chain->name);
1746 /*------------------------------------------------------------------*/
1747 /* cleanUpLevel - cleansup the symbol table specified for all the */
1748 /* symbols in the given level */
1749 /*------------------------------------------------------------------*/
1751 cleanUpLevel (bucket ** table, int level)
1756 /* go thru the entire table */
1757 for (i = 0; i < 256; i++)
1759 for (chain = table[i]; chain; chain = chain->next)
1761 if (chain->level >= level)
1763 deleteSym (table, chain->sym, chain->name);
1769 /*------------------------------------------------------------------*/
1770 /* computeTypeOr - computes the resultant type from two types */
1771 /*------------------------------------------------------------------*/
1773 computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
1776 assert ( (IS_CHAR (etype1) || IS_BIT (etype1))
1777 && (IS_CHAR (etype2) || IS_BIT (etype2)));
1779 if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
1781 SPEC_USIGN (reType) = SPEC_USIGN (etype1);
1785 if (SPEC_USIGN (etype1))
1787 if ( IS_LITERAL (etype2)
1788 && floatFromVal (valFromType (etype2)) >= 0)
1789 SPEC_USIGN (reType) = 1;
1792 /* promote to int */
1793 SPEC_USIGN (reType) = 0;
1794 SPEC_NOUN (reType) = V_INT;
1797 else /* etype1 signed */
1799 if ( IS_LITERAL (etype2)
1800 && floatFromVal (valFromType (etype2)) <= 127)
1801 SPEC_USIGN (reType) = 0;
1804 /* promote to int */
1805 SPEC_USIGN (reType) = 0;
1806 SPEC_NOUN (reType) = V_INT;
1810 if (SPEC_USIGN (etype2))
1812 if ( IS_LITERAL (etype1)
1813 && floatFromVal (valFromType (etype1)) >= 0)
1814 SPEC_USIGN (reType) = 1;
1817 /* promote to int */
1818 SPEC_USIGN (reType) = 0;
1819 SPEC_NOUN (reType) = V_INT;
1822 else /* etype2 signed */
1824 if ( IS_LITERAL (etype1)
1825 && floatFromVal (valFromType (etype1)) <= 127)
1826 SPEC_USIGN (reType) = 0;
1829 /* promote to int */
1830 SPEC_USIGN (reType) = 0;
1831 SPEC_NOUN (reType) = V_INT;
1837 /*------------------------------------------------------------------*/
1838 /* computeType - computes the resultant type from two types */
1839 /*------------------------------------------------------------------*/
1841 computeType (sym_link * type1, sym_link * type2,
1842 RESULT_TYPE resultType, int op)
1846 sym_link *etype1 = getSpec (type1);
1849 etype2 = type2 ? getSpec (type2) : type1;
1851 /* if one of them is a float then result is a float */
1852 /* here we assume that the types passed are okay */
1853 /* and can be cast to one another */
1854 /* which ever is greater in size */
1855 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1856 rType = newFloatLink ();
1857 /* if both are fixed16x16 then result is float */
1858 else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
1859 rType = newFixed16x16Link();
1860 else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
1861 rType = newFloatLink ();
1862 else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
1863 rType = newFloatLink ();
1865 /* if both are bitvars choose the larger one */
1866 else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
1867 rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
1868 copyLinkChain (type1) : copyLinkChain (type1);
1870 /* if only one of them is a bit variable then the other one prevails */
1871 else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1873 rType = copyLinkChain (type2);
1874 /* bitfield can have up to 16 bits */
1875 if (getSize (etype1) > 1)
1876 SPEC_NOUN (getSpec (rType)) = V_INT;
1878 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1880 rType = copyLinkChain (type1);
1881 /* bitfield can have up to 16 bits */
1882 if (getSize (etype2) > 1)
1883 SPEC_NOUN (getSpec (rType)) = V_INT;
1885 /* if one of them is a pointer or array then that
1887 else if (IS_PTR (type1) || IS_ARRAY (type1))
1888 rType = copyLinkChain (type1);
1889 else if (IS_PTR (type2) || IS_ARRAY (type2))
1890 rType = copyLinkChain (type2);
1891 else if (getSize (type1) > getSize (type2))
1892 rType = copyLinkChain (type1);
1894 rType = copyLinkChain (type2);
1896 reType = getSpec (rType);
1898 /* avoid conflicting types */
1899 reType->select.s.b_signed = 0;
1901 /* if result is a literal then make not so */
1902 if (IS_LITERAL (reType))
1903 SPEC_SCLS (reType) = S_REGISTER;
1907 case RESULT_TYPE_IFX:
1911 case RESULT_TYPE_BIT:
1914 SPEC_NOUN (reType) = V_BIT;
1918 case RESULT_TYPE_CHAR:
1919 if (IS_BITVAR (reType))
1921 SPEC_NOUN (reType) = V_CHAR;
1922 SPEC_SCLS (reType) = 0;
1923 SPEC_USIGN (reType) = 0;
1927 case RESULT_TYPE_INT:
1928 case RESULT_TYPE_NONE:
1929 case RESULT_TYPE_OTHER:
1930 if (IS_BIT (reType))
1932 SPEC_NOUN (reType) = V_CHAR;
1933 SPEC_SCLS (reType) = 0;
1934 SPEC_USIGN (reType) = 0;
1937 else if (IS_BITFIELD (reType))
1939 /* could be smarter, but it depends on the op */
1940 /* this is for the worst case: a multiplication of 4 * 4 bit */
1941 SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
1942 SPEC_SCLS (reType) = 0;
1943 SPEC_USIGN (reType) = 0;
1946 else if (IS_CHAR (reType))
1948 /* promotion of some special cases */
1953 return computeTypeOr (etype1, etype2, reType);
1955 if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
1957 SPEC_USIGN (reType) = 1;
1962 SPEC_NOUN (reType) = V_INT;
1963 SPEC_USIGN (reType) = 0;
1966 /* if both are unsigned char then no promotion required */
1967 if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
1969 SPEC_NOUN (reType) = V_INT;
1970 SPEC_USIGN (reType) = 0;
1983 /* SDCC's sign promotion:
1984 - if one or both operands are unsigned, the resultant type will be unsigned
1985 (except char, see below)
1986 - if an operand is promoted to a larger type (char -> int, int -> long),
1987 the larger type will be signed
1989 SDCC tries hard to avoid promotion to int and does 8 bit calculation as
1990 much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
1991 the standard. The standard demands, that the result has to be the same
1992 "as if" the promotion would have been performed:
1994 - if the result of an operation with two char's is promoted to a
1995 larger type, the result will be signed.
1997 More sophisticated are these:
1998 - if the result of an operation with two char's is a char again,
1999 the result will only then be unsigned, if both operands are
2000 unsigned. In all other cases the result will be signed.
2002 This seems to be contradictionary to the first two rules, but it makes
2003 real sense (all types are char's):
2005 A signed char can be negative; this must be preserved in the result
2008 Only if both operands are unsigned it's safe to make the result
2009 unsigned; this helps to avoid overflow:
2012 - ToDo: document '|', '^' and '&'
2014 Homework: - why is (200 * 200 < 0) true?
2015 - why is { char l = 200, r = 200; (r * l > 0) } true?
2018 if (!IS_FLOAT (reType)
2019 && ( (SPEC_USIGN (etype1)
2020 /* if this operand is promoted to a larger type,
2021 then it will be promoted to a signed type */
2022 && !(bitsForType (etype1) < bitsForType (reType))
2023 /* char require special handling */
2024 && !IS_CHAR (etype1))
2025 || /* same for 2nd operand */
2026 (SPEC_USIGN (etype2)
2027 && !(bitsForType (etype2) < bitsForType (reType))
2028 && !IS_CHAR (etype2))
2029 || /* if both are 'unsigned char' and not promoted
2030 let the result be unsigned too */
2031 ( SPEC_USIGN (etype1)
2032 && SPEC_USIGN (etype2)
2035 && IS_CHAR (reType))))
2036 SPEC_USIGN (reType) = 1;
2038 SPEC_USIGN (reType) = 0;
2043 /*--------------------------------------------------------------------*/
2044 /* compareType - will do type check return 1 if match, -1 if castable */
2045 /*--------------------------------------------------------------------*/
2047 compareType (sym_link * dest, sym_link * src)
2058 /* if dest is a declarator then */
2063 /* banked function pointer */
2064 if (IS_GENPTR (dest) && IS_GENPTR (src))
2066 if (IS_FUNC (src->next) && IS_VOID(dest->next))
2068 if (IS_FUNC (dest->next) && IS_VOID(src->next))
2070 return compareType (dest->next, src->next);
2073 if (DCL_TYPE (src) == DCL_TYPE (dest))
2077 //checkFunction(src,dest);
2079 return compareType (dest->next, src->next);
2081 if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
2086 (IS_GENPTR (dest) ||
2087 ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
2090 if (IS_PTR (dest) && IS_ARRAY (src))
2092 value *val=aggregateToPointer (valFromType(src));
2093 int res=compareType (dest, val->type);
2094 Safe_free(val->type);
2098 if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
2099 return compareType (dest->next, src);
2102 else if (IS_PTR (dest) && IS_INTEGRAL (src))
2108 /* if one is a specifier and the other is not */
2109 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2110 (IS_SPEC (dest) && !IS_SPEC (src)))
2113 /* if one of them is a void then ok */
2114 if (SPEC_NOUN (dest) == V_VOID &&
2115 SPEC_NOUN (src) != V_VOID)
2118 if (SPEC_NOUN (dest) != V_VOID &&
2119 SPEC_NOUN (src) == V_VOID)
2122 /* if they are both bitfields then if the lengths
2123 and starts don't match */
2124 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2125 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2126 SPEC_BSTR (dest) != SPEC_BSTR (src)))
2129 /* it is a specifier */
2130 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2132 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
2133 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
2135 bitsForType (dest) == bitsForType (src))
2136 instead of the next two lines, but the regression tests fail with
2137 them; I guess it's a problem with replaceCheaperOp */
2138 getSize (dest) == getSize (src) &&
2139 (IS_BIT (dest) == IS_BIT (src)))
2141 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
2146 else if (IS_STRUCT (dest))
2148 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2153 if (SPEC_LONG (dest) != SPEC_LONG (src))
2156 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2162 /*--------------------------------------------------------------------*/
2163 /* compareTypeExact - will do type check return 1 if match exactly */
2164 /*--------------------------------------------------------------------*/
2166 compareTypeExact (sym_link * dest, sym_link * src, int level)
2168 STORAGE_CLASS srcScls, destScls;
2179 /* if dest is a declarator then */
2184 if (DCL_TYPE (src) == DCL_TYPE (dest)) {
2185 if ((DCL_TYPE (src) == ARRAY) && (DCL_ELEM (src) != DCL_ELEM (dest)))
2187 if (DCL_PTR_CONST (src) != DCL_PTR_CONST (dest))
2189 if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
2193 value *exargs, *acargs, *checkValue;
2195 /* verify function return type */
2196 if (!compareTypeExact (dest->next, src->next, -1))
2198 if (FUNC_ISISR (dest) != FUNC_ISISR (src))
2200 if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
2202 if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
2205 if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
2209 /* compare expected args with actual args */
2210 exargs = FUNC_ARGS(dest);
2211 acargs = FUNC_ARGS(src);
2213 /* for all the expected args do */
2214 for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
2216 //checkTypeSanity(acargs->etype, acargs->name);
2218 if (IS_AGGREGATE (acargs->type))
2220 checkValue = copyValue (acargs);
2221 aggregateToPointer (checkValue);
2224 checkValue = acargs;
2227 if (!compareTypeExact (exargs->type, checkValue->type, -1))
2232 /* if one them ended we have a problem */
2233 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2234 (!exargs && acargs && !IS_VOID (acargs->type)))
2238 return compareTypeExact (dest->next, src->next, level);
2245 /* if one is a specifier and the other is not */
2246 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
2247 (IS_SPEC (dest) && !IS_SPEC (src)))
2250 /* if one of them is a void then ok */
2251 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
2254 /* if they are both bitfields then if the lengths
2255 and starts don't match */
2256 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
2257 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
2258 SPEC_BSTR (dest) != SPEC_BSTR (src)))
2261 if (IS_INTEGRAL (dest))
2263 /* signedness must match */
2264 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
2266 /* size must match */
2267 if (SPEC_LONG (dest) != SPEC_LONG (src))
2269 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
2273 if (IS_STRUCT (dest))
2275 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
2279 if (SPEC_CONST (dest) != SPEC_CONST (src))
2281 if (SPEC_VOLATILE (dest) != SPEC_VOLATILE (src))
2283 if (SPEC_STAT (dest) != SPEC_STAT (src))
2285 if (SPEC_ABSA (dest) != SPEC_ABSA (src))
2287 if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
2290 destScls = SPEC_SCLS (dest);
2291 srcScls = SPEC_SCLS (src);
2293 /* Compensate for const to const code change in checkSClass() */
2294 if (!level & port->mem.code_ro && SPEC_CONST (dest))
2296 if (srcScls == S_CODE && destScls == S_FIXED)
2298 if (destScls == S_CODE && srcScls == S_FIXED)
2302 /* compensate for allocGlobal() */
2303 if ((srcScls == S_FIXED || srcScls == S_AUTO)
2304 && port->mem.default_globl_map == xdata
2308 if (level>0 && !SPEC_STAT (dest))
2310 /* Compensate for hack-o-matic in checkSClass() */
2311 if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
2313 if (destScls == S_FIXED)
2314 destScls = (options.useXstack ? S_XSTACK : S_STACK);
2315 if (srcScls == S_FIXED)
2316 srcScls = (options.useXstack ? S_XSTACK : S_STACK);
2318 else if (TARGET_IS_DS390 || TARGET_IS_DS400 || options.useXstack)
2320 if (destScls == S_FIXED)
2322 if (srcScls == S_FIXED)
2327 if (srcScls != destScls)
2330 printf ("level = %d\n", level);
2331 printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
2332 SPEC_SCLS (src), SPEC_SCLS (dest));
2333 printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
2341 /*------------------------------------------------------------------*/
2342 /* inCalleeSaveList - return 1 if found in callee save list */
2343 /*------------------------------------------------------------------*/
2345 calleeCmp(void *p1, void *p2)
2347 return (strcmp((char *)p1, (char *)(p2)) == 0);
2351 inCalleeSaveList(char *s)
2353 if (options.all_callee_saves)
2355 return isinSetWith(options.calleeSavesSet, s, calleeCmp);
2358 /*-----------------------------------------------------------------*/
2359 /* aggregateToPointer: change an aggregate type function */
2360 /* argument to a pointer to that type. */
2361 /*-----------------------------------------------------------------*/
2363 aggregateToPointer (value * val)
2365 if (IS_AGGREGATE (val->type))
2367 /* if this is a structure */
2368 /* then we need to add a new link */
2369 if (IS_STRUCT (val->type))
2371 /* first lets add DECLARATOR type */
2372 sym_link *p = val->type;
2374 werror (W_STRUCT_AS_ARG, val->name);
2375 val->type = newLink (DECLARATOR);
2376 val->type->next = p;
2379 /* change to a pointer depending on the */
2380 /* storage class specified */
2381 switch (SPEC_SCLS (val->etype))
2384 DCL_TYPE (val->type) = IPOINTER;
2387 DCL_TYPE (val->type) = PPOINTER;
2390 if (SPEC_OCLS(val->etype)) {
2391 DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
2393 // this happens for (external) function parameters
2394 DCL_TYPE (val->type) = port->unqualified_pointer;
2400 DCL_TYPE (val->type) = POINTER;
2403 DCL_TYPE (val->type) = CPOINTER;
2406 DCL_TYPE (val->type) = FPOINTER;
2409 DCL_TYPE (val->type) = EEPPOINTER;
2412 DCL_TYPE (val->type) = port->unqualified_pointer;
2415 /* is there is a symbol associated then */
2416 /* change the type of the symbol as well */
2419 val->sym->type = copyLinkChain (val->type);
2420 val->sym->etype = getSpec (val->sym->type);
2425 /*------------------------------------------------------------------*/
2426 /* checkFunction - does all kinds of check on a function */
2427 /*------------------------------------------------------------------*/
2429 checkFunction (symbol * sym, symbol *csym)
2431 value *exargs, *acargs;
2435 if (getenv("DEBUG_SANITY")) {
2436 fprintf (stderr, "checkFunction: %s ", sym->name);
2439 if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
2441 werror(E_SYNTAX_ERROR, sym->name);
2445 /* move inline specifier from return type to function attributes */
2446 if (IS_INLINE (sym->etype))
2448 SPEC_INLINE (sym->etype) = 0;
2449 FUNC_ISINLINE (sym->type) = 1;
2452 /* make sure the type is complete and sane */
2453 checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
2455 /* if not type then some kind of error */
2459 /* if the function has no type then make it return int */
2460 if (!sym->type->next)
2461 sym->type->next = sym->etype = newIntLink ();
2463 /* function cannot return aggregate */
2464 if (IS_AGGREGATE (sym->type->next))
2466 werror (E_FUNC_AGGR, sym->name);
2470 /* check if this function is defined as calleeSaves
2471 then mark it as such */
2472 FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
2474 /* if interrupt service routine */
2475 /* then it cannot have arguments */
2476 if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
2478 if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
2479 werror (E_INT_ARGS, sym->name);
2480 FUNC_ARGS(sym->type)=NULL;
2484 if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type))
2486 werror (E_SHADOWREGS_NO_ISR, sym->name);
2489 for (argCnt=1, acargs = FUNC_ARGS(sym->type);
2491 acargs=acargs->next, argCnt++) {
2493 // this can happen for reentrant functions
2494 werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2495 // the show must go on: synthesize a name and symbol
2496 SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
2497 acargs->sym = newSymbol (acargs->name, 1);
2498 SPEC_OCLS (acargs->etype) = istack;
2499 acargs->sym->type = copyLinkChain (acargs->type);
2500 acargs->sym->etype = getSpec (acargs->sym->type);
2501 acargs->sym->_isparm = 1;
2502 strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
2503 } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) {
2505 werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
2510 /*JCF: Mark the register bank as used*/
2511 RegBankUsed[FUNC_REGBANK (sym->type)] = 1;
2513 if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
2514 return 1; /* not defined nothing more to check */
2516 /* check if body already present */
2517 if (csym && IFFUNC_HASBODY(csym->type))
2519 werror (E_FUNC_BODY, sym->name);
2523 /* check the return value type */
2524 if (compareType (csym->type, sym->type) <= 0)
2526 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
2527 printFromToType(csym->type, sym->type);
2531 if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
2533 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
2536 /* I don't think this is necessary for interrupts. An isr is a */
2537 /* root in the calling tree. */
2538 if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) &&
2539 (!FUNC_ISISR (sym->type)))
2541 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
2544 if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
2546 werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
2549 /* Really, reentrant should match regardless of argCnt, but */
2550 /* this breaks some existing code (the fp lib functions). If */
2551 /* the first argument is always passed the same way, this */
2552 /* lax checking is ok (but may not be true for in future ports) */
2553 if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type)
2556 //printf("argCnt = %d\n",argCnt);
2557 werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant");
2560 if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type))
2562 werror (E_PREV_DEF_CONFLICT, csym->name, "wparam");
2565 if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type))
2567 werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
2571 /* compare expected args with actual args */
2572 exargs = FUNC_ARGS(csym->type);
2573 acargs = FUNC_ARGS(sym->type);
2575 /* for all the expected args do */
2578 exargs = exargs->next, acargs = acargs->next, argCnt++)
2580 if (getenv("DEBUG_SANITY")) {
2581 fprintf (stderr, "checkFunction: %s ", exargs->name);
2583 /* make sure the type is complete and sane */
2584 checkTypeSanity(exargs->etype, exargs->name);
2586 /* If the actual argument is an array, any prototype
2587 * will have modified it to a pointer. Duplicate that
2590 if (IS_AGGREGATE (acargs->type))
2592 checkValue = copyValue (acargs);
2593 aggregateToPointer (checkValue);
2597 checkValue = acargs;
2600 if (compareType (exargs->type, checkValue->type) <= 0)
2602 werror (E_ARG_TYPE, argCnt);
2603 printFromToType(exargs->type, checkValue->type);
2608 /* if one them ended we have a problem */
2609 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
2610 (!exargs && acargs && !IS_VOID (acargs->type)))
2611 werror (E_ARG_COUNT);
2613 /* replace with this defition */
2614 sym->cdef = csym->cdef;
2615 deleteSym (SymbolTab, csym, csym->name);
2616 deleteFromSeg(csym);
2617 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
2618 if (IS_EXTERN (csym->etype) && !
2619 IS_EXTERN (sym->etype))
2621 addSet (&publics, sym);
2626 /*------------------------------------------------------------------*/
2627 /* cdbStructBlock - calls struct printing for a blcks */
2628 /*------------------------------------------------------------------*/
2629 void cdbStructBlock (int block)
2632 bucket **table = StructTab;
2635 /* go thru the entire table */
2636 for (i = 0; i < 256; i++)
2638 for (chain = table[i]; chain; chain = chain->next)
2640 if (chain->block >= block)
2643 debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
2649 /*-----------------------------------------------------------------*/
2650 /* processFuncPtrArgs - does some processing with args of func ptrs*/
2651 /*-----------------------------------------------------------------*/
2653 processFuncPtrArgs (sym_link * funcType)
2655 value *val = FUNC_ARGS(funcType);
2657 /* if it is void then remove parameters */
2658 if (val && IS_VOID (val->type))
2660 FUNC_ARGS(funcType) = NULL;
2665 /*-----------------------------------------------------------------*/
2666 /* processFuncArgs - does some processing with function args */
2667 /*-----------------------------------------------------------------*/
2669 processFuncArgs (symbol * func)
2673 sym_link *funcType=func->type;
2675 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
2676 fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
2678 /* find the function declaration within the type */
2679 while (funcType && !IS_FUNC(funcType))
2680 funcType=funcType->next;
2682 /* if this function has variable argument list */
2683 /* then make the function a reentrant one */
2684 if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
2685 FUNC_ISREENT(funcType)=1;
2687 /* check if this function is defined as calleeSaves
2688 then mark it as such */
2689 FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
2691 /* loop thru all the arguments */
2692 val = FUNC_ARGS(funcType);
2694 /* if it is void then remove parameters */
2695 if (val && IS_VOID (val->type))
2697 FUNC_ARGS(funcType) = NULL;
2701 /* reset regparm for the port */
2702 (*port->reset_regparms) ();
2704 /* if any of the arguments is an aggregate */
2705 /* change it to pointer to the same type */
2709 char buffer[SDCC_NAME_MAX+1];
2711 SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
2712 checkTypeSanity (val->etype, buffer);
2714 /* mark it as a register parameter if
2715 the function does not have VA_ARG
2716 and as port dictates */
2717 if (!IFFUNC_HASVARARGS(funcType) &&
2718 (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
2720 SPEC_REGPARM (val->etype) = 1;
2721 SPEC_ARGREG(val->etype) = argreg;
2722 } else if (IFFUNC_ISREENT(funcType)) {
2723 FUNC_HASSTACKPARM(funcType) = 1;
2726 if (IS_AGGREGATE (val->type))
2728 aggregateToPointer (val);
2735 /* if this is an internal generated function call */
2737 /* ignore --stack-auto for this one, we don't know how it is compiled */
2738 /* simply trust on --int-long-reent or --float-reent */
2739 if (IFFUNC_ISREENT(funcType)) {
2743 /* if this function is reentrant or */
2744 /* automatics r 2b stacked then nothing */
2745 if (IFFUNC_ISREENT (funcType) || options.stackAuto)
2749 val = FUNC_ARGS(funcType);
2754 /* if a symbolname is not given */
2755 /* synthesize a variable name */
2758 SNPRINTF (val->name, sizeof(val->name),
2759 "_%s_PARM_%d", func->name, pNum++);
2760 val->sym = newSymbol (val->name, 1);
2761 if (SPEC_SCLS(val->etype) == S_BIT)
2762 SPEC_OCLS (val->etype) = bit;
2764 SPEC_OCLS (val->etype) = port->mem.default_local_map;
2765 val->sym->type = copyLinkChain (val->type);
2766 val->sym->etype = getSpec (val->sym->type);
2767 val->sym->_isparm = 1;
2768 strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2770 /* ?? static functions shouldn't imply static parameters - EEP */
2771 if (IS_SPEC(func->etype)) {
2772 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2773 SPEC_STAT (func->etype);
2776 addSymChain (&val->sym);
2779 else /* symbol name given create synth name */
2782 SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
2783 strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
2784 val->sym->_isparm = 1;
2785 if (SPEC_SCLS(val->etype) == S_BIT)
2786 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
2788 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
2789 port->mem.default_local_map;
2792 /* ?? static functions shouldn't imply static parameters - EEP */
2793 if (IS_SPEC(func->etype)) {
2794 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
2795 SPEC_STAT (func->etype);
2799 if (SPEC_OCLS (val->sym->etype) == pdata)
2800 val->sym->iaccess = 1;
2801 if (!isinSet(operKeyReset, val->sym)) {
2802 addSet (&operKeyReset, val->sym);
2803 applyToSet (operKeyReset, resetParmKey);
2809 /*-----------------------------------------------------------------*/
2810 /* isSymbolEqual - compares two symbols return 1 if they match */
2811 /*-----------------------------------------------------------------*/
2813 isSymbolEqual (symbol * dest, symbol * src)
2815 /* if pointers match then equal */
2819 /* if one of them is null then don't match */
2823 /* if both of them have rname match on rname */
2824 if (dest->rname[0] && src->rname[0])
2825 return (!strcmp (dest->rname, src->rname));
2827 /* otherwise match on name */
2828 return (!strcmp (dest->name, src->name));
2831 void PT(sym_link *type)
2833 printTypeChain(type,0);
2835 /*-----------------------------------------------------------------*/
2836 /* printTypeChain - prints the type chain in human readable form */
2837 /*-----------------------------------------------------------------*/
2839 printTypeChain (sym_link * start, FILE * of)
2850 dbuf_init (&dbuf, 1024);
2851 dbuf_printTypeChain (start, &dbuf);
2852 dbuf_write_and_destroy (&dbuf, of);
2859 dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
2862 sym_link * type, * search;
2866 dbuf_append_str (dbuf, "void");
2870 /* Print the chain as it is written in the source: */
2871 /* start with the last entry. */
2872 /* However, the storage class at the end of the */
2873 /* chain reall applies to the first in the chain! */
2875 for (type = start; type && type->next; type = type->next)
2878 scls=SPEC_SCLS(type);
2886 case S_DATA: dbuf_append_str (dbuf, "data-"); break;
2887 case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break;
2888 case S_SFR: dbuf_append_str (dbuf, "sfr-"); break;
2889 case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break;
2890 case S_CODE: dbuf_append_str (dbuf, "code-"); break;
2891 case S_IDATA: dbuf_append_str (dbuf, "idata-"); break;
2892 case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break;
2893 case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break;
2894 case S_STACK: dbuf_append_str (dbuf, "stack-"); break;
2895 case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break;
2896 case S_BIT: dbuf_append_str (dbuf, "bit-"); break;
2897 case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break;
2904 if (!IS_FUNC(type)) {
2905 if (DCL_PTR_VOLATILE (type)) {
2906 dbuf_append_str (dbuf, "volatile-");
2908 if (DCL_PTR_CONST (type)) {
2909 dbuf_append_str (dbuf, "const-");
2911 if (DCL_PTR_RESTRICT (type)) {
2912 dbuf_append_str (dbuf, "restrict-");
2915 switch (DCL_TYPE (type))
2918 dbuf_printf (dbuf, "function %s %s",
2919 (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
2920 (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
2921 dbuf_append_str (dbuf, "( ");
2922 for (args = FUNC_ARGS(type);
2925 dbuf_printTypeChain(args->type, dbuf);
2927 dbuf_append_str (dbuf, ", ");
2929 dbuf_append_str (dbuf, ") ");
2932 dbuf_append_str (dbuf, "generic* ");
2935 dbuf_append_str (dbuf, "code* ");
2938 dbuf_append_str (dbuf, "xdata* ");
2941 dbuf_append_str (dbuf, "eeprom* ");
2944 dbuf_append_str (dbuf, "near* ");
2947 dbuf_append_str (dbuf, "idata* ");
2950 dbuf_append_str (dbuf, "pdata* ");
2953 dbuf_append_str (dbuf, "unknown* ");
2956 if (DCL_ELEM(type)) {
2957 dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type));
2959 dbuf_append_str (dbuf, "[] ");
2966 if (SPEC_VOLATILE (type))
2967 dbuf_append_str (dbuf, "volatile-");
2968 if (SPEC_CONST (type))
2969 dbuf_append_str (dbuf, "const-");
2970 if (SPEC_USIGN (type))
2971 dbuf_append_str (dbuf, "unsigned-");
2972 switch (SPEC_NOUN (type))
2976 dbuf_append_str (dbuf, "long-");
2977 dbuf_append_str (dbuf, "int");
2981 dbuf_append_str (dbuf, "char");
2985 dbuf_append_str (dbuf, "void");
2989 dbuf_append_str (dbuf, "float");
2993 dbuf_append_str (dbuf, "fixed16x16");
2997 dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
3001 dbuf_append_str (dbuf, "sbit");
3005 dbuf_append_str (dbuf, "bit");
3009 dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3013 dbuf_append_str (dbuf, "double");
3017 dbuf_append_str (dbuf, "unknown type");
3021 /* search entry in list before "type" */
3022 for (search = start; search && search->next != type;)
3023 search = search->next;
3026 dbuf_append_char(dbuf, ' ');
3030 /*--------------------------------------------------------------------*/
3031 /* printTypeChainRaw - prints the type chain in human readable form */
3032 /* in the raw data structure ordering */
3033 /*--------------------------------------------------------------------*/
3035 printTypeChainRaw (sym_link * start, FILE * of)
3048 fprintf (of, "void");
3058 if (!IS_FUNC(type)) {
3059 if (DCL_PTR_VOLATILE (type)) {
3060 fprintf (of, "volatile-");
3062 if (DCL_PTR_CONST (type)) {
3063 fprintf (of, "const-");
3065 if (DCL_PTR_RESTRICT (type)) {
3066 fprintf (of, "restrict-");
3069 switch (DCL_TYPE (type))
3072 if (IFFUNC_ISINLINE(type)) {
3073 fprintf (of, "inline-");
3075 fprintf (of, "function %s %s",
3076 (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
3077 (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
3079 for (args = FUNC_ARGS(type);
3082 printTypeChain(args->type, of);
3089 fprintf (of, "generic* ");
3092 fprintf (of, "code* ");
3095 fprintf (of, "xdata* ");
3098 fprintf (of, "eeprom* ");
3101 fprintf (of, "near* ");
3104 fprintf (of, "idata* ");
3107 fprintf (of, "pdata* ");
3110 fprintf (of, "unknown* ");
3113 if (DCL_ELEM(type)) {
3114 fprintf (of, "[%d] ", DCL_ELEM(type));
3116 fprintf (of, "[] ");
3120 if (DCL_TSPEC(type))
3123 printTypeChainRaw(DCL_TSPEC(type), of);
3127 else if (IS_SPEC (type))
3129 switch (SPEC_SCLS (type))
3131 case S_DATA: fprintf (of, "data-"); break;
3132 case S_XDATA: fprintf (of, "xdata-"); break;
3133 case S_SFR: fprintf (of, "sfr-"); break;
3134 case S_SBIT: fprintf (of, "sbit-"); break;
3135 case S_CODE: fprintf (of, "code-"); break;
3136 case S_IDATA: fprintf (of, "idata-"); break;
3137 case S_PDATA: fprintf (of, "pdata-"); break;
3138 case S_LITERAL: fprintf (of, "literal-"); break;
3139 case S_STACK: fprintf (of, "stack-"); break;
3140 case S_XSTACK: fprintf (of, "xstack-"); break;
3141 case S_BIT: fprintf (of, "bit-"); break;
3142 case S_EEPROM: fprintf (of, "eeprom-"); break;
3145 if (SPEC_VOLATILE (type))
3146 fprintf (of, "volatile-");
3147 if (SPEC_CONST (type))
3148 fprintf (of, "const-");
3149 if (SPEC_USIGN (type))
3150 fprintf (of, "unsigned-");
3151 switch (SPEC_NOUN (type))
3155 fprintf (of, "long-");
3156 fprintf (of, "int");
3160 fprintf (of, "char");
3164 fprintf (of, "void");
3168 fprintf (of, "float");
3172 fprintf (of, "fixed16x16");
3176 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
3180 fprintf (of, "sbit");
3184 fprintf (of, "bit");
3188 fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
3192 fprintf (of, "double");
3196 fprintf (of, "unknown type");
3201 fprintf (of, "NOT_SPEC_OR_DECL");
3211 /*-----------------------------------------------------------------*/
3212 /* powof2 - returns power of two for the number if number is pow 2 */
3213 /*-----------------------------------------------------------------*/
3215 powof2 (TYPE_TARGET_ULONG num)
3228 if (n1s > 1 || nshifts == 0)
3244 symbol *__fps16x16_add;
3245 symbol *__fps16x16_sub;
3246 symbol *__fps16x16_mul;
3247 symbol *__fps16x16_div;
3248 symbol *__fps16x16_eq;
3249 symbol *__fps16x16_neq;
3250 symbol *__fps16x16_lt;
3251 symbol *__fps16x16_lteq;
3252 symbol *__fps16x16_gt;
3253 symbol *__fps16x16_gteq;
3255 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3256 symbol *__muldiv[3][3][2];
3257 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
3258 sym_link *__multypes[3][2];
3259 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
3260 symbol *__conv[2][3][2];
3261 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */
3262 symbol *__fp16x16conv[2][4][2];
3263 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
3264 symbol *__rlrr[2][3][2];
3266 sym_link *floatType;
3267 sym_link *fixed16x16Type;
3270 _mangleFunctionName(char *in)
3272 if (port->getMangledFunctionName)
3274 return port->getMangledFunctionName(in);
3282 /*-----------------------------------------------------------------*/
3283 /* typeFromStr - create a typechain from an encoded string */
3284 /* basic types - 'c' - char */
3289 /* 'q' - fixed16x16 */
3291 /* '*' - pointer - default (GPOINTER) */
3292 /* modifiers - 'u' - unsigned */
3293 /* pointer modifiers - 'g' - generic */
3297 /* 'F' - function */
3298 /* examples : "ig*" - generic int * */
3299 /* "cx*" - char xdata * */
3300 /* "ui" - unsigned int */
3301 /*-----------------------------------------------------------------*/
3302 sym_link *typeFromStr (char *s)
3304 sym_link *r = newLink(DECLARATOR);
3316 r->class = SPECIFIER;
3317 SPEC_NOUN(r) = V_CHAR;
3321 r->class = SPECIFIER;
3322 SPEC_NOUN(r) = V_INT;
3325 r->class = SPECIFIER;
3326 SPEC_NOUN(r) = V_INT;
3330 r->class = SPECIFIER;
3331 SPEC_NOUN(r) = V_FLOAT;
3334 r->class = SPECIFIER;
3335 SPEC_NOUN(r) = V_FIXED16X16;
3338 r->class = SPECIFIER;
3339 SPEC_NOUN(r) = V_VOID;
3342 DCL_TYPE(r) = port->unqualified_pointer;
3349 assert(*(s+1)=='*');
3350 nr = newLink(DECLARATOR);
3355 DCL_TYPE(r) = GPOINTER;
3358 DCL_TYPE(r) = FPOINTER;
3361 DCL_TYPE(r) = CPOINTER;
3364 DCL_TYPE(r) = POINTER;
3367 DCL_TYPE(r) = FUNCTION;
3368 nr = newLink(DECLARATOR);
3371 DCL_TYPE(r) = CPOINTER;
3377 werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
3378 "typeFromStr: unknown type");
3381 if (IS_SPEC(r) && usign) {
3390 /*-----------------------------------------------------------------*/
3391 /* initCSupport - create functions for C support routines */
3392 /*-----------------------------------------------------------------*/
3396 const char *smuldivmod[] =
3400 const char *sbwd[] =
3402 "char", "int", "long", "fixed16x16",
3404 const char *fp16x16sbwd[] =
3406 "char", "int", "long", "float",
3412 const char *srlrr[] =
3417 int bwd, su, muldivmod, tofrom, rlrr;
3419 if (getenv("SDCC_NO_C_SUPPORT")) {
3420 /* for debugging only */
3424 floatType = newFloatLink ();
3425 fixed16x16Type = newFixed16x16Link ();
3427 for (bwd = 0; bwd < 3; bwd++)
3444 __multypes[bwd][0] = l;
3445 __multypes[bwd][1] = copyLinkChain (l);
3446 SPEC_USIGN (__multypes[bwd][1]) = 1;
3449 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
3450 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
3451 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
3452 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
3453 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
3454 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
3455 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
3456 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
3457 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
3458 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
3460 __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3461 __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3462 __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3463 __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent);
3464 __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3465 __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3466 __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3467 __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3468 __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3469 __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent);
3472 for (tofrom = 0; tofrom < 2; tofrom++)
3474 for (bwd = 0; bwd < 3; bwd++)
3476 for (su = 0; su < 2; su++)
3480 SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
3481 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
3485 SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
3486 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
3492 for (tofrom = 0; tofrom < 2; tofrom++)
3494 for (bwd = 0; bwd < 4; bwd++)
3496 for (su = 0; su < 2; su++)
3500 SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
3502 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
3504 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent);
3508 SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
3510 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
3512 __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent);
3519 for (muldivmod = 0; muldivmod < 3; muldivmod++)
3521 for (bwd = 0; bwd < 3; bwd++)
3523 for (su = 0; su < 2; su++)
3525 SNPRINTF (buffer, sizeof(buffer),
3527 smuldivmod[muldivmod],
3530 __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3531 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3536 muluint() and mulsint() resp. mululong() and mulslong() return the same result.
3537 Therefore they've been merged into mulint() and mullong().
3540 for (bwd = 0; bwd < 3; bwd++)
3542 for (su = 0; su < 2; su++)
3544 for (muldivmod = 1; muldivmod < 3; muldivmod++)
3546 /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
3547 if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0)
3549 SNPRINTF (buffer, sizeof(buffer),
3551 smuldivmod[muldivmod],
3554 __muldiv[muldivmod][bwd][su] = funcOfType (
3555 _mangleFunctionName(buffer),
3556 __multypes[bwd][su],
3557 __multypes[bwd][su],
3559 options.intlong_rent);
3560 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3566 if (TARGET_IS_PIC16)
3568 /* PIC16 port wants __divschar/__modschar to return an int, so that both
3569 * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
3570 * (first one would have to be sign extended, second one must not be).
3571 * Similarly, modschar should be handled, but the iCode introduces cast
3572 * here and forces '% : s8 x s8 -> s8' ... */
3574 for (muldivmod = 1; muldivmod < 2; muldivmod++) {
3575 SNPRINTF (buffer, sizeof(buffer),
3577 smuldivmod[muldivmod],
3580 __muldiv[muldivmod][bwd][su] = funcOfType (
3581 _mangleFunctionName(buffer),
3583 __multypes[bwd][su],
3585 options.intlong_rent);
3586 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3594 for (su = 0; su < 2; su++)
3596 /* muluchar and mulschar are still separate functions, because e.g. the z80
3597 port is sign/zero-extending to int before calling mulint() */
3598 SNPRINTF (buffer, sizeof(buffer),
3600 smuldivmod[muldivmod],
3603 __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3604 FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
3608 /* word and doubleword */
3609 for (bwd = 1; bwd < 3; bwd++)
3612 SNPRINTF (buffer, sizeof(buffer),
3614 smuldivmod[muldivmod],
3616 __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
3617 FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
3618 /* signed = unsigned */
3619 __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
3622 for (rlrr = 0; rlrr < 2; rlrr++)
3624 for (bwd = 0; bwd < 3; bwd++)
3626 for (su = 0; su < 2; su++)
3628 SNPRINTF (buffer, sizeof(buffer),
3633 __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
3634 FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
3640 /*-----------------------------------------------------------------*/
3641 /* initBuiltIns - create prototypes for builtin functions */
3642 /*-----------------------------------------------------------------*/
3648 if (!port->builtintable) return ;
3650 for (i = 0 ; port->builtintable[i].name ; i++) {
3651 sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
3652 port->builtintable[i].nParms,port->builtintable[i].parm_types);
3653 FUNC_ISBUILTIN(sym->type) = 1;
3654 FUNC_ISREENT(sym->type) = 0; /* can never be reentrant */
3658 sym_link *validateLink(sym_link *l,
3665 if (l && l->class==select)
3670 "Internal error: validateLink failed in %s(%s) @ %s:%u:"
3671 " expected %s, got %s\n",
3672 macro, args, file, line,
3673 DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
3675 return l; // never reached, makes compiler happy.
3678 /*--------------------------------------------------------------------*/
3679 /* newEnumType - create an integer type compatible with enumerations */
3680 /*--------------------------------------------------------------------*/
3682 newEnumType (symbol *enumlist)
3690 type = newLink (SPECIFIER);
3691 SPEC_NOUN (type) = V_INT;
3695 /* Determine the range of the enumerated values */
3697 min = max = (int) ulFromVal (valFromType (sym->type));
3698 for (sym = sym->next; sym; sym = sym->next)
3700 v = (int) ulFromVal (valFromType (sym->type));
3707 /* Determine the smallest integer type that is compatible with this range */
3708 type = newLink (SPECIFIER);
3709 if (min>=0 && max<=255)
3711 SPEC_NOUN (type) = V_CHAR;
3712 SPEC_USIGN (type) = 1;
3714 else if (min>=-128 && max<=127)
3716 SPEC_NOUN (type) = V_CHAR;
3718 else if (min>=0 && max<=65535)
3720 SPEC_NOUN (type) = V_INT;
3721 SPEC_USIGN (type) = 1;
3723 else if (min>=-32768 && max<=32767)
3725 SPEC_NOUN (type) = V_INT;
3729 SPEC_NOUN (type) = V_INT;
3730 SPEC_LONG (type) = 1;
3732 SPEC_USIGN (type) = 1;