This commit removes entities marked with the CUDA_Device pragma from the
packages specs and bodies they exist in.

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

gcc/ada/

        * gnat_cuda.adb (Remove_CUDA_Device_Entities): New function.
        (Expand_CUDA_Package): Call Remove_CUDA_Device_Entities.
        * gnat_cuda.ads (Expand_CUDA_Package): Expand documentation.
        * sem_prag.adb (Analyze_Pragma): Remove warning about
        CUDA_Device not being implemented.
diff --git a/gcc/ada/gnat_cuda.adb b/gcc/ada/gnat_cuda.adb
--- a/gcc/ada/gnat_cuda.adb
+++ b/gcc/ada/gnat_cuda.adb
@@ -25,22 +25,25 @@
 
 --  This package defines CUDA-specific datastructures and functions.
 
-with Atree;       use Atree;
-with Debug;       use Debug;
-with Elists;      use Elists;
-with Namet;       use Namet;
-with Nlists;      use Nlists;
-with Nmake;       use Nmake;
-with Rtsfind;     use Rtsfind;
-with Sinfo;       use Sinfo;
-with Sinfo.Nodes; use Sinfo.Nodes;
-with Stringt;     use Stringt;
-with Tbuild;      use Tbuild;
-with Uintp;       use Uintp;
-with Sem;         use Sem;
-with Sem_Aux;     use Sem_Aux;
-with Sem_Util;    use Sem_Util;
-with Snames;      use Snames;
+with Atree;          use Atree;
+with Debug;          use Debug;
+with Einfo.Entities; use Einfo.Entities;
+with Einfo.Utils;    use Einfo.Utils;
+with Elists;         use Elists;
+with Errout;         use Errout;
+with Namet;          use Namet;
+with Nlists;         use Nlists;
+with Nmake;          use Nmake;
+with Rtsfind;        use Rtsfind;
+with Sem;            use Sem;
+with Sem_Aux;        use Sem_Aux;
+with Sem_Util;       use Sem_Util;
+with Sinfo.Nodes;    use Sinfo.Nodes;
+with Sinfo;          use Sinfo;
+with Snames;         use Snames;
+with Stringt;        use Stringt;
+with Tbuild;         use Tbuild;
+with Uintp;          use Uintp;
 
 with GNAT.HTable;
 
@@ -120,6 +123,10 @@ package body GNAT_CUDA is
    --  are declared within package body Pack_Body. Returns No_Elist if Pack_Id
    --  does not contain such procedures.
 
+   procedure Remove_CUDA_Device_Entities (Pack_Id : Entity_Id);
+   --  Removes all entities marked with the CUDA_Device pragma from package
+   --  Pack_Id. Must only be called when compiling for the host.
+
    procedure Set_CUDA_Device_Entities
      (Pack_Id : Entity_Id;
       E       : Elist_Id);
@@ -226,6 +233,13 @@ package body GNAT_CUDA is
 
       Empty_CUDA_Global_Subprograms (N);
 
+      --  Remove CUDA_Device entities (except if they are also CUDA_Host), as
+      --  they can only be referenced from the device and might reference
+      --  device-only symbols.
+
+      Remove_CUDA_Device_Entities
+        (Package_Specification (Corresponding_Spec (N)));
+
       --  If procedures marked with CUDA_Global have been defined within N,
       --  we need to register them with the CUDA runtime at program startup.
       --  This requires multiple declarations and function calls which need
@@ -718,6 +732,54 @@ package body GNAT_CUDA is
       Analyze (New_Stmt);
    end Build_And_Insert_CUDA_Initialization;
 
+   ---------------------------------
+   -- Remove_CUDA_Device_Entities --
+   ---------------------------------
+
+   procedure Remove_CUDA_Device_Entities (Pack_Id : Entity_Id) is
+      Device_Entities : constant Elist_Id :=
+        Get_CUDA_Device_Entities (Pack_Id);
+      Device_Elmt     : Elmt_Id;
+      Device_Entity   : Entity_Id;
+      Bod             : Node_Id;
+   begin
+      pragma Assert (Debug_Flag_Underscore_C);
+
+      if Device_Entities = No_Elist then
+         return;
+      end if;
+
+      Device_Elmt := First_Elmt (Device_Entities);
+      while Present (Device_Elmt) loop
+         Device_Entity := Node (Device_Elmt);
+         Next_Elmt (Device_Elmt);
+
+         case Ekind (Device_Entity) is
+            when E_Function | E_Procedure =>
+               Bod := Subprogram_Body (Device_Entity);
+
+               if Nkind (Parent (Bod)) = N_Subunit
+                 and then Present (Corresponding_Stub (Parent (Bod)))
+               then
+                  Error_Msg_N
+                    ("Cuda_Device not suported on separate subprograms",
+                     Corresponding_Stub (Parent (Bod)));
+               else
+                  Remove (Bod);
+                  Remove (Subprogram_Spec (Device_Entity));
+               end if;
+
+            when E_Variable | E_Constant =>
+               Remove (Declaration_Node (Device_Entity));
+
+            when others =>
+               pragma Assert (False);
+         end case;
+
+         Remove_Entity_And_Homonym (Device_Entity);
+      end loop;
+   end Remove_CUDA_Device_Entities;
+
    ------------------------------
    -- Set_CUDA_Device_Entities --
    ------------------------------


diff --git a/gcc/ada/gnat_cuda.ads b/gcc/ada/gnat_cuda.ads
--- a/gcc/ada/gnat_cuda.ads
+++ b/gcc/ada/gnat_cuda.ads
@@ -86,7 +86,10 @@ package GNAT_CUDA is
    --  entity of its parent package body.
 
    procedure Expand_CUDA_Package (N : Node_Id);
-   --  When compiling for the host, generate code to register kernels with the
-   --  CUDA runtime and post-process kernels.
+   --  When compiling for the host:
+   --  - Generate code to register kernels with the CUDA runtime and
+   --    post-process kernels.
+   --  - Empty content of CUDA_Global procedures.
+   --  - Remove declarations of CUDA_Device entities.
 
 end GNAT_CUDA;


diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -14849,9 +14849,9 @@ package body Sem_Prag is
          begin
             GNAT_Pragma;
             Check_Arg_Count (1);
-            Arg_Node := Get_Pragma_Arg (Arg1);
+            Check_Arg_Is_Library_Level_Local_Name (Arg1);
 
-            Check_Arg_Is_Library_Level_Local_Name (Arg_Node);
+            Arg_Node := Get_Pragma_Arg (Arg1);
             Device_Entity := Entity (Arg_Node);
 
             if Ekind (Device_Entity) in E_Variable
@@ -14859,8 +14859,9 @@ package body Sem_Prag is
                                       | E_Procedure
                                       | E_Function
             then
-               Add_CUDA_Device_Entity (Scope (Device_Entity), Device_Entity);
-               Error_Msg_N ("??& not implemented yet", N);
+               Add_CUDA_Device_Entity
+                 (Package_Specification_Of_Scope (Scope (Device_Entity)),
+                  Device_Entity);
 
             else
                Error_Msg_NE ("& must be constant, variable or subprogram",


Reply via email to