X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=a7cbd7c0185f937617641c4aa2f0dd827f584460;hb=8b5bb80cd4be94a5da5af05c2abe67ab8c61939a;hp=5308992cf4efbcfb9855ff352de4587f59c689d2;hpb=15f7f3d75ebe0d7cf0ef84dea8abcd19cbdaa009;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 5308992c..a7cbd7c0 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -22,6 +22,8 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ +#define DEBUG_CF(x) /* puts(x); */ + #include "common.h" int currLineno = 0; @@ -647,7 +649,7 @@ reverseParms (ast * ptree) static int processParms (ast *func, value *defParm, - ast *actParm, + ast **actParm, int *parmNumber, /* unused, although updated */ bool rightmost) { @@ -655,7 +657,7 @@ processParms (ast *func, sym_link *functype; /* if none of them exist */ - if (!defParm && !actParm) + if (!defParm && !*actParm) return 0; if (defParm) @@ -685,27 +687,27 @@ processParms (ast *func, /* if defined parameters ended but actual parameters */ /* exist and this is not defined as a variable arg */ - if (!defParm && actParm && !IFFUNC_HASVARARGS(functype)) + if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype)) { werror (E_TOO_MANY_PARMS); return 1; } /* if defined parameters present but no actual parameters */ - if (defParm && !actParm) + if (defParm && !*actParm) { werror (E_TOO_FEW_PARMS); return 1; } /* if this is a PARAM node then match left & right */ - if (actParm->type == EX_OP && actParm->opval.op == PARAM) + if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM) { - actParm->decorated = 1; + (*actParm)->decorated = 1; return (processParms (func, defParm, - actParm->left, parmNumber, FALSE) || + &(*actParm)->left, parmNumber, FALSE) || processParms (func, defParm ? defParm->next : NULL, - actParm->right, parmNumber, rightmost)); + &(*actParm)->right, parmNumber, rightmost)); } else if (defParm) /* not vararg */ { @@ -725,28 +727,28 @@ processParms (ast *func, /* decorate parameter */ resultType = defParm ? getResultTypeFromType (defParm->etype) : RESULT_TYPE_NONE; - actParm = decorateType (actParm, resultType); + *actParm = decorateType (*actParm, resultType); - if (IS_VOID(actParm->ftype)) + if (IS_VOID((*actParm)->ftype)) { werror (E_VOID_VALUE_USED); return 1; } /* If this is a varargs function... */ - if (!defParm && actParm && IFFUNC_HASVARARGS(functype)) + if (!defParm && *actParm && IFFUNC_HASVARARGS(functype)) { ast *newType = NULL; sym_link *ftype; - if (IS_CAST_OP (actParm) - || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast)) + if (IS_CAST_OP (*actParm) + || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast)) { /* Parameter was explicitly typecast; don't touch it. */ return 0; } - ftype = actParm->ftype; + ftype = (*actParm)->ftype; /* If it's a char, upcast to int. */ if (IS_INTEGRAL (ftype) @@ -770,55 +772,55 @@ processParms (ast *func, if (newType) { /* cast required; change this op to a cast. */ - ast *parmCopy = resolveSymbols (copyAst (actParm)); + ast *parmCopy = resolveSymbols (copyAst (*actParm)); - actParm->type = EX_OP; - actParm->opval.op = CAST; - actParm->left = newType; - actParm->right = parmCopy; - actParm->decorated = 0; /* force typechecking */ - decorateType (actParm, RESULT_TYPE_NONE); + (*actParm)->type = EX_OP; + (*actParm)->opval.op = CAST; + (*actParm)->left = newType; + (*actParm)->right = parmCopy; + (*actParm)->decorated = 0; /* force typechecking */ + decorateType (*actParm, RESULT_TYPE_NONE); } return 0; } /* vararg */ /* if defined parameters ended but actual has not & */ /* reentrant */ - if (!defParm && actParm && + if (!defParm && *actParm && (options.stackAuto || IFFUNC_ISREENT (functype))) return 0; - resolveSymbols (actParm); + resolveSymbols (*actParm); /* the parameter type must be at least castable */ - if (compareType (defParm->type, actParm->ftype) == 0) + if (compareType (defParm->type, (*actParm)->ftype) == 0) { werror (E_INCOMPAT_TYPES); - printFromToType (actParm->ftype, defParm->type); + printFromToType ((*actParm)->ftype, defParm->type); return 1; } /* if the parameter is castable then add the cast */ - if (compareType (defParm->type, actParm->ftype) < 0) + if (compareType (defParm->type, (*actParm)->ftype) < 0) { ast *pTree; resultType = getResultTypeFromType (defParm->etype); - pTree = resolveSymbols (copyAst (actParm)); + pTree = resolveSymbols (copyAst (*actParm)); /* now change the current one to a cast */ - actParm->type = EX_OP; - actParm->opval.op = CAST; - actParm->left = newAst_LINK (defParm->type); - actParm->right = pTree; - actParm->decorated = 0; /* force typechecking */ - decorateType (actParm, resultType); + (*actParm)->type = EX_OP; + (*actParm)->opval.op = CAST; + (*actParm)->left = newAst_LINK (defParm->type); + (*actParm)->right = pTree; + (*actParm)->decorated = 0; /* force typechecking */ + decorateType (*actParm, resultType); } /* 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); - SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype); + (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype)); + SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype); + SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype); (*parmNumber)++; return 0; } @@ -1979,7 +1981,7 @@ searchLitOp (ast *tree, ast **parent, const char *ops) tree->right->right && (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1])) { - if (IS_LITERAL (RTYPE (tree->right)) ^ + if (IS_LITERAL (RTYPE (tree->right)) != IS_LITERAL (LTYPE (tree->right))) { tree->right->decorated = 0; @@ -1996,7 +1998,7 @@ searchLitOp (ast *tree, ast **parent, const char *ops) tree->left->right && (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1])) { - if (IS_LITERAL (RTYPE (tree->left)) ^ + if (IS_LITERAL (RTYPE (tree->left)) != IS_LITERAL (LTYPE (tree->left))) { tree->left->decorated = 0; @@ -2019,10 +2021,18 @@ RESULT_TYPE getResultTypeFromType (sym_link *type) { /* type = getSpec (type); */ - if (IS_BITVAR (type)) + if (IS_BIT (type)) return RESULT_TYPE_BIT; if (IS_BITFIELD (type)) - return RESULT_TYPE_CHAR; + { + int blen = SPEC_BLEN (type); + + if (blen <= 1) + return RESULT_TYPE_BIT; + if (blen <= 8) + return RESULT_TYPE_CHAR; + return RESULT_TYPE_INT; + } if (IS_CHAR (type)) return RESULT_TYPE_CHAR; if ( IS_INT (type) @@ -2051,7 +2061,8 @@ addCast (ast *tree, RESULT_TYPE resultType, bool upcast) upCasted = TRUE; break; case RESULT_TYPE_CHAR: - if (getSize (tree->etype) <= 1) + if (IS_CHAR (tree->etype) || + IS_FLOAT(tree->etype)) return tree; newLink = newCharLink(); break; @@ -2105,6 +2116,7 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) case ':': case '|': case '^': + case '~': case '*': case '+': case '-': @@ -2554,9 +2566,10 @@ decorateType (ast * tree, RESULT_TYPE resultType) return decorateType (otree, RESULT_CHECK); } - tree->left = addCast (tree->left, resultType, FALSE); - tree->right = addCast (tree->right, resultType, FALSE); - TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE); + TTYPE (tree) = computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op); TETYPE (tree) = getSpec (TTYPE (tree)); /* if left is a literal exchange left & right */ @@ -2576,11 +2589,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) ast *litTree = searchLitOp (tree, &parent, "&"); if (litTree) { - ast *tTree = litTree->left; + DEBUG_CF("&") + ast *tTree = litTree->left; litTree->left = tree->right; tree->right = tTree; /* both operands in tTree are literal now */ - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } } @@ -2703,11 +2717,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) ast *litTree = searchLitOp (tree, &parent, "|"); if (litTree) { + DEBUG_CF("|") ast *tTree = litTree->left; litTree->left = tree->right; tree->right = tTree; /* both operands in tTree are literal now */ - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } } /* fall through */ @@ -2760,21 +2775,21 @@ decorateType (ast * tree, RESULT_TYPE resultType) ast *litTree = searchLitOp (tree, &parent, "^"); if (litTree) { + DEBUG_CF("^") ast *tTree = litTree->left; litTree->left = tree->right; tree->right = tTree; /* both operands in litTree are literal now */ - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } } LRVAL (tree) = RRVAL (tree) = 1; - tree->left = addCast (tree->left, resultType, FALSE); - tree->right = addCast (tree->right, resultType, FALSE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), - FALSE)); + resultType, + tree->opval.op)); return tree; @@ -2806,7 +2821,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), - resultType == RESULT_TYPE_CHAR ? FALSE : TRUE)); + resultType, + tree->opval.op)); /* if right is a literal and */ /* left is also a division by a literal then */ @@ -2822,11 +2838,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_LITERAL (RTYPE (litTree))) { /* foo_div */ - litTree->right = newNode ('*', litTree->right, tree->right); + DEBUG_CF("div r") + litTree->right = newNode ('*', + litTree->right, + copyAst (tree->right)); litTree->right->lineno = tree->lineno; tree->right->opval.val = constVal ("1"); - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } else { @@ -2834,7 +2853,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) We can't call decorateType(parent, RESULT_CHECK), because this would cause an infinit loop. */ parent->decorated = 1; - decorateType (litTree, RESULT_CHECK); + decorateType (litTree, resultType); } } } @@ -2872,7 +2891,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), - resultType == RESULT_TYPE_CHAR ? FALSE : TRUE)); + resultType, + tree->opval.op)); return tree; /*------------------------------------------------------------------*/ @@ -2973,11 +2993,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) ast *litTree = searchLitOp (tree, &parent, "*"); if (litTree) { + DEBUG_CF("mul") ast *tTree = litTree->left; litTree->left = tree->right; tree->right = tTree; /* both operands in litTree are literal now */ - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } } @@ -2987,7 +3008,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), - resultType == RESULT_TYPE_CHAR ? FALSE : TRUE)); + resultType, + tree->opval.op)); return tree; @@ -3051,6 +3073,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) { tree->type = EX_VALUE; + tree->left = addCast (tree->left, resultType, TRUE); + tree->right = addCast (tree->right, resultType, TRUE); tree->opval.val = valPlus (valFromType (LETYPE (tree)), valFromType (RETYPE (tree))); tree->right = tree->left = NULL; @@ -3082,6 +3106,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (litTree->opval.op == '+') { /* foo_aa */ + DEBUG_CF("+ 1 AA") ast *tTree = litTree->left; litTree->left = tree->right; tree->right = tree->left; @@ -3091,6 +3116,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) { if (IS_LITERAL (RTYPE (litTree))) { + DEBUG_CF("+ 2 ASR") /* foo_asr */ ast *tTree = litTree->left; litTree->left = tree->right; @@ -3098,6 +3124,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) } else { + DEBUG_CF("+ 3 ASL") /* foo_asl */ ast *tTree = litTree->right; litTree->right = tree->right; @@ -3106,7 +3133,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.op = '-'; } } - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } } @@ -3121,8 +3148,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->right = addCast (tree->right, resultType, TRUE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree), - resultType == RESULT_TYPE_CHAR ? FALSE : TRUE)); + RTYPE (tree), + resultType, + tree->opval.op)); } return tree; @@ -3191,6 +3219,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) { tree->type = EX_VALUE; + tree->left = addCast (tree->left, resultType, TRUE); + tree->right = addCast (tree->right, resultType, TRUE); tree->opval.val = valMinus (valFromType (LETYPE (tree)), valFromType (RETYPE (tree))); tree->right = tree->left = NULL; @@ -3224,10 +3254,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) { tree->left = addCast (tree->left, resultType, TRUE); tree->right = addCast (tree->right, resultType, TRUE); + TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree), - resultType == RESULT_TYPE_CHAR ? FALSE : TRUE)); + RTYPE (tree), + resultType, + tree->opval.op)); } LRVAL (tree) = RRVAL (tree) = 1; @@ -3246,30 +3278,39 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (litTree->opval.op == '+') { /* foo_sa */ - litTree->right = newNode ('-', litTree->right, tree->right); - litTree->right->lineno = tree->lineno; - - tree->right->opval.val = constVal ("0"); + DEBUG_CF("- 1 SA") + ast *tTree = litTree->left; + litTree->left = litTree->right; + litTree->right = tree->right; + tree->right = tTree; + tree->opval.op = '+'; + litTree->opval.op = '-'; } else if (litTree->opval.op == '-') { if (IS_LITERAL (RTYPE (litTree))) { /* foo_ssr */ - litTree->right = newNode ('+', tree->right, litTree->right); - litTree->right->lineno = tree->lineno; - - tree->right->opval.val = constVal ("0"); + DEBUG_CF("- 2 SSR") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = litParent->left; + litParent->left = tTree; + litTree->opval.op = '+'; + + tree->decorated = 0; + decorateType (tree, resultType); } else { /* foo_ssl */ + DEBUG_CF("- 3 SSL") ast *tTree = litTree->right; litTree->right = tree->right; tree->right = tTree; } } - decorateType (litParent, RESULT_CHECK); + decorateType (litParent, resultType); } } return tree; @@ -3295,6 +3336,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; return tree; } + tree->left = addCast (tree->left, resultType, TRUE); LRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); return tree; @@ -3354,6 +3396,10 @@ decorateType (ast * tree, RESULT_TYPE resultType) goto errorTreeReturn; } + /* 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))) @@ -3371,11 +3417,11 @@ decorateType (ast * tree, RESULT_TYPE resultType) LRVAL (tree) = RRVAL (tree) = 1; if (tree->opval.op == LEFT_OP) { - tree->left = addCast (tree->left, resultType, TRUE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - NULL, - resultType == RESULT_TYPE_CHAR ? FALSE : TRUE)); + NULL, + resultType, + tree->opval.op)); } else /* RIGHT_OP */ { @@ -3594,7 +3640,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case AND_OP: case OR_OP: - /* each must me arithmetic type or be a pointer */ + /* each must be arithmetic type or be a pointer */ if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)) && !IS_INTEGRAL (LTYPE (tree))) @@ -3858,7 +3904,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) goto errorTreeReturn; } - TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE); + TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), + resultType, tree->opval.op); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -3941,7 +3988,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), - FALSE)); + RESULT_TYPE_NOPROM, + tree->opval.op)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) werror (E_CODE_WRITE, "-="); @@ -3983,7 +4031,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), - FALSE)); + RESULT_TYPE_NOPROM, + tree->opval.op)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) werror (E_CODE_WRITE, "+="); @@ -4082,7 +4131,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) functype = LTYPE (tree); if (processParms (tree->left, FUNC_ARGS(functype), - tree->right, &parmNumber, TRUE)) { + &tree->right, &parmNumber, TRUE)) { goto errorTreeReturn; }