Patchwork [Ada] Null procedures as actuals in instances

login
register
mail settings
Submitter Arnaud Charlet
Date Oct. 12, 2010, 9:38 a.m.
Message ID <20101012093826.GA6703@adacore.com>
Download mbox | patch
Permalink /patch/67515/
State New
Headers show

Comments

Arnaud Charlet - Oct. 12, 2010, 9:38 a.m.
To accomodate possible preconditions on null procedures we create a null body
for them, and place it in the code at the point the subprogram is frozen. If
the subprogram is used as an actual in an instantiation of a child unit, the
visibility may be different between the point of definition and the freeze
point. Therefore the types that appear in the signature of the generated body
must be analyzed at the point of the declaration.

Test_Server below must compile quietly in Ada2005 mode


with Test_Services;
with Services.Context_Server;
package body Test_Server is
  type No_Context is null record;
  procedure Initialize (The_Context : in out No_Context) is null;

  package This_Server is new
        Test_Services.Context_Server (No_Context, Initialize);

  procedure Finalize (The_Context : access No_Context) is null;

  procedure Start (Name : in String) is
  begin
     This_Server.Start (Name);
  end Start;
end Test_Server;
---
package Test_Server is
  procedure Start (Name : in String);
end Test_Server;
---
generic
   type Context is limited private;
   with procedure Initialize (The_Context : in out Context);
package Services.Context_Server is
   procedure Start (Name : in String);
end Services.Context_Server;
---
package body Services.Context_Server is
  Local_Context : Context;
  procedure Start (Name : in String) is
  begin
     Initialize (Local_Context);
  end Start;
end Services.Context_Server;
---
generic
   type Kind is private;
package Services is
   procedure Do_Something (With_Kind : in Kind);
end Services;
---
package body Services is
   Local_Kind : Kind;

   procedure Do_Something (With_Kind : in Kind) is
   begin
      Local_Kind := With_Kind;
   end Do_Something;
end Services;
---
with Services;
package test_services is new services (boolean);

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

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

	* sem_ch6.adb (Analyze_Subprogram_Declaration): If this is a
	declaration of a null procedure resolve the types of the profile of the
	generated null body now.

Patch

Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb	(revision 165316)
+++ sem_ch6.adb	(working copy)
@@ -2737,6 +2737,27 @@  package body Sem_Ch6 is
             Set_Defining_Identifier (Form,
               Make_Defining_Identifier (Loc,
                 Chars (Defining_Identifier (Form))));
+
+            --  Resolve the types of the formals now, because the freeze point
+            --  may appear in a different context, e.g. an instantiation.
+
+            if Nkind (Parameter_Type (Form)) /= N_Access_Definition then
+               Find_Type (Parameter_Type (Form));
+
+            elsif
+              No (Access_To_Subprogram_Definition (Parameter_Type (Form)))
+            then
+               Find_Type (Subtype_Mark (Parameter_Type (Form)));
+
+            else
+
+               --  the case of a null procedure with a formal that is an
+               --  access_to_subprogram type, and that is used as an actual
+               --  in an instantiation is left to the enthusiastic reader.
+
+               null;
+            end if;
+
             Next (Form);
          end loop;