X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=f44ae1cc744590b239bde7a01f464f7c1e3c8462;hb=02f0f9893dbcaa7aa93cb8ac1d2e28475e181352;hp=143d7b2d8708c12336ecef777c4b14b754a5b01b;hpb=85eb14cfe0a004bc714c7fc744080537bfbb4593;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 143d7b2d..f44ae1cc 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) @@ -768,57 +770,54 @@ processParms (ast *func, } if (newType) - { - /* cast required; change this op to a cast. */ - 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); - } + { + /* 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; } /* 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 +1978,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 +1995,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 +2018,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 +2058,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 +2113,7 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) case ':': case '|': case '^': + case '~': case '*': case '+': case '-': @@ -2288,7 +2297,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) resultTypeProp = resultTypePropagate (tree, resultType); if (tree->opval.op == '?') - dtl = decorateType (tree->left, RESULT_TYPE_NONE); + dtl = decorateType (tree->left, RESULT_TYPE_IFX); else dtl = decorateType (tree->left, resultTypeProp); @@ -2554,9 +2563,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 +2586,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 +2714,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 +2772,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 +2818,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 +2835,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 +2850,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 +2888,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 +2990,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 +3005,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 +3070,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 +3103,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 +3113,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 +3121,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) } else { + DEBUG_CF("+ 3 ASL") /* foo_asl */ ast *tTree = litTree->right; litTree->right = tree->right; @@ -3106,7 +3130,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.op = '-'; } } - decorateType (parent, RESULT_CHECK); + decorateType (parent, resultType); } } @@ -3121,8 +3145,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 +3216,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 +3251,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 +3275,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; @@ -3288,13 +3326,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if left is a literal then do it */ if (IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valComplement (valFromType (LETYPE (tree))); - tree->left = NULL; - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valComplement (valFromType (LETYPE (tree))); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return addCast (tree, resultType, TRUE); + } + tree->left = addCast (tree->left, resultType, TRUE); LRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); return tree; @@ -3354,6 +3393,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 +3414,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 +3637,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 +3901,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 +3985,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 +4028,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, "+="); @@ -4072,29 +4118,34 @@ decorateType (ast * tree, RESULT_TYPE resultType) goto errorTreeReturn; } - { - sym_link *functype; - parmNumber = 1; - - if (IS_CODEPTR(LTYPE(tree))) - functype = LTYPE (tree)->next; - else - functype = LTYPE (tree); + /* if there are parms, make sure that + parms are decorate / process / reverse only once */ + if (!tree->right || + !tree->right->decorated) + { + sym_link *functype; + parmNumber = 1; - if (processParms (tree->left, FUNC_ARGS(functype), - tree->right, &parmNumber, TRUE)) { - goto errorTreeReturn; - } + if (IS_CODEPTR(LTYPE(tree))) + functype = LTYPE (tree)->next; + else + functype = LTYPE (tree); - if ((options.stackAuto || IFFUNC_ISREENT (functype)) && - !IFFUNC_ISBUILTIN(functype)) - { - reverseParms (tree->right); - } + if (processParms (tree->left, FUNC_ARGS(functype), + &tree->right, &parmNumber, TRUE)) + { + goto errorTreeReturn; + } + + if ((options.stackAuto || IFFUNC_ISREENT (functype)) && + !IFFUNC_ISBUILTIN(functype)) + { + reverseParms (tree->right); + } - TTYPE (tree) = functype->next; - TETYPE (tree) = getSpec (TTYPE (tree)); - } + TTYPE (tree) = functype->next; + TETYPE (tree) = getSpec (TTYPE (tree)); + } return tree; /*------------------------------------------------------------------*/