diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -5876,16 +5876,20 @@ package body Exp_Ch7 is -- This is done only for non-generic packages if Ekind (Spec_Id) = E_Package then - Push_Scope (Spec_Id); - - -- Build dispatch tables of library level tagged types + -- Build dispatch tables of library-level tagged types for bodies + -- that are not compilation units (see Analyze_Compilation_Unit), + -- except for instances because they have no N_Compilation_Unit. if Tagged_Type_Expansion and then Is_Library_Level_Entity (Spec_Id) + and then (not Is_Compilation_Unit (Spec_Id) + or else Is_Generic_Instance (Spec_Id)) then Build_Static_Dispatch_Tables (N); end if; + Push_Scope (Spec_Id); + Expand_CUDA_Package (N); Build_Task_Activation_Call (N); @@ -6035,12 +6039,13 @@ package body Exp_Ch7 is Pop_Scope; end if; - -- Build dispatch tables of library-level tagged types + -- Build dispatch tables of library-level tagged types for instances + -- that are not compilation units (see Analyze_Compilation_Unit). if Tagged_Type_Expansion - and then (Is_Compilation_Unit (Id) - or else (Is_Generic_Instance (Id) - and then Is_Library_Level_Entity (Id))) + and then Is_Library_Level_Entity (Id) + and then Is_Generic_Instance (Id) + and then not Is_Compilation_Unit (Id) then Build_Static_Dispatch_Tables (N); end if; diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -524,12 +524,6 @@ package body Exp_Disp is -- Start of processing for Build_Static_Dispatch_Tables begin - if not Expander_Active - or else not Tagged_Type_Expansion - then - return; - end if; - if Nkind (N) = N_Package_Declaration then declare Spec : constant Node_Id := Specification (N); @@ -553,8 +547,15 @@ package body Exp_Disp is end; else pragma Assert (Nkind (N) = N_Package_Body); - Target_List := Declarations (N); - Build_Dispatch_Tables (Target_List); + declare + Spec_Id : constant Entity_Id := Corresponding_Spec (N); + + begin + Push_Scope (Spec_Id); + Target_List := Declarations (N); + Build_Dispatch_Tables (Target_List); + Pop_Scope; + end; end if; end Build_Static_Dispatch_Tables; diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -31,6 +31,7 @@ with Einfo; use Einfo; with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Errout; use Errout; +with Exp_Disp; use Exp_Disp; with Exp_Put_Image; with Exp_Util; use Exp_Util; with Elists; use Elists; @@ -1000,6 +1001,22 @@ package body Sem_Ch10 is end if; end if; + -- Build dispatch tables of library-level tagged types only now because + -- the generation of distribution stubs above may create some of them. + + if Expander_Active and then Tagged_Type_Expansion then + case Nkind (Unit_Node) is + when N_Package_Declaration | N_Package_Body => + Build_Static_Dispatch_Tables (Unit_Node); + + when N_Package_Instantiation => + Build_Static_Dispatch_Tables (Instance_Spec (Unit_Node)); + + when others => + null; + end case; + end if; + -- Remove unit from visibility, so that environment is clean for the -- next compilation, which is either the main unit or some other unit -- in the context.