X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=72f323ab3437b7d0de6f0fec90d132b1d5ffc86b;hb=ae36c610fdb3dfcd4d850c6fe0bf193bd0e455db;hp=40e1fed661ed02d3e1d3172c0342813453db5a8c;hpb=998bc7b7fc11e191943ed839f790fff34b78df3b;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 40e1fed6..72f323ab 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -23,6 +23,7 @@ #include "common.h" #include "newalloc.h" +#include "dbuf_string.h" #include "SDCCsymt.h" @@ -39,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"; @@ -69,7 +70,7 @@ bucket *enumTab[256]; /* enumerated table */ /*------------------------------------------------------------------*/ /* initSymt () - initialises symbol table related stuff */ /*------------------------------------------------------------------*/ -void +void initSymt () { int i = 0; @@ -80,7 +81,7 @@ initSymt () } /*-----------------------------------------------------------------*/ -/* newBucket - allocates & returns a new bucket */ +/* newBucket - allocates & returns a new bucket */ /*-----------------------------------------------------------------*/ bucket * newBucket () @@ -95,7 +96,7 @@ newBucket () /*-----------------------------------------------------------------*/ /* hashKey - computes the hashkey given a symbol name */ /*-----------------------------------------------------------------*/ -int +int hashKey (const char *s) { unsigned long key = 0; @@ -108,7 +109,7 @@ hashKey (const char *s) /*-----------------------------------------------------------------*/ /* addSym - adds a symbol to the hash Table */ /*-----------------------------------------------------------------*/ -void +void addSym (bucket ** stab, void *sym, char *sname, @@ -117,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; @@ -140,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 */ @@ -162,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; @@ -183,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) { @@ -198,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) @@ -292,11 +293,11 @@ newSymbol (char *name, int scope) sym = Safe_alloc ( sizeof (symbol)); - strncpyz (sym->name, name, sizeof(sym->name)); /* copy the name */ - sym->level = scope; /* set the level */ + strncpyz (sym->name, name, sizeof(sym->name)); /* copy the name */ + sym->level = scope; /* set the level */ sym->block = currBlockno; - sym->lineDef = mylineno; /* set the line number */ - sym->fileDef = currFname; + sym->lineDef = lexLineno; /* set the line number */ + sym->fileDef = lexFilename; return sym; } @@ -327,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 */ @@ -362,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)) @@ -375,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; @@ -435,9 +436,10 @@ 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; sym_link *head; sym_link *tail; sym_link *t; @@ -445,6 +447,9 @@ addDecl (symbol * sym, int type, sym_link * p) if (getenv("SDCC_DEBUG_FUNCTION_POINTERS")) fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p); + if (empty == NULL) + empty = newLink(SPECIFIER); + /* if we are passed a link then set head & tail */ if (p) { @@ -464,28 +469,28 @@ addDecl (symbol * sym, int type, sym_link * p) sym->type = head; sym->etype = tail; } + else if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail) + { + sym->etype = mergeSpec (sym->etype, head, sym->name); + } + else if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail) + { + t = sym->type; + while (t->next != sym->etype) + t = t->next; + t->next = head; + tail->next = sym->etype; + } + else if (IS_FUNC (sym->type) && IS_SPEC (sym->type->next) && + !memcmp(sym->type->next, empty, sizeof(sym_link))) + { + sym->type->next = head; + sym->etype = tail; + } else { - if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail) - { - sym->etype = mergeSpec (sym->etype, head, sym->name); - } - else - { - if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail) - { - t = sym->type; - while (t->next != sym->etype) - t = t->next; - t->next = head; - tail->next = sym->etype; - } - else - { - sym->etype->next = head; - sym->etype = tail; - } - } + sym->etype->next = head; + sym->etype = tail; } /* if the type is an unknown pointer and has @@ -540,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); @@ -564,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)) { @@ -580,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); } - } /*------------------------------------------------------------------*/ @@ -618,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) { @@ -633,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)) { @@ -650,9 +654,11 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) dest->select.s.b_signed|=src->select.s.b_signed; SPEC_STAT (dest) |= SPEC_STAT (src); SPEC_EXTR (dest) |= SPEC_EXTR (src); + SPEC_INLINE (dest) |= SPEC_INLINE (src); SPEC_CONST(dest) |= SPEC_CONST (src); SPEC_ABSA (dest) |= SPEC_ABSA (src); SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src); + SPEC_RESTRICT (dest) |= SPEC_RESTRICT (src); SPEC_ADDR (dest) |= SPEC_ADDR (src); SPEC_OCLS (dest) = SPEC_OCLS (src); SPEC_BLEN (dest) |= SPEC_BLEN (src); @@ -661,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); @@ -678,13 +684,14 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src); FUNC_INTNO(dest) |= FUNC_INTNO(src); FUNC_REGBANK(dest) |= FUNC_REGBANK(src); + FUNC_ISINLINE (dest) |= FUNC_ISINLINE (src); return dest; } -/*------------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ /* genSymName - generates and returns a name used for anonymous vars */ -/*------------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ char * genSymName (int level) { @@ -739,7 +746,7 @@ newFloatLink () } /*------------------------------------------------------------------*/ -/* newFixed16x16Link - a new Float type */ +/* newFixed16x16Link - a new Float type */ /*------------------------------------------------------------------*/ sym_link * newFixed16x16Link () @@ -798,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 */ @@ -839,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; } @@ -900,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 */ @@ -999,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) @@ -1024,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) @@ -1051,7 +1058,7 @@ reverseLink (sym_link * type) /*------------------------------------------------------------------*/ /* addSymChain - adds a symbol chain to the symboltable */ /*------------------------------------------------------------------*/ -void +void addSymChain (symbol ** symHead) { symbol *sym = *symHead; @@ -1066,83 +1073,103 @@ addSymChain (symbol ** symHead) if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype))) checkDecl (sym, 0); - - /* 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 */ + else + { + /* if this is an array without any dimension + then update the dimension from the initial value */ + if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type)) + DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival); + } + + /* if already exists in the symbol table on the same level */ if ((csym = findSymWithLevel (SymbolTab, sym)) && - csym->level == sym->level) { + csym->level == sym->level) + { + /* if not formal parameter and not in file scope + then show symbol redefined error + 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 (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY + && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY) + { + if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type)) + DCL_ELEM(csym->type) = DCL_ELEM(sym->type); + } - /* 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) - { - if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type)) - DCL_ELEM(csym->type) = DCL_ELEM(sym->type); - } + #if 0 + /* If only one of the definitions used the "at" keyword, copy */ + /* the address to the other. */ + if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype) + && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype)) + { + SPEC_ABSA (sym->etype) = 1; + SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype); + } + if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype) + && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype)) + { + SPEC_ABSA (csym->etype) = 1; + SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype); + } + #endif - #if 0 - /* If only one of the definitions used the "at" keyword, copy */ - /* the address to the other. */ - if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype) - && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype)) - { - SPEC_ABSA (sym->etype) = 1; - SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype); - } - if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype) - && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype)) - { - SPEC_ABSA (csym->etype) = 1; - SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype); - } - #endif - - error = 0; - if (csym->ival && sym->ival) - error = 1; - if (compareTypeExact (csym->type, sym->type, sym->level) != 1) - error = 1; - - if (error) { - /* one definition extern ? */ - if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) - werror (E_EXTERN_MISMATCH, sym->name); - else - werror (E_DUPLICATE, sym->name); - werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF); - #if 0 - fprintf (stderr, "from type '"); - printTypeChain (csym->type, stderr); - if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype)) - fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype)); - fprintf (stderr, "'\nto type '"); - printTypeChain (sym->type, stderr); - if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype)) - fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype)); - fprintf (stderr, "'\n"); - #endif - continue; + error = 0; + if (csym->ival && sym->ival) + error = 1; + if (compareTypeExact (csym->type, sym->type, sym->level) != 1) + error = 1; + } + + if (error) + { + /* one definition extern ? */ + if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) + werror (E_EXTERN_MISMATCH, sym->name); + else + werror (E_DUPLICATE, sym->name); + werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF); + #if 0 + fprintf (stderr, "from type '"); + printTypeChain (csym->type, stderr); + if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype)) + fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype)); + fprintf (stderr, "'\nto type '"); + printTypeChain (sym->type, stderr); + if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype)) + fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype)); + fprintf (stderr, "'\n"); + #endif + continue; + } + + 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); + + symPtrPtr = symHead; + while (*symPtrPtr && *symPtrPtr != csym) + symPtrPtr = &(*symPtrPtr)->next; + if (*symPtrPtr == csym) + *symPtrPtr = csym->next; } - if (csym->ival && !sym->ival) - sym->ival = csym->ival; - - /* delete current entry */ - deleteSym (SymbolTab, csym, csym->name); - deleteFromSeg(csym); - - symPtrPtr = symHead; - while (*symPtrPtr && *symPtrPtr != csym) - symPtrPtr = &(*symPtrPtr)->next; - if (*symPtrPtr == csym) - *symPtrPtr = csym->next; - - } - /* add new entry */ addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1); } @@ -1152,7 +1179,7 @@ addSymChain (symbol ** symHead) /*------------------------------------------------------------------*/ /* funcInChain - DCL Type 'FUNCTION' found in type chain */ /*------------------------------------------------------------------*/ -int +int funcInChain (sym_link * lnk) { while (lnk) @@ -1175,7 +1202,7 @@ structElemType (sym_link * stype, value * id) sym_link *petype = getSpec (stype); if (fields && id) { - + /* look for the id */ while (fields) { @@ -1185,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 @@ -1196,7 +1225,7 @@ structElemType (sym_link * stype, value * id) } werror (E_NOT_MEMBER, id->name); - + // the show must go on return newIntLink(); } @@ -1221,134 +1250,137 @@ getStructElement (structdef * sdef, symbol * sym) /*------------------------------------------------------------------*/ /* compStructSize - computes the size of a structure */ /*------------------------------------------------------------------*/ -int +int compStructSize (int su, structdef * sdef) { - int sum = 0, usum = 0; - int bitOffset = 0; - symbol *loop; - - /* for the identifiers */ - loop = sdef->fields; - while (loop) { + int sum = 0, usum = 0; + int bitOffset = 0; + symbol *loop; + + /* for the identifiers */ + loop = sdef->fields; + while (loop) { + + /* create the internal name for this variable */ + SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name); + if (su == UNION) { + sum = 0; + bitOffset = 0; + } + SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0); + + /* 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: */ + /* a "plain" int bitfield is unsigned */ + if (!loop->etype->select.s.b_signed) + SPEC_USIGN(loop->etype) = 1; + + if (loop->bitVar == BITVAR_PAD) { + /* A zero length bitfield forces padding */ + SPEC_BLEN (loop->etype) = 0; + 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; - /* create the internal name for this variable */ - SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name); - if (su == UNION) { - sum = 0; - bitOffset = 0; + if (bitOffset == 8) { + bitOffset = 0; + sum++; } - SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0); - - /* if this is a bit field */ - if (loop->bitVar) { - - /* change it to a unsigned bit */ - SPEC_NOUN (loop->etype) = V_BITFIELD; - /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */ - /* a "plain" int bitfield is unsigned */ - 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; - loop->offset = sum; - } - else { - if (bitOffset == 8) { - bitOffset = 0; - sum++; - } - /* check if this fit into the remaining */ - /* bits of this byte else align it to the */ - /* next byte boundary */ - if (loop->bitVar <= (8 - bitOffset)) { - /* fits into current byte */ - loop->offset = sum; - SPEC_BSTR (loop->etype) = bitOffset; - bitOffset += loop->bitVar; - } - else if (!bitOffset) { - /* does not fit, but is already byte aligned */ - 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 - * tightly pack bitfields, this means that when a - * bitfield goes beyond byte alignment, do not - * automatically start allocatint from next byte, - * but also use the available bits first */ - fprintf(stderr, ": packing bitfields in structures\n"); - SPEC_BSTR (loop->etype) = bitOffset; - bitOffset += loop->bitVar; - loop->offset = (su == UNION ? sum = 0 : sum); - } else { - /* does not fit; need to realign first */ - sum++; - loop->offset = (su == UNION ? sum = 0 : sum); - bitOffset = 0; - SPEC_BSTR (loop->etype) = bitOffset; - bitOffset += loop->bitVar; - } - } - while (bitOffset>8) { - bitOffset -= 8; - sum++; - } - } + /* check if this fit into the remaining */ + /* bits of this byte else align it to the */ + /* next byte boundary */ + if (loop->bitVar <= (8 - bitOffset)) { + /* fits into current byte */ + loop->offset = sum; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + } + else if (!bitOffset) { + /* does not fit, but is already byte aligned */ + loop->offset = sum; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; } else { - /* This is a non-bit field. Make sure we are */ - /* byte aligned first */ - if (bitOffset) { - sum++; - loop->offset = (su == UNION ? sum = 0 : sum); - bitOffset = 0; - } - loop->offset = sum; - checkDecl (loop, 1); - sum += getSize (loop->type); - - /* search for "flexibel array members" */ - /* and do some syntax checks */ - if ( su == STRUCT - && checkStructFlexArray (loop, loop->type)) - { - /* found a "flexible array member" */ - sdef->b_flexArrayMember = TRUE; - /* is another struct-member following? */ - if (loop->next) - werror (E_FLEXARRAY_NOTATEND); - /* is it the first struct-member? */ - else if (loop == sdef->fields) - werror (E_FLEXARRAY_INEMPTYSTRCT); - } + if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) { + /* if PIC16 && enviroment variable is set, then + * tightly pack bitfields, this means that when a + * bitfield goes beyond byte alignment, do not + * automatically start allocatint from next byte, + * but also use the available bits first */ + fprintf(stderr, ": packing bitfields in structures\n"); + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + loop->offset = (su == UNION ? sum = 0 : sum); + } else { + /* does not fit; need to realign first */ + sum++; + loop->offset = (su == UNION ? sum = 0 : sum); + bitOffset = 0; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + } } - - loop = loop->next; - - /* if union then size = sizeof largest field */ - if (su == UNION) { - /* For UNION, round up after each field */ - sum += ((bitOffset+7)/8); - usum = max (usum, sum); + while (bitOffset>8) { + bitOffset -= 8; + sum++; } + } + } + else { + /* This is a non-bit field. Make sure we are */ + /* byte aligned first */ + if (bitOffset) { + sum++; + loop->offset = (su == UNION ? sum = 0 : sum); + bitOffset = 0; + } + loop->offset = sum; + checkDecl (loop, 1); + sum += getSize (loop->type); + + /* search for "flexibel array members" */ + /* and do some syntax checks */ + if ( su == STRUCT + && checkStructFlexArray (loop, loop->type)) + { + /* found a "flexible array member" */ + sdef->b_flexArrayMember = TRUE; + /* is another struct-member following? */ + if (loop->next) + werror (E_FLEXARRAY_NOTATEND); + /* is it the first struct-member? */ + else if (loop == sdef->fields) + werror (E_FLEXARRAY_INEMPTYSTRCT); + } + } + loop = loop->next; + + /* if union then size = sizeof largest field */ + if (su == UNION) { + /* For UNION, round up after each field */ + sum += ((bitOffset+7)/8); + usum = max (usum, sum); } - - /* For STRUCT, round up after all fields processed */ - if (su != UNION) - sum += ((bitOffset+7)/8); - return (su == UNION ? usum : sum); + } + + /* For STRUCT, round up after all fields processed */ + if (su != UNION) + sum += ((bitOffset+7)/8); + + return (su == UNION ? usum : sum); } /*-------------------------------------------------------------------*/ @@ -1375,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 (;;) { @@ -1399,7 +1431,7 @@ promoteAnonStructs (int su, structdef * sdef) } dupfield = dupfield->next; } - + subfield->offset += base; if (subfield->next) subfield = subfield->next; @@ -1419,27 +1451,44 @@ 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 */ + + /* 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)) + { + werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT); + SPEC_RESTRICT (sym->etype) = 0; + } + t = sym->type; + while (t) + { + if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !IS_PTR (t)) + { + werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT); + DCL_PTR_RESTRICT (t) = 0; + break; + } + t = t->next; + } + /* if absolute address given then it mark it as volatile -- except in the PIC port */ @@ -1450,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) @@ -1553,7 +1602,7 @@ checkSClass (symbol * sym, int isProto) /* automatic symbols cannot be given */ /* an absolute address ignore it */ - if (sym->level && + if (sym->level && !IS_STATIC(sym->etype) && SPEC_ABSA (sym->etype) && (options.stackAuto || reentrant)) { @@ -1588,6 +1637,7 @@ checkSClass (symbol * sym, int isProto) //!sym->level && port->mem.code_ro && !IS_EXTERN (sym->etype) && + !SPEC_ABSA (sym->etype) && !funcInChain (sym->type)) werror (E_CODE_NO_INIT, sym->name); } @@ -1609,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); @@ -1620,7 +1670,7 @@ checkSClass (symbol * sym, int isProto) /*------------------------------------------------------------------*/ /* changePointer - change pointer to functions */ /*------------------------------------------------------------------*/ -void +void changePointer (sym_link * p) { @@ -1639,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 */ @@ -1682,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; @@ -1705,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; @@ -1739,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) @@ -1819,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)) { @@ -1862,6 +1912,17 @@ computeType (sym_link * type1, sym_link * type2, switch (resultType) { + case RESULT_TYPE_IFX: + if (TARGET_IS_HC08) + break; + //fallthrough + case RESULT_TYPE_BIT: + if (op == ':') + { + SPEC_NOUN (reType) = V_BIT; + return rType; + } + break; case RESULT_TYPE_CHAR: if (IS_BITVAR (reType)) { @@ -1957,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? */ @@ -1966,12 +2027,12 @@ computeType (sym_link * type1, sym_link * type2, && ( (SPEC_USIGN (etype1) /* if this operand is promoted to a larger type, then it will be promoted to a signed type */ - && !(getSize (etype1) < getSize (reType)) + && !(bitsForType (etype1) < bitsForType (reType)) /* char require special handling */ && !IS_CHAR (etype1)) - || /* same for 2nd operand */ + || /* same for 2nd operand */ (SPEC_USIGN (etype2) - && !(getSize (etype2) < getSize (reType)) + && !(bitsForType (etype2) < bitsForType (reType)) && !IS_CHAR (etype2)) || /* if both are 'unsigned char' and not promoted let the result be unsigned too */ @@ -1987,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) @@ -2014,30 +2095,36 @@ 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)) { - if (IS_FUNC(src)) { - //checkFunction(src,dest); + if (DCL_TYPE (src) == DCL_TYPE (dest)) + { + if (IS_FUNC(src)) + { + //checkFunction(src,dest); + } + return comparePtrType(dest, src, FALSE); } - return compareType (dest->next, src->next); - } - if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) { - return -1; - } - if (IS_PTR (src) && + if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) + { + return -1; + } + if (IS_PTR (src) && (IS_GENPTR (dest) || ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER)) )) - return -1; - if (IS_PTR (dest) && IS_ARRAY (src)) { - value *val=aggregateToPointer (valFromType(src)); - int res=compareType (dest, val->type); - Safe_free(val->type); - Safe_free(val); - return res; - } + { + return comparePtrType(dest, src, TRUE); + } + if (IS_PTR (dest) && IS_ARRAY (src)) + { + value *val=aggregateToPointer (valFromType(src)); + int res=compareType (dest, val->type); + Safe_free(val->type); + Safe_free(val); + return res; + } if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src)) return compareType (dest->next, src); return 0; @@ -2048,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))) @@ -2079,7 +2169,7 @@ compareType (sym_link * dest, sym_link * src) instead of the next two lines, but the regression tests fail with them; I guess it's a problem with replaceCheaperOp */ getSize (dest) == getSize (src) && - !(!IS_BIT (dest) && IS_BIT (src))) + (IS_BIT (dest) == IS_BIT (src))) return 1; else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src)) return -1; @@ -2097,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; } @@ -2109,7 +2199,7 @@ int compareTypeExact (sym_link * dest, sym_link * src, int level) { STORAGE_CLASS srcScls, destScls; - + if (!dest && !src) return 1; @@ -2175,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); @@ -2212,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)) @@ -2229,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; @@ -2242,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() */ @@ -2277,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) @@ -2299,8 +2389,8 @@ inCalleeSaveList(char *s) } /*-----------------------------------------------------------------*/ -/* aggregateToPointer: change an agggregate type function */ -/* argument to a pointer to that type. */ +/* aggregateToPointer: change an aggregate type function */ +/* argument to a pointer to that type. */ /*-----------------------------------------------------------------*/ value * aggregateToPointer (value * val) @@ -2338,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; @@ -2354,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) @@ -2368,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; @@ -2384,7 +2476,14 @@ 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)) + { + SPEC_INLINE (sym->etype) = 0; + FUNC_ISINLINE (sym->type) = 1; + } + /* make sure the type is complete and sane */ checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name); @@ -2422,11 +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 @@ -2437,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 */ @@ -2500,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); @@ -2583,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); @@ -2599,7 +2700,7 @@ processFuncPtrArgs (sym_link * funcType) /*-----------------------------------------------------------------*/ /* processFuncArgs - does some processing with function args */ /*-----------------------------------------------------------------*/ -void +void processFuncArgs (symbol * func) { value *val; @@ -2641,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 */ @@ -2689,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) @@ -2721,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)) { @@ -2743,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 */ @@ -2772,10 +2873,8 @@ void PT(sym_link *type) void printTypeChain (sym_link * start, FILE * of) { + struct dbuf_s dbuf; int nlr = 0; - value *args; - sym_link * type, * search; - STORAGE_CLASS scls; if (!of) { @@ -2783,8 +2882,23 @@ printTypeChain (sym_link * start, FILE * of) nlr = 1; } + dbuf_init (&dbuf, 1024); + dbuf_printTypeChain (start, &dbuf); + dbuf_write_and_destroy (&dbuf, of); + + if (nlr) + putc ('\n', of); +} + +void +dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf) +{ + value *args; + sym_link * type, * search; + STORAGE_CLASS scls; + if (start==NULL) { - fprintf (of, "void"); + dbuf_append_str (dbuf, "void"); return; } @@ -2802,20 +2916,20 @@ printTypeChain (sym_link * start, FILE * of) while (type) { if (type==start) { - switch (scls) + switch (scls) { - case S_DATA: fprintf (of, "data-"); break; - case S_XDATA: fprintf (of, "xdata-"); break; - case S_SFR: fprintf (of, "sfr-"); break; - case S_SBIT: fprintf (of, "sbit-"); break; - case S_CODE: fprintf (of, "code-"); break; - case S_IDATA: fprintf (of, "idata-"); break; - case S_PDATA: fprintf (of, "pdata-"); break; - case S_LITERAL: fprintf (of, "literal-"); break; - case S_STACK: fprintf (of, "stack-"); break; - case S_XSTACK: fprintf (of, "xstack-"); break; - case S_BIT: fprintf (of, "bit-"); break; - case S_EEPROM: fprintf (of, "eeprom-"); break; + case S_DATA: dbuf_append_str (dbuf, "data-"); break; + case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break; + case S_SFR: dbuf_append_str (dbuf, "sfr-"); break; + case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break; + case S_CODE: dbuf_append_str (dbuf, "code-"); break; + case S_IDATA: dbuf_append_str (dbuf, "idata-"); break; + case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break; + case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break; + case S_STACK: dbuf_append_str (dbuf, "stack-"); break; + case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break; + case S_BIT: dbuf_append_str (dbuf, "bit-"); break; + case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break; default: break; } } @@ -2824,57 +2938,60 @@ printTypeChain (sym_link * start, FILE * of) { if (!IS_FUNC(type)) { if (DCL_PTR_VOLATILE (type)) { - fprintf (of, "volatile-"); + dbuf_append_str (dbuf, "volatile-"); } if (DCL_PTR_CONST (type)) { - fprintf (of, "const-"); + dbuf_append_str (dbuf, "const-"); + } + if (DCL_PTR_RESTRICT (type)) { + dbuf_append_str (dbuf, "restrict-"); } } switch (DCL_TYPE (type)) { case FUNCTION: - fprintf (of, "function %s %s", + dbuf_printf (dbuf, "function %s %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "), (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " ")); - fprintf (of, "( "); - for (args = FUNC_ARGS(type); - args; + dbuf_append_str (dbuf, "( "); + for (args = FUNC_ARGS(type); + args; args=args->next) { - printTypeChain(args->type, of); + dbuf_printTypeChain(args->type, dbuf); if (args->next) - fprintf(of, ", "); + dbuf_append_str (dbuf, ", "); } - fprintf (of, ") "); + dbuf_append_str (dbuf, ") "); break; case GPOINTER: - fprintf (of, "generic* "); + dbuf_append_str (dbuf, "generic* "); break; case CPOINTER: - fprintf (of, "code* "); + dbuf_append_str (dbuf, "code* "); break; case FPOINTER: - fprintf (of, "xdata* "); + dbuf_append_str (dbuf, "xdata* "); break; case EEPPOINTER: - fprintf (of, "eeprom* "); + dbuf_append_str (dbuf, "eeprom* "); break; case POINTER: - fprintf (of, "near* "); + dbuf_append_str (dbuf, "near* "); break; case IPOINTER: - fprintf (of, "idata* "); + dbuf_append_str (dbuf, "idata* "); break; case PPOINTER: - fprintf (of, "pdata* "); + dbuf_append_str (dbuf, "pdata* "); break; case UPOINTER: - fprintf (of, "unknown* "); + dbuf_append_str (dbuf, "unknown* "); break; case ARRAY: if (DCL_ELEM(type)) { - fprintf (of, "[%d] ", DCL_ELEM(type)); + dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type)); } else { - fprintf (of, "[] "); + dbuf_append_str (dbuf, "[] "); } break; } @@ -2882,57 +2999,57 @@ printTypeChain (sym_link * start, FILE * of) else { if (SPEC_VOLATILE (type)) - fprintf (of, "volatile-"); + dbuf_append_str (dbuf, "volatile-"); if (SPEC_CONST (type)) - fprintf (of, "const-"); + dbuf_append_str (dbuf, "const-"); if (SPEC_USIGN (type)) - fprintf (of, "unsigned-"); + dbuf_append_str (dbuf, "unsigned-"); switch (SPEC_NOUN (type)) { case V_INT: if (IS_LONG (type)) - fprintf (of, "long-"); - fprintf (of, "int"); + dbuf_append_str (dbuf, "long-"); + dbuf_append_str (dbuf, "int"); break; case V_CHAR: - fprintf (of, "char"); + dbuf_append_str (dbuf, "char"); break; case V_VOID: - fprintf (of, "void"); + dbuf_append_str (dbuf, "void"); break; case V_FLOAT: - fprintf (of, "float"); + dbuf_append_str (dbuf, "float"); break; case V_FIXED16X16: - fprintf (of, "fixed16x16"); + dbuf_append_str (dbuf, "fixed16x16"); break; case V_STRUCT: - fprintf (of, "struct %s", SPEC_STRUCT (type)->tag); + dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag); break; case V_SBIT: - fprintf (of, "sbit"); + dbuf_append_str (dbuf, "sbit"); break; case V_BIT: - fprintf (of, "bit"); + dbuf_append_str (dbuf, "bit"); break; case V_BITFIELD: - fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type)); + dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type)); break; case V_DOUBLE: - fprintf (of, "double"); + dbuf_append_str (dbuf, "double"); break; default: - fprintf (of, "unknown type"); + dbuf_append_str (dbuf, "unknown type"); break; } } @@ -2941,10 +3058,8 @@ printTypeChain (sym_link * start, FILE * of) search = search->next; type = search; if (type) - fputc (' ', of); + dbuf_append_char(dbuf, ' '); } - if (nlr) - fprintf (of, "\n"); } /*--------------------------------------------------------------------*/ @@ -2970,7 +3085,7 @@ printTypeChainRaw (sym_link * start, FILE * of) } type = start; - + while (type) { if (IS_DECL (type)) @@ -2982,16 +3097,22 @@ printTypeChainRaw (sym_link * start, FILE * of) if (DCL_PTR_CONST (type)) { fprintf (of, "const-"); } + if (DCL_PTR_RESTRICT (type)) { + fprintf (of, "restrict-"); + } } switch (DCL_TYPE (type)) { case FUNCTION: - fprintf (of, "function %s %s", + if (IFFUNC_ISINLINE(type)) { + fprintf (of, "inline-"); + } + 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) @@ -3040,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; @@ -3126,7 +3247,7 @@ printTypeChainRaw (sym_link * start, FILE * of) /* powof2 - returns power of two for the number if number is pow 2 */ /*-----------------------------------------------------------------*/ int -powof2 (TYPE_UDWORD num) +powof2 (TYPE_TARGET_ULONG num) { int nshifts = 0; int n1s = 0; @@ -3166,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 */ @@ -3207,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 */ @@ -3221,7 +3342,7 @@ sym_link *typeFromStr (char *s) do { sym_link *nr; switch (*s) { - case 'u' : + case 'u' : usign = 1; s++; continue ; @@ -3288,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; } @@ -3304,7 +3425,7 @@ sym_link *typeFromStr (char *s) /*-----------------------------------------------------------------*/ /* initCSupport - create functions for C support routines */ /*-----------------------------------------------------------------*/ -void +void initCSupport () { const char *smuldivmod[] = @@ -3321,7 +3442,7 @@ initCSupport () }; const char *ssu[] = { - "s", "u" + "s", "su", "us", "u" }; const char *srlrr[] = { @@ -3391,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); } } @@ -3411,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 @@ -3419,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 @@ -3439,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; @@ -3451,39 +3572,85 @@ 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 (su = 0; su < 2; su++) + for (muldivmod = 0; muldivmod < 3; muldivmod++) { - for (muldivmod = 1; 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) { - /* div and mod */ 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); + "_%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; } } } - /* mul only */ - muldivmod = 0; - /* byte */ - bwd = 0; - for (su = 0; su < 2; su++) + + for (bwd = 1; bwd < 3; bwd++) { - /* muluchar and mulschar are still separate functions, because e.g. the z80 - port is sign/zero-extending to int before calling mulint() */ + for (su = 0; su < 2; su++) + { + for (muldivmod = 1; muldivmod < 3; muldivmod++) + { + /* 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 || bwd != 0 || su != 0) + { + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + 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; + } + } + } + } + + if (TARGET_IS_PIC16) + { + /* PIC16 port wants __divschar/__modschar to return an int, so that both + * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly + * (first one would have to be sign extended, second one must not be). + * Similarly, modschar should be handled, but the iCode introduces cast + * here and forces '% : s8 x s8 -> s8' ... */ + su = 0; bwd = 0; + for (muldivmod = 1; muldivmod < 2; muldivmod++) { 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); + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType ( + _mangleFunctionName(buffer), + __multypes[1][su], + __multypes[bwd][su], + 2, + options.intlong_rent); FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; } + } + + /* mul only */ + muldivmod = 0; /* signed only */ su = 0; /* word and doubleword */ @@ -3509,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; @@ -3536,23 +3703,23 @@ void initBuiltIns() } } -sym_link *validateLink(sym_link *l, +sym_link *validateLink(sym_link *l, const char *macro, const char *args, const char select, - const char *file, + 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(-1); + exit(EXIT_FAILURE); return l; // never reached, makes compiler happy. } @@ -3572,13 +3739,13 @@ newEnumType (symbol *enumlist) SPEC_NOUN (type) = V_INT; return type; } - + /* Determine the range of the enumerated values */ sym = enumlist; - min = max = (int) floatFromVal (valFromType (sym->type)); + min = max = (int) ulFromVal (valFromType (sym->type)); for (sym = sym->next; sym; sym = sym->next) { - v = (int) floatFromVal (valFromType (sym->type)); + v = (int) ulFromVal (valFromType (sym->type)); if (vmax) @@ -3612,6 +3779,6 @@ newEnumType (symbol *enumlist) if (min>=0) SPEC_USIGN (type) = 1; } - - return type; + + return type; }