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));
-
- 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;
}
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 '-':
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);
}
}
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 (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 (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;
/* 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;
/*----------------------------*/
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)))
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;
/*------------------------------------------------------------------*/