}
if (IS_CHAR (type))
return RESULT_TYPE_CHAR;
- if ( IS_INT (type)
- && !IS_LONG (type))
+ if (IS_INT (type) && !IS_LONG (type))
return RESULT_TYPE_INT;
return RESULT_TYPE_OTHER;
}
{
case AND_OP:
case OR_OP:
+ case '!':
return resultType;
case '=':
case '?':
there is resultType available */
dtr = tree->right;
break;
+ case SIZEOF:
+ /* don't allocate string if it is a sizeof argument */
+ ++noAlloc;
+ dtr = decorateType (tree->right, resultTypeProp);
+ --noAlloc;
+ break;
default:
dtr = decorateType (tree->right, resultTypeProp);
break;
}
/* if left is another '!' */
- if (tree->left->opval.op == '!')
+ if (IS_AST_NOT_OPER (tree->left))
{
+ if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
+ {
+ /* remove double '!!X' by 'X' */
+ return tree->left->left;
+ }
/* remove double '!!X' by 'X ? 1 : 0' */
tree->opval.op = '?';
tree->left = tree->left->left;
IS_LITERAL(RTYPE(tree)) &&
((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
{
- if (resultType == RESULT_TYPE_IFX)
+ if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
{
/* the parent is an ifx: */
/* if (unsigned value) */
if (IS_LITERAL(RTYPE(tree)) &&
floatFromVal (valFromType (RETYPE (tree))) == 0 &&
tree->opval.op == EQ_OP &&
- resultType == RESULT_TYPE_IFX)
+ (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
{
tree->opval.op = '!';
tree->right = NULL;
}
LRVAL (tree) = RRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newBoolLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
/* condition transformations */
{
/* change the type to a integer */
{
int size = getSize (tree->right->ftype);
+
SNPRINTF(buffer, sizeof(buffer), "%d", size);
if (!size && !IS_VOID(tree->right->ftype))
werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
tree->right = tree->left = NULL;
TETYPE (tree) = getSpec (TTYPE (tree) =
tree->opval.val->type);
+
return tree;
/*------------------------------------------------------------------*/
case '?':
/* the type is value of the colon operator (on the right) */
assert (IS_COLON_OP (tree->right));
+
+ if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right))
+ {
+ double valTrue = AST_LIT_VALUE (tree->right->left);
+ double valFalse = AST_LIT_VALUE (tree->right->right);
+
+ if ((valTrue == 1) && (valFalse == 0) &&
+ ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)))
+ {
+ /* assign cond to result */
+ return decorateType (tree->left, resultTypeProp);
+ }
+ else if ((valTrue == 0) && (valFalse == 1))
+ {
+ /* assign !cond to result */
+ tree->opval.op = '!';
+ tree->decorated = 0;
+ tree->right = NULL;
+ return decorateType (tree, resultTypeProp);
+ }
+ }
+
+ /* if they are equal then replace the tree */
+ if (!astHasVolatile (tree->right) &&
+ isAstEqual (tree->right->left, tree->right->right))
+ {
+ return decorateType (tree->right->left, resultTypeProp);
+ }
+
/* if already known then replace the tree : optimizer will do it
but faster to do it here */
if (IS_LITERAL (LTYPE (tree)))
root->right->opval.val : NULL);
/* if left is a BITVAR in BITSPACE */
- /* and right is a LITERAL then opt- */
- /* imize else do nothing */
+ /* and right is a LITERAL then */
+ /* optimize else do nothing */
if (vleft && vright &&
IS_BITVAR (vleft->etype) &&
IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
sym->level = level;
sym->block = currBlockno;
+ sym->reqv = NULL;
+ SYM_SPIL_LOC (sym) = NULL;
+ sym->key = 0;
+
/* If the symbol is a label, we need to renumber it */
if (sym->islbl)
fixupInlineLabel (sym);
static void
inlineAddDecl (symbol * sym, ast * block, int addSymTab)
{
+ sym->reqv = NULL;
+ SYM_SPIL_LOC (sym) = NULL;
+ sym->key = 0;
if (block != NULL)
{
symbol **decl = &(block->values.sym);
return inlineFindParmRecurse (parms, &index);
}
+/*-----------------------------------------------------------------*/
+/* inlineFindMaxBlockno - find maximum block number in an ast tree */
+/*-----------------------------------------------------------------*/
+static int
+inlineFindMaxBlockno (ast * tree, int maxBlockno)
+{
+ int tempBlockno;
+
+ if (!tree)
+ return maxBlockno;
+
+ tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno);
+ if (tempBlockno > maxBlockno)
+ maxBlockno = tempBlockno;
+
+ tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno);
+ if (tempBlockno > maxBlockno)
+ maxBlockno = tempBlockno;
+
+ if (tree->block > maxBlockno)
+ maxBlockno = tree->block;
+ return maxBlockno;
+}
+
+
+
/*-----------------------------------------------------------------*/
/* expandInlineFuncs - replace calls to inline functions with the */
int stack = 0;
sym_link *fetype;
iCode *piCode = NULL;
+ int savedBlockno;
if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
reentrant++;
inlineState.count = 0;
+ savedBlockno = currBlockno;
+ currBlockno = inlineFindMaxBlockno (body, 0);
expandInlineFuncs (body, NULL);
+ currBlockno = savedBlockno;
if (FUNC_ISINLINE (name->type))
name->funcTree = copyAst (body);
ex = newNode (FUNCTION, ex, body);
ex->values.args = FUNC_ARGS(name->type);
ex->decorated=1;
- if (options.dump_tree) PA(ex);
+ if (options.dump_tree)
+ PA(ex);
if (fatalError)
- {
- werror (E_FUNC_NO_CODE, name->name);
- goto skipall;
- }
+ goto skipall;
- /* Do not generate code for inline functions unless extern also */
+ /* Do not generate code for inline functions unless extern also. */
+#if 0
if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
goto skipall;
+#else
+ /* Temporary hack: always generate code for static inline functions. */
+ /* Ideally static inline functions should only be generated if needed. */
+ if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype))
+ goto skipall;
+#endif
/* create the node & generate intermediate code */
GcurMemmap = code;
name->generated = 1;
if (fatalError)
- {
- werror (E_FUNC_NO_CODE, name->name);
- goto skipall;
- }
+ goto skipall;
eBBlockFromiCode (piCode);