* as/mcs51/asdata.c,
[fw/sdcc] / src / SDCCast.c
index 24c3eb1c9daa14ad523906f5a1df9aadd7597ad8..4b16e347aa386ead902d6e019fbe67b9b7608f09 100644 (file)
@@ -227,7 +227,6 @@ copyAst (ast * src)
   dest->level = src->level;
   dest->funcName = src->funcName;
   dest->reversed = src->reversed;
-  dest->actualArgument = src->actualArgument;
 
   if (src->ftype)
     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
@@ -838,9 +837,6 @@ processParms (ast *func,
         }
     }
 
-  /* mark the actual parameter */
-  (*actParm)->actualArgument = 1;
-
   /* decorate parameter */
   resultType = defParm ? getResultTypeFromType (defParm->type) :
                          RESULT_TYPE_NONE;
@@ -858,11 +854,12 @@ processParms (ast *func,
       ast *newType = NULL;
       sym_link *ftype;
 
-      int isCast = IS_CAST_OP (*actParm);
-      int isAstLitValue = (IS_AST_LIT_VALUE (*actParm));
-
-      if (IS_CAST_OP (*actParm)
-        || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
+      /* don't perform integer promotion of explicitly typecasted variable arguments
+       * if sdcc extensions are enabled */
+      if (options.std_sdcc && 
+        (IS_CAST_OP (*actParm) ||
+        (IS_AST_SYM_VALUE (*actParm) && AST_VALUES (*actParm, removedCast)) ||
+        (IS_AST_LIT_VALUE (*actParm) && AST_VALUES (*actParm, literalFromCast))))
         {
           /* Parameter was explicitly typecast; don't touch it. */
           return 0;
@@ -1802,8 +1799,8 @@ astHasDeref (ast * tree)
 }
 
 /*-----------------------------------------------------------------*/
-/* isConformingBody - the loop body has to conform to a set of rules */
-/* for the loop to be considered reversible read on for rules      */
+/* isConformingBody - the loop body has to conform to a set of     */
+/* rules for the loop to be considered reversible read on for rules*/
 /*-----------------------------------------------------------------*/
 bool
 isConformingBody (ast * pbody, symbol * sym, ast * body)
@@ -1812,14 +1809,13 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
   /* we are going to do a pre-order traversal of the
      tree && check for the following conditions. (essentially
      a set of very shallow tests )
-     a) the sym passed does not participate in
-     any arithmetic operation
+     a) the sym passed does not participate in any arithmetic operation
      b) There are no function calls
      c) all jumps are within the body
      d) address of loop control variable not taken
-     e) if an assignment has a pointer on the
-     left hand side make sure right does not have
-     loop control variable */
+     e) if an assignment has a pointer on the left hand side make sure
+        right does not have loop control variable
+  */
 
   /* if we reach the end or a leaf then true */
   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
@@ -1874,9 +1870,9 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
       /* if right is NULL then unary operation  */
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*  address of                */
-/*----------------------------*/
+      /*----------------------------*/
       if (!pbody->right)
         {
           if (IS_AST_SYM_VALUE (pbody->left) &&
@@ -1976,7 +1972,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       if (astHasVolatile (pbody->left))
         return FALSE;
 
-      if (astHasDeref(pbody->right)) return FALSE;
+      if (astHasDeref(pbody->right))
+        return FALSE;
 
       return isConformingBody (pbody->left, sym, body) &&
         isConformingBody (pbody->right, sym, body);
@@ -1993,27 +1990,31 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       assert ("Parser should not have generated this\n");
 
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*      comma operator        */
-/*----------------------------*/
+      /*----------------------------*/
     case ',':
       return isConformingBody (pbody->left, sym, body) &&
         isConformingBody (pbody->right, sym, body);
 
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*       function call        */
-/*----------------------------*/
+      /*----------------------------*/
     case CALL:
-        /* if local & not passed as paramater then ok */
-        if (sym->level && !astHasSymbol(pbody->right,sym))
+        /* if local & not passed as parameter &
+           not used to find the function then ok */
+        if (sym->level && !astHasSymbol (pbody->right, sym) &&
+            !astHasSymbol (pbody->left, sym))
+          {
             return TRUE;
+          }
       return FALSE;
 
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*     return statement       */
-/*----------------------------*/
+      /*----------------------------*/
     case RETURN:
       return FALSE;
 
@@ -2032,9 +2033,6 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
   return isConformingBody (pbody->left, sym, body) &&
     isConformingBody (pbody->right, sym, body);
-
-
-
 }
 
 /*-----------------------------------------------------------------*/
@@ -2489,10 +2487,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
   /* just get the type        */
   if (tree->type == EX_VALUE)
     {
-
       if (IS_LITERAL (tree->opval.val->etype))
         {
-
           /* if this is a character array then declare it */
           if (IS_ARRAY (tree->opval.val->type))
             tree->opval.val = stringToSymbol (tree->opval.val);
@@ -3842,11 +3838,13 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       checkTypeSanity(LETYPE(tree), "(cast)");
 
 
-      /* if not an actual argument and
-       * if 'from' and 'to' are the same remove the superfluous cast,
+      /* if 'from' and 'to' are the same remove the superfluous cast,
        * this helps other optimizations */
-      if (!tree->actualArgument && compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
+      if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
         {
+          /* mark that the explicit cast has been removed,
+           * for proper processing (no integer promotion) of explicitly typecasted variable arguments */
+          tree->right->values.removedCast = 1;
           return tree->right;
         }
 
@@ -6288,19 +6286,13 @@ expandInlineFuncs (ast * tree, ast * block)
           /* during the function call. For example, a function         */
           /* declared as func(int x, int y) but called as func(y,x).   */
           /* { //inlinetree block                                      */
-          /*   type1 temparg1;                                         */
-          /*   ...                                                     */
-          /*   typen tempargn;                                         */
-          /*   temparg1 = argument1;                                   */
+          /*   type1 temparg1 = argument1;                             */
           /*   ...                                                     */
-          /*   tempargn = argumentn;                                   */
+          /*   typen tempargn = argumentn;                             */
           /*   { //inlinetree2 block                                   */
-          /*     type1 param1;                                         */
+          /*     type1 param1 = temparg1;                              */
           /*     ...                                                   */
-          /*     typen paramn;                                         */
-          /*     param1 = temparg1;                                    */
-          /*     ...                                                   */
-          /*     paramn = tempargn;                                    */
+          /*     typen paramn = tempargn;                              */
           /*     inline_function_code;                                 */
           /*     retlab:                                               */
           /*   }                                                       */
@@ -6326,6 +6318,7 @@ expandInlineFuncs (ast * tree, ast * block)
               assigntree = newNode ('=',
                                     newAst_VALUE (symbolVal (temparg)),
                                     passedarg);
+              assigntree->initMode=1; // tell that assignment is initializer
               inlinetree->right = newNode (NULLOP,
                                            assigntree,
                                            inlinetree->right);
@@ -6337,11 +6330,11 @@ expandInlineFuncs (ast * tree, ast * block)
               assigntree = newNode ('=',
                                     newAst_VALUE (symbolVal (parm)),
                                     newAst_VALUE (symbolVal (temparg)));
+              assigntree->initMode=1; // tell that assignment is initializer
               inlinetree2->right = newNode (NULLOP,
                                            assigntree,
                                            inlinetree2->right);
 
-
               args = args->next;
               argIndex++;
             }
@@ -6381,7 +6374,6 @@ expandInlineFuncs (ast * tree, ast * block)
           fixupInline (inlinetree, inlinetree->level);
           inlineState.count++;
         }
-
     }
 
   /* Recursively continue to search for functions to inline. */