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 <schonb...@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.
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