X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=77b03a7539247133beb29bf3eab3ec6309e17c70;hb=58151142d861d5ddf8d0de65544016fe6fa7e3c0;hp=98fd50febec73a622060274a4e75d3e0e6ec89b6;hpb=6812b951155467655aaaccb587131b8a403d2988;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 98fd50fe..77b03a75 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -72,7 +72,7 @@ newBucket () { bucket *bp; - bp = Safe_calloc (1, sizeof (bucket)); + bp = Safe_alloc ( sizeof (bucket)); return bp; } @@ -112,10 +112,16 @@ addSym (bucket ** stab, checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name); } + /* prevent overflow of the (r)name buffers */ + if (strlen(sname)>SDCC_SYMNAME_MAX) { + werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX); + sname[SDCC_SYMNAME_MAX]='\0'; + } + /* the symbols are always added at the head of the list */ i = hashKey (sname); /* get a free entry */ - bp = Safe_calloc (1, sizeof (bucket)); + bp = Safe_alloc ( sizeof (bucket)); bp->sym = sym; /* update the symbol pointer */ bp->level = level; /* update the nest level */ @@ -217,13 +223,12 @@ findSymWithLevel (bucket ** stab, symbol * sym) **/ while (bp) { - if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level) { /* if this is parameter then nothing else need to be checked */ if (((symbol *) (bp->sym))->_isparm) return (bp->sym); - /* if levels match then block numbers hsould also match */ + /* if levels match then block numbers should also match */ if (bp->level && bp->level == sym->level && bp->block == sym->block) return (bp->sym); /* if levels don't match then we are okay */ @@ -268,7 +273,7 @@ newSymbol (char *name, int scope) { symbol *sym; - sym = Safe_calloc (1, sizeof (symbol)); + sym = Safe_alloc ( sizeof (symbol)); strcpy (sym->name, name); /* copy the name */ sym->level = scope; /* set the level */ @@ -285,7 +290,7 @@ newLink () { sym_link *p; - p = Safe_calloc (1, sizeof (sym_link)); + p = Safe_alloc ( sizeof (sym_link)); return p; } @@ -298,7 +303,7 @@ newStruct (char *tag) { structdef *s; - s = Safe_calloc (1, sizeof (structdef)); + s = Safe_alloc ( sizeof (structdef)); strcpy (s->tag, tag); /* copy the tag */ return s; @@ -318,9 +323,13 @@ pointerTypes (sym_link * ptr, sym_link * type) ptr = ptr->next; /* could not find it */ - if (!ptr || IS_SPEC (ptr) || - DCL_TYPE (ptr) != UPOINTER) + if (!ptr || IS_SPEC (ptr)) + return; + + if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) { + pointerTypes (ptr->next, type); return; + } /* change the pointer type depending on the storage class of the type */ @@ -432,13 +441,13 @@ addDecl (symbol * sym, int type, sym_link * p) } } - /* if the type is a unknown pointer and has + /* if the type is an unknown pointer and has a tspec then take the storage class const & volatile attribute from the tspec & make it those of this symbol */ if (p && !IS_SPEC (p) && - DCL_TYPE (p) == UPOINTER && + //DCL_TYPE (p) == UPOINTER && DCL_TSPEC (p)) { if (!IS_SPEC (sym->etype)) @@ -499,7 +508,7 @@ void checkTypeSanity(sym_link *etype, char *name) { // special case for "short" if (etype->select.s._short) { - SPEC_NOUN(etype) = options.shortisint ? V_INT : V_CHAR; + SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT; etype->select.s._short = 0; } @@ -528,6 +537,33 @@ sym_link * mergeSpec (sym_link * dest, sym_link * src, char *name) { + sym_link *symlink=dest; + +#if 0 + if (!IS_SPEC(dest)) { + // This can happen for pointers, find the end type + while (dest && !IS_SPEC(dest)) + dest=dest->next; + } + if (!IS_SPEC(src)) { + // here we have a declarator as source, reverse them + symlink=src; + src=dest; + dest=symlink; + while (dest && !IS_SPEC(dest)) { + // and find the specifier + dest=dest->next; + } + } else { + symlink=dest; + } +#endif + + if (!IS_SPEC(dest) || !IS_SPEC(src)) { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator"); + exit (1); + } + if (getenv("DEBUG_mergeSpec")) { fprintf (stderr, "mergeSpec: \"%s\"\n", name); } @@ -592,7 +628,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL) SPEC_STRUCT (dest) = SPEC_STRUCT (src); - return dest; + return symlink; } /*------------------------------------------------------------------*/ @@ -918,48 +954,36 @@ addSymChain (symbol * symHead) symbol *sym = symHead; symbol *csym = NULL; - for (; sym != NULL; sym = sym->next) { changePointer(sym); + checkTypeSanity(sym->etype, sym->name); /* if already exists in the symbol table then check if - the previous was an extern definition if yes then + one of them is an extern definition if yes then then check if the type match, if the types match then delete the current entry and add the new entry */ if ((csym = findSymWithLevel (SymbolTab, sym)) && - csym->level == sym->level) - { - - /* previous definition extern ? */ - if (IS_EXTERN (csym->etype)) - { - /* do types match ? */ - if (checkType (csym->type, sym->type) != 1) - /* no then error */ - werror (E_DUPLICATE, csym->name); - - /* delete current entry */ - deleteSym (SymbolTab, csym, csym->name); - /* add new entry */ - addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1); - } - else /* not extern */ - werror (E_DUPLICATE, sym->name); + csym->level == sym->level) { + + /* one definition extern ? */ + if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) { + /* do types match ? */ + if (compareType (csym->type, sym->type) != 1) { + /* no then error */ + werror (E_EXTERN_MISMATCH, csym->name); + continue; + } + /* delete current entry */ + deleteSym (SymbolTab, csym, csym->name); + } else { + /* not extern */ + werror (E_DUPLICATE, sym->name); continue; } + } - /* check if previously defined */ - if (csym && csym->level == sym->level) - { - /* if the previous one was declared as extern */ - /* then check the type with the current one */ - if (IS_EXTERN (csym->etype)) - { - if (checkType (csym->type, sym->type) <= 0) - werror (W_EXTERN_MISMATCH, csym->name); - } - } + /* add new entry */ addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1); } } @@ -1078,7 +1102,7 @@ compStructSize (int su, structdef * sdef) } } else { - checkDecl (loop); + checkDecl (loop, 1); sum += getSize (loop->type); } @@ -1110,7 +1134,7 @@ compStructSize (int su, structdef * sdef) /* checkSClass - check the storage class specification */ /*------------------------------------------------------------------*/ static void -checkSClass (symbol * sym) +checkSClass (symbol * sym, int isProto) { if (getenv("DEBUG_SANITY")) { fprintf (stderr, "checkSClass: %s \n", sym->name); @@ -1178,23 +1202,6 @@ checkSClass (symbol * sym) sym->ival = NULL; } -#if 0 - /* if this is an automatic symbol then */ - /* storage class will be ignored and */ - /* symbol will be allocated on stack/ */ - /* data depending on flag */ - if (sym->level && - (options.stackAuto || reentrant) && - (SPEC_SCLS (sym->etype) != S_AUTO && - SPEC_SCLS (sym->etype) != S_FIXED && - SPEC_SCLS (sym->etype) != S_REGISTER && - SPEC_SCLS (sym->etype) != S_STACK && - SPEC_SCLS (sym->etype) != S_XSTACK)) - { - werror (E_AUTO_ASSUMED, sym->name); - SPEC_SCLS (sym->etype) = S_AUTO; - } -#else /* if this is an atomatic symbol */ if (sym->level && (options.stackAuto || reentrant)) { if ((SPEC_SCLS (sym->etype) == S_AUTO || @@ -1210,7 +1217,6 @@ checkSClass (symbol * sym) } } } -#endif /* automatic symbols cannot be given */ /* an absolute address ignore it */ @@ -1238,15 +1244,17 @@ checkSClass (symbol * sym) SPEC_BSTR (sym->etype) = 0; } - /* variables declared in CODE space must have */ - /* initializers if not an extern */ - if (SPEC_SCLS (sym->etype) == S_CODE && - sym->ival == NULL && - !sym->level && - port->mem.code_ro && - !IS_EXTERN (sym->etype) && - !funcInChain (sym->type)) - werror (E_CODE_NO_INIT, sym->name); + if (!isProto) { + /* variables declared in CODE space must have */ + /* initializers if not an extern */ + if (SPEC_SCLS (sym->etype) == S_CODE && + sym->ival == NULL && + //!sym->level && + port->mem.code_ro && + !IS_EXTERN (sym->etype) && + !funcInChain (sym->type)) + werror (E_CODE_NO_INIT, sym->name); + } /* if parameter or local variable then change */ /* the storage class to reflect where the var will go */ @@ -1296,10 +1304,10 @@ changePointer (symbol * sym) /* checkDecl - does semantic validation of a declaration */ /*------------------------------------------------------------------*/ int -checkDecl (symbol * sym) +checkDecl (symbol * sym, int isProto) { - checkSClass (sym); /* check the storage class */ + checkSClass (sym, isProto); /* check the storage class */ changePointer (sym); /* change pointers if required */ /* if this is an array without any dimension @@ -1416,10 +1424,14 @@ computeType (sym_link * type1, sym_link * type2) reType = getSpec (rType); - /* if either of them unsigned then make this unsigned */ - if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType)) + /* if either of them unsigned but not val then make this unsigned */ + if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || + (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && + !IS_FLOAT (reType)) SPEC_USIGN (reType) = 1; - + else + SPEC_USIGN (reType) = 0; + /* if result is a literal then make not so */ if (IS_LITERAL (reType)) SPEC_SCLS (reType) = S_REGISTER; @@ -1427,11 +1439,11 @@ computeType (sym_link * type1, sym_link * type2) return rType; } -/*------------------------------------------------------------------*/ -/* checkType - will do type check return 1 if match */ -/*------------------------------------------------------------------*/ +/*--------------------------------------------------------------------*/ +/* compareType - will do type check return 1 if match, -1 if castable */ +/*--------------------------------------------------------------------*/ int -checkType (sym_link * dest, sym_link * src) +compareType (sym_link * dest, sym_link * src) { if (!dest && !src) return 1; @@ -1448,15 +1460,14 @@ checkType (sym_link * dest, sym_link * src) if (IS_DECL (src)) { if (DCL_TYPE (src) == DCL_TYPE (dest)) - return checkType (dest->next, src->next); - else if (IS_PTR (src) && IS_PTR (dest)) + return compareType (dest->next, src->next); + if (IS_PTR (src) && IS_PTR (dest)) return -1; - else if (IS_PTR (dest) && IS_ARRAY (src)) + if (IS_PTR (dest) && IS_ARRAY (src)) return -1; - else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src)) - return -1 * checkType (dest->next, src); - else - return 0; + if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src)) + return -1 * compareType (dest->next, src); + return 0; } else if (IS_PTR (dest) && IS_INTEGRAL (src)) return -1; @@ -1508,7 +1519,7 @@ checkType (sym_link * dest, sym_link * src) return -1; if (SPEC_USIGN (dest) != SPEC_USIGN (src)) - return -2; + return -1; return 1; } @@ -1535,6 +1546,8 @@ inCalleeSaveList (char *s) void aggregateArgToPointer (value * val) { + int wasArray=IS_ARRAY(val->type); + if (IS_AGGREGATE (val->type)) { /* if this is a structure */ @@ -1587,6 +1600,12 @@ aggregateArgToPointer (value * val) default: DCL_TYPE (val->type) = GPOINTER; } + + if (wasArray) { + /* there is NO way to specify the storage of the pointer + associated with an array, so we make it the default */ + SPEC_SCLS(val->etype) = S_FIXED; + } /* is there is a symbol associated then */ /* change the type of the symbol as well */ @@ -1660,13 +1679,13 @@ checkFunction (symbol * sym) } /* check the return value type */ - if (checkType (csym->type, sym->type) <= 0) + if (compareType (csym->type, sym->type) <= 0) { werror (E_PREV_DEF_CONFLICT, csym->name, "type"); - werror (E_CONTINUE, "previous definition type "); + werror (W_CONTINUE, "previous definition type "); printTypeChain (csym->type, stderr); fprintf (stderr, "\n"); - werror (E_CONTINUE, "current definition type "); + werror (W_CONTINUE, "current definition type "); printTypeChain (sym->type, stderr); fprintf (stderr, "\n"); return 0; @@ -1687,7 +1706,7 @@ checkFunction (symbol * sym) werror (E_PREV_DEF_CONFLICT, csym->name, "_naked"); } - /* compare expected agrs with actual args */ + /* compare expected args with actual args */ exargs = csym->args; acargs = sym->args; @@ -1716,7 +1735,7 @@ checkFunction (symbol * sym) checkValue = acargs; } - if (checkType (exargs->type, checkValue->type) <= 0) + if (compareType (exargs->type, checkValue->type) <= 0) { werror (E_ARG_TYPE, argCnt); return 0; @@ -1870,10 +1889,11 @@ void PT(sym_link *type) /*-----------------------------------------------------------------*/ /* printTypeChain - prints the type chain in human readable form */ /*-----------------------------------------------------------------*/ -void -printTypeChain (sym_link * type, FILE * of) +void +printTypeChain (sym_link * start, FILE * of) { int nlr = 0; + sym_link * type, * search; if (!of) { @@ -1881,61 +1901,70 @@ printTypeChain (sym_link * type, FILE * of) nlr = 1; } + if (start==NULL) { + fprintf (of, "**err**"); + return; + } + + /* print the chain as it is written in the source: */ + /* start with the last entry */ + for (type = start; type && type->next; type = type->next) + ; while (type) { if (IS_DECL (type)) { - if (DCL_PTR_VOLATILE(type)) { + if (DCL_PTR_VOLATILE (type)) { fprintf (of, "volatile "); } switch (DCL_TYPE (type)) { case FUNCTION: - fprintf (of, "function "); + fprintf (of, "function"); break; case GPOINTER: - fprintf (of, "_generic * "); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "generic *"); break; case CPOINTER: - fprintf (of, "_code * "); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "code *"); break; case FPOINTER: - fprintf (of, "_far * "); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "far *"); break; case EEPPOINTER: - fprintf (of, "_eeprom * "); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "eeprom * "); break; case POINTER: - fprintf (of, "_near * "); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "near *"); break; case IPOINTER: - fprintf (of, "_idata *"); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "idata *"); break; case PPOINTER: - fprintf (of, "_pdata *"); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "pdata *"); break; case UPOINTER: - fprintf (of, " _unkown *"); if (DCL_PTR_CONST (type)) fprintf (of, "const "); + fprintf (of, "unkown *"); break; case ARRAY: - fprintf (of, "array of "); + fprintf (of, "array of"); break; } } @@ -1953,19 +1982,19 @@ printTypeChain (sym_link * type, FILE * of) case V_INT: if (IS_LONG (type)) fprintf (of, "long "); - fprintf (of, "int "); + fprintf (of, "int"); break; case V_CHAR: - fprintf (of, "char "); + fprintf (of, "char"); break; case V_VOID: - fprintf (of, "void "); + fprintf (of, "void"); break; case V_FLOAT: - fprintf (of, "float "); + fprintf (of, "float"); break; case V_STRUCT: @@ -1973,7 +2002,7 @@ printTypeChain (sym_link * type, FILE * of) break; case V_SBIT: - fprintf (of, "sbit "); + fprintf (of, "sbit"); break; case V_BIT: @@ -1981,15 +2010,20 @@ printTypeChain (sym_link * type, FILE * of) break; case V_DOUBLE: - fprintf (of, "double "); + fprintf (of, "double"); break; default: - fprintf (of, "unknown type "); + fprintf (of, "unknown type"); break; } } - type = type->next; + /* search entry in list before "type" */ + for (search = start; search && search->next != type;) + search = search->next; + type = search; + if (type) + fputc (' ', of); } if (nlr) fprintf (of, "\n"); @@ -1998,7 +2032,7 @@ printTypeChain (sym_link * type, FILE * of) /*-----------------------------------------------------------------*/ /* cdbTypeInfo - print the type information for debugger */ /*-----------------------------------------------------------------*/ -void +void cdbTypeInfo (sym_link * type, FILE * of) { fprintf (of, "{%d}", getSize (type)); @@ -2235,22 +2269,21 @@ symbol *__muldiv[3][3][2]; sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ symbol *__conv[2][3][2]; +/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ +symbol *__rlrr[2][3][2]; sym_link *floatType; -static void -_makeRegParam (symbol * sym) +static char * +_mangleFunctionName(char *in) { - value *val; - - val = sym->args; /* loop thru all the arguments */ - - /* reset regparm for the port */ - (*port->reset_regparms) (); - while (val) + if (port->getMangledFunctionName) { - SPEC_REGPARM (val->etype) = 1; - val = val->next; + return port->getMangledFunctionName(in); + } + else + { + return in; } } @@ -2272,8 +2305,17 @@ initCSupport () { "s", "u" }; + const char *srlrr[] = + { + "rl", "rr" + }; + + int bwd, su, muldivmod, tofrom, rlrr; - int bwd, su, muldivmod, tofrom; + if (getenv("SDCC_NO_C_SUPPORT")) { + /* for debugging only */ + return; + } floatType = newFloatLink (); @@ -2319,12 +2361,12 @@ initCSupport () if (tofrom) { sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]); - __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent); + __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent); } else { sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]); - __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent); + __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent); } } } @@ -2340,10 +2382,24 @@ initCSupport () smuldivmod[muldivmod], ssu[su], sbwd[bwd]); - __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); + __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1; - if (bwd < port->muldiv.force_reg_param_below) - _makeRegParam (__muldiv[muldivmod][bwd][su]); + } + } + } + + for (rlrr = 0; rlrr < 2; rlrr++) + { + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + sprintf (buffer, "_%s%s%s", + srlrr[rlrr], + ssu[su], + sbwd[bwd]); + __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent); + SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1; } } }