actParm->decorated = 0;
actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
actParm->left);
- actParm = decorateType(actParm);
+ actParm = decorateType(actParm, RESULT_CHECK);
} else {
newType = newAst_LINK(INTTYPE);
}
if (newType)
{
/* cast required; change this op to a cast. */
- ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
+ ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
actParm->type = EX_OP;
actParm->opval.op = CAST;
actParm->left = newType;
actParm->right = parmCopy;
- decorateType (actParm);
+ decorateType (actParm, RESULT_CHECK);
}
else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
{
/* if the parameter is castable then add the cast */
if (compareType (defParm->type, actParm->ftype) < 0)
{
- ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
+ ast *pTree = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
/* now change the current one to a cast */
actParm->type = EX_OP;
actParm->etype = defParm->etype;
actParm->ftype = defParm->type;
actParm->decorated=0; /* force typechecking */
- decorateType (actParm);
+ decorateType (actParm, RESULT_CHECK);
}
/* make a copy and change the regparm type to the defined parm */
if (ilist->type == INIT_DEEP)
ilist = ilist->init.deep;
- iExpr = decorateType (resolveSymbols (list2expr (ilist)));
- return decorateType (newNode ('=', sym, iExpr));
+ iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
+ return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
}
/*-----------------------------------------------------------------*/
break;
sflds->implicit = 1;
lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
- lAst = decorateType (resolveSymbols (lAst));
- rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
+ lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
+ rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
}
if (iloop) {
if (IS_CHAR (type->next))
if ((rast = createIvalCharPtr (sym,
type,
- decorateType (resolveSymbols (list2expr (ilist))))))
+ decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
- return decorateType (resolveSymbols (rast));
+ return decorateType (resolveSymbols (rast), RESULT_CHECK);
/* not the special case */
if (ilist->type != INIT_DEEP)
{
ast *aSym;
- aSym = decorateType (resolveSymbols(sym));
+ aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
rast = newNode(ARRAYINIT, aSym, NULL);
rast->values.constlist = literalL;
ast *aSym;
aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
- aSym = decorateType (resolveSymbols (aSym));
+ aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
rast = createIval (aSym, type->next, iloop, rast);
iloop = (iloop ? iloop->next : NULL);
if (!iloop)
DCL_ELEM (type) = size;
}
- return decorateType (resolveSymbols (rast));
+ return decorateType (resolveSymbols (rast), RESULT_CHECK);
}
// now WE don't need iexpr's symbol anymore
freeStringSymbol(AST_SYMBOL(iexpr));
- return decorateType (resolveSymbols (rast));
+ return decorateType (resolveSymbols (rast), RESULT_CHECK);
}
return NULL;
if (ilist->type == INIT_DEEP)
ilist = ilist->init.deep;
- iexpr = decorateType (resolveSymbols (list2expr (ilist)));
+ iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
/* if character pointer */
if (IS_CHAR (type->next))
rast = createIvalType (sym, type, ilist);
if (wid)
- return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
+ return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
else
- return decorateType (resolveSymbols (rast));
+ return decorateType (resolveSymbols (rast), RESULT_CHECK);
}
/*-----------------------------------------------------------------*/
return TRUE;
}
- cexpr = decorateType (resolveSymbols (cexpr));
+ cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
switch (cexpr->type)
{
value *
constExprValue (ast * cexpr, int check)
{
- cexpr = decorateType (resolveSymbols (cexpr));
+ cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
/* if this is not a constant then */
if (!IS_LITERAL (cexpr->ftype))
rloop))));
rloop->lineno=init->lineno;
- return decorateType (rloop);
+ return decorateType (rloop, RESULT_CHECK);
}
}
/*-----------------------------------------------------------------*/
-/* decorateType - compute type for this tree also does type checking */
-/* this is done bottom up, since type have to flow upwards */
-/* it also does constant folding, and paramater checking */
+/* getResultFromType */
/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+getResultTypeFromType (sym_link *type)
+{
+ /* type = getSpec (type); */
+ if (IS_BITVAR (type))
+ return RESULT_TYPE_BIT;
+ if (IS_BITFIELD (type))
+ return RESULT_TYPE_CHAR;
+ if (IS_CHAR (type))
+ return RESULT_TYPE_CHAR;
+ if ( IS_INT (type)
+ && !IS_LONG (type))
+ return RESULT_TYPE_INT;
+ return RESULT_TYPE_OTHER;
+}
+
+/*-----------------------------------------------------------------*/
+/* addCast - adds casts to a type specified by RESULT_TYPE */
+/*-----------------------------------------------------------------*/
+static void
+addCast (ast **tree, RESULT_TYPE resultType)
+{
+ sym_link *newLink;
+
+ switch (resultType)
+ {
+ case RESULT_TYPE_CHAR:
+ if (getSize ((*tree)->etype) <= 1)
+ return;
+ newLink = newCharLink();
+ break;
+ case RESULT_TYPE_INT:
+#if 0
+ /* casting from long to int costs additional 4 bytes dram! */
+ if (getSize ((*tree)->etype) <= INTSIZE)
+ return;
+ newLink = newIntLink();
+ break;
+#else
+ /* warn ("Loosing significant digits"); */
+ return;
+#endif
+ default:
+ return;
+ }
+ (*tree)->decorated = 0;
+ *tree = newNode (CAST, newAst_LINK (newLink), *tree);
+ /* keep unsigned type */
+ SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
+ *tree = decorateType (*tree, resultType);
+}
+
+/*-----------------------------------------------------------------*/
+/* resultTypePropagate - decides if resultType can be propagated */
+/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+resultTypePropagate (ast *tree, RESULT_TYPE resultType)
+{
+ switch (tree->opval.op)
+ {
+ case '=':
+ case '?':
+ case ':':
+ case '|':
+ case '^':
+ return resultType;
+ case '&':
+ if (!tree->right)
+ /* can be unary */
+ return RESULT_TYPE_NONE;
+ else
+ return resultType;
+ default:
+ return RESULT_TYPE_NONE;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* getLeftResultType - gets type from left branch for propagation */
+/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+getLeftResultType (ast *tree, RESULT_TYPE resultType)
+{
+ switch (tree->opval.op)
+ {
+ case '=':
+ case CAST:
+ if (IS_PTR (tree->left->ftype))
+ return RESULT_TYPE_NONE;
+ else
+ return getResultTypeFromType (tree->left->etype);
+ case RETURN:
+ if (IS_PTR (currFunc->type->next))
+ return RESULT_TYPE_NONE;
+ else
+ return getResultTypeFromType (currFunc->type->next);
+ default:
+ return resultType;
+ }
+}
+
+/*--------------------------------------------------------------------*/
+/* decorateType - compute type for this tree, also does type checking.*/
+/* This is done bottom up, since type has to flow upwards. */
+/* resultType flows top-down and forces e.g. char-arithmetik, if the */
+/* result is a char and the operand(s) are int's. */
+/* It also does constant folding, and parameter checking. */
+/*--------------------------------------------------------------------*/
ast *
-decorateType (ast * tree)
+decorateType (ast * tree, RESULT_TYPE resultType)
{
int parmNumber;
sym_link *p;
+ RESULT_TYPE resultTypeProp;
if (!tree)
return tree;
/*------------------------------------------------------------------*/
/*----------------------------*/
- /* leaf has been reached */
+/* leaf has been reached */
/*----------------------------*/
lineno=tree->lineno;
/* if this is of type value */
}
}
#endif
+
+ /* 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 */
+
+ dtl = decorateType (tree->left, resultTypeProp);
+
+ /* 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);
- dtl = decorateType (tree->left);
- /* delay right side for '?' operator since conditional macro expansions might
- rely on this */
- dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
+ /* delay right side for '?' operator since conditional macro expansions
+ might rely on this */
+ dtr = tree->opval.op == '?' ? tree->right :
+ decorateType (tree->right, resultTypeProp);
/* this is to take care of situations
when the tree gets rewritten */
if ((dtl && dtl->isError) || (dtr && dtr->isError))
return tree;
- 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);
+ 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 */
ast *otree = optimizeGetHbit (tree);
if (otree != tree)
- return decorateType (otree);
+ return decorateType (otree, RESULT_CHECK);
}
- TTYPE (tree) =
- computeType (LTYPE (tree), RTYPE (tree), FALSE);
+ if (getenv ("SDCC_NEWTYPEFLOW"))
+ {
+ addCast (&tree->left, resultType);
+ addCast (&tree->right, resultType);
+ }
+ TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
TETYPE (tree) = getSpec (TTYPE (tree));
/* if left is a literal exchange left & right */
litTree->left = tree->right;
tree->right = tTree;
/* both operands in tTree are literal now */
- decorateType (parent);
+ decorateType (parent, RESULT_CHECK);
}
}
LRVAL (tree) = RRVAL (tree) = 1;
+
return tree;
}
{
ast *wtree = optimizeRRCRLC (tree);
if (wtree != tree)
- return decorateType (wtree);
+ return decorateType (wtree, RESULT_CHECK);
wtree = optimizeSWAP (tree);
if (wtree != tree)
- return decorateType (wtree);
+ return decorateType (wtree, RESULT_CHECK);
}
/* if left is a literal exchange left & right */
litTree->left = tree->right;
tree->right = tTree;
/* both operands in tTree are literal now */
- decorateType (parent);
+ decorateType (parent, RESULT_CHECK);
}
}
/* fall through */
litTree->left = tree->right;
tree->right = tTree;
/* both operands in litTree are literal now */
- decorateType (parent);
+ decorateType (parent, RESULT_CHECK);
}
}
LRVAL (tree) = RRVAL (tree) = 1;
+ if (getenv ("SDCC_NEWTYPEFLOW"))
+ {
+ addCast (&tree->left, resultType);
+ addCast (&tree->right, resultType);
+ }
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
- TRUE));
+ ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
/* if right is a literal and */
/* left is also a division by a literal then */
litTree->right->lineno = tree->lineno;
tree->right->opval.val = constVal ("1");
- decorateType (parent);
+ decorateType (parent, RESULT_CHECK);
}
else
{
/* litTree->left is literal: no gcse possible.
- We can't call decorateType(parent), because
+ We can't call decorateType(parent, RESULT_CHECK), because
this would cause an infinit loop. */
parent->decorated = 1;
- decorateType (litTree);
+ decorateType (litTree, RESULT_CHECK);
}
}
}
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
- TRUE));
+ ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
return tree;
/*------------------------------------------------------------------*/
litTree->left = tree->right;
tree->right = tTree;
/* both operands in litTree are literal now */
- decorateType (parent);
+ decorateType (parent, RESULT_CHECK);
}
}
LRVAL (tree) = RRVAL (tree) = 1;
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree),
- TRUE));
-
+ if (!getenv ("SDCC_NEWTYPEFLOW"))
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree),
+ TRUE));
+ else
+ {
+ addCast (&tree->left, resultType);
+ addCast (&tree->right, resultType);
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree),
+ resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+ }
+
return tree;
/*------------------------------------------------------------------*/
tree->opval.op = '-';
}
}
- decorateType (parent);
+ decorateType (parent, RESULT_CHECK);
}
}
TETYPE (tree) = getSpec (TTYPE (tree) =
LTYPE (tree));
else
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree),
- FALSE));
+ if (!getenv ("SDCC_NEWTYPEFLOW"))
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree),
+ FALSE));
+ else
+ {
+ addCast (&tree->left, resultType);
+ addCast (&tree->right, resultType);
+ 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
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree),
- FALSE));
+ if (!getenv ("SDCC_NEWTYPEFLOW"))
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree),
+ FALSE));
+ else
+ {
+ addCast (&tree->left, resultType);
+ addCast (&tree->right, resultType);
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree),
+ resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+ }
LRVAL (tree) = RRVAL (tree) = 1;
tree->right = tTree;
}
}
- decorateType (litParent);
+ decorateType (litParent, RESULT_CHECK);
}
}
return tree;
LRVAL (tree) = RRVAL (tree) = 1;
if (tree->opval.op == LEFT_OP)
{
- /* promote char to int */
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- LTYPE (tree), /* no, not RTYPE! */
- TRUE));
+ 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);
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree),
+ resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+ }
}
else /* RIGHT_OP */
{
}
/* if unsigned value < 0 then always false */
/* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
- if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
+ if (SPEC_USIGN(LETYPE(tree)) &&
+ !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
+ IS_LITERAL(RTYPE(tree)) &&
((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
{
if (tree->opval.op == '<')
tree->right); /* val 0 */
tree->right->lineno = tree->lineno;
tree->right->left->lineno = tree->lineno;
- decorateType (tree->right);
+ decorateType (tree->right, RESULT_CHECK);
}
}
/* if they are both literal then */
/*----------------------------*/
case '?':
/* the type is value of the colon operator (on the right) */
- assert(IS_COLON_OP(tree->right));
+ assert (IS_COLON_OP (tree->right));
/* if already known then replace the tree : optimizer will do it
but faster to do it here */
- if (IS_LITERAL (LTYPE(tree))) {
- if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
- return decorateType(tree->right->left) ;
- } else {
- return decorateType(tree->right->right) ;
- }
- } else {
- tree->right = decorateType(tree->right);
- TTYPE (tree) = RTYPE(tree);
+ if (IS_LITERAL (LTYPE (tree)))
+ {
+ if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
+ return decorateType (tree->right->left, resultTypeProp);
+ else
+ return decorateType (tree->right->right, resultTypeProp);
+ }
+ else
+ {
+ tree->right = decorateType (tree->right, resultTypeProp);
+ TTYPE (tree) = RTYPE (tree);
TETYPE (tree) = getSpec (TTYPE (tree));
- }
+ }
return tree;
case ':':
goto errorTreeReturn;
}
- tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
+ tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
tree->opval.op = '=';
return tree;
goto errorTreeReturn;
}
- /* if there is going to be a casing required then add it */
+ /* if there is going to be a casting required then add it */
if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
{
tree->right =
decorateType (newNode (CAST,
- newAst_LINK (copyLinkChain (currFunc->type->next)),
- tree->right));
+ newAst_LINK (copyLinkChain (currFunc->type->next)),
+ tree->right),
+ RESULT_CHECK);
}
RRVAL (tree) = 1;
/*----------------------------*/
case FOR:
- decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
- decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
- decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
+ decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
+ decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
+ decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
/* if the for loop is reversible then
reverse it otherwise do what we normally
AST_FOR (tree, initExpr),
AST_FOR (tree, condExpr),
AST_FOR (tree, loopExpr),
- tree->left));
+ tree->left), RESULT_CHECK);
}
default:
TTYPE (tree) = TETYPE (tree) = NULL;
return NULL;
}
- caseVal = decorateType (resolveSymbols (caseVal));
+ caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
/* if not a constant then error */
if (!IS_LITERAL (caseVal->ftype))
{
&& !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
return tree;
- return decorateType (newNode (GETHBIT, tree->left->left, NULL));
+ return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
}
break;
}
- return decorateType (optExpr);
+ return decorateType (optExpr, RESULT_CHECK);
}
vleft = (root->left->type == EX_VALUE ?
break;
}
}
- return decorateType (resolveSymbols (optExpr));
+ return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
} /* end-of-if of BITVAR */
noOptimize:
SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
body = resolveSymbols (body); /* resolve the symbols */
- body = decorateType (body); /* propagateType & do semantic checks */
+ body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
+
ex = newAst_VALUE (symbolVal (name)); /* create name */
ex = newNode (FUNCTION, ex, body);
{
GcurMemmap = statsg;
codeOutFile = statsg->oFile;
- eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
+ eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
staticAutos = NULL;
}
return FALSE;
}
- if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
+ if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_CHECK)))
{
return FALSE;
}
return;
if (ilist->type == INIT_NODE)
- ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
+ ilist->init.node = decorateType (resolveSymbols (ilist->init.node), RESULT_CHECK);
if (ilist->type == INIT_DEEP)
resolveIvalSym (ilist->init.deep);
!SPEC_USIGN(val->type) &&
!SPEC_LONG(val->type) &&
SPEC_CVAL(val->type).v_int >= -128 &&
- SPEC_CVAL(val->type).v_int <= 127)
+ SPEC_CVAL(val->type).v_int < 0)
{
SPEC_NOUN(val->type) = V_CHAR;
}
- /* this could be too aggressive:
- 'unsigned char' promotes to 'signed int', so that we can
+ /* 'unsigned char' promotes to 'signed int', so that we can
reduce it the other way */
if (IS_INT(val->type) &&
!SPEC_USIGN(val->type) &&
!SPEC_LONG(val->type) &&
- SPEC_CVAL(val->type).v_int >= 128 &&
+ SPEC_CVAL(val->type).v_int >= 0 &&
SPEC_CVAL(val->type).v_int <= 255)
{
the programer wants */
SPEC_NOUN (val->type) = V_INT;
}
- else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
-#if 0
- if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
- dval<=0xff) {
- SPEC_USIGN (val->type) = 1;
- } else {
- SPEC_NOUN (val->type) = V_INT;
- }
-#else
- /* this is quite agressive: 'unsigned char' will be promoted to 'signed int',
- so that the signedness of a char shouldn't matter */
+ else { /* store char's always as unsigned; this helps other optimizations */
SPEC_USIGN (val->type) = 1;
-#endif
}
if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
SPEC_LONG (val->type) = 1;
SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
rval->etype,
- FALSE));
+ TRUE));
if (IS_FLOAT (val->type))
SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
else if (SPEC_LONG (val->type))
/* create a new value */
val = newValue ();
- val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
- rval->type : lval->type);
+ val->type = computeType (lval->etype, rval->etype, FALSE);
val->etype = getSpec (val->type);
+ SPEC_SCLS (val->etype) = S_LITERAL;
switch (op)
{
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
- (unsigned long) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
+ (TYPE_UDWORD) floatFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
- (long) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
+ (TYPE_DWORD) floatFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
- (unsigned) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
+ (TYPE_UWORD) floatFromVal (rval);
else
- SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
}
break;
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
- (unsigned long) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
+ (TYPE_UDWORD) floatFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
- (long) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
+ (TYPE_DWORD) floatFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
- (unsigned) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
+ (TYPE_UWORD) floatFromVal (rval);
else
SPEC_CVAL (val->type).v_int =
- (int) floatFromVal (lval) | (int) floatFromVal (rval);
+ (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
}
break;
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
- (unsigned long) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
+ (TYPE_UDWORD) floatFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
- (long) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
+ (TYPE_DWORD) floatFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
- (unsigned) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
+ (TYPE_UWORD) floatFromVal (rval);
else
SPEC_CVAL (val->type).v_int =
- (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
+ (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
}
break;
}
-
+
return cheapestVal(val);
}
val->type = val->etype = newCharLink ();
val->type->class = SPECIFIER;
SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
- SPEC_USIGN (val->type) = 0;
+ SPEC_USIGN (val->type) = 1;
switch (op)
{