int noLineno = 0;
int noAlloc = 0 ;
symbol *currFunc ;
-ast *createIval (ast *, link *, initList *, ast *);
-ast *createIvalCharPtr (ast *, link *, ast *);
+ast *createIval (ast *, sym_link *, initList *, ast *);
+ast *createIvalCharPtr (ast *, sym_link *, ast *);
ast *optimizeRRCRLC ( ast * );
ast *optimizeGetHbit(ast *);
ast *backPatchLabels (ast *,symbol *,symbol *);
ex->opval.op = (long) op ;
break ;
case EX_LINK :
- ex->opval.lnk = (link *) op;
+ ex->opval.lnk = (sym_link *) op;
break ;
case EX_STMNT :
ex->opval.stmnt= (unsigned) op;
return ex;
}
-ast* newAst_LINK(link*val)
+ast* newAst_LINK(sym_link*val)
{
ast* ex = newAst_(EX_LINK);
ex->opval.lnk = val;
/*-----------------------------------------------------------------*/
/* funcOfType :- function of type with name */
/*-----------------------------------------------------------------*/
-symbol *funcOfType (char *name, link *type, link *argType,
+symbol *funcOfType (char *name, sym_link *type, sym_link *argType,
int nArgs , int rent)
{
symbol *sym;
ast *actParm,
int *parmNumber)
{
- link *fetype = func->etype;
+ sym_link *fetype = func->etype;
/* if none of them exist */
if ( !defParm && !actParm)
return 1;
}
+ /* If this is a varagrs function... */
+ if (!defParm && actParm && func->hasVargs )
+ {
+ ast *newType = NULL;
+
+ if (IS_CAST_OP(actParm)
+ || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast))
+ {
+ /* Parameter was explicitly typecast; don't touch it. */
+ return 0;
+ }
+
+ /* If it's a small integer, upcast to int. */
+ if (IS_INTEGRAL(actParm->ftype)
+ && getSize(actParm->ftype) < INTSIZE)
+ {
+ newType = newAst_LINK(INTTYPE);
+ }
+
+ if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype))
+ {
+ newType = newAst_LINK(copyLinkChain(actParm->ftype));
+ DCL_TYPE(newType->opval.lnk) = GPOINTER;
+ }
+
+ 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;
+ decorateType(actParm);
+ }
+
+ return 0;
+ }
+
/* if defined parameters ended but actual has not & */
- /* has a variable argument list or statckAuto */
+ /* stackAuto */
if (! defParm && actParm &&
- (func->hasVargs || options.stackAuto || IS_RENT(fetype)))
+ (options.stackAuto || IS_RENT(fetype)))
return 0;
resolveSymbols(actParm);
/*-----------------------------------------------------------------*/
/* createIvalType - generates ival for basic types */
/*-----------------------------------------------------------------*/
-ast *createIvalType ( ast *sym,link *type, initList *ilist)
+ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
{
ast *iExpr;
/*-----------------------------------------------------------------*/
/* createIvalStruct - generates initial value for structures */
/*-----------------------------------------------------------------*/
-ast *createIvalStruct (ast *sym,link *type,initList *ilist)
+ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
{
ast *rast = NULL ;
symbol *sflds ;
/*-----------------------------------------------------------------*/
/* createIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
-ast *createIvalArray (ast *sym, link *type, initList *ilist)
+ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
{
ast *rast = NULL;
initList *iloop ;
/*-----------------------------------------------------------------*/
/* createIvalCharPtr - generates initial values for char pointers */
/*-----------------------------------------------------------------*/
-ast *createIvalCharPtr (ast *sym, link *type, ast *iexpr)
+ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
{
ast *rast = NULL ;
/*-----------------------------------------------------------------*/
/* createIvalPtr - generates initial value for pointers */
/*-----------------------------------------------------------------*/
-ast *createIvalPtr (ast *sym,link *type,initList *ilist)
+ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
{
ast *rast;
ast *iexpr ;
/*-----------------------------------------------------------------*/
/* createIval - generates code for initial value */
/*-----------------------------------------------------------------*/
-ast *createIval (ast *sym, link *type, initList *ilist, ast *wid)
+ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
{
ast *rast = NULL;
forbody
<sym> -= 1;
if (sym) goto for_continue ;
- <sym> = end - 1; */
+ <sym> = end */
/* put it together piece by piece */
rloop = newNode (NULLOP,
NULL),NULL),
newNode('=',
newAst_VALUE(symbolVal(sym)),
- newNode('-', end,
- newAst_VALUE(constVal("1")))));
+ end));
replLoopSym(loop->left, sym);
}
+#define DEMAND_INTEGER_PROMOTION
+
+#ifdef DEMAND_INTEGER_PROMOTION
+
+/*-----------------------------------------------------------------*/
+/* walk a tree looking for the leaves. Add a typecast to the given */
+/* type to each value leaf node. */
+/*-----------------------------------------------------------------*/
+void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
+{
+ if (!node)
+ {
+ /* WTF? We should never get here. */
+ return;
+ }
+
+ if (!node->left && !node->right)
+ {
+ /* We're at a leaf; if it's a value, apply the typecast */
+ if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
+ {
+ *parentPtr = decorateType(newNode(CAST,
+ newAst_LINK(copyLinkChain(type)),
+ node));
+ }
+ }
+ else
+ {
+ if (node->left)
+ {
+ pushTypeCastToLeaves(type, node->left, &(node->left));
+ }
+ if (node->right)
+ {
+ pushTypeCastToLeaves(type, node->right, &(node->right));
+ }
+ }
+}
+
+#endif
+
+/*-----------------------------------------------------------------*/
+/* Given an assignment operation in a tree, determine if the LHS */
+/* (the result) has a different (integer) type than the RHS. */
+/* If so, walk the RHS and add a typecast to the type of the LHS */
+/* to all leaf nodes. */
+/*-----------------------------------------------------------------*/
+void propAsgType(ast *tree)
+{
+#ifdef DEMAND_INTEGER_PROMOTION
+ if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
+ {
+ /* Nothing to do here... */
+ return;
+ }
+
+ if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
+ {
+ pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
+ }
+#else
+ (void)tree;
+#endif
+}
+
/*-----------------------------------------------------------------*/
/* decorateType - compute type for this tree also does type cheking*/
/* this is done bottom up, since type have to flow upwards*/
ast *decorateType (ast *tree)
{
int parmNumber ;
- link *p;
+ sym_link *p;
if ( ! tree )
return tree ;
case INC_OP: /* incerement operator unary so left only */
case DEC_OP:
{
- link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
+ sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
werror(E_CODE_WRITE,"++/--");
tree->left = NULL;
tree->right = NULL;
TTYPE(tree) = tree->opval.val->type;
+ tree->values.literalFromCast = 1;
}
else {
TTYPE(tree) = LTYPE(tree);
goto errorTreeReturn ;
}
LLVAL(tree) = 1;
+
+ propAsgType(tree);
+
return tree ;
case AND_ASSIGN:
goto errorTreeReturn ;
}
LLVAL(tree) = 1;
+
+ propAsgType(tree);
+
return tree ;
/*------------------------------------------------------------------*/
goto errorTreeReturn ;
}
LLVAL(tree) = 1;
+
+ propAsgType(tree);
+
return tree;
/*------------------------------------------------------------------*/
tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
tree->opval.op = '=';
+
+ propAsgType(tree);
+
return tree;
/*------------------------------------------------------------------*/
goto errorTreeReturn ;
}
+ propAsgType(tree);
+
return tree ;
/*------------------------------------------------------------------*/
}
/* if there is going to be a casing required then add it */
- if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
- tree->right =
+ if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
+ {
+#ifdef DEMAND_INTEGER_PROMOTION
+ if (IS_INTEGRAL(currFunc->type->next))
+ {
+ pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
+ }
+ else
+#endif
+ {
+ tree->right =
decorateType(newNode(CAST,
newAst_LINK(copyLinkChain(currFunc->type->next)),
tree->right));
+ }
}
RRVAL(tree) = 1;
/*-----------------------------------------------------------------*/
/* sizeofOp - processes size of operation */
/*-----------------------------------------------------------------*/
-value *sizeofOp( link *type)
+value *sizeofOp( sym_link *type)
{
char buff[10];
ast *ex ;
symbol *csym;
int stack = 0 ;
- link *fetype;
+ sym_link *fetype;
iCode *piCode = NULL;
/* if check function return 0 then some problem */