diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2014-02-25 15:03:23 +0000 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2014-02-25 16:03:23 +0100 |
commit | 7edfb4c6492dc8f503f5277adcaf5ab25c62cc46 (patch) | |
tree | 5c5f51d2f9af2943bc3851a9c729ed0f00505b78 /gcc/ada/sem_util.adb | |
parent | bbe9779cc857a7bbd28ab316bb325abd5ff0df71 (diff) | |
download | gcc-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.adb | 61 |
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 -- ------------------------------------ |