X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=86fad20a2c504b803c58a6f1326c60858f92d4ca;hb=e4686e809bb3f1922a4fe850adc00c503a72ad24;hp=09b4a28c66a5e39edee719bf1ff88f80b82961f3;hpb=5be90381bf67a833edd640da0d67400b3bb0f111;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 09b4a28c..86fad20a 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -50,8 +50,8 @@ int labelKey = 1; int noLineno = 0; int noAlloc = 0; symbol *currFunc=NULL; -static ast *createIval (ast *, sym_link *, initList *, ast *); -static ast *createIvalCharPtr (ast *, sym_link *, ast *); +static ast *createIval (ast *, sym_link *, initList *, ast *, ast *); +static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *); static ast *optimizeCompare (ast *); ast *optimizeRRCRLC (ast *); ast *optimizeSWAP (ast *); @@ -59,12 +59,12 @@ ast *optimizeGetHbit (ast *, RESULT_TYPE); ast *optimizeGetAbit (ast *, RESULT_TYPE); ast *optimizeGetByte (ast *, RESULT_TYPE); ast *optimizeGetWord (ast *, RESULT_TYPE); -ast *backPatchLabels (ast *, symbol *, symbol *); +static ast *backPatchLabels (ast *, symbol *, symbol *); void PA(ast *t); int inInitMode = 0; memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */ FILE *codeOutFile; -int +int ptt (ast * tree) { printTypeChain (tree->ftype, stdout); @@ -589,23 +589,23 @@ funcOfType (char *name, sym_link * type, sym_link * argType, symbol * funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes) { - + symbol *sym; int i ; /* create the symbol */ sym = newSymbol (name, 0); - + /* setup return value */ sym->type = newLink (DECLARATOR); DCL_TYPE (sym->type) = FUNCTION; sym->type->next = typeFromStr(rtype); sym->etype = getSpec (sym->type); - + /* if arguments required */ if (nArgs) { value *args; args = FUNC_ARGS(sym->type) = newValue (); - + for ( i = 0 ; i < nArgs ; i++ ) { args->type = typeFromStr(atypes[i]); args->etype = getSpec (args->type); @@ -647,7 +647,7 @@ reverseParms (ast * ptree) ttree->left = ptree->left; ptree->left = ttree; } - + /* Now reverse */ ttree = ptree->left; ptree->left = ptree->right; @@ -673,7 +673,7 @@ processParms (ast *func, { RESULT_TYPE resultType; sym_link *functype; - + /* if none of them exist */ if (!defParm && !*actParm) return 0; @@ -692,7 +692,7 @@ processParms (ast *func, functype = func->ftype->next; else functype = func->ftype; - + /* if the function is being called via a pointer & */ /* it has not been defined a reentrant then we cannot */ /* have parameters */ @@ -776,7 +776,7 @@ processParms (ast *func, if (IS_INTEGRAL (ftype) && (getSize (ftype) < (unsigned) INTSIZE)) { - newType = newAst_LINK(INTTYPE); + newType = newAst_LINK(INTTYPE); } if (IS_PTR(ftype) && !IS_GENPTR(ftype)) @@ -790,14 +790,14 @@ processParms (ast *func, newType = newAst_LINK (copyLinkChain (ftype)); DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; } - + if (newType) { /* cast required; change this op to a cast. */ (*actParm)->decorated = 0; *actParm = newNode (CAST, newType, *actParm); (*actParm)->lineno = (*actParm)->right->lineno; - + decorateType (*actParm, RESULT_TYPE_NONE); } return 0; @@ -810,7 +810,7 @@ processParms (ast *func, return 0; resolveSymbols (*actParm); - + /* the parameter type must be at least castable */ if (compareType (defParm->type, (*actParm)->ftype) == 0) { @@ -826,7 +826,7 @@ processParms (ast *func, resultType = getResultTypeFromType (defParm->etype); pTree = resolveSymbols (copyAst (*actParm)); - + /* now change the current one to a cast */ (*actParm)->type = EX_OP; (*actParm)->opval.op = CAST; @@ -864,7 +864,7 @@ createIvalType (ast * sym, sym_link * type, initList * ilist) /* createIvalStruct - generates initial value for structures */ /*-----------------------------------------------------------------*/ static ast * -createIvalStruct (ast * sym, sym_link * type, initList * ilist) +createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue) { ast *rast = NULL; ast *lAst; @@ -888,12 +888,15 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) sflds->implicit = 1; lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds))); lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE); - rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE); + rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, + iloop, rast, rootValue)), + RESULT_TYPE_NONE); + } if (iloop) { werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef, - W_EXCESS_INITIALIZERS, "struct", + W_EXCESS_INITIALIZERS, "struct", sym->opval.val->sym->name); } @@ -905,7 +908,7 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) /* createIvalArray - generates code for array initialization */ /*-----------------------------------------------------------------*/ static ast * -createIvalArray (ast * sym, sym_link * type, initList * ilist) +createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) { ast *rast = NULL; initList *iloop; @@ -918,83 +921,88 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) if (IS_CHAR (type->next)) if ((rast = createIvalCharPtr (sym, type, - decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE)))) + decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE), + rootValue))) return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); - /* not the special case */ - if (ilist->type != INIT_DEEP) - { - werror (E_INIT_STRUCT, ""); - return NULL; - } + /* not the special case */ + if (ilist->type != INIT_DEEP) + { + werror (E_INIT_STRUCT, ""); + return NULL; + } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) - { - ast *aSym; + if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) + { + ast *aSym; - aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE); - - rast = newNode(ARRAYINIT, aSym, NULL); - rast->values.constlist = literalL; - - // Make sure size is set to length of initializer list. - while (iloop) - { - size++; - iloop = iloop->next; - } - - if (lcnt && size > lcnt) - { - // Array size was specified, and we have more initializers than needed. - char *name=sym->opval.val->sym->name; - int lineno=sym->opval.val->sym->lineDef; - char *filename=sym->opval.val->sym->fileDef; - - werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); - } - } - else - { - for (;;) - { - ast *aSym; - - aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); - aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE); - rast = createIval (aSym, type->next, iloop, rast); - iloop = (iloop ? iloop->next : NULL); - if (!iloop) - { - break; - } - - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) - { - // is this a better way? at least it won't crash - char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : ""; - int lineno = iloop->lineno; - char *filename = iloop->filename; - werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); - - break; - } - } - } + aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE); + + rast = newNode(ARRAYINIT, aSym, NULL); + rast->values.constlist = literalL; + + // Make sure size is set to length of initializer list. + while (iloop) + { + size++; + iloop = iloop->next; + } + + if (lcnt && size > lcnt) + { + // Array size was specified, and we have more initializers than needed. + char *name=sym->opval.val->sym->name; + int lineno=sym->opval.val->sym->lineDef; + char *filename=sym->opval.val->sym->fileDef; + + werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); + } + } + else + { + for (;;) + { + ast *aSym; + + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); + aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE); + rast = createIval (aSym, type->next, iloop, rast, rootValue); + iloop = (iloop ? iloop->next : NULL); + if (!iloop) + { + break; + } + + /* no of elements given and we */ + /* have generated for all of them */ + if (!--lcnt) + { + // is this a better way? at least it won't crash + char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : ""; + int lineno = iloop->lineno; + char *filename = iloop->filename; + werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); + + break; + } + } + } - /* if we have not been given a size */ - if (!DCL_ELEM (type)) + /* if we have not been given a size */ + if (!DCL_ELEM (type)) { + /* check, if it's a flexible array */ + if (IS_STRUCT (AST_VALUE (rootValue)->type)) + AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next); + else DCL_ELEM (type) = size; } - return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } @@ -1002,9 +1010,10 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) /* createIvalCharPtr - generates initial values for char pointers */ /*-----------------------------------------------------------------*/ static ast * -createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) +createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal) { ast *rast = NULL; + unsigned size = 0; /* if this is a pointer & right is a literal array then */ /* just assignment will do */ @@ -1022,11 +1031,11 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) /* for each character generate an assignment */ /* to the array element */ char *s = SPEC_CVAL (iexpr->etype).v_char; - int i = 0; - int size = getSize (iexpr->ftype); - int symsize = getSize (type); - - if (size>symsize) + unsigned int i = 0; + unsigned int symsize = getSize (type); + + size = getSize (iexpr->ftype); + if (symsize && size>symsize) { if (size>(symsize+1)) { @@ -1052,6 +1061,16 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) // now WE don't need iexpr's symbol anymore freeStringSymbol(AST_SYMBOL(iexpr)); + /* if we have not been given a size */ + if (!DCL_ELEM (type)) + { + /* check, if it's a flexible array */ + if (IS_STRUCT (AST_VALUE (rootVal)->type)) + AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next); + else + DCL_ELEM (type) = size; + } + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } @@ -1062,7 +1081,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) /* createIvalPtr - generates initial value for pointers */ /*-----------------------------------------------------------------*/ static ast * -createIvalPtr (ast * sym, sym_link * type, initList * ilist) +createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal) { ast *rast; ast *iexpr; @@ -1075,7 +1094,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist) /* if character pointer */ if (IS_CHAR (type->next)) - if ((rast = createIvalCharPtr (sym, type, iexpr))) + if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal))) return rast; return newNode ('=', sym, iexpr); @@ -1085,7 +1104,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist) /* createIval - generates code for initial value */ /*-----------------------------------------------------------------*/ static ast * -createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) +createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue) { ast *rast = NULL; @@ -1094,15 +1113,15 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /* if structure then */ if (IS_STRUCT (type)) - rast = createIvalStruct (sym, type, ilist); + rast = createIvalStruct (sym, type, ilist, rootValue); else /* if this is a pointer */ if (IS_PTR (type)) - rast = createIvalPtr (sym, type, ilist); + rast = createIvalPtr (sym, type, ilist, rootValue); else /* if this is an array */ if (IS_ARRAY (type)) - rast = createIvalArray (sym, type, ilist); + rast = createIvalArray (sym, type, ilist, rootValue); else /* if type is SPECIFIER */ if (IS_SPEC (type)) @@ -1118,7 +1137,8 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ ast * initAggregates (symbol * sym, initList * ival, ast * wid) { - return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid); + ast *newAst = newAst_VALUE (symbolVal (sym)); + return createIval (newAst, sym->type, ival, wid, newAst); } /*-----------------------------------------------------------------*/ @@ -1163,7 +1183,7 @@ gatherAutoInit (symbol * autoChain) SPEC_SCLS (sym->etype) != S_CODE) { symbol *newSym; - + /* insert the symbol into the symbol table */ /* with level = 0 & name = rname */ newSym = copySymbol (sym); @@ -1175,7 +1195,7 @@ gatherAutoInit (symbol * autoChain) } else { if (getNelements(sym->type, sym->ival)>1) { werrorfl (sym->fileDef, sym->lineDef, - W_EXCESS_INITIALIZERS, "scalar", + W_EXCESS_INITIALIZERS, "scalar", sym->name); } work = newNode ('=', newAst_VALUE (symbolVal (newSym)), @@ -1197,7 +1217,7 @@ gatherAutoInit (symbol * autoChain) if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE) { initList *ilist=sym->ival; - + while (ilist->type == INIT_DEEP) { ilist = ilist->init.deep; } @@ -1205,19 +1225,19 @@ gatherAutoInit (symbol * autoChain) /* update lineno for error msg */ lineno=sym->lineDef; setAstLineno (ilist->init.node, lineno); - + if (IS_AGGREGATE (sym->type)) { work = initAggregates (sym, sym->ival, NULL); } else { if (getNelements(sym->type, sym->ival)>1) { werrorfl (sym->fileDef, sym->lineDef, - W_EXCESS_INITIALIZERS, "scalar", + W_EXCESS_INITIALIZERS, "scalar", sym->name); } work = newNode ('=', newAst_VALUE (symbolVal (sym)), list2expr (sym->ival)); } - + // just to be sure setAstLineno (work, sym->lineDef); @@ -1245,7 +1265,7 @@ void freeStringSymbol(symbol *sym) { } } } - + /*-----------------------------------------------------------------*/ /* stringToSymbol - creates a symbol from a literal string */ /*-----------------------------------------------------------------*/ @@ -1317,7 +1337,7 @@ processBlockVars (ast * tree, int *stack, int action) { *stack += allocVariables (tree->values.sym); autoInit = gatherAutoInit (tree->values.sym); - + /* if there are auto inits then do them */ if (autoInit) tree->left = newNode (NULLOP, autoInit, tree->left); @@ -1344,7 +1364,7 @@ bool constExprTree (ast *cexpr) { cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE); - switch (cexpr->type) + switch (cexpr->type) { case EX_VALUE: if (IS_AST_LIT_VALUE(cexpr)) { @@ -1359,7 +1379,7 @@ bool constExprTree (ast *cexpr) { // an array's address will never change return TRUE; } - if (IS_AST_SYM_VALUE(cexpr) && + if (IS_AST_SYM_VALUE(cexpr) && IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) { // a symbol in code space will never change // This is only for the 'char *s="hallo"' case and will have to leave @@ -1383,7 +1403,7 @@ bool constExprTree (ast *cexpr) { // cast ignored, maybe we should throw a warning here? return constExprTree(cexpr->right); } - if (cexpr->opval.op=='&') { + if (cexpr->opval.op=='&') { return TRUE; } if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) { @@ -1398,7 +1418,7 @@ bool constExprTree (ast *cexpr) { } return FALSE; } - + /*-----------------------------------------------------------------*/ /* constExprValue - returns the value of a constant expression */ /* or NULL if it is not a constant expression */ @@ -1454,7 +1474,7 @@ constExprValue (ast * cexpr, int check) /*-----------------------------------------------------------------*/ /* isLabelInAst - will return true if a given label is found */ /*-----------------------------------------------------------------*/ -bool +bool isLabelInAst (symbol * label, ast * tree) { if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree)) @@ -1474,7 +1494,7 @@ isLabelInAst (symbol * label, ast * tree) /* isLoopCountable - return true if the loop count can be determi- */ /* -ned at compile time . */ /*-----------------------------------------------------------------*/ -bool +bool isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, symbol ** sym, ast ** init, ast ** end) { @@ -1587,7 +1607,7 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, /*-----------------------------------------------------------------*/ /* astHasVolatile - returns true if ast contains any volatile */ /*-----------------------------------------------------------------*/ -bool +bool astHasVolatile (ast * tree) { if (!tree) @@ -1606,7 +1626,7 @@ astHasVolatile (ast * tree) /*-----------------------------------------------------------------*/ /* astHasPointer - return true if the ast contains any ptr variable */ /*-----------------------------------------------------------------*/ -bool +bool astHasPointer (ast * tree) { if (!tree) @@ -1631,7 +1651,7 @@ astHasPointer (ast * tree) /*-----------------------------------------------------------------*/ /* astHasSymbol - return true if the ast has the given symbol */ /*-----------------------------------------------------------------*/ -bool +bool astHasSymbol (ast * tree, symbol * sym) { if (!tree || IS_AST_LINK (tree)) @@ -1652,14 +1672,14 @@ astHasSymbol (ast * tree, symbol * sym) /*-----------------------------------------------------------------*/ /* astHasDeref - return true if the ast has an indirect access */ /*-----------------------------------------------------------------*/ -static bool +static bool astHasDeref (ast * tree) { if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree)) return FALSE; if (tree->opval.op == '*' && tree->right == NULL) return TRUE; - + return astHasDeref (tree->left) || astHasDeref (tree->right); } @@ -1667,7 +1687,7 @@ astHasDeref (ast * tree) /* isConformingBody - the loop body has to conform to a set of rules */ /* for the loop to be considered reversible read on for rules */ /*-----------------------------------------------------------------*/ -bool +bool isConformingBody (ast * pbody, symbol * sym, ast * body) { @@ -1686,7 +1706,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* if we reach the end or a leaf then true */ if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody)) return TRUE; - + /* if anything else is "volatile" */ if (IS_VOLATILE (TETYPE (pbody))) return FALSE; @@ -1868,7 +1888,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /*----------------------------*/ case CALL: /* if local & not passed as paramater then ok */ - if (sym->level && !astHasSymbol(pbody->right,sym)) + if (sym->level && !astHasSymbol(pbody->right,sym)) return TRUE; return FALSE; @@ -1934,7 +1954,7 @@ isLoopReversible (ast * loop, symbol ** loopCntrl, /*-----------------------------------------------------------------*/ /* replLoopSym - replace the loop sym by loop sym -1 */ /*-----------------------------------------------------------------*/ -static void +static void replLoopSym (ast * body, symbol * sym) { /* reached end */ @@ -2071,7 +2091,7 @@ getResultTypeFromType (sym_link *type) if (IS_BITFIELD (type)) { int blen = SPEC_BLEN (type); - + if (blen <= 1) return RESULT_TYPE_BIT; if (blen <= 8) @@ -2094,7 +2114,7 @@ addCast (ast *tree, RESULT_TYPE resultType, bool promote) { sym_link *newLink; bool upCasted = FALSE; - + switch (resultType) { case RESULT_TYPE_NONE: @@ -2219,7 +2239,7 @@ getLeftResultType (ast *tree, RESULT_TYPE resultType) case '[': if (!IS_ARRAY (LTYPE (tree))) return resultType; - if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256) + if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255) return RESULT_TYPE_CHAR; return resultType; default: @@ -2383,7 +2403,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) in tree->left->?type. If the op is e.g. '=' we extract the type information from there and propagate it to the right branch. */ resultTypeProp = getLeftResultType (tree, resultTypeProp); - + switch (tree->opval.op) { case '?': @@ -2391,12 +2411,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) expansions might rely on this */ dtr = tree->right; break; - case CALL: + case CALL: /* decorate right side for CALL (parameter list) in processParms(); there is resultType available */ dtr = tree->right; break; - default: + default: dtr = decorateType (tree->right, resultTypeProp); break; } @@ -2454,6 +2474,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) RRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next); + SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree)); return tree; /*------------------------------------------------------------------*/ @@ -2499,19 +2520,19 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* adjust the storage class */ switch (DCL_TYPE(tree->left->ftype)) { case POINTER: - SPEC_SCLS(TETYPE(tree)) = S_DATA; + SPEC_SCLS(TETYPE(tree)) = S_DATA; break; case FPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XDATA; + SPEC_SCLS(TETYPE(tree)) = S_XDATA; break; case CPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_CODE; + SPEC_SCLS(TETYPE(tree)) = S_CODE; break; case GPOINTER: SPEC_SCLS (TETYPE (tree)) = 0; break; case PPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XSTACK; + SPEC_SCLS(TETYPE(tree)) = S_XSTACK; break; case IPOINTER: SPEC_SCLS(TETYPE(tree)) = S_IDATA; @@ -2526,7 +2547,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) case FUNCTION: break; } - + /* This breaks with extern declarations, bitfields, and perhaps other */ /* cases (gcse). Let's leave this optimization disabled for now and */ /* ponder if there's a safe way to do this. -- EEP */ @@ -2555,7 +2576,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) SPEC_ABSA(sym->etype) = 1; addSym (SymbolTab, sym, sym->name, 0, 0, 0); allocGlobal (sym); - + AST_VALUE (tree) = symbolVal(sym); TLVAL (tree) = 1; TRVAL (tree) = 0; @@ -2564,7 +2585,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->right = NULL; } #endif - + return tree; /*------------------------------------------------------------------*/ @@ -2682,7 +2703,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) } LRVAL (tree) = RRVAL (tree) = 1; - + TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), resultType, @@ -2783,7 +2804,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) ast *wtree = optimizeRRCRLC (tree); if (wtree != tree) return decorateType (wtree, RESULT_TYPE_NONE); - + wtree = optimizeSWAP (tree); if (wtree != tree) return decorateType (wtree, RESULT_TYPE_NONE); @@ -3015,16 +3036,16 @@ decorateType (ast * tree, RESULT_TYPE resultType) SPEC_SCLS(TETYPE(tree)) = S_DATA; break; case FPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XDATA; + SPEC_SCLS(TETYPE(tree)) = S_XDATA; break; case CPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_CODE; + SPEC_SCLS(TETYPE(tree)) = S_CODE; break; case GPOINTER: SPEC_SCLS (TETYPE (tree)) = 0; break; case PPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XSTACK; + SPEC_SCLS(TETYPE(tree)) = S_XSTACK; break; case IPOINTER: SPEC_SCLS(TETYPE(tree)) = S_IDATA; @@ -3241,7 +3262,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) resultType, tree->opval.op)); } - + return tree; /*------------------------------------------------------------------*/ @@ -3266,11 +3287,15 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.val = valUnaryPM (valFromType (LETYPE (tree))); tree->left = NULL; TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - SPEC_USIGN(TETYPE(tree)) = 0; return tree; } + tree->left = addCast (tree->left, resultType, TRUE); + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + NULL, + resultType, + tree->opval.op)); LRVAL (tree) = 1; - TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree)); return tree; } @@ -3386,7 +3411,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->right = litParent->left; litParent->left = tTree; litTree->opval.op = '+'; - + tree->decorated = 0; decorateType (tree, resultType); } @@ -3513,7 +3538,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* make smaller type only if it's a LEFT_OP */ if (tree->opval.op == LEFT_OP) tree->left = addCast (tree->left, resultType, TRUE); - + /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) @@ -3661,7 +3686,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_ADDRESS_OF_OP(tree->right) && IS_AST_SYM_VALUE (tree->right->left) && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) { - + symbol * sym = AST_SYMBOL (tree->right->left); unsigned int gptype = 0; unsigned int addr = SPEC_ADDR (sym->etype); @@ -3688,7 +3713,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) } addr |= gptype << (8*(GPTRSIZE - 1)); } - + tree->type = EX_VALUE; tree->opval.val = valCastLiteral (LTYPE (tree), addr); @@ -3907,7 +3932,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if (unsigned value) */ return tree->left; } - + /* (unsigned value) ? 1 : 0 */ tree->opval.op = '?'; tree->right = newNode (':', @@ -3937,9 +3962,30 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) && (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree)))) { - werror (W_CMP_SU_CHAR); - tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE); - tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE); + /* Literals are 'optimized' to 'unsigned char'. Try to figure out, + if it's possible to use a 'signed char' */ + + /* is left a 'unsigned char'? */ + if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) && + /* the value range of a 'unsigned char' is 0...255; + if the actual value is < 128 it can be changed to signed */ + (int) floatFromVal (valFromType (RETYPE (tree))) < 128) + { + /* now we've got 2 'signed char'! */ + SPEC_USIGN (RETYPE (tree)) = 0; + } + /* same test for the left operand: */ + else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) && + (int) floatFromVal (valFromType (LETYPE (tree))) < 128) + { + SPEC_USIGN (LETYPE (tree)) = 0; + } + else + { + werror (W_CMP_SU_CHAR); + tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE); + tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE); + } } LRVAL (tree) = RRVAL (tree) = 1; @@ -4278,7 +4324,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* function call */ /*----------------------------*/ case CALL: - + /* undo any explicit pointer derefernce; PCALL will handle it instead */ if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP) { @@ -4298,11 +4344,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!tree->right || !tree->right->decorated) { - sym_link *functype; + sym_link *functype; parmNumber = 1; if (IS_FUNCPTR (LTYPE (tree))) - functype = LTYPE (tree)->next; + { + functype = LTYPE (tree)->next; + processFuncPtrArgs (functype); + } else functype = LTYPE (tree); @@ -4311,8 +4360,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) { goto errorTreeReturn; } - - if ((options.stackAuto || IFFUNC_ISREENT (functype)) && + + if ((options.stackAuto || IFFUNC_ISREENT (functype)) && !IFFUNC_ISBUILTIN(functype)) { reverseParms (tree->right); @@ -4477,7 +4526,7 @@ sizeofOp (sym_link * type) /*-----------------------------------------------------------------*/ /* backPatchLabels - change and or not operators to flow control */ /*-----------------------------------------------------------------*/ -ast * +static ast * backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) { @@ -4542,25 +4591,18 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) /* change not */ if (IS_NOT (tree)) { - int wasnot = IS_NOT (tree->left); + /* call with exchanged labels */ tree->left = backPatchLabels (tree->left, falseLabel, trueLabel); - /* if the left is already a IFX */ + /* if left isn't already a IFX */ if (!IS_IFX (tree->left)) - tree->left = newNode (IFX, tree->left, NULL); - - if (wasnot) - { - tree->left->trueLabel = trueLabel; - tree->left->falseLabel = falseLabel; - } - else { + tree->left = newNode (IFX, tree->left, NULL); tree->left->trueLabel = falseLabel; tree->left->falseLabel = trueLabel; } return tree->left; - } + } if (IS_IFX (tree)) { @@ -4586,7 +4628,7 @@ createBlock (symbol * decl, ast * body) ex = newNode (BLOCK, NULL, body); ex->values.sym = decl; - + ex->level++; ex->lineno = 0; return ex; @@ -4705,7 +4747,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) } /* create the case label */ - SNPRINTF(caseLbl, sizeof(caseLbl), + SNPRINTF(caseLbl, sizeof(caseLbl), "_case_%d_%d", swStat->values.switchVals.swNum, (int) floatFromVal (caseVal->opval.val)); @@ -5033,7 +5075,7 @@ optimizeGetHbit (ast * tree, RESULT_TYPE resultType) if (!expr && (resultType == RESULT_TYPE_BIT)) { expr = tree->left; - if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1) + if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1) expr = NULL; } if (!expr) @@ -5114,7 +5156,7 @@ optimizeGetByte (ast * tree, RESULT_TYPE resultType) } if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8)) return tree; - + /* make sure the port supports GETBYTE */ if (port->hasExtBitOp && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr)))) @@ -5140,7 +5182,7 @@ optimizeGetWord (ast * tree, RESULT_TYPE resultType) count = tree->left->right; if (AST_LIT_VALUE (tree->right) != 0xFFFF) expr = NULL; - } + } if (!expr && resultType == RESULT_TYPE_INT) { /* if this is a right shift over a multiple of 8 */ @@ -5153,7 +5195,7 @@ optimizeGetWord (ast * tree, RESULT_TYPE resultType) } if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8)) return tree; - + /* make sure the port supports GETWORD */ if (port->hasExtBitOp && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr)))) @@ -5508,7 +5550,7 @@ noOptimize: /*-----------------------------------------------------------------*/ /* addSymToBlock : adds the symbol to the first block we find */ /*-----------------------------------------------------------------*/ -void +void addSymToBlock (symbol * sym, ast * tree) { /* reached end of tree or a leaf */ @@ -5534,7 +5576,7 @@ addSymToBlock (symbol * sym, ast * tree) /*-----------------------------------------------------------------*/ /* processRegParms - do processing for register parameters */ /*-----------------------------------------------------------------*/ -static void +static void processRegParms (value * args, ast * body) { while (args) @@ -5651,7 +5693,6 @@ createFunction (symbol * name, ast * body) body = resolveSymbols (body); /* resolve the symbols */ body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */ - ex = newAst_VALUE (symbolVal (name)); /* create name */ ex = newNode (FUNCTION, ex, body); @@ -5979,11 +6020,11 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,")\n"); ast_print(tree->left,outfile,indent+2); return ; - } + } /*------------------------------------------------------------------*/ /*----------------------------*/ /* multiplication */ - /*----------------------------*/ + /*----------------------------*/ fprintf(outfile,"MULT (%p) type (",tree); printTypeChain(tree->ftype,outfile); fprintf(outfile,")\n"); @@ -6133,7 +6174,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,")\n"); ast_print(tree->right,outfile,indent+2); return ; - + case AND_OP: fprintf(outfile,"ANDAND (%p) type (",tree); printTypeChain(tree->ftype,outfile); @@ -6148,7 +6189,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) ast_print(tree->left,outfile,indent+2); ast_print(tree->right,outfile,indent+2); return ; - + /*------------------------------------------------------------------*/ /*----------------------------*/ /* comparison operators */ @@ -6307,7 +6348,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,")\n"); ast_print(tree->left,outfile,indent+2); ast_print(tree->right,outfile,indent+2); - return; + return; /*------------------------------------------------------------------*/ /*----------------------------*/ /* comma operator */ @@ -6448,12 +6489,12 @@ void PA(ast *t) int astErrors(ast *t) { int errors=0; - + if (t) { if (t->isError) errors++; - + if (t->type == EX_VALUE && t->opval.val->sym && t->opval.val->sym->undefined) @@ -6462,6 +6503,6 @@ int astErrors(ast *t) errors += astErrors(t->left); errors += astErrors(t->right); } - + return errors; }