aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/bindo-diagnostics.adb
diff options
context:
space:
mode:
authorHristian Kirtchev <kirtchev@adacore.com>2019-07-05 07:03:49 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-07-05 07:03:49 +0000
commit3eb5e54a4a50f3e7c39a1f5435f9d4eedb26bb37 (patch)
tree0059e2f40ae4c4b8daa60a2fe8f51826dcf58cdc /gcc/ada/bindo-diagnostics.adb
parent2ff7c604377c1220702aeb4c4b63ed76e56aa577 (diff)
downloadgcc-3eb5e54a4a50f3e7c39a1f5435f9d4eedb26bb37.zip
gcc-3eb5e54a4a50f3e7c39a1f5435f9d4eedb26bb37.tar.gz
gcc-3eb5e54a4a50f3e7c39a1f5435f9d4eedb26bb37.tar.bz2
[Ada] Stabilization of Elaboration order v4.0
This patch introduces several changes to the new elaboration order mechanism: * Instantiations processed in the context of invocation graph encoding now yield a relation which is later transformed into an invocation edge. This ensures that the unit where the instantiation resides properly depends on the unit where the body of the generic is. * The diagnostics of cycles that involve invocation edges now use a set to avoid infinite recursion when visiting paths that represent recursive code. * Various diagnostics that suggest the use of switches have been updated to indicate which tool the switches apply to. * Bindo can now output the dependencies of various units that specify why a predecessor unit must be elaborated prior to a successor unit. This functionality implements binder switch -e (output complete list of elaboration order dependencies). * The output of the elaboration order is now identical to that emitted by Binde. * The nature of the invocation graph encoding is now recorded in the ALI record rather than the Unit record of a unit. This ensures that both the spec and body share the same encoding kind. * A section on debugging elaboration order issues is now available in Bindo. 2019-07-05 Hristian Kirtchev <kirtchev@adacore.com> gcc/ada/ * ali.adb (For_Each_Invocation_Construct, For_Each_Invocation_Relation): New version. (Scan_ALI): Initialize field Invocation_Graph_Encoding. (Set_Invocation_Graph_Encoding): Update the setting of the invocation graph encoding. * ali.ads: Move field Invocation_Graph_Encoding from Unit_Record to ALI_Record because the encoding applies to the whole ALI, rather than one of the units (spec or body) for which the ALI file was created. (For_Each_Invocation_Construct, For_Each_Invocation_Relation): New version. * bindo.adb: Update the section on switches. Complete the section of debugging elaboration order issues. (Find_Elaboration_Order): Prepare the routine for the switch from the old to the new elaboration order mechanism. * bindo-diagnostics.adb (Find_And_Output_Invocation_Paths): Manage a visited set used by Visit_Vertex. (Output_All_Cycles_Suggestions, Output_Dynamic_Model_Suggestions): Clarify the nature of the suggested switch. (Output_Elaborate_Body_Transition): Update the diagnostic to emit a better message. (Output_Forced_Suggestions, Output_Full_Encoding_Suggestions): Clarify the nature of the suggested switch. (Visit_Vertex): Update the parameter profile to add a set of invokers visited during the transition. This set prevents infinite exploration of the graph in case the invocations are recursive. * bindo-elaborators.adb: Add a use clause for Bindo.Writers.Dependency_Writers. (Elaborate_Units_Common): Output the library graph after it has been augmented with invocation edges. Output just the components instead of outputting the whole library graph again. (Elaborate_Units_Dynamic, Elaborate_Units_Static): Output the dependencies as expressed in the library graph. * bindo-units.adb (Invocation_Graph_Encoding): Update the extraction of the invocation graph encoding. * bindo-writers.adb: Add with and use clauses for Binderr and Butil. (palgc, plgc): New debug routine. (Write_Components): Moved to the spec. Add a header for the output. (Write_Dependencies, Write_Dependencies_Of_Vertex, Write_Dependency_Edge): New routine. (Write_Elaboration_Order): Update the logic to follow the format of Binde's order output. (Write_Library_Graph): Do not output the components every time the graph is written. (Write_Unit): Output the invocation graph encoding of the unit. Output the invocation constructs and relations for the unit only. * bindo-writers.ads (Write_Components): Moved from the body. (Write_Dependencies): New routine. * bindusg.adb: Prepare the routine for the switch from the old to the new elaboration order mechanism. * debug.adb: Binder switch -d_O is now not associated with any functionality. * einfo.adb (Is_Elaboration_Target): The attribute applies to packages, as specified by the comment on the attribute usage. * opt.ads: Add a global flag which controls the choice between the new and the legacy elaboration order mechanism. * sem_elab.adb: Add Package_Target to type Target_Kind. (Build_Elaborate_Body_Procedure, Build_Elaborate_Procedure, Build_Elaborate_Spec_Procedure, Check_Elaboration_Scenarios, Check_SPARK_Model_In_Effect): Use Main_Unit_Entity to obtain the entity of the main unit. (Create_Package_Rep): New routine. (Create_Target_Rep): Add processing for packages. (Declaration_Placement_Of_Node, Has_Prior_Elaboration): Use Main_Unit_Entity to obtain the entity of the main unit. (Invocation_Graph_Recording_OK): Prepare the routine for the switch from the old to the new elaboration order mechanism. (Main_Unit_Entity): New routine. (Meet_Elaboration_Requirement, Process_Conditional_ABE_Variable_Reference): Use Main_Unit_Entity to obtain the entity of the main unit. (Process_Invocation_Instantiation): New routine. (Process_Invocation_Scenario): Add processing for instantiations. * switch-b.adb (Scan_Binder_Switches): Prepare the routine for the switch from the old to the new elaboration order mechanism. From-SVN: r273128
Diffstat (limited to 'gcc/ada/bindo-diagnostics.adb')
-rw-r--r--gcc/ada/bindo-diagnostics.adb63
1 files changed, 47 insertions, 16 deletions
diff --git a/gcc/ada/bindo-diagnostics.adb b/gcc/ada/bindo-diagnostics.adb
index a4b031d..0c9da46 100644
--- a/gcc/ada/bindo-diagnostics.adb
+++ b/gcc/ada/bindo-diagnostics.adb
@@ -247,6 +247,7 @@ package body Bindo.Diagnostics is
Last_Vertex : Library_Graph_Vertex_Id;
Elaborated_Vertex : Library_Graph_Vertex_Id;
End_Vertex : Library_Graph_Vertex_Id;
+ Visited_Invokers : IGV_Sets.Membership_Set;
Path : IGE_Lists.Doubly_Linked_List;
Path_Id : in out Nat);
pragma Inline (Visit_Vertex);
@@ -254,8 +255,9 @@ package body Bindo.Diagnostics is
-- vertex Invoker_Vertex as part of a DFS traversal. Last_Vertex denotes
-- the previous vertex in the traversal. Elaborated_Vertex is the vertex
-- whose elaboration started the traversal. End_Vertex is the vertex that
- -- terminates the traversal. All edges along the path are recorded in Path.
- -- Path_Id is the id of the path.
+ -- terminates the traversal. Visited_Invoker is the set of all invokers
+ -- visited so far. All edges along the path are recorded in Path. Path_Id
+ -- is the id of the path.
-------------------------
-- Diagnose_All_Cycles --
@@ -411,6 +413,7 @@ package body Bindo.Diagnostics is
is
Path : IGE_Lists.Doubly_Linked_List;
Path_Id : Nat;
+ Visited : IGV_Sets.Membership_Set;
begin
pragma Assert (Present (Inv_Graph));
@@ -429,6 +432,7 @@ package body Bindo.Diagnostics is
Path := IGE_Lists.Create;
Path_Id := 1;
+ Visited := IGV_Sets.Create (Number_Of_Vertices (Inv_Graph));
-- Start a DFS traversal over the invocation graph, in an attempt to
-- reach Destination from Source. The actual start of the path is the
@@ -447,10 +451,12 @@ package body Bindo.Diagnostics is
Last_Vertex => Source,
Elaborated_Vertex => Source,
End_Vertex => Destination,
+ Visited_Invokers => Visited,
Path => Path,
Path_Id => Path_Id);
IGE_Lists.Destroy (Path);
+ IGV_Sets.Destroy (Visited);
end Find_And_Output_Invocation_Paths;
---------------------------
@@ -511,7 +517,7 @@ package body Bindo.Diagnostics is
if Number_Of_Cycles (G) > 1 and then not Debug_Flag_Underscore_CC then
Error_Msg_Info
- (" diagnose all circularities (-d_C)");
+ (" diagnose all circularities (binder switch -d_C)");
end if;
end Output_All_Cycles_Suggestions;
@@ -535,7 +541,7 @@ package body Bindo.Diagnostics is
and then not Is_Dynamically_Elaborated (G)
then
Error_Msg_Info
- (" use the dynamic elaboration model (-gnatE)");
+ (" use the dynamic elaboration model (compiler switch -gnatE)");
end if;
end Output_Dynamic_Model_Suggestions;
@@ -665,17 +671,21 @@ package body Bindo.Diagnostics is
pragma Assert (Present (Expected_Destination));
-- The actual and expected destination vertices match, and denote the
- -- spec of a unit subject to pragma Elaborate_Body. There is no need to
- -- mention the pragma because it does not affect the path of the cycle.
- -- Treat the edge as a regular with edge.
+ -- spec or body of a unit subject to pragma Elaborate_Body. There is no
+ -- need to mention the pragma because it does not affect the path of the
+ -- cycle. Treat the edge as a regular with edge.
--
-- Actual_Destination
-- Source --> spec Elaborate_Body -->
-- Expected_Destination
+ --
+ -- spec Elaborate_Body
+ --
+ -- Actual_Destination
+ -- Source --> body -->
+ -- Expected_Destination
if Actual_Destination = Expected_Destination then
- pragma Assert (Is_Spec (G, Actual_Destination));
-
Error_Msg_Unit_1 := Name (G, Source);
Error_Msg_Unit_2 := Name (G, Actual_Destination);
Error_Msg_Info
@@ -698,14 +708,18 @@ package body Bindo.Diagnostics is
pragma Assert
(Proper_Body (G, Actual_Destination) = Expected_Destination);
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
Error_Msg_Unit_1 := Name (G, Actual_Destination);
Error_Msg_Info
(" unit $ is subject to pragma Elaborate_Body");
- Error_Msg_Unit_1 := Name (G, Source);
- Error_Msg_Unit_2 := Name (G, Expected_Destination);
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
Error_Msg_Info
- (" unit $ has with clause for unit $");
+ (" unit $ is in the closure of pragma Elaborate_Body");
end if;
end Output_Elaborate_Body_Transition;
@@ -832,8 +846,10 @@ package body Bindo.Diagnostics is
Error_Msg_Unit_1 := Name (G, Succ);
Error_Msg_Unit_2 := Name (G, Pred);
Error_Msg_Info
- (" remove the dependency of unit $ on unit $ from argument of -f "
- & "switch");
+ (" remove the dependency of unit $ on unit $ from the argument of "
+ & "switch -f");
+ Error_Msg_Info
+ (" remove switch -f");
end Output_Forced_Suggestions;
------------------------------
@@ -950,7 +966,8 @@ package body Bindo.Diagnostics is
if Invocation_Graph_Encoding (G, Succ) /= Full_Path_Encoding then
Error_Msg_Info
- (" use detailed invocation information (-gnatd_F)");
+ (" use detailed invocation information (compiler switch "
+ & "-gnatd_F)");
end if;
end if;
end Output_Full_Encoding_Suggestions;
@@ -1410,6 +1427,7 @@ package body Bindo.Diagnostics is
Last_Vertex : Library_Graph_Vertex_Id;
Elaborated_Vertex : Library_Graph_Vertex_Id;
End_Vertex : Library_Graph_Vertex_Id;
+ Visited_Invokers : IGV_Sets.Membership_Set;
Path : IGE_Lists.Doubly_Linked_List;
Path_Id : in out Nat)
is
@@ -1425,6 +1443,7 @@ package body Bindo.Diagnostics is
pragma Assert (Present (Last_Vertex));
pragma Assert (Present (Elaborated_Vertex));
pragma Assert (Present (End_Vertex));
+ pragma Assert (IGV_Sets.Present (Visited_Invokers));
pragma Assert (IGE_Lists.Present (Path));
-- The current invocation vertex resides within the end library vertex.
@@ -1444,7 +1463,14 @@ package body Bindo.Diagnostics is
-- Otherwise extend the search for the end library vertex via all edges
-- to targets.
- else
+ elsif not IGV_Sets.Contains (Visited_Invokers, Invoker) then
+
+ -- Prepare for invoker backtracking
+
+ IGV_Sets.Insert (Visited_Invokers, Invoker);
+
+ -- Extend the search via all edges to targets
+
Iter := Iterate_Edges_To_Targets (Inv_Graph, Invoker);
while Has_Next (Iter) loop
Next (Iter, Edge);
@@ -1466,6 +1492,7 @@ package body Bindo.Diagnostics is
Last_Vertex => Invoker_Vertex,
Elaborated_Vertex => Elaborated_Vertex,
End_Vertex => End_Vertex,
+ Visited_Invokers => Visited_Invokers,
Path => Path,
Path_Id => Path_Id);
@@ -1473,6 +1500,10 @@ package body Bindo.Diagnostics is
IGE_Lists.Delete_Last (Path);
end loop;
+
+ -- Backtrack the invoker
+
+ IGV_Sets.Delete (Visited_Invokers, Invoker);
end if;
end Visit_Vertex;