Commit dedac3eb by Robert Dewar Committed by Arnaud Charlet

par_sco.adb, [...]: Minor reformatting.

2011-08-05  Robert Dewar  <dewar@adacore.com>

	* par_sco.adb, sem_ch3.adb, scos.ads, a-iteint.ads, sem_ch12.adb,
	a-cimutr.adb, a-cimutr.ads, sem_util.ads, sem_res.adb, a-fihema.adb,
	sem_ch4.adb, lib-xref-alfa.adb, exp_disp.adb, a-comutr.adb,
	a-comutr.ads, lib-xref.adb: Minor reformatting.

2011-08-05  Robert Dewar  <dewar@adacore.com>

	* sem_ch11.adb (Analyze_Raise_Statement): Kill assignment to formal
	warning if there is an exception handler present.

From-SVN: r177451
parent 7c62a85a
2011-08-05 Robert Dewar <dewar@adacore.com>
* par_sco.adb, sem_ch3.adb, scos.ads, a-iteint.ads, sem_ch12.adb,
a-cimutr.adb, a-cimutr.ads, sem_util.ads, sem_res.adb, a-fihema.adb,
sem_ch4.adb, lib-xref-alfa.adb, exp_disp.adb, a-comutr.adb,
a-comutr.ads, lib-xref.adb: Minor reformatting.
2011-08-05 Robert Dewar <dewar@adacore.com>
* sem_ch11.adb (Analyze_Raise_Statement): Kill assignment to formal
warning if there is an exception handler present.
2011-08-05 Pascal Obry <obry@adacore.com> 2011-08-05 Pascal Obry <obry@adacore.com>
* a-iteint.ads: Fix copyright year. * a-iteint.ads: Fix copyright year.
......
...@@ -134,25 +134,24 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -134,25 +134,24 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Target_Count : Count_Type; Target_Count : Count_Type;
begin begin
-- We first restore the target container to its -- We first restore the target container to its default-initialized
-- default-initialized state, before we attempt any -- state, before we attempt any allocation, to ensure that invariants
-- allocation, to ensure that invariants are preserved -- are preserved in the event that the allocation fails.
-- in the event that the allocation fails.
Container.Root.Children := Children_Type'(others => null); Container.Root.Children := Children_Type'(others => null);
Container.Busy := 0; Container.Busy := 0;
Container.Lock := 0; Container.Lock := 0;
Container.Count := 0; Container.Count := 0;
-- Copy_Children returns a count of the number of nodes -- Copy_Children returns a count of the number of nodes that it
-- that it allocates, but it works by incrementing the -- allocates, but it works by incrementing the value that is passed in.
-- value that is passed in. We must therefore initialize -- We must therefore initialize the count value before calling
-- the count value before calling Copy_Children. -- Copy_Children.
Target_Count := 0; Target_Count := 0;
-- Now we attempt the allocation of subtrees. The invariants -- Now we attempt the allocation of subtrees. The invariants are
-- are satisfied even if the allocation fails. -- satisfied even if the allocation fails.
Copy_Children (Source, Root_Node (Container), Target_Count); Copy_Children (Source, Root_Node (Container), Target_Count);
pragma Assert (Target_Count = Source_Count); pragma Assert (Target_Count = Source_Count);
...@@ -181,11 +180,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -181,11 +180,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
raise Program_Error with "Position cursor not in container"; raise Program_Error with "Position cursor not in container";
end if; end if;
-- AI-0136 says to raise PE if Position equals the root node. -- AI-0136 says to raise PE if Position equals the root node. This does
-- This does not seem correct, as this value is just the limiting -- not seem correct, as this value is just the limiting condition of the
-- condition of the search. For now we omit this check, -- search. For now we omit this check pending a ruling from the ARG.???
-- pending a ruling from the ARG. ???
--
-- if Is_Root (Position) then -- if Is_Root (Position) then
-- raise Program_Error with "Position cursor designates root"; -- raise Program_Error with "Position cursor designates root";
-- end if; -- end if;
...@@ -241,6 +239,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -241,6 +239,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Last := First; Last := First;
for J in Count_Type'(2) .. Count loop for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ??? -- Reclaim other nodes if Storage_Error. ???
Element := new Element_Type'(New_Item); Element := new Element_Type'(New_Item);
...@@ -258,10 +257,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -258,10 +257,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => null); -- null means "insert at end of list" Before => null); -- null means "insert at end of list"
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Append_Child; end Append_Child;
...@@ -281,16 +279,15 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -281,16 +279,15 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Target.Clear; -- checks busy bit Target.Clear; -- checks busy bit
-- Copy_Children returns the number of nodes that it allocates, -- Copy_Children returns the number of nodes that it allocates, but it
-- but it does this by incrementing the count value passed in, -- does this by incrementing the count value passed in, so we must
-- so we must initialize the count before calling Copy_Children. -- initialize the count before calling Copy_Children.
Target_Count := 0; Target_Count := 0;
-- Note that Copy_Children inserts the newly-allocated children -- Note that Copy_Children inserts the newly-allocated children into
-- into their parent list only after the allocation of all the -- their parent list only after the allocation of all the children has
-- children has succeeded. This preserves invariants even if -- succeeded. This preserves invariants even if the allocation fails.
-- the allocation fails.
Copy_Children (Source.Root.Children, Root_Node (Target), Target_Count); Copy_Children (Source.Root.Children, Root_Node (Target), Target_Count);
pragma Assert (Target_Count = Source_Count); pragma Assert (Target_Count = Source_Count);
...@@ -303,7 +300,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -303,7 +300,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
----------- -----------
procedure Clear (Container : in out Tree) is procedure Clear (Container : in out Tree) is
Container_Count, Children_Count : Count_Type; Container_Count : Count_Type;
Children_Count : Count_Type;
begin begin
if Container.Busy > 0 then if Container.Busy > 0 then
...@@ -311,28 +309,24 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -311,28 +309,24 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
with "attempt to tamper with cursors (tree is busy)"; with "attempt to tamper with cursors (tree is busy)";
end if; end if;
-- We first set the container count to 0, in order to -- We first set the container count to 0, in order to preserve
-- preserve invariants in case the deallocation fails. -- invariants in case the deallocation fails. (This works because
-- (This works because Deallocate_Children immediately -- Deallocate_Children immediately removes the children from their
-- removes the children from their parent, and then -- parent, and then does the actual deallocation.)
-- does the actual deallocation.)
Container_Count := Container.Count; Container_Count := Container.Count;
Container.Count := 0; Container.Count := 0;
-- Deallocate_Children returns the number of nodes that -- Deallocate_Children returns the number of nodes that it deallocates,
-- it deallocates, but it does this by incrementing the -- but it does this by incrementing the count value that is passed in,
-- count value that is passed in, so we must first initialize -- so we must first initialize the count return value before calling it.
-- the count return value before calling it.
Children_Count := 0; Children_Count := 0;
-- See comment above. Deallocate_Children immediately -- See comment above. Deallocate_Children immediately removes the
-- removes the children list from their parent node (here, -- children list from their parent node (here, the root of the tree),
-- the root of the tree), and only after that does it -- and only after that does it attempt the actual deallocation. So even
-- attempt the actual deallocation. So even if the -- if the deallocation fails, the representation invariants
-- deallocation fails, the representation invariants
-- for the tree are preserved.
Deallocate_Children (Root_Node (Container), Children_Count); Deallocate_Children (Root_Node (Container), Children_Count);
pragma Assert (Children_Count = Container_Count); pragma Assert (Children_Count = Container_Count);
...@@ -383,9 +377,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -383,9 +377,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C : Tree_Node_Access; C : Tree_Node_Access;
begin begin
-- We special-case the first allocation, in order -- We special-case the first allocation, in order to establish the
-- to establish the representation invariants -- representation invariants for type Children_Type.
-- for type Children_Type.
C := Source.First; C := Source.First;
...@@ -401,9 +394,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -401,9 +394,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
CC.Last := CC.First; CC.Last := CC.First;
-- The representation invariants for the Children_Type -- The representation invariants for the Children_Type list have been
-- list have been established, so we can now copy -- established, so we can now copy the remaining children of Source.
-- the remaining children of Source.
C := C.Next; C := C.Next;
while C /= null loop while C /= null loop
...@@ -419,9 +411,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -419,9 +411,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C := C.Next; C := C.Next;
end loop; end loop;
-- We add the newly-allocated children to their parent list -- We add the newly-allocated children to their parent list only after
-- only after the allocation has succeeded, in order to -- the allocation has succeeded, in order to preserve invariants of the
-- preserve invariants of the parent. -- parent.
Parent.Children := CC; Parent.Children := CC;
end Copy_Children; end Copy_Children;
...@@ -450,6 +442,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -450,6 +442,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Result := Result + 1; Result := Result + 1;
Node := Node.Next; Node := Node.Next;
end loop; end loop;
return Result; return Result;
end Child_Count; end Child_Count;
...@@ -484,6 +477,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -484,6 +477,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
raise Program_Error with "Parent is not ancestor of Child"; raise Program_Error with "Parent is not ancestor of Child";
end if; end if;
end loop; end loop;
return Result; return Result;
end Child_Depth; end Child_Depth;
...@@ -527,10 +521,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -527,10 +521,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
raise Constraint_Error with "Source cursor designates root"; raise Constraint_Error with "Source cursor designates root";
end if; end if;
-- Copy_Subtree returns a count of the number of nodes -- Copy_Subtree returns a count of the number of nodes that it
-- that it allocates, but it works by incrementing the -- allocates, but it works by incrementing the value that is passed in.
-- value that is passed in. We must therefore initialize -- We must therefore initialize the count value before calling
-- the count value before calling Copy_Subtree. -- Copy_Subtree.
Target_Count := 0; Target_Count := 0;
...@@ -549,10 +543,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -549,10 +543,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Before.Node); Before => Before.Node);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Target.Count := Target.Count + Target_Count; Target.Count := Target.Count + Target_Count;
end Copy_Subtree; end Copy_Subtree;
...@@ -590,9 +583,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -590,9 +583,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C : Tree_Node_Access; C : Tree_Node_Access;
begin begin
-- We immediately remove the children from their -- We immediately remove the children from their parent, in order to
-- parent, in order to preserve invariants in case -- preserve invariants in case the deallocation fails.
-- the deallocation fails.
Subtree.Children := Children_Type'(others => null); Subtree.Children := Children_Type'(others => null);
...@@ -707,16 +699,15 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -707,16 +699,15 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
X := Position.Node; X := Position.Node;
Position := No_Element; Position := No_Element;
-- Restore represention invariants before attempting the -- Restore represention invariants before attempting the actual
-- actual deallocation. -- deallocation.
Remove_Subtree (X); Remove_Subtree (X);
Container.Count := Container.Count - 1; Container.Count := Container.Count - 1;
-- It is now safe to attempt the deallocation. This leaf -- It is now safe to attempt the deallocation. This leaf node has been
-- node has been disassociated from the tree, so even if -- disassociated from the tree, so even if the deallocation fails,
-- the deallocation fails, representation invariants -- representation invariants will remain satisfied.
-- will remain satisfied.
Deallocate_Node (X); Deallocate_Node (X);
end Delete_Leaf; end Delete_Leaf;
...@@ -753,38 +744,35 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -753,38 +744,35 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
X := Position.Node; X := Position.Node;
Position := No_Element; Position := No_Element;
-- Here is one case where a deallocation failure can -- Here is one case where a deallocation failure can result in the
-- result in the violation of a representation invariant. -- violation of a representation invariant. We disassociate the subtree
-- We disassociate the subtree from the tree now, but we -- from the tree now, but we only decrement the total node count after
-- only decrement the total node count after we attempt -- we attempt the deallocation. However, if the deallocation fails, the
-- the deallocation. However, if the deallocation fails, -- total node count will not get decremented.
-- the total node count will not get decremented.
-- -- One way around this dilemma is to count the nodes in the subtree
-- One way around this dilemma is to count the nodes -- before attempt to delete the subtree, but that is an O(n) operation,
-- in the subtree before attempt to delete the subtree, -- so it does not seem worth it.
-- but that is an O(n) operation, so it does not seem
-- worth it. -- Perhaps this is much ado about nothing, since the only way
-- -- deallocation can fail is if Controlled Finalization fails: this
-- Perhaps this is much ado about nothing, since the -- propagates Program_Error so all bets are off anyway. ???
-- only way deallocation can fail is if Controlled
-- Finalization fails: this propagates Program_Error
-- so all bets are off anyway. ???
Remove_Subtree (X); Remove_Subtree (X);
-- Deallocate_Subtree returns a count of the number of nodes -- Deallocate_Subtree returns a count of the number of nodes that it
-- that it deallocates, but it works by incrementing the -- deallocates, but it works by incrementing the value that is passed
-- value that is passed in. We must therefore initialize -- in. We must therefore initialize the count value before calling
-- the count value before calling Deallocate_Subtree. -- Deallocate_Subtree.
Count := 0; Count := 0;
Deallocate_Subtree (X, Count); Deallocate_Subtree (X, Count);
pragma Assert (Count <= Container.Count); pragma Assert (Count <= Container.Count);
-- See comments above. We would prefer to do this -- See comments above. We would prefer to do this sooner, but there's no
-- sooner, but there's no way to satisfy that goal -- way to satisfy that goal without an potentially severe execution
-- without an potentially severe execution penalty. -- penalty.
Container.Count := Container.Count - Count; Container.Count := Container.Count - Count;
end Delete_Subtree; end Delete_Subtree;
...@@ -804,6 +792,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -804,6 +792,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
N := N.Parent; N := N.Parent;
Result := Result + 1; Result := Result + 1;
end loop; end loop;
return Result; return Result;
end Depth; end Depth;
...@@ -1122,10 +1111,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1122,10 +1111,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Before.Node); Before => Before.Node);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Insert_Child; end Insert_Child;
...@@ -1144,11 +1132,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1144,11 +1132,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C : Children_Type renames Parent.Children; C : Children_Type renames Parent.Children;
begin begin
-- This is a simple utility operation to -- This is a simple utility operation to insert a list of nodes (from
-- insert a list of nodes (from First..Last) -- First..Last) as children of Parent. The Before node specifies where
-- as children of Parent. The Before node -- the new children should be inserted relative to the existing
-- specifies where the new children should be -- children.
-- inserted relative to the existing children.
if First = null then if First = null then
pragma Assert (Last = null); pragma Assert (Last = null);
...@@ -1194,8 +1181,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1194,8 +1181,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Before : Tree_Node_Access) Before : Tree_Node_Access)
is is
begin begin
-- This is a simple wrapper operation to insert -- This is a simple wrapper operation to insert a single child into the
-- a single child into the Parent's children list. -- Parent's children list.
Insert_Subtree_List Insert_Subtree_List
(First => Subtree, (First => Subtree,
...@@ -1282,6 +1269,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1282,6 +1269,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Process => Process); Process => Process);
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1315,6 +1303,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1315,6 +1303,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
end loop; end loop;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1330,13 +1319,11 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1330,13 +1319,11 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Node : Tree_Node_Access; Node : Tree_Node_Access;
begin begin
-- This is a helper function to recursively iterate over -- This is a helper function to recursively iterate over all the nodes
-- all the nodes in a subtree, in depth-first fashion. -- in a subtree, in depth-first fashion. This particular helper just
-- This particular helper just visits the children of this -- visits the children of this subtree, not the root of the subtree node
-- subtree, not the root of the subtree node itself. This -- itself. This is useful when starting from the ultimate root of the
-- is useful when starting from the ultimate root of the -- entire tree (see Iterate), as that root does not have an element.
-- entire tree (see Iterate), as that root does not have
-- an element.
Node := Subtree.Children.First; Node := Subtree.Children.First;
while Node /= null loop while Node /= null loop
...@@ -1366,12 +1353,12 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1366,12 +1353,12 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
if Is_Root (Position) then if Is_Root (Position) then
Iterate_Children (Position.Container, Position.Node, Process); Iterate_Children (Position.Container, Position.Node, Process);
else else
Iterate_Subtree (Position.Container, Position.Node, Process); Iterate_Subtree (Position.Container, Position.Node, Process);
end if; end if;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1385,10 +1372,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1385,10 +1372,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Process : not null access procedure (Position : Cursor)) Process : not null access procedure (Position : Cursor))
is is
begin begin
-- This is a helper function to recursively iterate over -- This is a helper function to recursively iterate over all the nodes
-- all the nodes in a subtree, in depth-first fashion. -- in a subtree, in depth-first fashion. It first visits the root of the
-- It first visits the root of the subtree, then visits -- subtree, then visits its children.
-- its children.
Process (Cursor'(Container, Subtree)); Process (Cursor'(Container, Subtree));
Iterate_Children (Container, Subtree, Process); Iterate_Children (Container, Subtree, Process);
...@@ -1484,17 +1470,15 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1484,17 +1470,15 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
function Node_Count (Container : Tree) return Count_Type is function Node_Count (Container : Tree) return Count_Type is
begin begin
-- Container.Count is the number of nodes we have actually -- Container.Count is the number of nodes we have actually allocated. We
-- allocated. We cache the value specifically so this Node_Count -- cache the value specifically so this Node_Count operation can execute
-- operation can execute in O(1) time, which makes it behave -- in O(1) time, which makes it behave similarly to how the Length
-- similarly to how the Length selector function behaves -- selector function behaves for other containers.
-- for other containers.
-- --
-- The cached node count value only describes the nodes -- The cached node count value only describes the nodes we have
-- we have allocated; the root node itself is not included -- allocated; the root node itself is not included in that count. The
-- in that count. The Node_Count operation returns a value -- Node_Count operation returns a value that includes the root node
-- that includes the root node (because the RM says so), so we -- (because the RM says so), so we must add 1 to our cached value.
-- must add 1 to our cached value.
return 1 + Container.Count; return 1 + Container.Count;
end Node_Count; end Node_Count;
...@@ -1555,6 +1539,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1555,6 +1539,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Last := First; Last := First;
for J in Count_Type'(2) .. Count loop for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ??? -- Reclaim other nodes if Storage_Error. ???
Element := new Element_Type'(New_Item); Element := new Element_Type'(New_Item);
...@@ -1572,10 +1557,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1572,10 +1557,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Parent.Node.Children.First); Before => Parent.Node.Children.First);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Prepend_Child; end Prepend_Child;
...@@ -1632,6 +1616,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1632,6 +1616,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
L := L - 1; L := L - 1;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
L := L - 1; L := L - 1;
...@@ -1653,7 +1638,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1653,7 +1638,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
function Read_Subtree function Read_Subtree
(Parent : Tree_Node_Access) return Tree_Node_Access; (Parent : Tree_Node_Access) return Tree_Node_Access;
Total_Count, Read_Count : Count_Type; Total_Count : Count_Type;
Read_Count : Count_Type;
------------------- -------------------
-- Read_Children -- -- Read_Children --
...@@ -1664,7 +1650,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1664,7 +1650,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
pragma Assert (Subtree.Children.First = null); pragma Assert (Subtree.Children.First = null);
pragma Assert (Subtree.Children.Last = null); pragma Assert (Subtree.Children.Last = null);
Count : Count_Type; -- number of child subtrees Count : Count_Type;
-- Number of child subtrees
C : Children_Type; C : Children_Type;
begin begin
...@@ -1687,8 +1675,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1687,8 +1675,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C.Last := C.Last.Next; C.Last := C.Last.Next;
end loop; end loop;
-- Now that the allocation and reads have completed successfully, -- Now that the allocation and reads have completed successfully, it
-- it is safe to link the children to their parent. -- is safe to link the children to their parent.
Subtree.Children := C; Subtree.Children := C;
end Read_Children; end Read_Children;
...@@ -1759,8 +1747,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1759,8 +1747,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C : Children_Type renames Subtree.Parent.Children; C : Children_Type renames Subtree.Parent.Children;
begin begin
-- This is a utility operation to remove a subtree -- This is a utility operation to remove a subtree node from its
-- node from its parent's list of children. -- parent's list of children.
if C.First = Subtree then if C.First = Subtree then
pragma Assert (Subtree.Prev = null); pragma Assert (Subtree.Prev = null);
...@@ -1850,6 +1838,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1850,6 +1838,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
end loop; end loop;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1954,10 +1943,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -1954,10 +1943,10 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
with "attempt to tamper with cursors (Source tree is busy)"; with "attempt to tamper with cursors (Source tree is busy)";
end if; end if;
-- We cache the count of the nodes we have allocated, so that -- We cache the count of the nodes we have allocated, so that operation
-- operation Node_Count can execute in O(1) time. But that means -- Node_Count can execute in O(1) time. But that means we must count the
-- we must count the nodes in the subtree we remove from Source -- nodes in the subtree we remove from Source and insert into Target, in
-- and insert into Target, in order to keep the count accurate. -- order to keep the count accurate.
Count := Subtree_Node_Count (Source_Parent.Node); Count := Subtree_Node_Count (Source_Parent.Node);
pragma Assert (Count >= 1); pragma Assert (Count >= 1);
...@@ -2041,13 +2030,13 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -2041,13 +2030,13 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
C : Tree_Node_Access; C : Tree_Node_Access;
begin begin
-- This is a utility operation to remove the children from -- This is a utility operation to remove the children from Source parent
-- Source parent and insert them into Target parent. -- and insert them into Target parent.
Source_Parent.Children := Children_Type'(others => null); Source_Parent.Children := Children_Type'(others => null);
-- Fix up the Parent pointers of each child to designate -- Fix up the Parent pointers of each child to designate its new Target
-- its new Target parent. -- parent.
C := CC.First; C := CC.First;
while C /= null loop while C /= null loop
...@@ -2140,17 +2129,16 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -2140,17 +2129,16 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
with "attempt to tamper with cursors (Source tree is busy)"; with "attempt to tamper with cursors (Source tree is busy)";
end if; end if;
-- This is an unfortunate feature of this API: we must count -- This is an unfortunate feature of this API: we must count the nodes
-- the nodes in the subtree that we remove from the source tree, -- in the subtree that we remove from the source tree, which is an O(n)
-- which is an O(n) operation. It would have been better if -- operation. It would have been better if the Tree container did not
-- the Tree container did not have a Node_Count selector; a -- have a Node_Count selector; a user that wants the number of nodes in
-- user that wants the number of nodes in the tree could -- the tree could simply call Subtree_Node_Count, with the understanding
-- simply call Subtree_Node_Count, with the understanding that -- that such an operation is O(n).
-- such an operation is O(n).
-- --
-- Of course, we could choose to implement the Node_Count selector -- Of course, we could choose to implement the Node_Count selector as an
-- as an O(n) operation, which would turn this splice operation -- O(n) operation, which would turn this splice operation into an O(1)
-- into an O(1) operation. ??? -- operation. ???
Subtree_Count := Subtree_Node_Count (Position.Node); Subtree_Count := Subtree_Node_Count (Position.Node);
pragma Assert (Subtree_Count <= Source.Count); pragma Assert (Subtree_Count <= Source.Count);
...@@ -2200,7 +2188,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -2200,7 +2188,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
end if; end if;
if Is_Root (Position) then if Is_Root (Position) then
-- Should this be PE instead? Need ARG confirmation. ??? -- Should this be PE instead? Need ARG confirmation. ???
raise Constraint_Error with "Position cursor designates root"; raise Constraint_Error with "Position cursor designates root";
end if; end if;
...@@ -2251,6 +2241,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -2251,6 +2241,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Result := Result + Subtree_Node_Count (Node); Result := Result + Subtree_Node_Count (Node);
Node := Node.Next; Node := Node.Next;
end loop; end loop;
return Result; return Result;
end Subtree_Node_Count; end Subtree_Node_Count;
...@@ -2340,6 +2331,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is ...@@ -2340,6 +2331,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
L := L - 1; L := L - 1;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
L := L - 1; L := L - 1;
......
...@@ -231,8 +231,8 @@ package Ada.Containers.Indefinite_Multiway_Trees is ...@@ -231,8 +231,8 @@ package Ada.Containers.Indefinite_Multiway_Trees is
-- Parent : Cursor; -- Parent : Cursor;
-- Process : not null access procedure (Position : Cursor)); -- Process : not null access procedure (Position : Cursor));
-- --
-- It seems that the Container parameter is there by mistake, but -- It seems that the Container parameter is there by mistake, but we need
-- we need an official ruling from the ARG. ??? -- an official ruling from the ARG. ???
procedure Iterate_Children procedure Iterate_Children
(Parent : Cursor; (Parent : Cursor;
...@@ -264,19 +264,17 @@ private ...@@ -264,19 +264,17 @@ private
use Ada.Finalization; use Ada.Finalization;
-- The Count component of type Tree represents the number of -- The Count component of type Tree represents the number of nodes that
-- nodes that have been (dynamically) allocated. It does not -- have been (dynamically) allocated. It does not include the root node
-- include the root node itself. As implementors, we decide -- itself. As implementors, we decide to cache this value, so that the
-- to cache this value, so that the selector function Node_Count -- selector function Node_Count can execute in O(1) time, in order to be
-- can execute in O(1) time, in order to be consistent with -- consistent with the behavior of the Length selector function for other
-- the behavior of the Length selector function for other -- standard container library units. This does mean, however, that the
-- standard container library units. This does mean, however, -- two-container forms for Splice_XXX (that move subtrees across tree
-- that the two-container forms for Splice_XXX (that move subtrees -- containers) will execute in O(n) time, because we must count the number
-- across tree containers) will execute in O(n) time, because -- of nodes in the subtree(s) that get moved. (We resolve the tension
-- we must count the number of nodes in the subtree(s) that -- between Node_Count and Splice_XXX in favor of Node_Count, under the
-- get moved. (We resolve the tension between Node_Count -- assumption that Node_Count is the more common operation).
-- and Splice_XXX in favor of Node_Count, under the assumption
-- that Node_Count is the more common operation).
type Tree is new Controlled with record type Tree is new Controlled with record
Root : aliased Tree_Node_Type; Root : aliased Tree_Node_Type;
......
...@@ -133,25 +133,24 @@ package body Ada.Containers.Multiway_Trees is ...@@ -133,25 +133,24 @@ package body Ada.Containers.Multiway_Trees is
Target_Count : Count_Type; Target_Count : Count_Type;
begin begin
-- We first restore the target container to its -- We first restore the target container to its default-initialized
-- default-initialized state, before we attempt any -- state, before we attempt any allocation, to ensure that invariants
-- allocation, to ensure that invariants are preserved -- are preserved in the event that the allocation fails.
-- in the event that the allocation fails.
Container.Root.Children := Children_Type'(others => null); Container.Root.Children := Children_Type'(others => null);
Container.Busy := 0; Container.Busy := 0;
Container.Lock := 0; Container.Lock := 0;
Container.Count := 0; Container.Count := 0;
-- Copy_Children returns a count of the number of nodes -- Copy_Children returns a count of the number of nodes that it
-- that it allocates, but it works by incrementing the -- allocates, but it works by incrementing the value that is passed
-- value that is passed in. We must therefore initialize -- in. We must therefore initialize the count value before calling
-- the count value before calling Copy_Children. -- Copy_Children.
Target_Count := 0; Target_Count := 0;
-- Now we attempt the allocation of subtrees. The invariants -- Now we attempt the allocation of subtrees. The invariants are
-- are satisfied even if the allocation fails. -- satisfied even if the allocation fails.
Copy_Children (Source, Root_Node (Container), Target_Count); Copy_Children (Source, Root_Node (Container), Target_Count);
pragma Assert (Target_Count = Source_Count); pragma Assert (Target_Count = Source_Count);
...@@ -180,11 +179,10 @@ package body Ada.Containers.Multiway_Trees is ...@@ -180,11 +179,10 @@ package body Ada.Containers.Multiway_Trees is
raise Program_Error with "Position cursor not in container"; raise Program_Error with "Position cursor not in container";
end if; end if;
-- AI-0136 says to raise PE if Position equals the root node. -- AI-0136 says to raise PE if Position equals the root node. This does
-- This does not seem correct, as this value is just the limiting -- not seem correct, as this value is just the limiting condition of the
-- condition of the search. For now we omit this check, -- search. For now we omit this check, pending a ruling from the ARG.???
-- pending a ruling from the ARG. ???
--
-- if Is_Root (Position) then -- if Is_Root (Position) then
-- raise Program_Error with "Position cursor designates root"; -- raise Program_Error with "Position cursor designates root";
-- end if; -- end if;
...@@ -238,7 +236,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -238,7 +236,9 @@ package body Ada.Containers.Multiway_Trees is
Last := First; Last := First;
for J in Count_Type'(2) .. Count loop for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ??? -- Reclaim other nodes if Storage_Error. ???
Last.Next := new Tree_Node_Type'(Parent => Parent.Node, Last.Next := new Tree_Node_Type'(Parent => Parent.Node,
Prev => Last, Prev => Last,
Element => New_Item, Element => New_Item,
...@@ -253,10 +253,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -253,10 +253,9 @@ package body Ada.Containers.Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => null); -- null means "insert at end of list" Before => null); -- null means "insert at end of list"
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Append_Child; end Append_Child;
...@@ -276,16 +275,15 @@ package body Ada.Containers.Multiway_Trees is ...@@ -276,16 +275,15 @@ package body Ada.Containers.Multiway_Trees is
Target.Clear; -- checks busy bit Target.Clear; -- checks busy bit
-- Copy_Children returns the number of nodes that it allocates, -- Copy_Children returns the number of nodes that it allocates, but it
-- but it does this by incrementing the count value passed in, -- does this by incrementing the count value passed in, so we must
-- so we must initialize the count before calling Copy_Children. -- initialize the count before calling Copy_Children.
Target_Count := 0; Target_Count := 0;
-- Note that Copy_Children inserts the newly-allocated children -- Note that Copy_Children inserts the newly-allocated children into
-- into their parent list only after the allocation of all the -- their parent list only after the allocation of all the children has
-- children has succeeded. This preserves invariants even if -- succeeded. This preserves invariants even if the allocation fails.
-- the allocation fails.
Copy_Children (Source.Root.Children, Root_Node (Target), Target_Count); Copy_Children (Source.Root.Children, Root_Node (Target), Target_Count);
pragma Assert (Target_Count = Source_Count); pragma Assert (Target_Count = Source_Count);
...@@ -306,28 +304,25 @@ package body Ada.Containers.Multiway_Trees is ...@@ -306,28 +304,25 @@ package body Ada.Containers.Multiway_Trees is
with "attempt to tamper with cursors (tree is busy)"; with "attempt to tamper with cursors (tree is busy)";
end if; end if;
-- We first set the container count to 0, in order to -- We first set the container count to 0, in order to preserve
-- preserve invariants in case the deallocation fails. -- invariants in case the deallocation fails. (This works because
-- (This works because Deallocate_Children immediately -- Deallocate_Children immediately removes the children from their
-- removes the children from their parent, and then -- parent, and then does the actual deallocation.)
-- does the actual deallocation.)
Container_Count := Container.Count; Container_Count := Container.Count;
Container.Count := 0; Container.Count := 0;
-- Deallocate_Children returns the number of nodes that -- Deallocate_Children returns the number of nodes that it deallocates,
-- it deallocates, but it does this by incrementing the -- but it does this by incrementing the count value that is passed in,
-- count value that is passed in, so we must first initialize -- so we must first initialize the count return value before calling it.
-- the count return value before calling it.
Children_Count := 0; Children_Count := 0;
-- See comment above. Deallocate_Children immediately -- See comment above. Deallocate_Children immediately removes the
-- removes the children list from their parent node (here, -- children list from their parent node (here, the root of the tree),
-- the root of the tree), and only after that does it -- and only after that does it attempt the actual deallocation. So even
-- attempt the actual deallocation. So even if the -- if the deallocation fails, the representation invariants for the tree
-- deallocation fails, the representation invariants -- are preserved.
-- for the tree are preserved.
Deallocate_Children (Root_Node (Container), Children_Count); Deallocate_Children (Root_Node (Container), Children_Count);
pragma Assert (Children_Count = Container_Count); pragma Assert (Children_Count = Container_Count);
...@@ -378,9 +373,8 @@ package body Ada.Containers.Multiway_Trees is ...@@ -378,9 +373,8 @@ package body Ada.Containers.Multiway_Trees is
C : Tree_Node_Access; C : Tree_Node_Access;
begin begin
-- We special-case the first allocation, in order -- We special-case the first allocation, in order to establish the
-- to establish the representation invariants -- representation invariants for type Children_Type.
-- for type Children_Type.
C := Source.First; C := Source.First;
...@@ -396,9 +390,8 @@ package body Ada.Containers.Multiway_Trees is ...@@ -396,9 +390,8 @@ package body Ada.Containers.Multiway_Trees is
CC.Last := CC.First; CC.Last := CC.First;
-- The representation invariants for the Children_Type -- The representation invariants for the Children_Type list have been
-- list have been established, so we can now copy -- established, so we can now copy the remaining children of Source.
-- the remaining children of Source.
C := C.Next; C := C.Next;
while C /= null loop while C /= null loop
...@@ -414,9 +407,8 @@ package body Ada.Containers.Multiway_Trees is ...@@ -414,9 +407,8 @@ package body Ada.Containers.Multiway_Trees is
C := C.Next; C := C.Next;
end loop; end loop;
-- We add the newly-allocated children to their parent list -- Add the newly-allocated children to their parent list only after the
-- only after the allocation has succeeded, in order to -- allocation has succeeded, so as to preserve invariants of the parent.
-- preserve invariants of the parent.
Parent.Children := CC; Parent.Children := CC;
end Copy_Children; end Copy_Children;
...@@ -445,6 +437,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -445,6 +437,7 @@ package body Ada.Containers.Multiway_Trees is
Result := Result + 1; Result := Result + 1;
Node := Node.Next; Node := Node.Next;
end loop; end loop;
return Result; return Result;
end Child_Count; end Child_Count;
...@@ -479,6 +472,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -479,6 +472,7 @@ package body Ada.Containers.Multiway_Trees is
raise Program_Error with "Parent is not ancestor of Child"; raise Program_Error with "Parent is not ancestor of Child";
end if; end if;
end loop; end loop;
return Result; return Result;
end Child_Depth; end Child_Depth;
...@@ -522,10 +516,10 @@ package body Ada.Containers.Multiway_Trees is ...@@ -522,10 +516,10 @@ package body Ada.Containers.Multiway_Trees is
raise Constraint_Error with "Source cursor designates root"; raise Constraint_Error with "Source cursor designates root";
end if; end if;
-- Copy_Subtree returns a count of the number of nodes -- Copy_Subtree returns a count of the number of nodes that it
-- that it allocates, but it works by incrementing the -- allocates, but it works by incrementing the value that is passed
-- value that is passed in. We must therefore initialize -- in. We must therefore initialize the count value before calling
-- the count value before calling Copy_Subtree. -- Copy_Subtree.
Target_Count := 0; Target_Count := 0;
...@@ -544,10 +538,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -544,10 +538,9 @@ package body Ada.Containers.Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Before.Node); Before => Before.Node);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Target.Count := Target.Count + Target_Count; Target.Count := Target.Count + Target_Count;
end Copy_Subtree; end Copy_Subtree;
...@@ -585,9 +578,8 @@ package body Ada.Containers.Multiway_Trees is ...@@ -585,9 +578,8 @@ package body Ada.Containers.Multiway_Trees is
C : Tree_Node_Access; C : Tree_Node_Access;
begin begin
-- We immediately remove the children from their -- We immediately remove the children from their parent, in order to
-- parent, in order to preserve invariants in case -- preserve invariants in case the deallocation fails.
-- the deallocation fails.
Subtree.Children := Children_Type'(others => null); Subtree.Children := Children_Type'(others => null);
...@@ -637,10 +629,10 @@ package body Ada.Containers.Multiway_Trees is ...@@ -637,10 +629,10 @@ package body Ada.Containers.Multiway_Trees is
with "attempt to tamper with cursors (tree is busy)"; with "attempt to tamper with cursors (tree is busy)";
end if; end if;
-- Deallocate_Children returns a count of the number of nodes -- Deallocate_Children returns a count of the number of nodes that it
-- that it deallocates, but it works by incrementing the -- deallocates, but it works by incrementing the value that is passed
-- value that is passed in. We must therefore initialize -- in. We must therefore initialize the count value before calling
-- the count value before calling Deallocate_Children. -- Deallocate_Children.
Count := 0; Count := 0;
...@@ -685,16 +677,15 @@ package body Ada.Containers.Multiway_Trees is ...@@ -685,16 +677,15 @@ package body Ada.Containers.Multiway_Trees is
X := Position.Node; X := Position.Node;
Position := No_Element; Position := No_Element;
-- Restore represention invariants before attempting the -- Restore represention invariants before attempting the actual
-- actual deallocation. -- deallocation.
Remove_Subtree (X); Remove_Subtree (X);
Container.Count := Container.Count - 1; Container.Count := Container.Count - 1;
-- It is now safe to attempt the deallocation. This leaf -- It is now safe to attempt the deallocation. This leaf node has been
-- node has been disassociated from the tree, so even if -- disassociated from the tree, so even if the deallocation fails,
-- the deallocation fails, representation invariants -- representation invariants will remain satisfied.
-- will remain satisfied.
Deallocate_Node (X); Deallocate_Node (X);
end Delete_Leaf; end Delete_Leaf;
...@@ -731,38 +722,35 @@ package body Ada.Containers.Multiway_Trees is ...@@ -731,38 +722,35 @@ package body Ada.Containers.Multiway_Trees is
X := Position.Node; X := Position.Node;
Position := No_Element; Position := No_Element;
-- Here is one case where a deallocation failure can -- Here is one case where a deallocation failure can result in the
-- result in the violation of a representation invariant. -- violation of a representation invariant. We disassociate the subtree
-- We disassociate the subtree from the tree now, but we -- from the tree now, but we only decrement the total node count after
-- only decrement the total node count after we attempt -- we attempt the deallocation. However, if the deallocation fails, the
-- the deallocation. However, if the deallocation fails, -- total node count will not get decremented.
-- the total node count will not get decremented.
-- -- One way around this dilemma is to count the nodes in the subtree
-- One way around this dilemma is to count the nodes -- before attempt to delete the subtree, but that is an O(n) operation,
-- in the subtree before attempt to delete the subtree, -- so it does not seem worth it.
-- but that is an O(n) operation, so it does not seem
-- worth it. -- Perhaps this is much ado about nothing, since the only way
-- -- deallocation can fail is if Controlled Finalization fails: this
-- Perhaps this is much ado about nothing, since the -- propagates Program_Error so all bets are off anyway. ???
-- only way deallocation can fail is if Controlled
-- Finalization fails: this propagates Program_Error
-- so all bets are off anyway. ???
Remove_Subtree (X); Remove_Subtree (X);
-- Deallocate_Subtree returns a count of the number of nodes -- Deallocate_Subtree returns a count of the number of nodes that it
-- that it deallocates, but it works by incrementing the -- deallocates, but it works by incrementing the value that is passed
-- value that is passed in. We must therefore initialize -- in. We must therefore initialize the count value before calling
-- the count value before calling Deallocate_Subtree. -- Deallocate_Subtree.
Count := 0; Count := 0;
Deallocate_Subtree (X, Count); Deallocate_Subtree (X, Count);
pragma Assert (Count <= Container.Count); pragma Assert (Count <= Container.Count);
-- See comments above. We would prefer to do this -- See comments above. We would prefer to do this sooner, but there's no
-- sooner, but there's no way to satisfy that goal -- way to satisfy that goal without a potentially severe execution
-- without an potentially severe execution penalty. -- penalty.
Container.Count := Container.Count - Count; Container.Count := Container.Count - Count;
end Delete_Subtree; end Delete_Subtree;
...@@ -782,6 +770,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -782,6 +770,7 @@ package body Ada.Containers.Multiway_Trees is
N := N.Parent; N := N.Parent;
Result := Result + 1; Result := Result + 1;
end loop; end loop;
return Result; return Result;
end Depth; end Depth;
...@@ -1080,7 +1069,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1080,7 +1069,9 @@ package body Ada.Containers.Multiway_Trees is
Last := Position.Node; Last := Position.Node;
for J in Count_Type'(2) .. Count loop for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ??? -- Reclaim other nodes if Storage_Error. ???
Last.Next := new Tree_Node_Type'(Parent => Parent.Node, Last.Next := new Tree_Node_Type'(Parent => Parent.Node,
Prev => Last, Prev => Last,
Element => New_Item, Element => New_Item,
...@@ -1095,10 +1086,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1095,10 +1086,9 @@ package body Ada.Containers.Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Before.Node); Before => Before.Node);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Insert_Child; end Insert_Child;
...@@ -1149,7 +1139,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1149,7 +1139,9 @@ package body Ada.Containers.Multiway_Trees is
Last := Position.Node; Last := Position.Node;
for J in Count_Type'(2) .. Count loop for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ??? -- Reclaim other nodes if Storage_Error. ???
Last.Next := new Tree_Node_Type'(Parent => Parent.Node, Last.Next := new Tree_Node_Type'(Parent => Parent.Node,
Prev => Last, Prev => Last,
Element => <>, Element => <>,
...@@ -1164,10 +1156,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1164,10 +1156,9 @@ package body Ada.Containers.Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Before.Node); Before => Before.Node);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Insert_Child; end Insert_Child;
...@@ -1186,11 +1177,10 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1186,11 +1177,10 @@ package body Ada.Containers.Multiway_Trees is
C : Children_Type renames Parent.Children; C : Children_Type renames Parent.Children;
begin begin
-- This is a simple utility operation to -- This is a simple utility operation to insert a list of nodes (from
-- insert a list of nodes (from First..Last) -- First..Last) as children of Parent. The Before node specifies where
-- as children of Parent. The Before node -- the new children should be inserted relative to the existing
-- specifies where the new children should be -- children.
-- inserted relative to the existing children.
if First = null then if First = null then
pragma Assert (Last = null); pragma Assert (Last = null);
...@@ -1236,8 +1226,8 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1236,8 +1226,8 @@ package body Ada.Containers.Multiway_Trees is
Before : Tree_Node_Access) Before : Tree_Node_Access)
is is
begin begin
-- This is a simple wrapper operation to insert -- This is a simple wrapper operation to insert a single child into the
-- a single child into the Parent's children list. -- Parent's children list.
Insert_Subtree_List Insert_Subtree_List
(First => Subtree, (First => Subtree,
...@@ -1324,6 +1314,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1324,6 +1314,7 @@ package body Ada.Containers.Multiway_Trees is
Process => Process); Process => Process);
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1357,6 +1348,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1357,6 +1348,7 @@ package body Ada.Containers.Multiway_Trees is
end loop; end loop;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1372,13 +1364,11 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1372,13 +1364,11 @@ package body Ada.Containers.Multiway_Trees is
Node : Tree_Node_Access; Node : Tree_Node_Access;
begin begin
-- This is a helper function to recursively iterate over -- This is a helper function to recursively iterate over all the nodes
-- all the nodes in a subtree, in depth-first fashion. -- in a subtree, in depth-first fashion. This particular helper just
-- This particular helper just visits the children of this -- visits the children of this subtree, not the root of the subtree node
-- subtree, not the root of the subtree node itself. This -- itself. This is useful when starting from the ultimate root of the
-- is useful when starting from the ultimate root of the -- entire tree (see Iterate), as that root does not have an element.
-- entire tree (see Iterate), as that root does not have
-- an element.
Node := Subtree.Children.First; Node := Subtree.Children.First;
while Node /= null loop while Node /= null loop
...@@ -1414,6 +1404,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1414,6 +1404,7 @@ package body Ada.Containers.Multiway_Trees is
end if; end if;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1427,10 +1418,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1427,10 +1418,9 @@ package body Ada.Containers.Multiway_Trees is
Process : not null access procedure (Position : Cursor)) Process : not null access procedure (Position : Cursor))
is is
begin begin
-- This is a helper function to recursively iterate over -- This is a helper function to recursively iterate over all the nodes
-- all the nodes in a subtree, in depth-first fashion. -- in a subtree, in depth-first fashion. It first visits the root of the
-- It first visits the root of the subtree, then visits -- subtree, then visits its children.
-- its children.
Process (Cursor'(Container, Subtree)); Process (Cursor'(Container, Subtree));
Iterate_Children (Container, Subtree, Process); Iterate_Children (Container, Subtree, Process);
...@@ -1526,17 +1516,15 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1526,17 +1516,15 @@ package body Ada.Containers.Multiway_Trees is
function Node_Count (Container : Tree) return Count_Type is function Node_Count (Container : Tree) return Count_Type is
begin begin
-- Container.Count is the number of nodes we have actually -- Container.Count is the number of nodes we have actually allocated. We
-- allocated. We cache the value specifically so this Node_Count -- cache the value specifically so this Node_Count operation can execute
-- operation can execute in O(1) time, which makes it behave -- in O(1) time, which makes it behave similarly to how the Length
-- similarly to how the Length selector function behaves -- selector function behaves for other containers.
-- for other containers.
-- -- The cached node count value only describes the nodes we have
-- The cached node count value only describes the nodes -- allocated; the root node itself is not included in that count. The
-- we have allocated; the root node itself is not included -- Node_Count operation returns a value that includes the root node
-- in that count. The Node_Count operation returns a value -- (because the RM says so), so we must add 1 to our cached value.
-- that includes the root node (because the RM says so), so we
-- must add 1 to our cached value.
return 1 + Container.Count; return 1 + Container.Count;
end Node_Count; end Node_Count;
...@@ -1595,7 +1583,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1595,7 +1583,9 @@ package body Ada.Containers.Multiway_Trees is
Last := First; Last := First;
for J in Count_Type'(2) .. Count loop for J in Count_Type'(2) .. Count loop
-- Reclaim other nodes if Storage_Error. ??? -- Reclaim other nodes if Storage_Error. ???
Last.Next := new Tree_Node_Type'(Parent => Parent.Node, Last.Next := new Tree_Node_Type'(Parent => Parent.Node,
Prev => Last, Prev => Last,
Element => New_Item, Element => New_Item,
...@@ -1610,10 +1600,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1610,10 +1600,9 @@ package body Ada.Containers.Multiway_Trees is
Parent => Parent.Node, Parent => Parent.Node,
Before => Parent.Node.Children.First); Before => Parent.Node.Children.First);
-- In order for operation Node_Count to complete -- In order for operation Node_Count to complete in O(1) time, we cache
-- in O(1) time, we cache the count value. Here we -- the count value. Here we increment the total count by the number of
-- increment the total count by the number of nodes -- nodes we just inserted.
-- we just inserted.
Container.Count := Container.Count + Count; Container.Count := Container.Count + Count;
end Prepend_Child; end Prepend_Child;
...@@ -1670,6 +1659,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1670,6 +1659,7 @@ package body Ada.Containers.Multiway_Trees is
L := L - 1; L := L - 1;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
L := L - 1; L := L - 1;
...@@ -1725,8 +1715,8 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1725,8 +1715,8 @@ package body Ada.Containers.Multiway_Trees is
C.Last := C.Last.Next; C.Last := C.Last.Next;
end loop; end loop;
-- Now that the allocation and reads have completed successfully, -- Now that the allocation and reads have completed successfully, it
-- it is safe to link the children to their parent. -- is safe to link the children to their parent.
Subtree.Children := C; Subtree.Children := C;
end Read_Children; end Read_Children;
...@@ -1878,6 +1868,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1878,6 +1868,7 @@ package body Ada.Containers.Multiway_Trees is
end loop; end loop;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
B := B - 1; B := B - 1;
...@@ -1909,11 +1900,11 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1909,11 +1900,11 @@ package body Ada.Containers.Multiway_Trees is
-- Start of processing for Root_Node -- Start of processing for Root_Node
begin begin
-- This is a utility function for converting from an access type -- This is a utility function for converting from an access type that
-- that designates the distinguished root node to an access type -- designates the distinguished root node to an access type designating
-- designating a non-root node. The representation of a root node -- a non-root node. The representation of a root node does not have an
-- does not have an element, but is otherwise identical to a -- element, but is otherwise identical to a non-root node, so the
-- non-root node, so the conversion itself is safe. -- conversion itself is safe.
return To_Tree_Node_Access (Container.Root'Unrestricted_Access); return To_Tree_Node_Access (Container.Root'Unrestricted_Access);
end Root_Node; end Root_Node;
...@@ -1997,10 +1988,10 @@ package body Ada.Containers.Multiway_Trees is ...@@ -1997,10 +1988,10 @@ package body Ada.Containers.Multiway_Trees is
with "attempt to tamper with cursors (Source tree is busy)"; with "attempt to tamper with cursors (Source tree is busy)";
end if; end if;
-- We cache the count of the nodes we have allocated, so that -- We cache the count of the nodes we have allocated, so that operation
-- operation Node_Count can execute in O(1) time. But that means -- Node_Count can execute in O(1) time. But that means we must count the
-- we must count the nodes in the subtree we remove from Source -- nodes in the subtree we remove from Source and insert into Target, in
-- and insert into Target, in order to keep the count accurate. -- order to keep the count accurate.
Count := Subtree_Node_Count (Source_Parent.Node); Count := Subtree_Node_Count (Source_Parent.Node);
pragma Assert (Count >= 1); pragma Assert (Count >= 1);
...@@ -2183,17 +2174,16 @@ package body Ada.Containers.Multiway_Trees is ...@@ -2183,17 +2174,16 @@ package body Ada.Containers.Multiway_Trees is
with "attempt to tamper with cursors (Source tree is busy)"; with "attempt to tamper with cursors (Source tree is busy)";
end if; end if;
-- This is an unfortunate feature of this API: we must count -- This is an unfortunate feature of this API: we must count the nodes
-- the nodes in the subtree that we remove from the source tree, -- in the subtree that we remove from the source tree, which is an O(n)
-- which is an O(n) operation. It would have been better if -- operation. It would have been better if the Tree container did not
-- the Tree container did not have a Node_Count selector; a -- have a Node_Count selector; a user that wants the number of nodes in
-- user that wants the number of nodes in the tree could -- the tree could simply call Subtree_Node_Count, with the understanding
-- simply call Subtree_Node_Count, with the understanding that -- that such an operation is O(n).
-- such an operation is O(n).
-- -- Of course, we could choose to implement the Node_Count selector as an
-- Of course, we could choose to implement the Node_Count selector -- O(n) operation, which would turn this splice operation into an O(1)
-- as an O(n) operation, which would turn this splice operation -- operation. ???
-- into an O(1) operation. ???
Subtree_Count := Subtree_Node_Count (Position.Node); Subtree_Count := Subtree_Node_Count (Position.Node);
pragma Assert (Subtree_Count <= Source.Count); pragma Assert (Subtree_Count <= Source.Count);
...@@ -2243,7 +2233,9 @@ package body Ada.Containers.Multiway_Trees is ...@@ -2243,7 +2233,9 @@ package body Ada.Containers.Multiway_Trees is
end if; end if;
if Is_Root (Position) then if Is_Root (Position) then
-- Should this be PE instead? Need ARG confirmation. ??? -- Should this be PE instead? Need ARG confirmation. ???
raise Constraint_Error with "Position cursor designates root"; raise Constraint_Error with "Position cursor designates root";
end if; end if;
...@@ -2294,6 +2286,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -2294,6 +2286,7 @@ package body Ada.Containers.Multiway_Trees is
Result := Result + Subtree_Node_Count (Node); Result := Result + Subtree_Node_Count (Node);
Node := Node.Next; Node := Node.Next;
end loop; end loop;
return Result; return Result;
end Subtree_Node_Count; end Subtree_Node_Count;
...@@ -2383,6 +2376,7 @@ package body Ada.Containers.Multiway_Trees is ...@@ -2383,6 +2376,7 @@ package body Ada.Containers.Multiway_Trees is
L := L - 1; L := L - 1;
B := B - 1; B := B - 1;
exception exception
when others => when others =>
L := L - 1; L := L - 1;
......
...@@ -238,8 +238,8 @@ package Ada.Containers.Multiway_Trees is ...@@ -238,8 +238,8 @@ package Ada.Containers.Multiway_Trees is
-- Parent : Cursor; -- Parent : Cursor;
-- Process : not null access procedure (Position : Cursor)); -- Process : not null access procedure (Position : Cursor));
-- --
-- It seems that the Container parameter is there by mistake, but -- It seems that the Container parameter is there by mistake, but we need
-- we need an official ruling from the ARG. ??? -- an official ruling from the ARG. ???
procedure Iterate_Children procedure Iterate_Children
(Parent : Cursor; (Parent : Cursor;
...@@ -251,29 +251,29 @@ package Ada.Containers.Multiway_Trees is ...@@ -251,29 +251,29 @@ package Ada.Containers.Multiway_Trees is
private private
-- A node of this multiway tree comprises an element and a list of -- A node of this multiway tree comprises an element and a list of children
-- children (that are themselves trees). The root node is distinguished -- (that are themselves trees). The root node is distinguished because it
-- because it contains only children: it does not have an element itself. -- contains only children: it does not have an element itself.
-- --
-- This design feature puts two design goals in tension: -- This design feature puts two design goals in tension:
-- (1) treat the root node the same as any other node -- (1) treat the root node the same as any other node
-- (2) not declare any objects of type Element_Type unnecessarily -- (2) not declare any objects of type Element_Type unnecessarily
-- --
-- To satisfy (1), we could simply declare the Root node of the tree -- To satisfy (1), we could simply declare the Root node of the tree using
-- using the normal Tree_Node_Type, but that would mean that (2) is not -- the normal Tree_Node_Type, but that would mean that (2) is not
-- satisfied. To resolve the tension (in favor of (2)), we declare the -- satisfied. To resolve the tension (in favor of (2)), we declare the
-- component Root as having a different node type, without an Element -- component Root as having a different node type, without an Element
-- component (thus satisfying goal (2)) but otherwise identical to a -- component (thus satisfying goal (2)) but otherwise identical to a normal
-- normal node, and then use Unchecked_Conversion to convert an access -- node, and then use Unchecked_Conversion to convert an access object
-- object designating the Root node component to the access type -- designating the Root node component to the access type designating a
-- designating a normal, non-root node (thus satisfying goal (1)). We make -- normal, non-root node (thus satisfying goal (1)). We make an explicit
-- an explicit check for Root when there is any attempt to manipulate the -- check for Root when there is any attempt to manipulate the Element
-- Element component of the node (a check required by the RM anyway). -- component of the node (a check required by the RM anyway).
-- --
-- In order to be explicit about node (and pointer) representation, we -- In order to be explicit about node (and pointer) representation, we
-- specify that the respective node types have convention C, to ensure -- specify that the respective node types have convention C, to ensure that
-- that the layout of the components of the node records is the same, -- the layout of the components of the node records is the same, thus
-- thus guaranteeing that (unchecked) conversions between access types -- guaranteeing that (unchecked) conversions between access types
-- designating each kind of node type is a meaningful conversion. -- designating each kind of node type is a meaningful conversion.
type Tree_Node_Type; type Tree_Node_Type;
...@@ -285,9 +285,8 @@ private ...@@ -285,9 +285,8 @@ private
Last : Tree_Node_Access; Last : Tree_Node_Access;
end record; end record;
-- See the comment above. This declaration must exactly -- See the comment above. This declaration must exactly match the
-- match the declaration of Root_Node_Type (except for -- declaration of Root_Node_Type (except for the Element component).
-- the Element component).
type Tree_Node_Type is record type Tree_Node_Type is record
Parent : Tree_Node_Access; Parent : Tree_Node_Access;
...@@ -298,9 +297,8 @@ private ...@@ -298,9 +297,8 @@ private
end record; end record;
pragma Convention (C, Tree_Node_Type); pragma Convention (C, Tree_Node_Type);
-- See the comment above. This declaration must match -- See the comment above. This declaration must match the declaration of
-- the declaration of Tree_Node_Type (except for the -- Tree_Node_Type (except for the Element component).
-- Element component).
type Root_Node_Type is record type Root_Node_Type is record
Parent : Tree_Node_Access; Parent : Tree_Node_Access;
...@@ -312,19 +310,17 @@ private ...@@ -312,19 +310,17 @@ private
use Ada.Finalization; use Ada.Finalization;
-- The Count component of type Tree represents the number of -- The Count component of type Tree represents the number of nodes that
-- nodes that have been (dynamically) allocated. It does not -- have been (dynamically) allocated. It does not include the root node
-- include the root node itself. As implementors, we decide -- itself. As implementors, we decide to cache this value, so that the
-- to cache this value, so that the selector function Node_Count -- selector function Node_Count can execute in O(1) time, in order to be
-- can execute in O(1) time, in order to be consistent with -- consistent with the behavior of the Length selector function for other
-- the behavior of the Length selector function for other -- standard container library units. This does mean, however, that the
-- standard container library units. This does mean, however, -- two-container forms for Splice_XXX (that move subtrees across tree
-- that the two-container forms for Splice_XXX (that move subtrees -- containers) will execute in O(n) time, because we must count the number
-- across tree containers) will execute in O(n) time, because -- of nodes in the subtree(s) that get moved. (We resolve the tension
-- we must count the number of nodes in the subtree(s) that -- between Node_Count and Splice_XXX in favor of Node_Count, under the
-- get moved. (We resolve the tension between Node_Count -- assumption that Node_Count is the more common operation).
-- and Splice_XXX in favor of Node_Count, under the assumption
-- that Node_Count is the more common operation).
type Tree is new Controlled with record type Tree is new Controlled with record
Root : aliased Root_Node_Type; Root : aliased Root_Node_Type;
......
...@@ -67,11 +67,10 @@ package body Ada.Finalization.Heap_Management is ...@@ -67,11 +67,10 @@ package body Ada.Finalization.Heap_Management is
procedure Fin_Assert (Condition : Boolean; Message : String); procedure Fin_Assert (Condition : Boolean; Message : String);
-- Asserts that the condition is True. Used instead of pragma Assert in -- Asserts that the condition is True. Used instead of pragma Assert in
-- delicate places where raising an exception would cause re-invocation of -- delicate places where raising an exception would cause re-invocation of
-- finalization. Instead of raising an exception, aborts the whole -- finalization. Instead of raising an exception, aborts the whole process.
-- process.
function Is_Empty (Objects : Node_Ptr) return Boolean; function Is_Empty (Objects : Node_Ptr) return Boolean;
-- True if the Objects list is empty. -- True if the Objects list is empty
---------------- ----------------
-- Fin_Assert -- -- Fin_Assert --
...@@ -194,6 +193,7 @@ package body Ada.Finalization.Heap_Management is ...@@ -194,6 +193,7 @@ package body Ada.Finalization.Heap_Management is
-- Note: no need to unlock in case of exceptions; the above code cannot -- Note: no need to unlock in case of exceptions; the above code cannot
-- raise any. -- raise any.
end Attach; end Attach;
--------------- ---------------
...@@ -279,8 +279,10 @@ package body Ada.Finalization.Heap_Management is ...@@ -279,8 +279,10 @@ package body Ada.Finalization.Heap_Management is
end if; end if;
Unlock_Task.all; Unlock_Task.all;
-- Note: no need to unlock in case of exceptions; the above code cannot -- Note: no need to unlock in case of exceptions; the above code cannot
-- raise any. -- raise any.
end Detach; end Detach;
-------------- --------------
...@@ -305,9 +307,12 @@ package body Ada.Finalization.Heap_Management is ...@@ -305,9 +307,12 @@ package body Ada.Finalization.Heap_Management is
-- modified. -- modified.
if Collection.Finalization_Started then if Collection.Finalization_Started then
-- ???Needed for shared libraries.
-- ???Needed for shared libraries
return; return;
end if; end if;
pragma Debug (Fin_Assert (not Collection.Finalization_Started, pragma Debug (Fin_Assert (not Collection.Finalization_Started,
"Finalize: already started")); "Finalize: already started"));
Collection.Finalization_Started := True; Collection.Finalization_Started := True;
...@@ -340,7 +345,6 @@ package body Ada.Finalization.Heap_Management is ...@@ -340,7 +345,6 @@ package body Ada.Finalization.Heap_Management is
begin begin
Collection.Finalize_Address (Object_Address); Collection.Finalize_Address (Object_Address);
exception exception
when Fin_Except : others => when Fin_Except : others =>
if not Raised then if not Raised then
......
...@@ -6,27 +6,10 @@ ...@@ -6,27 +6,10 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 2011, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with -- -- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow -- -- GNAT. In accordance with the copyright of that document, you can freely --
-- apply solely to the contents of the part following the private keyword. -- -- copy and modify this specification, provided that if you redistribute a --
-- -- -- modified version, any changes that you have made are clearly indicated. --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- -- -- --
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
...@@ -34,13 +17,21 @@ generic ...@@ -34,13 +17,21 @@ generic
type Cursor is private; type Cursor is private;
No_Element : Cursor; No_Element : Cursor;
pragma Unreferenced (No_Element); pragma Unreferenced (No_Element);
package Ada.Iterator_Interfaces is package Ada.Iterator_Interfaces is
type Forward_Iterator is limited interface; type Forward_Iterator is limited interface;
function First (Object : Forward_Iterator) return Cursor is abstract; function First (Object : Forward_Iterator) return Cursor is abstract;
function Next (Object : Forward_Iterator; Position : Cursor) return Cursor
is abstract; function Next
(Object : Forward_Iterator;
Position : Cursor) return Cursor is abstract;
type Reversible_Iterator is limited interface and Forward_Iterator; type Reversible_Iterator is limited interface and Forward_Iterator;
function Last (Object : Reversible_Iterator) return Cursor is abstract; function Last (Object : Reversible_Iterator) return Cursor is abstract;
function Previous (Object : Reversible_Iterator; Position : Cursor)
return Cursor is abstract; function Previous
(Object : Reversible_Iterator;
Position : Cursor) return Cursor is abstract;
end Ada.Iterator_Interfaces; end Ada.Iterator_Interfaces;
...@@ -877,8 +877,7 @@ package body ALFA is ...@@ -877,8 +877,7 @@ package body ALFA is
procedure Detect_And_Add_ALFA_Scope (N : Node_Id) is procedure Detect_And_Add_ALFA_Scope (N : Node_Id) is
begin begin
if Nkind_In (N, if Nkind_In (N, N_Subprogram_Declaration,
N_Subprogram_Declaration,
N_Subprogram_Body, N_Subprogram_Body,
N_Subprogram_Body_Stub, N_Subprogram_Body_Stub,
N_Package_Declaration, N_Package_Declaration,
......
...@@ -174,7 +174,8 @@ package body Lib.Xref is ...@@ -174,7 +174,8 @@ package body Lib.Xref is
when N_Pragma => when N_Pragma =>
if Get_Pragma_Id (Result) = Pragma_Precondition if Get_Pragma_Id (Result) = Pragma_Precondition
or else Get_Pragma_Id (Result) = Pragma_Postcondition or else
Get_Pragma_Id (Result) = Pragma_Postcondition
then then
return Empty; return Empty;
else else
......
...@@ -893,6 +893,7 @@ package body Par_SCO is ...@@ -893,6 +893,7 @@ package body Par_SCO is
if Index /= 0 then if Index /= 0 then
declare declare
T : SCO_Table_Entry renames SCO_Table.Table (Index); T : SCO_Table_Entry renames SCO_Table.Table (Index);
begin begin
-- Called multiple times for the same sloc (need to allow for -- Called multiple times for the same sloc (need to allow for
-- C2 = 'P') ??? -- C2 = 'P') ???
...@@ -1080,7 +1081,7 @@ package body Par_SCO is ...@@ -1080,7 +1081,7 @@ package body Par_SCO is
SCE : SC_Entry renames SC.Table (J); SCE : SC_Entry renames SC.Table (J);
Pragma_Sloc : Source_Ptr := No_Location; Pragma_Sloc : Source_Ptr := No_Location;
begin begin
-- For the statement SCO for a pragma controlled by -- For the case of a statement SCO for a pragma controlled by
-- Set_SCO_Pragma_Enable, set Pragma_Sloc so that the SCO (and -- Set_SCO_Pragma_Enable, set Pragma_Sloc so that the SCO (and
-- those of any nested decision) is emitted only if the pragma -- those of any nested decision) is emitted only if the pragma
-- is enabled. -- is enabled.
...@@ -1506,8 +1507,7 @@ package body Par_SCO is ...@@ -1506,8 +1507,7 @@ package body Par_SCO is
when N_Generic_Instantiation => when N_Generic_Instantiation =>
Typ := 'i'; Typ := 'i';
when when N_Representation_Clause |
N_Representation_Clause |
N_Use_Package_Clause | N_Use_Package_Clause |
N_Use_Type_Clause => N_Use_Type_Clause =>
Typ := ASCII.NUL; Typ := ASCII.NUL;
......
...@@ -339,7 +339,7 @@ package SCOs is ...@@ -339,7 +339,7 @@ package SCOs is
-- Disabled pragmas -- Disabled pragmas
-- No SCO is generated for disabled pragmas. -- No SCO is generated for disabled pragmas
--------------------------------------------------------------------- ---------------------------------------------------------------------
-- Internal table used to store Source Coverage Obligations (SCOs) -- -- Internal table used to store Source Coverage Obligations (SCOs) --
......
...@@ -432,6 +432,7 @@ package body Sem_Ch11 is ...@@ -432,6 +432,7 @@ package body Sem_Ch11 is
Exception_Id : constant Node_Id := Name (N); Exception_Id : constant Node_Id := Name (N);
Exception_Name : Entity_Id := Empty; Exception_Name : Entity_Id := Empty;
P : Node_Id; P : Node_Id;
Par : Node_Id;
begin begin
Check_SPARK_Restriction ("raise statement is not allowed", N); Check_SPARK_Restriction ("raise statement is not allowed", N);
...@@ -443,9 +444,9 @@ package body Sem_Ch11 is ...@@ -443,9 +444,9 @@ package body Sem_Ch11 is
Check_Restriction (No_Exceptions, N); Check_Restriction (No_Exceptions, N);
end if; end if;
-- Check for useless assignment to OUT or IN OUT scalar immediately -- Check for useless assignment to OUT or IN OUT scalar preceding the
-- preceding the raise. Right now we only look at assignment statements, -- raise. Right now we only look at assignment statements, we could do
-- we could do more. -- more.
if Is_List_Member (N) then if Is_List_Member (N) then
declare declare
...@@ -455,23 +456,51 @@ package body Sem_Ch11 is ...@@ -455,23 +456,51 @@ package body Sem_Ch11 is
begin begin
P := Prev (N); P := Prev (N);
-- Skip past null statements and pragmas
while Present (P)
and then Nkind_In (P, N_Null_Statement, N_Pragma)
loop
P := Prev (P);
end loop;
-- See if preceding statement is an assignment
if Present (P) if Present (P)
and then Nkind (P) = N_Assignment_Statement and then Nkind (P) = N_Assignment_Statement
then then
L := Name (P); L := Name (P);
-- Give warning for assignment to scalar formal
if Is_Scalar_Type (Etype (L)) if Is_Scalar_Type (Etype (L))
and then Is_Entity_Name (L) and then Is_Entity_Name (L)
and then Is_Formal (Entity (L)) and then Is_Formal (Entity (L))
then then
-- Don't give warning if we are covered by an exception
-- handler, since this may result in false positives, since
-- the handler may handle the exception and return normally.
-- First find enclosing sequence of statements
Par := N;
loop
Par := Parent (Par);
exit when Nkind (Par) = N_Handled_Sequence_Of_Statements;
end loop;
-- See if there is a handler, give message if not
if No (Exception_Handlers (Par)) then
Error_Msg_N Error_Msg_N
("?assignment to pass-by-copy formal may have no effect", ("?assignment to pass-by-copy formal " &
P); "may have no effect", P);
Error_Msg_N Error_Msg_N
("\?RAISE statement may result in abnormal return" & ("\?RAISE statement may result in abnormal return" &
" (RM 6.4.1(17))", P); " (RM 6.4.1(17))", P);
end if; end if;
end if; end if;
end if;
end; end;
end if; end if;
......
...@@ -4033,6 +4033,7 @@ package body Sem_Ch12 is ...@@ -4033,6 +4033,7 @@ package body Sem_Ch12 is
Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
Version => Ada_Version)); Version => Ada_Version));
return True; return True;
else else
return False; return False;
end if; end if;
...@@ -11892,12 +11893,11 @@ package body Sem_Ch12 is ...@@ -11892,12 +11893,11 @@ package body Sem_Ch12 is
if Present (E) then if Present (E) then
-- If the node is an entry call to an entry in an enclosing task, -- If the node is an entry call to an entry in an enclosing task,
-- it is rewritten as a selected component. No global entity -- it is rewritten as a selected component. No global entity to
-- to preserve in this case, the expansion will be redone in the -- preserve in this case, since the expansion will be redone in
-- instance. -- the instance.
if not Nkind_In (E, if not Nkind_In (E, N_Defining_Identifier,
N_Defining_Identifier,
N_Defining_Character_Literal, N_Defining_Character_Literal,
N_Defining_Operator_Symbol) N_Defining_Operator_Symbol)
then then
......
...@@ -6303,8 +6303,8 @@ package body Sem_Ch4 is ...@@ -6303,8 +6303,8 @@ package body Sem_Ch4 is
Func_Name := Empty; Func_Name := Empty;
Is_Var := False; Is_Var := False;
Ritem := First_Rep_Item (Etype (Prefix));
Ritem := First_Rep_Item (Etype (Prefix));
while Present (Ritem) loop while Present (Ritem) loop
if Nkind (Ritem) = N_Aspect_Specification then if Nkind (Ritem) = N_Aspect_Specification then
...@@ -6323,6 +6323,7 @@ package body Sem_Ch4 is ...@@ -6323,6 +6323,7 @@ package body Sem_Ch4 is
exit; exit;
end if; end if;
end if; end if;
Next_Rep_Item (Ritem); Next_Rep_Item (Ritem);
end loop; end loop;
......
...@@ -1756,7 +1756,7 @@ package body Sem_Res is ...@@ -1756,7 +1756,7 @@ package body Sem_Res is
procedure Build_Explicit_Dereference procedure Build_Explicit_Dereference
(Expr : Node_Id; (Expr : Node_Id;
Disc : Entity_Id); Disc : Entity_Id);
-- AI05-139 : names with implicit dereference. If the expression N is a -- AI05-139: Names with implicit dereference. If the expression N is a
-- reference type and the context imposes the corresponding designated -- reference type and the context imposes the corresponding designated
-- type, convert N into N.Disc.all. Such expressions are always over- -- type, convert N into N.Disc.all. Such expressions are always over-
-- loaded with both interpretations, and the dereference interpretation -- loaded with both interpretations, and the dereference interpretation
...@@ -2312,9 +2312,9 @@ package body Sem_Res is ...@@ -2312,9 +2312,9 @@ package body Sem_Res is
elsif Nkind (N) = N_Conditional_Expression then elsif Nkind (N) = N_Conditional_Expression then
Set_Etype (N, Expr_Type); Set_Etype (N, Expr_Type);
-- AI05-0139-2 : expression is overloaded because -- AI05-0139-2: Expression is overloaded because type has
-- type has implicit dereference. If type matches -- implicit dereference. If type matches context, no implicit
-- context, no implicit dereference is involved. -- dereference is involved.
elsif Has_Implicit_Dereference (Expr_Type) then elsif Has_Implicit_Dereference (Expr_Type) then
Set_Etype (N, Expr_Type); Set_Etype (N, Expr_Type);
......
...@@ -148,7 +148,7 @@ package Sem_Util is ...@@ -148,7 +148,7 @@ package Sem_Util is
-- means that for sure CE cannot be raised. -- means that for sure CE cannot be raised.
procedure Check_Implicit_Dereference (Nam : Node_Id; Typ : Entity_Id); procedure Check_Implicit_Dereference (Nam : Node_Id; Typ : Entity_Id);
-- AI05-139-2 : accessors and iterators for containers. This procedure -- AI05-139-2: Accessors and iterators for containers. This procedure
-- checks whether T is a reference type, and if so it adds an interprettion -- checks whether T is a reference type, and if so it adds an interprettion
-- to Expr whose type is the designated type of the reference_discriminant. -- to Expr whose type is the designated type of the reference_discriminant.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment