sem_ch6 (Analyze_Expression_Function): treat the function as Inline_Always...
authorEd Schonberg <schonberg@adacore.com>
Tue, 2 Aug 2011 15:04:46 +0000 (15:04 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Tue, 2 Aug 2011 15:04:46 +0000 (17:04 +0200)
2011-08-02  Ed Schonberg  <schonberg@adacore.com>

* sem_ch6 (Analyze_Expression_Function): treat the function as
Inline_Always, and introduce a subprogram declaration for it when it is
not a completion.
* inline.adb (Add_Inlined_Body): recognize bodies that come from
expression functions, so that the back-end can determine whether they
can in fact be inlined.
* sem_util.adb (Is_Expression_Function): predicate to determine whether
a function body comes from an expression function.

From-SVN: r177173

gcc/ada/ChangeLog
gcc/ada/inline.adb
gcc/ada/sem_ch6.adb
gcc/ada/sem_util.adb
gcc/ada/sem_util.ads

index 02e05f9b8c4255f38d7ccf7a56ccf053b98a1e56..e8407baba03b3454b4d887f49310e7333839d2de 100644 (file)
@@ -1,3 +1,14 @@
+2011-08-02  Ed Schonberg  <schonberg@adacore.com>
+
+       * sem_ch6 (Analyze_Expression_Function): treat the function as
+       Inline_Always, and introduce a subprogram declaration for it when it is
+       not a completion.
+       * inline.adb (Add_Inlined_Body): recognize bodies that come from
+       expression functions, so that the back-end can determine whether they
+       can in fact be inlined.
+       * sem_util.adb (Is_Expression_Function): predicate to determine whether
+       a function body comes from an expression function.
+
 2011-08-02  Gary Dismukes  <dismukes@adacore.com>
 
        * sem_ch6.adb (Check_Conformance): Revise the check for nonconforming
index c4937976be26d10ca3c475673e977689bc6c6787..68e53a5de6d1e5cfe484d05de0cdbd3248fb216e 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -342,7 +342,9 @@ package body Inline is
                   null;
 
                elsif not Is_Inlined (Pack)
-                 and then not Has_Completion (E)
+                 and then
+                   (not Has_Completion (E)
+                      or else Is_Expression_Function (E))
                then
                   Set_Is_Inlined (Pack);
                   Inlined_Bodies.Increment_Last;
index ca7c00519c45265155709d419579f27706bc39ba..1ca71fc288e139cd694fbbcded7adb1aaa1cdd92 100644 (file)
@@ -271,6 +271,7 @@ package body Sem_Ch6 is
       LocX     : constant Source_Ptr := Sloc (Expression (N));
       Def_Id   : constant Entity_Id  := Defining_Entity (Specification (N));
       New_Body : Node_Id;
+      New_Decl : Node_Id;
 
       Prev : constant Entity_Id := Current_Entity_In_Scope (Def_Id);
       --  If the expression is a completion, Prev is the entity whose
@@ -278,8 +279,13 @@ package body Sem_Ch6 is
 
    begin
       --  This is one of the occasions on which we transform the tree during
-      --  semantic analysis. Transform the expression function into an
-      --  equivalent subprogram body, and then analyze that.
+      --  semantic analysis. If this is a completion,  transform the expression
+      --  function into an equivalent subprogram body, and analyze it.
+
+      --  Expression functions are inlined unconditionally. The back-end will
+      --  determine whether this is possible.
+
+      Inline_Processing_Required := True;
 
       New_Body :=
         Make_Subprogram_Body (Loc,
@@ -304,10 +310,37 @@ package body Sem_Ch6 is
          Rewrite (N, Make_Null_Statement (Loc));
          Analyze (N);
          Analyze (New_Body);
+         Set_Is_Inlined (Prev);
 
-      else
+      elsif Present (Prev) then
          Rewrite (N, New_Body);
+         Set_Is_Inlined (Prev);
          Analyze (N);
+
+      --  If this is not a completion, create both a declaration and a body,
+      --  so that the expression can be inlined whenever possible.
+
+      else
+         New_Decl :=
+           Make_Subprogram_Declaration (Loc,
+             Specification => Specification (N));
+         Rewrite (N, New_Decl);
+         Analyze (N);
+         Set_Is_Inlined (Defining_Entity (New_Decl));
+
+         --  Create new set of formals for specification in body.
+
+         Set_Specification (New_Body,
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name =>
+               Make_Defining_Identifier (Loc, Chars (Defining_Entity (N))),
+             Parameter_Specifications =>
+               Copy_Parameter_List (Defining_Entity (New_Decl)),
+             Result_Definition =>
+               New_Copy_Tree (Result_Definition (Specification (New_Decl)))));
+
+         Insert_After (N, New_Body);
+         Analyze (New_Body);
       end if;
    end Analyze_Expression_Function;
 
index dbe5887690b4b38305fd5788c83a6a94a1f8b428..ef650401d7a65dc2d561c358d6f7c40829ca8ef6 100644 (file)
@@ -6541,6 +6541,26 @@ package body Sem_Util is
       end if;
    end Is_Descendent_Of;
 
+   ----------------------------
+   -- Is_Expression_Function --
+   ----------------------------
+
+   function Is_Expression_Function (Subp : Entity_Id) return Boolean is
+      Decl : constant Node_Id := Unit_Declaration_Node (Subp);
+
+   begin
+      return Ekind (Subp) = E_Function
+        and then Nkind (Decl) = N_Subprogram_Declaration
+        and then
+          (Nkind (Original_Node (Decl)) = N_Expression_Function
+            or else
+              (Present (Corresponding_Body (Decl))
+                and then
+                  Nkind (Original_Node
+                     (Unit_Declaration_Node (Corresponding_Body (Decl))))
+                 = N_Expression_Function));
+   end Is_Expression_Function;
+
    --------------
    -- Is_False --
    --------------
index aeb35571be1b4846489af1a39c08b599c884310f..163e6470431298a66f57dd37e40ff8e992e07129 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -741,6 +741,10 @@ package Sem_Util is
    --  First determine whether type T is an interface and then check whether
    --  it is of protected, synchronized or task kind.
 
+   function Is_Expression_Function (Subp : Entity_Id) return Boolean;
+   --  Predicate to determine whether a function entity comes from a rewritten
+   --  expression function, and should be inlined unconditionally.
+
    function Is_False (U : Uint) return Boolean;
    pragma Inline (Is_False);
    --  The argument is a Uint value which is the Boolean'Pos value of a Boolean