/* processParms - makes sure the parameters are okay and do some */
/* processing with them */
/*-----------------------------------------------------------------*/
-int
-processParms (ast * func,
+static int
+processParms (ast *func,
value *defParm,
- ast * actParm,
- int *parmNumber, // unused, although updated
+ ast *actParm,
+ int *parmNumber, /* unused, although updated */
bool rightmost)
{
+ RESULT_TYPE resultType;
+
/* if none of them exist */
if (!defParm && !actParm)
return 0;
- if (defParm) {
- if (getenv("DEBUG_SANITY")) {
- fprintf (stderr, "processParms: %s ", defParm->name);
+ 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);
}
- /* 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 */
/* exist and this is not defined as a variable arg */
if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
{
- //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
- // return 1; /* Already gave them an undefined function error */
+ /* if (func->type==EX_VALUE && func->opval.val->sym->undefined) */
+ /* return 1; *//* Already gave them an undefined function error */
werror (E_TOO_MANY_PARMS);
return 1;
}
return 1;
}
- if (IS_VOID(actParm->ftype)) {
- werror (E_VOID_VALUE_USED);
- return 1;
- }
+ /* if this is a PARAM node then match left & right */
+ if (actParm->type == EX_OP && actParm->opval.op == PARAM)
+ {
+ actParm->decorated = 1;
+ return (processParms (func, defParm,
+ actParm->left, parmNumber, FALSE) ||
+ processParms (func, defParm ? defParm->next : NULL,
+ actParm->right, parmNumber, rightmost));
+ }
+ else if (defParm) /* not vararg */
+ {
+ /* If we have found a value node by following only right-hand links,
+ * then we know that there are no more values after us.
+ *
+ * Therefore, if there are more defined parameters, the caller didn't
+ * supply enough.
+ */
+ if (rightmost && defParm->next)
+ {
+ werror (E_TOO_FEW_PARMS);
+ return 1;
+ }
+ }
+
+ /* decorate parameter */
+ resultType = defParm ? getResultTypeFromType (defParm->etype) :
+ RESULT_TYPE_NONE;
+ actParm = decorateType (actParm, resultType);
+
+ if (IS_VOID(actParm->ftype))
+ {
+ werror (E_VOID_VALUE_USED);
+ return 1;
+ }
/* If this is a varargs function... */
if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
}
ftype = actParm->ftype;
-
- /* If it's a small integer, upcast to int. */
+
+ /* If it's a char, upcast to int. */
if (IS_INTEGRAL (ftype)
&& (getSize (ftype) < (unsigned) INTSIZE))
{
- if (IS_AST_OP(actParm) &&
- (actParm->opval.op == LEFT_OP ||
- actParm->opval.op == '*' ||
- actParm->opval.op == '+' ||
- actParm->opval.op == '-') &&
- actParm->right) {
- // we should cast an operand instead of the result
- actParm->decorated = 0;
- actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
- actParm->left);
- actParm = decorateType(actParm, RESULT_CHECK);
- } else {
- newType = newAst_LINK(INTTYPE);
- }
+ newType = newAst_LINK(INTTYPE);
}
if (IS_PTR(ftype) && !IS_GENPTR(ftype))
newType = newAst_LINK (copyLinkChain (ftype));
DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
}
+
if (newType)
{
/* cast required; change this op to a cast. */
- ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
+ ast *parmCopy = resolveSymbols (copyAst (actParm));
actParm->type = EX_OP;
actParm->opval.op = CAST;
actParm->left = newType;
actParm->right = parmCopy;
- decorateType (actParm, RESULT_CHECK);
- }
- else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
- {
- return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
- processParms (func, NULL, actParm->right, parmNumber, rightmost));
+ actParm->decorated = 0; /* force typechecking */
+ decorateType (actParm, RESULT_TYPE_NONE);
}
return 0;
- }
+ } /* vararg */
/* if defined parameters ended but actual has not & */
/* reentrant */
return 0;
resolveSymbols (actParm);
- /* if this is a PARAM node then match left & right */
- if (actParm->type == EX_OP && actParm->opval.op == PARAM)
- {
- return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
- processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
- }
- else
+
+ /* the parameter type must be at least castable */
+ if (compareType (defParm->type, actParm->ftype) == 0)
{
- /* If we have found a value node by following only right-hand links,
- * then we know that there are no more values after us.
- *
- * Therefore, if there are more defined parameters, the caller didn't
- * supply enough.
- */
- if (rightmost && defParm->next)
- {
- werror (E_TOO_FEW_PARMS);
- return 1;
- }
+ werror (E_INCOMPAT_TYPES);
+ printFromToType (actParm->ftype, defParm->type);
+ return 1;
}
- /* the parameter type must be at least castable */
- if (compareType (defParm->type, actParm->ftype) == 0) {
- werror (E_INCOMPAT_TYPES);
- printFromToType (actParm->ftype, defParm->type);
- return 1;
- }
-
/* if the parameter is castable then add the cast */
if (compareType (defParm->type, actParm->ftype) < 0)
{
- ast *pTree = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
+ ast *pTree;
+ resultType = getResultTypeFromType (defParm->etype);
+ 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->etype = defParm->etype;
- actParm->ftype = defParm->type;
- actParm->decorated=0; /* force typechecking */
- decorateType (actParm, RESULT_CHECK);
+ actParm->decorated = 0; /* force typechecking */
+ decorateType (actParm, resultType);
}
/* make a copy and change the regparm type to the defined parm */
(*parmNumber)++;
return 0;
}
+
/*-----------------------------------------------------------------*/
/* createIvalType - generates ival for basic types */
/*-----------------------------------------------------------------*/
/* resolve the symbols in the ival */
if (sym->ival)
- resolveIvalSym (sym->ival);
+ resolveIvalSym (sym->ival, sym->type);
/* if this is a static variable & has an */
/* initial value the code needs to be lifted */
/*-----------------------------------------------------------------*/
/* getResultFromType */
/*-----------------------------------------------------------------*/
-static RESULT_TYPE
+RESULT_TYPE
getResultTypeFromType (sym_link *type)
{
/* type = getSpec (type); */
/*-----------------------------------------------------------------*/
/* addCast - adds casts to a type specified by RESULT_TYPE */
/*-----------------------------------------------------------------*/
-static void
-addCast (ast **tree, RESULT_TYPE resultType, bool upcast)
+static ast *
+addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
{
sym_link *newLink;
bool upCasted = FALSE;
case RESULT_TYPE_NONE:
/* char: promote to int */
if (!upcast ||
- getSize ((*tree)->etype) >= INTSIZE)
- return;
+ getSize (tree->etype) >= INTSIZE)
+ return tree;
newLink = newIntLink();
upCasted = TRUE;
break;
case RESULT_TYPE_CHAR:
- if (getSize ((*tree)->etype) <= 1)
- return;
+ if (getSize (tree->etype) <= 1)
+ return tree;
newLink = newCharLink();
break;
case RESULT_TYPE_INT:
#if 0
- if (getSize ((*tree)->etype) > INTSIZE)
+ if (getSize (tree->etype) > INTSIZE)
{
/* warn ("Loosing significant digits"); */
return;
#endif
/* char: promote to int */
if (!upcast ||
- getSize ((*tree)->etype) >= INTSIZE)
- return;
+ getSize (tree->etype) >= INTSIZE)
+ return tree;
newLink = newIntLink();
upCasted = TRUE;
break;
case RESULT_TYPE_OTHER:
if (!upcast)
- return;
+ return tree;
/* return type is long, float: promote char to int */
- if (getSize ((*tree)->etype) >= INTSIZE)
- return;
+ if (getSize (tree->etype) >= INTSIZE)
+ return tree;
newLink = newIntLink();
upCasted = TRUE;
break;
default:
- return;
+ return tree;
}
- (*tree)->decorated = 0;
- *tree = newNode (CAST, newAst_LINK (newLink), *tree);
+ tree->decorated = 0;
+ tree = newNode (CAST, newAst_LINK (newLink), tree);
/* keep unsigned type during cast to smaller type,
but not when promoting from char to int */
if (!upCasted)
- SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
- *tree = decorateType (*tree, resultType);
+ SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
+ return decorateType (tree, resultType);
}
/*-----------------------------------------------------------------*/
{
case '=':
case CAST:
- if (IS_PTR (tree->left->ftype))
+ if (IS_PTR (LTYPE (tree)))
return RESULT_TYPE_NONE;
else
- return getResultTypeFromType (tree->left->etype);
+ return getResultTypeFromType (LETYPE (tree));
case RETURN:
if (IS_PTR (currFunc->type->next))
return RESULT_TYPE_NONE;
else
return getResultTypeFromType (currFunc->type->next);
+ case '[':
+ if (!IS_ARRAY (LTYPE (tree)))
+ return resultType;
+ if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
+ return RESULT_TYPE_CHAR;
+ return resultType;
default:
return resultType;
}
/* Before decorating the left branch we've to decide in dependence
upon tree->opval.op, if resultType can be propagated */
- if (getenv ("SDCC_NEWTYPEFLOW"))
- resultTypeProp = resultTypePropagate (tree, resultType);
- else
- resultTypeProp = RESULT_TYPE_NONE; /* provide initialization */
+ resultTypeProp = resultTypePropagate (tree, resultType);
dtl = decorateType (tree->left, resultTypeProp);
+ /* if an array node, we may need to swap branches */
+ if (tree->opval.op == '[')
+ {
+ /* determine which is the array & which the index */
+ if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
+ IS_INTEGRAL (LTYPE (tree)))
+ {
+ ast *tempTree = tree->left;
+ tree->left = tree->right;
+ tree->right = tempTree;
+ }
+ }
+
/* After decorating the left branch there's type information available
in tree->left->?type. If the op is e.g. '=' we extract the type
information from there and propagate it to the right branch. */
- if (getenv ("SDCC_NEWTYPEFLOW"))
- resultTypeProp = getLeftResultType (tree, resultTypeProp);
+ resultTypeProp = getLeftResultType (tree, resultTypeProp);
- /* delay right side for '?' operator since conditional macro expansions
- might rely on this */
- dtr = tree->opval.op == '?' ? tree->right :
- decorateType (tree->right, resultTypeProp);
+ switch (tree->opval.op)
+ {
+ case '?':
+ /* delay right side for '?' operator since conditional macro
+ expansions might rely on this */
+ dtr = tree->right;
+ break;
+ case CALL:
+ /* decorate right side for CALL (parameter list) in processParms();
+ there is resultType available */
+ dtr = tree->right;
+ break;
+ default:
+ dtr = decorateType (tree->right, resultTypeProp);
+ break;
+ }
/* this is to take care of situations
when the tree gets rewritten */
tree->right = dtr;
if ((dtl && dtl->isError) || (dtr && dtr->isError))
return tree;
-
- if (!getenv ("SDCC_NEWTYPEFLOW"))
- {
- if (IS_AST_OP(tree) &&
- (tree->opval.op == CAST || tree->opval.op == '=') &&
- (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
- (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
- /* this is a cast/assign to a bigger type */
- if (IS_AST_OP(tree->right) &&
- IS_INTEGRAL(tree->right->ftype) &&
- (tree->right->opval.op == LEFT_OP ||
- tree->right->opval.op == '*' ||
- tree->right->opval.op == '+' ||
- tree->right->opval.op == '-') &&
- tree->right->right) {
- /* we should cast an operand instead of the result */
- tree->right->decorated = 0;
- tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
- tree->right->left);
- tree->right = decorateType(tree->right, RESULT_CHECK);
- }
- }
- }
}
/* depending on type of operator do */
/*----------------------------*/
case '[':
- /* determine which is the array & which the index */
- if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
- {
-
- ast *tempTree = tree->left;
- tree->left = tree->right;
- tree->right = tempTree;
- }
-
/* first check if this is a array or a pointer */
if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
{
werror (E_LVALUE_REQUIRED, "array access");
goto errorTreeReturn;
}
+
+ if (IS_LITERAL (RTYPE (tree)))
+ {
+ int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
+ int arraySize = DCL_ELEM (LTYPE (tree));
+ if (arraySize && arrayIndex >= arraySize)
+ {
+ werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
+ }
+ }
+
RRVAL (tree) = 1;
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
return tree;
return decorateType (otree, RESULT_CHECK);
}
- if (getenv ("SDCC_NEWTYPEFLOW"))
- {
- addCast (&tree->left, resultType, FALSE);
- addCast (&tree->right, resultType, FALSE);
- }
+ tree->left = addCast (tree->left, resultType, FALSE);
+ tree->right = addCast (tree->right, resultType, FALSE);
TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
TETYPE (tree) = getSpec (TTYPE (tree));
}
LRVAL (tree) = RRVAL (tree) = 1;
- if (getenv ("SDCC_NEWTYPEFLOW"))
- {
- addCast (&tree->left, resultType, FALSE);
- addCast (&tree->right, resultType, FALSE);
- }
+ tree->left = addCast (tree->left, resultType, FALSE);
+ tree->right = addCast (tree->right, resultType, FALSE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
}
LRVAL (tree) = RRVAL (tree) = 1;
- if (!getenv ("SDCC_NEWTYPEFLOW"))
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree),
- TRUE));
- else
- {
- addCast (&tree->left, resultType, FALSE);
- addCast (&tree->right, resultType, FALSE);
- TETYPE (tree) = getSpec (TTYPE (tree) =
+ tree->left = addCast (tree->left, resultType, FALSE);
+ tree->right = addCast (tree->right, resultType, FALSE);
+ TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
- }
return tree;
TETYPE (tree) = getSpec (TTYPE (tree) =
LTYPE (tree));
else
- if (!getenv ("SDCC_NEWTYPEFLOW"))
+ {
+ tree->left = addCast (tree->left, resultType, TRUE);
+ tree->right = addCast (tree->right, resultType, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree),
- FALSE));
- else
- {
- addCast (&tree->left, resultType, TRUE);
- addCast (&tree->right, resultType, TRUE);
- TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
- }
+ }
return tree;
TETYPE (tree) = getSpec (TTYPE (tree) =
LTYPE (tree));
else
- if (!getenv ("SDCC_NEWTYPEFLOW"))
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree),
- FALSE));
- else
- {
- addCast (&tree->left, resultType, TRUE);
- addCast (&tree->right, resultType, TRUE);
- TETYPE (tree) = getSpec (TTYPE (tree) =
+ {
+ 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));
- }
+ }
LRVAL (tree) = RRVAL (tree) = 1;
LRVAL (tree) = RRVAL (tree) = 1;
if (tree->opval.op == LEFT_OP)
{
- if (!getenv ("SDCC_NEWTYPEFLOW"))
- /* promote char to int */
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- LTYPE (tree), /* no, not RTYPE! */
- TRUE));
- else
- {
- addCast (&tree->left, resultType, TRUE);
- TETYPE (tree) = getSpec (TTYPE (tree) =
+ tree->left = addCast (tree->left, resultType, TRUE);
+ TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
- }
}
else /* RIGHT_OP */
{
AST_FOR (tree, loopExpr),
tree->left), RESULT_CHECK);
}
+ case PARAM:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "node PARAM shouldn't be processed here");
+ /* but in processParams() */
+ return tree;
default:
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;