1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- B I N D O . D I A G N O S T I C S --
9 -- Copyright (C) 2019-2020, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Binderr; use Binderr;
27 with Debug; use Debug;
28 with Restrict; use Restrict;
29 with Rident; use Rident;
30 with Types; use Types;
32 with Bindo.Validators;
34 use Bindo.Validators.Cycle_Validators;
38 use Bindo.Writers.Cycle_Writers;
39 use Bindo.Writers.Phase_Writers;
41 package body Bindo.Diagnostics is
43 -----------------------
44 -- Local subprograms --
45 -----------------------
47 procedure Diagnose_All_Cycles
48 (Inv_Graph : Invocation_Graph;
49 Lib_Graph : Library_Graph);
50 pragma Inline (Diagnose_All_Cycles);
51 -- Emit diagnostics for all cycles of library graph G
53 procedure Diagnose_Cycle
54 (Inv_Graph : Invocation_Graph;
55 Lib_Graph : Library_Graph;
56 Cycle : Library_Graph_Cycle_Id);
57 pragma Inline (Diagnose_Cycle);
58 -- Emit diagnostics for cycle Cycle of library graph G
60 procedure Find_And_Output_Invocation_Paths
61 (Inv_Graph : Invocation_Graph;
62 Lib_Graph : Library_Graph;
63 Source : Library_Graph_Vertex_Id;
64 Destination : Library_Graph_Vertex_Id);
65 pragma Inline (Find_And_Output_Invocation_Paths);
66 -- Find all paths in invocation graph Inv_Graph that originate from vertex
67 -- Source and reach vertex Destination of library graph Lib_Graph. Output
68 -- the transitions of each such path.
70 function Find_Elaboration_Root
71 (Inv_Graph : Invocation_Graph;
72 Lib_Graph : Library_Graph;
73 Vertex : Library_Graph_Vertex_Id) return Invocation_Graph_Vertex_Id;
74 pragma Inline (Find_Elaboration_Root);
75 -- Find the elaboration root in invocation graph Inv_Graph that corresponds
76 -- to vertex Vertex of library graph Lib_Graph.
78 procedure Output_All_Cycles_Suggestions (G : Library_Graph);
79 pragma Inline (Output_All_Cycles_Suggestions);
80 -- Suggest the diagnostic of all cycles in library graph G if circumstances
83 procedure Output_Elaborate_All_Suggestions
85 Pred : Library_Graph_Vertex_Id;
86 Succ : Library_Graph_Vertex_Id);
87 pragma Inline (Output_Elaborate_All_Suggestions);
88 -- Suggest ways to break a cycle that involves an Elaborate_All edge that
89 -- links predecessor Pred and successor Succ of library graph G.
91 procedure Output_Elaborate_All_Transition
93 Source : Library_Graph_Vertex_Id;
94 Actual_Destination : Library_Graph_Vertex_Id;
95 Expected_Destination : Library_Graph_Vertex_Id);
96 pragma Inline (Output_Elaborate_All_Transition);
97 -- Output a transition through an Elaborate_All edge of library graph G
98 -- with successor Source and predecessor Actual_Destination. Parameter
99 -- Expected_Destination denotes the predecessor as specified by the next
102 procedure Output_Elaborate_Body_Suggestions
104 Succ : Library_Graph_Vertex_Id);
105 pragma Inline (Output_Elaborate_Body_Suggestions);
106 -- Suggest ways to break a cycle that involves an edge where successor Succ
107 -- is either a spec subject to pragma Elaborate_Body or the body of such a
110 procedure Output_Elaborate_Body_Transition
112 Source : Library_Graph_Vertex_Id;
113 Actual_Destination : Library_Graph_Vertex_Id;
114 Expected_Destination : Library_Graph_Vertex_Id;
115 Elaborate_All_Active : Boolean);
116 pragma Inline (Output_Elaborate_Body_Transition);
117 -- Output a transition through an edge of library graph G with successor
118 -- Source and predecessor Actual_Destination. Vertex Source is either
119 -- a spec subject to pragma Elaborate_Body or denotes the body of such
120 -- a spec. Expected_Destination denotes the predecessor as specified by
121 -- the next edge in a cycle. Elaborate_All_Active should be set when the
122 -- transition occurs within a cycle that involves an Elaborate_All edge.
124 procedure Output_Elaborate_Suggestions
126 Pred : Library_Graph_Vertex_Id;
127 Succ : Library_Graph_Vertex_Id);
128 pragma Inline (Output_Elaborate_Suggestions);
129 -- Suggest ways to break a cycle that involves an Elaborate edge that links
130 -- predecessor Pred and successor Succ of library graph G.
132 procedure Output_Elaborate_Transition
134 Source : Library_Graph_Vertex_Id;
135 Actual_Destination : Library_Graph_Vertex_Id;
136 Expected_Destination : Library_Graph_Vertex_Id);
137 pragma Inline (Output_Elaborate_Transition);
138 -- Output a transition through an Elaborate edge of library graph G
139 -- with successor Source and predecessor Actual_Destination. Parameter
140 -- Expected_Destination denotes the predecessor as specified by the next
143 procedure Output_Forced_Suggestions
145 Pred : Library_Graph_Vertex_Id;
146 Succ : Library_Graph_Vertex_Id);
147 pragma Inline (Output_Forced_Suggestions);
148 -- Suggest ways to break a cycle that involves a Forced edge that links
149 -- predecessor Pred with successor Succ of library graph G.
151 procedure Output_Forced_Transition
153 Source : Library_Graph_Vertex_Id;
154 Actual_Destination : Library_Graph_Vertex_Id;
155 Expected_Destination : Library_Graph_Vertex_Id;
156 Elaborate_All_Active : Boolean);
157 pragma Inline (Output_Forced_Transition);
158 -- Output a transition through a Forced edge of library graph G with
159 -- successor Source and predecessor Actual_Destination. Parameter
160 -- Expected_Destination denotes the predecessor as specified by the
161 -- next edge in a cycle. Elaborate_All_Active should be set when the
162 -- transition occurs within a cycle that involves an Elaborate_All edge.
164 procedure Output_Full_Encoding_Suggestions
166 Cycle : Library_Graph_Cycle_Id;
167 First_Edge : Library_Graph_Edge_Id);
168 pragma Inline (Output_Full_Encoding_Suggestions);
169 -- Suggest the use of the full path invocation graph encoding to break
170 -- cycle Cycle with initial edge First_Edge of library graph G.
172 procedure Output_Invocation_Path
173 (Inv_Graph : Invocation_Graph;
174 Lib_Graph : Library_Graph;
175 Elaborated_Vertex : Library_Graph_Vertex_Id;
176 Path : IGE_Lists.Doubly_Linked_List;
177 Path_Id : in out Nat);
178 pragma Inline (Output_Invocation_Path);
179 -- Output path Path, which consists of invocation graph Inv_Graph edges.
180 -- Elaborated_Vertex is the vertex of library graph Lib_Graph whose
181 -- elaboration initiated the path. Path_Id is the unique id of the path.
183 procedure Output_Invocation_Path_Transition
184 (Inv_Graph : Invocation_Graph;
185 Lib_Graph : Library_Graph;
186 Edge : Invocation_Graph_Edge_Id);
187 pragma Inline (Output_Invocation_Path_Transition);
188 -- Output a transition through edge Edge of invocation graph G, which is
189 -- part of an invocation path. Lib_Graph is the related library graph.
191 procedure Output_Invocation_Related_Suggestions
193 Cycle : Library_Graph_Cycle_Id);
194 pragma Inline (Output_Invocation_Related_Suggestions);
195 -- Suggest ways to break cycle Cycle of library graph G that involves at
196 -- least one invocation edge.
198 procedure Output_Invocation_Transition
199 (Inv_Graph : Invocation_Graph;
200 Lib_Graph : Library_Graph;
201 Source : Library_Graph_Vertex_Id;
202 Destination : Library_Graph_Vertex_Id);
203 pragma Inline (Output_Invocation_Transition);
204 -- Output a transition through an invocation edge of library graph G with
205 -- successor Source and predecessor Destination. Inv_Graph is the related
208 procedure Output_Reason_And_Circularity_Header
210 First_Edge : Library_Graph_Edge_Id);
211 pragma Inline (Output_Reason_And_Circularity_Header);
212 -- Output the reason and circularity header for a circularity of library
213 -- graph G with initial edge First_Edge.
215 procedure Output_Suggestions
217 Cycle : Library_Graph_Cycle_Id;
218 First_Edge : Library_Graph_Edge_Id);
219 pragma Inline (Output_Suggestions);
220 -- Suggest various ways to break cycle Cycle with initial edge First_Edge
221 -- of library graph G.
223 procedure Output_Transition
224 (Inv_Graph : Invocation_Graph;
225 Lib_Graph : Library_Graph;
226 Current_Edge : Library_Graph_Edge_Id;
227 Next_Edge : Library_Graph_Edge_Id;
228 Elaborate_All_Active : Boolean);
229 pragma Inline (Output_Transition);
230 -- Output a transition described by edge Current_Edge, which is followed by
231 -- edge Next_Edge of library graph Lib_Graph. Inv_Graph denotes the related
232 -- invocation graph. Elaborate_All_Active should be set when the transition
233 -- occurs within a cycle that involves an Elaborate_All edge.
235 procedure Output_With_Transition
237 Source : Library_Graph_Vertex_Id;
238 Actual_Destination : Library_Graph_Vertex_Id;
239 Expected_Destination : Library_Graph_Vertex_Id;
240 Elaborate_All_Active : Boolean);
241 pragma Inline (Output_With_Transition);
242 -- Output a transition through a regular with edge of library graph G
243 -- with successor Source and predecessor Actual_Destination. Parameter
244 -- Expected_Destination denotes the predecessor as specified by the next
245 -- edge in a cycle. Elaborate_All_Active should be set when the transition
246 -- occurs within a cycle that involves an Elaborate_All edge.
248 procedure Visit_Vertex
249 (Inv_Graph : Invocation_Graph;
250 Lib_Graph : Library_Graph;
251 Invoker : Invocation_Graph_Vertex_Id;
252 Invoker_Vertex : Library_Graph_Vertex_Id;
253 Last_Vertex : Library_Graph_Vertex_Id;
254 Elaborated_Vertex : Library_Graph_Vertex_Id;
255 End_Vertex : Library_Graph_Vertex_Id;
256 Visited_Invokers : IGV_Sets.Membership_Set;
257 Path : IGE_Lists.Doubly_Linked_List;
258 Path_Id : in out Nat);
259 pragma Inline (Visit_Vertex);
260 -- Visit invocation graph vertex Invoker that resides in library graph
261 -- vertex Invoker_Vertex as part of a DFS traversal. Last_Vertex denotes
262 -- the previous vertex in the traversal. Elaborated_Vertex is the vertex
263 -- whose elaboration started the traversal. End_Vertex is the vertex that
264 -- terminates the traversal. Visited_Invoker is the set of all invokers
265 -- visited so far. All edges along the path are recorded in Path. Path_Id
266 -- is the id of the path.
268 -------------------------
269 -- Diagnose_All_Cycles --
270 -------------------------
272 procedure Diagnose_All_Cycles
273 (Inv_Graph : Invocation_Graph;
274 Lib_Graph : Library_Graph)
276 Cycle : Library_Graph_Cycle_Id;
277 Iter : All_Cycle_Iterator;
280 pragma Assert (Present (Inv_Graph));
281 pragma Assert (Present (Lib_Graph));
283 Iter := Iterate_All_Cycles (Lib_Graph);
284 while Has_Next (Iter) loop
288 (Inv_Graph => Inv_Graph,
289 Lib_Graph => Lib_Graph,
292 end Diagnose_All_Cycles;
294 ----------------------------
295 -- Diagnose_Circularities --
296 ----------------------------
298 procedure Diagnose_Circularities
299 (Inv_Graph : Invocation_Graph;
300 Lib_Graph : Library_Graph)
303 pragma Assert (Present (Inv_Graph));
304 pragma Assert (Present (Lib_Graph));
306 -- Find, validate, and output all cycles of the library graph
308 Find_Cycles (Lib_Graph);
309 Validate_Cycles (Lib_Graph);
310 Write_Cycles (Lib_Graph);
312 -- Diagnose all cycles in the graph regardless of their importance when
313 -- switch -d_C (diagnose all cycles) is in effect.
315 if Debug_Flag_Underscore_CC then
316 Diagnose_All_Cycles (Inv_Graph, Lib_Graph);
318 -- Otherwise diagnose the most important cycle in the graph
322 (Inv_Graph => Inv_Graph,
323 Lib_Graph => Lib_Graph,
324 Cycle => Highest_Precedence_Cycle (Lib_Graph));
326 end Diagnose_Circularities;
332 procedure Diagnose_Cycle
333 (Inv_Graph : Invocation_Graph;
334 Lib_Graph : Library_Graph;
335 Cycle : Library_Graph_Cycle_Id)
337 pragma Assert (Present (Inv_Graph));
338 pragma Assert (Present (Lib_Graph));
339 pragma Assert (Present (Cycle));
341 Elaborate_All_Active : constant Boolean :=
342 Contains_Elaborate_All_Edge
346 Current_Edge : Library_Graph_Edge_Id := No_Library_Graph_Edge;
347 First_Edge : Library_Graph_Edge_Id;
348 Iter : Edges_Of_Cycle_Iterator;
349 Next_Edge : Library_Graph_Edge_Id;
352 Start_Phase (Cycle_Diagnostics);
354 First_Edge := No_Library_Graph_Edge;
356 -- Inspect the edges of the cycle in pairs, emitting diagnostics based
357 -- on their successors and predecessors.
359 Iter := Iterate_Edges_Of_Cycle (Lib_Graph, Cycle);
360 while Has_Next (Iter) loop
362 -- Emit the reason for the cycle using the initial edge, which is the
363 -- most important edge in the cycle.
365 if not Present (First_Edge) then
366 Next (Iter, Current_Edge);
368 First_Edge := Current_Edge;
369 Output_Reason_And_Circularity_Header
371 First_Edge => First_Edge);
374 -- Obtain the other edge of the pair
376 exit when not Has_Next (Iter);
377 Next (Iter, Next_Edge);
379 -- Describe the transition from the current edge to the next edge by
380 -- taking into account the predecessors and successors involved, as
381 -- well as the nature of the edge.
384 (Inv_Graph => Inv_Graph,
385 Lib_Graph => Lib_Graph,
386 Current_Edge => Current_Edge,
387 Next_Edge => Next_Edge,
388 Elaborate_All_Active => Elaborate_All_Active);
390 Current_Edge := Next_Edge;
393 -- Describe the transition from the last edge to the first edge
396 (Inv_Graph => Inv_Graph,
397 Lib_Graph => Lib_Graph,
398 Current_Edge => Current_Edge,
399 Next_Edge => First_Edge,
400 Elaborate_All_Active => Elaborate_All_Active);
402 -- Suggest various alternatives for breaking the cycle
407 First_Edge => First_Edge);
409 End_Phase (Cycle_Diagnostics);
412 --------------------------------------
413 -- Find_And_Output_Invocation_Paths --
414 --------------------------------------
416 procedure Find_And_Output_Invocation_Paths
417 (Inv_Graph : Invocation_Graph;
418 Lib_Graph : Library_Graph;
419 Source : Library_Graph_Vertex_Id;
420 Destination : Library_Graph_Vertex_Id)
422 Path : IGE_Lists.Doubly_Linked_List;
424 Visited : IGV_Sets.Membership_Set;
427 pragma Assert (Present (Inv_Graph));
428 pragma Assert (Present (Lib_Graph));
429 pragma Assert (Present (Source));
430 pragma Assert (Present (Destination));
432 -- Nothing to do when the invocation graph encoding format of the source
433 -- vertex does not contain detailed information about invocation paths.
435 if Invocation_Graph_Encoding (Lib_Graph, Source) /=
441 Path := IGE_Lists.Create;
443 Visited := IGV_Sets.Create (Number_Of_Vertices (Inv_Graph));
445 -- Start a DFS traversal over the invocation graph, in an attempt to
446 -- reach Destination from Source. The actual start of the path is the
447 -- elaboration root invocation vertex that corresponds to the Source.
448 -- Each unique path is emitted as part of the current cycle diagnostic.
451 (Inv_Graph => Inv_Graph,
452 Lib_Graph => Lib_Graph,
454 Find_Elaboration_Root
455 (Inv_Graph => Inv_Graph,
456 Lib_Graph => Lib_Graph,
458 Invoker_Vertex => Source,
459 Last_Vertex => Source,
460 Elaborated_Vertex => Source,
461 End_Vertex => Destination,
462 Visited_Invokers => Visited,
466 IGE_Lists.Destroy (Path);
467 IGV_Sets.Destroy (Visited);
468 end Find_And_Output_Invocation_Paths;
470 ---------------------------
471 -- Find_Elaboration_Root --
472 ---------------------------
474 function Find_Elaboration_Root
475 (Inv_Graph : Invocation_Graph;
476 Lib_Graph : Library_Graph;
477 Vertex : Library_Graph_Vertex_Id) return Invocation_Graph_Vertex_Id
479 Current_Vertex : Invocation_Graph_Vertex_Id;
480 Iter : Elaboration_Root_Iterator;
481 Root_Vertex : Invocation_Graph_Vertex_Id;
484 pragma Assert (Present (Inv_Graph));
485 pragma Assert (Present (Lib_Graph));
486 pragma Assert (Present (Vertex));
488 -- Assume that the vertex does not have a corresponding elaboration root
490 Root_Vertex := No_Invocation_Graph_Vertex;
492 -- Inspect all elaboration roots trying to find the one that resides in
497 -- * The iterator must run to completion in order to unlock the
500 Iter := Iterate_Elaboration_Roots (Inv_Graph);
501 while Has_Next (Iter) loop
502 Next (Iter, Current_Vertex);
504 if not Present (Root_Vertex)
505 and then Body_Vertex (Inv_Graph, Current_Vertex) = Vertex
507 Root_Vertex := Current_Vertex;
512 end Find_Elaboration_Root;
514 -----------------------------------
515 -- Output_All_Cycles_Suggestions --
516 -----------------------------------
518 procedure Output_All_Cycles_Suggestions (G : Library_Graph) is
520 pragma Assert (Present (G));
522 -- The library graph contains at least one cycle and only the highest
523 -- priority cycle was diagnosed. Diagnosing all cycles may yield extra
524 -- information for decision making.
526 if Number_Of_Cycles (G) > 1 and then not Debug_Flag_Underscore_CC then
528 (" diagnose all circularities (binder switch -d_C)");
530 end Output_All_Cycles_Suggestions;
532 --------------------------------------
533 -- Output_Elaborate_All_Suggestions --
534 --------------------------------------
536 procedure Output_Elaborate_All_Suggestions
538 Pred : Library_Graph_Vertex_Id;
539 Succ : Library_Graph_Vertex_Id)
542 pragma Assert (Present (G));
543 pragma Assert (Present (Pred));
544 pragma Assert (Present (Succ));
546 Error_Msg_Unit_1 := Name (G, Pred);
547 Error_Msg_Unit_2 := Name (G, Succ);
549 (" change pragma Elaborate_All for unit $ to Elaborate in unit $");
551 (" remove pragma Elaborate_All for unit $ in unit $");
552 end Output_Elaborate_All_Suggestions;
554 -------------------------------------
555 -- Output_Elaborate_All_Transition --
556 -------------------------------------
558 procedure Output_Elaborate_All_Transition
560 Source : Library_Graph_Vertex_Id;
561 Actual_Destination : Library_Graph_Vertex_Id;
562 Expected_Destination : Library_Graph_Vertex_Id)
565 pragma Assert (Present (G));
566 pragma Assert (Present (Source));
567 pragma Assert (Present (Actual_Destination));
568 pragma Assert (Present (Expected_Destination));
570 -- The actual and expected destination vertices match, and denote the
571 -- initial declaration of a unit.
573 -- Elaborate_All Actual_Destination
574 -- Source ---------------> spec -->
575 -- Expected_Destination
577 -- Elaborate_All Actual_Destination
578 -- Source ---------------> stand-alone body -->
579 -- Expected_Destination
581 if Actual_Destination = Expected_Destination then
582 Error_Msg_Unit_1 := Name (G, Source);
583 Error_Msg_Unit_2 := Name (G, Actual_Destination);
585 (" unit $ has with clause and pragma Elaborate_All for unit $");
587 -- Otherwise the actual destination vertex denotes the spec of a unit,
588 -- while the expected destination is the corresponding body.
590 -- Elaborate_All Actual_Destination
591 -- Source ---------------> spec
594 -- Expected_Destination
597 pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
598 pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
600 (Proper_Body (G, Actual_Destination) = Expected_Destination);
602 Error_Msg_Unit_1 := Name (G, Source);
603 Error_Msg_Unit_2 := Name (G, Actual_Destination);
605 (" unit $ has with clause and pragma Elaborate_All for unit $");
607 Error_Msg_Unit_1 := Name (G, Expected_Destination);
609 (" unit $ is in the closure of pragma Elaborate_All");
611 end Output_Elaborate_All_Transition;
613 ---------------------------------------
614 -- Output_Elaborate_Body_Suggestions --
615 ---------------------------------------
617 procedure Output_Elaborate_Body_Suggestions
619 Succ : Library_Graph_Vertex_Id)
621 Spec : Library_Graph_Vertex_Id;
624 pragma Assert (Present (G));
625 pragma Assert (Present (Succ));
627 -- Find the initial declaration of the unit because it is the one
628 -- subject to pragma Elaborate_Body.
630 if Is_Body_With_Spec (G, Succ) then
631 Spec := Proper_Spec (G, Succ);
636 Error_Msg_Unit_1 := Name (G, Spec);
638 (" remove pragma Elaborate_Body in unit $");
639 end Output_Elaborate_Body_Suggestions;
641 --------------------------------------
642 -- Output_Elaborate_Body_Transition --
643 --------------------------------------
645 procedure Output_Elaborate_Body_Transition
647 Source : Library_Graph_Vertex_Id;
648 Actual_Destination : Library_Graph_Vertex_Id;
649 Expected_Destination : Library_Graph_Vertex_Id;
650 Elaborate_All_Active : Boolean)
653 pragma Assert (Present (G));
654 pragma Assert (Present (Source));
655 pragma Assert (Present (Actual_Destination));
656 pragma Assert (Present (Expected_Destination));
658 -- The actual and expected destination vertices match
660 -- Actual_Destination
661 -- Source --------> spec -->
662 -- Elaborate_Body Expected_Destination
666 -- Actual_Destination
667 -- Source --------> body -->
668 -- Elaborate_Body Expected_Destination
670 if Actual_Destination = Expected_Destination then
671 Error_Msg_Unit_1 := Name (G, Source);
672 Error_Msg_Unit_2 := Name (G, Actual_Destination);
674 (" unit $ has with clause for unit $");
676 -- The actual destination vertex denotes the spec of a unit while the
677 -- expected destination is the corresponding body, and the unit is in
678 -- the closure of an earlier Elaborate_All pragma.
680 -- Actual_Destination
681 -- Source --------> spec
684 -- Expected_Destination
686 elsif Elaborate_All_Active then
687 pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
688 pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
690 (Proper_Body (G, Actual_Destination) = Expected_Destination);
692 Error_Msg_Unit_1 := Name (G, Source);
693 Error_Msg_Unit_2 := Name (G, Actual_Destination);
695 (" unit $ has with clause for unit $");
697 Error_Msg_Unit_1 := Name (G, Expected_Destination);
699 (" unit $ is in the closure of pragma Elaborate_All");
701 -- Otherwise the actual destination vertex is the spec of a unit subject
702 -- to pragma Elaborate_Body and the expected destination vertex is the
705 -- Actual_Destination
706 -- Source --------> spec Elaborate_Body
709 -- Expected_Destination
713 (Is_Elaborate_Body_Pair
715 Spec_Vertex => Actual_Destination,
716 Body_Vertex => Expected_Destination));
718 Error_Msg_Unit_1 := Name (G, Source);
719 Error_Msg_Unit_2 := Name (G, Actual_Destination);
721 (" unit $ has with clause for unit $");
723 Error_Msg_Unit_1 := Name (G, Actual_Destination);
725 (" unit $ is subject to pragma Elaborate_Body");
727 Error_Msg_Unit_1 := Name (G, Expected_Destination);
729 (" unit $ is in the closure of pragma Elaborate_Body");
731 end Output_Elaborate_Body_Transition;
733 ----------------------------------
734 -- Output_Elaborate_Suggestions --
735 ----------------------------------
737 procedure Output_Elaborate_Suggestions
739 Pred : Library_Graph_Vertex_Id;
740 Succ : Library_Graph_Vertex_Id)
743 pragma Assert (Present (G));
744 pragma Assert (Present (Pred));
745 pragma Assert (Present (Succ));
747 Error_Msg_Unit_1 := Name (G, Pred);
748 Error_Msg_Unit_2 := Name (G, Succ);
750 (" remove pragma Elaborate for unit $ in unit $");
751 end Output_Elaborate_Suggestions;
753 ---------------------------------
754 -- Output_Elaborate_Transition --
755 ---------------------------------
757 procedure Output_Elaborate_Transition
759 Source : Library_Graph_Vertex_Id;
760 Actual_Destination : Library_Graph_Vertex_Id;
761 Expected_Destination : Library_Graph_Vertex_Id)
763 Spec : Library_Graph_Vertex_Id;
766 pragma Assert (Present (G));
767 pragma Assert (Present (Source));
768 pragma Assert (Present (Actual_Destination));
769 pragma Assert (Present (Expected_Destination));
771 -- The actual and expected destination vertices match, and denote the
772 -- initial declaration of a unit.
774 -- Elaborate Actual_Destination
775 -- Source -----------> spec -->
776 -- Expected_Destination
778 -- Elaborate Actual_Destination
779 -- Source -----------> stand-alone body -->
780 -- Expected_Destination
782 -- The processing of pragma Elaborate body generates an edge between a
783 -- successor and predecessor body.
787 -- Elaborate Actual_Destination
788 -- Source -----------> body -->
789 -- Expected_Destination
791 if Actual_Destination = Expected_Destination then
793 -- Find the initial declaration of the unit because it is the one
794 -- subject to pragma Elaborate.
796 if Is_Body_With_Spec (G, Actual_Destination) then
797 Spec := Proper_Spec (G, Actual_Destination);
799 Spec := Actual_Destination;
802 Error_Msg_Unit_1 := Name (G, Source);
803 Error_Msg_Unit_2 := Name (G, Spec);
805 (" unit $ has with clause and pragma Elaborate for unit $");
807 if Actual_Destination /= Spec then
808 Error_Msg_Unit_1 := Name (G, Actual_Destination);
810 (" unit $ is in the closure of pragma Elaborate");
813 -- Otherwise the actual destination vertex denotes the spec of a unit
814 -- while the expected destination vertex is the corresponding body.
816 -- Elaborate Actual_Destination
817 -- Source -----------> spec
820 -- Expected_Destination
823 pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
824 pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
826 (Proper_Body (G, Actual_Destination) = Expected_Destination);
828 Error_Msg_Unit_1 := Name (G, Source);
829 Error_Msg_Unit_2 := Name (G, Actual_Destination);
831 (" unit $ has with clause and pragma Elaborate for unit $");
833 Error_Msg_Unit_1 := Name (G, Expected_Destination);
835 (" unit $ is in the closure of pragma Elaborate");
837 end Output_Elaborate_Transition;
839 -------------------------------
840 -- Output_Forced_Suggestions --
841 -------------------------------
843 procedure Output_Forced_Suggestions
845 Pred : Library_Graph_Vertex_Id;
846 Succ : Library_Graph_Vertex_Id)
849 pragma Assert (Present (G));
850 pragma Assert (Present (Pred));
851 pragma Assert (Present (Succ));
853 Error_Msg_Unit_1 := Name (G, Succ);
854 Error_Msg_Unit_2 := Name (G, Pred);
856 (" remove the dependency of unit $ on unit $ from the argument of "
859 (" remove switch -f");
860 end Output_Forced_Suggestions;
862 ------------------------------
863 -- Output_Forced_Transition --
864 ------------------------------
866 procedure Output_Forced_Transition
868 Source : Library_Graph_Vertex_Id;
869 Actual_Destination : Library_Graph_Vertex_Id;
870 Expected_Destination : Library_Graph_Vertex_Id;
871 Elaborate_All_Active : Boolean)
874 pragma Assert (Present (G));
875 pragma Assert (Present (Source));
876 pragma Assert (Present (Actual_Destination));
877 pragma Assert (Present (Expected_Destination));
879 -- The actual and expected destination vertices match
881 -- Forced Actual_Destination
882 -- Source --------> spec -->
883 -- Expected_Destination
885 -- Forced Actual_Destination
886 -- Source --------> body -->
887 -- Expected_Destination
889 if Actual_Destination = Expected_Destination then
890 Error_Msg_Unit_1 := Name (G, Source);
891 Error_Msg_Unit_2 := Name (G, Actual_Destination);
893 (" unit $ has a dependency on unit $ forced by -f switch");
895 -- The actual destination vertex denotes the spec of a unit while the
896 -- expected destination is the corresponding body, and the unit is in
897 -- the closure of an earlier Elaborate_All pragma.
899 -- Forced Actual_Destination
900 -- Source --------> spec
903 -- Expected_Destination
905 elsif Elaborate_All_Active then
906 pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
907 pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
909 (Proper_Body (G, Actual_Destination) = Expected_Destination);
911 Error_Msg_Unit_1 := Name (G, Source);
912 Error_Msg_Unit_2 := Name (G, Actual_Destination);
914 (" unit $ has a dependency on unit $ forced by -f switch");
916 Error_Msg_Unit_1 := Name (G, Expected_Destination);
918 (" unit $ is in the closure of pragma Elaborate_All");
920 -- Otherwise the actual destination vertex denotes a spec subject to
921 -- pragma Elaborate_Body while the expected destination denotes the
922 -- corresponding body.
924 -- Forced Actual_Destination
925 -- Source --------> spec Elaborate_Body
928 -- Expected_Destination
932 (Is_Elaborate_Body_Pair
934 Spec_Vertex => Actual_Destination,
935 Body_Vertex => Expected_Destination));
937 Error_Msg_Unit_1 := Name (G, Source);
938 Error_Msg_Unit_2 := Name (G, Actual_Destination);
940 (" unit $ has a dependency on unit $ forced by -f switch");
942 Error_Msg_Unit_1 := Name (G, Actual_Destination);
944 (" unit $ is subject to pragma Elaborate_Body");
946 Error_Msg_Unit_1 := Name (G, Expected_Destination);
948 (" unit $ is in the closure of pragma Elaborate_Body");
950 end Output_Forced_Transition;
952 --------------------------------------
953 -- Output_Full_Encoding_Suggestions --
954 --------------------------------------
956 procedure Output_Full_Encoding_Suggestions
958 Cycle : Library_Graph_Cycle_Id;
959 First_Edge : Library_Graph_Edge_Id)
961 Succ : Library_Graph_Vertex_Id;
964 pragma Assert (Present (G));
965 pragma Assert (Present (Cycle));
966 pragma Assert (Present (First_Edge));
968 if Is_Invocation_Edge (G, First_Edge) then
969 Succ := Successor (G, First_Edge);
971 if Invocation_Graph_Encoding (G, Succ) /= Full_Path_Encoding then
973 (" use detailed invocation information (compiler switch "
977 end Output_Full_Encoding_Suggestions;
979 ----------------------------
980 -- Output_Invocation_Path --
981 -----------------------------
983 procedure Output_Invocation_Path
984 (Inv_Graph : Invocation_Graph;
985 Lib_Graph : Library_Graph;
986 Elaborated_Vertex : Library_Graph_Vertex_Id;
987 Path : IGE_Lists.Doubly_Linked_List;
988 Path_Id : in out Nat)
990 Edge : Invocation_Graph_Edge_Id;
991 Iter : IGE_Lists.Iterator;
994 pragma Assert (Present (Inv_Graph));
995 pragma Assert (Present (Lib_Graph));
996 pragma Assert (Present (Elaborated_Vertex));
997 pragma Assert (IGE_Lists.Present (Path));
999 Error_Msg_Nat_1 := Path_Id;
1000 Error_Msg_Info (" path #:");
1002 Error_Msg_Unit_1 := Name (Lib_Graph, Elaborated_Vertex);
1003 Error_Msg_Info (" elaboration of unit $");
1005 Iter := IGE_Lists.Iterate (Path);
1006 while IGE_Lists.Has_Next (Iter) loop
1007 IGE_Lists.Next (Iter, Edge);
1009 Output_Invocation_Path_Transition
1010 (Inv_Graph => Inv_Graph,
1011 Lib_Graph => Lib_Graph,
1015 Path_Id := Path_Id + 1;
1016 end Output_Invocation_Path;
1018 ---------------------------------------
1019 -- Output_Invocation_Path_Transition --
1020 ---------------------------------------
1022 procedure Output_Invocation_Path_Transition
1023 (Inv_Graph : Invocation_Graph;
1024 Lib_Graph : Library_Graph;
1025 Edge : Invocation_Graph_Edge_Id)
1027 pragma Assert (Present (Inv_Graph));
1028 pragma Assert (Present (Lib_Graph));
1029 pragma Assert (Present (Edge));
1031 Declared : constant String := "declared at {:#:#";
1033 Targ : constant Invocation_Graph_Vertex_Id :=
1034 Target (Inv_Graph, Edge);
1035 Targ_Extra : constant Name_Id :=
1036 Extra (Inv_Graph, Edge);
1037 Targ_Vertex : constant Library_Graph_Vertex_Id :=
1038 Spec_Vertex (Inv_Graph, Targ);
1041 Error_Msg_Name_1 := Name (Inv_Graph, Targ);
1042 Error_Msg_Nat_1 := Line (Inv_Graph, Targ);
1043 Error_Msg_Nat_2 := Column (Inv_Graph, Targ);
1044 Error_Msg_File_1 := File_Name (Lib_Graph, Targ_Vertex);
1046 case Kind (Inv_Graph, Edge) is
1047 when Accept_Alternative =>
1049 (" selection of entry % "
1052 when Access_Taken =>
1054 (" aliasing of subprogram % "
1059 (" call to subprogram % "
1062 when Controlled_Adjustment
1063 | Internal_Controlled_Adjustment
1065 Error_Msg_Name_1 := Targ_Extra;
1067 (" adjustment actions for type % "
1070 when Controlled_Finalization
1071 | Internal_Controlled_Finalization
1073 Error_Msg_Name_1 := Targ_Extra;
1075 (" finalization actions for type % "
1078 when Controlled_Initialization
1079 | Internal_Controlled_Initialization
1080 | Type_Initialization
1082 Error_Msg_Name_1 := Targ_Extra;
1084 (" initialization actions for type % "
1087 when Default_Initial_Condition_Verification =>
1088 Error_Msg_Name_1 := Targ_Extra;
1090 (" verification of Default_Initial_Condition for type % "
1093 when Initial_Condition_Verification =>
1095 (" verification of Initial_Condition "
1098 when Instantiation =>
1100 (" instantiation % "
1103 when Invariant_Verification =>
1104 Error_Msg_Name_1 := Targ_Extra;
1106 (" verification of invariant for type % "
1109 when Postcondition_Verification =>
1110 Error_Msg_Name_1 := Targ_Extra;
1112 (" verification of postcondition for subprogram % "
1115 when Protected_Entry_Call =>
1117 (" call to protected entry % "
1120 when Protected_Subprogram_Call =>
1122 (" call to protected subprogram % "
1125 when Task_Activation =>
1127 (" activation of local task "
1130 when Task_Entry_Call =>
1132 (" call to task entry % "
1136 pragma Assert (False);
1139 end Output_Invocation_Path_Transition;
1141 -------------------------------------------
1142 -- Output_Invocation_Related_Suggestions --
1143 -------------------------------------------
1145 procedure Output_Invocation_Related_Suggestions
1147 Cycle : Library_Graph_Cycle_Id)
1150 pragma Assert (Present (G));
1151 pragma Assert (Present (Cycle));
1153 -- Nothing to do when the cycle does not contain an invocation edge
1155 if Invocation_Edge_Count (G, Cycle) = 0 then
1159 -- The cycle contains at least one invocation edge, where at least
1160 -- one of the paths the edge represents activates a task. The use of
1161 -- restriction No_Entry_Calls_In_Elaboration_Code may halt the flow
1162 -- within the task body on a select or accept statement, eliminating
1163 -- subsequent invocation edges, thus breaking the cycle.
1165 if not Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
1166 and then Contains_Task_Activation (G, Cycle)
1169 (" use pragma Restrictions "
1170 & "(No_Entry_Calls_In_Elaboration_Code)");
1173 -- The cycle contains at least one invocation edge where the successor
1174 -- was statically elaborated. The use of the dynamic model may remove
1175 -- one of the invocation edges in the cycle, thus breaking the cycle.
1177 if Contains_Static_Successor_Edge (G, Cycle) then
1179 (" use the dynamic elaboration model (compiler switch -gnatE)");
1181 end Output_Invocation_Related_Suggestions;
1183 ----------------------------------
1184 -- Output_Invocation_Transition --
1185 ----------------------------------
1187 procedure Output_Invocation_Transition
1188 (Inv_Graph : Invocation_Graph;
1189 Lib_Graph : Library_Graph;
1190 Source : Library_Graph_Vertex_Id;
1191 Destination : Library_Graph_Vertex_Id)
1194 pragma Assert (Present (Inv_Graph));
1195 pragma Assert (Present (Lib_Graph));
1196 pragma Assert (Present (Source));
1197 pragma Assert (Present (Destination));
1199 Error_Msg_Unit_1 := Name (Lib_Graph, Source);
1200 Error_Msg_Unit_2 := Name (Lib_Graph, Destination);
1202 (" unit $ invokes a construct of unit $ at elaboration time");
1204 Find_And_Output_Invocation_Paths
1205 (Inv_Graph => Inv_Graph,
1206 Lib_Graph => Lib_Graph,
1208 Destination => Destination);
1209 end Output_Invocation_Transition;
1211 ------------------------------------------
1212 -- Output_Reason_And_Circularity_Header --
1213 ------------------------------------------
1215 procedure Output_Reason_And_Circularity_Header
1217 First_Edge : Library_Graph_Edge_Id)
1219 pragma Assert (Present (G));
1220 pragma Assert (Present (First_Edge));
1222 Succ : constant Library_Graph_Vertex_Id := Successor (G, First_Edge);
1225 Error_Msg_Unit_1 := Name (G, Succ);
1226 Error_Msg ("Elaboration circularity detected");
1227 Error_Msg_Info ("");
1228 Error_Msg_Info (" Reason:");
1229 Error_Msg_Info ("");
1230 Error_Msg_Info (" unit $ depends on its own elaboration");
1231 Error_Msg_Info ("");
1232 Error_Msg_Info (" Circularity:");
1233 Error_Msg_Info ("");
1234 end Output_Reason_And_Circularity_Header;
1236 ------------------------
1237 -- Output_Suggestions --
1238 ------------------------
1240 procedure Output_Suggestions
1242 Cycle : Library_Graph_Cycle_Id;
1243 First_Edge : Library_Graph_Edge_Id)
1245 pragma Assert (Present (G));
1246 pragma Assert (Present (Cycle));
1247 pragma Assert (Present (First_Edge));
1249 Pred : constant Library_Graph_Vertex_Id := Predecessor (G, First_Edge);
1250 Succ : constant Library_Graph_Vertex_Id := Successor (G, First_Edge);
1253 Error_Msg_Info ("");
1254 Error_Msg_Info (" Suggestions:");
1255 Error_Msg_Info ("");
1257 -- Output edge-specific suggestions
1259 if Is_Elaborate_All_Edge (G, First_Edge) then
1260 Output_Elaborate_All_Suggestions
1265 elsif Is_Elaborate_Body_Edge (G, First_Edge) then
1266 Output_Elaborate_Body_Suggestions
1270 elsif Is_Elaborate_Edge (G, First_Edge) then
1271 Output_Elaborate_Suggestions
1276 elsif Is_Forced_Edge (G, First_Edge) then
1277 Output_Forced_Suggestions
1283 -- Output general purpose suggestions
1285 Output_Invocation_Related_Suggestions
1289 Output_Full_Encoding_Suggestions
1292 First_Edge => First_Edge);
1294 Output_All_Cycles_Suggestions (G);
1296 Error_Msg_Info ("");
1297 end Output_Suggestions;
1299 -----------------------
1300 -- Output_Transition --
1301 -----------------------
1303 procedure Output_Transition
1304 (Inv_Graph : Invocation_Graph;
1305 Lib_Graph : Library_Graph;
1306 Current_Edge : Library_Graph_Edge_Id;
1307 Next_Edge : Library_Graph_Edge_Id;
1308 Elaborate_All_Active : Boolean)
1310 pragma Assert (Present (Inv_Graph));
1311 pragma Assert (Present (Lib_Graph));
1312 pragma Assert (Present (Current_Edge));
1313 pragma Assert (Present (Next_Edge));
1315 Actual_Destination : constant Library_Graph_Vertex_Id :=
1316 Predecessor (Lib_Graph, Current_Edge);
1317 Expected_Destination : constant Library_Graph_Vertex_Id :=
1318 Successor (Lib_Graph, Next_Edge);
1319 Source : constant Library_Graph_Vertex_Id :=
1320 Successor (Lib_Graph, Current_Edge);
1323 if Is_Elaborate_All_Edge (Lib_Graph, Current_Edge) then
1324 Output_Elaborate_All_Transition
1327 Actual_Destination => Actual_Destination,
1328 Expected_Destination => Expected_Destination);
1330 elsif Is_Elaborate_Body_Edge (Lib_Graph, Current_Edge) then
1331 Output_Elaborate_Body_Transition
1334 Actual_Destination => Actual_Destination,
1335 Expected_Destination => Expected_Destination,
1336 Elaborate_All_Active => Elaborate_All_Active);
1338 elsif Is_Elaborate_Edge (Lib_Graph, Current_Edge) then
1339 Output_Elaborate_Transition
1342 Actual_Destination => Actual_Destination,
1343 Expected_Destination => Expected_Destination);
1345 elsif Is_Forced_Edge (Lib_Graph, Current_Edge) then
1346 Output_Forced_Transition
1349 Actual_Destination => Actual_Destination,
1350 Expected_Destination => Expected_Destination,
1351 Elaborate_All_Active => Elaborate_All_Active);
1353 elsif Is_Invocation_Edge (Lib_Graph, Current_Edge) then
1354 Output_Invocation_Transition
1355 (Inv_Graph => Inv_Graph,
1356 Lib_Graph => Lib_Graph,
1358 Destination => Expected_Destination);
1361 pragma Assert (Is_With_Edge (Lib_Graph, Current_Edge));
1363 Output_With_Transition
1366 Actual_Destination => Actual_Destination,
1367 Expected_Destination => Expected_Destination,
1368 Elaborate_All_Active => Elaborate_All_Active);
1370 end Output_Transition;
1372 ----------------------------
1373 -- Output_With_Transition --
1374 ----------------------------
1376 procedure Output_With_Transition
1378 Source : Library_Graph_Vertex_Id;
1379 Actual_Destination : Library_Graph_Vertex_Id;
1380 Expected_Destination : Library_Graph_Vertex_Id;
1381 Elaborate_All_Active : Boolean)
1384 pragma Assert (Present (G));
1385 pragma Assert (Present (Source));
1386 pragma Assert (Present (Actual_Destination));
1387 pragma Assert (Present (Expected_Destination));
1389 -- The actual and expected destination vertices match, and denote the
1390 -- initial declaration of a unit.
1392 -- with Actual_Destination
1393 -- Source ------> spec -->
1394 -- Expected_Destination
1396 -- with Actual_Destination
1397 -- Source ------> stand-alone body -->
1398 -- Expected_Destination
1400 if Actual_Destination = Expected_Destination then
1401 Error_Msg_Unit_1 := Name (G, Source);
1402 Error_Msg_Unit_2 := Name (G, Actual_Destination);
1404 (" unit $ has with clause for unit $");
1406 -- The actual destination vertex denotes the spec of a unit while the
1407 -- expected destination is the corresponding body, and the unit is in
1408 -- the closure of an earlier Elaborate_All pragma.
1410 -- with Actual_Destination
1411 -- Source ------> spec
1414 -- Expected_Destination
1416 elsif Elaborate_All_Active then
1417 pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
1418 pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
1420 (Proper_Body (G, Actual_Destination) = Expected_Destination);
1422 Error_Msg_Unit_1 := Name (G, Source);
1423 Error_Msg_Unit_2 := Name (G, Actual_Destination);
1425 (" unit $ has with clause for unit $");
1427 Error_Msg_Unit_1 := Name (G, Expected_Destination);
1429 (" unit $ is in the closure of pragma Elaborate_All");
1431 -- Otherwise the actual destination vertex denotes a spec subject to
1432 -- pragma Elaborate_Body while the expected destination denotes the
1433 -- corresponding body.
1435 -- with Actual_Destination
1436 -- Source ------> spec Elaborate_Body
1439 -- Expected_Destination
1443 (Is_Elaborate_Body_Pair
1445 Spec_Vertex => Actual_Destination,
1446 Body_Vertex => Expected_Destination));
1448 Error_Msg_Unit_1 := Name (G, Source);
1449 Error_Msg_Unit_2 := Name (G, Actual_Destination);
1451 (" unit $ has with clause for unit $");
1453 Error_Msg_Unit_1 := Name (G, Actual_Destination);
1455 (" unit $ is subject to pragma Elaborate_Body");
1457 Error_Msg_Unit_1 := Name (G, Expected_Destination);
1459 (" unit $ is in the closure of pragma Elaborate_Body");
1461 end Output_With_Transition;
1467 procedure Visit_Vertex
1468 (Inv_Graph : Invocation_Graph;
1469 Lib_Graph : Library_Graph;
1470 Invoker : Invocation_Graph_Vertex_Id;
1471 Invoker_Vertex : Library_Graph_Vertex_Id;
1472 Last_Vertex : Library_Graph_Vertex_Id;
1473 Elaborated_Vertex : Library_Graph_Vertex_Id;
1474 End_Vertex : Library_Graph_Vertex_Id;
1475 Visited_Invokers : IGV_Sets.Membership_Set;
1476 Path : IGE_Lists.Doubly_Linked_List;
1477 Path_Id : in out Nat)
1479 Edge : Invocation_Graph_Edge_Id;
1480 Iter : Edges_To_Targets_Iterator;
1481 Targ : Invocation_Graph_Vertex_Id;
1484 pragma Assert (Present (Inv_Graph));
1485 pragma Assert (Present (Lib_Graph));
1486 pragma Assert (Present (Invoker));
1487 pragma Assert (Present (Invoker_Vertex));
1488 pragma Assert (Present (Last_Vertex));
1489 pragma Assert (Present (Elaborated_Vertex));
1490 pragma Assert (Present (End_Vertex));
1491 pragma Assert (IGV_Sets.Present (Visited_Invokers));
1492 pragma Assert (IGE_Lists.Present (Path));
1494 -- The current invocation vertex resides within the end library vertex.
1495 -- Emit the path that started from some elaboration root and ultimately
1496 -- reached the desired library vertex.
1498 if Body_Vertex (Inv_Graph, Invoker) = End_Vertex
1499 and then Invoker_Vertex /= Last_Vertex
1501 Output_Invocation_Path
1502 (Inv_Graph => Inv_Graph,
1503 Lib_Graph => Lib_Graph,
1504 Elaborated_Vertex => Elaborated_Vertex,
1506 Path_Id => Path_Id);
1508 -- Otherwise extend the search for the end library vertex via all edges
1511 elsif not IGV_Sets.Contains (Visited_Invokers, Invoker) then
1513 -- Prepare for invoker backtracking
1515 IGV_Sets.Insert (Visited_Invokers, Invoker);
1517 -- Extend the search via all edges to targets
1519 Iter := Iterate_Edges_To_Targets (Inv_Graph, Invoker);
1520 while Has_Next (Iter) loop
1523 -- Prepare for edge backtracking
1525 IGE_Lists.Append (Path, Edge);
1527 -- The traversal proceeds through the library vertex that houses
1528 -- the body of the target.
1530 Targ := Target (Inv_Graph, Edge);
1533 (Inv_Graph => Inv_Graph,
1534 Lib_Graph => Lib_Graph,
1536 Invoker_Vertex => Body_Vertex (Inv_Graph, Targ),
1537 Last_Vertex => Invoker_Vertex,
1538 Elaborated_Vertex => Elaborated_Vertex,
1539 End_Vertex => End_Vertex,
1540 Visited_Invokers => Visited_Invokers,
1542 Path_Id => Path_Id);
1544 -- Backtrack the edge
1546 IGE_Lists.Delete_Last (Path);
1549 -- Backtrack the invoker
1551 IGV_Sets.Delete (Visited_Invokers, Invoker);
1555 end Bindo.Diagnostics;