[D] Move building of typeof(null) values to a common function.

gcc/d/ChangeLog:

	* d-codegen.cc (build_typeof_null_value): New function.
	* d-tree.h (build_typeof_null_value): Declare.
	* d-convert.cc (convert_expr): Use build_typeof_null_value.
	* expr.cc (ExprVisitor::visit(NullExp)): Likewise.

From-SVN: r267955
This commit is contained in:
Iain Buclaw 2019-01-15 23:02:43 +00:00 committed by Iain Buclaw
parent 37879e0161
commit 5e95646e73
5 changed files with 50 additions and 38 deletions

View File

@ -1,3 +1,10 @@
2019-01-16 Iain Buclaw <ibuclaw@gdcproject.org>
* d-codegen.cc (build_typeof_null_value): New function.
* d-tree.h (build_typeof_null_value): Declare.
* d-convert.cc (convert_expr): Use build_typeof_null_value.
* expr.cc (ExprVisitor::visit(NullExp)): Likewise.
2019-01-15 Richard Sandiford <richard.sandiford@arm.com>
PR inline-asm/52813

View File

@ -448,6 +448,42 @@ extract_from_method_call (tree t, tree& callee, tree& object)
callee = CONSTRUCTOR_ELT (t, 1)->value;
}
/* Build a typeof(null) constant of type TYPE. Handles certain special case
conversions, where the underlying type is an aggregate with a nullable
interior pointer. */
tree
build_typeof_null_value (Type *type)
{
Type *tb = type->toBasetype ();
tree value;
/* For dynamic arrays, set length and pointer fields to zero. */
if (tb->ty == Tarray)
value = d_array_value (build_ctype (type), size_int (0), null_pointer_node);
/* For associative arrays, set the pointer field to null. */
else if (tb->ty == Taarray)
{
tree ctype = build_ctype (type);
gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype));
value = build_constructor_single (ctype, TYPE_FIELDS (ctype),
null_pointer_node);
}
/* For delegates, set the frame and function pointer fields to null. */
else if (tb->ty == Tdelegate)
value = build_delegate_cst (null_pointer_node, null_pointer_node, type);
/* Simple zero constant for all other types. */
else
value = build_zero_cst (build_ctype (type));
TREE_CONSTANT (value) = 1;
return value;
}
/* Build a dereference into the virtual table for OBJECT to retrieve
a function pointer of type FNTYPE at position INDEX. */

View File

@ -560,18 +560,12 @@ convert_expr (tree exp, Type *etype, Type *totype)
case Tnull:
/* Casting from typeof(null) is represented as all zeros. */
if (tbtype->ty == Tarray)
{
tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
return d_array_value (build_ctype (totype), size_int (0),
build_nop (ptrtype, exp));
}
else if (tbtype->ty == Taarray)
return build_constructor (build_ctype (totype), NULL);
else if (tbtype->ty == Tdelegate)
return build_delegate_cst (exp, null_pointer_node, totype);
result = build_typeof_null_value (totype);
return build_zero_cst (build_ctype (totype));
/* Make sure the expression is still evaluated if necessary. */
if (TREE_SIDE_EFFECTS (exp))
result = compound_expr (exp, result);
break;
case Tvector:
if (tbtype->ty == Tsarray)

View File

@ -511,6 +511,7 @@ extern tree delegate_object (tree);
extern tree build_delegate_cst (tree, tree, Type *);
extern tree build_method_call (tree, tree, Type *);
extern void extract_from_method_call (tree, tree &, tree &);
extern tree build_typeof_null_value (Type *);
extern tree build_vindex_ref (tree, tree, size_t);
extern tree d_save_expr (tree);
extern tree stabilize_expr (tree *);

View File

@ -2941,33 +2941,7 @@ public:
void visit (NullExp *e)
{
Type *tb = e->type->toBasetype ();
tree value;
/* Handle certain special case conversions, where the underlying type is an
aggregate with a nullable interior pointer. */
if (tb->ty == Tarray)
{
/* For dynamic arrays, set length and pointer fields to zero. */
value = d_array_value (build_ctype (e->type), size_int (0),
null_pointer_node);
}
else if (tb->ty == Taarray)
{
/* For associative arrays, set the pointer field to null. */
value = build_constructor (build_ctype (e->type), NULL);
}
else if (tb->ty == Tdelegate)
{
/* For delegates, set the frame and function pointer to null. */
value = build_delegate_cst (null_pointer_node,
null_pointer_node, e->type);
}
else
value = d_convert (build_ctype (e->type), integer_zero_node);
TREE_CONSTANT (value) = 1;
this->result_ = value;
this->result_ = build_typeof_null_value (e->type);
}
/* Build a vector literal. */