A library unit name that is a renaming can appear in the name of a with_clause. When it is the prefix of a name, an implicit with_clause must be created for it, as well as for the unit it renames. So if R renames A, and we have a with_clause on R.B (where B is a child unit of A) we need with_clauses on both R an A (both of which can themselves be child units). This is because R may be used as a prefix within the current unit, and because A is needed to retrieve A.B. This patch fixes a bug in the handling of such with_clauses, and simplifies the processing by creating the with_clause for R when processing the with_clause for R.B at load time, before any analysis has taken place.
The following must compile quietly: gcc -c with_child.ads --- package Orig_Parent is end Orig_Parent; --- package Orig_Parent.Child is end Orig_Parent.Child; --- function Orig_Parent.Child.Grandchild return Integer; --- package Renam_Parent is end Renam_Parent; --- with Orig_Parent.Child; package Renam_Parent.Child renames Orig_Parent.Child; --- with Renam_Parent.Child.Grandchild; package With_Child is X : Integer := Renam_Parent.Child.Grandchild; end With_Child; Tested on x86_64-pc-linux-gnu, committed on trunk 2012-02-22 Ed Schonberg <schonb...@adacore.com> * lib-load.adb (Load_Unit): If the prefix of the name in a with-clause is a renaming, add a with-clause on the original unit. * sem_ch10.adb (Build_Unit_Name): Remove code made obsolete by new handling of renamings in with-clauses.
Index: lib-load.adb =================================================================== --- lib-load.adb (revision 184470) +++ lib-load.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- 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- -- @@ -406,9 +406,25 @@ New_Child (Load_Name, Get_Unit_Name (Name (Unit (Cunit (Unump))))); + -- If the load is for a with_clause, for visibility purposes both + -- the renamed entity and renaming one must be available in the + -- current unit: the renamed one in order to retrieve the child + -- unit, and the original one because it may be used as a prefix + -- in the body of the current unit. We add an explicit with_clause + -- for the original parent so that the renaming declaration is + -- properly loaded and analyzed. + + if Present (With_Node) then + Insert_After (With_Node, + Make_With_Clause (Sloc (With_Node), + Name => Copy_Separate_Tree (Prefix (Name (With_Node))))); + end if; + -- Save the renaming entity, to establish its visibility when -- installing the context. The implicit with is on this entity, - -- not on the package it renames. + -- not on the package it renames. This is somewhat redundant given + -- the with_clause just created, but it simplifies subsequent + -- expansion of the current with_clause. Optimizable ??? if Nkind (Error_Node) = N_With_Clause and then Nkind (Name (Error_Node)) = N_Selected_Component Index: sem_ch10.adb =================================================================== --- sem_ch10.adb (revision 184470) +++ sem_ch10.adb (working copy) @@ -2936,33 +2936,12 @@ function Build_Unit_Name (Nam : Node_Id) return Node_Id is Ent : Entity_Id; - Renaming : Entity_Id; Result : Node_Id; begin if Nkind (Nam) = N_Identifier then + return New_Occurrence_Of (Entity (Nam), Loc); - -- If the parent unit P in the name of the with_clause for P.Q is - -- a renaming of package R, then the entity of the parent is set - -- to R, but the identifier retains Chars (P) to be consistent - -- with the source (see details in lib-load). However the implicit - -- with_clause for the parent must make the entity for P visible, - -- because P.Q may be used as a prefix within the current unit. - -- The entity for P is the current_entity with that name, because - -- the package renaming declaration for it has just been analyzed. - -- Note that this case can only happen if P.Q has already appeared - -- in a previous with_clause in a related unit, such as the - -- library body of the current unit. - - if Chars (Nam) /= Chars (Entity (Nam)) then - Renaming := Current_Entity (Nam); - pragma Assert (Renamed_Entity (Renaming) = Entity (Nam)); - return New_Occurrence_Of (Renaming, Loc); - - else - return New_Occurrence_Of (Entity (Nam), Loc); - end if; - else Ent := Entity (Nam);