X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=72f323ab3437b7d0de6f0fec90d132b1d5ffc86b;hb=HEAD;hp=5bb73d5a97a47b4db30d8fc2cdea951f72e3009f;hpb=a408d9da29a7cd633e158f65770f223a83210a90;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 5bb73d5a..72f323ab 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -40,7 +40,7 @@ void printFromToType(sym_link *from, sym_link *to) { /* noun strings */ char *nounName(sym_link *sl) { - switch (SPEC_NOUN(sl)) + switch (SPEC_NOUN(sl)) { case V_INT: { if (SPEC_LONG(sl)) return "long"; @@ -70,7 +70,7 @@ bucket *enumTab[256]; /* enumerated table */ /*------------------------------------------------------------------*/ /* initSymt () - initialises symbol table related stuff */ /*------------------------------------------------------------------*/ -void +void initSymt () { int i = 0; @@ -81,7 +81,7 @@ initSymt () } /*-----------------------------------------------------------------*/ -/* newBucket - allocates & returns a new bucket */ +/* newBucket - allocates & returns a new bucket */ /*-----------------------------------------------------------------*/ bucket * newBucket () @@ -96,7 +96,7 @@ newBucket () /*-----------------------------------------------------------------*/ /* hashKey - computes the hashkey given a symbol name */ /*-----------------------------------------------------------------*/ -int +int hashKey (const char *s) { unsigned long key = 0; @@ -109,7 +109,7 @@ hashKey (const char *s) /*-----------------------------------------------------------------*/ /* addSym - adds a symbol to the hash Table */ /*-----------------------------------------------------------------*/ -void +void addSym (bucket ** stab, void *sym, char *sname, @@ -118,7 +118,7 @@ addSym (bucket ** stab, int checkType) { int i; /* index into the hash Table */ - bucket *bp; /* temp bucket * */ + bucket *bp; /* temp bucket * */ if (checkType) { symbol *csym = (symbol *)sym; @@ -141,8 +141,8 @@ addSym (bucket ** stab, /* get a free entry */ bp = Safe_alloc ( sizeof (bucket)); - bp->sym = sym; /* update the symbol pointer */ - bp->level = level; /* update the nest level */ + bp->sym = sym; /* update the symbol pointer */ + bp->level = level; /* update the nest level */ bp->block = block; strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */ @@ -163,9 +163,9 @@ addSym (bucket ** stab, } /*-----------------------------------------------------------------*/ -/* deleteSym - deletes a symbol from the hash Table entry */ +/* deleteSym - deletes a symbol from the hash Table entry */ /*-----------------------------------------------------------------*/ -void +void deleteSym (bucket ** stab, void *sym, char *sname) { int i = 0; @@ -184,6 +184,7 @@ deleteSym (bucket ** stab, void *sym, char *sname) if (!bp) /* did not find it */ return; + /* if this is the first one in the chain */ if (!bp->prev) { @@ -199,11 +200,10 @@ deleteSym (bucket ** stab, void *sym, char *sname) bp->prev->next = bp->next; } - } /*-----------------------------------------------------------------*/ -/* findSym - finds a symbol in a table */ +/* findSym - finds a symbol in a table */ /*-----------------------------------------------------------------*/ void * findSym (bucket ** stab, void *sym, const char *sname) @@ -328,7 +328,7 @@ newStruct (char *tag) strncpyz (s->tag, tag, sizeof(s->tag)); /* copy the tag */ return s; } - + /*------------------------------------------------------------------*/ /* sclsFromPtr - Return the storage class a pointer points into. */ /* S_FIXED is returned for generic pointers or other */ @@ -363,7 +363,7 @@ sclsFromPtr(sym_link *ptr) /*------------------------------------------------------------------*/ /* pointerTypes - do the computation for the pointer types */ /*------------------------------------------------------------------*/ -void +void pointerTypes (sym_link * ptr, sym_link * type) { if (IS_SPEC (ptr)) @@ -376,7 +376,7 @@ pointerTypes (sym_link * ptr, sym_link * type) /* could not find it */ if (!ptr || IS_SPEC (ptr)) return; - + if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) { pointerTypes (ptr->next, type); return; @@ -436,7 +436,7 @@ pointerTypes (sym_link * ptr, sym_link * type) /*------------------------------------------------------------------*/ /* addDecl - adds a declarator @ the end of a chain */ /*------------------------------------------------------------------*/ -void +void addDecl (symbol * sym, int type, sym_link * p) { static sym_link *empty = NULL; @@ -545,19 +545,19 @@ void checkTypeSanity(sym_link *etype, char *name) { fprintf (stderr, "checking sanity for %s %p\n", name, etype); } - if ((SPEC_NOUN(etype)==V_CHAR || - SPEC_NOUN(etype)==V_FLOAT || + if ((SPEC_NOUN(etype)==V_CHAR || + SPEC_NOUN(etype)==V_FLOAT || SPEC_NOUN(etype)==V_FIXED16X16 || - SPEC_NOUN(etype)==V_DOUBLE || + SPEC_NOUN(etype)==V_DOUBLE || SPEC_NOUN(etype)==V_VOID) && (SPEC_SHORT(etype) || SPEC_LONG(etype))) { // long or short for char float double or void werror (E_LONG_OR_SHORT_INVALID, noun, name); } - if ((SPEC_NOUN(etype)==V_FLOAT || + if ((SPEC_NOUN(etype)==V_FLOAT || SPEC_NOUN(etype)==V_FIXED16X16 || - SPEC_NOUN(etype)==V_DOUBLE || - SPEC_NOUN(etype)==V_VOID) && + SPEC_NOUN(etype)==V_DOUBLE || + SPEC_NOUN(etype)==V_VOID) && (etype->select.s.b_signed || SPEC_USIGN(etype))) { // signed or unsigned for float double or void werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name); @@ -569,7 +569,7 @@ void checkTypeSanity(sym_link *etype, char *name) { SPEC_SHORT(etype) = 0; } - /* if no noun e.g. + /* if no noun e.g. "const a;" or "data b;" or "signed s" or "long l" assume an int */ if (!SPEC_NOUN(etype)) { @@ -585,14 +585,13 @@ void checkTypeSanity(sym_link *etype, char *name) { } if (etype->select.s.b_signed && SPEC_USIGN(etype)) { - // signed AND unsigned + // signed AND unsigned werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name); } if (SPEC_SHORT(etype) && SPEC_LONG(etype)) { // short AND long werror (E_LONG_AND_SHORT_INVALID, noun, name); } - } /*------------------------------------------------------------------*/ @@ -623,7 +622,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) 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) { @@ -638,7 +637,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) /* copy all the specifications */ - // we really should do: + // we really should do: #if 0 if (SPEC_what(src)) { if (SPEC_what(dest)) { @@ -668,11 +667,11 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) SPEC_ENUM (dest) |= SPEC_ENUM (src); if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest)) SPEC_ARGREG(dest) = SPEC_ARGREG(src); - + if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL) SPEC_STRUCT (dest) = SPEC_STRUCT (src); - /* these are the only function attributes that will be set + /* these are the only function attributes that will be set in a specifier while parsing */ FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src); FUNC_BANKED(dest) |= FUNC_BANKED(src); @@ -690,9 +689,9 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) return dest; } -/*------------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ /* genSymName - generates and returns a name used for anonymous vars */ -/*------------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ char * genSymName (int level) { @@ -747,7 +746,7 @@ newFloatLink () } /*------------------------------------------------------------------*/ -/* newFixed16x16Link - a new Float type */ +/* newFixed16x16Link - a new Float type */ /*------------------------------------------------------------------*/ sym_link * newFixed16x16Link () @@ -806,7 +805,7 @@ newBoolLink () /*------------------------------------------------------------------*/ /* getSize - returns size of a type chain in bytes */ /*------------------------------------------------------------------*/ -unsigned int +unsigned int getSize (sym_link * p) { /* if nothing return 0 */ @@ -847,7 +846,7 @@ getSize (sym_link * p) if (DCL_ELEM(p)) { return DCL_ELEM (p) * getSize (p->next); } else { - // werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + // werror (E_INTERNAL_ERROR, __FILE__, __LINE__, // "can not tell the size of an array[]"); return 0; } @@ -908,7 +907,7 @@ checkStructFlexArray (symbol *sym, sym_link *p) /*------------------------------------------------------------------*/ /* bitsForType - returns # of bits required to store this type */ /*------------------------------------------------------------------*/ -unsigned int +unsigned int bitsForType (sym_link * p) { /* if nothing return 0 */ @@ -1007,7 +1006,7 @@ copySymbol (symbol * src) } /*------------------------------------------------------------------*/ -/* reverseSyms - reverses the links for a symbol chain */ +/* reverseSyms - reverses the links for a symbol chain */ /*------------------------------------------------------------------*/ symbol * reverseSyms (symbol * sym) @@ -1032,7 +1031,7 @@ reverseSyms (symbol * sym) } /*------------------------------------------------------------------*/ -/* reverseLink - reverses the links for a type chain */ +/* reverseLink - reverses the links for a type chain */ /*------------------------------------------------------------------*/ sym_link * reverseLink (sym_link * type) @@ -1059,7 +1058,7 @@ reverseLink (sym_link * type) /*------------------------------------------------------------------*/ /* addSymChain - adds a symbol chain to the symboltable */ /*------------------------------------------------------------------*/ -void +void addSymChain (symbol ** symHead) { symbol *sym = *symHead; @@ -1082,24 +1081,20 @@ addSymChain (symbol ** symHead) DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival); } - /* if already exists in the symbol table then check if - 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 already exists in the symbol table on the same level */ if ((csym = findSymWithLevel (SymbolTab, sym)) && csym->level == sym->level) { /* if not formal parameter and not in file scope then show symbol redefined error - else check if symbols have conpatible types */ + else check if symbols have compatible types */ if (!sym->_isparm && sym->level > 0) error = 1; else { - /* If the previous definition was for an array with incomplete */ - /* type, and the new definition has completed the type, update */ - /* the original type to match */ + /* If the previous definition was for an array with incomplete + type, and the new definition has completed the type, update + the original type to match */ if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY) { @@ -1156,6 +1151,14 @@ addSymChain (symbol ** symHead) if (csym->ival && !sym->ival) sym->ival = csym->ival; + if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype)) + { + /* if none of symbols is a compiler defined function + and at least one is not extern + then set the new symbol to non extern */ + SPEC_EXTR(sym->etype) = SPEC_EXTR(csym->etype); + } + /* delete current entry */ deleteSym (SymbolTab, csym, csym->name); deleteFromSeg(csym); @@ -1176,7 +1179,7 @@ addSymChain (symbol ** symHead) /*------------------------------------------------------------------*/ /* funcInChain - DCL Type 'FUNCTION' found in type chain */ /*------------------------------------------------------------------*/ -int +int funcInChain (sym_link * lnk) { while (lnk) @@ -1209,6 +1212,8 @@ structElemType (sym_link * stype, value * id) etype = getSpec (type); SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? SPEC_SCLS (etype) : SPEC_SCLS (petype)); + SPEC_OCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? + SPEC_OCLS (etype) : SPEC_OCLS (petype)); if (IS_SPEC (type)) SPEC_CONST (type) |= SPEC_CONST (stype); else @@ -1245,7 +1250,7 @@ getStructElement (structdef * sdef, symbol * sym) /*------------------------------------------------------------------*/ /* compStructSize - computes the size of a structure */ /*------------------------------------------------------------------*/ -int +int compStructSize (int su, structdef * sdef) { int sum = 0, usum = 0; @@ -1267,6 +1272,8 @@ compStructSize (int su, structdef * sdef) /* if this is a bit field */ if (loop->bitVar) { + SPEC_BUNNAMED (loop->etype) = loop->bitUnnamed; + /* change it to a unsigned bit */ SPEC_NOUN (loop->etype) = V_BITFIELD; /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */ @@ -1274,16 +1281,17 @@ compStructSize (int su, structdef * sdef) if (!loop->etype->select.s.b_signed) SPEC_USIGN(loop->etype) = 1; - SPEC_BLEN (loop->etype) = loop->bitVar; - if (loop->bitVar == BITVAR_PAD) { /* A zero length bitfield forces padding */ - SPEC_BSTR (loop->etype) = bitOffset; SPEC_BLEN (loop->etype) = 0; - bitOffset = 8; + SPEC_BSTR (loop->etype) = bitOffset; + if (bitOffset > 0) + bitOffset = 8; /* padding is not needed when at bit 0 */ loop->offset = sum; } else { + SPEC_BLEN (loop->etype) = loop->bitVar; + if (bitOffset == 8) { bitOffset = 0; sum++; @@ -1302,7 +1310,7 @@ compStructSize (int su, structdef * sdef) loop->offset = sum; SPEC_BSTR (loop->etype) = bitOffset; bitOffset += loop->bitVar; - } + } else { if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) { /* if PIC16 && enviroment variable is set, then @@ -1399,12 +1407,12 @@ promoteAnonStructs (int su, structdef * sdef) /* Found an anonymous struct/union. Replace it */ /* with the fields it contains and adjust all */ /* the offsets */ - + base = field->offset; subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields); if (!subfield) continue; /* just in case it's empty */ - + *tofield = subfield; for (;;) { @@ -1423,7 +1431,7 @@ promoteAnonStructs (int su, structdef * sdef) } dupfield = dupfield->next; } - + subfield->offset += base; if (subfield->next) subfield = subfield->next; @@ -1443,26 +1451,26 @@ promoteAnonStructs (int su, structdef * sdef) /*------------------------------------------------------------------*/ /* checkSClass - check the storage class specification */ /*------------------------------------------------------------------*/ -static void +static void checkSClass (symbol * sym, int isProto) { sym_link *t; - + if (getenv("DEBUG_SANITY")) { fprintf (stderr, "checkSClass: %s \n", sym->name); } - + /* type is literal can happen for 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 */ if (SPEC_SCLS (sym->etype) == S_SBIT || SPEC_SCLS (sym->etype) == S_SFR) { SPEC_VOLATILE (sym->etype) = 1; } - + /* make sure restrict is only used with pointers */ if (SPEC_RESTRICT (sym->etype)) { @@ -1480,7 +1488,7 @@ checkSClass (symbol * sym, int isProto) } t = t->next; } - + /* if absolute address given then it mark it as volatile -- except in the PIC port */ @@ -1491,7 +1499,7 @@ checkSClass (symbol * sym, int isProto) if (IS_ABSOLUTE (sym->etype)) SPEC_VOLATILE (sym->etype) = 1; - + if (TARGET_IS_MCS51 && IS_ABSOLUTE (sym->etype) && SPEC_SCLS (sym->etype) == S_SFR) @@ -1651,7 +1659,7 @@ checkSClass (symbol * sym, int isProto) * control this allocation, but the code was originally that way, and * changing it for non-390 ports breaks the compiler badly. */ - bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? + bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 1 : options.useXstack; SPEC_SCLS (sym->etype) = (useXdata ? S_XDATA : S_FIXED); @@ -1662,7 +1670,7 @@ checkSClass (symbol * sym, int isProto) /*------------------------------------------------------------------*/ /* changePointer - change pointer to functions */ /*------------------------------------------------------------------*/ -void +void changePointer (sym_link * p) { @@ -1681,14 +1689,14 @@ changePointer (sym_link * p) } /*------------------------------------------------------------------*/ -/* checkDecl - does semantic validation of a declaration */ +/* checkDecl - does semantic validation of a declaration */ /*------------------------------------------------------------------*/ -int +int checkDecl (symbol * sym, int isProto) { - checkSClass (sym, isProto); /* check the storage class */ - changePointer (sym->type); /* change pointers if required */ + checkSClass (sym, isProto); /* check the storage class */ + changePointer (sym->type); /* change pointers if required */ /* if this is an array without any dimension then update the dimension from the initial value */ @@ -1724,7 +1732,7 @@ copyLinkChain (sym_link * p) /* cleanUpBlock - cleansup the symbol table specified for all the */ /* symbols in the given block */ /*------------------------------------------------------------------*/ -void +void cleanUpBlock (bucket ** table, int block) { int i; @@ -1747,7 +1755,7 @@ cleanUpBlock (bucket ** table, int block) /* cleanUpLevel - cleansup the symbol table specified for all the */ /* symbols in the given level */ /*------------------------------------------------------------------*/ -void +void cleanUpLevel (bucket ** table, int level) { int i; @@ -1781,7 +1789,7 @@ computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType) SPEC_USIGN (reType) = SPEC_USIGN (etype1); return reType; } - + if (SPEC_USIGN (etype1)) { if ( IS_LITERAL (etype2) @@ -1861,12 +1869,12 @@ computeType (sym_link * type1, sym_link * type2, rType = newFloatLink (); else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) ) rType = newFloatLink (); - + /* if both are bitvars choose the larger one */ else if (IS_BITVAR (etype1) && IS_BITVAR (etype2)) rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ? - copyLinkChain (type1) : copyLinkChain (type1); - + copyLinkChain (type1) : copyLinkChain (type2); + /* if only one of them is a bit variable then the other one prevails */ else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2)) { @@ -2010,7 +2018,7 @@ computeType (sym_link * type1, sym_link * type2, 2 * 100 = 200; - ToDo: document '|', '^' and '&' - + Homework: - why is (200 * 200 < 0) true? - why is { char l = 200, r = 200; (r * l > 0) } true? */ @@ -2022,7 +2030,7 @@ computeType (sym_link * type1, sym_link * type2, && !(bitsForType (etype1) < bitsForType (reType)) /* char require special handling */ && !IS_CHAR (etype1)) - || /* same for 2nd operand */ + || /* same for 2nd operand */ (SPEC_USIGN (etype2) && !(bitsForType (etype2) < bitsForType (reType)) && !IS_CHAR (etype2)) @@ -2040,8 +2048,28 @@ computeType (sym_link * type1, sym_link * type2, return rType; } +int +comparePtrType (sym_link * dest, sym_link * src, bool bMustCast) +{ + int res; + + if (IS_VOID (src->next) && IS_VOID (dest->next)) + return bMustCast ? -1 : 1; + if ((IS_VOID (src->next) && !IS_VOID (dest->next)) || + (!IS_VOID (src->next) && IS_VOID (dest->next)) ) + return -1; + res = compareType (dest->next, src->next); + if (res == 1) + return bMustCast ? -1 : 1; + else if (res == -2) + return -2; + else + return 0; +} + /*--------------------------------------------------------------------*/ -/* compareType - will do type check return 1 if match, -1 if castable */ +/* compareType - will do type check return 1 if match, 0 if no match, */ +/* -1 if castable, -2 if only signedness differs */ /*--------------------------------------------------------------------*/ int compareType (sym_link * dest, sym_link * src) @@ -2067,7 +2095,7 @@ compareType (sym_link * dest, sym_link * src) return -1; if (IS_FUNC (dest->next) && IS_VOID(src->next)) return -1; - return compareType (dest->next, src->next); + return comparePtrType(dest, src, FALSE); } if (DCL_TYPE (src) == DCL_TYPE (dest)) @@ -2076,17 +2104,19 @@ compareType (sym_link * dest, sym_link * src) { //checkFunction(src,dest); } - return compareType (dest->next, src->next); + return comparePtrType(dest, src, FALSE); } if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) { return -1; } - if (IS_PTR (src) && + if (IS_PTR (src) && (IS_GENPTR (dest) || ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER)) )) - return -1; + { + return comparePtrType(dest, src, TRUE); + } if (IS_PTR (dest) && IS_ARRAY (src)) { value *val=aggregateToPointer (valFromType(src)); @@ -2105,6 +2135,9 @@ compareType (sym_link * dest, sym_link * src) return 0; } + if (IS_PTR (src) && IS_VOID (dest)) + return -1; + /* if one is a specifier and the other is not */ if ((IS_SPEC (src) && !IS_SPEC (dest)) || (IS_SPEC (dest) && !IS_SPEC (src))) @@ -2154,7 +2187,7 @@ compareType (sym_link * dest, sym_link * src) return -1; if (SPEC_USIGN (dest) != SPEC_USIGN (src)) - return -1; + return -2; return 1; } @@ -2166,7 +2199,7 @@ int compareTypeExact (sym_link * dest, sym_link * src, int level) { STORAGE_CLASS srcScls, destScls; - + if (!dest && !src) return 1; @@ -2232,7 +2265,7 @@ compareTypeExact (sym_link * dest, sym_link * src, int level) /* if one them ended we have a problem */ if ((exargs && !acargs && !IS_VOID (exargs->type)) || (!exargs && acargs && !IS_VOID (acargs->type))) - return 0; + return 0; return 1; } return compareTypeExact (dest->next, src->next, level); @@ -2269,7 +2302,7 @@ compareTypeExact (sym_link * dest, sym_link * src, int level) if (SPEC_SHORT (dest) != SPEC_SHORT (src)) return 0; } - + if (IS_STRUCT (dest)) { if (SPEC_STRUCT (dest) != SPEC_STRUCT (src)) @@ -2286,12 +2319,12 @@ compareTypeExact (sym_link * dest, sym_link * src, int level) return 0; if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src)) return 0; - + destScls = SPEC_SCLS (dest); srcScls = SPEC_SCLS (src); - + /* Compensate for const to const code change in checkSClass() */ - if (!level & port->mem.code_ro && SPEC_CONST (dest)) + if (((!level) & port->mem.code_ro) && SPEC_CONST (dest)) { if (srcScls == S_CODE && destScls == S_FIXED) destScls = S_CODE; @@ -2299,12 +2332,12 @@ compareTypeExact (sym_link * dest, sym_link * src, int level) srcScls = S_CODE; } - /* compensate for allocGlobal() */ + /* compensate for allocGlobal() */ if ((srcScls == S_FIXED || srcScls == S_AUTO) && port->mem.default_globl_map == xdata && !level) srcScls = S_XDATA; - + if (level>0 && !SPEC_STAT (dest)) { /* Compensate for hack-o-matic in checkSClass() */ @@ -2334,12 +2367,12 @@ compareTypeExact (sym_link * dest, sym_link * src, int level) #endif return 0; } - + return 1; } /*------------------------------------------------------------------*/ -/* inCalleeSaveList - return 1 if found in callee save list */ +/* inCalleeSaveList - return 1 if found in callee save list */ /*------------------------------------------------------------------*/ static int calleeCmp(void *p1, void *p2) @@ -2395,6 +2428,8 @@ aggregateToPointer (value * val) } break; case S_AUTO: + DCL_TYPE (val->type) = PTR_TYPE(SPEC_OCLS(val->etype)); + break; case S_DATA: case S_REGISTER: DCL_TYPE (val->type) = POINTER; @@ -2411,7 +2446,7 @@ aggregateToPointer (value * val) default: DCL_TYPE (val->type) = port->unqualified_pointer; } - + /* is there is a symbol associated then */ /* change the type of the symbol as well */ if (val->sym) @@ -2425,7 +2460,7 @@ aggregateToPointer (value * val) /*------------------------------------------------------------------*/ /* checkFunction - does all kinds of check on a function */ /*------------------------------------------------------------------*/ -int +int checkFunction (symbol * sym, symbol *csym) { value *exargs, *acargs; @@ -2441,7 +2476,7 @@ checkFunction (symbol * sym, symbol *csym) werror(E_SYNTAX_ERROR, sym->name); return 0; } - + /* move inline specifier from return type to function attributes */ if (IS_INLINE (sym->etype)) { @@ -2486,10 +2521,10 @@ checkFunction (symbol * sym, symbol *csym) werror (E_SHADOWREGS_NO_ISR, sym->name); } - for (argCnt=1, acargs = FUNC_ARGS(sym->type); - acargs; + for (argCnt=1, acargs = FUNC_ARGS(sym->type); + acargs; acargs=acargs->next, argCnt++) { - if (!acargs->sym) { + if (!acargs->sym) { // this can happen for reentrant functions werror(E_PARAM_NAME_OMITTED, sym->name, argCnt); // the show must go on: synthesize a name and symbol @@ -2500,13 +2535,16 @@ checkFunction (symbol * sym, symbol *csym) acargs->sym->etype = getSpec (acargs->sym->type); acargs->sym->_isparm = 1; strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname)); - } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { + } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { // synthesized name werror(E_PARAM_NAME_OMITTED, sym->name, argCnt); } } argCnt--; + /*JCF: Mark the register bank as used*/ + RegBankUsed[FUNC_REGBANK (sym->type)] = 1; + if (!csym && !(csym = findSym (SymbolTab, sym, sym->name))) return 1; /* not defined nothing more to check */ @@ -2538,9 +2576,6 @@ checkFunction (symbol * sym, symbol *csym) werror (E_PREV_DEF_CONFLICT, csym->name, "using"); } - /*JCF: Mark the register bank as used*/ - RegBankUsed[FUNC_REGBANK (sym->type)] = 1; - if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type)) { werror (E_PREV_DEF_CONFLICT, csym->name, "_naked"); @@ -2566,7 +2601,7 @@ checkFunction (symbol * sym, symbol *csym) { werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs"); } - + /* compare expected args with actual args */ exargs = FUNC_ARGS(csym->type); @@ -2649,7 +2684,7 @@ void cdbStructBlock (int block) /*-----------------------------------------------------------------*/ /* processFuncPtrArgs - does some processing with args of func ptrs*/ /*-----------------------------------------------------------------*/ -void +void processFuncPtrArgs (sym_link * funcType) { value *val = FUNC_ARGS(funcType); @@ -2665,7 +2700,7 @@ processFuncPtrArgs (sym_link * funcType) /*-----------------------------------------------------------------*/ /* processFuncArgs - does some processing with function args */ /*-----------------------------------------------------------------*/ -void +void processFuncArgs (symbol * func) { value *val; @@ -2707,10 +2742,10 @@ processFuncArgs (symbol * func) { int argreg = 0; char buffer[SDCC_NAME_MAX+1]; - + SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum); checkTypeSanity (val->etype, buffer); - + /* mark it as a register parameter if the function does not have VA_ARG and as port dictates */ @@ -2755,7 +2790,7 @@ processFuncArgs (symbol * func) /* synthesize a variable name */ if (!val->sym) { - SNPRINTF (val->name, sizeof(val->name), + SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++); val->sym = newSymbol (val->name, 1); if (SPEC_SCLS(val->etype) == S_BIT) @@ -2787,7 +2822,7 @@ processFuncArgs (symbol * func) else SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = port->mem.default_local_map; - + #if 0 /* ?? static functions shouldn't imply static parameters - EEP */ if (IS_SPEC(func->etype)) { @@ -2809,7 +2844,7 @@ processFuncArgs (symbol * func) /*-----------------------------------------------------------------*/ /* isSymbolEqual - compares two symbols return 1 if they match */ /*-----------------------------------------------------------------*/ -int +int isSymbolEqual (symbol * dest, symbol * src) { /* if pointers match then equal */ @@ -2881,7 +2916,7 @@ dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf) while (type) { if (type==start) { - switch (scls) + switch (scls) { case S_DATA: dbuf_append_str (dbuf, "data-"); break; case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break; @@ -2915,12 +2950,12 @@ dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf) switch (DCL_TYPE (type)) { case FUNCTION: - dbuf_printf (dbuf, "function %s %s", + dbuf_printf (dbuf, "function %s %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "), (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " ")); dbuf_append_str (dbuf, "( "); - for (args = FUNC_ARGS(type); - args; + for (args = FUNC_ARGS(type); + args; args=args->next) { dbuf_printTypeChain(args->type, dbuf); if (args->next) @@ -3050,7 +3085,7 @@ printTypeChainRaw (sym_link * start, FILE * of) } type = start; - + while (type) { if (IS_DECL (type)) @@ -3072,12 +3107,12 @@ printTypeChainRaw (sym_link * start, FILE * of) if (IFFUNC_ISINLINE(type)) { fprintf (of, "inline-"); } - fprintf (of, "function %s %s", + fprintf (of, "function %s %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "), (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " ")); fprintf (of, "( "); - for (args = FUNC_ARGS(type); - args; + for (args = FUNC_ARGS(type); + args; args=args->next) { printTypeChain(args->type, of); if (args->next) @@ -3126,7 +3161,7 @@ printTypeChainRaw (sym_link * start, FILE * of) } else if (IS_SPEC (type)) { - switch (SPEC_SCLS (type)) + switch (SPEC_SCLS (type)) { case S_DATA: fprintf (of, "data-"); break; case S_XDATA: fprintf (of, "xdata-"); break; @@ -3252,8 +3287,8 @@ symbol *__fps16x16_lteq; symbol *__fps16x16_gt; symbol *__fps16x16_gteq; -/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ -symbol *__muldiv[3][3][2]; +/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */ +symbol *__muldiv[3][3][4]; /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */ sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ @@ -3293,8 +3328,8 @@ _mangleFunctionName(char *in) /* pointer modifiers - 'g' - generic */ /* 'x' - xdata */ /* 'p' - code */ -/* 'd' - data */ -/* 'F' - function */ +/* 'd' - data */ +/* 'F' - function */ /* examples : "ig*" - generic int * */ /* "cx*" - char xdata * */ /* "ui" - unsigned int */ @@ -3307,7 +3342,7 @@ sym_link *typeFromStr (char *s) do { sym_link *nr; switch (*s) { - case 'u' : + case 'u' : usign = 1; s++; continue ; @@ -3374,7 +3409,7 @@ sym_link *typeFromStr (char *s) s++; break; default: - werror(E_INTERNAL_ERROR, __FILE__, __LINE__, + werror(E_INTERNAL_ERROR, __FILE__, __LINE__, "typeFromStr: unknown type"); break; } @@ -3390,7 +3425,7 @@ sym_link *typeFromStr (char *s) /*-----------------------------------------------------------------*/ /* initCSupport - create functions for C support routines */ /*-----------------------------------------------------------------*/ -void +void initCSupport () { const char *smuldivmod[] = @@ -3407,7 +3442,7 @@ initCSupport () }; const char *ssu[] = { - "s", "u" + "s", "su", "us", "u" }; const char *srlrr[] = { @@ -3477,12 +3512,12 @@ initCSupport () { if (tofrom) { - SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su*3], sbwd[bwd]); __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent); } else { - SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su*3], sbwd[bwd]); __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent); } } @@ -3497,7 +3532,7 @@ initCSupport () { if (tofrom) { - SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su*3], fp16x16sbwd[bwd]); if(bwd == 3) { __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent); } else @@ -3505,7 +3540,7 @@ initCSupport () } else { - SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su*3], fp16x16sbwd[bwd]); if(bwd == 3) { __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent); } else @@ -3525,7 +3560,7 @@ initCSupport () SNPRINTF (buffer, sizeof(buffer), "_%s%s%s", smuldivmod[muldivmod], - ssu[su], + ssu[su*3], sbwd[bwd]); __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; @@ -3537,7 +3572,34 @@ initCSupport () Therefore they've been merged into mulint() and mullong(). */ - for (bwd = 0; bwd < 3; bwd++) + /* byte */ + bwd = 0; + for (su = 0; su < 4; su++) + { + for (muldivmod = 0; muldivmod < 3; muldivmod++) + { + /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80 + port is sign/zero-extending to int before calling mulint() */ + /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */ + if (!TARGET_IS_PIC16 || muldivmod != 1 || su != 0) + { + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType ( + _mangleFunctionName(buffer), + __multypes[bwd][su%2], + __multypes[bwd][su/2], + 2, + options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } + } + } + + for (bwd = 1; bwd < 3; bwd++) { for (su = 0; su < 2; su++) { @@ -3549,7 +3611,7 @@ initCSupport () SNPRINTF (buffer, sizeof(buffer), "_%s%s%s", smuldivmod[muldivmod], - ssu[su], + ssu[su*3], sbwd[bwd]); __muldiv[muldivmod][bwd][su] = funcOfType ( _mangleFunctionName(buffer), @@ -3589,20 +3651,6 @@ initCSupport () /* mul only */ muldivmod = 0; - /* byte */ - bwd = 0; - for (su = 0; su < 2; su++) - { - /* muluchar and mulschar are still separate functions, because e.g. the z80 - port is sign/zero-extending to int before calling mulint() */ - SNPRINTF (buffer, sizeof(buffer), - "_%s%s%s", - smuldivmod[muldivmod], - ssu[su], - sbwd[bwd]); - __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); - FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; - } /* signed only */ su = 0; /* word and doubleword */ @@ -3628,7 +3676,7 @@ initCSupport () SNPRINTF (buffer, sizeof(buffer), "_%s%s%s", srlrr[rlrr], - ssu[su], + ssu[su*3], sbwd[bwd]); __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent); FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1; @@ -3661,15 +3709,15 @@ sym_link *validateLink(sym_link *l, const char select, const char *file, unsigned line) -{ +{ if (l && l->class==select) { return l; } - fprintf(stderr, + fprintf(stderr, "Internal error: validateLink failed in %s(%s) @ %s:%u:" " expected %s, got %s\n", - macro, args, file, line, + macro, args, file, line, DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link"); exit(EXIT_FAILURE); return l; // never reached, makes compiler happy. @@ -3691,7 +3739,7 @@ newEnumType (symbol *enumlist) SPEC_NOUN (type) = V_INT; return type; } - + /* Determine the range of the enumerated values */ sym = enumlist; min = max = (int) ulFromVal (valFromType (sym->type)); @@ -3731,6 +3779,6 @@ newEnumType (symbol *enumlist) if (min>=0) SPEC_USIGN (type) = 1; } - + return type; }