X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=433afeafc7ffa0b9cc7147f80f2982896016d46d;hb=863a13df07e59f59b4c2ad965dfad13777f5c696;hp=07b39065482ad52a1a113c45d9a89debf013ed6f;hpb=74bfe960542de56b1479c755682e23e9686abebf;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 07b39065..433afeaf 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -30,7 +30,7 @@ char *nounName(sym_link *sl) { { case V_INT: { if (SPEC_LONG(sl)) return "long"; - if (SPEC_SHORT(sl)) return "short"; + if (sl->select.s._short) return "short"; return "int"; } case V_FLOAT: return "float"; @@ -98,13 +98,19 @@ addSym (bucket ** stab, void *sym, char *sname, int level, - int block) + int block, + int checkType) { int i; /* index into the hash Table */ bucket *bp; /* temp bucket * */ - /* Make sure sym is a symbol and not a structdef */ - if (StructTab!=stab) checkTypeSanity(((symbol *)sym)->etype, sname); + if (checkType) { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "addSym: %s ", sname); + } + /* make sure the type is complete and sane */ + checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name); + } /* the symbols are always added at the head of the list */ i = hashKey (sname); @@ -211,13 +217,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 */ @@ -312,9 +317,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 */ @@ -406,7 +415,7 @@ addDecl (symbol * sym, int type, sym_link * p) { if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail) { - sym->etype = mergeSpec (sym->etype, head); + sym->etype = mergeSpec (sym->etype, head, sym->name); } else { @@ -426,13 +435,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)) @@ -452,38 +461,63 @@ addDecl (symbol * sym, int type, sym_link * p) checkTypeSanity: prevent the user from doing e.g.: unsigned float uf; ------------------------------------------------------------------*/ -void checkTypeSanity(sym_link *dest, char *name) { +void checkTypeSanity(sym_link *etype, char *name) { char *noun; - if (!dest) { - //printf ("sanity check skipped for %s\n", name); + if (!etype) { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name); + } + return; + } + + if (!IS_SPEC(etype)) { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name); + } return; } - noun=nounName(dest); + noun=nounName(etype); - //printf ("checking sanity for %s\n", name); + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype); + } - if ((SPEC_NOUN(dest)==V_CHAR || - SPEC_NOUN(dest)==V_FLOAT || - SPEC_NOUN(dest)==V_DOUBLE || - SPEC_NOUN(dest)==V_VOID) && - (SPEC_SHORT(dest) || SPEC_LONG(dest))) { + if ((SPEC_NOUN(etype)==V_CHAR || + SPEC_NOUN(etype)==V_FLOAT || + SPEC_NOUN(etype)==V_DOUBLE || + SPEC_NOUN(etype)==V_VOID) && + (etype->select.s._short || SPEC_LONG(etype))) { // long or short for char float double or void werror (E_LONG_OR_SHORT_INVALID, noun, name); } - if ((SPEC_NOUN(dest)==V_FLOAT || - SPEC_NOUN(dest)==V_DOUBLE || - SPEC_NOUN(dest)==V_VOID) && - (SPEC_SIGNED(dest) || SPEC_USIGN(dest))) { + if ((SPEC_NOUN(etype)==V_FLOAT || + SPEC_NOUN(etype)==V_DOUBLE || + SPEC_NOUN(etype)==V_VOID) && + (etype->select.s._signed || SPEC_USIGN(etype))) { // signed or unsigned for float double or void werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name); } - if (SPEC_SIGNED(dest) && SPEC_USIGN(dest)) { + + // special case for "short" + if (etype->select.s._short) { + SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT; + etype->select.s._short = 0; + } + + /* if no noun e.g. + "const a;" or "data b;" or "signed s" or "long l" + assume an int */ + if (!SPEC_NOUN(etype)) { + SPEC_NOUN(etype)=V_INT; + } + + if (etype->select.s._signed && SPEC_USIGN(etype)) { // signed AND unsigned werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name); } - if (SPEC_SHORT(dest) && SPEC_LONG(dest)) { + if (etype->select.s._short && SPEC_LONG(etype)) { // short AND long werror (E_LONG_AND_SHORT_INVALID, noun, name); } @@ -494,30 +528,81 @@ void checkTypeSanity(sym_link *dest, char *name) { /* mergeSpec - merges two specifiers and returns the new one */ /*------------------------------------------------------------------*/ sym_link * -mergeSpec (sym_link * dest, sym_link * src) +mergeSpec (sym_link * dest, sym_link * src, char *name) { - /* we shouldn't redeclare the type */ - if ((SPEC_NOUN (dest) && SPEC_NOUN (src)) && - (SPEC_NOUN(dest) != SPEC_NOUN(src))) { - werror(E_TWO_OR_MORE_DATA_TYPES, yylval.yychar); + 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); } - /* if noun different then src overrides */ - if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest)) - SPEC_NOUN (dest) = SPEC_NOUN (src); + if (SPEC_NOUN(src)) { + if (!SPEC_NOUN(dest)) { + SPEC_NOUN(dest)=SPEC_NOUN(src); + } else { + /* we shouldn't redeclare the type */ + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "mergeSpec: "); + } + werror(E_TWO_OR_MORE_DATA_TYPES, name); + } + } + + if (SPEC_SCLS(src)) { + /* if destination has no storage class */ + if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) { + SPEC_SCLS (dest) = SPEC_SCLS (src); + } else { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "mergeSpec: "); + } + werror(E_TWO_OR_MORE_STORAGE_CLASSES, name); + } + } - /* if destination has no storage class */ - if (!SPEC_SCLS (dest) || - ((SPEC_SCLS(dest) == S_CONSTANT || SPEC_SCLS(dest) == S_REGISTER) && - SPEC_SCLS (src))) - SPEC_SCLS (dest) = SPEC_SCLS (src); - /* special case for const */ /* copy all the specifications */ + + // we really should do: +#if 0 + if (SPEC_what(src)) { + if (SPEC_what(dest)) { + werror(W_DUPLICATE_SPEC, "what"); + } + SPEC_what(dst)|=SPEC_what(src); + } +#endif + // but there are more important thing right now + SPEC_LONG (dest) |= SPEC_LONG (src); - SPEC_SHORT (dest) |= SPEC_SHORT (src); + dest->select.s._short|=src->select.s._short; SPEC_USIGN (dest) |= SPEC_USIGN (src); - SPEC_SIGNED (dest) |= SPEC_SIGNED (src); + dest->select.s._signed|=src->select.s._signed; SPEC_STAT (dest) |= SPEC_STAT (src); SPEC_EXTR (dest) |= SPEC_EXTR (src); SPEC_ABSA (dest) |= SPEC_ABSA (src); @@ -537,7 +622,7 @@ mergeSpec (sym_link * dest, sym_link * src) if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL) SPEC_STRUCT (dest) = SPEC_STRUCT (src); - return dest; + return symlink; } /*------------------------------------------------------------------*/ @@ -660,7 +745,7 @@ getSize (sym_link * p) switch (SPEC_NOUN (p)) { /* depending on the specifier type */ case V_INT: - return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE)); + return (IS_LONG (p) ? LONGSIZE : INTSIZE); case V_FLOAT: return FLOATSIZE; case V_CHAR: @@ -719,7 +804,7 @@ bitsForType (sym_link * p) switch (SPEC_NOUN (p)) { /* depending on the specifier type */ case V_INT: - return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8)); + return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8); case V_FLOAT: return FLOATSIZE * 8; case V_CHAR: @@ -863,49 +948,37 @@ 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 (1 || 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); - } - 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); - } - } - addSym (SymbolTab, sym, sym->name, sym->level, sym->block); + /* add new entry */ + addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1); } } @@ -1023,7 +1096,7 @@ compStructSize (int su, structdef * sdef) } } else { - checkDecl (loop); + checkDecl (loop, 1); sum += getSize (loop->type); } @@ -1055,13 +1128,20 @@ 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); + } + if (strcmp(sym->name, "_testsGlobal")==0) { + printf ("oach\n"); + } + /* type is literal can happen foe enums change to auto */ if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype)) SPEC_SCLS (sym->etype) = S_AUTO; - + /* if sfr or sbit then must also be */ /* volatile the initial value will be xlated */ /* to an absolute address */ @@ -1078,26 +1158,24 @@ checkSClass (symbol * sym) sym->ival = NULL; } } - + /* if absolute address given then it mark it as volatile */ if (IS_ABSOLUTE (sym->etype)) SPEC_VOLATILE (sym->etype) = 1; - + /* global variables declared const put into code */ if (sym->level == 0 && - SPEC_SCLS (sym->etype) == S_CONSTANT) - { - SPEC_SCLS (sym->etype) = S_CODE; - SPEC_CONST (sym->etype) = 1; - } - + SPEC_CONST (sym->etype)) { + SPEC_SCLS (sym->etype) = S_CODE; + } + /* global variable in code space is a constant */ if (sym->level == 0 && SPEC_SCLS (sym->etype) == S_CODE && port->mem.code_ro) SPEC_CONST (sym->etype) = 1; - + /* if bit variable then no storage class can be */ /* specified since bit is already a storage */ @@ -1118,23 +1196,22 @@ checkSClass (symbol * sym) sym->ival = NULL; } - /* 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 && - SPEC_SCLS (sym->etype) != S_CONSTANT)) - { - werror (E_AUTO_ASSUMED, sym->name); + /* if this is an atomatic symbol */ + if (sym->level && (options.stackAuto || reentrant)) { + if ((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)) { SPEC_SCLS (sym->etype) = S_AUTO; + } else { + /* storage class may only be specified for statics */ + if (!IS_STATIC(sym->etype)) { + werror (E_AUTO_ASSUMED, sym->name); + } } - + } + /* automatic symbols cannot be given */ /* an absolute address ignore it */ if (sym->level && @@ -1161,15 +1238,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 */ @@ -1219,10 +1298,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 @@ -1339,10 +1418,12 @@ 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; - + /* if result is a literal then make not so */ if (IS_LITERAL (reType)) SPEC_SCLS (reType) = S_REGISTER; @@ -1350,11 +1431,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; @@ -1371,15 +1452,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; @@ -1401,17 +1481,6 @@ checkType (sym_link * dest, sym_link * src) SPEC_NOUN (src) == V_VOID) return -1; - /* char === to short */ - if (SPEC_NOUN (dest) == V_CHAR && - SPEC_NOUN (src) == V_INT && - SPEC_SHORT (src)) - return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2); - - if (SPEC_NOUN (src) == V_CHAR && - SPEC_NOUN (dest) == V_INT && - SPEC_SHORT (dest)) - return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2); - /* if they are both bitfields then if the lengths and starts don't match */ if (IS_BITFIELD (dest) && IS_BITFIELD (src) && @@ -1441,17 +1510,14 @@ checkType (sym_link * dest, sym_link * src) if (SPEC_LONG (dest) != SPEC_LONG (src)) return -1; - if (SPEC_SHORT (dest) != SPEC_SHORT (src)) - return -1; - if (SPEC_USIGN (dest) != SPEC_USIGN (src)) - return -2; + return -1; return 1; } /*------------------------------------------------------------------*/ -/* inCalleeSaveList - return 1 if found in calle save list */ +/* inCalleeSaveList - return 1 if found in callee save list */ /*------------------------------------------------------------------*/ bool inCalleeSaveList (char *s) @@ -1542,8 +1608,16 @@ checkFunction (symbol * sym) { symbol *csym; value *exargs, *acargs; + value *checkValue; int argCnt = 0; + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "checkFunction: %s ", sym->name); + } + + /* make sure the type is complete and sane */ + checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name); + /* if not type then some kind of error */ if (!sym->type) return 0; @@ -1589,13 +1663,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; @@ -1604,13 +1678,16 @@ checkFunction (symbol * sym) if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype)) { werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt"); - return 0; } if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype)) { werror (E_PREV_DEF_CONFLICT, csym->name, "using"); - return 0; + } + + if (SPEC_NAKED (csym->etype) != SPEC_NAKED (sym->etype)) + { + werror (E_PREV_DEF_CONFLICT, csym->name, "_naked"); } /* compare expected agrs with actual args */ @@ -1622,7 +1699,12 @@ checkFunction (symbol * sym) exargs && acargs; exargs = exargs->next, acargs = acargs->next, argCnt++) { - value *checkValue; + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "checkFunction: %s ", exargs->name); + } + /* make sure the type is complete and sane */ + checkTypeSanity(exargs->etype, exargs->name); + /* If the actual argument is an array, any prototype * will have modified it to a pointer. Duplicate that * change here. @@ -1637,7 +1719,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; @@ -1652,7 +1734,7 @@ checkFunction (symbol * sym) /* replace with this defition */ sym->cdef = csym->cdef; deleteSym (SymbolTab, csym, csym->name); - addSym (SymbolTab, sym, sym->name, sym->level, sym->block); + addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1); if (IS_EXTERN (csym->etype) && ! IS_EXTERN (sym->etype)) { @@ -1791,10 +1873,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) { @@ -1802,61 +1885,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; } } @@ -1874,21 +1966,19 @@ printTypeChain (sym_link * type, FILE * of) case V_INT: if (IS_LONG (type)) fprintf (of, "long "); - if (IS_SHORT (type)) - fprintf (of, "short "); - 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: @@ -1896,7 +1986,7 @@ printTypeChain (sym_link * type, FILE * of) break; case V_SBIT: - fprintf (of, "sbit "); + fprintf (of, "sbit"); break; case V_BIT: @@ -1904,15 +1994,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"); @@ -1921,7 +2016,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)); @@ -1969,8 +2064,6 @@ cdbTypeInfo (sym_link * type, FILE * of) case V_INT: if (IS_LONG (type)) fprintf (of, "SL"); - else if (IS_SHORT (type)) - fprintf (of, "SS"); else fprintf (of, "SI"); break; @@ -2160,22 +2253,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; } } @@ -2197,8 +2289,17 @@ initCSupport () { "s", "u" }; + const char *srlrr[] = + { + "rl", "rr" + }; - int bwd, su, muldivmod, tofrom; + int bwd, su, muldivmod, tofrom, rlrr; + + if (getenv("SDCC_NO_C_SUPPORT")) { + /* for debugging only */ + return; + } floatType = newFloatLink (); @@ -2244,12 +2345,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); } } } @@ -2265,10 +2366,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; } } }