diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-10-04 17:07:59 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-10-04 17:07:59 +0200 |
commit | bed8af19ec83d0e51a37a55faf1a87979a85a9b9 (patch) | |
tree | d86193b63a1853cbc95c49932831c817706056d6 /gcc/ada/exp_ch3.adb | |
parent | c452684d45087cb02bf3a9ebe973682a3b946a56 (diff) | |
download | gcc-bed8af19ec83d0e51a37a55faf1a87979a85a9b9.zip gcc-bed8af19ec83d0e51a37a55faf1a87979a85a9b9.tar.gz gcc-bed8af19ec83d0e51a37a55faf1a87979a85a9b9.tar.bz2 |
[multiple changes]
2010-10-04 Vincent Celier <celier@adacore.com>
* a-direct.adb (Copy_File): Interpret the Form parameter and call
System.OS_Lib.Copy_File to do the work accordingly. Raise Use_Error if
the Form parameter contains an incorrect value for field preserve= or
mode=.
* a-direct.ads (Create_Directory, Create_Path): Indicate that the Form
parameter is ignored.
(Copy_File): Indicate the interpretation of the Form parameter.
2010-10-04 Vincent Celier <celier@adacore.com>
* make.adb (Gnatmake): When there are no foreign languages declared and
a main in attribute Main of the main project does not exist or is a
source of another project, fail immediately before attempting
compilation.
2010-10-04 Javier Miranda <miranda@adacore.com>
* exp_disp.ads (Convert_Tag_To_Interface): New function which must be
used to convert a node referencing a tag to a class-wide interface type.
* exp_disp.adb (Convert_Tag_To_Interface): New function.
(Expand_Interface_Conversion): Replace invocation of
Unchecked_Conversion by new function Convert_Tag_To_Interface.
(Write_DT): Add support for null primitives.
* exp_ch3.adb (Expand_N_Object_Declaration): For tagged type objects,
cleanup code that handles interface conversions and avoid unchecked
conversion of referenced tag components.
* exp_ch5.adb (Expand_N_Assignment_Statement): Code cleanup. Avoid
unrequired conversions when generating a dispatching call to _assign.
* sprint.adb (Write_Itype): Fix wrong output of not null access itypes.
2010-10-04 Ed Schonberg <schonberg@adacore.com>
* exp_ch4.adb (Expand_N_Op_Not): Handle properly both operands when the
parent is a binary boolean operation and the operand is an unpacked
array.
(Build_Boolean_Array_Proc_Call): If the operands are both negations, the
operands of the rewritten node are the operands of the negations, not
the negations themselves.
From-SVN: r164942
Diffstat (limited to 'gcc/ada/exp_ch3.adb')
-rw-r--r-- | gcc/ada/exp_ch3.adb | 163 |
1 files changed, 78 insertions, 85 deletions
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index ee44dd9..93e1dfd 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -4809,20 +4809,20 @@ package body Exp_Ch3 is Iface : constant Entity_Id := Root_Type (Typ); Expr_N : Node_Id := Expr; Expr_Typ : Entity_Id; - - Decl_1 : Node_Id; - Decl_2 : Node_Id; New_Expr : Node_Id; + Obj_Id : Entity_Id; + Tag_Comp : Node_Id; begin -- If the original node of the expression was a conversion -- to this specific class-wide interface type then we - -- restore the original node to generate code that - -- statically displaces the pointer to the interface - -- component. + -- restore the original node because we must copy the object + -- before displacing the pointer to reference the secondary + -- tag component. This code must be kept synchronized with + -- the expansion done by routine Expand_Interface_Conversion if not Comes_From_Source (Expr_N) - and then Nkind (Expr_N) = N_Unchecked_Type_Conversion + and then Nkind (Expr_N) = N_Explicit_Dereference and then Nkind (Original_Node (Expr_N)) = N_Type_Conversion and then Etype (Original_Node (Expr_N)) = Typ then @@ -4839,6 +4839,7 @@ package body Exp_Ch3 is Set_Expression (N, Expr_N); end if; + Obj_Id := Make_Temporary (Loc, 'D', Expr_N); Expr_Typ := Base_Type (Etype (Expr_N)); if Is_Class_Wide_Type (Expr_Typ) then @@ -4849,122 +4850,114 @@ package body Exp_Ch3 is -- CW : I'Class := Obj; -- by -- Tmp : T := Obj; - -- CW : I'Class renames TiC!(Tmp.I_Tag); + -- type Ityp is not null access I'Class; + -- CW : I'Class renames Ityp(Tmp.I_Tag'Address).all; if Comes_From_Source (Expr_N) and then Nkind (Expr_N) = N_Identifier and then not Is_Interface (Expr_Typ) + and then Interface_Present_In_Ancestor (Expr_Typ, Typ) and then (Expr_Typ = Etype (Expr_Typ) or else not Is_Variable_Size_Record (Etype (Expr_Typ))) then - Decl_1 := + -- Copy the object + + Insert_Action (N, Make_Object_Declaration (Loc, - Defining_Identifier => - Make_Temporary (Loc, 'D', Expr_N), + Defining_Identifier => Obj_Id, Object_Definition => New_Occurrence_Of (Expr_Typ, Loc), Expression => - Unchecked_Convert_To (Expr_Typ, - Relocate_Node (Expr_N))); + Relocate_Node (Expr_N))); -- Statically reference the tag associated with the -- interface - Decl_2 := - Make_Object_Renaming_Declaration (Loc, - Defining_Identifier => Make_Temporary (Loc, 'D'), - Subtype_Mark => New_Occurrence_Of (Typ, Loc), - Name => - Unchecked_Convert_To (Typ, - Make_Selected_Component (Loc, - Prefix => - New_Occurrence_Of - (Defining_Identifier (Decl_1), Loc), - Selector_Name => - New_Reference_To - (Find_Interface_Tag (Expr_Typ, Iface), - Loc)))); - - -- General case: + Tag_Comp := + Make_Selected_Component (Loc, + Prefix => New_Occurrence_Of (Obj_Id, Loc), + Selector_Name => + New_Reference_To + (Find_Interface_Tag (Expr_Typ, Iface), Loc)); -- Replace -- IW : I'Class := Obj; -- by -- type Equiv_Record is record ... end record; -- implicit subtype CW is <Class_Wide_Subtype>; - -- Temp : CW := CW!(Obj'Address); - -- IW : I'Class renames Displace (Temp, I'Tag); + -- Tmp : CW := CW!(Obj); + -- type Ityp is not null access I'Class; + -- IW : I'Class renames + -- Ityp!(Displace (Temp'Address, I'Tag)).all; else - -- Generate the equivalent record type + -- Generate the equivalent record type and update + -- the subtype indication to reference it Expand_Subtype_From_Expr (N => N, Unc_Type => Typ, Subtype_Indic => Object_Definition (N), - Exp => Expression (N)); + Exp => Expr_N); + + if not Is_Interface (Etype (Expr_N)) then + New_Expr := Relocate_Node (Expr_N); + + -- For interface types we use 'Address which displaces + -- the pointer to the base of the object (if required) - if not Is_Interface (Etype (Expression (N))) then - New_Expr := Relocate_Node (Expression (N)); else New_Expr := - Make_Explicit_Dereference (Loc, - Unchecked_Convert_To (RTE (RE_Tag_Ptr), - Make_Attribute_Reference (Loc, - Prefix => Relocate_Node (Expression (N)), - Attribute_Name => Name_Address))); + Unchecked_Convert_To (Etype (Object_Definition (N)), + Make_Explicit_Dereference (Loc, + Unchecked_Convert_To (RTE (RE_Tag_Ptr), + Make_Attribute_Reference (Loc, + Prefix => Relocate_Node (Expr_N), + Attribute_Name => Name_Address)))); end if; - Decl_1 := + -- Copy the object + + Insert_Action (N, Make_Object_Declaration (Loc, - Defining_Identifier => - Make_Temporary (Loc, 'D', New_Expr), - Object_Definition => + Defining_Identifier => Obj_Id, + Object_Definition => New_Occurrence_Of - (Etype (Object_Definition (N)), Loc), - Expression => - Unchecked_Convert_To - (Etype (Object_Definition (N)), New_Expr)); - - Decl_2 := - Make_Object_Renaming_Declaration (Loc, - Defining_Identifier => Make_Temporary (Loc, 'D'), - Subtype_Mark => New_Occurrence_Of (Typ, Loc), - Name => - Unchecked_Convert_To (Typ, - Make_Explicit_Dereference (Loc, - Unchecked_Convert_To (RTE (RE_Tag_Ptr), - Make_Function_Call (Loc, - Name => - New_Reference_To (RTE (RE_Displace), Loc), - Parameter_Associations => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of - (Defining_Identifier (Decl_1), Loc), - Attribute_Name => Name_Address), - - Unchecked_Convert_To (RTE (RE_Tag), - New_Reference_To - (Node - (First_Elmt - (Access_Disp_Table (Iface))), - Loc)))))))); + (Etype (Object_Definition (N)), Loc), + Expression => New_Expr)); + + -- Dynamically reference the tag associated with the + -- interface + + Tag_Comp := + Make_Function_Call (Loc, + Name => New_Reference_To (RTE (RE_Displace), Loc), + Parameter_Associations => New_List ( + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Obj_Id, Loc), + Attribute_Name => Name_Address), + New_Reference_To + (Node (First_Elmt (Access_Disp_Table (Iface))), + Loc))); end if; - Insert_Action (N, Decl_1); - Rewrite (N, Decl_2); - Analyze (N); - - -- Replace internal identifier of Decl_2 by the identifier - -- found in the sources. We also have to exchange entities - -- containing their defining identifiers to ensure the - -- correct replacement of the object declaration by this - -- object renaming declaration (because such definings - -- identifier have been previously added by Enter_Name to - -- the current scope). We must preserve the homonym chain - -- of the source entity as well. + Rewrite (N, + Make_Object_Renaming_Declaration (Loc, + Defining_Identifier => Make_Temporary (Loc, 'D'), + Subtype_Mark => New_Occurrence_Of (Typ, Loc), + Name => Convert_Tag_To_Interface (Typ, Tag_Comp))); + + Analyze (N, Suppress => All_Checks); + + -- Replace internal identifier of rewriten node by the + -- identifier found in the sources. We also have to exchange + -- entities containing their defining identifiers to ensure + -- the correct replacement of the object declaration by this + -- object renaming declaration ---because these identifiers + -- were previously added by Enter_Name to the current scope. + -- We must preserve the homonym chain of the source entity + -- as well. Set_Chars (Defining_Identifier (N), Chars (Def_Id)); Set_Homonym (Defining_Identifier (N), Homonym (Def_Id)); |