diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c4d2dccb2d9..88ecf6b9c0e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,15 @@ +2011-09-19 Ed Schonberg + + * sem_ch6.adb (Analyze_Expression_Function): When the expression + function is transformed into a declaration and a body, insert + body at the end of the declarative part, to prevent premature + freeze actions, and preserve original specification in the + subprogram declaration. + +2011-09-19 Vincent Celier + + * projects.texi: Minor editing. + 2011-09-19 Robert Dewar * sem_aggr.adb, lib-writ.ads, s-restri.ads, sem_ch6.adb, diff --git a/gcc/ada/projects.texi b/gcc/ada/projects.texi index d6130411409..87627a26f72 100644 --- a/gcc/ada/projects.texi +++ b/gcc/ada/projects.texi @@ -2599,7 +2599,7 @@ both depend on C. Here is an extra for all of these projects: project C is package Compiler is - for Default_Switches ("Ada") use ("-O3, "-gnatn"); + for Default_Switches ("Ada") use ("-O3", "-gnatn"); for Switches ("c_file1.adb") use ("-O0", "-g"); end Compiler; end C; @@ -3687,7 +3687,6 @@ end MyProj; * gnatmake and Project Files:: * The GNAT Driver and Project Files:: * The Development Environments:: -* Cleaning up with GPRclean:: @end menu @c --------------------------------------------- @@ -4554,73 +4553,3 @@ will be relative to this path. The root project directory is used if this value is not defined. @end table - -@c --------------------------------------------- -@node Cleaning up with GPRclean -@section Cleaning up with GPRclean -@c --------------------------------------------- - -@noindent -The GPRclean tool removes the files created by GPRbuild. -At a minimum, to invoke GPRclean you must specify a main project file -in a command such as @code{gprclean proj.gpr} or @code{gprclean -P proj.gpr}. - -Examples of invocation of GPRclean: - -@smallexample - gprclean -r prj1.gpr - gprclean -c -P prj2.gpr -@end smallexample - -@menu -* Switches for GPRclean:: -@end menu - -@c --------------------------------------------- -@node Switches for GPRclean -@subsection Switches for GPRclean -@c --------------------------------------------- - -@noindent -The switches for GPRclean are: - -@itemize @bullet -@item @option{--config=
} : Specify the - configuration project file name - -@item @option{--autoconf=} - - This specifies a configuration project file name that already exists or will - be created automatically. Option @option{--autoconf=} - cannot be specified more than once. If the configuration project file - specified with @option{--autoconf=} exists, then it is used. Otherwise, - @value{gprconfig} is invoked to create it automatically. - -@item @option{-c} : Only delete compiler-generated files. Do not delete - executables and libraries. - -@item @option{-f} : Force deletions of unwritable files - -@item @option{-F} : Display full project path name in brief error messages - -@item @option{-h} : Display this message - -@item @option{-n} : Do not delete files, only list files to delete - -@item @option{-P} : Use Project File @emph{}. - -@item @option{-q} : Be quiet/terse. There is no output, except to report - problems. - -@item @option{-r} : (recursive) Clean all projects referenced by the main - project directly or indirectly. Without this switch, GPRclean only - cleans the main project. - -@item @option{-v} : Verbose mode - -@item @option{-vPx} : Specify verbosity when parsing Project Files. - x = 0 (default), 1 or 2. - -@item @option{-Xnm=val} : Specify an external reference for Project Files. - -@end itemize diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index fd87387eaee..b2a046bb4f8 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -288,7 +288,7 @@ package body Sem_Ch6 is New_Body := Make_Subprogram_Body (Loc, - Specification => Specification (N), + Specification => Copy_Separate_Tree (Specification (N)), Declarations => Empty_List, Handled_Statement_Sequence => Make_Handled_Sequence_Of_Statements (LocX, @@ -296,9 +296,8 @@ package body Sem_Ch6 is Make_Simple_Return_Statement (LocX, Expression => Expression (N))))); - if Present (Prev) - and then Ekind (Prev) = E_Generic_Function - then + if Present (Prev) and then Ekind (Prev) = E_Generic_Function then + -- If the expression completes a generic subprogram, we must create a -- separate node for the body, because at instantiation the original -- node of the generic copy must be a generic subprogram body, and @@ -311,34 +310,53 @@ package body Sem_Ch6 is Analyze (New_Body); Set_Is_Inlined (Prev); - elsif Present (Prev) then + elsif Present (Prev) + and then Comes_From_Source (Prev) + then Rewrite (N, New_Body); - Set_Is_Inlined (Prev); Analyze (N); + -- Prev is the previous entity with the same name, but it is can + -- be an unrelated spec that is not completed by the expression + -- function. In that case the relevant entity is the one in the body. + -- Not clear that the backend can inline it in this case ??? + + if Has_Completion (Prev) then + Set_Is_Inlined (Prev); + else + Set_Is_Inlined (Defining_Entity (New_Body)); + end if; + -- If this is not a completion, create both a declaration and a body, so - -- that the expression can be inlined whenever possible. The spec of the - -- new subprogram declaration is a copy of the original specification, - -- which is now part of the subprogram body. + -- that the expression can be inlined whenever possible. else New_Decl := Make_Subprogram_Declaration (Loc, - Specification => Copy_Separate_Tree (Specification (N))); - - -- Do rewrite propagating the information that an expression function - -- comes from source (otherwise references to this entity are not - -- stored). + Specification => Specification (N)); Rewrite (N, New_Decl); - Set_Comes_From_Source - (Defining_Entity (N), Comes_From_Source (Def_Id)); - Analyze (N); Set_Is_Inlined (Defining_Entity (New_Decl)); - Insert_After (N, New_Body); - Analyze (New_Body); + -- To prevent premature freeze action, insert the new body at the end + -- of the current declarations, or at the end of the package spec. + + declare + Decls : List_Id := List_Containing (N); + Par : constant Node_Id := Parent (Decls); + + begin + if Nkind (Par) = N_Package_Specification + and then Decls = Visible_Declarations (Par) + and then Present (Private_Declarations (Par)) + and then not Is_Empty_List (Private_Declarations (Par)) + then + Decls := Private_Declarations (Par); + end if; + + Insert_After (Last (Decls), New_Body); + end; end if; -- If the return expression is a static constant, we suppress warning