diff mbox

[Ada] Cross-reference information for expression functions that are completions

Message ID 20120222140423.GA13887@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Feb. 22, 2012, 2:04 p.m. UTC
This patch removes some duplicate entries for an expression function that is
the completion of a previous function declaration.

The following commonds:

      gcc -c -gnat12 p.adb
      grep greater p.ali

must yield:

   2V13*greater{boolean} 2>22 2>25 2|2b13


package P is
   function greater (X, Y : integer) return Boolean;
   function equal (x, Y: Boolean) return Boolean is (X or Y);
end P;
---
package body P is
   function greater (X, Y : integer) return Boolean is
     (X > Y);
   function incr (x : integer) return integer is (X+1);
end P;

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

2012-02-22  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch6.adb (Analyze_Expression_Function): If the construct
	is a completion, indicate that its formals are the formals of
	a completion, and as such do not get a cross- reference entry.
	(Analyze_Subprogram_Specification): Do not generate a definition
	for the entity of an expression function, because it may be a
	completion. Definition will be generated if needed when analyzing
	the generated subprogram declaration.
diff mbox

Patch

Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb	(revision 184470)
+++ sem_ch6.adb	(working copy)
@@ -273,7 +273,6 @@ 
       Spec     : constant Node_Id    := Specification (N);
 
       Def_Id :  Entity_Id;
-      pragma Unreferenced (Def_Id);
 
       Prev :  Entity_Id;
       --  If the expression is a completion, Prev is the entity whose
@@ -371,6 +370,26 @@ 
 
          if Has_Completion (Prev) then
             Set_Is_Inlined (Prev);
+
+            --  The formals of the expression function are body formals,
+            --  and do not appear in the ali file, which will only contain
+            --  references to the formals of the original subprogram spec.
+
+            declare
+               F1 : Entity_Id;
+               F2 : Entity_Id;
+
+            begin
+               F1 := First_Formal (Def_Id);
+               F2 := First_Formal (Prev);
+
+               while Present (F1) loop
+                  Set_Spec_Entity (F1, F2);
+                  Next_Formal (F1);
+                  Next_Formal (F2);
+               end loop;
+            end;
+
          else
             Set_Is_Inlined (Defining_Entity (New_Body));
          end if;
@@ -3198,8 +3217,12 @@ 
       end if;
 
       Designator := Analyze_Subprogram_Specification (Specification (N));
+
+      --  A reference may already have been generated for the unit name, in
+      --  which case the following call is redundant. However it is needed for
+      --  declarations that are the rewriting of an expression function.
+
       Generate_Definition (Designator);
-      --  ??? why this call, already in Analyze_Subprogram_Specification
 
       if Debug_Flag_C then
          Write_Str ("==> subprogram spec ");
@@ -3399,9 +3422,15 @@ 
          Check_SPARK_Restriction ("user-defined operator is not allowed", N);
       end if;
 
-      --  Proceed with analysis
+      --  Proceed with analysis. Do not emit a cross-reference entry if the
+      --  specification comes from an expression function, because it may be
+      --  the completion of a previous declaration. It is is not, the cross-
+      --  reference entry will be emitted for the new subprogram declaration.
 
-      Generate_Definition (Designator);
+      if Nkind (Parent (N)) /= N_Expression_Function then
+         Generate_Definition (Designator);
+      end if;
+
       Set_Contract (Designator, Make_Contract (Sloc (Designator)));
 
       if Nkind (N) = N_Function_Specification then