diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2019-07-05 07:03:49 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-07-05 07:03:49 +0000 |
commit | 3eb5e54a4a50f3e7c39a1f5435f9d4eedb26bb37 (patch) | |
tree | 0059e2f40ae4c4b8daa60a2fe8f51826dcf58cdc /gcc/ada/bindo-diagnostics.adb | |
parent | 2ff7c604377c1220702aeb4c4b63ed76e56aa577 (diff) | |
download | gcc-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.adb | 63 |
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; |