Patchwork [Ada] Instantiation of a renaming of an implicit child unit

login
register
mail settings
Submitter Arnaud Charlet
Date Oct. 19, 2010, 10:24 a.m.
Message ID <20101019102420.GA14742@adacore.com>
Download mbox | patch
Permalink /patch/68301/
State New
Headers show

Comments

Arnaud Charlet - Oct. 19, 2010, 10:24 a.m.
The implicit child unit that is present in the instantiation of a parent generic
is not materialized in the parent instance, but retrieved when instantiated.
This requires installing  the parent instance on the scope stack. This patch
handles the case where the generic unit being instantiated is a renaming of the
implicit child within a parent unit, where additional tree traversal is needed
to retrieve the parent instance.

The following must compile and execute quietly:

with p;
with decl;
procedure main is
   package x is new decl.r;

begin
   if X.Var /= 1111 then
      raise Program_Error;
   end if;
end main;
---
generic
   X : integer;
package gp1 is
   Val : Integer := X;
   type some_type is new integer;
end gp1;
---
generic package gp1.gp2 is
  type and_now_something_completely_different is new some_type;
  Var : integer := Val;
end;
---
with gp1;
package p is new gp1 (1111);
---
with gp1.gp2;
with p;
package decl is
  generic package r renames p.gp2;
end decl;

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

2010-10-19  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch12.adb (Check_Generic_Child_Unit): Handle properly the case of
	an instantiation of a renaming of the implicit generic child that
	appears within an instance of its parent.

Patch

Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb	(revision 165687)
+++ sem_ch12.adb	(working copy)
@@ -5309,6 +5309,25 @@  package body Sem_Ch12 is
             then
                Install_Parent (Inst_Par);
                Parent_Installed := True;
+
+            --  The generic unit may be the renaming of the implicit child
+            --  present in an instance. In that case the parent instance is
+            --  obtained from the name of the renamed entity.
+
+            elsif Ekind (Entity (Gen_Id)) = E_Generic_Package
+              and then Present (Renamed_Entity (Entity (Gen_Id)))
+              and then Is_Child_Unit (Renamed_Entity (Entity (Gen_Id)))
+            then
+               declare
+                  Renamed_Package : constant Node_Id :=
+                    Name (Parent (Entity (Gen_Id)));
+               begin
+                  if Nkind (Renamed_Package) = N_Expanded_Name then
+                     Inst_Par := Entity (Prefix (Renamed_Package));
+                     Install_Parent (Inst_Par);
+                     Parent_Installed := True;
+                  end if;
+               end;
             end if;
          end if;