X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=4572ac760c72eb72dc2db377f491334cc8e78b99;hb=74d7034386679789c3e835c2d104941fd6c759d3;hp=9c62ab82694c47225b089e27c8fe25a73db1d472;hpb=bbf0be42537e2cc9acbfcda9ea3f12c9e78c6e89;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 9c62ab82..4572ac76 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -23,7 +23,6 @@ -------------------------------------------------------------------------*/ #include "common.h" -#include "newalloc.h" int currLineno = 0; set *astList = NULL; @@ -46,7 +45,6 @@ int labelKey = 1; #define ALLOCATE 1 #define DEALLOCATE 2 -char buffer[1024]; int noLineno = 0; int noAlloc = 0; symbol *currFunc; @@ -76,7 +74,7 @@ newAst (int type, void *op) ast *ex; static int oldLineno = 0; - Safe_calloc (1, ex, sizeof (ast)); + ex = Safe_alloc ( sizeof (ast)); ex->type = type; ex->lineno = (noLineno ? oldLineno : yylineno); @@ -111,7 +109,7 @@ newAst_ (unsigned type) ast *ex; static int oldLineno = 0; - ex = Safe_calloc (1, sizeof (ast)); + ex = Safe_alloc ( sizeof (ast)); ex->type = type; ex->lineno = (noLineno ? oldLineno : yylineno); @@ -180,7 +178,6 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel) /* if this is a literal then we already know the result */ if (condAst->etype && IS_LITERAL (condAst->etype)) { - /* then depending on the expression value */ if (floatFromVal (condAst->opval.val)) ifxNode = newNode (GOTO, @@ -223,9 +220,14 @@ copyAstValues (ast * dest, ast * src) break; case INLINEASM: - dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1); + dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1); strcpy (dest->values.inlineasm, src->values.inlineasm); + break; + case ARRAYINIT: + dest->values.constlist = copyLiteralList(src->values.constlist); + break; + case FOR: AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel)); AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel)); @@ -249,13 +251,12 @@ copyAst (ast * src) if (!src) return NULL; - dest = Safe_calloc (1, sizeof (ast)); + dest = Safe_alloc ( sizeof (ast)); dest->type = src->type; dest->lineno = src->lineno; dest->level = src->level; dest->funcName = src->funcName; - dest->argSym = src->argSym; /* if this is a leaf */ /* if value */ @@ -462,6 +463,7 @@ resolveSymbols (ast * tree) tree->opval.val->etype = tree->opval.val->etype; tree->opval.val->type = tree->opval.val->sym->type; werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name); + allocVariables (tree->opval.val->sym); } else { @@ -539,12 +541,18 @@ funcOfType (char *name, sym_link * type, sym_link * argType, /* create the symbol */ sym = newSymbol (name, 0); + /* setup return value */ + sym->type = newLink (); + DCL_TYPE (sym->type) = FUNCTION; + sym->type->next = copyLinkChain (type); + sym->etype = getSpec (sym->type); + FUNC_ISREENT(sym->type) = rent; + /* if arguments required */ if (nArgs) { - value *args; - args = sym->args = newValue (); + args = FUNC_ARGS(sym->type) = newValue (); while (nArgs--) { @@ -556,13 +564,6 @@ funcOfType (char *name, sym_link * type, sym_link * argType, } } - /* setup return value */ - sym->type = newLink (); - DCL_TYPE (sym->type) = FUNCTION; - sym->type->next = copyLinkChain (type); - sym->etype = getSpec (sym->type); - SPEC_RENT (sym->etype) = rent; - /* save it */ addSymChain (sym); sym->cdef = 1; @@ -600,31 +601,35 @@ reverseParms (ast * ptree) /*-----------------------------------------------------------------*/ int processParms (ast * func, - value * defParm, + value *defParm, ast * actParm, - int *parmNumber, - bool rightmost) + int *parmNumber, // unused, although updated + bool rightmost) // double checked? { - sym_link *fetype = func->etype; - /* if none of them exist */ if (!defParm && !actParm) return 0; + if (defParm) { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "processParms: %s ", defParm->name); + } + /* make sure the type is complete and sane */ + checkTypeSanity(defParm->etype, defParm->name); + } + /* if the function is being called via a pointer & */ /* it has not been defined a reentrant then we cannot */ /* have parameters */ - if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto) + if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto) { - werror (E_NONRENT_ARGS); + werror (W_NONRENT_ARGS); return 1; } /* if defined parameters ended but actual parameters */ /* exist and this is not defined as a variable arg */ - /* also check if statckAuto option is specified */ - if ((!defParm) && actParm && (!func->hasVargs) && - !options.stackAuto && !IS_RENT (fetype)) + if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype)) { werror (E_TOO_MANY_PARMS); return 1; @@ -638,7 +643,7 @@ processParms (ast * func, } /* If this is a varargs function... */ - if (!defParm && actParm && func->hasVargs) + if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype)) { ast *newType = NULL; sym_link *ftype; @@ -680,6 +685,7 @@ processParms (ast * func, if (IS_AGGREGATE (ftype)) { + // jwk: don't we need aggregateToPointer here? newType = newAst_LINK (copyLinkChain (ftype)); DCL_TYPE (newType->opval.lnk) = GPOINTER; } @@ -705,7 +711,7 @@ processParms (ast * func, /* if defined parameters ended but actual has not & */ /* stackAuto */ if (!defParm && actParm && - (options.stackAuto || IS_RENT (fetype))) + (options.stackAuto || IFFUNC_ISREENT (func->ftype))) return 0; resolveSymbols (actParm); @@ -723,7 +729,7 @@ processParms (ast * func, * Therefore, if there are more defined parameters, the caller didn't * supply enough. */ - if (rightmost && defParm->next) + if (0 && rightmost && defParm->next) { werror (E_TOO_FEW_PARMS); return 1; @@ -731,19 +737,19 @@ processParms (ast * func, } /* the parameter type must be at least castable */ - if (checkType (defParm->type, actParm->ftype) == 0) - { - werror (E_TYPE_MISMATCH_PARM, *parmNumber); - werror (E_CONTINUE, "defined type "); - printTypeChain (defParm->type, stderr); - fprintf (stderr, "\n"); - werror (E_CONTINUE, "actual type "); - printTypeChain (actParm->ftype, stderr); - fprintf (stderr, "\n"); - } + if (compareType (defParm->type, actParm->ftype) == 0) { + werror (E_INCOMPAT_TYPES); + fprintf (stderr, "type --> '"); + printTypeChain (actParm->ftype, stderr); + fprintf (stderr, "' "); + fprintf (stderr, "assigned to type --> '"); + printTypeChain (defParm->type, stderr); + fprintf (stderr, "'\n"); + return 1; + } /* if the parameter is castable then add the cast */ - if (checkType (defParm->type, actParm->ftype) < 0) + if (compareType (defParm->type, actParm->ftype) < 0) { ast *pTree = resolveSymbols (copyAst (actParm)); @@ -756,9 +762,6 @@ processParms (ast * func, actParm->ftype = defParm->type; } -/* actParm->argSym = resolveFromTable(defParm)->sym ; */ - - actParm->argSym = defParm->sym; /* make a copy and change the regparm type to the defined parm */ actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype)); SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype); @@ -825,6 +828,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) ast *rast = NULL; initList *iloop; int lcnt = 0, size = 0; + literalList *literalL; /* take care of the special case */ /* array of characters can be init */ @@ -836,51 +840,77 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) return decorateType (resolveSymbols (rast)); - /* not the special case */ - if (ilist->type != INIT_DEEP) + /* not the special case */ + if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, ""); - return NULL; + werror (E_INIT_STRUCT, ""); + return NULL; } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - for (;;) + if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) { - ast *aSym; - size++; - - aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1)))); - aSym = decorateType (resolveSymbols (aSym)); - rast = createIval (aSym, type->next, iloop, rast); - iloop = (iloop ? iloop->next : NULL); - if (!iloop) - break; - /* if not array limits given & we */ - /* are out of initialisers then */ - if (!DCL_ELEM (type) && !iloop) - break; + ast *aSym; - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) { - /* if initializers left */ - if (iloop) { - // there has to be a better way - char *name=sym->opval.val->sym->name; - int lineno=sym->opval.val->sym->lineDef; - werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + aSym = decorateType (resolveSymbols(sym)); + + 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; + + werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + } + } + else + { + for (;;) + { + ast *aSym; + + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); + aSym = decorateType (resolveSymbols (aSym)); + 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) + { + // there has to be a better way + char *name=sym->opval.val->sym->name; + int lineno=sym->opval.val->sym->lineDef; + werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + + break; + } } - break; - } } - /* if we have not been given a size */ - if (!DCL_ELEM (type)) - DCL_ELEM (type) = size; + /* if we have not been given a size */ + if (!DCL_ELEM (type)) + { + DCL_ELEM (type) = size; + } - return decorateType (resolveSymbols (rast)); + return decorateType (resolveSymbols (rast)); } @@ -905,7 +935,6 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) SPEC_SCLS (iexpr->etype) == S_CODE) && IS_ARRAY (iexpr->ftype)) { - /* for each character generate an assignment */ /* to the array element */ char *s = SPEC_CVAL (iexpr->etype).v_char; @@ -983,6 +1012,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /* if type is SPECIFIER */ if (IS_SPEC (type)) rast = createIvalType (sym, type, ilist); + if (wid) return decorateType (resolveSymbols (newNode (NULLOP, wid, rast))); else @@ -992,9 +1022,42 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /*-----------------------------------------------------------------*/ /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ -ast * -initAggregates (symbol * sym, initList * ival, ast * wid) -{ + +/* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *); + +ast * initAggregates (symbol * sym, initList * ival, ast * wid) { + ast *ast; + symbol *newSym; + + if (getenv("TRY_THE_NEW_INITIALIZER")) { + + if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) { + fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless " + "with -mmcs51 and --model-large"); + exit(404); + } + + if (SPEC_OCLS(sym->etype)==xdata && + getSize(sym->type) > 16) { // else it isn't worth it: do it the old way + + // copy this symbol + newSym=copySymbol (sym); + SPEC_OCLS(newSym->etype)=code; + sprintf (newSym->name, "%s_init__", sym->name); + sprintf (newSym->rname,"%s_init__", sym->rname); + addSym (SymbolTab, newSym, newSym->name, 0, 0, 1); + + // emit it in the static segment + addSet(&statsg->syms, newSym); + + // now memcpy() the entire array from cseg + ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE + newAst_VALUE (symbolVal (sym)), + newAst_VALUE (symbolVal (newSym))); + return decorateType(resolveSymbols(ast)); + } + } + return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid); } @@ -1027,14 +1090,14 @@ gatherAutoInit (symbol * autoChain) symbol *newSym; // this can only be a constant - if (!IS_LITERAL(sym->ival->init.node->etype)) { + if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) { werror (E_CONST_EXPECTED); } /* insert the symbol into the symbol table */ /* with level = 0 & name = rname */ newSym = copySymbol (sym); - addSym (SymbolTab, newSym, newSym->name, 0, 0); + addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1); /* now lift the code to main */ if (IS_AGGREGATE (sym->type)) @@ -1130,8 +1193,8 @@ processBlockVars (ast * tree, int *stack, int action) if (action == ALLOCATE) { - autoInit = gatherAutoInit (tree->values.sym); *stack += allocVariables (tree->values.sym); + autoInit = gatherAutoInit (tree->values.sym); /* if there are auto inits then do them */ if (autoInit) @@ -1148,6 +1211,7 @@ processBlockVars (ast * tree, int *stack, int action) /*-----------------------------------------------------------------*/ /* constExprValue - returns the value of a constant expression */ +/* or NULL if it is not a constant expression */ /*-----------------------------------------------------------------*/ value * constExprValue (ast * cexpr, int check) @@ -1384,11 +1448,25 @@ astHasSymbol (ast * tree, symbol * sym) else return FALSE; } - + return astHasSymbol (tree->left, sym) || astHasSymbol (tree->right, sym); } +/*-----------------------------------------------------------------*/ +/* astHasDeref - return true if the ast has an indirect access */ +/*-----------------------------------------------------------------*/ +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); +} + /*-----------------------------------------------------------------*/ /* isConformingBody - the loop body has to conform to a set of rules */ /* for the loop to be considered reversible read on for rules */ @@ -1539,6 +1617,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) if (astHasVolatile (pbody->left)) return FALSE; + + if (astHasDeref(pbody->right)) return FALSE; return isConformingBody (pbody->left, sym, body) && isConformingBody (pbody->right, sym, body); @@ -1705,7 +1785,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) } -#define DEMAND_INTEGER_PROMOTION +//#define DEMAND_INTEGER_PROMOTION #ifdef DEMAND_INTEGER_PROMOTION @@ -1827,11 +1907,6 @@ decorateType (ast * tree) /* otherwise just copy the type information */ COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); - if (funcInChain (tree->opval.val->type)) - { - tree->hasVargs = tree->opval.val->sym->hasVargs; - tree->args = copyValueChain (tree->opval.val->sym->args); - } return tree; } @@ -1862,13 +1937,6 @@ decorateType (ast * tree) /* and mark it as referenced */ tree->opval.val->sym->isref = 1; - /* if this is of type function or function pointer */ - if (funcInChain (tree->opval.val->type)) - { - tree->hasVargs = tree->opval.val->sym->hasVargs; - tree->args = copyValueChain (tree->opval.val->sym->args); - - } } } } @@ -1901,10 +1969,10 @@ decorateType (ast * tree) switch (tree->opval.op) { -/*------------------------------------------------------------------*/ -/*----------------------------*/ - /* array node */ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* array node */ + /*----------------------------*/ case '[': /* determine which is the array & which the index */ @@ -1943,10 +2011,10 @@ decorateType (ast * tree) } return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* struct/union */ -/*----------------------------*/ + /*----------------------------*/ case '.': /* if this is not a structure */ if (!IS_STRUCT (LTYPE (tree))) @@ -1956,14 +2024,14 @@ decorateType (ast * tree) } TTYPE (tree) = structElemType (LTYPE (tree), (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL), &tree->args); + tree->right->opval.val : NULL)); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* struct/union pointer */ -/*----------------------------*/ + /*----------------------------*/ case PTR_OP: /* if not pointer to a structure */ if (!IS_PTR (LTYPE (tree))) @@ -1980,7 +2048,7 @@ decorateType (ast * tree) TTYPE (tree) = structElemType (LTYPE (tree)->next, (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL), &tree->args); + tree->right->opval.val : NULL)); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -1993,7 +2061,7 @@ decorateType (ast * tree) { sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree)); COPYTYPE (TTYPE (tree), TETYPE (tree), ltc); - if (!tree->initMode && IS_CONSTANT (TETYPE (tree))) + if (!tree->initMode && IS_CONSTANT(TETYPE(tree))) werror (E_CODE_WRITE, "++/--"); if (tree->right) @@ -2015,7 +2083,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2045,6 +2113,9 @@ decorateType (ast * tree) return decorateType (otree); } +#if 0 + // we can't do this because of "(int & 0xff) << 3" + /* if right or left is literal then result of that type */ if (IS_LITERAL (RTYPE (tree))) { @@ -2069,6 +2140,11 @@ decorateType (ast * tree) TETYPE (tree) = getSpec (TTYPE (tree)); } } +#else + TTYPE (tree) = + computeType (LTYPE (tree), RTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); +#endif LRVAL (tree) = RRVAL (tree) = 1; return tree; } @@ -2153,7 +2229,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2215,7 +2291,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2260,9 +2336,7 @@ decorateType (ast * tree) } TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ? LTYPE (tree)->next : NULL); - TETYPE (tree) = getSpec (TTYPE (tree)); - tree->args = tree->left->args; - tree->hasVargs = tree->left->hasVargs; + TETYPE (tree) = getSpec (TTYPE (tree)); SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree)); return tree; } @@ -2299,19 +2373,17 @@ decorateType (ast * tree) } LRVAL (tree) = RRVAL (tree) = 1; - /* promote result to int if left & right are char / short + /* promote result to int if left & right are char this will facilitate hardware multiplies 8bit x 8bit = 16bit */ - if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) && - (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree))); - SPEC_NOUN(TETYPE(tree)) = V_INT; - SPEC_SHORT(TETYPE(tree))=0; + if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) { + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + SPEC_NOUN(TETYPE(tree)) = V_INT; } else { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree))); + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); } return tree; @@ -2576,7 +2648,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype)) { werror (E_SHIFT_OP_INVALID); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2622,10 +2694,10 @@ decorateType (ast * tree) } return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* casting */ -/*----------------------------*/ + /*----------------------------*/ case CAST: /* change the type */ /* cannot cast to an aggregate type */ if (IS_AGGREGATE (LTYPE (tree))) @@ -2637,23 +2709,51 @@ decorateType (ast * tree) /* make sure the type is complete and sane */ checkTypeSanity(LETYPE(tree), "(cast)"); +#if 0 /* if the right is a literal replace the tree */ - if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = - valCastLiteral (LTYPE (tree), - floatFromVal (valFromType (RETYPE (tree)))); - tree->left = NULL; - tree->right = NULL; - TTYPE (tree) = tree->opval.val->type; - tree->values.literalFromCast = 1; - } - else - { - TTYPE (tree) = LTYPE (tree); - LRVAL (tree) = 1; - } + if (IS_LITERAL (RETYPE (tree))) { + if (!IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && + ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ { + sym_link *rest = LTYPE(tree)->next; + werror(W_LITERAL_GENERIC); + TTYPE(tree) = newLink(); + DCL_TYPE(TTYPE(tree)) = FPOINTER; + TTYPE(tree)->next = rest; + tree->left->opval.lnk = TTYPE(tree); + LRVAL (tree) = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } +#else + /* if the right is a literal replace the tree */ + if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } +#endif TETYPE (tree) = getSpec (TTYPE (tree)); @@ -2719,7 +2819,7 @@ decorateType (ast * tree) /* if they are pointers they must be castable */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) { - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); fprintf (stderr, "comparing type "); @@ -2736,7 +2836,7 @@ decorateType (ast * tree) if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) || (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))))) - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); fprintf (stderr, "comparing type "); @@ -2780,19 +2880,30 @@ decorateType (ast * tree) tree->opval.val->type); return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* conditional operator '?' */ -/*----------------------------*/ + /*----------------------------*/ case '?': - /* the type is one on the left */ - TTYPE (tree) = LTYPE (tree); - TETYPE (tree) = getSpec (TTYPE (tree)); + /* the type is value of the colon operator (on the right) */ + assert(IS_COLON_OP(tree->right)); + /* if already known then replace the tree : optimizer will do it + but faster to do it here */ + if (IS_LITERAL (LTYPE(tree))) { + if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) { + return tree->right->left ; + } else { + return tree->right->right ; + } + } else { + TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree). + TETYPE (tree) = getSpec (TTYPE (tree)); + } return tree; case ':': /* if they don't match we have a problem */ - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_TYPE_MISMATCH, "conditional operator", " "); goto errorTreeReturn; @@ -2957,7 +3068,7 @@ decorateType (ast * tree) } /* they should either match or be castable */ - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_TYPE_MISMATCH, "assignment", " "); fprintf (stderr, "type --> '"); @@ -2982,22 +3093,13 @@ decorateType (ast * tree) fprintf (stderr, "'\n"); } - /* extra checks for pointer types */ - if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && - !IS_GENPTR (LTYPE (tree))) - { - if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree))) - werror (W_PTR_ASSIGN); - } - TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); RRVAL (tree) = 1; LLVAL (tree) = 1; if (!tree->initMode ) { - if (IS_CONSTANT (LETYPE (tree))) { - werror (E_CODE_WRITE, " "); - } + if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree)))) + werror (E_CODE_WRITE, " "); } if (LRVAL (tree)) { @@ -3025,17 +3127,17 @@ decorateType (ast * tree) parmNumber = 1; if (processParms (tree->left, - tree->left->args, + FUNC_ARGS(tree->left->ftype), tree->right, &parmNumber, TRUE)) goto errorTreeReturn; - if (options.stackAuto || IS_RENT (LETYPE (tree))) + if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) { - tree->left->args = reverseVal (tree->left->args); + //IFFUNC_ARGS(tree->left->ftype) = + //reverseVal (IFFUNC_ARGS(tree->left->ftype)); reverseParms (tree->right); } - tree->args = tree->left->args; TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next); return tree; @@ -3047,9 +3149,14 @@ decorateType (ast * tree) if (!tree->right) goto voidcheck; - if (checkType (currFunc->type->next, RTYPE (tree)) == 0) + if (compareType (currFunc->type->next, RTYPE (tree)) == 0) { - werror (E_RETURN_MISMATCH); + werror (W_RETURN_MISMATCH); + fprintf (stderr, "from type '"); + printTypeChain (RTYPE(tree), stderr); + fprintf (stderr, "' to type '"); + printTypeChain (currFunc->type->next, stderr); + fprintf (stderr, "'\n"); goto errorTreeReturn; } @@ -3062,7 +3169,7 @@ decorateType (ast * tree) } /* if there is going to be a casing required then add it */ - if (checkType (currFunc->type->next, RTYPE (tree)) < 0) + if (compareType (currFunc->type->next, RTYPE (tree)) < 0) { #if 0 && defined DEMAND_INTEGER_PROMOTION if (IS_INTEGRAL (currFunc->type->next)) @@ -3334,7 +3441,7 @@ createLabel (symbol * label, ast * stmnt) if ((csym = findSym (LabelTab, NULL, name))) werror (E_DUPLICATE_LABEL, label->name); else - addSym (LabelTab, label, name, label->level, 0); + addSym (LabelTab, label, name, label->level, 0, 0); label->islbl = 1; label->key = labelKey++; @@ -3458,8 +3565,12 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody) symbol *ifTrue, *ifFalse, *ifEnd; /* if neither exists */ - if (!elseBody && !ifBody) - return condAst; + if (!elseBody && !ifBody) { + // if there are no side effects (i++, j() etc) + if (!hasSEFcalls(condAst)) { + return condAst; + } + } /* create the labels */ sprintf (buffer, "_iffalse_%d", Lblnum); @@ -4038,7 +4149,7 @@ createFunction (symbol * name, ast * body) iCode *piCode = NULL; /* if check function return 0 then some problem */ - if (checkFunction (name) == 0) + if (checkFunction (name, NULL) == 0) return NULL; /* create a dummy block if none exists */ @@ -4072,22 +4183,22 @@ createFunction (symbol * name, ast * body) /* set the stack pointer */ /* PENDING: check this for the mcs51 */ stackPtr = -port->stack.direction * port->stack.call_overhead; - if (IS_ISR (name->etype)) + if (IFFUNC_ISISR (name->type)) stackPtr -= port->stack.direction * port->stack.isr_overhead; - if (IS_RENT (name->etype) || options.stackAuto) + if (IFFUNC_ISREENT (name->type) || options.stackAuto) stackPtr -= port->stack.direction * port->stack.reent_overhead; xstackPtr = -port->stack.direction * port->stack.call_overhead; fetype = getSpec (name->type); /* get the specifier for the function */ /* if this is a reentrant function then */ - if (IS_RENT (fetype)) + if (IFFUNC_ISREENT (name->type)) reentrant++; - allocParms (name->args); /* allocate the parameters */ + allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */ /* do processing for parameters that are passed in registers */ - processRegParms (name->args, body); + processRegParms (FUNC_ARGS(name->type), body); /* set the stack pointer */ stackPtr = 0; @@ -4110,7 +4221,7 @@ createFunction (symbol * name, ast * body) ex = newAst_VALUE (symbolVal (name)); /* create name */ ex = newNode (FUNCTION, ex, body); - ex->values.args = name->args; + ex->values.args = FUNC_ARGS(name->type); if (fatalError) { @@ -4145,20 +4256,20 @@ skipall: /* dealloc the block variables */ processBlockVars (body, &stack, DEALLOCATE); /* deallocate paramaters */ - deallocParms (name->args); + deallocParms (FUNC_ARGS(name->type)); - if (IS_RENT (fetype)) + if (IFFUNC_ISREENT (name->type)) reentrant--; /* we are done freeup memory & cleanup */ noLineno--; labelKey = 1; name->key = 0; - name->fbody = 1; + FUNC_HASBODY(name->type) = 1; addSet (&operKeyReset, name); applyToSet (operKeyReset, resetParmKey); - if (options.debug && !options.nodebug) + if (options.debug) cdbStructBlock (1, cdbFile); cleanUpLevel (LabelTab, 0); @@ -4609,6 +4720,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,")\n"); ast_print(tree->left,outfile,indent+4); ast_print(tree->right,outfile,indent+4); + return; case ':': fprintf(outfile,"COLON(:) (%p) type (",tree);