Patchwork [Ada] Iterators over containers of indefinite types

login
register
mail settings
Submitter Arnaud Charlet
Date Aug. 2, 2011, 1:52 p.m.
Message ID <20110802135211.GA24257@adacore.com>
Download mbox | patch
Permalink /patch/107921/
State New
Headers show

Comments

Arnaud Charlet - Aug. 2, 2011, 1:52 p.m.
If the elements of the container are indefinite, the iterator must build the
actual subtypes of each element in the iteration. As this is done during
expansion, the analysis of the loop body must be delayed until the loop is
expanded as an iterator loop.
The following must compile quietly in Ada2012 mode:

with Ada.Containers.Indefinite_Vectors;
with Ada.Text_IO;
procedure ContIt is
    use Ada;
    package Str_Vect is
      new Containers.Indefinite_Vectors (Natural, String);
    V : Str_Vect.Vector;
    C : Str_Vect.Cursor;
    use Str_Vect;
begin
    V.Append ("toto");
    V.Append ("everything");
    V.Append ("absolument tout");

    for E of V loop
      Text_IO.Put_Line ("> " & E);
    end loop;
end ContIt;

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

2011-08-02  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch5.adb (Analyze_Loop_Statement):  If the iteration scheme is an
	Ada2012 iterator, the loop will be rewritten during expansion into a
	while loop with a cursor and an element declaration. Do not analyze the
	body in this case, because if the container is for indefinite types the
	actual subtype of the elements will only be determined when the cursor
	declaration is analyzed.

Patch

Index: sem_ch5.adb
===================================================================
--- sem_ch5.adb	(revision 177152)
+++ sem_ch5.adb	(working copy)
@@ -2387,7 +2387,33 @@ 
       Kill_Current_Values;
       Push_Scope (Ent);
       Analyze_Iteration_Scheme (Iter);
-      Analyze_Statements (Statements (Loop_Statement));
+
+      --  Analyze the statements of the body except in the case of an Ada 2012
+      --  iterator with the expander active. In this case the expander will do
+      --  a rewrite of the loop into a while loop. We will then analyze the
+      --  loop body when we analyze this while loop.
+
+      --  We need to do this delay because if the container is for indefinite
+      --  types the actual subtype of the components will only be determined
+      --  when the cursor declaration is analyzed.
+
+      --  If the expander is not active, then we want to analyze the loop body
+      --  now even in the Ada 2012 iterator case, since the rewriting will not
+      --  be done.
+
+      if No (Iter)
+        or else No (Iterator_Specification (Iter))
+        or else not Expander_Active
+      then
+         Analyze_Statements (Statements (Loop_Statement));
+      end if;
+
+      --  Finish up processing for the loop. We kill all current values, since
+      --  in general we don't know if the statements in the loop have been
+      --  executed. We could do a bit better than this with a loop that we
+      --  know will execute at least once, but it's not worth the trouble and
+      --  the front end is not in the business of flow tracing.
+
       Process_End_Label (Loop_Statement, 'e', Ent);
       End_Scope;
       Kill_Current_Values;