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 <[email protected]>
* 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.
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