mirror of git://gcc.gnu.org/git/gcc.git
decl.c (compile_time_known_address_p): Rewrite and move around.
* decl.c (compile_time_known_address_p): Rewrite and move around. (gnat_to_gnu_type): Move around. (get_unpadded_type): Likewise. * utils.c (update_pointer_to): Use synthetic macro. Tidy comments. From-SVN: r145654
This commit is contained in:
parent
c22ba5ffd4
commit
229077b0b4
|
@ -1,3 +1,10 @@
|
||||||
|
2009-04-07 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* decl.c (compile_time_known_address_p): Rewrite and move around.
|
||||||
|
(gnat_to_gnu_type): Move around.
|
||||||
|
(get_unpadded_type): Likewise.
|
||||||
|
* utils.c (update_pointer_to): Use synthetic macro. Tidy comments.
|
||||||
|
|
||||||
2009-04-07 Eric Botcazou <ebotcazou@adacore.com>
|
2009-04-07 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gcc-interface/trans.c (check_for_eliminated_entity): New function.
|
* gcc-interface/trans.c (check_for_eliminated_entity): New function.
|
||||||
|
|
|
@ -139,6 +139,7 @@ static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool,
|
||||||
bool *);
|
bool *);
|
||||||
static bool same_discriminant_p (Entity_Id, Entity_Id);
|
static bool same_discriminant_p (Entity_Id, Entity_Id);
|
||||||
static bool array_type_has_nonaliased_component (Entity_Id, tree);
|
static bool array_type_has_nonaliased_component (Entity_Id, tree);
|
||||||
|
static bool compile_time_known_address_p (Node_Id);
|
||||||
static void components_to_record (tree, Node_Id, tree, int, bool, tree *,
|
static void components_to_record (tree, Node_Id, tree, int, bool, tree *,
|
||||||
bool, bool, bool, bool);
|
bool, bool, bool, bool);
|
||||||
static Uint annotate_value (tree);
|
static Uint annotate_value (tree);
|
||||||
|
@ -152,36 +153,6 @@ static unsigned int ceil_alignment (unsigned HOST_WIDE_INT);
|
||||||
static void check_ok_for_atomic (tree, Entity_Id, bool);
|
static void check_ok_for_atomic (tree, Entity_Id, bool);
|
||||||
static int compatible_signatures_p (tree ftype1, tree ftype2);
|
static int compatible_signatures_p (tree ftype1, tree ftype2);
|
||||||
static void rest_of_type_decl_compilation_no_defer (tree);
|
static void rest_of_type_decl_compilation_no_defer (tree);
|
||||||
|
|
||||||
/* Return true if GNAT_ADDRESS is a compile time known value.
|
|
||||||
In particular catch System'To_Address. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
compile_time_known_address_p (Node_Id gnat_address)
|
|
||||||
{
|
|
||||||
return ((Nkind (gnat_address) == N_Unchecked_Type_Conversion
|
|
||||||
&& Compile_Time_Known_Value (Expression (gnat_address)))
|
|
||||||
|| Compile_Time_Known_Value (gnat_address));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given GNAT_ENTITY, an entity in the incoming GNAT tree, return a
|
|
||||||
GCC type corresponding to that entity. GNAT_ENTITY is assumed to
|
|
||||||
refer to an Ada type. */
|
|
||||||
|
|
||||||
tree
|
|
||||||
gnat_to_gnu_type (Entity_Id gnat_entity)
|
|
||||||
{
|
|
||||||
tree gnu_decl;
|
|
||||||
|
|
||||||
/* The back end never attempts to annotate generic types */
|
|
||||||
if (Is_Generic_Type (gnat_entity) && type_annotate_only)
|
|
||||||
return void_type_node;
|
|
||||||
|
|
||||||
/* Convert the ada entity type into a GCC TYPE_DECL node. */
|
|
||||||
gnu_decl = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 0);
|
|
||||||
gcc_assert (TREE_CODE (gnu_decl) == TYPE_DECL);
|
|
||||||
return TREE_TYPE (gnu_decl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given GNAT_ENTITY, a GNAT defining identifier node, which denotes some Ada
|
/* Given GNAT_ENTITY, a GNAT defining identifier node, which denotes some Ada
|
||||||
entity, this routine returns the equivalent GCC tree for that entity
|
entity, this routine returns the equivalent GCC tree for that entity
|
||||||
|
@ -4757,6 +4728,38 @@ gnat_to_gnu_field_decl (Entity_Id gnat_entity)
|
||||||
return gnu_field;
|
return gnu_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Similar, but GNAT_ENTITY is assumed to refer to a GNAT type. Return
|
||||||
|
the GCC type corresponding to that entity. */
|
||||||
|
|
||||||
|
tree
|
||||||
|
gnat_to_gnu_type (Entity_Id gnat_entity)
|
||||||
|
{
|
||||||
|
tree gnu_decl;
|
||||||
|
|
||||||
|
/* The back end never attempts to annotate generic types. */
|
||||||
|
if (Is_Generic_Type (gnat_entity) && type_annotate_only)
|
||||||
|
return void_type_node;
|
||||||
|
|
||||||
|
gnu_decl = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 0);
|
||||||
|
gcc_assert (TREE_CODE (gnu_decl) == TYPE_DECL);
|
||||||
|
|
||||||
|
return TREE_TYPE (gnu_decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar, but GNAT_ENTITY is assumed to refer to a GNAT type. Return
|
||||||
|
the unpadded version of the GCC type corresponding to that entity. */
|
||||||
|
|
||||||
|
tree
|
||||||
|
get_unpadded_type (Entity_Id gnat_entity)
|
||||||
|
{
|
||||||
|
tree type = gnat_to_gnu_type (gnat_entity);
|
||||||
|
|
||||||
|
if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
|
||||||
|
type = TREE_TYPE (TYPE_FIELDS (type));
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrap up compilation of DECL, a TYPE_DECL, possibly deferring it.
|
/* Wrap up compilation of DECL, a TYPE_DECL, possibly deferring it.
|
||||||
Every TYPE_DECL generated for a type definition must be passed
|
Every TYPE_DECL generated for a type definition must be passed
|
||||||
to this function once everything else has been done for it. */
|
to this function once everything else has been done for it. */
|
||||||
|
@ -5093,6 +5096,18 @@ array_type_has_nonaliased_component (Entity_Id gnat_type, tree gnu_type)
|
||||||
|
|
||||||
return type_for_nonaliased_component_p (TREE_TYPE (gnu_type));
|
return type_for_nonaliased_component_p (TREE_TYPE (gnu_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if GNAT_ADDRESS is a value known at compile-time. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
compile_time_known_address_p (Node_Id gnat_address)
|
||||||
|
{
|
||||||
|
/* Catch System'To_Address. */
|
||||||
|
if (Nkind (gnat_address) == N_Unchecked_Type_Conversion)
|
||||||
|
gnat_address = Expression (gnat_address);
|
||||||
|
|
||||||
|
return Compile_Time_Known_Value (gnat_address);
|
||||||
|
}
|
||||||
|
|
||||||
/* Given GNAT_ENTITY, elaborate all expressions that are required to
|
/* Given GNAT_ENTITY, elaborate all expressions that are required to
|
||||||
be elaborated at the point of its definition, but do nothing else. */
|
be elaborated at the point of its definition, but do nothing else. */
|
||||||
|
@ -5440,19 +5455,6 @@ prepend_attributes (Entity_Id gnat_entity, struct attrib ** attr_list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the unpadded version of a GNAT type. */
|
|
||||||
|
|
||||||
tree
|
|
||||||
get_unpadded_type (Entity_Id gnat_entity)
|
|
||||||
{
|
|
||||||
tree type = gnat_to_gnu_type (gnat_entity);
|
|
||||||
|
|
||||||
if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
|
|
||||||
type = TREE_TYPE (TYPE_FIELDS (type));
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called when we need to protect a variable object using a save_expr. */
|
/* Called when we need to protect a variable object using a save_expr. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
|
|
|
@ -3738,9 +3738,9 @@ shift_unc_components_for_thin_pointers (tree type)
|
||||||
DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
|
DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE. In
|
/* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.
|
||||||
the normal case this is just two adjustments, but we have more to do
|
In the normal case this is just two adjustments, but we have more to
|
||||||
if NEW is an UNCONSTRAINED_ARRAY_TYPE. */
|
do if NEW_TYPE is an UNCONSTRAINED_ARRAY_TYPE. */
|
||||||
|
|
||||||
void
|
void
|
||||||
update_pointer_to (tree old_type, tree new_type)
|
update_pointer_to (tree old_type, tree new_type)
|
||||||
|
@ -3756,35 +3756,34 @@ update_pointer_to (tree old_type, tree new_type)
|
||||||
type = TYPE_NEXT_VARIANT (type))
|
type = TYPE_NEXT_VARIANT (type))
|
||||||
update_pointer_to (type, new_type);
|
update_pointer_to (type, new_type);
|
||||||
|
|
||||||
/* If no pointer or reference, we are done. */
|
/* If no pointers and no references, we are done. */
|
||||||
if (!ptr && !ref)
|
if (!ptr && !ref)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Merge the old type qualifiers in the new type.
|
/* Merge the old type qualifiers in the new type.
|
||||||
|
|
||||||
Each old variant has qualifiers for specific reasons, and the new
|
Each old variant has qualifiers for specific reasons, and the new
|
||||||
designated type as well. Each set of qualifiers represents useful
|
designated type as well. Each set of qualifiers represents useful
|
||||||
information grabbed at some point, and merging the two simply unifies
|
information grabbed at some point, and merging the two simply unifies
|
||||||
these inputs into the final type description.
|
these inputs into the final type description.
|
||||||
|
|
||||||
Consider for instance a volatile type frozen after an access to constant
|
Consider for instance a volatile type frozen after an access to constant
|
||||||
type designating it. After the designated type freeze, we get here with a
|
type designating it; after the designated type's freeze, we get here with
|
||||||
volatile new_type and a dummy old_type with a readonly variant, created
|
a volatile NEW_TYPE and a dummy OLD_TYPE with a readonly variant, created
|
||||||
when the access type was processed. We shall make a volatile and readonly
|
when the access type was processed. We will make a volatile and readonly
|
||||||
designated type, because that's what it really is.
|
designated type, because that's what it really is.
|
||||||
|
|
||||||
We might also get here for a non-dummy old_type variant with different
|
We might also get here for a non-dummy OLD_TYPE variant with different
|
||||||
qualifiers than the new_type ones, for instance in some cases of pointers
|
qualifiers than those of NEW_TYPE, for instance in some cases of pointers
|
||||||
to private record type elaboration (see the comments around the call to
|
to private record type elaboration (see the comments around the call to
|
||||||
this routine from gnat_to_gnu_entity/E_Access_Type). We have to merge the
|
this routine in gnat_to_gnu_entity <E_Access_Type>). We have to merge
|
||||||
qualifiers in those cases too, to avoid accidentally discarding the
|
the qualifiers in those cases too, to avoid accidentally discarding the
|
||||||
initial set, and will often end up with old_type == new_type then. */
|
initial set, and will often end up with OLD_TYPE == NEW_TYPE then. */
|
||||||
new_type = build_qualified_type (new_type,
|
new_type
|
||||||
TYPE_QUALS (old_type)
|
= build_qualified_type (new_type,
|
||||||
| TYPE_QUALS (new_type));
|
TYPE_QUALS (old_type) | TYPE_QUALS (new_type));
|
||||||
|
|
||||||
/* If the new type and the old one are identical, there is nothing to
|
/* If old type and new type are identical, there is nothing to do. */
|
||||||
update. */
|
|
||||||
if (old_type == new_type)
|
if (old_type == new_type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3805,10 +3804,10 @@ update_pointer_to (tree old_type, tree new_type)
|
||||||
TREE_TYPE (ref1) = new_type;
|
TREE_TYPE (ref1) = new_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now deal with the unconstrained array case. In this case the "pointer"
|
/* Now deal with the unconstrained array case. In this case the "pointer"
|
||||||
is actually a RECORD_TYPE where both fields are pointers to dummy nodes.
|
is actually a RECORD_TYPE where both fields are pointers to dummy nodes.
|
||||||
Turn them into pointers to the correct types using update_pointer_to. */
|
Turn them into pointers to the correct types using update_pointer_to. */
|
||||||
else if (TREE_CODE (ptr) != RECORD_TYPE || !TYPE_IS_FAT_POINTER_P (ptr))
|
else if (!TYPE_FAT_POINTER_P (ptr))
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -3826,26 +3825,25 @@ update_pointer_to (tree old_type, tree new_type)
|
||||||
TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_ptr)))));
|
TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_ptr)))));
|
||||||
|
|
||||||
/* The references to the template bounds present in the array type
|
/* The references to the template bounds present in the array type
|
||||||
are made through a PLACEHOLDER_EXPR of type new_ptr. Since we
|
are made through a PLACEHOLDER_EXPR of type NEW_PTR. Since we
|
||||||
are updating ptr to make it a full replacement for new_ptr as
|
are updating PTR to make it a full replacement for NEW_PTR as
|
||||||
pointer to new_type, we must rework the PLACEHOLDER_EXPR so as
|
pointer to NEW_TYPE, we must rework the PLACEHOLDER_EXPR so as
|
||||||
to make it of type ptr. */
|
to make it of type PTR. */
|
||||||
new_ref = build3 (COMPONENT_REF, TREE_TYPE (bounds_field),
|
new_ref = build3 (COMPONENT_REF, TREE_TYPE (bounds_field),
|
||||||
build0 (PLACEHOLDER_EXPR, ptr),
|
build0 (PLACEHOLDER_EXPR, ptr),
|
||||||
bounds_field, NULL_TREE);
|
bounds_field, NULL_TREE);
|
||||||
|
|
||||||
/* Create the new array for the new PLACEHOLDER_EXPR and make
|
/* Create the new array for the new PLACEHOLDER_EXPR and make pointers
|
||||||
pointers to the dummy array point to it.
|
to the dummy array point to it.
|
||||||
|
|
||||||
??? This is now the only use of substitute_in_type,
|
??? This is now the only use of substitute_in_type, which is a very
|
||||||
which is a very "heavy" routine to do this, so it
|
"heavy" routine to do this, it should be replaced at some point. */
|
||||||
should be replaced at some point. */
|
|
||||||
update_pointer_to
|
update_pointer_to
|
||||||
(TREE_TYPE (TREE_TYPE (array_field)),
|
(TREE_TYPE (TREE_TYPE (array_field)),
|
||||||
substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))),
|
substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))),
|
||||||
TREE_CHAIN (TYPE_FIELDS (new_ptr)), new_ref));
|
TREE_CHAIN (TYPE_FIELDS (new_ptr)), new_ref));
|
||||||
|
|
||||||
/* Make ptr the pointer to new_type. */
|
/* Make PTR the pointer to NEW_TYPE. */
|
||||||
TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type)
|
TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type)
|
||||||
= TREE_TYPE (new_type) = ptr;
|
= TREE_TYPE (new_type) = ptr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue