From: squirek <squi...@adacore.com> The patch implements the experimental feature to allow use package clauses within the context area to imply with.
gcc/ada/ChangeLog: * sem_ch8.adb (Analyze_Package_Name): Add code to expand use clauses such that they have an implicit with associated with them when extensions are enabled. * sem_ch10.ads (Analyze_With_Clause): New. * sem_ch10.adb (Analyze_With_Clause): Add comes from source check for warning. (Expand_With_Clause): Moved to the spec. * sem_util.adb, sem_util.ads (Is_In_Context_Clause): Moved from sem_prag. * sem_prag.adb (Analyze_Pragma): Update calls to Is_In_Context_Clause. (Is_In_Context_Clause): Moved to sem_util. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/sem_ch10.adb | 10 +--------- gcc/ada/sem_ch10.ads | 9 +++++++++ gcc/ada/sem_ch8.adb | 39 +++++++++++++++++++++++++++++++++++++++ gcc/ada/sem_prag.adb | 31 +++---------------------------- gcc/ada/sem_util.adb | 21 +++++++++++++++++++++ gcc/ada/sem_util.ads | 4 ++++ 6 files changed, 77 insertions(+), 37 deletions(-) diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb index de5a8c846ba..9af96fc41b6 100644 --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -123,15 +123,6 @@ package body Sem_Ch10 is -- Verify that a stub is declared immediately within a compilation unit, -- and not in an inner frame. - procedure Expand_With_Clause (Item : Node_Id; Nam : Node_Id; N : Node_Id); - -- When a child unit appears in a context clause, the implicit withs on - -- parents are made explicit, and with clauses are inserted in the context - -- clause before the one for the child. If a parent in the with_clause - -- is a renaming, the implicit with_clause is on the renaming whose name - -- is mentioned in the with_clause, and not on the package it renames. - -- N is the compilation unit whose list of context items receives the - -- implicit with_clauses. - procedure Generate_Parent_References (N : Node_Id; P_Id : Entity_Id); -- Generate cross-reference information for the parents of child units -- and of subunits. N is a defining_program_unit_name, and P_Id is the @@ -2955,6 +2946,7 @@ package body Sem_Ch10 is if Ada_Version >= Ada_95 and then In_Predefined_Renaming (U) + and then Comes_From_Source (N) then if Restriction_Check_Required (No_Obsolescent_Features) then Check_Restriction (No_Obsolescent_Features, N); diff --git a/gcc/ada/sem_ch10.ads b/gcc/ada/sem_ch10.ads index c80c4129506..9585785f10a 100644 --- a/gcc/ada/sem_ch10.ads +++ b/gcc/ada/sem_ch10.ads @@ -45,6 +45,15 @@ package Sem_Ch10 is -- set when Ent is a tagged type and its class-wide type needs to appear -- in the tree. + procedure Expand_With_Clause (Item : Node_Id; Nam : Node_Id; N : Node_Id); + -- When a child unit appears in a context clause, the implicit withs on + -- parents are made explicit, and with clauses are inserted in the context + -- clause before the one for the child. If a parent in the with_clause + -- is a renaming, the implicit with_clause is on the renaming whose name + -- is mentioned in the with_clause, and not on the package it renames. + -- N is the compilation unit whose list of context items receives the + -- implicit with_clauses. + procedure Install_Context (N : Node_Id; Chain : Boolean := True); -- Installs the entities from the context clause of the given compilation -- unit into the visibility chains. This is done before analyzing a unit. diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb index 6fb9a9a1f5a..65d30967ae0 100644 --- a/gcc/ada/sem_ch8.adb +++ b/gcc/ada/sem_ch8.adb @@ -77,6 +77,7 @@ with Style; with Table; with Tbuild; use Tbuild; with Uintp; use Uintp; +with Uname; use Uname; with Warnsw; use Warnsw; package body Sem_Ch8 is @@ -4300,6 +4301,44 @@ package body Sem_Ch8 is begin pragma Assert (Nkind (Clause) = N_Use_Package_Clause); + + -- Perform "use implies with" expansion (when extensions are enabled) + -- by inserting an extra with clause since redundant clauses don't + -- really matter. + + if All_Extensions_Allowed and then Is_In_Context_Clause (Clause) then + declare + Unum : Unit_Number_Type; + With_Clause : constant Node_Id := + Make_With_Clause (Sloc (Clause), + Name => New_Copy_Tree (Pack)); + begin + -- Attempt to load the unit mentioned in the use clause + + Unum := Load_Unit + (Load_Name => Get_Unit_Name (With_Clause), + Required => False, + Subunit => False, + Error_Node => Clause, + With_Node => With_Clause); + + -- Either we can't file the unit or the use clause is a + -- reference to a nested package - in that case just handle + -- the use clause normally. + + if Unum /= No_Unit then + + Set_Library_Unit (With_Clause, Cunit (Unum)); + Set_Is_Implicit_With (With_Clause); + + Analyze (With_Clause); + Expand_With_Clause + (With_Clause, Name (With_Clause), + Enclosing_Comp_Unit_Node (Clause)); + end if; + end; + end if; + Analyze (Pack); -- Verify that the package standard is not directly named in a diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 6fe29665148..dcee8600d7c 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -5117,10 +5117,6 @@ package body Sem_Prag is -- Determines if the placement of the current pragma is appropriate -- for a configuration pragma. - function Is_In_Context_Clause return Boolean; - -- Returns True if pragma appears within the context clause of a unit, - -- and False for any other placement (does not generate any messages). - function Is_Static_String_Expression (Arg : Node_Id) return Boolean; -- Analyzes the argument, and determines if it is a static string -- expression, returns True if so, False if non-static or not String. @@ -6014,7 +6010,7 @@ package body Sem_Prag is -- Check case of appearing within context clause - if not Is_Unused and then Is_In_Context_Clause then + if not Is_Unused and then Is_In_Context_Clause (N) then -- The arguments must all be units mentioned in a with clause in -- the same context clause. Note that Par.Prag already checked @@ -8132,27 +8128,6 @@ package body Sem_Prag is end if; end Is_Configuration_Pragma; - -------------------------- - -- Is_In_Context_Clause -- - -------------------------- - - function Is_In_Context_Clause return Boolean is - Plist : List_Id; - Parent_Node : Node_Id; - - begin - if Is_List_Member (N) then - Plist := List_Containing (N); - Parent_Node := Parent (Plist); - - return Present (Parent_Node) - and then Nkind (Parent_Node) = N_Compilation_Unit - and then Context_Items (Parent_Node) = Plist; - end if; - - return False; - end Is_In_Context_Clause; - --------------------------------- -- Is_Static_String_Expression -- --------------------------------- @@ -16876,7 +16851,7 @@ package body Sem_Prag is begin -- Pragma must be in context items list of a compilation unit - if not Is_In_Context_Clause then + if not Is_In_Context_Clause (N) then Pragma_Misplaced; end if; @@ -16972,7 +16947,7 @@ package body Sem_Prag is -- Pragma must be in context items list of a compilation unit - if not Is_In_Context_Clause then + if not Is_In_Context_Clause (N) then Pragma_Misplaced; end if; diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index b833b355297..ce54deaab85 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -17872,6 +17872,27 @@ package body Sem_Util is return Nkind (Spec_Decl) in N_Generic_Declaration; end Is_Generic_Declaration_Or_Body; + -------------------------- + -- Is_In_Context_Clause -- + -------------------------- + + function Is_In_Context_Clause (N : Node_Id) return Boolean is + Plist : List_Id; + Parent_Node : Node_Id; + + begin + if Is_List_Member (N) then + Plist := List_Containing (N); + Parent_Node := Parent (Plist); + + return Present (Parent_Node) + and then Nkind (Parent_Node) = N_Compilation_Unit + and then Context_Items (Parent_Node) = Plist; + end if; + + return False; + end Is_In_Context_Clause; + --------------------------- -- Is_Independent_Object -- --------------------------- diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index fd749c4b8d4..167b0966dad 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -2095,6 +2095,10 @@ package Sem_Util is -- Determine whether arbitrary declaration Decl denotes a generic package, -- a generic subprogram or a generic body. + function Is_In_Context_Clause (N : Node_Id) return Boolean; + -- Returns True if N appears within the context clause of a unit, and False + -- for any other placement. + function Is_Independent_Object (N : Node_Id) return Boolean; -- Determine whether arbitrary node N denotes a reference to an independent -- object as per RM C.6(8). -- 2.43.0