1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- B I N D O . E L A B O R A T O R S --
9 -- Copyright (C) 2019-2023, 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 Butil
; use Butil
;
27 with Debug
; use Debug
;
28 with Output
; use Output
;
29 with Types
; use Types
;
31 with Bindo
.Augmentors
;
33 use Bindo
.Augmentors
.Library_Graph_Augmentors
;
37 use Bindo
.Builders
.Invocation_Graph_Builders
;
38 use Bindo
.Builders
.Library_Graph_Builders
;
40 with Bindo
.Diagnostics
;
41 use Bindo
.Diagnostics
;
46 with Bindo
.Validators
;
48 use Bindo
.Validators
.Elaboration_Order_Validators
;
52 use Bindo
.Writers
.ALI_Writers
;
53 use Bindo
.Writers
.Dependency_Writers
;
54 use Bindo
.Writers
.Elaboration_Order_Writers
;
55 use Bindo
.Writers
.Invocation_Graph_Writers
;
56 use Bindo
.Writers
.Library_Graph_Writers
;
57 use Bindo
.Writers
.Phase_Writers
;
58 use Bindo
.Writers
.Unit_Closure_Writers
;
61 with GNAT
.Graphs
; use GNAT
.Graphs
;
63 package body Bindo
.Elaborators
is
65 -- The following type defines the advancement of the elaboration order
66 -- algorithm in terms of steps.
68 type Elaboration_Order_Step
is new Natural;
70 Initial_Step
: constant Elaboration_Order_Step
:=
71 Elaboration_Order_Step
'First;
73 ----------------------------------------------
74 -- Invocation_And_Library_Graph_Elaborators --
75 ----------------------------------------------
77 package body Invocation_And_Library_Graph_Elaborators
is
79 -----------------------
80 -- Local subprograms --
81 -----------------------
83 procedure Create_Component_Vertex_Sets
86 Elaborable_Vertices
: out LGV_Sets
.Membership_Set
;
87 Waiting_Vertices
: out LGV_Sets
.Membership_Set
;
88 Step
: Elaboration_Order_Step
);
89 pragma Inline
(Create_Component_Vertex_Sets
);
90 -- Split all vertices of component Comp of library graph G as follows:
92 -- * Elaborable vertices are added to set Elaborable_Vertices.
94 -- * Vertices that are still waiting on their predecessors to be
95 -- elaborated are added to set Waiting_Vertices.
97 -- Step is the current step in the elaboration order.
99 procedure Create_Vertex_Sets
101 Elaborable_Vertices
: out LGV_Sets
.Membership_Set
;
102 Waiting_Vertices
: out LGV_Sets
.Membership_Set
;
103 Step
: Elaboration_Order_Step
);
104 pragma Inline
(Create_Vertex_Sets
);
105 -- Split all vertices of library graph G as follows:
107 -- * Elaborable vertices are added to set Elaborable_Vertices.
109 -- * Vertices that are still waiting on their predecessors to be
110 -- elaborated are added to set Waiting_Vertices.
112 -- Step is the current step in the elaboration order.
114 procedure Elaborate_Component
117 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
118 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
119 Order
: in out Unit_Id_Table
;
120 Step
: Elaboration_Order_Step
);
121 pragma Inline
(Elaborate_Component
);
122 -- Elaborate as many vertices as possible that appear in component Comp
123 -- of library graph G. The sets contain vertices arranged as follows:
125 -- * All_Elaborable_Vertices - all elaborable vertices in the library
128 -- * All_Waiting_Vertices - all vertices in the library graph that are
129 -- waiting on predecessors to be elaborated.
131 -- Order is the elaboration order. Step denotes the current step in the
132 -- elaboration order.
134 procedure Elaborate_Library_Graph
136 Order
: out Unit_Id_Table
;
137 Status
: out Elaboration_Order_Status
);
138 pragma Inline
(Elaborate_Library_Graph
);
139 -- Elaborate as many vertices as possible of library graph G. Order is
140 -- the elaboration order. Status is the condition of the elaboration
143 procedure Elaborate_Vertex
145 Vertex
: Library_Graph_Vertex_Id
;
146 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
147 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
148 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
149 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
150 Order
: in out Unit_Id_Table
;
151 Step
: Elaboration_Order_Step
;
152 Indent
: Indentation_Level
);
153 pragma Inline
(Elaborate_Vertex
);
154 -- Elaborate vertex Vertex of library graph G by adding its unit to
155 -- elaboration order Order. The routine updates awaiting successors
156 -- where applicable. The sets contain vertices arranged as follows:
158 -- * All_Elaborable_Vertices - all elaborable vertices in the library
161 -- * All_Waiting_Vertices - all vertices in the library graph that are
162 -- waiting on predecessors to be elaborated.
164 -- * Comp_Elaborable_Vertices - all elaborable vertices found in the
165 -- component of Vertex.
167 -- * Comp_Waiting_Vertices - all vertices found in the component of
168 -- Vertex that are still waiting on predecessors to be elaborated.
170 -- Order denotes the elaboration order. Step is the current step in the
171 -- elaboration order. Indent denotes the desired indentation level for
174 function Find_Best_Elaborable_Vertex
176 Set
: LGV_Sets
.Membership_Set
;
177 Step
: Elaboration_Order_Step
;
178 Indent
: Indentation_Level
) return Library_Graph_Vertex_Id
;
179 pragma Inline
(Find_Best_Elaborable_Vertex
);
180 -- Find the best vertex of library graph G from membership set S that
181 -- can be elaborated. Step is the current step in the elaboration order.
182 -- Indent is the desired indentation level for tracing.
184 function Find_Best_Vertex
186 Set
: LGV_Sets
.Membership_Set
;
187 Is_Suitable_Vertex
: LGV_Predicate_Ptr
;
188 Compare_Vertices
: LGV_Comparator_Ptr
;
189 Initial_Best_Msg
: String;
190 Subsequent_Best_Msg
: String;
191 Step
: Elaboration_Order_Step
;
192 Indent
: Indentation_Level
)
193 return Library_Graph_Vertex_Id
;
194 pragma Inline
(Find_Best_Vertex
);
195 -- Find the best vertex of library graph G from membership set S which
196 -- satisfies predicate Is_Suitable_Vertex and is preferred by comparator
197 -- Compare_Vertices. Initial_Best_Msg is emitted on the first candidate
198 -- vertex. Subsequent_Best_Msg is emitted whenever a better vertex is
199 -- discovered. Step is the current step in the elaboration order. Indent
200 -- is the desired indentation level for tracing.
202 function Find_Best_Weakly_Elaborable_Vertex
204 Set
: LGV_Sets
.Membership_Set
;
205 Step
: Elaboration_Order_Step
;
206 Indent
: Indentation_Level
) return Library_Graph_Vertex_Id
;
207 pragma Inline
(Find_Best_Weakly_Elaborable_Vertex
);
208 -- Find the best vertex of library graph G from membership set S that
209 -- can be weakly elaborated. Step is the current step in the elaboration
210 -- order. Indent is the desired indentation level for tracing.
212 function Has_Elaborable_Body
214 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
215 pragma Inline
(Has_Elaborable_Body
);
216 -- Determine whether vertex Vertex of library graph G has a body that is
217 -- elaborable. It is assumed that the vertex has been elaborated.
219 procedure Insert_Elaborable_Successor
221 Vertex
: Library_Graph_Vertex_Id
;
222 Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
223 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
224 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
226 Step
: Elaboration_Order_Step
;
227 Indent
: Indentation_Level
);
228 pragma Inline
(Insert_Elaborable_Successor
);
229 -- Add elaborable successor Vertex of library graph G to membership set
230 -- Elaborable_Vertices and remove it from both All_Waiting_Vertices and
231 -- Comp_Waiting_Vertices. Msg is a message emitted for tracing purposes.
232 -- Step is the current step in the elaboration order. Indent denotes the
233 -- desired indentation level for tracing.
235 procedure Insert_Vertex
237 Vertex
: Library_Graph_Vertex_Id
;
238 Set
: LGV_Sets
.Membership_Set
;
240 Step
: Elaboration_Order_Step
;
241 Indent
: Indentation_Level
);
242 pragma Inline
(Insert_Vertex
);
243 -- Add vertex Vertex of library graph G to membership set Set. Msg is
244 -- a message emitted for tracing purposes. Step is the current step in
245 -- the elaboration order. Indent is the desired indentation level for
248 function Is_Better_Elaborable_Vertex
250 Vertex
: Library_Graph_Vertex_Id
;
251 Compared_To
: Library_Graph_Vertex_Id
) return Precedence_Kind
;
252 pragma Inline
(Is_Better_Elaborable_Vertex
);
253 -- Determine whether vertex Vertex of library graph G is a better choice
254 -- for elaboration compared to vertex Compared_To.
256 function Is_Better_Weakly_Elaborable_Vertex
258 Vertex
: Library_Graph_Vertex_Id
;
259 Compared_To
: Library_Graph_Vertex_Id
) return Precedence_Kind
;
260 pragma Inline
(Is_Better_Weakly_Elaborable_Vertex
);
261 -- Determine whether vertex Vertex of library graph G is a better choice
262 -- for weak elaboration compared to vertex Compared_To.
264 function Is_Suitable_Elaborable_Vertex
266 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
267 pragma Inline
(Is_Suitable_Elaborable_Vertex
);
268 -- Determine whether vertex Vertex of library graph G is suitable for
271 function Is_Suitable_Weakly_Elaborable_Vertex
273 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
274 pragma Inline
(Is_Suitable_Weakly_Elaborable_Vertex
);
275 -- Determine whether vertex Vertex of library graph G is suitable for
278 procedure Set_Unit_Elaboration_Positions
(Order
: Unit_Id_Table
);
279 pragma Inline
(Set_Unit_Elaboration_Positions
);
280 -- Set the ALI.Units positions of all elaboration units in order Order
282 procedure Trace_Component
286 Step
: Elaboration_Order_Step
);
287 pragma Inline
(Trace_Component
);
288 -- Write elaboration-related information for component Comp of library
289 -- graph G to standard output, starting with message Msg. Step is the
290 -- current step in the elaboration order.
292 procedure Trace_Step
(Step
: Elaboration_Order_Step
);
293 pragma Inline
(Trace_Step
);
294 -- Write current step Step of the elaboration order to standard output
296 procedure Trace_Vertex
298 Vertex
: Library_Graph_Vertex_Id
;
300 Step
: Elaboration_Order_Step
;
301 Indent
: Indentation_Level
);
302 pragma Inline
(Trace_Vertex
);
303 -- Write elaboration-related information for vertex Vertex of library
304 -- graph G to standard output, starting with message Msg. Step is the
305 -- current step in the elaboration order. Indent denotes the desired
306 -- indentation level for tracing.
308 procedure Trace_Vertices
310 Set
: LGV_Sets
.Membership_Set
;
313 Step
: Elaboration_Order_Step
;
314 Indent
: Indentation_Level
);
315 pragma Inline
(Trace_Vertices
);
316 -- Write the candidate vertices of library graph G present in membership
317 -- set Set to standard output, starting with message Set_Msg. Vertex_Msg
318 -- is the message emitted prior to each vertex. Step denotes the current
319 -- step in the elaboration order. Indent denotes the desired indentation
320 -- level for tracing.
322 procedure Update_Successor
324 Edge
: Library_Graph_Edge_Id
;
325 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
326 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
327 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
328 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
329 Step
: Elaboration_Order_Step
;
330 Indent
: Indentation_Level
);
331 pragma Inline
(Update_Successor
);
332 -- Notify the successor of edge Edge of library graph G along with its
333 -- component that their predecessor has just been elaborated. This may
334 -- cause new vertices to become elaborable. The sets contain vertices
335 -- arranged as follows:
337 -- * All_Elaborable_Vertices - all elaborable vertices in the library
340 -- * All_Waiting_Vertices - all vertices in the library graph that are
341 -- waiting on predecessors to be elaborated.
343 -- * Comp_Elaborable_Vertices - all elaborable vertices found in the
344 -- component of Vertex.
346 -- * Comp_Waiting_Vertices - all vertices found in the component of
347 -- Vertex that are still waiting on predecessors to be elaborated.
349 -- Step is the current step in the elaboration order. Indent denotes the
350 -- desired indentation level for tracing.
352 procedure Update_Successors
354 Vertex
: Library_Graph_Vertex_Id
;
355 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
356 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
357 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
358 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
359 Step
: Elaboration_Order_Step
;
360 Indent
: Indentation_Level
);
361 pragma Inline
(Update_Successors
);
362 -- Notify all successors of vertex Vertex of library graph G along with
363 -- their components that their predecessor has just been elaborated.
364 -- This may cause new vertices to become elaborable. The sets contain
365 -- vertices arranged as follows:
367 -- * All_Elaborable_Vertices - all elaborable vertices in the library
370 -- * All_Waiting_Vertices - all vertices in the library graph that are
371 -- waiting on predecessors to be elaborated.
373 -- * Comp_Elaborable_Vertices - all elaborable vertices found in the
374 -- component of Vertex.
376 -- * Comp_Waiting_Vertices - all vertices found in the component of
377 -- Vertex that are still waiting on predecessors to be elaborated.
379 -- Step is the current step in the elaboration order. Indent denotes the
380 -- desired indentation level for tracing.
382 ----------------------------------
383 -- Create_Component_Vertex_Sets --
384 ----------------------------------
386 procedure Create_Component_Vertex_Sets
389 Elaborable_Vertices
: out LGV_Sets
.Membership_Set
;
390 Waiting_Vertices
: out LGV_Sets
.Membership_Set
;
391 Step
: Elaboration_Order_Step
)
393 pragma Assert
(Present
(G
));
394 pragma Assert
(Present
(Comp
));
396 Num_Of_Vertices
: constant Natural :=
397 Number_Of_Component_Vertices
(G
, Comp
);
399 Iter
: Component_Vertex_Iterator
;
400 Vertex
: Library_Graph_Vertex_Id
;
403 Elaborable_Vertices
:= LGV_Sets
.Create
(Num_Of_Vertices
);
404 Waiting_Vertices
:= LGV_Sets
.Create
(Num_Of_Vertices
);
406 Iter
:= Iterate_Component_Vertices
(G
, Comp
);
407 while Has_Next
(Iter
) loop
410 -- Add the vertex to the proper set depending on whether it can be
413 if Is_Elaborable_Vertex
(G
, Vertex
) then
417 Set
=> Elaborable_Vertices
,
418 Msg
=> "add elaborable component vertex",
420 Indent
=> No_Indentation
);
426 Set
=> Waiting_Vertices
,
427 Msg
=> "add waiting component vertex",
429 Indent
=> No_Indentation
);
432 end Create_Component_Vertex_Sets
;
434 ------------------------
435 -- Create_Vertex_Sets --
436 ------------------------
438 procedure Create_Vertex_Sets
440 Elaborable_Vertices
: out LGV_Sets
.Membership_Set
;
441 Waiting_Vertices
: out LGV_Sets
.Membership_Set
;
442 Step
: Elaboration_Order_Step
)
444 pragma Assert
(Present
(G
));
446 Num_Of_Vertices
: constant Natural := Number_Of_Vertices
(G
);
448 Iter
: Library_Graphs
.All_Vertex_Iterator
;
449 Vertex
: Library_Graph_Vertex_Id
;
452 Elaborable_Vertices
:= LGV_Sets
.Create
(Num_Of_Vertices
);
453 Waiting_Vertices
:= LGV_Sets
.Create
(Num_Of_Vertices
);
455 Iter
:= Iterate_All_Vertices
(G
);
456 while Has_Next
(Iter
) loop
459 -- Add the vertex to the proper set depending on whether it can be
462 if Is_Elaborable_Vertex
(G
, Vertex
) then
466 Set
=> Elaborable_Vertices
,
467 Msg
=> "add elaborable vertex",
469 Indent
=> No_Indentation
);
475 Set
=> Waiting_Vertices
,
476 Msg
=> "add waiting vertex",
478 Indent
=> No_Indentation
);
481 end Create_Vertex_Sets
;
483 -------------------------
484 -- Elaborate_Component --
485 -------------------------
487 procedure Elaborate_Component
490 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
491 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
492 Order
: in out Unit_Id_Table
;
493 Step
: Elaboration_Order_Step
)
495 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
496 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
497 Vertex
: Library_Graph_Vertex_Id
;
500 pragma Assert
(Present
(G
));
501 pragma Assert
(Present
(Comp
));
502 pragma Assert
(LGV_Sets
.Present
(All_Elaborable_Vertices
));
503 pragma Assert
(LGV_Sets
.Present
(All_Waiting_Vertices
));
508 Msg
=> "elaborating component",
511 -- Divide all vertices of the component into an elaborable and
512 -- waiting vertex set.
514 Create_Component_Vertex_Sets
517 Elaborable_Vertices
=> Comp_Elaborable_Vertices
,
518 Waiting_Vertices
=> Comp_Waiting_Vertices
,
524 Set
=> Comp_Elaborable_Vertices
,
525 Set_Msg
=> "elaborable component vertices",
526 Vertex_Msg
=> "elaborable component vertex",
528 Indent
=> Nested_Indentation
);
532 Set
=> Comp_Waiting_Vertices
,
533 Set_Msg
=> "waiting component vertices",
534 Vertex_Msg
=> "waiting component vertex",
536 Indent
=> Nested_Indentation
);
539 Find_Best_Elaborable_Vertex
541 Set
=> Comp_Elaborable_Vertices
,
543 Indent
=> Nested_Indentation
);
545 -- The component lacks an elaborable vertex. This indicates that
546 -- either all vertices of the component have been elaborated or
547 -- the graph has a circularity. Locate the best weak vertex that
548 -- was compiled with the dynamic model to elaborate from the set
549 -- waiting vertices. This action assumes that certain invocations
550 -- will not take place at elaboration time. An order produced in
551 -- this fashion may fail an ABE check at run time.
553 if not Present
(Vertex
) then
555 Find_Best_Weakly_Elaborable_Vertex
557 Set
=> Comp_Waiting_Vertices
,
559 Indent
=> Nested_Indentation
);
562 -- Stop the elaboration when either all vertices of the component
563 -- have been elaborated, or the graph contains a circularity.
565 exit when not Present
(Vertex
);
567 -- Try to elaborate as many vertices within the component as
568 -- possible. Each successful elaboration signals the appropriate
569 -- successors and components that they have one less predecessor
575 All_Elaborable_Vertices
=> All_Elaborable_Vertices
,
576 All_Waiting_Vertices
=> All_Waiting_Vertices
,
577 Comp_Elaborable_Vertices
=> Comp_Elaborable_Vertices
,
578 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
581 Indent
=> Nested_Indentation
);
584 LGV_Sets
.Destroy
(Comp_Elaborable_Vertices
);
585 LGV_Sets
.Destroy
(Comp_Waiting_Vertices
);
586 end Elaborate_Component
;
588 -----------------------------
589 -- Elaborate_Library_Graph --
590 -----------------------------
592 procedure Elaborate_Library_Graph
594 Order
: out Unit_Id_Table
;
595 Status
: out Elaboration_Order_Status
)
597 Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
598 Step
: Elaboration_Order_Step
;
599 Vertex
: Library_Graph_Vertex_Id
;
600 Waiting_Vertices
: LGV_Sets
.Membership_Set
;
603 pragma Assert
(Present
(G
));
605 Step
:= Initial_Step
;
607 -- Divide all vertices of the library graph into an elaborable and
608 -- waiting vertex set.
612 Elaborable_Vertices
=> Elaborable_Vertices
,
613 Waiting_Vertices
=> Waiting_Vertices
,
621 Set
=> Elaborable_Vertices
,
622 Set_Msg
=> "elaborable vertices",
623 Vertex_Msg
=> "elaborable vertex",
625 Indent
=> No_Indentation
);
629 Set
=> Waiting_Vertices
,
630 Set_Msg
=> "waiting vertices",
631 Vertex_Msg
=> "waiting vertex",
633 Indent
=> No_Indentation
);
636 Find_Best_Elaborable_Vertex
638 Set
=> Elaborable_Vertices
,
640 Indent
=> No_Indentation
);
642 -- The graph lacks an elaborable vertex. This indicates that
643 -- either all vertices have been elaborated or the graph has a
644 -- circularity. Find the best weak vertex that was compiled with
645 -- the dynamic model to elaborate from set of waiting vertices.
646 -- This action assumes that certain invocations will not take
647 -- place at elaboration time. An order produced in this fashion
648 -- may fail an ABE check at run time.
650 if not Present
(Vertex
) then
652 Find_Best_Weakly_Elaborable_Vertex
654 Set
=> Waiting_Vertices
,
656 Indent
=> No_Indentation
);
659 -- Stop the elaboration when either all vertices of the graph have
660 -- been elaborated, or the graph contains a circularity.
662 exit when not Present
(Vertex
);
664 -- Elaborate the component of the vertex by trying to elaborate as
665 -- many vertices within the component as possible. Each successful
666 -- elaboration signals the appropriate successors and components
667 -- that they have one less predecessor to wait on.
671 Comp
=> Component
(G
, Vertex
),
672 All_Elaborable_Vertices
=> Elaborable_Vertices
,
673 All_Waiting_Vertices
=> Waiting_Vertices
,
678 -- The graph contains an Elaborate_All circularity when at least one
679 -- edge subject to the related pragma appears in a component.
681 if Has_Elaborate_All_Cycle
(G
) then
682 Status
:= Order_Has_Elaborate_All_Circularity
;
684 -- The graph contains a circularity when at least one vertex failed
687 elsif LGV_Sets
.Size
(Waiting_Vertices
) /= 0 then
688 Status
:= Order_Has_Circularity
;
690 -- Otherwise the elaboration order is satisfactory
696 LGV_Sets
.Destroy
(Elaborable_Vertices
);
697 LGV_Sets
.Destroy
(Waiting_Vertices
);
698 end Elaborate_Library_Graph
;
700 ---------------------
701 -- Elaborate_Units --
702 ---------------------
704 procedure Elaborate_Units
705 (Order
: out Unit_Id_Table
;
706 Main_Lib_File
: File_Name_Type
)
708 pragma Unreferenced
(Main_Lib_File
);
710 Inv_Graph
: Invocation_Graph
;
711 Lib_Graph
: Library_Graph
;
712 Status
: Elaboration_Order_Status
;
715 Start_Phase
(Unit_Elaboration
);
717 -- Initialize all unit-related data structures and gather all units
718 -- that need elaboration.
721 Collect_Elaborable_Units
;
723 -- Create the library graph that captures the dependencies between
726 Lib_Graph
:= Build_Library_Graph
;
728 -- Create the invocation graph that represents the flow of execution
730 Inv_Graph
:= Build_Invocation_Graph
(Lib_Graph
);
732 -- Traverse the invocation graph starting from elaboration code in
733 -- order to discover transitions of the execution flow from a unit
734 -- to a unit that result in extra edges within the library graph.
736 Augment_Library_Graph
(Inv_Graph
);
738 -- Create the component graph by collapsing all library items into
739 -- library units and traversing the library graph.
741 Find_Components
(Lib_Graph
);
743 -- Output the contents of the ALI tables and both graphs to standard
744 -- output now that they have been fully decorated.
747 Write_Invocation_Graph
(Inv_Graph
);
748 Write_Library_Graph
(Lib_Graph
);
750 -- Traverse the library graph to determine the elaboration order of
753 Elaborate_Library_Graph
(Lib_Graph
, Order
, Status
);
755 -- The elaboration order is satisfactory
757 if Status
= Order_OK
then
758 Validate_Elaboration_Order
(Order
);
760 -- Set attribute Elab_Position of table ALI.Units for all units in
761 -- the elaboration order.
763 Set_Unit_Elaboration_Positions
(Order
);
765 -- Output the dependencies among units when switch -e (output
766 -- complete list of elaboration order dependencies) is active.
768 Write_Dependencies
(Lib_Graph
);
770 -- Output the elaboration order when switch -l (output chosen
771 -- elaboration order) is in effect.
773 Write_Elaboration_Order
(Order
);
775 -- Output the sources referenced in the closure of the order when
776 -- switch -R (list sources referenced in closure) is in effect.
778 Write_Unit_Closure
(Order
);
780 -- Otherwise the library graph contains at least one circularity
783 Diagnose_Circularities
(Inv_Graph
);
789 -- Destroy all unit-related data structures
792 End_Phase
(Unit_Elaboration
);
794 -- Halt the bind when there is no satisfactory elaboration order
796 if Status
/= Order_OK
then
797 raise Unrecoverable_Error
;
801 ----------------------
802 -- Elaborate_Vertex --
803 ----------------------
805 procedure Elaborate_Vertex
807 Vertex
: Library_Graph_Vertex_Id
;
808 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
809 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
810 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
811 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
812 Order
: in out Unit_Id_Table
;
813 Step
: Elaboration_Order_Step
;
814 Indent
: Indentation_Level
)
817 pragma Assert
(Present
(G
));
818 pragma Assert
(Present
(Vertex
));
819 pragma Assert
(Needs_Elaboration
(G
, Vertex
));
820 pragma Assert
(LGV_Sets
.Present
(All_Elaborable_Vertices
));
821 pragma Assert
(LGV_Sets
.Present
(All_Waiting_Vertices
));
822 pragma Assert
(LGV_Sets
.Present
(Comp_Elaborable_Vertices
));
823 pragma Assert
(LGV_Sets
.Present
(Comp_Waiting_Vertices
));
828 Msg
=> "elaborating vertex",
832 -- Remove the vertex from both elaborable sets. This is needed when
833 -- the vertex is both an overall best candidate among all vertices,
834 -- and the best candidate within the component.
836 LGV_Sets
.Delete
(All_Elaborable_Vertices
, Vertex
);
837 LGV_Sets
.Delete
(Comp_Elaborable_Vertices
, Vertex
);
839 -- Remove the vertex from both waiting sets. This is needed when a
840 -- weakly elaborable vertex is both an overall best candidate among
841 -- all waiting vertices and the best waiting candidate within the
844 LGV_Sets
.Delete
(All_Waiting_Vertices
, Vertex
);
845 LGV_Sets
.Delete
(Comp_Waiting_Vertices
, Vertex
);
847 -- Mark the vertex as elaborated in order to prevent further attempts
848 -- to re-elaborate it.
850 Set_In_Elaboration_Order
(G
, Vertex
);
852 -- Add the unit represented by the vertex to the elaboration order
854 Unit_Id_Tables
.Append
(Order
, Unit
(G
, Vertex
));
856 -- Notify all successors and their components that they have one
857 -- fewer predecessor to wait on. This may cause some successors to
858 -- be included in one of the sets.
863 All_Elaborable_Vertices
=> All_Elaborable_Vertices
,
864 All_Waiting_Vertices
=> All_Waiting_Vertices
,
865 Comp_Elaborable_Vertices
=> Comp_Elaborable_Vertices
,
866 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
868 Indent
=> Indent
+ Nested_Indentation
);
870 -- Elaborate an eligible completing body immediately after its spec.
871 -- This action satisfies the semantics of pragma Elaborate_Body. In
872 -- addition, it ensures that a body will not "drift" too far from its
873 -- spec in case invocation edges are removed from the library graph.
875 if Has_Elaborable_Body
(G
, Vertex
) then
878 Vertex
=> Proper_Body
(G
, Vertex
),
879 All_Elaborable_Vertices
=> All_Elaborable_Vertices
,
880 All_Waiting_Vertices
=> All_Waiting_Vertices
,
881 Comp_Elaborable_Vertices
=> Comp_Elaborable_Vertices
,
882 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
887 end Elaborate_Vertex
;
889 ---------------------------------
890 -- Find_Best_Elaborable_Vertex --
891 ---------------------------------
893 function Find_Best_Elaborable_Vertex
895 Set
: LGV_Sets
.Membership_Set
;
896 Step
: Elaboration_Order_Step
;
897 Indent
: Indentation_Level
) return Library_Graph_Vertex_Id
900 pragma Assert
(Present
(G
));
901 pragma Assert
(LGV_Sets
.Present
(Set
));
907 Is_Suitable_Vertex
=>
908 Is_Suitable_Elaborable_Vertex
'Access,
910 Is_Better_Elaborable_Vertex
'Access,
911 Initial_Best_Msg
=> "initial best elaborable vertex",
912 Subsequent_Best_Msg
=> "better elaborable vertex",
915 end Find_Best_Elaborable_Vertex
;
917 ----------------------
918 -- Find_Best_Vertex --
919 ----------------------
921 function Find_Best_Vertex
923 Set
: LGV_Sets
.Membership_Set
;
924 Is_Suitable_Vertex
: LGV_Predicate_Ptr
;
925 Compare_Vertices
: LGV_Comparator_Ptr
;
926 Initial_Best_Msg
: String;
927 Subsequent_Best_Msg
: String;
928 Step
: Elaboration_Order_Step
;
929 Indent
: Indentation_Level
)
930 return Library_Graph_Vertex_Id
932 Best_Vertex
: Library_Graph_Vertex_Id
;
933 Current_Vertex
: Library_Graph_Vertex_Id
;
934 Iter
: LGV_Sets
.Iterator
;
937 pragma Assert
(Present
(G
));
938 pragma Assert
(LGV_Sets
.Present
(Set
));
939 pragma Assert
(Is_Suitable_Vertex
/= null);
940 pragma Assert
(Compare_Vertices
/= null);
942 -- Assume that there is no candidate
944 Best_Vertex
:= No_Library_Graph_Vertex
;
946 -- Inspect all vertices in the set, looking for the best candidate
947 -- according to the comparator.
949 Iter
:= LGV_Sets
.Iterate
(Set
);
950 while LGV_Sets
.Has_Next
(Iter
) loop
951 LGV_Sets
.Next
(Iter
, Current_Vertex
);
952 pragma Assert
(Needs_Elaboration
(G
, Current_Vertex
));
954 if Is_Suitable_Vertex
.all (G
, Current_Vertex
) then
956 -- A previous iteration already picked the best candidate.
957 -- Update the best candidate when the current vertex is a
960 if Present
(Best_Vertex
) then
961 if Compare_Vertices
.all
963 Vertex
=> Current_Vertex
,
964 Compared_To
=> Best_Vertex
) = Higher_Precedence
966 Best_Vertex
:= Current_Vertex
;
970 Vertex
=> Best_Vertex
,
971 Msg
=> Subsequent_Best_Msg
,
976 -- Otherwise this is the first candidate
979 Best_Vertex
:= Current_Vertex
;
983 Vertex
=> Best_Vertex
,
984 Msg
=> Initial_Best_Msg
,
992 end Find_Best_Vertex
;
994 ----------------------------------------
995 -- Find_Best_Weakly_Elaborable_Vertex --
996 ----------------------------------------
998 function Find_Best_Weakly_Elaborable_Vertex
1000 Set
: LGV_Sets
.Membership_Set
;
1001 Step
: Elaboration_Order_Step
;
1002 Indent
: Indentation_Level
) return Library_Graph_Vertex_Id
1005 pragma Assert
(Present
(G
));
1006 pragma Assert
(LGV_Sets
.Present
(Set
));
1012 Is_Suitable_Vertex
=>
1013 Is_Suitable_Weakly_Elaborable_Vertex
'Access,
1015 Is_Better_Weakly_Elaborable_Vertex
'Access,
1016 Initial_Best_Msg
=> "initial best weakly elaborable vertex",
1017 Subsequent_Best_Msg
=> "better weakly elaborable vertex",
1020 end Find_Best_Weakly_Elaborable_Vertex
;
1022 -------------------------
1023 -- Has_Elaborable_Body --
1024 -------------------------
1026 function Has_Elaborable_Body
1028 Vertex
: Library_Graph_Vertex_Id
) return Boolean
1031 pragma Assert
(Present
(G
));
1032 pragma Assert
(Present
(Vertex
));
1034 -- The body of an already-elaborated spec subject to Elaborate_Body
1035 -- is always elaborable.
1037 if Is_Spec_With_Elaborate_Body
(G
, Vertex
) then
1040 elsif Is_Spec_With_Body
(G
, Vertex
) then
1041 return Is_Elaborable_Vertex
(G
, Proper_Body
(G
, Vertex
));
1045 end Has_Elaborable_Body
;
1047 ---------------------------------
1048 -- Insert_Elaborable_Successor --
1049 ---------------------------------
1051 procedure Insert_Elaborable_Successor
1053 Vertex
: Library_Graph_Vertex_Id
;
1054 Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
1055 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
1056 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
1058 Step
: Elaboration_Order_Step
;
1059 Indent
: Indentation_Level
)
1061 pragma Assert
(Present
(G
));
1062 pragma Assert
(Present
(Vertex
));
1063 pragma Assert
(LGV_Sets
.Present
(Elaborable_Vertices
));
1064 pragma Assert
(LGV_Sets
.Present
(All_Waiting_Vertices
));
1065 pragma Assert
(LGV_Sets
.Present
(Comp_Waiting_Vertices
));
1067 Complement
: constant Library_Graph_Vertex_Id
:=
1068 Complementary_Vertex
1071 Force_Complement
=> False);
1074 -- Remove the successor from both waiting vertex sets because it may
1075 -- be the best vertex to elaborate across the whole graph and within
1078 LGV_Sets
.Delete
(All_Waiting_Vertices
, Vertex
);
1079 LGV_Sets
.Delete
(Comp_Waiting_Vertices
, Vertex
);
1084 Set
=> Elaborable_Vertices
,
1089 if Present
(Complement
) then
1091 -- Remove the complement of the successor from both waiting vertex
1092 -- sets because it may be the best vertex to elaborate across the
1093 -- whole graph and within its component.
1095 LGV_Sets
.Delete
(All_Waiting_Vertices
, Complement
);
1096 LGV_Sets
.Delete
(Comp_Waiting_Vertices
, Complement
);
1100 Vertex
=> Complement
,
1101 Set
=> Elaborable_Vertices
,
1106 end Insert_Elaborable_Successor
;
1112 procedure Insert_Vertex
1114 Vertex
: Library_Graph_Vertex_Id
;
1115 Set
: LGV_Sets
.Membership_Set
;
1117 Step
: Elaboration_Order_Step
;
1118 Indent
: Indentation_Level
)
1121 pragma Assert
(Present
(G
));
1122 pragma Assert
(Present
(Vertex
));
1123 pragma Assert
(Needs_Elaboration
(G
, Vertex
));
1124 pragma Assert
(LGV_Sets
.Present
(Set
));
1126 -- Nothing to do when the vertex is already present in the set
1128 if LGV_Sets
.Contains
(Set
, Vertex
) then
1139 -- Add the vertex to the set
1141 LGV_Sets
.Insert
(Set
, Vertex
);
1144 ---------------------------------
1145 -- Is_Better_Elaborable_Vertex --
1146 ---------------------------------
1148 function Is_Better_Elaborable_Vertex
1150 Vertex
: Library_Graph_Vertex_Id
;
1151 Compared_To
: Library_Graph_Vertex_Id
) return Precedence_Kind
1154 pragma Assert
(Present
(G
));
1155 pragma Assert
(Present
(Vertex
));
1156 pragma Assert
(Present
(Compared_To
));
1158 -- Prefer a spec with Elaborate_Body over its corresponding body
1160 if Is_Elaborate_Body_Pair
1162 Spec_Vertex
=> Vertex
,
1163 Body_Vertex
=> Compared_To
)
1165 return Higher_Precedence
;
1167 elsif Is_Elaborate_Body_Pair
1169 Spec_Vertex
=> Compared_To
,
1170 Body_Vertex
=> Vertex
)
1172 return Lower_Precedence
;
1174 -- Prefer a predefined unit over a non-predefined unit
1176 elsif Is_Predefined_Unit
(G
, Vertex
)
1177 and then not Is_Predefined_Unit
(G
, Compared_To
)
1179 return Higher_Precedence
;
1181 elsif not Is_Predefined_Unit
(G
, Vertex
)
1182 and then Is_Predefined_Unit
(G
, Compared_To
)
1184 return Lower_Precedence
;
1186 -- Prefer an internal unit over a non-internal unit
1188 elsif Is_Internal_Unit
(G
, Vertex
)
1189 and then not Is_Internal_Unit
(G
, Compared_To
)
1191 return Higher_Precedence
;
1193 elsif not Is_Internal_Unit
(G
, Vertex
)
1194 and then Is_Internal_Unit
(G
, Compared_To
)
1196 return Lower_Precedence
;
1198 -- Prefer a preelaborated unit over a non-preelaborated unit
1200 elsif Is_Preelaborated_Unit
(G
, Vertex
)
1201 and then not Is_Preelaborated_Unit
(G
, Compared_To
)
1203 return Higher_Precedence
;
1205 elsif not Is_Preelaborated_Unit
(G
, Vertex
)
1206 and then Is_Preelaborated_Unit
(G
, Compared_To
)
1208 return Lower_Precedence
;
1210 -- Otherwise default to lexicographical order to ensure deterministic
1213 elsif Uname_Less
(Name
(G
, Vertex
), Name
(G
, Compared_To
)) then
1214 return Higher_Precedence
;
1217 return Lower_Precedence
;
1219 end Is_Better_Elaborable_Vertex
;
1221 ----------------------------------------
1222 -- Is_Better_Weakly_Elaborable_Vertex --
1223 ----------------------------------------
1225 function Is_Better_Weakly_Elaborable_Vertex
1227 Vertex
: Library_Graph_Vertex_Id
;
1228 Compared_To
: Library_Graph_Vertex_Id
) return Precedence_Kind
1230 Comp_Strong_Preds
: Natural;
1231 Comp_Weak_Preds
: Natural;
1232 Vertex_Strong_Preds
: Natural;
1233 Vertex_Weak_Preds
: Natural;
1236 pragma Assert
(Present
(G
));
1237 pragma Assert
(Present
(Vertex
));
1238 pragma Assert
(Present
(Compared_To
));
1240 -- Obtain the number of pending predecessors for both candidates,
1241 -- taking into account Elaborate_Body pairs.
1243 Pending_Predecessors_For_Elaboration
1246 Strong_Preds
=> Vertex_Strong_Preds
,
1247 Weak_Preds
=> Vertex_Weak_Preds
);
1249 Pending_Predecessors_For_Elaboration
1251 Vertex
=> Compared_To
,
1252 Strong_Preds
=> Comp_Strong_Preds
,
1253 Weak_Preds
=> Comp_Weak_Preds
);
1255 -- Neither candidate should be waiting on strong predecessors,
1256 -- otherwise the candidate cannot be weakly elaborated.
1258 pragma Assert
(Vertex_Strong_Preds
= 0);
1259 pragma Assert
(Comp_Strong_Preds
= 0);
1261 -- Prefer a unit with fewer weak predecessors over a unit with more
1262 -- weak predecessors.
1264 if Vertex_Weak_Preds
< Comp_Weak_Preds
then
1265 return Higher_Precedence
;
1267 elsif Vertex_Weak_Preds
> Comp_Weak_Preds
then
1268 return Lower_Precedence
;
1270 -- Otherwise default to lexicographical order to ensure deterministic
1273 elsif Uname_Less
(Name
(G
, Vertex
), Name
(G
, Compared_To
)) then
1274 return Higher_Precedence
;
1277 return Lower_Precedence
;
1279 end Is_Better_Weakly_Elaborable_Vertex
;
1281 -----------------------------------
1282 -- Is_Suitable_Elaborable_Vertex --
1283 -----------------------------------
1285 function Is_Suitable_Elaborable_Vertex
1287 Vertex
: Library_Graph_Vertex_Id
) return Boolean
1290 pragma Assert
(Present
(G
));
1291 pragma Assert
(Present
(Vertex
));
1293 -- A vertex is suitable for elaboration as long it is not waiting on
1294 -- any predecessors, ignoring the static or dynamic model.
1296 return Is_Elaborable_Vertex
(G
, Vertex
);
1297 end Is_Suitable_Elaborable_Vertex
;
1299 ------------------------------------------
1300 -- Is_Suitable_Weakly_Elaborable_Vertex --
1301 ------------------------------------------
1303 function Is_Suitable_Weakly_Elaborable_Vertex
1305 Vertex
: Library_Graph_Vertex_Id
) return Boolean
1308 pragma Assert
(Present
(G
));
1309 pragma Assert
(Present
(Vertex
));
1311 -- A vertex is suitable for weak elaboration when it is waiting on
1312 -- weak predecessors only, and the unit it represents was compiled
1313 -- using the dynamic model.
1316 Is_Dynamically_Elaborated
(G
, Vertex
)
1317 and then Is_Weakly_Elaborable_Vertex
(G
, Vertex
);
1318 end Is_Suitable_Weakly_Elaborable_Vertex
;
1320 ------------------------------------
1321 -- Set_Unit_Elaboration_Positions --
1322 ------------------------------------
1324 procedure Set_Unit_Elaboration_Positions
(Order
: Unit_Id_Table
) is
1328 for Position
in Unit_Id_Tables
.First
..
1329 Unit_Id_Tables
.Last
(Order
)
1331 U_Id
:= Order
.Table
(Position
);
1333 ALI
.Units
.Table
(U_Id
).Elab_Position
:= Position
;
1335 end Set_Unit_Elaboration_Positions
;
1337 ---------------------
1338 -- Trace_Component --
1339 ---------------------
1341 procedure Trace_Component
1343 Comp
: Component_Id
;
1345 Step
: Elaboration_Order_Step
)
1348 pragma Assert
(Present
(G
));
1349 pragma Assert
(Present
(Comp
));
1351 -- Nothing to do when switch -d_T (output elaboration order and cycle
1352 -- detection trace information) is not in effect.
1354 if not Debug_Flag_Underscore_TT
then
1360 Write_Str
(" (Comp_Id_");
1361 Write_Int
(Int
(Comp
));
1366 Indent_By
(Nested_Indentation
);
1367 Write_Str
("pending strong predecessors: ");
1368 Write_Num
(Int
(Pending_Strong_Predecessors
(G
, Comp
)));
1372 Indent_By
(Nested_Indentation
);
1373 Write_Str
("pending weak predecessors : ");
1374 Write_Num
(Int
(Pending_Weak_Predecessors
(G
, Comp
)));
1376 end Trace_Component
;
1382 procedure Trace_Step
(Step
: Elaboration_Order_Step
) is
1384 -- Nothing to do when switch -d_T (output elaboration order and cycle
1385 -- detection trace information) is not in effect.
1387 if not Debug_Flag_Underscore_TT
then
1393 Val_Indent
=> Step_Column
);
1401 procedure Trace_Vertex
1403 Vertex
: Library_Graph_Vertex_Id
;
1405 Step
: Elaboration_Order_Step
;
1406 Indent
: Indentation_Level
)
1408 pragma Assert
(Present
(G
));
1409 pragma Assert
(Present
(Vertex
));
1411 Attr_Indent
: constant Indentation_Level
:=
1412 Indent
+ Nested_Indentation
;
1413 Comp
: constant Component_Id
:= Component
(G
, Vertex
);
1416 -- Nothing to do when switch -d_T (output elaboration order and cycle
1417 -- detection trace information) is not in effect.
1419 if not Debug_Flag_Underscore_TT
then
1426 Write_Str
(" (LGV_Id_");
1427 Write_Int
(Int
(Vertex
));
1432 Indent_By
(Attr_Indent
);
1433 Write_Str
("name = ");
1434 Write_Name
(Name
(G
, Vertex
));
1438 Indent_By
(Attr_Indent
);
1439 Write_Str
("Component (Comp_Id_");
1440 Write_Int
(Int
(Comp
));
1445 Indent_By
(Attr_Indent
);
1446 Write_Str
("pending strong predecessors: ");
1447 Write_Num
(Int
(Pending_Strong_Predecessors
(G
, Vertex
)));
1451 Indent_By
(Attr_Indent
);
1452 Write_Str
("pending weak predecessors : ");
1453 Write_Num
(Int
(Pending_Weak_Predecessors
(G
, Vertex
)));
1457 Indent_By
(Attr_Indent
);
1458 Write_Str
("pending strong components : ");
1459 Write_Num
(Int
(Pending_Strong_Predecessors
(G
, Comp
)));
1463 Indent_By
(Attr_Indent
);
1464 Write_Str
("pending weak components : ");
1465 Write_Num
(Int
(Pending_Weak_Predecessors
(G
, Comp
)));
1469 --------------------
1470 -- Trace_Vertices --
1471 --------------------
1473 procedure Trace_Vertices
1475 Set
: LGV_Sets
.Membership_Set
;
1477 Vertex_Msg
: String;
1478 Step
: Elaboration_Order_Step
;
1479 Indent
: Indentation_Level
)
1481 Vertex_Indent
: constant Indentation_Level
:=
1482 Indent
+ Nested_Indentation
;
1484 Iter
: LGV_Sets
.Iterator
;
1485 Vertex
: Library_Graph_Vertex_Id
;
1488 pragma Assert
(Present
(G
));
1489 pragma Assert
(LGV_Sets
.Present
(Set
));
1491 -- Nothing to do when switch -d_T (output elaboration order and cycle
1492 -- detection trace information) is not in effect.
1494 if not Debug_Flag_Underscore_TT
then
1500 Write_Str
(Set_Msg
);
1502 Write_Int
(Int
(LGV_Sets
.Size
(Set
)));
1505 Iter
:= LGV_Sets
.Iterate
(Set
);
1506 while LGV_Sets
.Has_Next
(Iter
) loop
1507 LGV_Sets
.Next
(Iter
, Vertex
);
1514 Indent
=> Vertex_Indent
);
1518 ----------------------
1519 -- Update_Successor --
1520 ----------------------
1522 procedure Update_Successor
1524 Edge
: Library_Graph_Edge_Id
;
1525 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
1526 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
1527 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
1528 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
1529 Step
: Elaboration_Order_Step
;
1530 Indent
: Indentation_Level
)
1532 pragma Assert
(Present
(G
));
1533 pragma Assert
(Present
(Edge
));
1534 pragma Assert
(LGV_Sets
.Present
(All_Elaborable_Vertices
));
1535 pragma Assert
(LGV_Sets
.Present
(All_Waiting_Vertices
));
1536 pragma Assert
(LGV_Sets
.Present
(Comp_Elaborable_Vertices
));
1537 pragma Assert
(LGV_Sets
.Present
(Comp_Waiting_Vertices
));
1539 Pred
: constant Library_Graph_Vertex_Id
:= Predecessor
(G
, Edge
);
1540 Succ
: constant Library_Graph_Vertex_Id
:= Successor
(G
, Edge
);
1542 pragma Assert
(Needs_Elaboration
(G
, Pred
));
1543 pragma Assert
(Needs_Elaboration
(G
, Succ
));
1545 In_Different_Components
: constant Boolean :=
1546 not In_Same_Component
1551 Succ_Comp
: constant Component_Id
:= Component
(G
, Succ
);
1552 Vertex_Indent
: constant Indentation_Level
:=
1553 Indent
+ Nested_Indentation
;
1555 Iter
: Component_Vertex_Iterator
;
1556 Vertex
: Library_Graph_Vertex_Id
;
1562 Msg
=> "updating successor",
1566 -- Notify the successor that it has one less predecessor to wait on.
1567 -- This effectively eliminates the edge that links the two.
1569 Decrement_Pending_Predecessors
1574 -- The predecessor and successor reside in different components.
1575 -- Notify the successor component it has one fewer components to
1578 if In_Different_Components
then
1579 Decrement_Pending_Predecessors
1585 -- At this point the successor may become elaborable when its final
1586 -- predecessor or final predecessor component has been elaborated.
1588 if Is_Elaborable_Vertex
(G
, Succ
) then
1590 -- The predecessor and successor reside in different components.
1591 -- The successor must not be added to the candidates of Pred's
1592 -- component because this will mix units from the two components.
1593 -- Instead, the successor is added to the set of all elaborable
1596 if In_Different_Components
then
1597 Insert_Elaborable_Successor
1600 Elaborable_Vertices
=> All_Elaborable_Vertices
,
1601 All_Waiting_Vertices
=> All_Waiting_Vertices
,
1602 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
1603 Msg
=> "add elaborable successor",
1605 Indent
=> Vertex_Indent
);
1607 -- Otherwise the predecessor and successor reside within the same
1608 -- component. Pred's component gains another elaborable vertex.
1611 Insert_Elaborable_Successor
1614 Elaborable_Vertices
=> Comp_Elaborable_Vertices
,
1615 All_Waiting_Vertices
=> All_Waiting_Vertices
,
1616 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
1618 "add elaborable component successor",
1620 Indent
=> Vertex_Indent
);
1624 -- At this point the successor component may become elaborable when
1625 -- its final predecessor component is elaborated. This in turn may
1626 -- allow vertices of the successor component to be elaborated.
1628 if In_Different_Components
1629 and then Is_Elaborable_Component
(G
, Succ_Comp
)
1631 Iter
:= Iterate_Component_Vertices
(G
, Succ_Comp
);
1632 while Has_Next
(Iter
) loop
1633 Next
(Iter
, Vertex
);
1635 if Is_Elaborable_Vertex
(G
, Vertex
) then
1636 Insert_Elaborable_Successor
1639 Elaborable_Vertices
=> All_Elaborable_Vertices
,
1640 All_Waiting_Vertices
=> All_Waiting_Vertices
,
1641 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
1642 Msg
=> "add elaborable vertex",
1644 Indent
=> Vertex_Indent
);
1648 end Update_Successor
;
1650 -----------------------
1651 -- Update_Successors --
1652 -----------------------
1654 procedure Update_Successors
1656 Vertex
: Library_Graph_Vertex_Id
;
1657 All_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
1658 All_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
1659 Comp_Elaborable_Vertices
: LGV_Sets
.Membership_Set
;
1660 Comp_Waiting_Vertices
: LGV_Sets
.Membership_Set
;
1661 Step
: Elaboration_Order_Step
;
1662 Indent
: Indentation_Level
)
1664 Edge
: Library_Graph_Edge_Id
;
1665 Iter
: Edges_To_Successors_Iterator
;
1668 pragma Assert
(Present
(G
));
1669 pragma Assert
(Present
(Vertex
));
1670 pragma Assert
(Needs_Elaboration
(G
, Vertex
));
1671 pragma Assert
(LGV_Sets
.Present
(All_Elaborable_Vertices
));
1672 pragma Assert
(LGV_Sets
.Present
(All_Waiting_Vertices
));
1673 pragma Assert
(LGV_Sets
.Present
(Comp_Elaborable_Vertices
));
1674 pragma Assert
(LGV_Sets
.Present
(Comp_Waiting_Vertices
));
1676 Iter
:= Iterate_Edges_To_Successors
(G
, Vertex
);
1677 while Has_Next
(Iter
) loop
1679 pragma Assert
(Predecessor
(G
, Edge
) = Vertex
);
1684 All_Elaborable_Vertices
=> All_Elaborable_Vertices
,
1685 All_Waiting_Vertices
=> All_Waiting_Vertices
,
1686 Comp_Elaborable_Vertices
=> Comp_Elaborable_Vertices
,
1687 Comp_Waiting_Vertices
=> Comp_Waiting_Vertices
,
1691 end Update_Successors
;
1692 end Invocation_And_Library_Graph_Elaborators
;
1694 end Bindo
.Elaborators
;