Commit f3d34576 by Eric Botcazou Committed by Eric Botcazou

gigi.h (build_function_stub): Remove.

	* gcc-interface/gigi.h (build_function_stub): Remove.
	(build_return_expr): Likewise.
	(convert_vms_descriptor): Declare.
	* gcc-interface/utils.c (convert_vms_descriptor): Make global.
	(build_function_stub): Move to...
	* gcc-interface/utils2.c (build_return_expr): Move to...
	* gcc-interface/trans.c (build_function_stub): ...here.
	(build_return_expr): ...here.
	(Subprogram_Body_to_gnu): Add local variable for language_function.
	Disconnect the parameter attributes cache, if any, once done with it.
	Call end_subprog_body only after setting the end_locus.
	Build the stub associated with the function, if any, at the very end.
	(gnat_to_gnu) <N_Return_Statement>: Remove couple of useless local
	variables and streamline control flow.

From-SVN: r176712
parent 40ecdf41
2011-07-24 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/gigi.h (build_function_stub): Remove.
(build_return_expr): Likewise.
(convert_vms_descriptor): Declare.
* gcc-interface/utils.c (convert_vms_descriptor): Make global.
(build_function_stub): Move to...
* gcc-interface/utils2.c (build_return_expr): Move to...
* gcc-interface/trans.c (build_function_stub): ...here.
(build_return_expr): ...here.
(Subprogram_Body_to_gnu): Add local variable for language_function.
Disconnect the parameter attributes cache, if any, once done with it.
Call end_subprog_body only after setting the end_locus.
Build the stub associated with the function, if any, at the very end.
(gnat_to_gnu) <N_Return_Statement>: Remove couple of useless local
variables and streamline control flow.
2011-07-23 Arnaud Charlet <charlet@adacore.com>
PR ada/49819
......
......@@ -706,10 +706,6 @@ extern tree build_vms_descriptor (tree type, Mechanism_Type mech,
extern tree build_vms_descriptor32 (tree type, Mechanism_Type mech,
Entity_Id gnat_entity);
/* Build a stub for the subprogram specified by the GCC tree GNU_SUBPROG
and the GNAT node GNAT_SUBPROG. */
extern void build_function_stub (tree gnu_subprog, Entity_Id gnat_subprog);
/* Build a type to be used to represent an aliased object whose nominal type
is an unconstrained array. This consists of a RECORD_TYPE containing a
field of TEMPLATE_TYPE and a field of OBJECT_TYPE, which is an ARRAY_TYPE.
......@@ -812,13 +808,9 @@ extern tree build_cond_expr (tree result_type, tree condition_operand,
tree true_operand, tree false_operand);
/* Similar, but for COMPOUND_EXPR. */
extern tree build_compound_expr (tree result_type, tree stmt_operand,
tree expr_operand);
/* Similar, but for RETURN_EXPR. */
extern tree build_return_expr (tree ret_obj, tree ret_val);
/* Build a CALL_EXPR to call FUNDECL with one argument, ARG. Return
the CALL_EXPR. */
extern tree build_call_1_expr (tree fundecl, tree arg);
......@@ -893,6 +885,15 @@ extern tree build_allocator (tree type, tree init, tree result_type,
extern tree fill_vms_descriptor (tree gnu_type, tree gnu_expr,
Node_Id gnat_actual);
/* Convert GNU_EXPR, a pointer to a VMS descriptor, to GNU_TYPE, a regular
pointer or fat pointer type. GNU_EXPR_ALT_TYPE is the alternate (32-bit)
pointer type of GNU_EXPR. BY_REF is true if the result is to be used by
reference. GNAT_SUBPROG is the subprogram to which the VMS descriptor is
passed. */
extern tree convert_vms_descriptor (tree gnu_type, tree gnu_expr,
tree gnu_expr_alt_type, bool by_ref,
Entity_Id gnat_subprog);
/* Indicate that we need to take the address of T and that it therefore
should not be allocated in a register. Returns true if successful. */
extern bool gnat_mark_addressable (tree t);
......
......@@ -3295,7 +3295,7 @@ convert_vms_descriptor32 (tree gnu_type, tree gnu_expr, Entity_Id gnat_subprog)
reference. GNAT_SUBPROG is the subprogram to which the VMS descriptor is
passed. */
static tree
tree
convert_vms_descriptor (tree gnu_type, tree gnu_expr, tree gnu_expr_alt_type,
bool by_ref, Entity_Id gnat_subprog)
{
......@@ -3344,69 +3344,6 @@ convert_vms_descriptor (tree gnu_type, tree gnu_expr, tree gnu_expr_alt_type,
return build3 (COND_EXPR, gnu_type, is64bit, gnu_expr64, gnu_expr32);
}
/* Build a stub for the subprogram specified by the GCC tree GNU_SUBPROG
and the GNAT node GNAT_SUBPROG. */
void
build_function_stub (tree gnu_subprog, Entity_Id gnat_subprog)
{
tree gnu_subprog_type, gnu_subprog_addr, gnu_subprog_call;
tree gnu_subprog_param, gnu_stub_param, gnu_param;
tree gnu_stub_decl = DECL_FUNCTION_STUB (gnu_subprog);
VEC(tree,gc) *gnu_param_vec = NULL;
gnu_subprog_type = TREE_TYPE (gnu_subprog);
/* Initialize the information structure for the function. */
allocate_struct_function (gnu_stub_decl, false);
set_cfun (NULL);
begin_subprog_body (gnu_stub_decl);
start_stmt_group ();
gnat_pushlevel ();
/* Loop over the parameters of the stub and translate any of them
passed by descriptor into a by reference one. */
for (gnu_stub_param = DECL_ARGUMENTS (gnu_stub_decl),
gnu_subprog_param = DECL_ARGUMENTS (gnu_subprog);
gnu_stub_param;
gnu_stub_param = TREE_CHAIN (gnu_stub_param),
gnu_subprog_param = TREE_CHAIN (gnu_subprog_param))
{
if (DECL_BY_DESCRIPTOR_P (gnu_stub_param))
{
gcc_assert (DECL_BY_REF_P (gnu_subprog_param));
gnu_param
= convert_vms_descriptor (TREE_TYPE (gnu_subprog_param),
gnu_stub_param,
DECL_PARM_ALT_TYPE (gnu_stub_param),
DECL_BY_DOUBLE_REF_P (gnu_subprog_param),
gnat_subprog);
}
else
gnu_param = gnu_stub_param;
VEC_safe_push (tree, gc, gnu_param_vec, gnu_param);
}
/* Invoke the internal subprogram. */
gnu_subprog_addr = build1 (ADDR_EXPR, build_pointer_type (gnu_subprog_type),
gnu_subprog);
gnu_subprog_call = build_call_vec (TREE_TYPE (gnu_subprog_type),
gnu_subprog_addr, gnu_param_vec);
/* Propagate the return value, if any. */
if (VOID_TYPE_P (TREE_TYPE (gnu_subprog_type)))
add_stmt (gnu_subprog_call);
else
add_stmt (build_return_expr (DECL_RESULT (gnu_stub_decl),
gnu_subprog_call));
gnat_poplevel ();
end_subprog_body (end_stmt_group ());
}
/* Build a type to be used to represent an aliased object whose nominal type
is an unconstrained array. This consists of a RECORD_TYPE containing a
......
......@@ -1407,43 +1407,6 @@ build_compound_expr (tree result_type, tree stmt_operand, tree expr_operand)
return result;
}
/* Similar, but for RETURN_EXPR. If RET_VAL is non-null, build a RETURN_EXPR
around the assignment of RET_VAL to RET_OBJ. Otherwise just build a bare
RETURN_EXPR around RESULT_OBJ, which may be null in this case. */
tree
build_return_expr (tree ret_obj, tree ret_val)
{
tree result_expr;
if (ret_val)
{
/* The gimplifier explicitly enforces the following invariant:
RETURN_EXPR
|
MODIFY_EXPR
/ \
/ \
RET_OBJ ...
As a consequence, type consistency dictates that we use the type
of the RET_OBJ as the operation type. */
tree operation_type = TREE_TYPE (ret_obj);
/* Convert the right operand to the operation type. Note that it's the
same transformation as in the MODIFY_EXPR case of build_binary_op,
with the assumption that the type cannot involve a placeholder. */
if (operation_type != TREE_TYPE (ret_val))
ret_val = convert (operation_type, ret_val);
result_expr = build2 (MODIFY_EXPR, operation_type, ret_obj, ret_val);
}
else
result_expr = ret_obj;
return build1 (RETURN_EXPR, void_type_node, result_expr);
}
/* Build a CALL_EXPR to call FUNDECL with one argument, ARG. Return
the CALL_EXPR. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment