[Ada] Renamed child units in with-clauses.

Arnaud Charlet charlet@adacore.com
Thu Jul 31 15:14:00 GMT 2008


If the parent unit in a with_clause is a unit renaming, the Load routine
replaces it with the unit it renames, in order to find the proper file that
holds the child unit. The original name is preserved in the with_clause, so
that the proper implicit with_clause can be generated when the context is
installed. The compiler did not handle properly the case when the unit renaming
is itself a child unit. In that case the compiler failed to create the proper
imkplicit with_clause, leading to spurious visibility errors.

The following must compile quietly:

with A1.B.C;
procedure P is
   X : integer := 15;
begin
   A1.B.C (X);
end;
--
package A1 is
   pragma Pure;
end A1;
---
with A1.X;
package A1.B renames A1.X;
---
package A1.X is
   type T is null record;
end A1.X;
---
Procedure A1.X.C (X : integer);

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

2008-07-31  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch10.adb (Build_Unit_Name): If the unit name in a with_clause
	has the form A.B.C and B is a unit renaming, analyze its compilation
	unit and add a with_clause on A.b to the context.

-------------- next part --------------
Index: sem_ch10.adb
===================================================================
--- sem_ch10.adb	(revision 138355)
+++ sem_ch10.adb	(working copy)
@@ -2660,13 +2660,18 @@ package body Sem_Ch10 is
       P     : Node_Id;
 
       function Build_Unit_Name (Nam : Node_Id) return Node_Id;
-      --  Comment required here ???
+      --  Build name to be used in implicit with_clause. In most cases this
+      --  is the source name, but if renamings are present we must make the
+      --  original unit visible, not the one it renames. The entity in the
+      --  use clause is the renamed unit, but the identifier is the one from
+      --  the source, which allows us to recover the unit renaming.
 
       ---------------------
       -- Build_Unit_Name --
       ---------------------
 
       function Build_Unit_Name (Nam : Node_Id) return Node_Id is
+         Ent      : Entity_Id;
          Renaming : Entity_Id;
          Result   : Node_Id;
 
@@ -2695,12 +2700,34 @@ package body Sem_Ch10 is
             end if;
 
          else
+            Ent := Entity (Nam);
+
+            if Present (Entity (Selector_Name (Nam)))
+              and then Chars (Entity (Selector_Name (Nam))) /= Chars (Ent)
+              and then
+                Nkind (Unit_Declaration_Node (Entity (Selector_Name (Nam))))
+                  = N_Package_Renaming_Declaration
+            then
+
+               --  The name in the with_clause is of the form A.B.C, and B
+               --  is given by a renaming declaration. In that case we may
+               --  not have analyzed the unit for B, but replaced it directly
+               --  in lib-load with the unit it renames. We have to make A.B
+               --  visible, so analyze the declaration for B now, in case it
+               --  has not been done yet.
+
+               Ent :=  Entity (Selector_Name (Nam));
+               Analyze
+                 (Parent
+                   (Unit_Declaration_Node (Entity (Selector_Name (Nam)))));
+            end if;
+
             Result :=
               Make_Expanded_Name (Loc,
                 Chars  => Chars (Entity (Nam)),
                 Prefix => Build_Unit_Name (Prefix (Nam)),
-                Selector_Name => New_Occurrence_Of (Entity (Nam), Loc));
-            Set_Entity (Result, Entity (Nam));
+                Selector_Name => New_Occurrence_Of (Ent, Loc));
+            Set_Entity (Result, Ent);
             return Result;
          end if;
       end Build_Unit_Name;


More information about the Gcc-patches mailing list