aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_util.adb
diff options
context:
space:
mode:
authorHristian Kirtchev <kirtchev@adacore.com>2014-02-25 15:03:23 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2014-02-25 16:03:23 +0100
commit7edfb4c6492dc8f503f5277adcaf5ab25c62cc46 (patch)
tree5c5f51d2f9af2943bc3851a9c729ed0f00505b78 /gcc/ada/sem_util.adb
parentbbe9779cc857a7bbd28ab316bb325abd5ff0df71 (diff)
downloadgcc-7edfb4c6492dc8f503f5277adcaf5ab25c62cc46.zip
gcc-7edfb4c6492dc8f503f5277adcaf5ab25c62cc46.tar.gz
gcc-7edfb4c6492dc8f503f5277adcaf5ab25c62cc46.tar.bz2
2014-02-25 Hristian Kirtchev <kirtchev@adacore.com>
* einfo.ads Update the usage of flag Uses_Sec_Stack. Uses_Sec_Stack now applies to E_Loop entities. * exp_ch5.adb (Expand_Iterator_Loop): The temporary for a cursor now starts with the letter 'C'. This makes reading expanded code easier. * exp_ch7.adb (Establish_Transient_Scope): Add local variable Iter_Loop. Signal that an Ada 2012 iterator loop requires secondary stack management when creating a transient scope for an element reference. * exp_util.adb (Process_Statements_For_Controlled_Objects): When wrapping the statements of a loop, pass the E_Loop entity to the wrapping machinery. (Wrap_Statements_In_Block): Add formal parameter Scop along with comment on usage. Add local variables Block_Id, Block_Nod and Iter_Loop. Mark the generated block as requiring secondary stack management when the block is created inside an Ada 2012 iterator loop. This ensures that any reference objects are reclaimed on each iteration of the loop. * sem_ch5.adb (Analyze_Loop_Statement): Mark the generated block tasked with the handling of container iterators as requiring secondary stack management. This ensures that iterators are reclaimed when the loop terminates or is exited in any fashion. * sem_util.adb (Add_Block_Identifier): New routine. (Find_Enclosing_Iterator_Loop): New routine. * sem_util.ads (Add_Block_Identifier): New routine. (Find_Enclosing_Iterator_Loop): New routine. From-SVN: r208133
Diffstat (limited to 'gcc/ada/sem_util.adb')
-rw-r--r--gcc/ada/sem_util.adb61
1 files changed, 61 insertions, 0 deletions
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 3f87216..d33c235 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -217,6 +217,33 @@ package body Sem_Util is
Append_Elmt (A, L);
end Add_Access_Type_To_Process;
+ --------------------------
+ -- Add_Block_Identifier --
+ --------------------------
+
+ procedure Add_Block_Identifier (N : Node_Id; Id : out Entity_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ begin
+ pragma Assert (Nkind (N) = N_Block_Statement);
+
+ -- The block already has a label, return its entity
+
+ if Present (Identifier (N)) then
+ Id := Entity (Identifier (N));
+
+ -- Create a new block label and set its attributes
+
+ else
+ Id := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
+ Set_Etype (Id, Standard_Void_Type);
+ Set_Parent (Id, N);
+
+ Set_Identifier (N, New_Occurrence_Of (Id, Loc));
+ Set_Block_Node (Id, Identifier (N));
+ end if;
+ end Add_Block_Identifier;
+
-----------------------
-- Add_Contract_Item --
-----------------------
@@ -5592,6 +5619,40 @@ package body Sem_Util is
raise Program_Error;
end Find_Corresponding_Discriminant;
+ ----------------------------------
+ -- Find_Enclosing_Iterator_Loop --
+ ----------------------------------
+
+ function Find_Enclosing_Iterator_Loop (Id : Entity_Id) return Entity_Id is
+ Constr : Node_Id;
+ S : Entity_Id;
+
+ begin
+ -- Traverse the scope chain looking for an iterator loop. Such loops are
+ -- usually transformed into blocks, hence the use of Original_Node.
+
+ S := Id;
+ while Present (S) and then S /= Standard_Standard loop
+ if Ekind (S) = E_Loop
+ and then Nkind (Parent (S)) = N_Implicit_Label_Declaration
+ then
+ Constr := Original_Node (Label_Construct (Parent (S)));
+
+ if Nkind (Constr) = N_Loop_Statement
+ and then Present (Iteration_Scheme (Constr))
+ and then Nkind (Iterator_Specification (Iteration_Scheme
+ (Constr))) = N_Iterator_Specification
+ then
+ return S;
+ end if;
+ end if;
+
+ S := Scope (S);
+ end loop;
+
+ return Empty;
+ end Find_Enclosing_Iterator_Loop;
+
------------------------------------
-- Find_Loop_In_Conditional_Block --
------------------------------------