* src/SDCC.y (labeled_statement): case and default no longer require
[fw/sdcc] / src / SDCCast.c
index 8e20910cf1c505dae56081cc9e485c210bbe0a52..5d7bdffc92c56f7a35f5a878bd9ef33d65105d9a 100644 (file)
@@ -22,6 +22,8 @@
    what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+#define DEBUG_CF(x) /* puts(x); */
+
 #include "common.h"
 
 int currLineno = 0;
@@ -1979,7 +1981,7 @@ searchLitOp (ast *tree, ast **parent, const char *ops)
           tree->right->right &&
           (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
        {
-         if (IS_LITERAL (RTYPE (tree->right)) ^
+         if (IS_LITERAL (RTYPE (tree->right)) !=
              IS_LITERAL (LTYPE (tree->right)))
            {
              tree->right->decorated = 0;
@@ -1996,7 +1998,7 @@ searchLitOp (ast *tree, ast **parent, const char *ops)
           tree->left->right &&
          (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
        {
-         if (IS_LITERAL (RTYPE (tree->left)) ^
+         if (IS_LITERAL (RTYPE (tree->left)) !=
              IS_LITERAL (LTYPE (tree->left)))
            {
              tree->left->decorated = 0;
@@ -2059,7 +2061,7 @@ addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
        upCasted = TRUE;
        break;
       case RESULT_TYPE_CHAR:
-       if (getSize (tree->etype) <= 1)
+       if (IS_CHAR (tree->etype))
          return tree;
        newLink = newCharLink();
        break;
@@ -2562,8 +2564,6 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              return decorateType (otree, RESULT_CHECK);
          }
 
-         tree->left  = addCast (tree->left,  resultType, FALSE);
-         tree->right = addCast (tree->right, resultType, FALSE);
          TTYPE (tree) = computeType (LTYPE (tree),
                                      RTYPE (tree),
                                      resultType,
@@ -2587,11 +2587,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              ast *litTree = searchLitOp (tree, &parent, "&");
              if (litTree)
                {
-                 ast *tTree = litTree->left;
+                 DEBUG_CF("&")
+                 ast *tTree = litTree->left;
                  litTree->left = tree->right;
                  tree->right = tTree;
                  /* both operands in tTree are literal now */
-                 decorateType (parent, RESULT_CHECK);
+                 decorateType (parent, resultType);
                }
            }
 
@@ -2714,11 +2715,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          ast *litTree = searchLitOp (tree, &parent, "|");
          if (litTree)
            {
+             DEBUG_CF("|")
              ast *tTree = litTree->left;
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in tTree are literal now */
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
         }
       /* fall through */
@@ -2771,17 +2773,16 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          ast *litTree = searchLitOp (tree, &parent, "^");
          if (litTree)
            {
+             DEBUG_CF("^")
              ast *tTree = litTree->left;
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in litTree are literal now */
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      tree->left  = addCast (tree->left,  resultType, FALSE);
-      tree->right = addCast (tree->right, resultType, FALSE);
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
@@ -2835,11 +2836,14 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              if (IS_LITERAL (RTYPE (litTree)))
                {
                  /* foo_div */
-                 litTree->right = newNode ('*', litTree->right, tree->right);
+                 DEBUG_CF("div r")
+                 litTree->right = newNode ('*',
+                                           litTree->right,
+                                           copyAst (tree->right));
                  litTree->right->lineno = tree->lineno;
 
                  tree->right->opval.val = constVal ("1");
-                 decorateType (parent, RESULT_CHECK);
+                 decorateType (parent, resultType);
                }
              else
                {
@@ -2847,7 +2851,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                     We can't call decorateType(parent, RESULT_CHECK), because
                     this would cause an infinit loop. */
                  parent->decorated = 1;
-                 decorateType (litTree, RESULT_CHECK);
+                 decorateType (litTree, resultType);
                }
            }
        }
@@ -2987,11 +2991,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          ast *litTree = searchLitOp (tree, &parent, "*");
          if (litTree)
            {
+             DEBUG_CF("mul")
              ast *tTree = litTree->left;
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in litTree are literal now */
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
         }
 
@@ -3066,6 +3071,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
        {
          tree->type = EX_VALUE;
+         tree->left  = addCast (tree->left,  resultType, TRUE);
+          tree->right = addCast (tree->right, resultType, TRUE);
          tree->opval.val = valPlus (valFromType (LETYPE (tree)),
                                     valFromType (RETYPE (tree)));
          tree->right = tree->left = NULL;
@@ -3097,6 +3104,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              if (litTree->opval.op == '+')
                {
                  /* foo_aa */
+                 DEBUG_CF("+ 1 AA")
                  ast *tTree = litTree->left;
                  litTree->left = tree->right;
                  tree->right = tree->left;
@@ -3106,6 +3114,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                {
                  if (IS_LITERAL (RTYPE (litTree)))
                    {
+                     DEBUG_CF("+ 2 ASR")
                      /* foo_asr */
                      ast *tTree = litTree->left;
                      litTree->left = tree->right;
@@ -3113,6 +3122,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                    }
                  else
                    {
+                     DEBUG_CF("+ 3 ASL")
                      /* foo_asl */
                      ast *tTree = litTree->right;
                      litTree->right = tree->right;
@@ -3121,7 +3131,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                      tree->opval.op = '-';
                    }
                }
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
        }
 
@@ -3207,6 +3217,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
        {
          tree->type = EX_VALUE;
+         tree->left  = addCast (tree->left,  resultType, TRUE);
+         tree->right = addCast (tree->right, resultType, TRUE);
          tree->opval.val = valMinus (valFromType (LETYPE (tree)),
                                      valFromType (RETYPE (tree)));
          tree->right = tree->left = NULL;
@@ -3240,6 +3252,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
        {
          tree->left  = addCast (tree->left,  resultType, TRUE);
          tree->right = addCast (tree->right, resultType, TRUE);
+
          TETYPE (tree) = getSpec (TTYPE (tree) =
                                     computeType (LTYPE (tree),
                                                  RTYPE (tree),
@@ -3263,30 +3276,39 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              if (litTree->opval.op == '+')
                {
                  /* foo_sa */
-                 litTree->right = newNode ('-', litTree->right, tree->right);
-                 litTree->right->lineno = tree->lineno;
-
-                 tree->right->opval.val = constVal ("0");
+                 DEBUG_CF("- 1 SA")
+                 ast *tTree = litTree->left;
+                 litTree->left = litTree->right;
+                 litTree->right = tree->right;
+                 tree->right = tTree;
+                 tree->opval.op = '+';
+                 litTree->opval.op = '-';
                }
              else if (litTree->opval.op == '-')
                {
                  if (IS_LITERAL (RTYPE (litTree)))
                    {
                      /* foo_ssr */
-                     litTree->right = newNode ('+', tree->right, litTree->right);
-                     litTree->right->lineno = tree->lineno;
-
-                     tree->right->opval.val = constVal ("0");
+                     DEBUG_CF("- 2 SSR")
+                     ast *tTree = litTree->left;
+                     litTree->left = tree->right;
+                     tree->right = litParent->left;
+                     litParent->left = tTree;
+                     litTree->opval.op = '+';
+                     
+                     tree->decorated = 0;
+                     decorateType (tree, resultType);
                    }
                  else
                    {
                      /* foo_ssl */
+                     DEBUG_CF("- 3 SSL")
                      ast *tTree = litTree->right;
                      litTree->right = tree->right;
                      tree->right = tTree;
                    }
                }
-             decorateType (litParent, RESULT_CHECK);
+             decorateType (litParent, resultType);
            }
        }
       return tree;
@@ -3371,6 +3393,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          goto errorTreeReturn;
        }
 
+      /* make smaller type only if it's a LEFT_OP */
+      if (tree->opval.op == LEFT_OP)
+        tree->left = addCast (tree->left, resultType, TRUE);
+      
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
@@ -3388,7 +3414,6 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       LRVAL (tree) = RRVAL (tree) = 1;
       if (tree->opval.op == LEFT_OP)
        {
-         tree->left = addCast (tree->left, resultType, TRUE);
          TETYPE (tree) = getSpec (TTYPE (tree) =
                                       computeType (LTYPE (tree),
                                                    NULL,
@@ -3612,7 +3637,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       /*----------------------------*/
     case AND_OP:
     case OR_OP:
-      /* each must me arithmetic type or be a pointer */
+      /* each must be arithmetic type or be a pointer */
       if (!IS_PTR (LTYPE (tree)) &&
          !IS_ARRAY (LTYPE (tree)) &&
          !IS_INTEGRAL (LTYPE (tree)))