Commit 5b7dd52d by Javier Miranda Committed by Arnaud Charlet

exp_disp.adb (Make_DT, [...]): Avoid generating dispatch tables of locally…

exp_disp.adb (Make_DT, [...]): Avoid generating dispatch tables of locally defined tagged types statically.

2008-05-20  Javier Miranda  <miranda@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>

	* exp_disp.adb (Make_DT, Make_Secondary_DT, Make_Tags): Avoid
	generating dispatch tables of locally defined tagged types statically.
	Remove implicit if-statement that is no longer required.
	(Expand_Dispatching_Call): If this is a call to an instance of the
	generic dispatching constructor, the type of the first argument may be
	a subtype of Tag, so always use the base type to recognize this case.

From-SVN: r135625
parent d4817e3f
...@@ -335,8 +335,9 @@ package body Exp_Disp is ...@@ -335,8 +335,9 @@ package body Exp_Disp is
Loc : constant Source_Ptr := Sloc (Call_Node); Loc : constant Source_Ptr := Sloc (Call_Node);
Call_Typ : constant Entity_Id := Etype (Call_Node); Call_Typ : constant Entity_Id := Etype (Call_Node);
Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node); Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
Param_List : constant List_Id := Parameter_Associations (Call_Node); Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
Param_List : constant List_Id := Parameter_Associations (Call_Node);
Subp : Entity_Id; Subp : Entity_Id;
CW_Typ : Entity_Id; CW_Typ : Entity_Id;
...@@ -416,9 +417,9 @@ package body Exp_Disp is ...@@ -416,9 +417,9 @@ package body Exp_Disp is
-- This capability of dispatching directly by tag is also needed by the -- This capability of dispatching directly by tag is also needed by the
-- implementation of AI-260 (for the generic dispatching constructors). -- implementation of AI-260 (for the generic dispatching constructors).
if Etype (Ctrl_Arg) = RTE (RE_Tag) if Ctrl_Typ = RTE (RE_Tag)
or else (RTE_Available (RE_Interface_Tag) or else (RTE_Available (RE_Interface_Tag)
and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag)) and then Ctrl_Typ = RTE (RE_Interface_Tag))
then then
CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp)); CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
...@@ -427,11 +428,11 @@ package body Exp_Disp is ...@@ -427,11 +428,11 @@ package body Exp_Disp is
-- there are cases where the controlling type is resolved to a specific -- there are cases where the controlling type is resolved to a specific
-- type (such as for designated types of arguments such as CW'Access). -- type (such as for designated types of arguments such as CW'Access).
elsif Is_Access_Type (Etype (Ctrl_Arg)) then elsif Is_Access_Type (Ctrl_Typ) then
CW_Typ := Class_Wide_Type (Designated_Type (Etype (Ctrl_Arg))); CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
else else
CW_Typ := Class_Wide_Type (Etype (Ctrl_Arg)); CW_Typ := Class_Wide_Type (Ctrl_Typ);
end if; end if;
Typ := Root_Type (CW_Typ); Typ := Root_Type (CW_Typ);
...@@ -619,9 +620,9 @@ package body Exp_Disp is ...@@ -619,9 +620,9 @@ package body Exp_Disp is
-- interface class-wide type then use it directly. Otherwise, the tag -- interface class-wide type then use it directly. Otherwise, the tag
-- must be extracted from the controlling object. -- must be extracted from the controlling object.
if Etype (Ctrl_Arg) = RTE (RE_Tag) if Ctrl_Typ = RTE (RE_Tag)
or else (RTE_Available (RE_Interface_Tag) or else (RTE_Available (RE_Interface_Tag)
and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag)) and then Ctrl_Typ = RTE (RE_Interface_Tag))
then then
Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg); Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
...@@ -643,8 +644,8 @@ package body Exp_Disp is ...@@ -643,8 +644,8 @@ package body Exp_Disp is
-- Ada 2005 (AI-251): Abstract interface class-wide type -- Ada 2005 (AI-251): Abstract interface class-wide type
elsif Is_Interface (Etype (Ctrl_Arg)) elsif Is_Interface (Ctrl_Typ)
and then Is_Class_Wide_Type (Etype (Ctrl_Arg)) and then Is_Class_Wide_Type (Ctrl_Typ)
then then
Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg); Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
...@@ -3175,10 +3176,7 @@ package body Exp_Disp is ...@@ -3175,10 +3176,7 @@ package body Exp_Disp is
if not Building_Static_DT (Typ) then if not Building_Static_DT (Typ) then
Set_Ekind (Predef_Prims, E_Variable); Set_Ekind (Predef_Prims, E_Variable);
Set_Is_Statically_Allocated (Predef_Prims);
Set_Ekind (Iface_DT, E_Variable); Set_Ekind (Iface_DT, E_Variable);
Set_Is_Statically_Allocated (Iface_DT);
-- Statically allocated dispatch tables and related entities are -- Statically allocated dispatch tables and related entities are
-- constants. -- constants.
...@@ -3676,9 +3674,9 @@ package body Exp_Disp is ...@@ -3676,9 +3674,9 @@ package body Exp_Disp is
-- Local variables -- Local variables
Elab_Code : constant List_Id := New_List; Elab_Code : constant List_Id := New_List;
Result : constant List_Id := New_List; Result : constant List_Id := New_List;
Tname : constant Name_Id := Chars (Typ); Tname : constant Name_Id := Chars (Typ);
AI : Elmt_Id; AI : Elmt_Id;
AI_Tag_Elmt : Elmt_Id; AI_Tag_Elmt : Elmt_Id;
AI_Tag_Comp : Elmt_Id; AI_Tag_Comp : Elmt_Id;
...@@ -3689,11 +3687,9 @@ package body Exp_Disp is ...@@ -3689,11 +3687,9 @@ package body Exp_Disp is
I_Depth : Nat := 0; I_Depth : Nat := 0;
Iface_Table_Node : Node_Id; Iface_Table_Node : Node_Id;
Name_ITable : Name_Id; Name_ITable : Name_Id;
Name_No_Reg : Name_Id;
Nb_Predef_Prims : Nat := 0; Nb_Predef_Prims : Nat := 0;
Nb_Prim : Nat := 0; Nb_Prim : Nat := 0;
New_Node : Node_Id; New_Node : Node_Id;
No_Reg : Node_Id;
Num_Ifaces : Nat := 0; Num_Ifaces : Nat := 0;
Parent_Typ : Entity_Id; Parent_Typ : Entity_Id;
Prim : Entity_Id; Prim : Entity_Id;
...@@ -3903,26 +3899,11 @@ package body Exp_Disp is ...@@ -3903,26 +3899,11 @@ package body Exp_Disp is
DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ))); DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ))); Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
Set_Is_Statically_Allocated (DT); Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
Set_Is_Statically_Allocated (SSD); Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
Set_Is_Statically_Allocated (TSD); Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
Set_Is_Statically_Allocated (Predef_Prims); Set_Is_Statically_Allocated (Predef_Prims,
Is_Library_Level_Tagged_Type (Typ));
-- Generate code to define the boolean that controls registration, in
-- order to avoid multiple registrations for tagged types defined in
-- multiple-called scopes.
Name_No_Reg := New_External_Name (Tname, 'F', Suffix_Index => -1);
No_Reg := Make_Defining_Identifier (Loc, Name_No_Reg);
Set_Ekind (No_Reg, E_Variable);
Set_Is_Statically_Allocated (No_Reg);
Append_To (Result,
Make_Object_Declaration (Loc,
Defining_Identifier => No_Reg,
Object_Definition => New_Reference_To (Standard_Boolean, Loc),
Expression => New_Reference_To (Standard_True, Loc)));
-- In case of locally defined tagged type we declare the object -- In case of locally defined tagged type we declare the object
-- containing the dispatch table by means of a variable. Its -- containing the dispatch table by means of a variable. Its
...@@ -4544,7 +4525,8 @@ package body Exp_Disp is ...@@ -4544,7 +4525,8 @@ package body Exp_Disp is
Name_ITable := New_External_Name (Tname, 'I'); Name_ITable := New_External_Name (Tname, 'I');
ITable := Make_Defining_Identifier (Loc, Name_ITable); ITable := Make_Defining_Identifier (Loc, Name_ITable);
Set_Is_Statically_Allocated (ITable); Set_Is_Statically_Allocated (ITable,
Is_Library_Level_Tagged_Type (Typ));
-- The table of interfaces is not constant; its slots are -- The table of interfaces is not constant; its slots are
-- filled at run-time by the IP routine using attribute -- filled at run-time by the IP routine using attribute
...@@ -5385,19 +5367,10 @@ package body Exp_Disp is ...@@ -5385,19 +5367,10 @@ package body Exp_Disp is
-- Skip this action in the following cases: -- Skip this action in the following cases:
-- 1) if Register_Tag is not available. -- 1) if Register_Tag is not available.
-- 2) in No_Run_Time mode. -- 2) in No_Run_Time mode.
-- 3) if Typ is an abstract interface type (the secondary tags will -- 3) if Typ is not defined at the library level (this is required
-- be registered later in types implementing this interface type).
-- 4) if Typ is not defined at the library level (this is required
-- to avoid adding concurrency control to the hash table used -- to avoid adding concurrency control to the hash table used
-- by the run-time to register the tags). -- by the run-time to register the tags).
-- Generate:
-- if No_Reg then
-- [ Elab_Code ]
-- [ Register_Tag (Dt_Ptr); ]
-- No_Reg := False;
-- end if;
if not No_Run_Time_Mode if not No_Run_Time_Mode
and then Is_Library_Level_Entity (Typ) and then Is_Library_Level_Entity (Typ)
and then RTE_Available (RE_Register_Tag) and then RTE_Available (RE_Register_Tag)
...@@ -5409,15 +5382,9 @@ package body Exp_Disp is ...@@ -5409,15 +5382,9 @@ package body Exp_Disp is
New_List (New_Reference_To (DT_Ptr, Loc)))); New_List (New_Reference_To (DT_Ptr, Loc))));
end if; end if;
Append_To (Elab_Code, if not Is_Empty_List (Elab_Code) then
Make_Assignment_Statement (Loc, Append_List_To (Result, Elab_Code);
Name => New_Reference_To (No_Reg, Loc), end if;
Expression => New_Reference_To (Standard_False, Loc)));
Append_To (Result,
Make_Implicit_If_Statement (Typ,
Condition => New_Reference_To (No_Reg, Loc),
Then_Statements => Elab_Code));
-- Populate the two auxiliary tables used for dispatching -- Populate the two auxiliary tables used for dispatching
-- asynchronous, conditional and timed selects for synchronized -- asynchronous, conditional and timed selects for synchronized
...@@ -5838,7 +5805,8 @@ package body Exp_Disp is ...@@ -5838,7 +5805,8 @@ package body Exp_Disp is
Set_Ekind (Iface_DT_Ptr, E_Constant); Set_Ekind (Iface_DT_Ptr, E_Constant);
Set_Is_Tag (Iface_DT_Ptr); Set_Is_Tag (Iface_DT_Ptr);
Set_Has_Thunks (Iface_DT_Ptr); Set_Has_Thunks (Iface_DT_Ptr);
Set_Is_Statically_Allocated (Iface_DT_Ptr); Set_Is_Statically_Allocated (Iface_DT_Ptr,
Is_Library_Level_Tagged_Type (Typ));
Set_Is_True_Constant (Iface_DT_Ptr); Set_Is_True_Constant (Iface_DT_Ptr);
Set_Related_Type Set_Related_Type
(Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp))); (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
...@@ -5854,7 +5822,8 @@ package body Exp_Disp is ...@@ -5854,7 +5822,8 @@ package body Exp_Disp is
Set_Ekind (Iface_DT_Ptr, E_Constant); Set_Ekind (Iface_DT_Ptr, E_Constant);
Set_Is_Tag (Iface_DT_Ptr); Set_Is_Tag (Iface_DT_Ptr);
Set_Has_Thunks (Iface_DT_Ptr); Set_Has_Thunks (Iface_DT_Ptr);
Set_Is_Statically_Allocated (Iface_DT_Ptr); Set_Is_Statically_Allocated (Iface_DT_Ptr,
Is_Library_Level_Tagged_Type (Typ));
Set_Is_True_Constant (Iface_DT_Ptr); Set_Is_True_Constant (Iface_DT_Ptr);
Set_Related_Type Set_Related_Type
(Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp))); (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
...@@ -5869,7 +5838,8 @@ package body Exp_Disp is ...@@ -5869,7 +5838,8 @@ package body Exp_Disp is
Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag)); Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
Set_Ekind (Iface_DT_Ptr, E_Constant); Set_Ekind (Iface_DT_Ptr, E_Constant);
Set_Is_Tag (Iface_DT_Ptr); Set_Is_Tag (Iface_DT_Ptr);
Set_Is_Statically_Allocated (Iface_DT_Ptr); Set_Is_Statically_Allocated (Iface_DT_Ptr,
Is_Library_Level_Tagged_Type (Typ));
Set_Is_True_Constant (Iface_DT_Ptr); Set_Is_True_Constant (Iface_DT_Ptr);
Set_Related_Type Set_Related_Type
(Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp))); (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
...@@ -5883,7 +5853,8 @@ package body Exp_Disp is ...@@ -5883,7 +5853,8 @@ package body Exp_Disp is
Set_Etype (Iface_DT_Ptr, RTE (RE_Address)); Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
Set_Ekind (Iface_DT_Ptr, E_Constant); Set_Ekind (Iface_DT_Ptr, E_Constant);
Set_Is_Tag (Iface_DT_Ptr); Set_Is_Tag (Iface_DT_Ptr);
Set_Is_Statically_Allocated (Iface_DT_Ptr); Set_Is_Statically_Allocated (Iface_DT_Ptr,
Is_Library_Level_Tagged_Type (Typ));
Set_Is_True_Constant (Iface_DT_Ptr); Set_Is_True_Constant (Iface_DT_Ptr);
Set_Related_Type Set_Related_Type
(Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp))); (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
......
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