d: Move private functions out of ExprVisitor into local statics
authorIain Buclaw <ibuclaw@gdcproject.org>
Thu, 16 Jul 2020 12:02:24 +0000 (14:02 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Thu, 30 Jul 2020 16:00:35 +0000 (18:00 +0200)
None of these functions need access to the context pointer of the
visitor class, so have been made free standing.

gcc/d/ChangeLog:

* expr.cc (needs_postblit): Move out of ExprVisitor as a static
function.  Update all callers.
(needs_dtor): Likewise.
(lvalue_p): Likewise.
(binary_op): Likewise.
(binop_assignment): Likewise.

gcc/d/expr.cc

index 7a209fbe73368f5926768aa63016c7eba892d75e..ac9a2820112af19b9b489bca829841c0fc585be1 100644 (file)
@@ -43,181 +43,186 @@ along with GCC; see the file COPYING3.  If not see
 #include "d-tree.h"
 
 
-/* Implements the visitor interface to build the GCC trees of all Expression
-   AST classes emitted from the D Front-end.
-   All visit methods accept one parameter E, which holds the frontend AST
-   of the expression to compile.  They also don't return any value, instead
-   generated code is cached in RESULT_ and returned from the caller.  */
+/* Determine if type T is a struct that has a postblit.  */
 
-class ExprVisitor : public Visitor
+static bool
+needs_postblit (Type *t)
 {
-  using Visitor::visit;
-
-  tree result_;
-  bool constp_;
+  t = t->baseElemOf ();
 
-  /* Determine if type is a struct that has a postblit.  */
-
-  bool needs_postblit (Type *t)
-  {
-    t = t->baseElemOf ();
-
-    if (TypeStruct *ts = t->isTypeStruct ())
-      {
-       if (ts->sym->postblit)
-         return true;
-      }
+  if (TypeStruct *ts = t->isTypeStruct ())
+    {
+      if (ts->sym->postblit)
+       return true;
+    }
 
-    return false;
-  }
+  return false;
+}
 
-  /* Determine if type is a struct that has a destructor.  */
+/* Determine if type T is a struct that has a destructor.  */
 
-  bool needs_dtor (Type *t)
-  {
-    t = t->baseElemOf ();
+static bool
+needs_dtor (Type *t)
+{
+  t = t->baseElemOf ();
 
-    if (TypeStruct *ts = t->isTypeStruct ())
-      {
-       if (ts->sym->dtor)
-         return true;
-      }
+  if (TypeStruct *ts = t->isTypeStruct ())
+    {
+      if (ts->sym->dtor)
+       return true;
+    }
 
-    return false;
-  }
+  return false;
+}
 
-  /* Determine if expression is suitable lvalue.  */
+/* Determine if expression E is a suitable lvalue.  */
 
-  bool lvalue_p (Expression *e)
-  {
-    SliceExp *se = e->isSliceExp ();
-    if (se != NULL && se->e1->isLvalue ())
-      return true;
+static bool
+lvalue_p (Expression *e)
+{
+  SliceExp *se = e->isSliceExp ();
+  if (se != NULL && se->e1->isLvalue ())
+    return true;
 
-    CastExp *ce = e->isCastExp ();
-    if (ce != NULL && ce->e1->isLvalue ())
-      return true;
+  CastExp *ce = e->isCastExp ();
+  if (ce != NULL && ce->e1->isLvalue ())
+    return true;
 
-    return (e->op != TOKslice && e->isLvalue ());
-  }
-
-  /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
-     ARG1.  Perform relevant conversions needed for correct code operations.  */
+  return (e->op != TOKslice && e->isLvalue ());
+}
 
-  tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
-  {
-    tree t0 = TREE_TYPE (arg0);
-    tree t1 = TREE_TYPE (arg1);
-    tree ret = NULL_TREE;
+/* Build an expression of code CODE, data type TYPE, and operands ARG0 and
+   ARG1.  Perform relevant conversions needed for correct code operations.  */
 
-    bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
+static tree
+binary_op (tree_code code, tree type, tree arg0, tree arg1)
+{
+  tree t0 = TREE_TYPE (arg0);
+  tree t1 = TREE_TYPE (arg1);
+  tree ret = NULL_TREE;
 
-    /* Deal with float mod expressions immediately.  */
-    if (code == FLOAT_MOD_EXPR)
-      return build_float_modulus (type, arg0, arg1);
+  bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
 
-    if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
-      return build_nop (type, build_offset_op (code, arg0, arg1));
+  /* Deal with float mod expressions immediately.  */
+  if (code == FLOAT_MOD_EXPR)
+    return build_float_modulus (type, arg0, arg1);
 
-    if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
-      return build_nop (type, build_offset_op (code, arg1, arg0));
+  if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
+    return build_nop (type, build_offset_op (code, arg0, arg1));
 
-    if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
-      {
-       gcc_assert (code == MINUS_EXPR);
-       tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
+  if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
+    return build_nop (type, build_offset_op (code, arg1, arg0));
 
-       /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
-          pointers.  If some platform cannot provide that, or has a larger
-          ptrdiff_type to support differences larger than half the address
-          space, cast the pointers to some larger integer type and do the
-          computations in that type.  */
-       if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
-         ret = fold_build2 (MINUS_EXPR, ptrtype,
-                            d_convert (ptrtype, arg0),
-                            d_convert (ptrtype, arg1));
-       else
-         ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
-      }
-    else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
-      {
-       tree inttype = (unsignedp)
-         ? d_unsigned_type (type) : d_signed_type (type);
-       ret = fold_build2 (code, inttype, arg0, arg1);
-      }
-    else
-      {
-       /* If the operation needs excess precision.  */
-       tree eptype = excess_precision_type (type);
-       if (eptype != NULL_TREE)
-         {
-           arg0 = d_convert (eptype, arg0);
-           arg1 = d_convert (eptype, arg1);
-         }
-       else
-         {
-           /* Front-end does not do this conversion and GCC does not
-              always do it right.  */
-           if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
-             arg1 = d_convert (t0, arg1);
-           else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
-             arg0 = d_convert (t1, arg0);
+  if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
+    {
+      gcc_assert (code == MINUS_EXPR);
+      tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
+
+      /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
+        pointers.  If some platform cannot provide that, or has a larger
+        ptrdiff_type to support differences larger than half the address
+        space, cast the pointers to some larger integer type and do the
+        computations in that type.  */
+      if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
+       ret = fold_build2 (MINUS_EXPR, ptrtype,
+                          d_convert (ptrtype, arg0),
+                          d_convert (ptrtype, arg1));
+      else
+       ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
+    }
+  else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
+    {
+      tree inttype = (unsignedp)
+       ? d_unsigned_type (type) : d_signed_type (type);
+      ret = fold_build2 (code, inttype, arg0, arg1);
+    }
+  else
+    {
+      /* If the operation needs excess precision.  */
+      tree eptype = excess_precision_type (type);
+      if (eptype != NULL_TREE)
+       {
+         arg0 = d_convert (eptype, arg0);
+         arg1 = d_convert (eptype, arg1);
+       }
+      else
+       {
+         /* Front-end does not do this conversion and GCC does not
+            always do it right.  */
+         if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
+           arg1 = d_convert (t0, arg1);
+         else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
+           arg0 = d_convert (t1, arg0);
+
+         eptype = type;
+       }
+
+      ret = fold_build2 (code, eptype, arg0, arg1);
+    }
 
-           eptype = type;
-         }
+  return d_convert (type, ret);
+}
 
-       ret = fold_build2 (code, eptype, arg0, arg1);
-      }
+/* Build a binary expression of code CODE, assigning the result into E1.  */
 
-    return d_convert (type, ret);
-  }
+static tree
+binop_assignment (tree_code code, Expression *e1, Expression *e2)
+{
+  /* Skip casts for lhs assignment.  */
+  Expression *e1b = e1;
+  while (e1b->op == TOKcast)
+    {
+      CastExp *ce = e1b->isCastExp ();
+      gcc_assert (same_type_p (ce->type, ce->to));
+      e1b = ce->e1;
+    }
 
-  /* Build a binary expression of code CODE, assigning the result into E1.  */
+  /* Stabilize LHS for assignment.  */
+  tree lhs = build_expr (e1b);
+  tree lexpr = stabilize_expr (&lhs);
 
-  tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
-  {
-    /* Skip casts for lhs assignment.  */
-    Expression *e1b = e1;
-    while (e1b->op == TOKcast)
-      {
-       CastExp *ce = e1b->isCastExp ();
-       gcc_assert (same_type_p (ce->type, ce->to));
-       e1b = ce->e1;
-      }
+  /* The LHS expression could be an assignment, to which its operation gets
+     lost during gimplification.  */
+  if (TREE_CODE (lhs) == MODIFY_EXPR)
+    {
+      /* If LHS has side effects, call stabilize_reference on it, so it can
+        be evaluated multiple times.  */
+      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
+       lhs = build_assign (MODIFY_EXPR,
+                           stabilize_reference (TREE_OPERAND (lhs, 0)),
+                           TREE_OPERAND (lhs, 1));
+
+      lexpr = compound_expr (lexpr, lhs);
+      lhs = TREE_OPERAND (lhs, 0);
+    }
 
-    /* Stabilize LHS for assignment.  */
-    tree lhs = build_expr (e1b);
-    tree lexpr = stabilize_expr (&lhs);
+  lhs = stabilize_reference (lhs);
 
-    /* The LHS expression could be an assignment, to which its operation gets
-       lost during gimplification.  */
-    if (TREE_CODE (lhs) == MODIFY_EXPR)
-      {
-       /* If LHS has side effects, call stabilize_reference on it, so it can
-          be evaluated multiple times.  */
-       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
-         lhs = build_assign (MODIFY_EXPR,
-                             stabilize_reference (TREE_OPERAND (lhs, 0)),
-                             TREE_OPERAND (lhs, 1));
+  /* Save RHS, to ensure that the expression is evaluated before LHS.  */
+  tree rhs = build_expr (e2);
+  tree rexpr = d_save_expr (rhs);
 
-       lexpr = compound_expr (lexpr, lhs);
-       lhs = TREE_OPERAND (lhs, 0);
-      }
+  rhs = binary_op (code, build_ctype (e1->type),
+                  convert_expr (lhs, e1b->type, e1->type), rexpr);
+  if (TREE_SIDE_EFFECTS (rhs))
+    rhs = compound_expr (rexpr, rhs);
 
-    lhs = stabilize_reference (lhs);
+  tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
+  return compound_expr (lexpr, expr);
+}
 
-    /* Save RHS, to ensure that the expression is evaluated before LHS.  */
-    tree rhs = build_expr (e2);
-    tree rexpr = d_save_expr (rhs);
+/* Implements the visitor interface to build the GCC trees of all Expression
+   AST classes emitted from the D Front-end.
+   All visit methods accept one parameter E, which holds the frontend AST
+   of the expression to compile.  They also don't return any value, instead
+   generated code is cached in RESULT_ and returned from the caller.  */
 
-    rhs = this->binary_op (code, build_ctype (e1->type),
-                          convert_expr (lhs, e1b->type, e1->type), rexpr);
-    if (TREE_SIDE_EFFECTS (rhs))
-      rhs = compound_expr (rexpr, rhs);
+class ExprVisitor : public Visitor
+{
+  using Visitor::visit;
 
-    tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
-    return compound_expr (lexpr, expr);
-  }
+  tree result_;
+  bool constp_;
 
 public:
   ExprVisitor (bool constp)
@@ -653,8 +658,8 @@ public:
        gcc_unreachable ();
       }
 
-    this->result_ = this->binary_op (code, build_ctype (e->type),
-                                    build_expr (e->e1), build_expr (e->e2));
+    this->result_ = binary_op (code, build_ctype (e->type),
+                              build_expr (e->e1), build_expr (e->e2));
   }
 
 
