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 <[email protected]>
* 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;