what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
+#define DEBUG_CF(x) /* puts(x); */
+
#include "common.h"
int currLineno = 0;
static int
processParms (ast *func,
value *defParm,
- ast *actParm,
+ ast **actParm,
int *parmNumber, /* unused, although updated */
bool rightmost)
{
sym_link *functype;
/* if none of them exist */
- if (!defParm && !actParm)
+ if (!defParm && !*actParm)
return 0;
if (defParm)
/* 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 */
{
/* 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)
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;
}
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;
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;
upCasted = TRUE;
break;
case RESULT_TYPE_CHAR:
- if (IS_CHAR (tree->etype))
+ if (IS_CHAR (tree->etype) ||
+ IS_FLOAT(tree->etype))
return tree;
newLink = newCharLink();
break;
case ':':
case '|':
case '^':
+ case '~':
case '*':
case '+':
case '-':
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),
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);
}
}
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 */
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),
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
{
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);
}
}
}
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);
}
}
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;
if (litTree->opval.op == '+')
{
/* foo_aa */
+ DEBUG_CF("+ 1 AA")
ast *tTree = litTree->left;
litTree->left = tree->right;
tree->right = tree->left;
{
if (IS_LITERAL (RTYPE (litTree)))
{
+ DEBUG_CF("+ 2 ASR")
/* foo_asr */
ast *tTree = litTree->left;
litTree->left = tree->right;
}
else
{
+ DEBUG_CF("+ 3 ASL")
/* foo_asl */
ast *tTree = litTree->right;
litTree->right = tree->right;
tree->opval.op = '-';
}
}
- decorateType (parent, RESULT_CHECK);
+ decorateType (parent, 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;
{
tree->left = addCast (tree->left, resultType, TRUE);
tree->right = addCast (tree->right, resultType, TRUE);
+
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
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;
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;
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)))
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,
/*----------------------------*/
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)))
functype = LTYPE (tree);
if (processParms (tree->left, FUNC_ARGS(functype),
- tree->right, &parmNumber, TRUE)) {
+ &tree->right, &parmNumber, TRUE)) {
goto errorTreeReturn;
}