@@ -807,7 +812,7 @@ public:
        gcc_unreachable ();
       }
 
-    tree exp = this->binop_assignment (code, e1b, e->e2);
+    tree exp = binop_assignment (code, e1b, e->e2);
     this->result_ = convert_expr (exp, e1b->type, e->type);
   }
 
@@ -915,8 +920,8 @@ public:
        Type *etype = stype->nextOf ()->toBasetype ();
 
        /* Determine if we need to run postblit or dtor.  */
-       bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
-       bool destructor = this->needs_dtor (etype);
+       bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
+       bool destructor = needs_dtor (etype);
 
        if (e->memset & blockAssign)
          {
@@ -1098,15 +1103,15 @@ public:
        gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
 
        /* Determine if we need to run postblit.  */
-       bool postblit = this->needs_postblit (etype);
-       bool destructor = this->needs_dtor (etype);
-       bool lvalue_p = this->lvalue_p (e->e2);
+       bool postblit = needs_postblit (etype);
+       bool destructor = needs_dtor (etype);
+       bool lvalue = lvalue_p (e->e2);
 
        /* Even if the elements in rhs are all rvalues and don't have
           to call postblits, this assignment should call dtors on old
           assigned elements.  */
        if ((!postblit && !destructor)
-           || (e->op == TOKconstruct && !lvalue_p && postblit)
+           || (e->op == TOKconstruct && !lvalue && postblit)
            || (e->op == TOKblit || e->e1->type->size () == 0))
          {
            tree t1 = build_expr (e->e1);
@@ -1132,7 +1137,7 @@ public:
          {
            /* Generate: _d_arrayassign_l()
                     or: _d_arrayassign_r()  */
-           libcall_fn libcall = (lvalue_p)
+           libcall_fn libcall = (lvalue)
              ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
            tree elembuf = build_local_temp (build_ctype (etype));