Streamline implementation of renaming in gigi
The main changes are 1) the bulk of the implementation is put back entirely in gnat_to_gnu_entity and 2) the handling of lvalues is unified, i.e. it no longer depends on the Materialize_Entity flag being present on the entity. gcc/ada/ChangeLog: * gcc-interface/ada-tree.h (DECL_RENAMED_OBJECT): Delete. * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Always use the stabilized reference directly for renaming and create a variable pointing to it separately if requested. * gcc-interface/misc.c (gnat_print_decl): Adjust for deletion. * gcc-interface/trans.c (Identifier_to_gnu): Likewise. (gnat_to_gnu) <N_Object_Renaming_Declaration>: Do not deal with side-effects here. <N_Exception_Renaming_Declaration>: Likewise.
This commit is contained in:
parent
cd42cdc225
commit
5bdd063b9d
@ -525,13 +525,6 @@ do { \
|
||||
#define SET_DECL_INDUCTION_VAR(NODE, X) \
|
||||
SET_DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE), X)
|
||||
|
||||
/* In a VAR_DECL without the DECL_LOOP_PARM_P flag set and that is a renaming
|
||||
pointer, points to the object being renamed, if any. */
|
||||
#define DECL_RENAMED_OBJECT(NODE) \
|
||||
GET_DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))
|
||||
#define SET_DECL_RENAMED_OBJECT(NODE, X) \
|
||||
SET_DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE), X)
|
||||
|
||||
/* In a TYPE_DECL, points to the parallel type if any, otherwise 0. */
|
||||
#define DECL_PARALLEL_TYPE(NODE) \
|
||||
GET_DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))
|
||||
|
@ -714,7 +714,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
bool mutable_p = false;
|
||||
bool used_by_ref = false;
|
||||
tree gnu_ext_name = NULL_TREE;
|
||||
tree gnu_renamed_obj = NULL_TREE;
|
||||
tree gnu_ada_size = NULL_TREE;
|
||||
|
||||
/* We need to translate the renamed object even though we are only
|
||||
@ -1041,13 +1040,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
else if (type_is_padding_self_referential (TREE_TYPE (gnu_expr)))
|
||||
gnu_type = TREE_TYPE (gnu_expr);
|
||||
|
||||
/* Case 1: if this is a constant renaming stemming from a function
|
||||
call, treat it as a normal object whose initial value is what
|
||||
is being renamed. RM 3.3 says that the result of evaluating a
|
||||
function call is a constant object. Therefore, it can be the
|
||||
inner object of a constant renaming and the renaming must be
|
||||
fully instantiated, i.e. it cannot be a reference to (part of)
|
||||
an existing object. And treat other rvalues the same way. */
|
||||
/* If this is a constant renaming stemming from a function call,
|
||||
treat it as a normal object whose initial value is what is being
|
||||
renamed. RM 3.3 says that the result of evaluating a function
|
||||
call is a constant object. Therefore, it can be the inner
|
||||
object of a constant renaming and the renaming must be fully
|
||||
instantiated, i.e. it cannot be a reference to (part of) an
|
||||
existing object. And treat other rvalues the same way. */
|
||||
tree inner = gnu_expr;
|
||||
while (handled_component_p (inner) || CONVERT_EXPR_P (inner))
|
||||
inner = TREE_OPERAND (inner, 0);
|
||||
@ -1089,92 +1088,75 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
&& DECL_RETURN_VALUE_P (inner)))
|
||||
;
|
||||
|
||||
/* Case 2: if the renaming entity need not be materialized, use
|
||||
the elaborated renamed expression for the renaming. But this
|
||||
means that the caller is responsible for evaluating the address
|
||||
of the renaming in the correct place for the definition case to
|
||||
instantiate the SAVE_EXPRs. But we cannot use this mechanism if
|
||||
the renamed object is an N_Expression_With_Actions because this
|
||||
would fail the assertion below. */
|
||||
else if (!Materialize_Entity (gnat_entity)
|
||||
&& Nkind (gnat_renamed_obj) != N_Expression_With_Actions)
|
||||
/* Otherwise, this is an lvalue being renamed, so it needs to be
|
||||
elaborated as a reference and substituted for the entity. But
|
||||
this means that we must evaluate the address of the renaming
|
||||
in the definition case to instantiate the SAVE_EXPRs. */
|
||||
else
|
||||
{
|
||||
tree init = NULL_TREE;
|
||||
tree gnu_init = NULL_TREE;
|
||||
|
||||
gnu_decl
|
||||
if (type_annotate_only && TREE_CODE (gnu_expr) == ERROR_MARK)
|
||||
break;
|
||||
|
||||
gnu_expr
|
||||
= elaborate_reference (gnu_expr, gnat_entity, definition,
|
||||
&init);
|
||||
&gnu_init);
|
||||
|
||||
/* We cannot evaluate the first arm of a COMPOUND_EXPR in the
|
||||
correct place for this case. */
|
||||
gcc_assert (!init);
|
||||
|
||||
/* No DECL_EXPR will be created so the expression needs to be
|
||||
/* No DECL_EXPR might be created so the expression needs to be
|
||||
marked manually because it will likely be shared. */
|
||||
if (global_bindings_p ())
|
||||
MARK_VISITED (gnu_decl);
|
||||
MARK_VISITED (gnu_expr);
|
||||
|
||||
/* This assertion will fail if the renamed object isn't aligned
|
||||
enough as to make it possible to honor the alignment set on
|
||||
the renaming. */
|
||||
if (align)
|
||||
{
|
||||
unsigned int ralign = DECL_P (gnu_decl)
|
||||
? DECL_ALIGN (gnu_decl)
|
||||
: TYPE_ALIGN (TREE_TYPE (gnu_decl));
|
||||
const unsigned int ralign
|
||||
= DECL_P (gnu_expr)
|
||||
? DECL_ALIGN (gnu_expr)
|
||||
: TYPE_ALIGN (TREE_TYPE (gnu_expr));
|
||||
gcc_assert (ralign >= align);
|
||||
}
|
||||
|
||||
/* The expression might not be a DECL so save it manually. */
|
||||
gnu_decl = gnu_expr;
|
||||
save_gnu_tree (gnat_entity, gnu_decl, true);
|
||||
saved = true;
|
||||
annotate_object (gnat_entity, gnu_type, NULL_TREE, false);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Case 3: otherwise, make a constant pointer to the object we
|
||||
are renaming and attach the object to the pointer after it is
|
||||
elaborated. The object will be referenced directly instead
|
||||
of indirectly via the pointer to avoid aliasing problems with
|
||||
non-addressable entities. The pointer is called a "renaming"
|
||||
pointer in this case. Note that we also need to preserve the
|
||||
volatility of the renamed object through the indirection. */
|
||||
else
|
||||
{
|
||||
tree init = NULL_TREE;
|
||||
/* If this is only a reference to the entity, we are done. */
|
||||
if (!definition)
|
||||
break;
|
||||
|
||||
if (TREE_THIS_VOLATILE (gnu_expr) && !TYPE_VOLATILE (gnu_type))
|
||||
gnu_type
|
||||
= change_qualified_type (gnu_type, TYPE_QUAL_VOLATILE);
|
||||
gnu_type = build_reference_type (gnu_type);
|
||||
used_by_ref = true;
|
||||
const_flag = true;
|
||||
volatile_flag = false;
|
||||
inner_const_flag = TREE_READONLY (gnu_expr);
|
||||
gnu_size = NULL_TREE;
|
||||
/* Otherwise, emit the initialization statement, if any. */
|
||||
if (gnu_init)
|
||||
add_stmt (gnu_init);
|
||||
|
||||
gnu_renamed_obj
|
||||
= elaborate_reference (gnu_expr, gnat_entity, definition,
|
||||
&init);
|
||||
|
||||
/* The expression needs to be marked manually because it will
|
||||
likely be shared, even for a definition since the ADDR_EXPR
|
||||
built below can cause the first few nodes to be folded. */
|
||||
if (global_bindings_p ())
|
||||
MARK_VISITED (gnu_renamed_obj);
|
||||
|
||||
if (type_annotate_only
|
||||
&& TREE_CODE (gnu_renamed_obj) == ERROR_MARK)
|
||||
gnu_expr = NULL_TREE;
|
||||
else
|
||||
/* If it needs to be materialized for debugging purposes, build
|
||||
the entity as indirect reference to the renamed object. */
|
||||
if (Materialize_Entity (gnat_entity))
|
||||
{
|
||||
gnu_expr
|
||||
= build_unary_op (ADDR_EXPR, gnu_type, gnu_renamed_obj);
|
||||
if (init)
|
||||
gnu_expr
|
||||
= build_compound_expr (TREE_TYPE (gnu_expr), init,
|
||||
gnu_expr);
|
||||
gnu_type = build_reference_type (gnu_type);
|
||||
const_flag = true;
|
||||
volatile_flag = false;
|
||||
|
||||
gnu_expr = build_unary_op (ADDR_EXPR, gnu_type, gnu_expr);
|
||||
|
||||
create_var_decl (gnu_entity_name, gnu_ext_name,
|
||||
TREE_TYPE (gnu_expr), gnu_expr,
|
||||
const_flag, Is_Public (gnat_entity),
|
||||
imported_p, static_flag, volatile_flag,
|
||||
artificial_p, debug_info_p, attr_list,
|
||||
gnat_entity, false);
|
||||
}
|
||||
|
||||
/* Otherwise, instantiate the SAVE_EXPRs if needed. */
|
||||
else if (TREE_SIDE_EFFECTS (gnu_expr))
|
||||
add_stmt (build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1538,7 +1520,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
imported_p || !definition, static_flag,
|
||||
volatile_flag, artificial_p,
|
||||
debug_info_p && definition, attr_list,
|
||||
gnat_entity, !gnu_renamed_obj);
|
||||
gnat_entity, true);
|
||||
DECL_BY_REF_P (gnu_decl) = used_by_ref;
|
||||
DECL_POINTS_TO_READONLY_P (gnu_decl) = used_by_ref && inner_const_flag;
|
||||
DECL_CAN_NEVER_BE_NULL_P (gnu_decl) = Can_Never_Be_Null (gnat_entity);
|
||||
@ -1566,10 +1548,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
else if (kind == E_Loop_Parameter)
|
||||
DECL_LOOP_PARM_P (gnu_decl) = 1;
|
||||
|
||||
/* If this is a renaming pointer, attach the renamed object to it. */
|
||||
if (gnu_renamed_obj)
|
||||
SET_DECL_RENAMED_OBJECT (gnu_decl, gnu_renamed_obj);
|
||||
|
||||
/* If this is a constant and we are defining it or it generates a real
|
||||
symbol at the object level and we are referencing it, we may want
|
||||
or need to have a true variable to represent it:
|
||||
|
@ -467,9 +467,6 @@ gnat_print_decl (FILE *file, tree node, int indent)
|
||||
if (DECL_LOOP_PARM_P (node))
|
||||
print_node (file, "induction var", DECL_INDUCTION_VAR (node),
|
||||
indent + 4);
|
||||
else
|
||||
print_node (file, "renamed object", DECL_RENAMED_OBJECT (node),
|
||||
indent + 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1249,25 +1249,16 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
|
||||
true)))
|
||||
gnu_result = DECL_INITIAL (gnu_result);
|
||||
|
||||
/* If it's a renaming pointer, get to the renamed object. */
|
||||
if (TREE_CODE (gnu_result) == VAR_DECL
|
||||
&& !DECL_LOOP_PARM_P (gnu_result)
|
||||
&& DECL_RENAMED_OBJECT (gnu_result))
|
||||
gnu_result = DECL_RENAMED_OBJECT (gnu_result);
|
||||
/* Do the final dereference. */
|
||||
gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
|
||||
|
||||
/* Otherwise, do the final dereference. */
|
||||
else
|
||||
{
|
||||
gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
|
||||
if ((TREE_CODE (gnu_result) == INDIRECT_REF
|
||||
|| TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
|
||||
&& No (Address_Clause (gnat_entity)))
|
||||
TREE_THIS_NOTRAP (gnu_result) = 1;
|
||||
|
||||
if ((TREE_CODE (gnu_result) == INDIRECT_REF
|
||||
|| TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
|
||||
&& No (Address_Clause (gnat_entity)))
|
||||
TREE_THIS_NOTRAP (gnu_result) = 1;
|
||||
|
||||
if (read_only)
|
||||
TREE_READONLY (gnu_result) = 1;
|
||||
}
|
||||
if (read_only)
|
||||
TREE_READONLY (gnu_result) = 1;
|
||||
}
|
||||
|
||||
/* If we have a constant declaration and its initializer, try to return the
|
||||
@ -6543,31 +6534,19 @@ gnat_to_gnu (Node_Id gnat_node)
|
||||
&& (Is_Array_Type (Etype (gnat_temp))
|
||||
|| Is_Record_Type (Etype (gnat_temp))
|
||||
|| Is_Concurrent_Type (Etype (gnat_temp)))))
|
||||
{
|
||||
tree gnu_temp
|
||||
= gnat_to_gnu_entity (gnat_temp,
|
||||
gnat_to_gnu (Renamed_Object (gnat_temp)),
|
||||
true);
|
||||
/* See case 2 of renaming in gnat_to_gnu_entity. */
|
||||
if (TREE_SIDE_EFFECTS (gnu_temp))
|
||||
gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_temp);
|
||||
}
|
||||
gnat_to_gnu_entity (gnat_temp,
|
||||
gnat_to_gnu (Renamed_Object (gnat_temp)),
|
||||
true);
|
||||
break;
|
||||
|
||||
case N_Exception_Renaming_Declaration:
|
||||
gnat_temp = Defining_Entity (gnat_node);
|
||||
gnu_result = alloc_stmt_list ();
|
||||
|
||||
/* See the above case for the rationale. */
|
||||
if (Present (Renamed_Entity (gnat_temp)))
|
||||
{
|
||||
tree gnu_temp
|
||||
= gnat_to_gnu_entity (gnat_temp,
|
||||
gnat_to_gnu (Renamed_Entity (gnat_temp)),
|
||||
true);
|
||||
if (TREE_SIDE_EFFECTS (gnu_temp))
|
||||
gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_temp);
|
||||
}
|
||||
gnat_to_gnu_entity (gnat_temp,
|
||||
gnat_to_gnu (Renamed_Entity (gnat_temp)),
|
||||
true);
|
||||
break;
|
||||
|
||||
case N_Subprogram_Renaming_Declaration:
|
||||
|
Loading…
Reference in New Issue
Block a user