Commit 2e885a6f by Arnaud Charlet

[multiple changes]

2016-04-27  Hristian Kirtchev  <kirtchev@adacore.com>

	* aspects.ads Aspects Export and Import do not require delay. They
	were classified as delayed aspects, but treated as non-delayed
	by the analysis of aspects.
	* freeze.adb (Copy_Import_Pragma): New routine.
	(Wrap_Imported_Subprogram): Copy the import pragma by first
	resetting all semantic fields to avoid an infinite loop when
	performing the copy.
	* sem_ch13.adb (Analyze_Aspects_At_Freeze_Point): Add
	comment on the processing of aspects Export and Import
	at the freeze point.
	(Analyze_Aspect_Convention: New routine.
	(Analyze_Aspect_Export_Import): New routine.
	(Analyze_Aspect_External_Link_Name): New routine.
	(Analyze_Aspect_External_Or_Link_Name): Removed.
	(Analyze_Aspect_Specifications): Factor out the analysis of
	aspects Convention, Export, External_Name, Import, and Link_Name
	in their respective routines.  Aspects Export and Import should
	not generate a Boolean pragma because their corresponding pragmas
	have a very different syntax.
	(Build_Export_Import_Pragma): New routine.
	(Get_Interfacing_Aspects): New routine.

2016-04-27  Eric Botcazou  <ebotcazou@adacore.com>

	* inline.adb (Add_Inlined_Body): Overhaul implementation,
	robustify handling of -gnatn1, add special treatment for
	expression functions.

2016-04-27  Doug Rupp  <rupp@adacore.com>

	* g-traceb.ads: Update comment.
	* exp_ch2.adb: minor style fix in object declaration

From-SVN: r235483
parent 2a253c5b
2016-04-27 Hristian Kirtchev <kirtchev@adacore.com>
* aspects.ads Aspects Export and Import do not require delay. They
were classified as delayed aspects, but treated as non-delayed
by the analysis of aspects.
* freeze.adb (Copy_Import_Pragma): New routine.
(Wrap_Imported_Subprogram): Copy the import pragma by first
resetting all semantic fields to avoid an infinite loop when
performing the copy.
* sem_ch13.adb (Analyze_Aspects_At_Freeze_Point): Add
comment on the processing of aspects Export and Import
at the freeze point.
(Analyze_Aspect_Convention: New routine.
(Analyze_Aspect_Export_Import): New routine.
(Analyze_Aspect_External_Link_Name): New routine.
(Analyze_Aspect_External_Or_Link_Name): Removed.
(Analyze_Aspect_Specifications): Factor out the analysis of
aspects Convention, Export, External_Name, Import, and Link_Name
in their respective routines. Aspects Export and Import should
not generate a Boolean pragma because their corresponding pragmas
have a very different syntax.
(Build_Export_Import_Pragma): New routine.
(Get_Interfacing_Aspects): New routine.
2016-04-27 Eric Botcazou <ebotcazou@adacore.com>
* inline.adb (Add_Inlined_Body): Overhaul implementation,
robustify handling of -gnatn1, add special treatment for
expression functions.
2016-04-27 Doug Rupp <rupp@adacore.com>
* g-traceb.ads: Update comment.
* exp_ch2.adb: minor style fix in object declaration
2016-04-27 Hristian Kirtchev <kirtchev@adacore.com>
* sem_elab.adb (Check_Internal_Call): Do not
consider a call when it appears within pragma Initial_Condition
since the pragma is part of the elaboration statements of a
......
......@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
-- Copyright (C) 2010-2015, Free Software Foundation, Inc. --
-- Copyright (C) 2010-2016, 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- --
......@@ -652,12 +652,10 @@ package Aspects is
Aspect_Dispatching_Domain => Always_Delay,
Aspect_Dynamic_Predicate => Always_Delay,
Aspect_Elaborate_Body => Always_Delay,
Aspect_Export => Always_Delay,
Aspect_External_Name => Always_Delay,
Aspect_External_Tag => Always_Delay,
Aspect_Favor_Top_Level => Always_Delay,
Aspect_Implicit_Dereference => Always_Delay,
Aspect_Import => Always_Delay,
Aspect_Independent => Always_Delay,
Aspect_Independent_Components => Always_Delay,
Aspect_Inline => Always_Delay,
......@@ -726,9 +724,11 @@ package Aspects is
Aspect_Disable_Controlled => Never_Delay,
Aspect_Effective_Reads => Never_Delay,
Aspect_Effective_Writes => Never_Delay,
Aspect_Export => Never_Delay,
Aspect_Extensions_Visible => Never_Delay,
Aspect_Ghost => Never_Delay,
Aspect_Global => Never_Delay,
Aspect_Import => Never_Delay,
Aspect_Initial_Condition => Never_Delay,
Aspect_Initializes => Never_Delay,
Aspect_No_Elaboration_Code_All => Never_Delay,
......
......@@ -413,7 +413,7 @@ package body Exp_Ch2 is
and then (Is_Atomic (E) or else Is_Atomic (Etype (E)))
then
declare
Set : Boolean;
Set : Boolean;
begin
-- If variable is atomic, but type is not, setting depends on
......
......@@ -4676,14 +4676,65 @@ package body Freeze is
-- for the subprogram body that calls the inner procedure.
procedure Wrap_Imported_Subprogram (E : Entity_Id) is
function Copy_Import_Pragma return Node_Id;
-- Obtain a copy of the Import_Pragma which belongs to subprogram E
------------------------
-- Copy_Import_Pragma --
------------------------
function Copy_Import_Pragma return Node_Id is
-- The subprogram should have an import pragma, otherwise it does
-- need a wrapper.
Prag : constant Node_Id := Import_Pragma (E);
pragma Assert (Present (Prag));
-- Save all semantic fields of the pragma
Save_Asp : constant Node_Id := Corresponding_Aspect (Prag);
Save_From : constant Boolean := From_Aspect_Specification (Prag);
Save_Prag : constant Node_Id := Next_Pragma (Prag);
Save_Rep : constant Node_Id := Next_Rep_Item (Prag);
Result : Node_Id;
begin
-- Reset all semantic fields. This avoids a potential infinite
-- loop when the pragma comes from an aspect as the duplication
-- will copy the aspect, then copy the corresponding pragma and
-- so on.
Set_Corresponding_Aspect (Prag, Empty);
Set_From_Aspect_Specification (Prag, False);
Set_Next_Pragma (Prag, Empty);
Set_Next_Rep_Item (Prag, Empty);
Result := Copy_Separate_Tree (Prag);
-- Restore the original semantic fields
Set_Corresponding_Aspect (Prag, Save_Asp);
Set_From_Aspect_Specification (Prag, Save_From);
Set_Next_Pragma (Prag, Save_Prag);
Set_Next_Rep_Item (Prag, Save_Rep);
return Result;
end Copy_Import_Pragma;
-- Local variables
Loc : constant Source_Ptr := Sloc (E);
CE : constant Name_Id := Chars (E);
Spec : Node_Id;
Parms : List_Id;
Stmt : Node_Id;
Iprag : Node_Id;
Bod : Node_Id;
Forml : Entity_Id;
Parms : List_Id;
Prag : Node_Id;
Spec : Node_Id;
Stmt : Node_Id;
-- Start of processing for Wrap_Imported_Subprogram
begin
-- Nothing to do if not imported
......@@ -4706,18 +4757,14 @@ package body Freeze is
-- generates the right visibility, and that is exactly what the
-- calls to Copy_Separate_Tree give us.
-- Acquire copy of Inline pragma, and indicate that it does not
-- come from an aspect, as it applies to an internal entity.
Iprag := Copy_Separate_Tree (Import_Pragma (E));
Set_From_Aspect_Specification (Iprag, False);
Prag := Copy_Import_Pragma;
-- Fix up spec to be not imported any more
Set_Is_Imported (E, False);
Set_Interface_Name (E, Empty);
Set_Has_Completion (E, False);
Set_Import_Pragma (E, Empty);
Set_Interface_Name (E, Empty);
Set_Is_Imported (E, False);
-- Grab the subprogram declaration and specification
......@@ -4757,13 +4804,12 @@ package body Freeze is
Copy_Separate_Tree (Spec),
Declarations => New_List (
Make_Subprogram_Declaration (Loc,
Specification =>
Copy_Separate_Tree (Spec)),
Iprag),
Specification => Copy_Separate_Tree (Spec)),
Prag),
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
Statements => New_List (Stmt),
End_Label => Make_Identifier (Loc, CE)));
Statements => New_List (Stmt),
End_Label => Make_Identifier (Loc, CE)));
-- Append the body to freeze result
......
......@@ -62,6 +62,7 @@
-- GNU/Linux PowerPC
-- LynxOS x86
-- LynxOS 178 xcoff PowerPC
-- LynxOS 178 elf PowerPC
-- Solaris x86
-- Solaris sparc
-- VxWorks PowerPC
......
......@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
-- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
-- Copyright (C) 1992-2016, 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- --
......@@ -390,6 +390,40 @@ package body Inline is
return;
end if;
-- Find out whether the call must be inlined. Unless the result is
-- Dont_Inline, Must_Inline also creates an edge for the call in the
-- callgraph; however, it will not be activated until after Is_Called
-- is set on the subprogram.
Level := Must_Inline;
if Level = Dont_Inline then
return;
end if;
-- If the call was generated by the compiler and is to a subprogram in
-- a run-time unit, we need to suppress debugging information for it,
-- so that the code that is eventually inlined will not affect the
-- debugging of the program. We do not do it if the call comes from
-- source because, even if the call is inlined, the user may expect it
-- to be present in the debugging information.
if not Comes_From_Source (N)
and then In_Extended_Main_Source_Unit (N)
and then
Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (E)))
then
Set_Needs_Debug_Info (E, False);
end if;
-- If the subprogram is an expression function, then there is no need to
-- load any package body since the body of the function is in the spec.
if Is_Expression_Function (E) then
Set_Is_Called (E);
return;
end if;
-- Find unit containing E, and add to list of inlined bodies if needed.
-- If the body is already present, no need to load any other unit. This
-- is the case for an initialization procedure, which appears in the
......@@ -403,77 +437,48 @@ package body Inline is
-- no enclosing package to retrieve. In this case, it is the body of
-- the function that will have to be loaded.
Level := Must_Inline;
if Level /= Dont_Inline then
declare
Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
begin
-- Ensure that Analyze_Inlined_Bodies will be invoked after
-- completing the analysis of the current unit.
declare
Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
Inline_Processing_Required := True;
begin
if Pack = E then
Set_Is_Called (E);
Inlined_Bodies.Increment_Last;
Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
if Pack = E then
elsif Ekind (Pack) = E_Package then
Set_Is_Called (E);
-- Library-level inlined function. Add function itself to
-- list of needed units.
if Is_Generic_Instance (Pack) then
null;
Set_Is_Called (E);
-- Do not inline the package if the subprogram is an init proc
-- or other internally generated subprogram, because in that
-- case the subprogram body appears in the same unit that
-- declares the type, and that body is visible to the back end.
-- Do not inline it either if it is in the main unit.
-- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
-- calls if the back-end takes care of inlining the call.
elsif (Level = Inline_Package
or else (Level = Inline_Call
and then Has_Pragma_Inline_Always (E)
and then Back_End_Inlining))
and then not Is_Inlined (Pack)
and then not Is_Internal (E)
and then not In_Main_Unit_Or_Subunit (Pack)
then
Set_Is_Inlined (Pack);
Inlined_Bodies.Increment_Last;
Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
elsif Ekind (Pack) = E_Package then
Set_Is_Called (E);
if Is_Generic_Instance (Pack) then
null;
-- Do not inline the package if the subprogram is an init proc
-- or other internally generated subprogram, because in that
-- case the subprogram body appears in the same unit that
-- declares the type, and that body is visible to the back end.
-- Do not inline it either if it is in the main unit.
elsif Level = Inline_Package
and then not Is_Inlined (Pack)
and then not Is_Internal (E)
and then not In_Main_Unit_Or_Subunit (Pack)
then
Set_Is_Inlined (Pack);
Inlined_Bodies.Increment_Last;
Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
-- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
-- calls if the back-end takes care of inlining the call.
elsif Level = Inline_Call
and then Has_Pragma_Inline_Always (E)
and then Back_End_Inlining
then
Set_Is_Inlined (Pack);
Inlined_Bodies.Increment_Last;
Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
end if;
Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
end if;
end if;
-- If the call was generated by the compiler and is to a function
-- in a run-time unit, we need to suppress debugging information
-- for it, so that the code that is eventually inlined will not
-- affect debugging of the program. We do not do it if the call
-- comes from source because, even if the call is inlined, the
-- user may expect it to be present in the debugging information.
if not Comes_From_Source (N)
and then In_Extended_Main_Source_Unit (N)
and then
Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (E)))
then
Set_Needs_Debug_Info (E, False);
end if;
end;
end if;
-- Ensure that Analyze_Inlined_Bodies will be invoked after
-- completing the analysis of the current unit.
Inline_Processing_Required := True;
end;
end Add_Inlined_Body;
----------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment