diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-04-08 06:47:55 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-04-08 06:47:55 +0000 |
commit | cc60bd167ed27492916b1cc0a316ea41a89a60d1 (patch) | |
tree | 1de7681091aaa76f00129510f3d08256cfb44e88 /gcc/ada/exp_disp.adb | |
parent | f970b6bf3b38e38b8b3218ad6a22879e12e46b42 (diff) | |
download | gcc-cc60bd167ed27492916b1cc0a316ea41a89a60d1.tar.gz |
2008-04-08 Javier Miranda <miranda@adacore.com>
Robert Dewar <dewar@adacore.com>
Ed Schonberg <schonberg@adacore.com>
* a-tags.adb (Register_Interface_Offset): New subprogram.
(Set_Dynamic_Offset_To_Top): New subprogram (see previous comment).
(To_Predef_Prims_Table_Ptr): Removed.
(Acc_Size): Removed.
(To_Acc_Size): Removed.
(Parent_Size): Modified to the call the subprogram returning the size of
the parent by means of the new TSD component Size_Func.
* a-tags.ads (Offset_To_Top_Ptr): New access type declaration.
(DT_Offset_To_Top_Offset): New constant value that is used to generate
code referencing the Offset_To_Top component of the dispatch table's
prologue.
(Prim_Ptr): New declaration of access to procedure. Used to avoid the
use of 'address to initialize dispatch table slots.
(Size_Func): New component of the TSD. Used by the run-time to call the
size primitive of the tagged type.
* checks.adb (Apply_Access_Check): Avoid check when accessing the
Offset_To_Top component of a dispatch table.
(Null_Exclusion_Static_Checks): If the non-null access type appears in a
deferred constant declaration. do not add a null expression, to prevent
spurious errors when full declaration is analyzed.
(Apply_Discriminant_Check): If both discriminant constraints share a
node which is not static but has no side effects, do not generate a
check for that discriminant.
(Generate_Index_Checks): Set Name_Req to true in call to duplicate
subexpr, since the prefix of an attribute is a name.
* checks.ads: Fix nit in comment.
* exp_ch3.ads, exp_ch3.adb (Freeze_Record_Type): Do not add the spec
and body of predefined primitives in case of CPP tagged type
derivations.
(Freeze_Type): Deal properly with no storage pool case
(Make_Predefined_Primitive_Specs): Generate specification of abstract
primitive Deep_Adjust if a nonlimited interface is derived from a
limited interface.
(Build_Dcheck_Functions): Create discriminant-checking functions only
for variants that have some component(s).
(Build_Slice_Assignment): In expanded code for slice assignment, handle
properly the case where the slice bounds extend to the last value of the
underlying representation.
(Get_Simple_Init_Val): New calling sequence, accomodate Invalid_Value
(Is_Variable_Size_Record): An array component has a static size if
index bounds are enumeration literals.
* exp_disp.adb (Make_DT): Use the first subtype to determine whether
an external tag has been specified for the type.
(Building_Static_DT): Add missing support for private types.
(Make_DT): Add declaration of Parent_Typ to ensure consistent access
to the entity associated with the parent of Typ. This is done to
avoid wrong access when the parent is a private type.
(Expand_Interface_Conversion): Improve error message when the
configurable runtime has no support for dynamic interface conversion.
(Expand_Interface_Thunk): Add missing support to interface types in
configurable runtime.
(Expand_Dispatching_Call): remove obsolete code.
(Make_DT): Replace occurrences of RE_Address by RE_Prim_Ptr, and
ensure that all subtypes and aggregates associated with dispatch
tables have the attribute Is_Dispatch_Table_Entity set to true.
(Register_Primitive): Rename one variable to improve code reading.
Replace occurrences of RE_Addres by RE_Prim_Ptr. Register copy o
of the pointer to the 'size primitive in the TSD.
* rtsfind.ads (RE_DT_Offset_To_Top_Offset): New entity.
(RE_Offset_To_Top_Ptr): New entity.
(RE_Register_Interface_Offset): New entity.
(RE_Set_Dynamic_Offset_To_Top): New entity.
(RE_Set_Offset_To_Top): Removed entity.
(RE_Prim_Ptr): New entity
(RE_Size_Func): New entity
(RE_Size_Ptr): New entity
(RTU_Id): Add Ada_Dispatching and Ada_Dispatching_EDF.
(Ada_Dispatching_Child): Define this new subrange.
(RE_Id): Add new required run-time calls (RE_Set_Deadline, RE_Clock,
RE_Time_Span, and RE_Time_Span_Zero).
(RE_Unit_Table): Add new required run-time calls
* rtsfind.adb (Get_Unit_Name): Add processing for Ada.Dispatching
children.
* exp_atag.ads, exp_atag.adb (Build_Offset_To_Top): New subprogram.
(Build_Set_Static_Offset_To_Top): New subprogram. Generates code that
initializes the Offset_To_Top component of a dispatch table.
(Build_Predef_Prims): Removed.
(Build_Get_Predefined_Prim_Op_Address): Replace call to Predef_Prims by
its actual code.
(Build_Set_Size_Function): New subprogram.
* exp_ch13.adb: Do not generate storage variable for storage_size zero
(Expand): Handle setting/restoring flag Inside_Freezing_Actions
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@134020 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_disp.adb')
-rw-r--r-- | gcc/ada/exp_disp.adb | 448 |
1 files changed, 301 insertions, 147 deletions
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb index c14c7348dea..b4efbf87cc7 100644 --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -99,7 +99,15 @@ package body Exp_Disp is ------------------------ function Building_Static_DT (Typ : Entity_Id) return Boolean is + Root_Typ : Entity_Id := Root_Type (Typ); + begin + -- Handle private types + + if Present (Full_View (Root_Typ)) then + Root_Typ := Full_View (Root_Typ); + end if; + return Static_Dispatch_Tables and then Is_Library_Level_Tagged_Type (Typ) @@ -107,7 +115,7 @@ package body Exp_Disp is -- build the dispatch tables because we must inherit primitives -- from the CPP side. - and then not Is_CPP_Class (Root_Type (Typ)); + and then not Is_CPP_Class (Root_Typ); end Building_Static_DT; ---------------------------------- @@ -548,7 +556,6 @@ package body Exp_Disp is Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node); Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node); Set_Etype (Subp_Typ, Res_Typ); - Init_Size_Align (Subp_Ptr_Typ); Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp)); -- Create a new list of parameters which is a copy of the old formal @@ -575,18 +582,11 @@ package body Exp_Disp is Set_Etype (New_Formal, Etype (Param)); end if; - if Is_Itype (Etype (New_Formal)) then - Extra := New_Copy (Etype (New_Formal)); - - if Ekind (Extra) = E_Record_Subtype - or else Ekind (Extra) = E_Class_Wide_Subtype - then - Set_Cloned_Subtype (Extra, Etype (New_Formal)); - end if; - - Set_Etype (New_Formal, Extra); - Set_Scope (Etype (New_Formal), Subp_Typ); - end if; + -- If the type of the formal is an itype, there was code here + -- introduced in 1998 in revision 1.46, to create a new itype + -- by copy. This seems useless, and in fact leads to semantic + -- errors when the itype is the completion of a type derived + -- from a private type. Extra := New_Formal; Next_Formal (Old_Formal); @@ -780,7 +780,7 @@ package body Exp_Disp is -- Give error if configurable run time and Displace not available if not RTE_Available (RE_Displace) then - Error_Msg_CRT ("abstract interface types", N); + Error_Msg_CRT ("dynamic interface conversion", N); return; end if; @@ -839,9 +839,7 @@ package body Exp_Disp is begin New_Itype := Create_Itype (E_Anonymous_Access_Type, N); - Set_Etype (New_Itype, New_Itype); - Init_Esize (New_Itype); - Init_Size_Align (New_Itype); + Set_Etype (New_Itype, New_Itype); Set_Directly_Designated_Type (New_Itype, Etyp); Rewrite (N, @@ -1205,6 +1203,8 @@ package body Exp_Disp is Decl_1 : Node_Id; Decl_2 : Node_Id; Formal : Node_Id; + New_Arg : Node_Id; + Offset_To_Top : Node_Id; Target : Entity_Id; Target_Formal : Entity_Id; @@ -1212,13 +1212,6 @@ package body Exp_Disp is Thunk_Id := Empty; Thunk_Code := Empty; - -- Give message if configurable run-time and Offset_To_Top unavailable - - if not RTE_Available (RE_Offset_To_Top) then - Error_Msg_CRT ("abstract interface types", Prim); - return; - end if; - -- Traverse the list of alias to find the final target Target := Prim; @@ -1284,6 +1277,20 @@ package body Exp_Disp is (Directly_Designated_Type (Etype (Target_Formal)), Loc))); + New_Arg := + Unchecked_Convert_To (RTE (RE_Address), + New_Reference_To (Defining_Identifier (Formal), Loc)); + + if not RTE_Available (RE_Offset_To_Top) then + Offset_To_Top := + Build_Offset_To_Top (Loc, New_Arg); + else + Offset_To_Top := + Make_Function_Call (Loc, + Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc), + Parameter_Associations => New_List (New_Arg)); + end if; + Decl_1 := Make_Object_Declaration (Loc, Defining_Identifier => @@ -1299,14 +1306,7 @@ package body Exp_Disp is (RTE (RE_Storage_Offset), New_Reference_To (Defining_Identifier (Formal), Loc)), Right_Opnd => - Make_Function_Call (Loc, - Name => - New_Reference_To (RTE (RE_Offset_To_Top), Loc), - Parameter_Associations => New_List ( - Unchecked_Convert_To - (RTE (RE_Address), - New_Reference_To - (Defining_Identifier (Formal), Loc)))))); + Offset_To_Top)); Append_To (Decl, Decl_2); Append_To (Decl, Decl_1); @@ -1326,6 +1326,23 @@ package body Exp_Disp is -- - Offset_To_Top (Formal'Address) -- S2 : Addr_Ptr := Addr_Ptr!(S1) + New_Arg := + Make_Attribute_Reference (Loc, + Prefix => + New_Reference_To (Defining_Identifier (Formal), Loc), + Attribute_Name => + Name_Address); + + if not RTE_Available (RE_Offset_To_Top) then + Offset_To_Top := + Build_Offset_To_Top (Loc, New_Arg); + else + Offset_To_Top := + Make_Function_Call (Loc, + Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc), + Parameter_Associations => New_List (New_Arg)); + end if; + Decl_1 := Make_Object_Declaration (Loc, Defining_Identifier => @@ -1344,15 +1361,7 @@ package body Exp_Disp is (Defining_Identifier (Formal), Loc), Attribute_Name => Name_Address)), Right_Opnd => - Make_Function_Call (Loc, - Name => - New_Reference_To (RTE (RE_Offset_To_Top), Loc), - Parameter_Associations => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Reference_To - (Defining_Identifier (Formal), Loc), - Attribute_Name => Name_Address))))); + Offset_To_Top)); Decl_2 := Make_Object_Declaration (Loc, @@ -3042,6 +3051,10 @@ package body Exp_Disp is (Expression (Parent (RTE (RE_Max_Predef_Prims))))); + DT_Decl : constant Elist_Id := New_Elmt_List; + DT_Aggr : constant Elist_Id := New_Elmt_List; + -- Entities marked with attribute Is_Dispatch_Table_Entity + procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id); -- Verify that all non-tagged types in the profile of a subprogram -- are frozen at the point the subprogram is frozen. This enforces @@ -3229,6 +3242,7 @@ package body Exp_Disp is declare Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id; + Decl : Node_Id; Thunk_Id : Entity_Id; Thunk_Code : Node_Id; @@ -3272,27 +3286,43 @@ package body Exp_Disp is for J in Prim_Table'Range loop if Present (Prim_Table (J)) then New_Node := - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Prim_Table (J), Loc), Attribute_Name => Name_Unrestricted_Access)); else - New_Node := - New_Reference_To (RTE (RE_Null_Address), Loc); + New_Node := Make_Null (Loc); end if; Append_To (Prim_Ops_Aggr_List, New_Node); end loop; + New_Node := + Make_Aggregate (Loc, + Expressions => Prim_Ops_Aggr_List); + + -- Remember aggregates initializing dispatch tables + + Append_Elmt (New_Node, DT_Aggr); + + Decl := + Make_Subtype_Declaration (Loc, + Defining_Identifier => + Make_Defining_Identifier (Loc, + New_Internal_Name ('S')), + Subtype_Indication => + New_Reference_To (RTE (RE_Address_Array), Loc)); + + Append_To (Result, Decl); + Append_To (Result, Make_Object_Declaration (Loc, Defining_Identifier => Predef_Prims, Constant_Present => Building_Static_DT (Typ), Aliased_Present => True, - Object_Definition => - New_Reference_To (RTE (RE_Address_Array), Loc), - Expression => Make_Aggregate (Loc, - Expressions => Prim_Ops_Aggr_List))); + Object_Definition => New_Reference_To + (Defining_Identifier (Decl), Loc), + Expression => New_Node)); Append_To (Result, Make_Attribute_Definition_Clause (Loc, @@ -3492,15 +3522,13 @@ package body Exp_Disp is Prim_Ops_Aggr_List := New_List; if Empty_DT then - Append_To (Prim_Ops_Aggr_List, - New_Reference_To (RTE (RE_Null_Address), Loc)); + Append_To (Prim_Ops_Aggr_List, Make_Null (Loc)); elsif Is_Abstract_Type (Typ) or else not Building_Static_DT (Typ) then for J in 1 .. Nb_Prim loop - Append_To (Prim_Ops_Aggr_List, - New_Reference_To (RTE (RE_Null_Address), Loc)); + Append_To (Prim_Ops_Aggr_List, Make_Null (Loc)); end loop; else @@ -3556,13 +3584,12 @@ package body Exp_Disp is for J in Prim_Table'Range loop if Present (Prim_Table (J)) then New_Node := - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Prim_Table (J), Loc), Attribute_Name => Name_Unrestricted_Access)); else - New_Node := - New_Reference_To (RTE (RE_Null_Address), Loc); + New_Node := Make_Null (Loc); end if; Append_To (Prim_Ops_Aggr_List, New_Node); @@ -3570,9 +3597,15 @@ package body Exp_Disp is end; end if; - Append_To (DT_Aggr_List, + New_Node := Make_Aggregate (Loc, - Expressions => Prim_Ops_Aggr_List)); + Expressions => Prim_Ops_Aggr_List); + + Append_To (DT_Aggr_List, New_Node); + + -- Remember aggregates initializing dispatch tables + + Append_Elmt (New_Node, DT_Aggr); Append_To (Result, Make_Object_Declaration (Loc, @@ -3635,14 +3668,10 @@ package body Exp_Disp is (RTE_Record_Component (RE_Predef_Prims), Loc)), Attribute_Name => Name_Address))); - -- Mark entities containing library level static dispatch tables. - -- This attribute is later propagated to all the access-to-subprogram - -- itypes generated to fill the dispatch table slots (see exp_attr). + -- Remember entities containing dispatch tables - if Building_Static_DT (Typ) then - Set_Is_Static_Dispatch_Table_Entity (Predef_Prims); - Set_Is_Static_Dispatch_Table_Entity (Iface_DT); - end if; + Append_Elmt (Predef_Prims, DT_Decl); + Append_Elmt (Iface_DT, DT_Decl); end Make_Secondary_DT; -- Local variables @@ -3666,6 +3695,7 @@ package body Exp_Disp is New_Node : Node_Id; No_Reg : Node_Id; Num_Ifaces : Nat := 0; + Parent_Typ : Entity_Id; Prim : Entity_Id; Prim_Elmt : Elmt_Id; Prim_Ops_Aggr_List : List_Id; @@ -3761,6 +3791,14 @@ package body Exp_Disp is end if; end if; + -- Initialize Parent_Typ handling private types + + Parent_Typ := Etype (Typ); + + if Present (Full_View (Parent_Typ)) then + Parent_Typ := Full_View (Parent_Typ); + end if; + -- Ensure that all the primitives are frozen. This is only required when -- building static dispatch tables --- the primitives must be frozen to -- be referenced (otherwise we have problems with the backend). It is @@ -4045,6 +4083,7 @@ package body Exp_Disp is -- HT_Link => HT_Link'Address, -- Transportable => <<boolean-value>>, -- RC_Offset => <<integer-value>>, + -- [ Size_Func => Size_Prim'Access ] -- [ Interfaces_Table => <<access-value>> ] -- [ SSD => SSD_Table'Address ] -- Tags_Table => (0 => null, @@ -4204,23 +4243,28 @@ package body Exp_Disp is -- External tag of a library-level tagged type: Check for a definition -- of External_Tag. The clause is considered only if it applies to this -- specific tagged type, as opposed to one of its ancestors. + -- If the type is an unconstrained type extension, we are building the + -- dispatch table of its anonymous base type, so the external tag, if + -- any was specified, must be retrieved from the first subtype. else declare - Def : constant Node_Id := Get_Attribute_Definition_Clause (Typ, - Attribute_External_Tag); + Def : constant Node_Id := Get_Attribute_Definition_Clause + (First_Subtype (Typ), + Attribute_External_Tag); + Old_Val : String_Id; New_Val : String_Id; E : Entity_Id; begin if not Present (Def) - or else Entity (Name (Def)) /= Typ + or else Entity (Name (Def)) /= First_Subtype (Typ) then New_Node := Unchecked_Convert_To (RTE (RE_Cstring_Ptr), Make_Attribute_Reference (Loc, - Prefix => New_Reference_To (Exname, Loc), + Prefix => New_Reference_To (Exname, Loc), Attribute_Name => Name_Address)); else Old_Val := Strval (Expr_Value_S (Expression (Def))); @@ -4320,15 +4364,8 @@ package body Exp_Disp is declare RC_Offset_Node : Node_Id; - Parent_Typ : Entity_Id; begin - if Present (Full_View (Etype (Typ))) then - Parent_Typ := Full_View (Etype (Typ)); - else - Parent_Typ := Etype (Typ); - end if; - if not Has_Controlled_Component (Typ) then RC_Offset_Node := Make_Integer_Literal (Loc, 0); @@ -4368,6 +4405,52 @@ package body Exp_Disp is Append_To (TSD_Aggr_List, RC_Offset_Node); end; + -- Size_Func + + if RTE_Record_Component_Available (RE_Size_Func) then + if not Building_Static_DT (Typ) + or else Is_Interface (Typ) + then + Append_To (TSD_Aggr_List, + Unchecked_Convert_To (RTE (RE_Size_Ptr), + New_Reference_To (RTE (RE_Null_Address), Loc))); + + else + declare + Prim_Elmt : Elmt_Id; + Prim : Entity_Id; + + begin + Prim_Elmt := First_Elmt (Primitive_Operations (Typ)); + while Present (Prim_Elmt) loop + Prim := Node (Prim_Elmt); + + if Chars (Prim) = Name_uSize then + while Present (Alias (Prim)) loop + Prim := Alias (Prim); + end loop; + + if Is_Abstract_Subprogram (Prim) then + Append_To (TSD_Aggr_List, + Unchecked_Convert_To (RTE (RE_Size_Ptr), + New_Reference_To (RTE (RE_Null_Address), Loc))); + else + Append_To (TSD_Aggr_List, + Unchecked_Convert_To (RTE (RE_Size_Ptr), + Make_Attribute_Reference (Loc, + Prefix => New_Reference_To (Prim, Loc), + Attribute_Name => Name_Unrestricted_Access))); + end if; + + exit; + end if; + + Next_Elmt (Prim_Elmt); + end loop; + end; + end if; + end if; + -- Interfaces_Table (required for AI-405) if RTE_Record_Component_Available (RE_Interfaces_Table) then @@ -4561,34 +4644,34 @@ package body Exp_Disp is -- Initialize the table of ancestor tags. In case of interface types -- this table is not needed. - declare - Current_Typ : Entity_Id; - Parent_Typ : Entity_Id; - Pos : Nat; + TSD_Tags_List := New_List; - begin - TSD_Tags_List := New_List; + -- If we are not statically allocating the dispatch table then we must + -- fill position 0 with null because we still have not generated the + -- tag of Typ. - -- If we are not statically allocating the dispatch table then we - -- must fill position 0 with null because we still have not - -- generated the tag of Typ. + if not Building_Static_DT (Typ) + or else Is_Interface (Typ) + then + Append_To (TSD_Tags_List, + Unchecked_Convert_To (RTE (RE_Tag), + New_Reference_To (RTE (RE_Null_Address), Loc))); - if not Building_Static_DT (Typ) - or else Is_Interface (Typ) - then - Append_To (TSD_Tags_List, - Unchecked_Convert_To (RTE (RE_Tag), - New_Reference_To (RTE (RE_Null_Address), Loc))); + -- Otherwise we can safely reference the tag - -- Otherwise we can safely reference the tag + else + Append_To (TSD_Tags_List, + New_Reference_To (DT_Ptr, Loc)); + end if; - else - Append_To (TSD_Tags_List, - New_Reference_To (DT_Ptr, Loc)); - end if; + -- Fill the rest of the table with the tags of the ancestors - -- Fill the rest of the table with the tags of the ancestors + declare + Current_Typ : Entity_Id; + Parent_Typ : Entity_Id; + Pos : Nat; + begin Pos := 1; Current_Typ := Typ; @@ -4775,6 +4858,7 @@ package body Exp_Disp is declare Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id; + Decl : Node_Id; E : Entity_Id; begin @@ -4808,26 +4892,43 @@ package body Exp_Disp is for J in Prim_Table'Range loop if Present (Prim_Table (J)) then New_Node := - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Prim_Table (J), Loc), Attribute_Name => Name_Unrestricted_Access)); else - New_Node := New_Reference_To (RTE (RE_Null_Address), Loc); + New_Node := Make_Null (Loc); end if; Append_To (Prim_Ops_Aggr_List, New_Node); end loop; + New_Node := + Make_Aggregate (Loc, + Expressions => Prim_Ops_Aggr_List); + + Decl := + Make_Subtype_Declaration (Loc, + Defining_Identifier => + Make_Defining_Identifier (Loc, + New_Internal_Name ('S')), + Subtype_Indication => + New_Reference_To (RTE (RE_Address_Array), Loc)); + + Append_To (Result, Decl); + Append_To (Result, Make_Object_Declaration (Loc, Defining_Identifier => Predef_Prims, Aliased_Present => True, Constant_Present => Building_Static_DT (Typ), - Object_Definition => - New_Reference_To (RTE (RE_Address_Array), Loc), - Expression => Make_Aggregate (Loc, - Expressions => Prim_Ops_Aggr_List))); + Object_Definition => New_Reference_To + (Defining_Identifier (Decl), Loc), + Expression => New_Node)); + + -- Remember aggregates initializing dispatch tables + + Append_Elmt (New_Node, DT_Aggr); Append_To (Result, Make_Attribute_Definition_Clause (Loc, @@ -4880,9 +4981,7 @@ package body Exp_Disp is -- Offset_To_Top - if RTE_Record_Component_Available (RE_Offset_To_Top) then - Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0)); - end if; + Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0)); -- Typeinfo @@ -4896,13 +4995,11 @@ package body Exp_Disp is Prim_Ops_Aggr_List := New_List; if Nb_Prim = 0 then - Append_To (Prim_Ops_Aggr_List, - New_Reference_To (RTE (RE_Null_Address), Loc)); + Append_To (Prim_Ops_Aggr_List, Make_Null (Loc)); elsif not Building_Static_DT (Typ) then for J in 1 .. Nb_Prim loop - Append_To (Prim_Ops_Aggr_List, - New_Reference_To (RTE (RE_Null_Address), Loc)); + Append_To (Prim_Ops_Aggr_List, Make_Null (Loc)); end loop; else @@ -4951,12 +5048,12 @@ package body Exp_Disp is for J in Prim_Table'Range loop if Present (Prim_Table (J)) then New_Node := - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Prim_Table (J), Loc), Attribute_Name => Name_Unrestricted_Access)); else - New_Node := New_Reference_To (RTE (RE_Null_Address), Loc); + New_Node := Make_Null (Loc); end if; Append_To (Prim_Ops_Aggr_List, New_Node); @@ -4964,9 +5061,15 @@ package body Exp_Disp is end; end if; - Append_To (DT_Aggr_List, + New_Node := Make_Aggregate (Loc, - Expressions => Prim_Ops_Aggr_List)); + Expressions => Prim_Ops_Aggr_List); + + Append_To (DT_Aggr_List, New_Node); + + -- Remember aggregates initializing dispatch tables + + Append_Elmt (New_Node, DT_Aggr); -- In case of locally defined tagged types we have already declared -- and uninitialized object for the dispatch table, which is now @@ -5048,26 +5151,27 @@ package body Exp_Disp is -- If the ancestor is a CPP_Class type we inherit the dispatch tables -- in the init proc, and we don't need to fill them in here. - elsif Is_CPP_Class (Etype (Typ)) then + elsif Is_CPP_Class (Parent_Typ) then null; -- Otherwise we fill in the dispatch tables here else - if Typ /= Etype (Typ) + if Typ /= Parent_Typ and then not Is_Interface (Typ) and then not Restriction_Active (No_Dispatching_Calls) then -- Inherit the dispatch table if not Is_Interface (Typ) - and then not Is_Interface (Etype (Typ)) - and then not Is_CPP_Class (Etype (Typ)) + and then not Is_Interface (Parent_Typ) + and then not Is_CPP_Class (Parent_Typ) then declare Nb_Prims : constant Int := UI_To_Int (DT_Entry_Count - (First_Tag_Component (Etype (Typ)))); + (First_Tag_Component (Parent_Typ))); + begin Append_To (Elab_Code, Build_Inherit_Predefined_Prims (Loc, @@ -5076,7 +5180,7 @@ package body Exp_Disp is (Node (Next_Elmt (First_Elmt - (Access_Disp_Table (Etype (Typ))))), Loc), + (Access_Disp_Table (Parent_Typ)))), Loc), New_Tag_Node => New_Reference_To (Node @@ -5092,7 +5196,7 @@ package body Exp_Disp is New_Reference_To (Node (First_Elmt - (Access_Disp_Table (Etype (Typ)))), Loc), + (Access_Disp_Table (Parent_Typ))), Loc), New_Tag_Node => New_Reference_To (DT_Ptr, Loc), Num_Prims => Nb_Prims)); end if; @@ -5101,13 +5205,13 @@ package body Exp_Disp is -- Inherit the secondary dispatch tables of the ancestor - if not Is_CPP_Class (Etype (Typ)) then + if not Is_CPP_Class (Parent_Typ) then declare Sec_DT_Ancestor : Elmt_Id := Next_Elmt (Next_Elmt (First_Elmt - (Access_Disp_Table (Etype (Typ))))); + (Access_Disp_Table (Parent_Typ)))); Sec_DT_Typ : Elmt_Id := Next_Elmt (Next_Elmt @@ -5327,18 +5431,49 @@ package body Exp_Disp is Make_Select_Specific_Data_Table (Typ)); end if; - -- Mark entities containing library level static dispatch tables. This - -- attribute is later propagated to all the access-to-subprogram itypes - -- generated to fill the dispatch table slots (see exp_attr). + -- Remember entities containing dispatch tables - if Building_Static_DT (Typ) then - Set_Is_Static_Dispatch_Table_Entity (Predef_Prims); - Set_Is_Static_Dispatch_Table_Entity (DT); - end if; + Append_Elmt (Predef_Prims, DT_Decl); + Append_Elmt (DT, DT_Decl); Analyze_List (Result, Suppress => All_Checks); Set_Has_Dispatch_Table (Typ); + -- Mark entities containing dispatch tables. Required by the + -- backend to handle them properly. + + if not Is_Interface (Typ) then + declare + Elmt : Elmt_Id; + + begin + -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have + -- the decoration required by the backend + + Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr)); + Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr)); + + -- Object declarations + + Elmt := First_Elmt (DT_Decl); + while Present (Elmt) loop + Set_Is_Dispatch_Table_Entity (Node (Elmt)); + pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype + or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype); + Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt))); + Next_Elmt (Elmt); + end loop; + + -- Aggregates initializing dispatch tables + + Elmt := First_Elmt (DT_Aggr); + while Present (Elmt) loop + Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt))); + Next_Elmt (Elmt); + end loop; + end; + end if; + return Result; end Make_DT; @@ -5763,7 +5898,7 @@ package body Exp_Disp is -- expand dispatching calls through the primary dispatch table. -- Generate: - -- type Typ_DT is array (1 .. Nb_Prims) of Address; + -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr; -- type Typ_DT_Acc is access Typ_DT; declare @@ -5791,7 +5926,7 @@ package body Exp_Disp is Component_Definition => Make_Component_Definition (Loc, Subtype_Indication => - New_Reference_To (RTE (RE_Address), Loc))))); + New_Reference_To (RTE (RE_Prim_Ptr), Loc))))); Append_To (Result, Make_Full_Type_Declaration (Loc, @@ -5810,6 +5945,11 @@ package body Exp_Disp is Analyze_List (Result); Set_Suppress_Init_Proc (Base_Type (DT_Prims)); + + -- Mark entity of dispatch table. Required by the backend to handle + -- the properly. + + Set_Is_Dispatch_Table_Entity (DT_Prims); end; Set_Ekind (DT_Ptr, E_Constant); @@ -5949,9 +6089,9 @@ package body Exp_Disp is L : List_Id; Pos : Uint; Tag : Entity_Id; + Tag_Typ : Entity_Id; Thunk_Id : Entity_Id; Thunk_Code : Node_Id; - Typ : Entity_Id; begin pragma Assert (not Restriction_Active (No_Dispatching_Calls)); @@ -5961,35 +6101,49 @@ package body Exp_Disp is end if; if not Present (Abstract_Interface_Alias (Prim)) then - Typ := Scope (DTC_Entity (Prim)); + Tag_Typ := Scope (DTC_Entity (Prim)); Pos := DT_Position (Prim); - Tag := First_Tag_Component (Typ); + Tag := First_Tag_Component (Tag_Typ); if Is_Predefined_Dispatching_Operation (Prim) or else Is_Predefined_Dispatching_Alias (Prim) then - DT_Ptr := Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))); + DT_Ptr := + Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ)))); + Insert_After (Ins_Nod, Build_Set_Predefined_Prim_Op_Address (Loc, Tag_Node => New_Reference_To (DT_Ptr, Loc), Position => Pos, Address_Node => - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Prim, Loc), Attribute_Name => Name_Unrestricted_Access)))); + -- Register copy of the pointer to the 'size primitive in the TSD. + + if Chars (Prim) = Name_uSize + and then RTE_Record_Component_Available (RE_Size_Func) + then + DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ))); + Insert_After (Ins_Nod, + Build_Set_Size_Function (Loc, + Tag_Node => New_Reference_To (DT_Ptr, Loc), + Size_Func => Prim)); + end if; + else pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag)); - DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ))); + DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ))); Insert_After (Ins_Nod, Build_Set_Prim_Op_Address (Loc, - Typ => Typ, + Typ => Tag_Typ, Tag_Node => New_Reference_To (DT_Ptr, Loc), Position => Pos, Address_Node => - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Prim, Loc), Attribute_Name => Name_Unrestricted_Access)))); @@ -6002,14 +6156,14 @@ package body Exp_Disp is -- else to do here. else - Typ := Find_Dispatching_Type (Alias (Prim)); + Tag_Typ := Find_Dispatching_Type (Alias (Prim)); Iface_Typ := Find_Dispatching_Type (Abstract_Interface_Alias (Prim)); pragma Assert (Is_Interface (Iface_Typ)); Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code); - if not Is_Parent (Iface_Typ, Typ) + if not Is_Parent (Iface_Typ, Tag_Typ) and then Present (Thunk_Code) then -- Comment needed on why checks are suppressed. This is not just @@ -6022,7 +6176,7 @@ package body Exp_Disp is -- the secondary dispatch table of Prim's controlling type with -- Thunk_Id's address. - Iface_DT_Elmt := Find_Interface_ADT (Typ, Iface_Typ); + Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ); Iface_DT_Ptr := Node (Iface_DT_Elmt); pragma Assert (Has_Thunks (Iface_DT_Ptr)); @@ -6040,7 +6194,7 @@ package body Exp_Disp is New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc), Position => Pos, Address_Node => - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Thunk_Id, Loc), Attribute_Name => Name_Unrestricted_Access)))); @@ -6056,7 +6210,7 @@ package body Exp_Disp is New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc), Position => Pos, Address_Node => - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Alias (Prim), Loc), Attribute_Name => Name_Unrestricted_Access)))); @@ -6073,7 +6227,7 @@ package body Exp_Disp is Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc), Position => Pos, Address_Node => - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Thunk_Id, Loc), Attribute_Name => Name_Unrestricted_Access)))); @@ -6089,7 +6243,7 @@ package body Exp_Disp is Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc), Position => Pos, Address_Node => - Unchecked_Convert_To (RTE (RE_Address), + Unchecked_Convert_To (RTE (RE_Prim_Ptr), Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Alias (Prim), Loc), Attribute_Name => Name_Unrestricted_Access)))); |