diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-01-26 14:47:48 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-01-26 14:47:48 +0000 |
commit | bd550baffa529087be2a7eb98dd64735da53e52b (patch) | |
tree | 966853aeb51ebcb01d4672b5d9fcb8065248a86d /gcc/ada/exp_ch3.adb | |
parent | fc1e99dbe7d9e443abf618cc1cbf0f3b490cd17f (diff) | |
download | gcc-bd550baffa529087be2a7eb98dd64735da53e52b.tar.gz |
2004-01-26 Ed Schonberg <schonberg@gnat.com>
* exp_ch3.adb (Build_Slice_Assignment): New TSS procedure for
one-dimensional array an slice assignments, when component type is
controlled.
* exp_ch5.adb (Expand_Assign_Array): If array is one-dimensional,
component type is controlled, and control_actions are in effect, use
TSS procedure rather than generating inline code.
* exp_tss.ads (TSS_Slice_Assign): New TSS procedure for one-dimensional
arrays with controlled components.
2004-01-26 Vincent Celier <celier@gnat.com>
* gnatcmd.adb (GNATCmd): Add specification of argument file on the
command line for the non VMS case.
* gnatlink.adb (Process_Binder_File): When building object file, if
GNU linker is used, put all object paths between quotes, to prevent ld
error when there are unusual characters (such as '!') in the paths.
* Makefile.generic: When there are sources in Ada and the main is in
C/C++, invoke gnatmake with -B, instead of -z.
* vms_conv.adb (Preprocess_Command_Data): New procedure, extracted
from VMS_Conversion.
(Process_Argument): New procedure, extracted from VMS_Conversion. Add
specification of argument file on the command line.
2004-01-26 Bernard Banner <banner@gnat.com>
* Makefile.in: Enable GMEM_LIB and SYMLIB for x86_64
2004-01-26 Ed Schonberg <schonberg@gnat.com>
* snames.adb: Update copyright notice.
Add info on slice assignment for controlled arrays.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76634 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_ch3.adb')
-rw-r--r-- | gcc/ada/exp_ch3.adb | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index 42d15862443..111e14b3508 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -114,6 +114,12 @@ package body Exp_Ch3 is -- Build record initialization procedure. N is the type declaration -- node, and Pe is the corresponding entity for the record type. + procedure Build_Slice_Assignment (Typ : Entity_Id); + -- Build assignment procedure for one-dimensional arrays of controlled + -- types. Other array and slice assignments are expanded in-line, but + -- the code expansion for controlled components (when control actions + -- are active) can lead to very large blocks that GCC3 handles poorly. + procedure Build_Variant_Record_Equality (Typ : Entity_Id); -- Create An Equality function for the non-tagged variant record 'Typ' -- and attach it to the TSS list @@ -2474,6 +2480,287 @@ package body Exp_Ch3 is end if; end Build_Record_Init_Proc; + ---------------------------- + -- Build_Slice_Assignment -- + ---------------------------- + + -- Generates the following subprogram: + -- procedure Assign + -- (Source, Target : Array_Type, + -- Left_Lo, Left_Hi, Right_Lo, Right_Hi : Index; + -- Rev : Boolean) + -- is + -- Li1 : Index; + -- Ri1 : Index; + -- begin + -- if Rev then + -- Li1 := Left_Hi; + -- Ri1 := Right_Hi; + -- else + -- Li1 := Left_Lo; + -- Ri1 := Right_Lo; + -- end if; + -- + -- loop + -- Target (Li1) := Source (Ri1); + -- if Rev then + -- exit when Li2 = Left_Lo; + -- Li2 := Index'pred (Li2); + -- Ri2 := Index'pred (Ri2); + -- else + -- exit when Li2 = Left_Hi; + -- Li2 := Index'succ (Li2); + -- Ri2 := Index'succ (Ri2); + -- end if; + -- end loop; + -- end Assign; + + procedure Build_Slice_Assignment (Typ : Entity_Id) is + Loc : constant Source_Ptr := Sloc (Typ); + Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ))); + + -- Build formal parameters of procedure + + Larray : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('A')); + Rarray : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('R')); + Left_Lo : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('L')); + Left_Hi : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('L')); + Right_Lo : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('R')); + Right_Hi : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('R')); + Rev : constant Entity_Id := + Make_Defining_Identifier + (Loc, Chars => New_Internal_Name ('D')); + Proc_Name : constant Entity_Id := + Make_Defining_Identifier (Loc, + Chars => Make_TSS_Name (Typ, TSS_Slice_Assign)); + + Lnn : constant Entity_Id := + Make_Defining_Identifier (Loc, New_Internal_Name ('L')); + Rnn : constant Entity_Id := + Make_Defining_Identifier (Loc, New_Internal_Name ('R')); + -- subscripts for left and right sides + + Decls : List_Id; + Loops : Node_Id; + Stats : List_Id; + + begin + + -- Build declarations for indices. + + Decls := New_List; + + Append_To (Decls, + Make_Object_Declaration (Loc, + Defining_Identifier => Lnn, + Object_Definition => + New_Occurrence_Of (Index, Loc))); + + Append_To (Decls, + Make_Object_Declaration (Loc, + Defining_Identifier => Rnn, + Object_Definition => + New_Occurrence_Of (Index, Loc))); + + Stats := New_List; + + -- Build initializations for indices. + + declare + F_Init : constant List_Id := New_List; + B_Init : constant List_Id := New_List; + + begin + Append_To (F_Init, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Lnn, Loc), + Expression => New_Occurrence_Of (Left_Lo, Loc))); + + Append_To (F_Init, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Rnn, Loc), + Expression => New_Occurrence_Of (Right_Lo, Loc))); + + Append_To (B_Init, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Lnn, Loc), + Expression => New_Occurrence_Of (Left_Hi, Loc))); + + Append_To (B_Init, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Rnn, Loc), + Expression => New_Occurrence_Of (Right_Hi, Loc))); + + Append_To (Stats, + Make_If_Statement (Loc, + Condition => New_Occurrence_Of (Rev, Loc), + Then_Statements => B_Init, + Else_Statements => F_Init)); + end; + + -- Now construct the assignment statement + + Loops := + Make_Loop_Statement (Loc, + Statements => New_List ( + Make_Assignment_Statement (Loc, + Name => + Make_Indexed_Component (Loc, + Prefix => New_Occurrence_Of (Larray, Loc), + Expressions => New_List (New_Occurrence_Of (Lnn, Loc))), + Expression => + Make_Indexed_Component (Loc, + Prefix => New_Occurrence_Of (Rarray, Loc), + Expressions => New_List (New_Occurrence_Of (Rnn, Loc))))), + End_Label => Empty); + + -- Build the increment/decrement statements. + + declare + F_Ass : constant List_Id := New_List; + B_Ass : constant List_Id := New_List; + + begin + Append_To (F_Ass, + Make_Exit_Statement (Loc, + Condition => + Make_Op_Eq (Loc, + Left_Opnd => New_Occurrence_Of (Lnn, Loc), + Right_Opnd => New_Occurrence_Of (Left_Hi, Loc)))); + + Append_To (B_Ass, + Make_Exit_Statement (Loc, + Condition => + Make_Op_Eq (Loc, + Left_Opnd => New_Occurrence_Of (Lnn, Loc), + Right_Opnd => New_Occurrence_Of (Left_Lo, Loc)))); + + Append_To (F_Ass, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Lnn, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Index, Loc), + Attribute_Name => Name_Succ, + Expressions => New_List ( + New_Occurrence_Of (Lnn, Loc))))); + + Append_To (F_Ass, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Rnn, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Index, Loc), + Attribute_Name => Name_Succ, + Expressions => New_List ( + New_Occurrence_Of (Rnn, Loc))))); + + Append_To (B_Ass, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Lnn, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Index, Loc), + Attribute_Name => Name_Pred, + Expressions => New_List ( + New_Occurrence_Of (Lnn, Loc))))); + + Append_To (B_Ass, + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Rnn, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Index, Loc), + Attribute_Name => Name_Pred, + Expressions => New_List ( + New_Occurrence_Of (Rnn, Loc))))); + + Append_To (Statements (Loops), + Make_If_Statement (Loc, + Condition => New_Occurrence_Of (Rev, Loc), + Then_Statements => B_Ass, + Else_Statements => F_Ass)); + end; + + Append_To (Stats, Loops); + + declare + Spec : Node_Id; + Formals : List_Id := New_List; + + begin + Formals := New_List ( + Make_Parameter_Specification (Loc, + Defining_Identifier => Larray, + Out_Present => True, + Parameter_Type => + New_Reference_To (Base_Type (Typ), Loc)), + + Make_Parameter_Specification (Loc, + Defining_Identifier => Rarray, + Parameter_Type => + New_Reference_To (Base_Type (Typ), Loc)), + + Make_Parameter_Specification (Loc, + Defining_Identifier => Left_Lo, + Parameter_Type => + New_Reference_To (Index, Loc)), + + Make_Parameter_Specification (Loc, + Defining_Identifier => Left_Hi, + Parameter_Type => + New_Reference_To (Index, Loc)), + + Make_Parameter_Specification (Loc, + Defining_Identifier => Right_Lo, + Parameter_Type => + New_Reference_To (Index, Loc)), + + Make_Parameter_Specification (Loc, + Defining_Identifier => Right_Hi, + Parameter_Type => + New_Reference_To (Index, Loc))); + + Append_To (Formals, + Make_Parameter_Specification (Loc, + Defining_Identifier => Rev, + Parameter_Type => + New_Reference_To (Standard_Boolean, Loc))); + + Spec := + Make_Procedure_Specification (Loc, + Defining_Unit_Name => Proc_Name, + Parameter_Specifications => Formals); + + Discard_Node ( + Make_Subprogram_Body (Loc, + Specification => Spec, + Declarations => Decls, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => Stats))); + end; + + Set_TSS (Typ, Proc_Name); + Set_Is_Pure (Proc_Name); + end Build_Slice_Assignment; + ------------------------------------ -- Build_Variant_Record_Equality -- ------------------------------------ @@ -3483,6 +3770,12 @@ package body Exp_Ch3 is if Typ = Base and then Has_Controlled_Component (Base) then Build_Controlling_Procs (Base); + + if not Is_Limited_Type (Component_Type (Typ)) + and then Number_Dimensions (Typ) = 1 + then + Build_Slice_Assignment (Typ); + end if; end if; -- For packed case, there is a default initialization, except |