* src/pic16/gen.c (genNearPointerSet): fixed handling of literals
[fw/sdcc] / src / SDCCast.c
index d29c998c84d66d2fbcdfa578edeadf8ea11a24c6..f1847f2ffb7d8bd8d34c4d2b4adb0d356318b5da 100644 (file)
@@ -2189,8 +2189,7 @@ getResultTypeFromType (sym_link *type)
     }
   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;
 }
@@ -2281,6 +2280,7 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType)
     {
       case AND_OP:
       case OR_OP:
+      case '!':
         return resultType;
       case '=':
       case '?':
@@ -2570,6 +2570,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              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;
@@ -3640,8 +3646,13 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       /* 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;
@@ -4126,7 +4137,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           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) */
@@ -4148,7 +4159,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       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;
@@ -4203,7 +4214,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      TTYPE (tree) = TETYPE (tree) = newBoolLink ();
+      TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
 
       /* condition transformations */
       {
@@ -4258,6 +4269,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       /* 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);
@@ -4267,6 +4279,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       tree->right = tree->left = NULL;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                                tree->opval.val->type);
+
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -4355,6 +4368,35 @@ decorateType (ast * tree, RESULT_TYPE resultType)
     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)))
@@ -5750,8 +5792,8 @@ optimizeCompare (ast * root)
             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)) &&
@@ -5947,6 +5989,10 @@ fixupInline (ast * tree, int level)
       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);
@@ -6016,6 +6062,9 @@ fixupInline (ast * tree, int level)
 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);
@@ -6102,6 +6151,32 @@ inlineFindParm (ast * parms, int index)
   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  */
@@ -6280,6 +6355,7 @@ createFunction (symbol * name, ast * body)
   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);
@@ -6336,7 +6412,10 @@ createFunction (symbol * name, ast * body)
     reentrant++;
 
   inlineState.count = 0;
+  savedBlockno = currBlockno;
+  currBlockno = inlineFindMaxBlockno (body, 0);
   expandInlineFuncs (body, NULL);
+  currBlockno = savedBlockno;
 
   if (FUNC_ISINLINE (name->type))
     name->funcTree = copyAst (body);
@@ -6371,16 +6450,21 @@ createFunction (symbol * name, ast * 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;
@@ -6389,10 +6473,7 @@ createFunction (symbol * name, ast * body)
   name->generated = 1;
 
   if (fatalError)
-    {
-      werror (E_FUNC_NO_CODE, name->name);
-      goto skipall;
-    }
+    goto skipall;
 
   eBBlockFromiCode (piCode);