Commit f08863f9 by Eric Botcazou Committed by Eric Botcazou

decl.c (gnat_to_gnu_entity): Fix comment.

	* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Class_Wide_Type>: Fix
	comment.
	* gcc-interface/trans.c (process_freeze_entity): Use local copy of
	Ekind.  Return early for class-wide types.  Do not compute initializer
	unless necessary.  Reuse the tree for an associated class-wide type
	only if processing its root type.

From-SVN: r158295
parent 3f529c2c
2010-04-14 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Class_Wide_Type>: Fix
comment.
* gcc-interface/trans.c (process_freeze_entity): Use local copy of
Ekind. Return early for class-wide types. Do not compute initializer
unless necessary. Reuse the tree for an associated class-wide type
only if processing its root type.
2010-04-13 Duncan Sands <baldrick@free.fr> 2010-04-13 Duncan Sands <baldrick@free.fr>
* gcc-interface/misc.c (gnat_eh_type_covers): Remove. * gcc-interface/misc.c (gnat_eh_type_covers): Remove.
......
...@@ -4343,9 +4343,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -4343,9 +4343,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
break; break;
} }
/* Simple class_wide types are always viewed as their root_type
by Gigi unless an Equivalent_Type is specified. */
case E_Class_Wide_Type: case E_Class_Wide_Type:
/* Class-wide types are always transformed into their root type. */
gnu_decl = gnat_to_gnu_entity (gnat_equiv_type, NULL_TREE, 0); gnu_decl = gnat_to_gnu_entity (gnat_equiv_type, NULL_TREE, 0);
maybe_present = true; maybe_present = true;
break; break;
......
...@@ -6073,92 +6073,85 @@ elaborate_all_entities (Node_Id gnat_node) ...@@ -6073,92 +6073,85 @@ elaborate_all_entities (Node_Id gnat_node)
elaborate_all_entities (Library_Unit (gnat_node)); elaborate_all_entities (Library_Unit (gnat_node));
} }
/* Do the processing of N_Freeze_Entity, GNAT_NODE. */ /* Do the processing of GNAT_NODE, an N_Freeze_Entity. */
static void static void
process_freeze_entity (Node_Id gnat_node) process_freeze_entity (Node_Id gnat_node)
{ {
Entity_Id gnat_entity = Entity (gnat_node); const Entity_Id gnat_entity = Entity (gnat_node);
tree gnu_old; const Entity_Kind kind = Ekind (gnat_entity);
tree gnu_new; tree gnu_old, gnu_new;
tree gnu_init
= (Nkind (Declaration_Node (gnat_entity)) == N_Object_Declaration
&& present_gnu_tree (Declaration_Node (gnat_entity)))
? get_gnu_tree (Declaration_Node (gnat_entity)) : NULL_TREE;
/* If this is a package, need to generate code for the package. */ /* If this is a package, we need to generate code for the package. */
if (Ekind (gnat_entity) == E_Package) if (kind == E_Package)
{ {
insert_code_for insert_code_for
(Parent (Corresponding_Body (Parent (Corresponding_Body
(Parent (Declaration_Node (gnat_entity))))); (Parent (Declaration_Node (gnat_entity)))));
return; return;
} }
/* Check for old definition after the above call. This Freeze_Node /* Don't do anything for class-wide types as they are always transformed
might be for one its Itypes. */ into their root type. */
if (kind == E_Class_Wide_Type)
return;
/* Check for an old definition. This freeze node might be for an Itype. */
gnu_old gnu_old
= present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : 0; = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : NULL_TREE;
/* If this entity has an Address representation clause, GNU_OLD is the /* If this entity has an address representation clause, GNU_OLD is the
address, so discard it here. */ address, so discard it here. */
if (Present (Address_Clause (gnat_entity))) if (Present (Address_Clause (gnat_entity)))
gnu_old = 0; gnu_old = NULL_TREE;
/* Don't do anything for class-wide types as they are always transformed
into their root type. */
if (Ekind (gnat_entity) == E_Class_Wide_Type)
return;
/* Don't do anything for subprograms that may have been elaborated before /* Don't do anything for subprograms that may have been elaborated before
their freeze nodes. This can happen, for example because of an inner call their freeze nodes. This can happen, for example, because of an inner
in an instance body, or a previous compilation of a spec for inlining call in an instance body or because of previous compilation of a spec
purposes. */ for inlining purposes. */
if (gnu_old if (gnu_old
&& ((TREE_CODE (gnu_old) == FUNCTION_DECL && ((TREE_CODE (gnu_old) == FUNCTION_DECL
&& (Ekind (gnat_entity) == E_Function && (kind == E_Function || kind == E_Procedure))
|| Ekind (gnat_entity) == E_Procedure)) || (TREE_CODE (TREE_TYPE (gnu_old)) == FUNCTION_TYPE
|| (gnu_old && kind == E_Subprogram_Type)))
&& TREE_CODE (TREE_TYPE (gnu_old)) == FUNCTION_TYPE
&& Ekind (gnat_entity) == E_Subprogram_Type)))
return; return;
/* If we have a non-dummy type old tree, we have nothing to do, except /* If we have a non-dummy type old tree, we have nothing to do, except
aborting if this is the public view of a private type whose full view was aborting if this is the public view of a private type whose full view was
not delayed, as this node was never delayed as it should have been. We not delayed, as this node was never delayed as it should have been. We
let this happen for concurrent types and their Corresponding_Record_Type, let this happen for concurrent types and their Corresponding_Record_Type,
however, because each might legitimately be elaborated before it's own however, because each might legitimately be elaborated before its own
freeze node, e.g. while processing the other. */ freeze node, e.g. while processing the other. */
if (gnu_old if (gnu_old
&& !(TREE_CODE (gnu_old) == TYPE_DECL && !(TREE_CODE (gnu_old) == TYPE_DECL
&& TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old)))) && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old))))
{ {
gcc_assert ((IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind) gcc_assert ((IN (kind, Incomplete_Or_Private_Kind)
&& Present (Full_View (gnat_entity)) && Present (Full_View (gnat_entity))
&& No (Freeze_Node (Full_View (gnat_entity)))) && No (Freeze_Node (Full_View (gnat_entity))))
|| Is_Concurrent_Type (gnat_entity) || Is_Concurrent_Type (gnat_entity)
|| (IN (Ekind (gnat_entity), Record_Kind) || (IN (kind, Record_Kind)
&& Is_Concurrent_Record_Type (gnat_entity))); && Is_Concurrent_Record_Type (gnat_entity)));
return; return;
} }
/* Reset the saved tree, if any, and elaborate the object or type for real. /* Reset the saved tree, if any, and elaborate the object or type for real.
If there is a full declaration, elaborate it and copy the type to If there is a full view, elaborate it and use the result. And, if this
GNAT_ENTITY. Likewise if this is the record subtype corresponding to is the root type of a class-wide type, reuse it for the latter. */
a class wide type or subtype. */
if (gnu_old) if (gnu_old)
{ {
save_gnu_tree (gnat_entity, NULL_TREE, false); save_gnu_tree (gnat_entity, NULL_TREE, false);
if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind) if (IN (kind, Incomplete_Or_Private_Kind)
&& Present (Full_View (gnat_entity)) && Present (Full_View (gnat_entity))
&& present_gnu_tree (Full_View (gnat_entity))) && present_gnu_tree (Full_View (gnat_entity)))
save_gnu_tree (Full_View (gnat_entity), NULL_TREE, false); save_gnu_tree (Full_View (gnat_entity), NULL_TREE, false);
if (Present (Class_Wide_Type (gnat_entity)) if (IN (kind, Type_Kind)
&& Class_Wide_Type (gnat_entity) != gnat_entity) && Present (Class_Wide_Type (gnat_entity))
&& Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
save_gnu_tree (Class_Wide_Type (gnat_entity), NULL_TREE, false); save_gnu_tree (Class_Wide_Type (gnat_entity), NULL_TREE, false);
} }
if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind) if (IN (kind, Incomplete_Or_Private_Kind)
&& Present (Full_View (gnat_entity))) && Present (Full_View (gnat_entity)))
{ {
gnu_new = gnat_to_gnu_entity (Full_View (gnat_entity), NULL_TREE, 1); gnu_new = gnat_to_gnu_entity (Full_View (gnat_entity), NULL_TREE, 1);
...@@ -6174,16 +6167,25 @@ process_freeze_entity (Node_Id gnat_node) ...@@ -6174,16 +6167,25 @@ process_freeze_entity (Node_Id gnat_node)
Set_RM_Size (gnat_entity, RM_Size (Full_View (gnat_entity))); Set_RM_Size (gnat_entity, RM_Size (Full_View (gnat_entity)));
/* The above call may have defined this entity (the simplest example /* The above call may have defined this entity (the simplest example
of this is when we have a private enumeral type since the bounds of this is when we have a private enumeral type since the bounds
will have the public view. */ will have the public view). */
if (!present_gnu_tree (gnat_entity)) if (!present_gnu_tree (gnat_entity))
save_gnu_tree (gnat_entity, gnu_new, false); save_gnu_tree (gnat_entity, gnu_new, false);
if (Present (Class_Wide_Type (gnat_entity))
&& Class_Wide_Type (gnat_entity) != gnat_entity)
save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);
} }
else else
gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, 1); {
tree gnu_init
= (Nkind (Declaration_Node (gnat_entity)) == N_Object_Declaration
&& present_gnu_tree (Declaration_Node (gnat_entity)))
? get_gnu_tree (Declaration_Node (gnat_entity)) : NULL_TREE;
gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, 1);
}
if (IN (kind, Type_Kind)
&& Present (Class_Wide_Type (gnat_entity))
&& Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);
/* If we've made any pointers to the old version of this type, we /* If we've made any pointers to the old version of this type, we
have to update them. */ have to update them. */
......
2010-04-14 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/class_wide.adb: Rename into...
* gnat.dg/class_wide1.adb: ...this.
* gnat.dg/class_wide2.ad[sb]: New test.
2010-04-14 Tobias Burnus <burnus@net-b.de> 2010-04-14 Tobias Burnus <burnus@net-b.de>
PR fortran/18918 PR fortran/18918
......
-- { dg-do compile } -- { dg-do compile }
procedure class_wide is procedure Class_Wide1 is
package P is package P is
type T is tagged null record; type T is tagged null record;
procedure P1 (x : T'Class); procedure P1 (x : T'Class);
......
-- { dg-do compile }
package body Class_Wide2 is
procedure Initialize is
Var_Acc : Class_Acc := new Grand_Child;
Var : Grand_Child'Class := Grand_Child'Class (Var_Acc.all); -- { dg-bogus "already constrained" "" { xfail *-*-* } }
begin
Var := Grand_Child'Class (Var_Acc.all);
end Initialize;
end Class_Wide2;
package Class_Wide2 is
type Root_1 (V : Integer) is tagged record
null;
end record;
type Child is new Root_1 (1) with null record;
type Class_Acc is access all Child'Class;
type Grand_Child is new Child with record
null;
end record;
procedure Initialize;
end Class_Wide2;
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