summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch3.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-26 14:47:48 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-26 14:47:48 +0000
commitbd550baffa529087be2a7eb98dd64735da53e52b (patch)
tree966853aeb51ebcb01d4672b5d9fcb8065248a86d /gcc/ada/exp_ch3.adb
parentfc1e99dbe7d9e443abf618cc1cbf0f3b490cd17f (diff)
downloadgcc-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.adb293
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