Iterator filters can appear in loop parameter specifications and
in iterator specifications, and thus in Iterated_Element_Awsociations
in container aggregates. This patch extend the parsing and expansion
of Iterated associations, to better distinguish the Ada_2020 construct
from the Ada_2012 Iterated_Component_Association.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * par-ch4.adb (P_Iterated_Component_Association): If the
        construct includes an iterator filter it corresponds to an
        Iterated_Element_Association, so build the proper node for it.
        * exp_aggr.adb (Expand_Container_Aggregate, Aggregate_Size): If
        the component is an Iterated_Element_Association, treat it as
        having a non-static size.
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6954,6 +6954,16 @@ package body Exp_Aggr is
 
          if Present (Component_Associations (N)) then
             Comp := First (Component_Associations (N));
+
+            --  If the component is an Iterated_Element_Association
+            --  it includes an iterator or a loop parameter, possibly
+            --  with a filter, so we do not attempt to compute its
+            --  size. Room for future optimization ???
+
+            if Nkind (Comp) = N_Iterated_Element_Association then
+               return -1;
+            end if;
+
             while Present (Comp) loop
                Choice := First (Choice_List (Comp));
 


diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -3421,11 +3421,37 @@ package body Ch4 is
    function P_Iterated_Component_Association return Node_Id is
       Assoc_Node : Node_Id;
       Choice     : Node_Id;
+      Filter     : Node_Id := Empty;
       Id         : Node_Id;
       Iter_Spec  : Node_Id;
       Loop_Spec  : Node_Id;
       State      : Saved_Scan_State;
 
+      procedure Build_Iterated_Element_Association;
+      --  If the iterator includes a key expression or a filter, it is
+      --  an Ada_2020 Iterator_Element_Association within a container
+      --  aggregate.
+
+      ----------------------------------------
+      -- Build_Iterated_Element_Association --
+      ----------------------------------------
+
+      procedure Build_Iterated_Element_Association is
+      begin
+         Choice :=  First (Discrete_Choices (Assoc_Node));
+         Assoc_Node :=
+           New_Node (N_Iterated_Element_Association, Prev_Token_Ptr);
+         Set_Loop_Parameter_Specification (Assoc_Node, Loop_Spec);
+
+         if Present (Next (Choice)) then
+            Error_Msg_N ("expect loop parameter specification", Choice);
+         end if;
+
+         Remove (Choice);
+         Set_Discrete_Subtype_Definition (Loop_Spec, Choice);
+         Set_Iterator_Filter (Loop_Spec, Filter);
+      end Build_Iterated_Element_Association;
+
    --  Start of processing for P_Iterated_Component_Association
 
    begin
@@ -3443,6 +3469,8 @@ package body Ch4 is
       --  In addition, if "use" is present after the specification,
       --  this is an Iterated_Element_Association that carries a
       --  key_expression, and we generate the appropriate node.
+      --  Finally, the Iterated_Element form is reserved for contwiner
+      --  aggregates, and is illegal in array aggregates.
 
       Id := P_Defining_Identifier;
       Assoc_Node :=
@@ -3453,29 +3481,34 @@ package body Ch4 is
          T_In;
          Set_Discrete_Choices (Assoc_Node, P_Discrete_Choice_List);
 
+         --  The iterator may include a filter.
+
+         if Token = Tok_When then
+            Scan;    -- past WHEN
+            Filter := P_Condition;
+         end if;
+
+         --  Build loop_parameter specification.
+
+         Loop_Spec :=
+           New_Node (N_Loop_Parameter_Specification, Prev_Token_Ptr);
+         Set_Defining_Identifier (Loop_Spec, Id);
+
          if Token = Tok_Use then
 
             --  Ada_2020 Key-expression is present, rewrite node as an
             --  iterated_Element_Awwoiation.
 
             Scan;  --  past USE
-            Loop_Spec :=
-              New_Node (N_Loop_Parameter_Specification, Prev_Token_Ptr);
-            Set_Defining_Identifier (Loop_Spec, Id);
-
-            Choice :=  First (Discrete_Choices (Assoc_Node));
-
-            if Present (Next (Choice)) then
-               Error_Msg_N ("expect loop parameter specification", Choice);
-            end if;
+            Build_Iterated_Element_Association;
+            Set_Key_Expression (Assoc_Node, P_Expression);
 
-            Remove (Choice);
-            Set_Discrete_Subtype_Definition (Loop_Spec, Choice);
+         elsif Present (Filter) then
+            --  A loop_Parameter_Specification also indicates an Ada_2020
+            --  conwtruct, in contrast with a subtype indication used in
+            --  array aggregates.
 
-            Assoc_Node :=
-              New_Node (N_Iterated_Element_Association, Prev_Token_Ptr);
-            Set_Loop_Parameter_Specification (Assoc_Node, Loop_Spec);
-            Set_Key_Expression (Assoc_Node, P_Expression);
+            Build_Iterated_Element_Association;
          end if;
 
          TF_Arrow;


Reply via email to