d: Move private functions out of ExprVisitor into local statics
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.
This commit is contained in:
parent
561a19c301
commit
dc60d67674
|
@ -43,23 +43,11 @@ 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_;
|
||||
|
||||
/* Determine if type is a struct that has a postblit. */
|
||||
|
||||
bool needs_postblit (Type *t)
|
||||
{
|
||||
t = t->baseElemOf ();
|
||||
|
||||
if (TypeStruct *ts = t->isTypeStruct ())
|
||||
|
@ -69,12 +57,13 @@ class ExprVisitor : public Visitor
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
static bool
|
||||
needs_dtor (Type *t)
|
||||
{
|
||||
t = t->baseElemOf ();
|
||||
|
||||
if (TypeStruct *ts = t->isTypeStruct ())
|
||||
|
@ -84,12 +73,13 @@ class ExprVisitor : public Visitor
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if expression is suitable lvalue. */
|
||||
/* Determine if expression E is a suitable lvalue. */
|
||||
|
||||
bool lvalue_p (Expression *e)
|
||||
{
|
||||
static bool
|
||||
lvalue_p (Expression *e)
|
||||
{
|
||||
SliceExp *se = e->isSliceExp ();
|
||||
if (se != NULL && se->e1->isLvalue ())
|
||||
return true;
|
||||
|
@ -99,13 +89,14 @@ class ExprVisitor : public Visitor
|
|||
return true;
|
||||
|
||||
return (e->op != TOKslice && e->isLvalue ());
|
||||
}
|
||||
}
|
||||
|
||||
/* Build an expression of code CODE, data type TYPE, and operands ARG0 and
|
||||
/* Build an expression of code CODE, data type TYPE, and operands ARG0 and
|
||||
ARG1. Perform relevant conversions needed for correct code operations. */
|
||||
|
||||
tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
|
||||
{
|
||||
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;
|
||||
|
@ -170,12 +161,13 @@ class ExprVisitor : public Visitor
|
|||
}
|
||||
|
||||
return d_convert (type, ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a binary expression of code CODE, assigning the result into E1. */
|
||||
/* Build a binary expression of code CODE, assigning the result into E1. */
|
||||
|
||||
tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
|
||||
{
|
||||
static tree
|
||||
binop_assignment (tree_code code, Expression *e1, Expression *e2)
|
||||
{
|
||||
/* Skip casts for lhs assignment. */
|
||||
Expression *e1b = e1;
|
||||
while (e1b->op == TOKcast)
|
||||
|
@ -210,14 +202,27 @@ class ExprVisitor : public Visitor
|
|||
tree rhs = build_expr (e2);
|
||||
tree rexpr = d_save_expr (rhs);
|
||||
|
||||
rhs = this->binary_op (code, build_ctype (e1->type),
|
||||
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);
|
||||
|
||||
tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
|
||||
return compound_expr (lexpr, expr);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
class ExprVisitor : public Visitor
|
||||
{
|
||||
using Visitor::visit;
|
||||
|
||||
tree result_;
|
||||
bool constp_;
|
||||
|
||||
public:
|
||||
ExprVisitor (bool constp)
|
||||
|
@ -653,7 +658,7 @@ public:
|
|||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
this->result_ = this->binary_op (code, build_ctype (e->type),
|
||||
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));
|
||||
|
||||
|
|
Loading…
Reference in New Issue