This patch fixes a name resolution problem in a child instance. involving a name of the form A.B.C, where A. B and C constitute a generic hierarchy. Within an instance of C, this name must be rewritten to denote the instances of A, B and C. Previously the compiler only handled one level of child units.
The following must compile quietly: gnatmake -q pack-td.ads --- with Gen_Pack.Child.TD; with Gen_Pack.Child.TD.T; package Pack.TD is package TD_Inst is new Pack.Smth2.TD; package T_Inst is new TD_Inst.T; end Pack.TD; -- with Gen_Pack; with Gen_Pack.Child; package Pack is package Smth is new Gen_Pack (Integer); package Smth2 is new Smth.Child; end Pack; -- generic type Formal_Type is range <>; package Gen_Pack is function Self (X : Formal_Type) return Formal_Type is (X); end Gen_Pack; -- generic package Gen_Pack.Child is function Minus_Self (X : Formal_Type) return Formal_Type is (-X); end Gen_Pack.Child; -- generic package Gen_Pack.Child.TD is type Tst is tagged null record; end Gen_Pack.Child.TD; -- generic package Gen_Pack.Child.TD.T is type Tst is new Gen_Pack.Child.TD.Tst with null record; end Gen_Pack.Child.TD.T; Tested on x86_64-pc-linux-gnu, committed on trunk 2013-10-10 Ed Schonberg <schonb...@adacore.com> * sem_ch8.adb (Find_Expanded_Name): Handle properly a fully qualified reference to a generic child unit within itself, in an instantiation.
Index: sem_ch8.adb =================================================================== --- sem_ch8.adb (revision 203342) +++ sem_ch8.adb (working copy) @@ -5157,12 +5157,10 @@ Selector : constant Node_Id := Selector_Name (N); Candidate : Entity_Id := Empty; P_Name : Entity_Id; - O_Name : Entity_Id; Id : Entity_Id; begin P_Name := Entity (Prefix (N)); - O_Name := P_Name; -- If the prefix is a renamed package, look for the entity in the -- original package. @@ -5340,15 +5338,22 @@ else -- Within the instantiation of a child unit, the prefix may -- denote the parent instance, but the selector has the name - -- of the original child. Find whether we are within the - -- corresponding instance, and get the proper entity, which - -- can only be an enclosing scope. + -- of the original child. That is to say, when A.B appears + -- within an instantiation of generic child unit B, the scope + -- stack includes an instance of A (P_Name) and an instance + -- of B under some other name. We scan the scope to find this + -- child instance, which is the desired entity. + -- Note that the parent may itself be a child instance, if + -- the reference is of the form A.B.C, in which case A.B has + -- already been rewritten with the proper entity. - if O_Name /= P_Name - and then In_Open_Scopes (P_Name) + if In_Open_Scopes (P_Name) and then Is_Generic_Instance (P_Name) then declare + Gen_Par : constant Entity_Id := + Generic_Parent (Specification + (Unit_Declaration_Node (P_Name))); S : Entity_Id := Current_Scope; P : Entity_Id; @@ -5365,9 +5370,12 @@ P := Generic_Parent (Specification (Unit_Declaration_Node (S))); + -- Check that P is a generic child of the generic + -- parent of the prefix. + if Present (P) - and then Chars (Scope (P)) = Chars (O_Name) and then Chars (P) = Chars (Selector) + and then Scope (P) = Gen_Par then Id := S; goto Found;