1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- B I N D O . G R A P H S --
9 -- Copyright (C) 2019, 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 Ada.Unchecked_Deallocation;
28 with Butil; use Butil;
29 with Debug; use Debug;
30 with Output; use Output;
35 package body Bindo.Graphs is
37 -----------------------
38 -- Local subprograms --
39 -----------------------
41 function Sequence_Next_Cycle return Library_Graph_Cycle_Id;
42 pragma Inline (Sequence_Next_Cycle);
43 -- Generate a new unique library graph cycle handle
45 function Sequence_Next_Edge return Invocation_Graph_Edge_Id;
46 pragma Inline (Sequence_Next_Edge);
47 -- Generate a new unique invocation graph edge handle
49 function Sequence_Next_Edge return Library_Graph_Edge_Id;
50 pragma Inline (Sequence_Next_Edge);
51 -- Generate a new unique library graph edge handle
53 function Sequence_Next_Vertex return Invocation_Graph_Vertex_Id;
54 pragma Inline (Sequence_Next_Vertex);
55 -- Generate a new unique invocation graph vertex handle
57 function Sequence_Next_Vertex return Library_Graph_Vertex_Id;
58 pragma Inline (Sequence_Next_Vertex);
59 -- Generate a new unique library graph vertex handle
61 -----------------------------------
62 -- Destroy_Invocation_Graph_Edge --
63 -----------------------------------
65 procedure Destroy_Invocation_Graph_Edge
66 (Edge : in out Invocation_Graph_Edge_Id)
68 pragma Unreferenced (Edge);
71 end Destroy_Invocation_Graph_Edge;
73 ---------------------------------
74 -- Destroy_Library_Graph_Cycle --
75 ---------------------------------
77 procedure Destroy_Library_Graph_Cycle
78 (Cycle : in out Library_Graph_Cycle_Id)
80 pragma Unreferenced (Cycle);
83 end Destroy_Library_Graph_Cycle;
85 --------------------------------
86 -- Destroy_Library_Graph_Edge --
87 --------------------------------
89 procedure Destroy_Library_Graph_Edge
90 (Edge : in out Library_Graph_Edge_Id)
92 pragma Unreferenced (Edge);
95 end Destroy_Library_Graph_Edge;
97 --------------------------------
98 -- Hash_Invocation_Graph_Edge --
99 --------------------------------
101 function Hash_Invocation_Graph_Edge
102 (Edge : Invocation_Graph_Edge_Id) return Bucket_Range_Type
105 pragma Assert (Present (Edge));
107 return Bucket_Range_Type (Edge);
108 end Hash_Invocation_Graph_Edge;
110 ----------------------------------
111 -- Hash_Invocation_Graph_Vertex --
112 ----------------------------------
114 function Hash_Invocation_Graph_Vertex
115 (Vertex : Invocation_Graph_Vertex_Id) return Bucket_Range_Type
118 pragma Assert (Present (Vertex));
120 return Bucket_Range_Type (Vertex);
121 end Hash_Invocation_Graph_Vertex;
123 ------------------------------
124 -- Hash_Library_Graph_Cycle --
125 ------------------------------
127 function Hash_Library_Graph_Cycle
128 (Cycle : Library_Graph_Cycle_Id) return Bucket_Range_Type
131 pragma Assert (Present (Cycle));
133 return Bucket_Range_Type (Cycle);
134 end Hash_Library_Graph_Cycle;
136 -----------------------------
137 -- Hash_Library_Graph_Edge --
138 -----------------------------
140 function Hash_Library_Graph_Edge
141 (Edge : Library_Graph_Edge_Id) return Bucket_Range_Type
144 pragma Assert (Present (Edge));
146 return Bucket_Range_Type (Edge);
147 end Hash_Library_Graph_Edge;
149 -------------------------------
150 -- Hash_Library_Graph_Vertex --
151 -------------------------------
153 function Hash_Library_Graph_Vertex
154 (Vertex : Library_Graph_Vertex_Id) return Bucket_Range_Type
157 pragma Assert (Present (Vertex));
159 return Bucket_Range_Type (Vertex);
160 end Hash_Library_Graph_Vertex;
162 -----------------------
163 -- Invocation_Graphs --
164 -----------------------
166 package body Invocation_Graphs is
168 -----------------------
169 -- Local subprograms --
170 -----------------------
173 new Ada.Unchecked_Deallocation
174 (Invocation_Graph_Attributes, Invocation_Graph);
176 function Get_IGE_Attributes
177 (G : Invocation_Graph;
178 Edge : Invocation_Graph_Edge_Id)
179 return Invocation_Graph_Edge_Attributes;
180 pragma Inline (Get_IGE_Attributes);
181 -- Obtain the attributes of edge Edge of invocation graph G
183 function Get_IGV_Attributes
184 (G : Invocation_Graph;
185 Vertex : Invocation_Graph_Vertex_Id)
186 return Invocation_Graph_Vertex_Attributes;
187 pragma Inline (Get_IGV_Attributes);
188 -- Obtain the attributes of vertex Vertex of invocation graph G
190 procedure Increment_Invocation_Graph_Edge_Count
191 (G : Invocation_Graph;
192 Kind : Invocation_Kind);
193 pragma Inline (Increment_Invocation_Graph_Edge_Count);
194 -- Increment the number of edges of king Kind in invocation graph G by
197 function Is_Elaboration_Root
198 (G : Invocation_Graph;
199 Vertex : Invocation_Graph_Vertex_Id) return Boolean;
200 pragma Inline (Is_Elaboration_Root);
201 -- Determine whether vertex Vertex of invocation graph denotes the
202 -- elaboration procedure of a spec or a body.
204 function Is_Existing_Source_Target_Relation
205 (G : Invocation_Graph;
206 Rel : Source_Target_Relation) return Boolean;
207 pragma Inline (Is_Existing_Source_Target_Relation);
208 -- Determine whether a source vertex and a target vertex described by
209 -- relation Rel are already related in invocation graph G.
211 procedure Save_Elaboration_Root
212 (G : Invocation_Graph;
213 Root : Invocation_Graph_Vertex_Id);
214 pragma Inline (Save_Elaboration_Root);
215 -- Save elaboration root Root of invocation graph G
217 procedure Set_Corresponding_Vertex
218 (G : Invocation_Graph;
219 IS_Id : Invocation_Signature_Id;
220 Vertex : Invocation_Graph_Vertex_Id);
221 pragma Inline (Set_Corresponding_Vertex);
222 -- Associate vertex Vertex of invocation graph G with signature IS_Id
224 procedure Set_Is_Existing_Source_Target_Relation
225 (G : Invocation_Graph;
226 Rel : Source_Target_Relation;
227 Val : Boolean := True);
228 pragma Inline (Set_Is_Existing_Source_Target_Relation);
229 -- Mark a source vertex and a target vertex described by relation Rel as
230 -- already related in invocation graph G depending on value Val.
232 procedure Set_IGE_Attributes
233 (G : Invocation_Graph;
234 Edge : Invocation_Graph_Edge_Id;
235 Val : Invocation_Graph_Edge_Attributes);
236 pragma Inline (Set_IGE_Attributes);
237 -- Set the attributes of edge Edge of invocation graph G to value Val
239 procedure Set_IGV_Attributes
240 (G : Invocation_Graph;
241 Vertex : Invocation_Graph_Vertex_Id;
242 Val : Invocation_Graph_Vertex_Attributes);
243 pragma Inline (Set_IGV_Attributes);
244 -- Set the attributes of vertex Vertex of invocation graph G to value
252 (G : Invocation_Graph;
253 Source : Invocation_Graph_Vertex_Id;
254 Target : Invocation_Graph_Vertex_Id;
255 IR_Id : Invocation_Relation_Id)
257 pragma Assert (Present (G));
258 pragma Assert (Present (Source));
259 pragma Assert (Present (Target));
260 pragma Assert (Present (IR_Id));
262 Rel : constant Source_Target_Relation :=
266 Edge : Invocation_Graph_Edge_Id;
269 -- Nothing to do when the source and target are already related by an
272 if Is_Existing_Source_Target_Relation (G, Rel) then
276 Edge := Sequence_Next_Edge;
278 -- Add the edge to the underlying graph
284 Destination => Target);
286 -- Build and save the attributes of the edge
291 Val => (Relation => IR_Id));
293 -- Mark the source and target as related by the new edge. This
294 -- prevents all further attempts to link the same source and target.
296 Set_Is_Existing_Source_Target_Relation (G, Rel);
298 -- Update the edge statistics
300 Increment_Invocation_Graph_Edge_Count (G, Kind (IR_Id));
308 (G : Invocation_Graph;
309 IC_Id : Invocation_Construct_Id;
310 Body_Vertex : Library_Graph_Vertex_Id;
311 Spec_Vertex : Library_Graph_Vertex_Id)
313 pragma Assert (Present (G));
314 pragma Assert (Present (IC_Id));
315 pragma Assert (Present (Body_Vertex));
316 pragma Assert (Present (Spec_Vertex));
318 Construct_Signature : constant Invocation_Signature_Id :=
320 Vertex : Invocation_Graph_Vertex_Id;
323 -- Nothing to do when the construct already has a vertex
325 if Present (Corresponding_Vertex (G, Construct_Signature)) then
329 Vertex := Sequence_Next_Vertex;
331 -- Add the vertex to the underlying graph
333 DG.Add_Vertex (G.Graph, Vertex);
335 -- Build and save the attributes of the vertex
340 Val => (Body_Vertex => Body_Vertex,
342 Spec_Vertex => Spec_Vertex));
344 -- Associate the construct with its corresponding vertex
346 Set_Corresponding_Vertex (G, Construct_Signature, Vertex);
348 -- Save the vertex for later processing when it denotes a spec or
349 -- body elaboration procedure.
351 if Is_Elaboration_Root (G, Vertex) then
352 Save_Elaboration_Root (G, Vertex);
361 (G : Invocation_Graph;
362 Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
365 pragma Assert (Present (G));
366 pragma Assert (Present (Vertex));
368 return Get_IGV_Attributes (G, Vertex).Body_Vertex;
376 (G : Invocation_Graph;
377 Vertex : Invocation_Graph_Vertex_Id) return Nat
380 pragma Assert (Present (G));
381 pragma Assert (Present (Vertex));
383 return Column (Signature (Construct (G, Vertex)));
391 (G : Invocation_Graph;
392 Vertex : Invocation_Graph_Vertex_Id) return Invocation_Construct_Id
395 pragma Assert (Present (G));
396 pragma Assert (Present (Vertex));
398 return Get_IGV_Attributes (G, Vertex).Construct;
401 --------------------------
402 -- Corresponding_Vertex --
403 --------------------------
405 function Corresponding_Vertex
406 (G : Invocation_Graph;
407 IS_Id : Invocation_Signature_Id) return Invocation_Graph_Vertex_Id
410 pragma Assert (Present (G));
411 pragma Assert (Present (IS_Id));
413 return Signature_Tables.Get (G.Signature_To_Vertex, IS_Id);
414 end Corresponding_Vertex;
421 (Initial_Vertices : Positive;
422 Initial_Edges : Positive) return Invocation_Graph
424 G : constant Invocation_Graph := new Invocation_Graph_Attributes;
427 G.Edge_Attributes := IGE_Tables.Create (Initial_Edges);
430 (Initial_Vertices => Initial_Vertices,
431 Initial_Edges => Initial_Edges);
432 G.Relations := Relation_Sets.Create (Initial_Edges);
433 G.Roots := IGV_Sets.Create (Initial_Vertices);
434 G.Signature_To_Vertex := Signature_Tables.Create (Initial_Vertices);
435 G.Vertex_Attributes := IGV_Tables.Create (Initial_Vertices);
444 procedure Destroy (G : in out Invocation_Graph) is
446 pragma Assert (Present (G));
448 IGE_Tables.Destroy (G.Edge_Attributes);
449 DG.Destroy (G.Graph);
450 Relation_Sets.Destroy (G.Relations);
451 IGV_Sets.Destroy (G.Roots);
452 Signature_Tables.Destroy (G.Signature_To_Vertex);
453 IGV_Tables.Destroy (G.Vertex_Attributes);
458 -----------------------------------
459 -- Destroy_Invocation_Graph_Edge --
460 -----------------------------------
462 procedure Destroy_Invocation_Graph_Edge
463 (Edge : in out Invocation_Graph_Edge_Id)
465 pragma Unreferenced (Edge);
468 end Destroy_Invocation_Graph_Edge;
470 ----------------------------------------------
471 -- Destroy_Invocation_Graph_Edge_Attributes --
472 ----------------------------------------------
474 procedure Destroy_Invocation_Graph_Edge_Attributes
475 (Attrs : in out Invocation_Graph_Edge_Attributes)
477 pragma Unreferenced (Attrs);
480 end Destroy_Invocation_Graph_Edge_Attributes;
482 -------------------------------------
483 -- Destroy_Invocation_Graph_Vertex --
484 -------------------------------------
486 procedure Destroy_Invocation_Graph_Vertex
487 (Vertex : in out Invocation_Graph_Vertex_Id)
489 pragma Unreferenced (Vertex);
492 end Destroy_Invocation_Graph_Vertex;
494 ------------------------------------------------
495 -- Destroy_Invocation_Graph_Vertex_Attributes --
496 ------------------------------------------------
498 procedure Destroy_Invocation_Graph_Vertex_Attributes
499 (Attrs : in out Invocation_Graph_Vertex_Attributes)
501 pragma Unreferenced (Attrs);
504 end Destroy_Invocation_Graph_Vertex_Attributes;
511 (G : Invocation_Graph;
512 Edge : Invocation_Graph_Edge_Id) return Name_Id
515 pragma Assert (Present (G));
516 pragma Assert (Present (Edge));
518 return Extra (Relation (G, Edge));
521 ------------------------
522 -- Get_IGE_Attributes --
523 ------------------------
525 function Get_IGE_Attributes
526 (G : Invocation_Graph;
527 Edge : Invocation_Graph_Edge_Id)
528 return Invocation_Graph_Edge_Attributes
531 pragma Assert (Present (G));
532 pragma Assert (Present (Edge));
534 return IGE_Tables.Get (G.Edge_Attributes, Edge);
535 end Get_IGE_Attributes;
537 ------------------------
538 -- Get_IGV_Attributes --
539 ------------------------
541 function Get_IGV_Attributes
542 (G : Invocation_Graph;
543 Vertex : Invocation_Graph_Vertex_Id)
544 return Invocation_Graph_Vertex_Attributes
547 pragma Assert (Present (G));
548 pragma Assert (Present (Vertex));
550 return IGV_Tables.Get (G.Vertex_Attributes, Vertex);
551 end Get_IGV_Attributes;
557 function Has_Next (Iter : All_Edge_Iterator) return Boolean is
559 return DG.Has_Next (DG.All_Edge_Iterator (Iter));
566 function Has_Next (Iter : All_Vertex_Iterator) return Boolean is
568 return DG.Has_Next (DG.All_Vertex_Iterator (Iter));
575 function Has_Next (Iter : Edges_To_Targets_Iterator) return Boolean is
577 return DG.Has_Next (DG.Outgoing_Edge_Iterator (Iter));
584 function Has_Next (Iter : Elaboration_Root_Iterator) return Boolean is
586 return IGV_Sets.Has_Next (IGV_Sets.Iterator (Iter));
589 -------------------------------
590 -- Hash_Invocation_Signature --
591 -------------------------------
593 function Hash_Invocation_Signature
594 (IS_Id : Invocation_Signature_Id) return Bucket_Range_Type
597 pragma Assert (Present (IS_Id));
599 return Bucket_Range_Type (IS_Id);
600 end Hash_Invocation_Signature;
602 ---------------------------------
603 -- Hash_Source_Target_Relation --
604 ---------------------------------
606 function Hash_Source_Target_Relation
607 (Rel : Source_Target_Relation) return Bucket_Range_Type
610 pragma Assert (Present (Rel.Source));
611 pragma Assert (Present (Rel.Target));
615 (Bucket_Range_Type (Rel.Source),
616 Bucket_Range_Type (Rel.Target));
617 end Hash_Source_Target_Relation;
619 -------------------------------------------
620 -- Increment_Invocation_Graph_Edge_Count --
621 -------------------------------------------
623 procedure Increment_Invocation_Graph_Edge_Count
624 (G : Invocation_Graph;
625 Kind : Invocation_Kind)
627 pragma Assert (Present (G));
629 Count : Natural renames G.Counts (Kind);
633 end Increment_Invocation_Graph_Edge_Count;
635 ---------------------------------
636 -- Invocation_Graph_Edge_Count --
637 ---------------------------------
639 function Invocation_Graph_Edge_Count
640 (G : Invocation_Graph;
641 Kind : Invocation_Kind) return Natural
644 pragma Assert (Present (G));
646 return G.Counts (Kind);
647 end Invocation_Graph_Edge_Count;
649 -------------------------
650 -- Is_Elaboration_Root --
651 -------------------------
653 function Is_Elaboration_Root
654 (G : Invocation_Graph;
655 Vertex : Invocation_Graph_Vertex_Id) return Boolean
657 pragma Assert (Present (G));
658 pragma Assert (Present (Vertex));
660 Vertex_Kind : constant Invocation_Construct_Kind :=
661 Kind (Construct (G, Vertex));
665 Vertex_Kind = Elaborate_Body_Procedure
667 Vertex_Kind = Elaborate_Spec_Procedure;
668 end Is_Elaboration_Root;
670 ----------------------------------------
671 -- Is_Existing_Source_Target_Relation --
672 ----------------------------------------
674 function Is_Existing_Source_Target_Relation
675 (G : Invocation_Graph;
676 Rel : Source_Target_Relation) return Boolean
679 pragma Assert (Present (G));
681 return Relation_Sets.Contains (G.Relations, Rel);
682 end Is_Existing_Source_Target_Relation;
684 -----------------------
685 -- Iterate_All_Edges --
686 -----------------------
688 function Iterate_All_Edges
689 (G : Invocation_Graph) return All_Edge_Iterator
692 pragma Assert (Present (G));
694 return All_Edge_Iterator (DG.Iterate_All_Edges (G.Graph));
695 end Iterate_All_Edges;
697 --------------------------
698 -- Iterate_All_Vertices --
699 --------------------------
701 function Iterate_All_Vertices
702 (G : Invocation_Graph) return All_Vertex_Iterator
705 pragma Assert (Present (G));
707 return All_Vertex_Iterator (DG.Iterate_All_Vertices (G.Graph));
708 end Iterate_All_Vertices;
710 ------------------------------
711 -- Iterate_Edges_To_Targets --
712 ------------------------------
714 function Iterate_Edges_To_Targets
715 (G : Invocation_Graph;
716 Vertex : Invocation_Graph_Vertex_Id) return Edges_To_Targets_Iterator
719 pragma Assert (Present (G));
720 pragma Assert (Present (Vertex));
723 Edges_To_Targets_Iterator
724 (DG.Iterate_Outgoing_Edges (G.Graph, Vertex));
725 end Iterate_Edges_To_Targets;
727 -------------------------------
728 -- Iterate_Elaboration_Roots --
729 -------------------------------
731 function Iterate_Elaboration_Roots
732 (G : Invocation_Graph) return Elaboration_Root_Iterator
735 pragma Assert (Present (G));
737 return Elaboration_Root_Iterator (IGV_Sets.Iterate (G.Roots));
738 end Iterate_Elaboration_Roots;
745 (G : Invocation_Graph;
746 Edge : Invocation_Graph_Edge_Id) return Invocation_Kind
749 pragma Assert (Present (G));
750 pragma Assert (Present (Edge));
752 return Kind (Relation (G, Edge));
760 (G : Invocation_Graph;
761 Vertex : Invocation_Graph_Vertex_Id) return Nat
764 pragma Assert (Present (G));
765 pragma Assert (Present (Vertex));
767 return Line (Signature (Construct (G, Vertex)));
775 (G : Invocation_Graph;
776 Vertex : Invocation_Graph_Vertex_Id) return Name_Id
779 pragma Assert (Present (G));
780 pragma Assert (Present (Vertex));
782 return Name (Signature (Construct (G, Vertex)));
790 (Iter : in out All_Edge_Iterator;
791 Edge : out Invocation_Graph_Edge_Id)
794 DG.Next (DG.All_Edge_Iterator (Iter), Edge);
802 (Iter : in out All_Vertex_Iterator;
803 Vertex : out Invocation_Graph_Vertex_Id)
806 DG.Next (DG.All_Vertex_Iterator (Iter), Vertex);
814 (Iter : in out Edges_To_Targets_Iterator;
815 Edge : out Invocation_Graph_Edge_Id)
818 DG.Next (DG.Outgoing_Edge_Iterator (Iter), Edge);
826 (Iter : in out Elaboration_Root_Iterator;
827 Root : out Invocation_Graph_Vertex_Id)
830 IGV_Sets.Next (IGV_Sets.Iterator (Iter), Root);
833 ---------------------
834 -- Number_Of_Edges --
835 ---------------------
837 function Number_Of_Edges (G : Invocation_Graph) return Natural is
839 pragma Assert (Present (G));
841 return DG.Number_Of_Edges (G.Graph);
844 --------------------------------
845 -- Number_Of_Edges_To_Targets --
846 --------------------------------
848 function Number_Of_Edges_To_Targets
849 (G : Invocation_Graph;
850 Vertex : Invocation_Graph_Vertex_Id) return Natural
853 pragma Assert (Present (G));
854 pragma Assert (Present (Vertex));
856 return DG.Number_Of_Outgoing_Edges (G.Graph, Vertex);
857 end Number_Of_Edges_To_Targets;
859 ---------------------------------
860 -- Number_Of_Elaboration_Roots --
861 ---------------------------------
863 function Number_Of_Elaboration_Roots
864 (G : Invocation_Graph) return Natural
867 pragma Assert (Present (G));
869 return IGV_Sets.Size (G.Roots);
870 end Number_Of_Elaboration_Roots;
872 ------------------------
873 -- Number_Of_Vertices --
874 ------------------------
876 function Number_Of_Vertices (G : Invocation_Graph) return Natural is
878 pragma Assert (Present (G));
880 return DG.Number_Of_Vertices (G.Graph);
881 end Number_Of_Vertices;
887 function Present (G : Invocation_Graph) return Boolean is
897 (G : Invocation_Graph;
898 Edge : Invocation_Graph_Edge_Id) return Invocation_Relation_Id
901 pragma Assert (Present (G));
902 pragma Assert (Present (Edge));
904 return Get_IGE_Attributes (G, Edge).Relation;
907 ---------------------------
908 -- Save_Elaboration_Root --
909 ---------------------------
911 procedure Save_Elaboration_Root
912 (G : Invocation_Graph;
913 Root : Invocation_Graph_Vertex_Id)
916 pragma Assert (Present (G));
917 pragma Assert (Present (Root));
919 IGV_Sets.Insert (G.Roots, Root);
920 end Save_Elaboration_Root;
922 ------------------------------
923 -- Set_Corresponding_Vertex --
924 ------------------------------
926 procedure Set_Corresponding_Vertex
927 (G : Invocation_Graph;
928 IS_Id : Invocation_Signature_Id;
929 Vertex : Invocation_Graph_Vertex_Id)
932 pragma Assert (Present (G));
933 pragma Assert (Present (IS_Id));
934 pragma Assert (Present (Vertex));
936 Signature_Tables.Put (G.Signature_To_Vertex, IS_Id, Vertex);
937 end Set_Corresponding_Vertex;
939 --------------------------------------------
940 -- Set_Is_Existing_Source_Target_Relation --
941 --------------------------------------------
943 procedure Set_Is_Existing_Source_Target_Relation
944 (G : Invocation_Graph;
945 Rel : Source_Target_Relation;
946 Val : Boolean := True)
949 pragma Assert (Present (G));
950 pragma Assert (Present (Rel.Source));
951 pragma Assert (Present (Rel.Target));
954 Relation_Sets.Insert (G.Relations, Rel);
956 Relation_Sets.Delete (G.Relations, Rel);
958 end Set_Is_Existing_Source_Target_Relation;
960 ------------------------
961 -- Set_IGE_Attributes --
962 ------------------------
964 procedure Set_IGE_Attributes
965 (G : Invocation_Graph;
966 Edge : Invocation_Graph_Edge_Id;
967 Val : Invocation_Graph_Edge_Attributes)
970 pragma Assert (Present (G));
971 pragma Assert (Present (Edge));
973 IGE_Tables.Put (G.Edge_Attributes, Edge, Val);
974 end Set_IGE_Attributes;
976 ------------------------
977 -- Set_IGV_Attributes --
978 ------------------------
980 procedure Set_IGV_Attributes
981 (G : Invocation_Graph;
982 Vertex : Invocation_Graph_Vertex_Id;
983 Val : Invocation_Graph_Vertex_Attributes)
986 pragma Assert (Present (G));
987 pragma Assert (Present (Vertex));
989 IGV_Tables.Put (G.Vertex_Attributes, Vertex, Val);
990 end Set_IGV_Attributes;
997 (G : Invocation_Graph;
998 Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
1001 pragma Assert (Present (G));
1002 pragma Assert (Present (Vertex));
1004 return Get_IGV_Attributes (G, Vertex).Spec_Vertex;
1012 (G : Invocation_Graph;
1013 Edge : Invocation_Graph_Edge_Id) return Invocation_Graph_Vertex_Id
1016 pragma Assert (Present (G));
1017 pragma Assert (Present (Edge));
1019 return DG.Destination_Vertex (G.Graph, Edge);
1021 end Invocation_Graphs;
1023 --------------------
1024 -- Library_Graphs --
1025 --------------------
1027 package body Library_Graphs is
1029 -----------------------
1030 -- Local subprograms --
1031 -----------------------
1033 procedure Add_Body_Before_Spec_Edge
1035 Vertex : Library_Graph_Vertex_Id;
1036 Edges : LGE_Lists.Doubly_Linked_List);
1037 pragma Inline (Add_Body_Before_Spec_Edge);
1038 -- Create a new edge in library graph G between vertex Vertex and its
1039 -- corresponding spec or body, where the body is a predecessor and the
1040 -- spec a successor. Add the edge to list Edges.
1042 procedure Add_Body_Before_Spec_Edges
1044 Edges : LGE_Lists.Doubly_Linked_List);
1045 pragma Inline (Add_Body_Before_Spec_Edges);
1046 -- Create new edges in library graph G for all vertices and their
1047 -- corresponding specs or bodies, where the body is a predecessor
1048 -- and the spec is a successor. Add all edges to list Edges.
1052 Attrs : Library_Graph_Cycle_Attributes;
1053 Indent : Indentation_Level);
1054 pragma Inline (Add_Cycle);
1055 -- Store a cycle described by attributes Attrs in library graph G,
1056 -- unless a prior rotation of it already exists. The edges of the cycle
1057 -- must be in normalized form. Indent is the desired indentation level
1060 function Add_Edge_With_Return
1062 Pred : Library_Graph_Vertex_Id;
1063 Succ : Library_Graph_Vertex_Id;
1064 Kind : Library_Graph_Edge_Kind) return Library_Graph_Edge_Id;
1065 pragma Inline (Add_Edge_With_Return);
1066 -- Create a new edge in library graph G with source vertex Pred and
1067 -- destination vertex Succ, and return its handle. Kind denotes the
1068 -- nature of the edge. If Pred and Succ are already related, no edge
1069 -- is created and No_Library_Graph_Edge is returned.
1071 procedure Add_Vertex_And_Complement
1073 Vertex : Library_Graph_Vertex_Id;
1074 Set : LGV_Sets.Membership_Set;
1075 Do_Complement : Boolean);
1076 pragma Inline (Add_Vertex_And_Complement);
1077 -- Add vertex Vertex of library graph G to set Set. If the vertex is
1078 -- part of an Elaborate_Body pair, or flag Do_Complement is set, add
1079 -- the complementary vertex to the set.
1081 function Copy_Cycle_Path
1082 (Cycle_Path : LGE_Lists.Doubly_Linked_List)
1083 return LGE_Lists.Doubly_Linked_List;
1084 pragma Inline (Copy_Cycle_Path);
1085 -- Create a deep copy of list Cycle_Path
1087 function Cycle_Kind_Of
1089 Edge : Library_Graph_Edge_Id) return Library_Graph_Cycle_Kind;
1090 pragma Inline (Cycle_Kind_Of);
1091 -- Determine the cycle kind of edge Edge of library graph G if the edge
1092 -- participated in a circuit.
1094 procedure Decrement_Library_Graph_Edge_Count
1096 Kind : Library_Graph_Edge_Kind);
1097 pragma Inline (Decrement_Library_Graph_Edge_Count);
1098 -- Decrement the number of edges of kind King in library graph G by one
1100 procedure Delete_Body_Before_Spec_Edges
1102 Edges : LGE_Lists.Doubly_Linked_List);
1103 pragma Inline (Delete_Body_Before_Spec_Edges);
1104 -- Delete all edges in list Edges from library graph G, that link spec
1105 -- and bodies, where the body acts as the predecessor and the spec as a
1108 procedure Delete_Edge
1110 Edge : Library_Graph_Edge_Id);
1111 pragma Inline (Delete_Edge);
1112 -- Delete edge Edge from library graph G
1114 procedure Find_All_Cycles_Through_Vertex
1116 Vertex : Library_Graph_Vertex_Id;
1117 End_Vertices : LGV_Sets.Membership_Set;
1118 Most_Significant_Edge : Library_Graph_Edge_Id;
1119 Invocation_Edge_Count : Natural;
1120 Spec_And_Body_Together : Boolean;
1121 Cycle_Path : LGE_Lists.Doubly_Linked_List;
1122 Visited_Vertices : LGV_Sets.Membership_Set;
1123 Indent : Indentation_Level);
1124 pragma Inline (Find_All_Cycles_Through_Vertex);
1125 -- Explore all edges to successors of vertex Vertex of library graph G
1126 -- in an attempt to find a cycle. A cycle is considered closed when the
1127 -- Vertex appears in set End_Vertices. Most_Significant_Edge denotes the
1128 -- edge with the highest significance along the candidate cycle path.
1129 -- Invocation_Edge_Count denotes the number of invocation edges along
1130 -- the candidate cycle path. Spec_And_Body_Together should be set when
1131 -- spec and body vertices must be treated as one vertex. Cycle_Path is
1132 -- the candidate cycle path. Visited_Vertices denotes the set of visited
1133 -- vertices so far. Indent is the desired indentation level for tracing.
1135 procedure Find_All_Cycles_With_Edge
1137 Initial_Edge : Library_Graph_Edge_Id;
1138 Spec_And_Body_Together : Boolean;
1139 Cycle_Path : LGE_Lists.Doubly_Linked_List;
1140 Visited_Vertices : LGV_Sets.Membership_Set;
1141 Indent : Indentation_Level);
1142 pragma Inline (Find_All_Cycles_With_Edge);
1143 -- Find all cycles which contain edge Initial_Edge of library graph G.
1144 -- Spec_And_Body_Together should be set when spec and body vertices must
1145 -- be treated as one vertex. Cycle_Path is the candidate cycle path.
1146 -- Visited_Vertices is the set of visited vertices so far. Indent is
1147 -- the desired indentation level for tracing.
1149 function Find_First_Lower_Precedence_Cycle
1151 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Id;
1152 pragma Inline (Find_First_Lower_Precedence_Cycle);
1153 -- Inspect the list of cycles of library graph G and return the first
1154 -- cycle whose precedence is lower than that of cycle Cycle. If there
1155 -- is no such cycle, return No_Library_Graph_Cycle.
1158 new Ada.Unchecked_Deallocation
1159 (Library_Graph_Attributes, Library_Graph);
1161 function Get_Component_Attributes
1163 Comp : Component_Id) return Component_Attributes;
1164 pragma Inline (Get_Component_Attributes);
1165 -- Obtain the attributes of component Comp of library graph G
1167 function Get_LGC_Attributes
1169 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Attributes;
1170 pragma Inline (Get_LGC_Attributes);
1171 -- Obtain the attributes of cycle Cycle of library graph G
1173 function Get_LGE_Attributes
1175 Edge : Library_Graph_Edge_Id)
1176 return Library_Graph_Edge_Attributes;
1177 pragma Inline (Get_LGE_Attributes);
1178 -- Obtain the attributes of edge Edge of library graph G
1180 function Get_LGV_Attributes
1182 Vertex : Library_Graph_Vertex_Id)
1183 return Library_Graph_Vertex_Attributes;
1184 pragma Inline (Get_LGV_Attributes);
1185 -- Obtain the attributes of vertex Edge of library graph G
1187 function Has_Elaborate_Body
1189 Vertex : Library_Graph_Vertex_Id) return Boolean;
1190 pragma Inline (Has_Elaborate_Body);
1191 -- Determine whether vertex Vertex of library graph G is subject to
1192 -- pragma Elaborate_Body.
1194 function Highest_Precedence_Edge
1196 Left : Library_Graph_Edge_Id;
1197 Right : Library_Graph_Edge_Id) return Library_Graph_Edge_Id;
1198 pragma Inline (Highest_Precedence_Edge);
1199 -- Return the edge with highest precedence among edges Left and Right of
1202 procedure Increment_Library_Graph_Edge_Count
1204 Kind : Library_Graph_Edge_Kind);
1205 pragma Inline (Increment_Library_Graph_Edge_Count);
1206 -- Increment the number of edges of king Kind in library graph G by one
1208 procedure Increment_Pending_Predecessors
1210 Comp : Component_Id;
1211 Edge : Library_Graph_Edge_Id);
1212 pragma Inline (Increment_Pending_Predecessors);
1213 -- Increment the number of pending predecessors component Comp which was
1214 -- reached via edge Edge of library graph G must wait on before it can
1215 -- be elaborated by one.
1217 procedure Increment_Pending_Predecessors
1219 Vertex : Library_Graph_Vertex_Id;
1220 Edge : Library_Graph_Edge_Id);
1221 pragma Inline (Increment_Pending_Predecessors);
1222 -- Increment the number of pending predecessors vertex Vertex which was
1223 -- reached via edge Edge of library graph G must wait on before it can
1224 -- be elaborated by one.
1226 procedure Initialize_Components (G : Library_Graph);
1227 pragma Inline (Initialize_Components);
1228 -- Initialize on the initial call or re-initialize on subsequent calls
1229 -- all components of library graph G.
1231 procedure Insert_And_Sort
1233 Cycle : Library_Graph_Cycle_Id);
1234 pragma Inline (Insert_And_Sort);
1235 -- Insert cycle Cycle in library graph G and sort it based on its
1236 -- precedence relative to all recorded cycles.
1238 function Is_Cycle_Initiating_Edge
1240 Edge : Library_Graph_Edge_Id) return Boolean;
1241 pragma Inline (Is_Cycle_Initiating_Edge);
1242 -- Determine whether edge Edge of library graph G starts a cycle
1244 function Is_Cyclic_Edge
1246 Edge : Library_Graph_Edge_Id) return Boolean;
1247 pragma Inline (Is_Cyclic_Edge);
1248 -- Determine whether edge Edge of library graph G participates in a
1251 function Is_Cyclic_Elaborate_All_Edge
1253 Edge : Library_Graph_Edge_Id) return Boolean;
1254 pragma Inline (Is_Cyclic_Elaborate_All_Edge);
1255 -- Determine whether edge Edge of library graph G participates in a
1256 -- cycle and has a predecessor that is subject to pragma Elaborate_All.
1258 function Is_Cyclic_Elaborate_Body_Edge
1260 Edge : Library_Graph_Edge_Id) return Boolean;
1261 pragma Inline (Is_Cyclic_Elaborate_Body_Edge);
1262 -- Determine whether edge Edge of library graph G participates in a
1263 -- cycle and has a successor that is either a spec subject to pragma
1264 -- Elaborate_Body, or a body that completes such a spec.
1266 function Is_Cyclic_Elaborate_Edge
1268 Edge : Library_Graph_Edge_Id) return Boolean;
1269 pragma Inline (Is_Cyclic_Elaborate_Edge);
1270 -- Determine whether edge Edge of library graph G participates in a
1271 -- cycle and has a predecessor that is subject to pragma Elaborate.
1273 function Is_Cyclic_Forced_Edge
1275 Edge : Library_Graph_Edge_Id) return Boolean;
1276 pragma Inline (Is_Cyclic_Forced_Edge);
1277 -- Determine whether edge Edge of library graph G participates in a
1278 -- cycle and came from the forced-elaboration-order file.
1280 function Is_Cyclic_Invocation_Edge
1282 Edge : Library_Graph_Edge_Id) return Boolean;
1283 pragma Inline (Is_Cyclic_Invocation_Edge);
1284 -- Determine whether edge Edge of library graph G participates in a
1285 -- cycle and came from the traversal of the invocation graph.
1287 function Is_Cyclic_With_Edge
1289 Edge : Library_Graph_Edge_Id) return Boolean;
1290 pragma Inline (Is_Cyclic_With_Edge);
1291 -- Determine whether edge Edge of library graph G participates in a
1292 -- cycle and is the result of a with dependency between its successor
1295 function Is_Recorded_Cycle
1297 Attrs : Library_Graph_Cycle_Attributes) return Boolean;
1298 pragma Inline (Is_Recorded_Cycle);
1299 -- Determine whether a cycle described by its attributes Attrs has
1300 -- has already been recorded in library graph G.
1302 function Is_Recorded_Edge
1304 Rel : Predecessor_Successor_Relation) return Boolean;
1305 pragma Inline (Is_Recorded_Edge);
1306 -- Determine whether a predecessor vertex and a successor vertex
1307 -- described by relation Rel are already linked in library graph G.
1309 function Links_Vertices_In_Same_Component
1311 Edge : Library_Graph_Edge_Id) return Boolean;
1312 pragma Inline (Links_Vertices_In_Same_Component);
1313 -- Determine whether edge Edge of library graph G links a predecessor
1314 -- and successor that reside in the same component.
1316 function Maximum_Invocation_Edge_Count
1318 Edge : Library_Graph_Edge_Id;
1319 Count : Natural) return Natural;
1320 pragma Inline (Maximum_Invocation_Edge_Count);
1321 -- Determine whether edge Edge of library graph G is an invocation edge,
1322 -- and if it is return Count + 1, otherwise return Count.
1324 procedure Normalize_And_Add_Cycle
1326 Most_Significant_Edge : Library_Graph_Edge_Id;
1327 Invocation_Edge_Count : Natural;
1328 Cycle_Path : LGE_Lists.Doubly_Linked_List;
1329 Indent : Indentation_Level);
1330 pragma Inline (Normalize_And_Add_Cycle);
1331 -- Normalize a cycle described by its path Cycle_Path and add it to
1332 -- library graph G. Most_Significant_Edge denotes the edge with the
1333 -- highest significance along the cycle path. Invocation_Edge_Count
1334 -- denotes the number of invocation edges along the cycle path. Indent
1335 -- is the desired indentation level for tracing.
1337 procedure Normalize_Cycle_Path
1338 (Cycle_Path : LGE_Lists.Doubly_Linked_List;
1339 Most_Significant_Edge : Library_Graph_Edge_Id);
1340 pragma Inline (Normalize_Cycle_Path);
1341 -- Normalize cycle path Path by rotating it until its starting edge is
1346 Cycle : Library_Graph_Cycle_Id) return LGE_Lists.Doubly_Linked_List;
1347 pragma Inline (Path);
1348 -- Obtain the path of edges which comprises cycle Cycle of library
1353 Cycle : Library_Graph_Cycle_Id;
1354 Compared_To : Library_Graph_Cycle_Id) return Precedence_Kind;
1355 pragma Inline (Precedence);
1356 -- Determine the precedence of cycle Cycle of library graph G compared
1357 -- to cycle Compared_To.
1360 (Kind : Library_Graph_Cycle_Kind;
1361 Compared_To : Library_Graph_Cycle_Kind) return Precedence_Kind;
1362 pragma Inline (Precedence);
1363 -- Determine the precedence of cycle kind Kind compared to cycle kind
1368 Edge : Library_Graph_Edge_Id;
1369 Compared_To : Library_Graph_Edge_Id) return Precedence_Kind;
1370 pragma Inline (Precedence);
1371 -- Determine the precedence of edge Edge of library graph G compared to
1372 -- edge Compared_To.
1376 Vertex : Library_Graph_Vertex_Id;
1377 Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind;
1378 pragma Inline (Precedence);
1379 -- Determine the precedence of vertex Vertex of library graph G compared
1380 -- to vertex Compared_To.
1382 procedure Remove_Vertex_And_Complement
1384 Vertex : Library_Graph_Vertex_Id;
1385 Set : LGV_Sets.Membership_Set;
1386 Do_Complement : Boolean);
1387 pragma Inline (Remove_Vertex_And_Complement);
1388 -- Remove vertex Vertex of library graph G from set Set. If the vertex
1389 -- is part of an Elaborate_Body pair, or Do_Complement is set, remove
1390 -- the complementary vertex from the set.
1392 procedure Set_Component_Attributes
1394 Comp : Component_Id;
1395 Val : Component_Attributes);
1396 pragma Inline (Set_Component_Attributes);
1397 -- Set the attributes of component Comp of library graph G to value Val
1399 procedure Set_Corresponding_Vertex
1402 Val : Library_Graph_Vertex_Id);
1403 pragma Inline (Set_Corresponding_Vertex);
1404 -- Associate vertex Val of library graph G with unit U_Id
1406 procedure Set_Is_Recorded_Cycle
1408 Attrs : Library_Graph_Cycle_Attributes;
1409 Val : Boolean := True);
1410 pragma Inline (Set_Is_Recorded_Cycle);
1411 -- Mark a cycle described by its attributes Attrs as recorded in library
1412 -- graph G depending on value Val.
1414 procedure Set_Is_Recorded_Edge
1416 Rel : Predecessor_Successor_Relation;
1417 Val : Boolean := True);
1418 pragma Inline (Set_Is_Recorded_Edge);
1419 -- Mark a predecessor vertex and a successor vertex described by
1420 -- relation Rel as already linked depending on value Val.
1422 procedure Set_LGC_Attributes
1424 Cycle : Library_Graph_Cycle_Id;
1425 Val : Library_Graph_Cycle_Attributes);
1426 pragma Inline (Set_LGC_Attributes);
1427 -- Set the attributes of cycle Cycle of library graph G to value Val
1429 procedure Set_LGE_Attributes
1431 Edge : Library_Graph_Edge_Id;
1432 Val : Library_Graph_Edge_Attributes);
1433 pragma Inline (Set_LGE_Attributes);
1434 -- Set the attributes of edge Edge of library graph G to value Val
1436 procedure Set_LGV_Attributes
1438 Vertex : Library_Graph_Vertex_Id;
1439 Val : Library_Graph_Vertex_Attributes);
1440 pragma Inline (Set_LGV_Attributes);
1441 -- Set the attributes of vertex Vertex of library graph G to value Val
1443 procedure Trace_Cycle
1445 Cycle : Library_Graph_Cycle_Id;
1446 Indent : Indentation_Level);
1447 pragma Inline (Trace_Cycle);
1448 -- Write the contents of cycle Cycle of library graph G to standard
1449 -- output. Indent is the desired indentation level for tracing.
1451 procedure Trace_Edge
1453 Edge : Library_Graph_Edge_Id;
1454 Indent : Indentation_Level);
1455 pragma Inline (Trace_Edge);
1456 -- Write the contents of edge Edge of library graph G to standard
1457 -- output. Indent is the desired indentation level for tracing.
1459 procedure Trace_Eol;
1460 pragma Inline (Trace_Eol);
1461 -- Write an end-of-line to standard output
1463 procedure Trace_Vertex
1465 Vertex : Library_Graph_Vertex_Id;
1466 Indent : Indentation_Level);
1467 pragma Inline (Trace_Vertex);
1468 -- Write the contents of vertex Vertex of library graph G to standard
1469 -- output. Indent is the desired indentation level for tracing.
1471 procedure Update_Pending_Predecessors
1472 (Strong_Predecessors : in out Natural;
1473 Weak_Predecessors : in out Natural;
1474 Update_Weak : Boolean;
1476 pragma Inline (Update_Pending_Predecessors);
1477 -- Update the number of pending strong or weak predecessors denoted by
1478 -- Strong_Predecessors and Weak_Predecessors respectively depending on
1479 -- flag Update_Weak by adding value Value.
1481 procedure Update_Pending_Predecessors_Of_Components (G : Library_Graph);
1482 pragma Inline (Update_Pending_Predecessors_Of_Components);
1483 -- Update the number of pending predecessors all components of library
1484 -- graph G must wait on before they can be elaborated.
1486 procedure Update_Pending_Predecessors_Of_Components
1488 Edge : Library_Graph_Edge_Id);
1489 pragma Inline (Update_Pending_Predecessors_Of_Components);
1490 -- Update the number of pending predecessors the component of edge
1491 -- LGE_Is's successor vertex of library graph G must wait on before
1492 -- it can be elaborated.
1494 -------------------------------
1495 -- Add_Body_Before_Spec_Edge --
1496 -------------------------------
1498 procedure Add_Body_Before_Spec_Edge
1500 Vertex : Library_Graph_Vertex_Id;
1501 Edges : LGE_Lists.Doubly_Linked_List)
1503 Edge : Library_Graph_Edge_Id;
1506 pragma Assert (Present (G));
1507 pragma Assert (Present (Vertex));
1508 pragma Assert (LGE_Lists.Present (Edges));
1510 -- A vertex requires a special Body_Before_Spec edge to its
1511 -- Corresponding_Item when it either denotes a
1513 -- * Body that completes a previous spec
1515 -- * Spec with a completing body
1517 -- The edge creates an intentional circularity between the spec and
1518 -- body in order to emulate a library unit, and guarantees that both
1519 -- will appear in the same component.
1521 -- Due to the structure of the library graph, either the spec or
1522 -- the body may be visited first, yet Corresponding_Item will still
1523 -- attempt to create the Body_Before_Spec edge. This is OK because
1524 -- successor and predecessor are kept consistent in both cases, and
1525 -- Add_Edge_With_Return will prevent the creation of the second edge.
1527 -- Assume that that no Body_Before_Spec is necessary
1529 Edge := No_Library_Graph_Edge;
1531 -- A body that completes a previous spec
1533 if Is_Body_With_Spec (G, Vertex) then
1535 Add_Edge_With_Return
1537 Pred => Vertex, -- body
1538 Succ => Corresponding_Item (G, Vertex), -- spec
1539 Kind => Body_Before_Spec_Edge);
1541 -- A spec with a completing body
1543 elsif Is_Spec_With_Body (G, Vertex) then
1545 Add_Edge_With_Return
1547 Pred => Corresponding_Item (G, Vertex), -- body
1548 Succ => Vertex, -- spec
1549 Kind => Body_Before_Spec_Edge);
1552 if Present (Edge) then
1553 LGE_Lists.Append (Edges, Edge);
1555 end Add_Body_Before_Spec_Edge;
1557 --------------------------------
1558 -- Add_Body_Before_Spec_Edges --
1559 --------------------------------
1561 procedure Add_Body_Before_Spec_Edges
1563 Edges : LGE_Lists.Doubly_Linked_List)
1565 Iter : Elaborable_Units_Iterator;
1569 pragma Assert (Present (G));
1570 pragma Assert (LGE_Lists.Present (Edges));
1572 Iter := Iterate_Elaborable_Units;
1573 while Has_Next (Iter) loop
1576 Add_Body_Before_Spec_Edge
1578 Vertex => Corresponding_Vertex (G, U_Id),
1581 end Add_Body_Before_Spec_Edges;
1589 Attrs : Library_Graph_Cycle_Attributes;
1590 Indent : Indentation_Level)
1592 Cycle : Library_Graph_Cycle_Id;
1595 pragma Assert (Present (G));
1597 -- Nothing to do when the cycle has already been recorded, possibly
1598 -- in a rotated form.
1600 if Is_Recorded_Cycle (G, Attrs) then
1604 -- Mark the cycle as recorded. This prevents further attempts to add
1605 -- rotations of the same cycle.
1607 Set_Is_Recorded_Cycle (G, Attrs);
1609 -- Save the attributes of the cycle
1611 Cycle := Sequence_Next_Cycle;
1612 Set_LGC_Attributes (G, Cycle, Attrs);
1614 Trace_Cycle (G, Cycle, Indent);
1616 -- Insert the cycle in the list of all cycle based on its precedence
1618 Insert_And_Sort (G, Cycle);
1627 Pred : Library_Graph_Vertex_Id;
1628 Succ : Library_Graph_Vertex_Id;
1629 Kind : Library_Graph_Edge_Kind)
1631 Edge : Library_Graph_Edge_Id;
1632 pragma Unreferenced (Edge);
1635 pragma Assert (Present (G));
1636 pragma Assert (Present (Pred));
1637 pragma Assert (Present (Succ));
1638 pragma Assert (Kind /= No_Edge);
1641 Add_Edge_With_Return
1648 --------------------------
1649 -- Add_Edge_With_Return --
1650 --------------------------
1652 function Add_Edge_With_Return
1654 Pred : Library_Graph_Vertex_Id;
1655 Succ : Library_Graph_Vertex_Id;
1656 Kind : Library_Graph_Edge_Kind) return Library_Graph_Edge_Id
1658 pragma Assert (Present (G));
1659 pragma Assert (Present (Pred));
1660 pragma Assert (Present (Succ));
1661 pragma Assert (Kind /= No_Edge);
1663 Rel : constant Predecessor_Successor_Relation :=
1664 (Predecessor => Pred,
1667 Edge : Library_Graph_Edge_Id;
1670 -- Nothing to do when the predecessor and successor are already
1671 -- related by an edge.
1673 if Is_Recorded_Edge (G, Rel) then
1674 return No_Library_Graph_Edge;
1677 Edge := Sequence_Next_Edge;
1679 -- Add the edge to the underlying graph. Note that the predecessor
1680 -- is the source of the edge because it will later need to notify
1681 -- all its successors that it has been elaborated.
1687 Destination => Succ);
1689 -- Construct and save the attributes of the edge
1694 Val => (Kind => Kind));
1696 -- Mark the predecessor and successor as related by the new edge.
1697 -- This prevents all further attempts to link the same predecessor
1700 Set_Is_Recorded_Edge (G, Rel);
1702 -- Update the number of pending predecessors the successor must wait
1703 -- on before it is elaborated.
1705 Increment_Pending_Predecessors
1710 -- Update the edge statistics
1712 Increment_Library_Graph_Edge_Count (G, Kind);
1715 end Add_Edge_With_Return;
1721 procedure Add_Vertex
1725 Vertex : Library_Graph_Vertex_Id;
1728 pragma Assert (Present (G));
1729 pragma Assert (Present (U_Id));
1731 -- Nothing to do when the unit already has a vertex
1733 if Present (Corresponding_Vertex (G, U_Id)) then
1737 Vertex := Sequence_Next_Vertex;
1739 -- Add the vertex to the underlying graph
1741 DG.Add_Vertex (G.Graph, Vertex);
1743 -- Construct and save the attributes of the vertex
1749 (Corresponding_Item => No_Library_Graph_Vertex,
1750 In_Elaboration_Order => False,
1751 Pending_Strong_Predecessors => 0,
1752 Pending_Weak_Predecessors => 0,
1755 -- Associate the unit with its corresponding vertex
1757 Set_Corresponding_Vertex (G, U_Id, Vertex);
1760 -------------------------------
1761 -- Add_Vertex_And_Complement --
1762 -------------------------------
1764 procedure Add_Vertex_And_Complement
1766 Vertex : Library_Graph_Vertex_Id;
1767 Set : LGV_Sets.Membership_Set;
1768 Do_Complement : Boolean)
1770 pragma Assert (Present (G));
1771 pragma Assert (Present (Vertex));
1772 pragma Assert (LGV_Sets.Present (Set));
1774 Complement : constant Library_Graph_Vertex_Id :=
1775 Complementary_Vertex
1778 Force_Complement => Do_Complement);
1781 LGV_Sets.Insert (Set, Vertex);
1783 if Present (Complement) then
1784 LGV_Sets.Insert (Set, Complement);
1786 end Add_Vertex_And_Complement;
1788 --------------------------
1789 -- Complementary_Vertex --
1790 --------------------------
1792 function Complementary_Vertex
1794 Vertex : Library_Graph_Vertex_Id;
1795 Force_Complement : Boolean) return Library_Graph_Vertex_Id
1797 Complement : Library_Graph_Vertex_Id;
1800 pragma Assert (Present (G));
1801 pragma Assert (Present (Vertex));
1803 -- Assume that there is no complementary vertex
1805 Complement := No_Library_Graph_Vertex;
1807 -- The caller requests the complement explicitly
1809 if Force_Complement then
1810 Complement := Corresponding_Item (G, Vertex);
1812 -- The vertex is a completing body of a spec subject to pragma
1813 -- Elaborate_Body. The complementary vertex is the spec.
1815 elsif Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then
1816 Complement := Proper_Spec (G, Vertex);
1818 -- The vertex is a spec subject to pragma Elaborate_Body. The
1819 -- complementary vertex is the body.
1821 elsif Is_Spec_With_Elaborate_Body (G, Vertex) then
1822 Complement := Proper_Body (G, Vertex);
1826 end Complementary_Vertex;
1834 Vertex : Library_Graph_Vertex_Id) return Component_Id
1837 pragma Assert (Present (G));
1838 pragma Assert (Present (Vertex));
1840 return DG.Component (G.Graph, Vertex);
1843 ------------------------------------
1844 -- Contains_Weak_Static_Successor --
1845 ------------------------------------
1847 function Contains_Weak_Static_Successor
1849 Cycle : Library_Graph_Cycle_Id) return Boolean
1851 Edge : Library_Graph_Edge_Id;
1852 Iter : Edges_Of_Cycle_Iterator;
1856 pragma Assert (Present (G));
1857 pragma Assert (Present (Cycle));
1859 -- Assume that no weak static successor has been seen
1865 -- * The iteration must run to completion in order to unlock the
1866 -- edges of the cycle.
1868 Iter := Iterate_Edges_Of_Cycle (G, Cycle);
1869 while Has_Next (Iter) loop
1873 and then Is_Invocation_Edge (G, Edge)
1874 and then not Is_Dynamically_Elaborated (G, Successor (G, Edge))
1881 end Contains_Weak_Static_Successor;
1883 ---------------------
1884 -- Copy_Cycle_Path --
1885 ---------------------
1887 function Copy_Cycle_Path
1888 (Cycle_Path : LGE_Lists.Doubly_Linked_List)
1889 return LGE_Lists.Doubly_Linked_List
1891 Edge : Library_Graph_Edge_Id;
1892 Iter : LGE_Lists.Iterator;
1893 Path : LGE_Lists.Doubly_Linked_List;
1896 pragma Assert (LGE_Lists.Present (Cycle_Path));
1898 Path := LGE_Lists.Create;
1899 Iter := LGE_Lists.Iterate (Cycle_Path);
1900 while LGE_Lists.Has_Next (Iter) loop
1901 LGE_Lists.Next (Iter, Edge);
1903 LGE_Lists.Append (Path, Edge);
1907 end Copy_Cycle_Path;
1909 ------------------------
1910 -- Corresponding_Item --
1911 ------------------------
1913 function Corresponding_Item
1915 Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
1918 pragma Assert (Present (G));
1919 pragma Assert (Present (Vertex));
1921 return Get_LGV_Attributes (G, Vertex).Corresponding_Item;
1922 end Corresponding_Item;
1924 --------------------------
1925 -- Corresponding_Vertex --
1926 --------------------------
1928 function Corresponding_Vertex
1930 U_Id : Unit_Id) return Library_Graph_Vertex_Id
1933 pragma Assert (Present (G));
1934 pragma Assert (Present (U_Id));
1936 return Unit_Tables.Get (G.Unit_To_Vertex, U_Id);
1937 end Corresponding_Vertex;
1944 (Initial_Vertices : Positive;
1945 Initial_Edges : Positive) return Library_Graph
1947 G : constant Library_Graph := new Library_Graph_Attributes;
1950 G.Component_Attributes := Component_Tables.Create (Initial_Vertices);
1951 G.Cycle_Attributes := LGC_Tables.Create (Initial_Vertices);
1952 G.Cycles := LGC_Lists.Create;
1953 G.Edge_Attributes := LGE_Tables.Create (Initial_Edges);
1956 (Initial_Vertices => Initial_Vertices,
1957 Initial_Edges => Initial_Edges);
1958 G.Recorded_Cycles := RC_Sets.Create (Initial_Vertices);
1959 G.Recorded_Edges := RE_Sets.Create (Initial_Edges);
1960 G.Unit_To_Vertex := Unit_Tables.Create (Initial_Vertices);
1961 G.Vertex_Attributes := LGV_Tables.Create (Initial_Vertices);
1970 function Cycle_Kind_Of
1972 Edge : Library_Graph_Edge_Id) return Library_Graph_Cycle_Kind
1974 pragma Assert (Present (G));
1975 pragma Assert (Present (Edge));
1978 if Is_Cyclic_Elaborate_All_Edge (G, Edge) then
1979 return Elaborate_All_Cycle;
1981 elsif Is_Cyclic_Elaborate_Body_Edge (G, Edge) then
1982 return Elaborate_Body_Cycle;
1984 elsif Is_Cyclic_Elaborate_Edge (G, Edge) then
1985 return Elaborate_Cycle;
1987 elsif Is_Cyclic_Forced_Edge (G, Edge) then
1988 return Forced_Cycle;
1990 elsif Is_Cyclic_Invocation_Edge (G, Edge) then
1991 return Invocation_Cycle;
1994 return No_Cycle_Kind;
1998 ----------------------------------------
1999 -- Decrement_Library_Graph_Edge_Count --
2000 ----------------------------------------
2002 procedure Decrement_Library_Graph_Edge_Count
2004 Kind : Library_Graph_Edge_Kind)
2006 pragma Assert (Present (G));
2008 Count : Natural renames G.Counts (Kind);
2012 end Decrement_Library_Graph_Edge_Count;
2014 ------------------------------------
2015 -- Decrement_Pending_Predecessors --
2016 ------------------------------------
2018 procedure Decrement_Pending_Predecessors
2020 Comp : Component_Id;
2021 Edge : Library_Graph_Edge_Id)
2023 Attrs : Component_Attributes;
2026 pragma Assert (Present (G));
2027 pragma Assert (Present (Comp));
2029 Attrs := Get_Component_Attributes (G, Comp);
2031 Update_Pending_Predecessors
2032 (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
2033 Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
2034 Update_Weak => Is_Invocation_Edge (G, Edge),
2037 Set_Component_Attributes (G, Comp, Attrs);
2038 end Decrement_Pending_Predecessors;
2040 ------------------------------------
2041 -- Decrement_Pending_Predecessors --
2042 ------------------------------------
2044 procedure Decrement_Pending_Predecessors
2046 Vertex : Library_Graph_Vertex_Id;
2047 Edge : Library_Graph_Edge_Id)
2049 Attrs : Library_Graph_Vertex_Attributes;
2052 pragma Assert (Present (G));
2053 pragma Assert (Present (Vertex));
2055 Attrs := Get_LGV_Attributes (G, Vertex);
2057 Update_Pending_Predecessors
2058 (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
2059 Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
2060 Update_Weak => Is_Invocation_Edge (G, Edge),
2063 Set_LGV_Attributes (G, Vertex, Attrs);
2064 end Decrement_Pending_Predecessors;
2066 -----------------------------------
2067 -- Delete_Body_Before_Spec_Edges --
2068 -----------------------------------
2070 procedure Delete_Body_Before_Spec_Edges
2072 Edges : LGE_Lists.Doubly_Linked_List)
2074 Edge : Library_Graph_Edge_Id;
2075 Iter : LGE_Lists.Iterator;
2078 pragma Assert (Present (G));
2079 pragma Assert (LGE_Lists.Present (Edges));
2081 Iter := LGE_Lists.Iterate (Edges);
2082 while LGE_Lists.Has_Next (Iter) loop
2083 LGE_Lists.Next (Iter, Edge);
2084 pragma Assert (Kind (G, Edge) = Body_Before_Spec_Edge);
2086 Delete_Edge (G, Edge);
2088 end Delete_Body_Before_Spec_Edges;
2094 procedure Delete_Edge
2096 Edge : Library_Graph_Edge_Id)
2098 pragma Assert (Present (G));
2099 pragma Assert (Present (Edge));
2101 Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
2102 Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
2103 Rel : constant Predecessor_Successor_Relation :=
2104 (Predecessor => Pred,
2108 -- Update the edge statistics
2110 Decrement_Library_Graph_Edge_Count (G, Kind (G, Edge));
2112 -- Update the number of pending predecessors the successor must wait
2113 -- on before it is elaborated.
2115 Decrement_Pending_Predecessors
2120 -- Delete the link between the predecessor and successor. This allows
2121 -- for further attempts to link the same predecessor and successor.
2123 RE_Sets.Delete (G.Recorded_Edges, Rel);
2125 -- Delete the attributes of the edge
2127 LGE_Tables.Delete (G.Edge_Attributes, Edge);
2129 -- Delete the edge from the underlying graph
2131 DG.Delete_Edge (G.Graph, Edge);
2138 procedure Destroy (G : in out Library_Graph) is
2140 pragma Assert (Present (G));
2142 Component_Tables.Destroy (G.Component_Attributes);
2143 LGC_Tables.Destroy (G.Cycle_Attributes);
2144 LGC_Lists.Destroy (G.Cycles);
2145 LGE_Tables.Destroy (G.Edge_Attributes);
2146 DG.Destroy (G.Graph);
2147 RC_Sets.Destroy (G.Recorded_Cycles);
2148 RE_Sets.Destroy (G.Recorded_Edges);
2149 Unit_Tables.Destroy (G.Unit_To_Vertex);
2150 LGV_Tables.Destroy (G.Vertex_Attributes);
2155 ----------------------------------
2156 -- Destroy_Component_Attributes --
2157 ----------------------------------
2159 procedure Destroy_Component_Attributes
2160 (Attrs : in out Component_Attributes)
2162 pragma Unreferenced (Attrs);
2165 end Destroy_Component_Attributes;
2167 --------------------------------------------
2168 -- Destroy_Library_Graph_Cycle_Attributes --
2169 --------------------------------------------
2171 procedure Destroy_Library_Graph_Cycle_Attributes
2172 (Attrs : in out Library_Graph_Cycle_Attributes)
2175 LGE_Lists.Destroy (Attrs.Path);
2176 end Destroy_Library_Graph_Cycle_Attributes;
2178 -------------------------------------------
2179 -- Destroy_Library_Graph_Edge_Attributes --
2180 -------------------------------------------
2182 procedure Destroy_Library_Graph_Edge_Attributes
2183 (Attrs : in out Library_Graph_Edge_Attributes)
2185 pragma Unreferenced (Attrs);
2188 end Destroy_Library_Graph_Edge_Attributes;
2190 ----------------------------------
2191 -- Destroy_Library_Graph_Vertex --
2192 ----------------------------------
2194 procedure Destroy_Library_Graph_Vertex
2195 (Vertex : in out Library_Graph_Vertex_Id)
2197 pragma Unreferenced (Vertex);
2200 end Destroy_Library_Graph_Vertex;
2202 ---------------------------------------------
2203 -- Destroy_Library_Graph_Vertex_Attributes --
2204 ---------------------------------------------
2206 procedure Destroy_Library_Graph_Vertex_Attributes
2207 (Attrs : in out Library_Graph_Vertex_Attributes)
2209 pragma Unreferenced (Attrs);
2212 end Destroy_Library_Graph_Vertex_Attributes;
2220 Vertex : Library_Graph_Vertex_Id) return File_Name_Type
2223 pragma Assert (Present (G));
2224 pragma Assert (Present (Vertex));
2226 return File_Name (Unit (G, Vertex));
2229 ------------------------------------
2230 -- Find_All_Cycles_Through_Vertex --
2231 ------------------------------------
2233 procedure Find_All_Cycles_Through_Vertex
2235 Vertex : Library_Graph_Vertex_Id;
2236 End_Vertices : LGV_Sets.Membership_Set;
2237 Most_Significant_Edge : Library_Graph_Edge_Id;
2238 Invocation_Edge_Count : Natural;
2239 Spec_And_Body_Together : Boolean;
2240 Cycle_Path : LGE_Lists.Doubly_Linked_List;
2241 Visited_Vertices : LGV_Sets.Membership_Set;
2242 Indent : Indentation_Level)
2244 Edge_Indent : constant Indentation_Level :=
2245 Indent + Nested_Indentation;
2247 Iter : Edges_To_Successors_Iterator;
2248 Next_Edge : Library_Graph_Edge_Id;
2251 pragma Assert (Present (G));
2252 pragma Assert (LGV_Sets.Present (End_Vertices));
2253 pragma Assert (Present (Most_Significant_Edge));
2254 pragma Assert (LGE_Lists.Present (Cycle_Path));
2255 pragma Assert (LGV_Sets.Present (Visited_Vertices));
2257 -- Nothing to do when there is no vertex
2259 if not Present (Vertex) then
2263 Trace_Vertex (G, Vertex, Indent);
2265 -- The current vertex denotes the end vertex of the cycle and closes
2266 -- the circuit. Normalize the cycle such that it is rotated with its
2267 -- most significant edge first, and record it for diagnostics.
2269 if LGV_Sets.Contains (End_Vertices, Vertex) then
2270 Normalize_And_Add_Cycle
2272 Most_Significant_Edge => Most_Significant_Edge,
2273 Invocation_Edge_Count => Invocation_Edge_Count,
2274 Cycle_Path => Cycle_Path,
2275 Indent => Indent + Nested_Indentation);
2277 -- Otherwise extend the search for a cycle only when the vertex has
2278 -- not been visited yet.
2280 elsif not LGV_Sets.Contains (Visited_Vertices, Vertex) then
2282 -- Prepare for vertex backtracking
2284 LGV_Sets.Insert (Visited_Vertices, Vertex);
2286 -- Extend the search via all edges to successors of the vertex
2288 Iter := Iterate_Edges_To_Successors (G, Vertex);
2289 while Has_Next (Iter) loop
2290 Next (Iter, Next_Edge);
2292 if Is_Cyclic_Edge (G, Next_Edge) then
2293 Trace_Edge (G, Next_Edge, Edge_Indent);
2295 -- Prepare for edge backtracking. Prepending ensures that
2296 -- final ordering of edges can be traversed from successor
2299 LGE_Lists.Prepend (Cycle_Path, Next_Edge);
2301 -- Extend the search via the successor of the next edge
2303 Find_All_Cycles_Through_Vertex
2305 Vertex => Successor (G, Next_Edge),
2306 End_Vertices => End_Vertices,
2308 -- The next edge may be more important than the current
2309 -- most important edge, thus "upgrading" the nature of
2310 -- the cycle, and shifting its point of normalization.
2312 Most_Significant_Edge =>
2313 Highest_Precedence_Edge
2316 Right => Most_Significant_Edge),
2318 -- The next edge may be an invocation edge, in which case
2319 -- the count of invocation edges increases by one.
2321 Invocation_Edge_Count =>
2322 Maximum_Invocation_Edge_Count
2325 Count => Invocation_Edge_Count),
2326 Spec_And_Body_Together => Spec_And_Body_Together,
2327 Cycle_Path => Cycle_Path,
2328 Visited_Vertices => Visited_Vertices,
2331 -- Backtrack the edge
2333 LGE_Lists.Delete_First (Cycle_Path);
2337 -- Extend the search via the complementary vertex when the current
2338 -- vertex is part of an Elaborate_Body pair, or the initial edge
2339 -- is an Elaborate_All edge.
2341 Find_All_Cycles_Through_Vertex
2344 Complementary_Vertex
2347 Force_Complement => Spec_And_Body_Together),
2348 End_Vertices => End_Vertices,
2349 Most_Significant_Edge => Most_Significant_Edge,
2350 Invocation_Edge_Count => Invocation_Edge_Count,
2351 Spec_And_Body_Together => Spec_And_Body_Together,
2352 Cycle_Path => Cycle_Path,
2353 Visited_Vertices => Visited_Vertices,
2356 -- Backtrack the vertex
2358 LGV_Sets.Delete (Visited_Vertices, Vertex);
2360 end Find_All_Cycles_Through_Vertex;
2362 -------------------------------
2363 -- Find_All_Cycles_With_Edge --
2364 -------------------------------
2366 procedure Find_All_Cycles_With_Edge
2368 Initial_Edge : Library_Graph_Edge_Id;
2369 Spec_And_Body_Together : Boolean;
2370 Cycle_Path : LGE_Lists.Doubly_Linked_List;
2371 Visited_Vertices : LGV_Sets.Membership_Set;
2372 Indent : Indentation_Level)
2374 pragma Assert (Present (G));
2375 pragma Assert (Present (Initial_Edge));
2376 pragma Assert (LGE_Lists.Present (Cycle_Path));
2377 pragma Assert (LGV_Sets.Present (Visited_Vertices));
2379 Pred : constant Library_Graph_Vertex_Id :=
2380 Predecessor (G, Initial_Edge);
2381 Succ : constant Library_Graph_Vertex_Id :=
2382 Successor (G, Initial_Edge);
2384 End_Vertices : LGV_Sets.Membership_Set;
2387 Trace_Edge (G, Initial_Edge, Indent);
2389 -- Use a set to represent the end vertices of the cycle. The set is
2390 -- needed to accommodate the Elaborate_All and Elaborate_Body cases
2391 -- where a cycle may terminate on either a spec or a body vertex.
2393 End_Vertices := LGV_Sets.Create (2);
2394 Add_Vertex_And_Complement
2397 Set => End_Vertices,
2398 Do_Complement => Spec_And_Body_Together);
2400 -- Prepare for edge backtracking
2402 -- The initial edge starts the path. During the traversal, edges with
2403 -- higher precedence may be discovered, in which case they supersede
2404 -- the initial edge in terms of significance. Prepending to the cycle
2405 -- path ensures that the vertices can be visited in the proper order
2408 LGE_Lists.Prepend (Cycle_Path, Initial_Edge);
2410 -- Prepare for vertex backtracking
2412 -- The predecessor is considered the terminator of the path. Add it
2413 -- to the set of visited vertices along with its complement vertex
2414 -- in the Elaborate_All and Elaborate_Body cases to prevent infinite
2417 Add_Vertex_And_Complement
2420 Set => Visited_Vertices,
2421 Do_Complement => Spec_And_Body_Together);
2423 -- Traverse a potential cycle by continuously visiting successors
2424 -- until either the predecessor of the initial edge is reached, or
2425 -- no more successors are available.
2427 Find_All_Cycles_Through_Vertex
2430 End_Vertices => End_Vertices,
2431 Most_Significant_Edge => Initial_Edge,
2432 Invocation_Edge_Count =>
2433 Maximum_Invocation_Edge_Count
2435 Edge => Initial_Edge,
2437 Spec_And_Body_Together => Spec_And_Body_Together,
2438 Cycle_Path => Cycle_Path,
2439 Visited_Vertices => Visited_Vertices,
2440 Indent => Indent + Nested_Indentation);
2442 -- Backtrack the edge
2444 LGE_Lists.Delete_First (Cycle_Path);
2446 -- Backtrack the predecessor, along with the complement vertex in the
2447 -- Elaborate_All and Elaborate_Body cases.
2449 Remove_Vertex_And_Complement
2452 Set => Visited_Vertices,
2453 Do_Complement => Spec_And_Body_Together);
2455 LGV_Sets.Destroy (End_Vertices);
2456 end Find_All_Cycles_With_Edge;
2458 ---------------------
2459 -- Find_Components --
2460 ---------------------
2462 procedure Find_Components (G : Library_Graph) is
2463 Edges : LGE_Lists.Doubly_Linked_List;
2466 pragma Assert (Present (G));
2468 -- Initialize or reinitialize the components of the graph
2470 Initialize_Components (G);
2472 -- Create a set of special edges that link a predecessor body with a
2473 -- successor spec. This is an illegal dependency, however using such
2474 -- edges eliminates the need to create yet another graph, where both
2475 -- spec and body are collapsed into a single vertex.
2477 Edges := LGE_Lists.Create;
2478 Add_Body_Before_Spec_Edges (G, Edges);
2480 DG.Find_Components (G.Graph);
2482 -- Remove the special edges that link a predecessor body with a
2483 -- successor spec because they cause unresolvable circularities.
2485 Delete_Body_Before_Spec_Edges (G, Edges);
2486 LGE_Lists.Destroy (Edges);
2488 -- Update the number of predecessors various components must wait on
2489 -- before they can be elaborated.
2491 Update_Pending_Predecessors_Of_Components (G);
2492 end Find_Components;
2498 procedure Find_Cycles (G : Library_Graph) is
2499 Cycle_Path : LGE_Lists.Doubly_Linked_List;
2500 Edge : Library_Graph_Edge_Id;
2501 Iter : All_Edge_Iterator;
2502 Visited_Vertices : LGV_Sets.Membership_Set;
2505 pragma Assert (Present (G));
2507 -- Use a list of edges to describe the path of a cycle
2509 Cycle_Path := LGE_Lists.Create;
2511 -- Use a set of visited vertices to prevent infinite traversal of the
2514 Visited_Vertices := LGV_Sets.Create (Number_Of_Vertices (G));
2516 -- Inspect all edges, trying to find an edge that links two vertices
2517 -- in the same component.
2519 Iter := Iterate_All_Edges (G);
2520 while Has_Next (Iter) loop
2523 -- Find all cycles involving the current edge. Duplicate cycles in
2524 -- the forms of rotations are not saved for diagnostic purposes.
2526 if Is_Cycle_Initiating_Edge (G, Edge) then
2527 Find_All_Cycles_With_Edge
2529 Initial_Edge => Edge,
2530 Spec_And_Body_Together => Is_Elaborate_All_Edge (G, Edge),
2531 Cycle_Path => Cycle_Path,
2532 Visited_Vertices => Visited_Vertices,
2533 Indent => No_Indentation);
2539 LGE_Lists.Destroy (Cycle_Path);
2540 LGV_Sets.Destroy (Visited_Vertices);
2543 ---------------------------------------
2544 -- Find_First_Lower_Precedence_Cycle --
2545 ---------------------------------------
2547 function Find_First_Lower_Precedence_Cycle
2549 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Id
2551 Current_Cycle : Library_Graph_Cycle_Id;
2552 Iter : All_Cycle_Iterator;
2553 Lesser_Cycle : Library_Graph_Cycle_Id;
2556 pragma Assert (Present (G));
2557 pragma Assert (Present (Cycle));
2559 -- Assume that there is no lesser cycle
2561 Lesser_Cycle := No_Library_Graph_Cycle;
2563 -- Find a cycle with a slightly lower precedence than the input
2568 -- * The iterator must run to completion in order to unlock the
2569 -- list of all cycles.
2571 Iter := Iterate_All_Cycles (G);
2572 while Has_Next (Iter) loop
2573 Next (Iter, Current_Cycle);
2575 if not Present (Lesser_Cycle)
2579 Compared_To => Current_Cycle) = Higher_Precedence
2581 Lesser_Cycle := Current_Cycle;
2585 return Lesser_Cycle;
2586 end Find_First_Lower_Precedence_Cycle;
2588 ------------------------------
2589 -- Get_Component_Attributes --
2590 ------------------------------
2592 function Get_Component_Attributes
2594 Comp : Component_Id) return Component_Attributes
2597 pragma Assert (Present (G));
2598 pragma Assert (Present (Comp));
2600 return Component_Tables.Get (G.Component_Attributes, Comp);
2601 end Get_Component_Attributes;
2603 ------------------------
2604 -- Get_LGC_Attributes --
2605 ------------------------
2607 function Get_LGC_Attributes
2609 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Attributes
2612 pragma Assert (Present (G));
2613 pragma Assert (Present (Cycle));
2615 return LGC_Tables.Get (G.Cycle_Attributes, Cycle);
2616 end Get_LGC_Attributes;
2618 ------------------------
2619 -- Get_LGE_Attributes --
2620 ------------------------
2622 function Get_LGE_Attributes
2624 Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Attributes
2627 pragma Assert (Present (G));
2628 pragma Assert (Present (Edge));
2630 return LGE_Tables.Get (G.Edge_Attributes, Edge);
2631 end Get_LGE_Attributes;
2633 ------------------------
2634 -- Get_LGV_Attributes --
2635 ------------------------
2637 function Get_LGV_Attributes
2639 Vertex : Library_Graph_Vertex_Id)
2640 return Library_Graph_Vertex_Attributes
2643 pragma Assert (Present (G));
2644 pragma Assert (Present (Vertex));
2646 return LGV_Tables.Get (G.Vertex_Attributes, Vertex);
2647 end Get_LGV_Attributes;
2649 -----------------------------
2650 -- Has_Elaborate_All_Cycle --
2651 -----------------------------
2653 function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean is
2654 Edge : Library_Graph_Edge_Id;
2655 Iter : All_Edge_Iterator;
2659 pragma Assert (Present (G));
2661 -- Assume that no cyclic Elaborate_All edge has been seen
2667 -- * The iteration must run to completion in order to unlock the
2670 Iter := Iterate_All_Edges (G);
2671 while Has_Next (Iter) loop
2674 if not Seen and then Is_Cyclic_Elaborate_All_Edge (G, Edge) then
2680 end Has_Elaborate_All_Cycle;
2682 ------------------------
2683 -- Has_Elaborate_Body --
2684 ------------------------
2686 function Has_Elaborate_Body
2688 Vertex : Library_Graph_Vertex_Id) return Boolean
2690 pragma Assert (Present (G));
2691 pragma Assert (Present (Vertex));
2693 U_Id : constant Unit_Id := Unit (G, Vertex);
2694 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
2697 -- Treat the spec and body as decoupled when switch -d_b (ignore the
2698 -- effects of pragma Elaborate_Body) is in effect.
2700 return U_Rec.Elaborate_Body and not Debug_Flag_Underscore_B;
2701 end Has_Elaborate_Body;
2707 function Has_Next (Iter : All_Cycle_Iterator) return Boolean is
2709 return LGC_Lists.Has_Next (LGC_Lists.Iterator (Iter));
2716 function Has_Next (Iter : All_Edge_Iterator) return Boolean is
2718 return DG.Has_Next (DG.All_Edge_Iterator (Iter));
2725 function Has_Next (Iter : All_Vertex_Iterator) return Boolean is
2727 return DG.Has_Next (DG.All_Vertex_Iterator (Iter));
2734 function Has_Next (Iter : Component_Iterator) return Boolean is
2736 return DG.Has_Next (DG.Component_Iterator (Iter));
2743 function Has_Next (Iter : Component_Vertex_Iterator) return Boolean is
2745 return DG.Has_Next (DG.Component_Vertex_Iterator (Iter));
2752 function Has_Next (Iter : Edges_Of_Cycle_Iterator) return Boolean is
2754 return LGE_Lists.Has_Next (LGE_Lists.Iterator (Iter));
2761 function Has_Next (Iter : Edges_To_Successors_Iterator) return Boolean is
2763 return DG.Has_Next (DG.Outgoing_Edge_Iterator (Iter));
2766 -----------------------------------------
2767 -- Hash_Library_Graph_Cycle_Attributes --
2768 -----------------------------------------
2770 function Hash_Library_Graph_Cycle_Attributes
2771 (Attrs : Library_Graph_Cycle_Attributes) return Bucket_Range_Type
2773 Edge : Library_Graph_Edge_Id;
2774 Hash : Bucket_Range_Type;
2775 Iter : LGE_Lists.Iterator;
2778 pragma Assert (LGE_Lists.Present (Attrs.Path));
2780 -- The hash is obtained in the following manner:
2782 -- (((edge1 * 31) + edge2) * 31) + edgeN
2785 Iter := LGE_Lists.Iterate (Attrs.Path);
2786 while LGE_Lists.Has_Next (Iter) loop
2787 LGE_Lists.Next (Iter, Edge);
2789 Hash := (Hash * 31) + Bucket_Range_Type (Edge);
2793 end Hash_Library_Graph_Cycle_Attributes;
2795 -----------------------------------------
2796 -- Hash_Predecessor_Successor_Relation --
2797 -----------------------------------------
2799 function Hash_Predecessor_Successor_Relation
2800 (Rel : Predecessor_Successor_Relation) return Bucket_Range_Type
2803 pragma Assert (Present (Rel.Predecessor));
2804 pragma Assert (Present (Rel.Successor));
2808 (Bucket_Range_Type (Rel.Predecessor),
2809 Bucket_Range_Type (Rel.Successor));
2810 end Hash_Predecessor_Successor_Relation;
2812 ------------------------------
2813 -- Highest_Precedence_Cycle --
2814 ------------------------------
2816 function Highest_Precedence_Cycle
2817 (G : Library_Graph) return Library_Graph_Cycle_Id
2820 pragma Assert (Present (G));
2821 pragma Assert (LGC_Lists.Present (G.Cycles));
2823 if LGC_Lists.Is_Empty (G.Cycles) then
2824 return No_Library_Graph_Cycle;
2826 -- The highest precedence cycle is always the first in the list of
2830 return LGC_Lists.First (G.Cycles);
2832 end Highest_Precedence_Cycle;
2834 -----------------------------
2835 -- Highest_Precedence_Edge --
2836 -----------------------------
2838 function Highest_Precedence_Edge
2840 Left : Library_Graph_Edge_Id;
2841 Right : Library_Graph_Edge_Id) return Library_Graph_Edge_Id
2843 Edge_Prec : Precedence_Kind;
2846 pragma Assert (Present (G));
2848 -- Both edges are available, pick the one with highest precedence
2850 if Present (Left) and then Present (Right) then
2855 Compared_To => Right);
2857 if Edge_Prec = Higher_Precedence then
2860 -- The precedence rules for edges are such that no two edges can
2861 -- ever have the same precedence.
2864 pragma Assert (Edge_Prec = Lower_Precedence);
2868 -- Otherwise at least one edge must be present
2870 elsif Present (Left) then
2874 pragma Assert (Present (Right));
2878 end Highest_Precedence_Edge;
2880 --------------------------
2881 -- In_Elaboration_Order --
2882 --------------------------
2884 function In_Elaboration_Order
2886 Vertex : Library_Graph_Vertex_Id) return Boolean
2889 pragma Assert (Present (G));
2890 pragma Assert (Present (Vertex));
2892 return Get_LGV_Attributes (G, Vertex).In_Elaboration_Order;
2893 end In_Elaboration_Order;
2895 -----------------------
2896 -- In_Same_Component --
2897 -----------------------
2899 function In_Same_Component
2901 Left : Library_Graph_Vertex_Id;
2902 Right : Library_Graph_Vertex_Id) return Boolean
2905 pragma Assert (Present (G));
2906 pragma Assert (Present (Left));
2907 pragma Assert (Present (Right));
2909 return Component (G, Left) = Component (G, Right);
2910 end In_Same_Component;
2912 ----------------------------------------
2913 -- Increment_Library_Graph_Edge_Count --
2914 ----------------------------------------
2916 procedure Increment_Library_Graph_Edge_Count
2918 Kind : Library_Graph_Edge_Kind)
2920 pragma Assert (Present (G));
2922 Count : Natural renames G.Counts (Kind);
2926 end Increment_Library_Graph_Edge_Count;
2928 ------------------------------------
2929 -- Increment_Pending_Predecessors --
2930 ------------------------------------
2932 procedure Increment_Pending_Predecessors
2934 Comp : Component_Id;
2935 Edge : Library_Graph_Edge_Id)
2937 Attrs : Component_Attributes;
2940 pragma Assert (Present (G));
2941 pragma Assert (Present (Comp));
2943 Attrs := Get_Component_Attributes (G, Comp);
2945 Update_Pending_Predecessors
2946 (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
2947 Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
2948 Update_Weak => Is_Invocation_Edge (G, Edge),
2951 Set_Component_Attributes (G, Comp, Attrs);
2952 end Increment_Pending_Predecessors;
2954 ------------------------------------
2955 -- Increment_Pending_Predecessors --
2956 ------------------------------------
2958 procedure Increment_Pending_Predecessors
2960 Vertex : Library_Graph_Vertex_Id;
2961 Edge : Library_Graph_Edge_Id)
2963 Attrs : Library_Graph_Vertex_Attributes;
2966 pragma Assert (Present (G));
2967 pragma Assert (Present (Vertex));
2969 Attrs := Get_LGV_Attributes (G, Vertex);
2971 Update_Pending_Predecessors
2972 (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
2973 Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
2974 Update_Weak => Is_Invocation_Edge (G, Edge),
2977 Set_LGV_Attributes (G, Vertex, Attrs);
2978 end Increment_Pending_Predecessors;
2980 ---------------------------
2981 -- Initialize_Components --
2982 ---------------------------
2984 procedure Initialize_Components (G : Library_Graph) is
2986 pragma Assert (Present (G));
2988 -- The graph already contains a set of components. Reinitialize
2989 -- them in order to accommodate the new set of components about to
2992 if Number_Of_Components (G) > 0 then
2993 Component_Tables.Destroy (G.Component_Attributes);
2995 G.Component_Attributes :=
2996 Component_Tables.Create (Number_Of_Vertices (G));
2998 end Initialize_Components;
3000 ---------------------
3001 -- Insert_And_Sort --
3002 ---------------------
3004 procedure Insert_And_Sort
3006 Cycle : Library_Graph_Cycle_Id)
3008 Lesser_Cycle : Library_Graph_Cycle_Id;
3011 pragma Assert (Present (G));
3012 pragma Assert (Present (Cycle));
3013 pragma Assert (LGC_Lists.Present (G.Cycles));
3015 -- The input cycle is the first to be inserted
3017 if LGC_Lists.Is_Empty (G.Cycles) then
3018 LGC_Lists.Prepend (G.Cycles, Cycle);
3020 -- Otherwise the list of all cycles contains at least one cycle.
3021 -- Insert the input cycle based on its precedence.
3024 Lesser_Cycle := Find_First_Lower_Precedence_Cycle (G, Cycle);
3026 -- The list contains at least one cycle, and the input cycle has a
3027 -- higher precedence compared to some cycle in the list.
3029 if Present (Lesser_Cycle) then
3030 LGC_Lists.Insert_Before
3032 Before => Lesser_Cycle,
3035 -- Otherwise the input cycle has the lowest precedence among all
3039 LGC_Lists.Append (G.Cycles, Cycle);
3042 end Insert_And_Sort;
3044 ---------------------------
3045 -- Invocation_Edge_Count --
3046 ---------------------------
3048 function Invocation_Edge_Count
3050 Cycle : Library_Graph_Cycle_Id) return Natural
3053 pragma Assert (Present (G));
3054 pragma Assert (Present (Cycle));
3056 return Get_LGC_Attributes (G, Cycle).Invocation_Edge_Count;
3057 end Invocation_Edge_Count;
3059 -------------------------------
3060 -- Invocation_Graph_Encoding --
3061 -------------------------------
3063 function Invocation_Graph_Encoding
3065 Vertex : Library_Graph_Vertex_Id)
3066 return Invocation_Graph_Encoding_Kind
3069 pragma Assert (Present (G));
3070 pragma Assert (Present (Vertex));
3072 return Invocation_Graph_Encoding (Unit (G, Vertex));
3073 end Invocation_Graph_Encoding;
3081 Vertex : Library_Graph_Vertex_Id) return Boolean
3083 pragma Assert (Present (G));
3084 pragma Assert (Present (Vertex));
3086 U_Id : constant Unit_Id := Unit (G, Vertex);
3087 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3090 return U_Rec.Utype = Is_Body or else U_Rec.Utype = Is_Body_Only;
3093 -----------------------------------------
3094 -- Is_Body_Of_Spec_With_Elaborate_Body --
3095 -----------------------------------------
3097 function Is_Body_Of_Spec_With_Elaborate_Body
3099 Vertex : Library_Graph_Vertex_Id) return Boolean
3102 pragma Assert (Present (G));
3103 pragma Assert (Present (Vertex));
3105 if Is_Body_With_Spec (G, Vertex) then
3107 Is_Spec_With_Elaborate_Body
3109 Vertex => Proper_Spec (G, Vertex));
3113 end Is_Body_Of_Spec_With_Elaborate_Body;
3115 -----------------------
3116 -- Is_Body_With_Spec --
3117 -----------------------
3119 function Is_Body_With_Spec
3121 Vertex : Library_Graph_Vertex_Id) return Boolean
3123 pragma Assert (Present (G));
3124 pragma Assert (Present (Vertex));
3126 U_Id : constant Unit_Id := Unit (G, Vertex);
3127 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3130 return U_Rec.Utype = Is_Body;
3131 end Is_Body_With_Spec;
3133 ------------------------------
3134 -- Is_Cycle_Initiating_Edge --
3135 ------------------------------
3137 function Is_Cycle_Initiating_Edge
3139 Edge : Library_Graph_Edge_Id) return Boolean
3142 pragma Assert (Present (G));
3143 pragma Assert (Present (Edge));
3146 Is_Cyclic_Elaborate_All_Edge (G, Edge)
3147 or else Is_Cyclic_Elaborate_Body_Edge (G, Edge)
3148 or else Is_Cyclic_Elaborate_Edge (G, Edge)
3149 or else Is_Cyclic_Forced_Edge (G, Edge)
3150 or else Is_Cyclic_Invocation_Edge (G, Edge);
3151 end Is_Cycle_Initiating_Edge;
3153 --------------------
3154 -- Is_Cyclic_Edge --
3155 --------------------
3157 function Is_Cyclic_Edge
3159 Edge : Library_Graph_Edge_Id) return Boolean
3162 pragma Assert (Present (G));
3163 pragma Assert (Present (Edge));
3166 Is_Cycle_Initiating_Edge (G, Edge)
3167 or else Is_Cyclic_With_Edge (G, Edge);
3170 ----------------------------------
3171 -- Is_Cyclic_Elaborate_All_Edge --
3172 ----------------------------------
3174 function Is_Cyclic_Elaborate_All_Edge
3176 Edge : Library_Graph_Edge_Id) return Boolean
3179 pragma Assert (Present (G));
3180 pragma Assert (Present (Edge));
3183 Is_Elaborate_All_Edge (G, Edge)
3184 and then Links_Vertices_In_Same_Component (G, Edge);
3185 end Is_Cyclic_Elaborate_All_Edge;
3187 -----------------------------------
3188 -- Is_Cyclic_Elaborate_Body_Edge --
3189 -----------------------------------
3191 function Is_Cyclic_Elaborate_Body_Edge
3193 Edge : Library_Graph_Edge_Id) return Boolean
3196 pragma Assert (Present (G));
3197 pragma Assert (Present (Edge));
3200 Is_Elaborate_Body_Edge (G, Edge)
3201 and then Links_Vertices_In_Same_Component (G, Edge);
3202 end Is_Cyclic_Elaborate_Body_Edge;
3204 ------------------------------
3205 -- Is_Cyclic_Elaborate_Edge --
3206 ------------------------------
3208 function Is_Cyclic_Elaborate_Edge
3210 Edge : Library_Graph_Edge_Id) return Boolean
3213 pragma Assert (Present (G));
3214 pragma Assert (Present (Edge));
3217 Is_Elaborate_Edge (G, Edge)
3218 and then Links_Vertices_In_Same_Component (G, Edge);
3219 end Is_Cyclic_Elaborate_Edge;
3221 ---------------------------
3222 -- Is_Cyclic_Forced_Edge --
3223 ---------------------------
3225 function Is_Cyclic_Forced_Edge
3227 Edge : Library_Graph_Edge_Id) return Boolean
3230 pragma Assert (Present (G));
3231 pragma Assert (Present (Edge));
3234 Is_Forced_Edge (G, Edge)
3235 and then Links_Vertices_In_Same_Component (G, Edge);
3236 end Is_Cyclic_Forced_Edge;
3238 -------------------------------
3239 -- Is_Cyclic_Invocation_Edge --
3240 -------------------------------
3242 function Is_Cyclic_Invocation_Edge
3244 Edge : Library_Graph_Edge_Id) return Boolean
3247 pragma Assert (Present (G));
3248 pragma Assert (Present (Edge));
3251 Is_Invocation_Edge (G, Edge)
3252 and then Links_Vertices_In_Same_Component (G, Edge);
3253 end Is_Cyclic_Invocation_Edge;
3255 -------------------------
3256 -- Is_Cyclic_With_Edge --
3257 -------------------------
3259 function Is_Cyclic_With_Edge
3261 Edge : Library_Graph_Edge_Id) return Boolean
3264 pragma Assert (Present (G));
3265 pragma Assert (Present (Edge));
3267 -- Ignore Elaborate_Body edges because they also appear as with
3268 -- edges, but have special successors.
3271 Is_With_Edge (G, Edge)
3272 and then Links_Vertices_In_Same_Component (G, Edge)
3273 and then not Is_Elaborate_Body_Edge (G, Edge);
3274 end Is_Cyclic_With_Edge;
3276 -------------------------------
3277 -- Is_Dynamically_Elaborated --
3278 -------------------------------
3280 function Is_Dynamically_Elaborated
3282 Vertex : Library_Graph_Vertex_Id) return Boolean
3285 pragma Assert (Present (G));
3286 pragma Assert (Present (Vertex));
3288 return Is_Dynamically_Elaborated (Unit (G, Vertex));
3289 end Is_Dynamically_Elaborated;
3291 -----------------------------
3292 -- Is_Elaborable_Component --
3293 -----------------------------
3295 function Is_Elaborable_Component
3297 Comp : Component_Id) return Boolean
3300 pragma Assert (Present (G));
3301 pragma Assert (Present (Comp));
3303 -- A component is elaborable when:
3305 -- * It is not waiting on strong predecessors, and
3306 -- * It is not waiting on weak predecessors
3309 Pending_Strong_Predecessors (G, Comp) = 0
3310 and then Pending_Weak_Predecessors (G, Comp) = 0;
3311 end Is_Elaborable_Component;
3313 --------------------------
3314 -- Is_Elaborable_Vertex --
3315 --------------------------
3317 function Is_Elaborable_Vertex
3319 Vertex : Library_Graph_Vertex_Id) return Boolean
3321 pragma Assert (Present (G));
3322 pragma Assert (Present (Vertex));
3324 Complement : constant Library_Graph_Vertex_Id :=
3325 Complementary_Vertex
3328 Force_Complement => False);
3330 Strong_Preds : Natural;
3331 Weak_Preds : Natural;
3334 -- A vertex is elaborable when:
3336 -- * It has not been elaborated yet, and
3337 -- * The complement vertex of an Elaborate_Body pair has not been
3338 -- elaborated yet, and
3339 -- * It resides within an elaborable component, and
3340 -- * It is not waiting on strong predecessors, and
3341 -- * It is not waiting on weak predecessors
3343 if In_Elaboration_Order (G, Vertex) then
3346 elsif Present (Complement)
3347 and then In_Elaboration_Order (G, Complement)
3351 elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then
3355 Pending_Predecessors_For_Elaboration
3358 Strong_Preds => Strong_Preds,
3359 Weak_Preds => Weak_Preds);
3361 return Strong_Preds = 0 and then Weak_Preds = 0;
3362 end Is_Elaborable_Vertex;
3364 ---------------------------
3365 -- Is_Elaborate_All_Edge --
3366 ---------------------------
3368 function Is_Elaborate_All_Edge
3370 Edge : Library_Graph_Edge_Id) return Boolean
3373 pragma Assert (Present (G));
3374 pragma Assert (Present (Edge));
3376 return Kind (G, Edge) = Elaborate_All_Edge;
3377 end Is_Elaborate_All_Edge;
3379 ----------------------------
3380 -- Is_Elaborate_Body_Edge --
3381 ----------------------------
3383 function Is_Elaborate_Body_Edge
3385 Edge : Library_Graph_Edge_Id) return Boolean
3387 pragma Assert (Present (G));
3388 pragma Assert (Present (Edge));
3390 Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
3394 Kind (G, Edge) = With_Edge
3396 (Is_Spec_With_Elaborate_Body (G, Succ)
3397 or else Is_Body_Of_Spec_With_Elaborate_Body (G, Succ));
3398 end Is_Elaborate_Body_Edge;
3400 -----------------------
3401 -- Is_Elaborate_Edge --
3402 -----------------------
3404 function Is_Elaborate_Edge
3406 Edge : Library_Graph_Edge_Id) return Boolean
3409 pragma Assert (Present (G));
3410 pragma Assert (Present (Edge));
3412 return Kind (G, Edge) = Elaborate_Edge;
3413 end Is_Elaborate_Edge;
3415 ----------------------------
3416 -- Is_Elaborate_Body_Pair --
3417 ----------------------------
3419 function Is_Elaborate_Body_Pair
3421 Spec_Vertex : Library_Graph_Vertex_Id;
3422 Body_Vertex : Library_Graph_Vertex_Id) return Boolean
3425 pragma Assert (Present (G));
3426 pragma Assert (Present (Spec_Vertex));
3427 pragma Assert (Present (Body_Vertex));
3430 Is_Spec_With_Elaborate_Body (G, Spec_Vertex)
3431 and then Is_Body_Of_Spec_With_Elaborate_Body (G, Body_Vertex)
3432 and then Proper_Body (G, Spec_Vertex) = Body_Vertex;
3433 end Is_Elaborate_Body_Pair;
3435 --------------------
3436 -- Is_Forced_Edge --
3437 --------------------
3439 function Is_Forced_Edge
3441 Edge : Library_Graph_Edge_Id) return Boolean
3444 pragma Assert (Present (G));
3445 pragma Assert (Present (Edge));
3447 return Kind (G, Edge) = Forced_Edge;
3450 ----------------------
3451 -- Is_Internal_Unit --
3452 ----------------------
3454 function Is_Internal_Unit
3456 Vertex : Library_Graph_Vertex_Id) return Boolean
3459 pragma Assert (Present (G));
3460 pragma Assert (Present (Vertex));
3462 return Is_Internal_Unit (Unit (G, Vertex));
3463 end Is_Internal_Unit;
3465 ------------------------
3466 -- Is_Invocation_Edge --
3467 ------------------------
3469 function Is_Invocation_Edge
3471 Edge : Library_Graph_Edge_Id) return Boolean
3474 pragma Assert (Present (G));
3475 pragma Assert (Present (Edge));
3477 return Kind (G, Edge) = Invocation_Edge;
3478 end Is_Invocation_Edge;
3480 ------------------------
3481 -- Is_Predefined_Unit --
3482 ------------------------
3484 function Is_Predefined_Unit
3486 Vertex : Library_Graph_Vertex_Id) return Boolean
3489 pragma Assert (Present (G));
3490 pragma Assert (Present (Vertex));
3492 return Is_Predefined_Unit (Unit (G, Vertex));
3493 end Is_Predefined_Unit;
3495 ---------------------------
3496 -- Is_Preelaborated_Unit --
3497 ---------------------------
3499 function Is_Preelaborated_Unit
3501 Vertex : Library_Graph_Vertex_Id) return Boolean
3503 pragma Assert (Present (G));
3504 pragma Assert (Present (Vertex));
3506 U_Id : constant Unit_Id := Unit (G, Vertex);
3507 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3510 return U_Rec.Preelab or else U_Rec.Pure;
3511 end Is_Preelaborated_Unit;
3513 -----------------------
3514 -- Is_Recorded_Cycle --
3515 -----------------------
3517 function Is_Recorded_Cycle
3519 Attrs : Library_Graph_Cycle_Attributes) return Boolean
3522 pragma Assert (Present (G));
3524 return RC_Sets.Contains (G.Recorded_Cycles, Attrs);
3525 end Is_Recorded_Cycle;
3527 ----------------------
3528 -- Is_Recorded_Edge --
3529 ----------------------
3531 function Is_Recorded_Edge
3533 Rel : Predecessor_Successor_Relation) return Boolean
3536 pragma Assert (Present (G));
3537 pragma Assert (Present (Rel.Predecessor));
3538 pragma Assert (Present (Rel.Successor));
3540 return RE_Sets.Contains (G.Recorded_Edges, Rel);
3541 end Is_Recorded_Edge;
3549 Vertex : Library_Graph_Vertex_Id) return Boolean
3551 pragma Assert (Present (G));
3552 pragma Assert (Present (Vertex));
3554 U_Id : constant Unit_Id := Unit (G, Vertex);
3555 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3558 return U_Rec.Utype = Is_Spec or else U_Rec.Utype = Is_Spec_Only;
3561 -----------------------
3562 -- Is_Spec_With_Body --
3563 -----------------------
3565 function Is_Spec_With_Body
3567 Vertex : Library_Graph_Vertex_Id) return Boolean
3569 pragma Assert (Present (G));
3570 pragma Assert (Present (Vertex));
3572 U_Id : constant Unit_Id := Unit (G, Vertex);
3573 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3576 return U_Rec.Utype = Is_Spec;
3577 end Is_Spec_With_Body;
3579 ---------------------------------
3580 -- Is_Spec_With_Elaborate_Body --
3581 ---------------------------------
3583 function Is_Spec_With_Elaborate_Body
3585 Vertex : Library_Graph_Vertex_Id) return Boolean
3588 pragma Assert (Present (G));
3589 pragma Assert (Present (Vertex));
3592 Is_Spec_With_Body (G, Vertex)
3593 and then Has_Elaborate_Body (G, Vertex);
3594 end Is_Spec_With_Elaborate_Body;
3596 ---------------------------------
3597 -- Is_Weakly_Elaborable_Vertex --
3598 ----------------------------------
3600 function Is_Weakly_Elaborable_Vertex
3602 Vertex : Library_Graph_Vertex_Id) return Boolean
3604 pragma Assert (Present (G));
3605 pragma Assert (Present (Vertex));
3607 Complement : constant Library_Graph_Vertex_Id :=
3608 Complementary_Vertex
3611 Force_Complement => False);
3613 Strong_Preds : Natural;
3614 Weak_Preds : Natural;
3617 -- A vertex is weakly elaborable when:
3619 -- * It has not been elaborated yet, and
3620 -- * The complement vertex of an Elaborate_Body pair has not been
3621 -- elaborated yet, and
3622 -- * It resides within an elaborable component, and
3623 -- * It is not waiting on strong predecessors, and
3624 -- * It is waiting on at least one weak predecessor
3626 if In_Elaboration_Order (G, Vertex) then
3629 elsif Present (Complement)
3630 and then In_Elaboration_Order (G, Complement)
3634 elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then
3638 Pending_Predecessors_For_Elaboration
3641 Strong_Preds => Strong_Preds,
3642 Weak_Preds => Weak_Preds);
3644 return Strong_Preds = 0 and then Weak_Preds >= 1;
3645 end Is_Weakly_Elaborable_Vertex;
3651 function Is_With_Edge
3653 Edge : Library_Graph_Edge_Id) return Boolean
3656 pragma Assert (Present (G));
3657 pragma Assert (Present (Edge));
3659 return Kind (G, Edge) = With_Edge;
3662 ------------------------
3663 -- Iterate_All_Cycles --
3664 ------------------------
3666 function Iterate_All_Cycles
3667 (G : Library_Graph) return All_Cycle_Iterator
3670 pragma Assert (Present (G));
3672 return All_Cycle_Iterator (LGC_Lists.Iterate (G.Cycles));
3673 end Iterate_All_Cycles;
3675 -----------------------
3676 -- Iterate_All_Edges --
3677 -----------------------
3679 function Iterate_All_Edges
3680 (G : Library_Graph) return All_Edge_Iterator
3683 pragma Assert (Present (G));
3685 return All_Edge_Iterator (DG.Iterate_All_Edges (G.Graph));
3686 end Iterate_All_Edges;
3688 --------------------------
3689 -- Iterate_All_Vertices --
3690 --------------------------
3692 function Iterate_All_Vertices
3693 (G : Library_Graph) return All_Vertex_Iterator
3696 pragma Assert (Present (G));
3698 return All_Vertex_Iterator (DG.Iterate_All_Vertices (G.Graph));
3699 end Iterate_All_Vertices;
3701 ------------------------
3702 -- Iterate_Components --
3703 ------------------------
3705 function Iterate_Components
3706 (G : Library_Graph) return Component_Iterator
3709 pragma Assert (Present (G));
3711 return Component_Iterator (DG.Iterate_Components (G.Graph));
3712 end Iterate_Components;
3714 --------------------------------
3715 -- Iterate_Component_Vertices --
3716 --------------------------------
3718 function Iterate_Component_Vertices
3720 Comp : Component_Id) return Component_Vertex_Iterator
3723 pragma Assert (Present (G));
3724 pragma Assert (Present (Comp));
3727 Component_Vertex_Iterator
3728 (DG.Iterate_Component_Vertices (G.Graph, Comp));
3729 end Iterate_Component_Vertices;
3731 ----------------------------
3732 -- Iterate_Edges_Of_Cycle --
3733 ----------------------------
3735 function Iterate_Edges_Of_Cycle
3737 Cycle : Library_Graph_Cycle_Id) return Edges_Of_Cycle_Iterator
3740 pragma Assert (Present (G));
3741 pragma Assert (Present (Cycle));
3743 return Edges_Of_Cycle_Iterator (LGE_Lists.Iterate (Path (G, Cycle)));
3744 end Iterate_Edges_Of_Cycle;
3746 ---------------------------------
3747 -- Iterate_Edges_To_Successors --
3748 ---------------------------------
3750 function Iterate_Edges_To_Successors
3752 Vertex : Library_Graph_Vertex_Id) return Edges_To_Successors_Iterator
3755 pragma Assert (Present (G));
3756 pragma Assert (Present (Vertex));
3759 Edges_To_Successors_Iterator
3760 (DG.Iterate_Outgoing_Edges (G.Graph, Vertex));
3761 end Iterate_Edges_To_Successors;
3769 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Kind
3772 pragma Assert (Present (G));
3773 pragma Assert (Present (Cycle));
3775 return Get_LGC_Attributes (G, Cycle).Kind;
3784 Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Kind
3787 pragma Assert (Present (G));
3788 pragma Assert (Present (Edge));
3790 return Get_LGE_Attributes (G, Edge).Kind;
3799 Cycle : Library_Graph_Cycle_Id) return Natural
3802 pragma Assert (Present (G));
3803 pragma Assert (Present (Cycle));
3805 return LGE_Lists.Size (Path (G, Cycle));
3808 ------------------------------
3809 -- Library_Graph_Edge_Count --
3810 ------------------------------
3812 function Library_Graph_Edge_Count
3814 Kind : Library_Graph_Edge_Kind) return Natural
3817 pragma Assert (Present (G));
3819 return G.Counts (Kind);
3820 end Library_Graph_Edge_Count;
3822 --------------------------------------
3823 -- Links_Vertices_In_Same_Component --
3824 --------------------------------------
3826 function Links_Vertices_In_Same_Component
3828 Edge : Library_Graph_Edge_Id) return Boolean
3831 pragma Assert (Present (G));
3832 pragma Assert (Present (Edge));
3834 -- An edge is part of a cycle when both the successor and predecessor
3835 -- reside in the same component.
3840 Left => Predecessor (G, Edge),
3841 Right => Successor (G, Edge));
3842 end Links_Vertices_In_Same_Component;
3844 -----------------------------------
3845 -- Maximum_Invocation_Edge_Count --
3846 -----------------------------------
3848 function Maximum_Invocation_Edge_Count
3850 Edge : Library_Graph_Edge_Id;
3851 Count : Natural) return Natural
3853 New_Count : Natural;
3856 pragma Assert (Present (G));
3860 if Present (Edge) and then Is_Invocation_Edge (G, Edge) then
3861 New_Count := New_Count + 1;
3865 end Maximum_Invocation_Edge_Count;
3873 Vertex : Library_Graph_Vertex_Id) return Unit_Name_Type
3876 pragma Assert (Present (G));
3877 pragma Assert (Present (Vertex));
3879 return Name (Unit (G, Vertex));
3882 -----------------------
3883 -- Needs_Elaboration --
3884 -----------------------
3886 function Needs_Elaboration
3888 Vertex : Library_Graph_Vertex_Id) return Boolean
3891 pragma Assert (Present (G));
3892 pragma Assert (Present (Vertex));
3894 return Needs_Elaboration (Unit (G, Vertex));
3895 end Needs_Elaboration;
3902 (Iter : in out All_Cycle_Iterator;
3903 Cycle : out Library_Graph_Cycle_Id)
3906 LGC_Lists.Next (LGC_Lists.Iterator (Iter), Cycle);
3914 (Iter : in out All_Edge_Iterator;
3915 Edge : out Library_Graph_Edge_Id)
3918 DG.Next (DG.All_Edge_Iterator (Iter), Edge);
3926 (Iter : in out All_Vertex_Iterator;
3927 Vertex : out Library_Graph_Vertex_Id)
3930 DG.Next (DG.All_Vertex_Iterator (Iter), Vertex);
3938 (Iter : in out Edges_Of_Cycle_Iterator;
3939 Edge : out Library_Graph_Edge_Id)
3942 LGE_Lists.Next (LGE_Lists.Iterator (Iter), Edge);
3950 (Iter : in out Component_Iterator;
3951 Comp : out Component_Id)
3954 DG.Next (DG.Component_Iterator (Iter), Comp);
3962 (Iter : in out Edges_To_Successors_Iterator;
3963 Edge : out Library_Graph_Edge_Id)
3966 DG.Next (DG.Outgoing_Edge_Iterator (Iter), Edge);
3974 (Iter : in out Component_Vertex_Iterator;
3975 Vertex : out Library_Graph_Vertex_Id)
3978 DG.Next (DG.Component_Vertex_Iterator (Iter), Vertex);
3981 -----------------------------
3982 -- Normalize_And_Add_Cycle --
3983 -----------------------------
3985 procedure Normalize_And_Add_Cycle
3987 Most_Significant_Edge : Library_Graph_Edge_Id;
3988 Invocation_Edge_Count : Natural;
3989 Cycle_Path : LGE_Lists.Doubly_Linked_List;
3990 Indent : Indentation_Level)
3992 Path : LGE_Lists.Doubly_Linked_List;
3995 pragma Assert (Present (G));
3996 pragma Assert (Present (Most_Significant_Edge));
3997 pragma Assert (LGE_Lists.Present (Cycle_Path));
3999 -- Replicate the path of the cycle in order to avoid sharing lists
4001 Path := Copy_Cycle_Path (Cycle_Path);
4003 -- Normalize the path of the cycle such that its most significant
4004 -- edge is the first in the list of edges.
4006 Normalize_Cycle_Path
4007 (Cycle_Path => Path,
4008 Most_Significant_Edge => Most_Significant_Edge);
4010 -- Save the cycle for diagnostic purposes. Its kind is determined by
4011 -- its most significant edge.
4016 (Invocation_Edge_Count => Invocation_Edge_Count,
4020 Edge => Most_Significant_Edge),
4023 end Normalize_And_Add_Cycle;
4025 --------------------------
4026 -- Normalize_Cycle_Path --
4027 --------------------------
4029 procedure Normalize_Cycle_Path
4030 (Cycle_Path : LGE_Lists.Doubly_Linked_List;
4031 Most_Significant_Edge : Library_Graph_Edge_Id)
4033 Edge : Library_Graph_Edge_Id;
4036 pragma Assert (LGE_Lists.Present (Cycle_Path));
4037 pragma Assert (Present (Most_Significant_Edge));
4039 -- Perform at most |Cycle_Path| rotations in case the cycle is
4040 -- malformed and the significant edge does not appear within.
4042 for Rotation in 1 .. LGE_Lists.Size (Cycle_Path) loop
4043 Edge := LGE_Lists.First (Cycle_Path);
4045 -- The cycle is already rotated such that the most significant
4048 if Edge = Most_Significant_Edge then
4051 -- Otherwise rotate the cycle by relocating the current edge from
4052 -- the start to the end of the path. This preserves the order of
4056 LGE_Lists.Delete_First (Cycle_Path);
4057 LGE_Lists.Append (Cycle_Path, Edge);
4061 pragma Assert (False);
4062 end Normalize_Cycle_Path;
4064 ----------------------------------
4065 -- Number_Of_Component_Vertices --
4066 ----------------------------------
4068 function Number_Of_Component_Vertices
4070 Comp : Component_Id) return Natural
4073 pragma Assert (Present (G));
4074 pragma Assert (Present (Comp));
4076 return DG.Number_Of_Component_Vertices (G.Graph, Comp);
4077 end Number_Of_Component_Vertices;
4079 --------------------------
4080 -- Number_Of_Components --
4081 --------------------------
4083 function Number_Of_Components (G : Library_Graph) return Natural is
4085 pragma Assert (Present (G));
4087 return DG.Number_Of_Components (G.Graph);
4088 end Number_Of_Components;
4090 ----------------------
4091 -- Number_Of_Cycles --
4092 ----------------------
4094 function Number_Of_Cycles (G : Library_Graph) return Natural is
4096 pragma Assert (Present (G));
4098 return LGC_Lists.Size (G.Cycles);
4099 end Number_Of_Cycles;
4101 ---------------------
4102 -- Number_Of_Edges --
4103 ---------------------
4105 function Number_Of_Edges (G : Library_Graph) return Natural is
4107 pragma Assert (Present (G));
4109 return DG.Number_Of_Edges (G.Graph);
4110 end Number_Of_Edges;
4112 -----------------------------------
4113 -- Number_Of_Edges_To_Successors --
4114 -----------------------------------
4116 function Number_Of_Edges_To_Successors
4118 Vertex : Library_Graph_Vertex_Id) return Natural
4121 pragma Assert (Present (G));
4123 return DG.Number_Of_Outgoing_Edges (G.Graph, Vertex);
4124 end Number_Of_Edges_To_Successors;
4126 ------------------------
4127 -- Number_Of_Vertices --
4128 ------------------------
4130 function Number_Of_Vertices (G : Library_Graph) return Natural is
4132 pragma Assert (Present (G));
4134 return DG.Number_Of_Vertices (G.Graph);
4135 end Number_Of_Vertices;
4143 Cycle : Library_Graph_Cycle_Id) return LGE_Lists.Doubly_Linked_List
4146 pragma Assert (Present (G));
4147 pragma Assert (Present (Cycle));
4149 return Get_LGC_Attributes (G, Cycle).Path;
4152 ------------------------------------------
4153 -- Pending_Predecessors_For_Elaboration --
4154 ------------------------------------------
4156 procedure Pending_Predecessors_For_Elaboration
4158 Vertex : Library_Graph_Vertex_Id;
4159 Strong_Preds : out Natural;
4160 Weak_Preds : out Natural)
4162 Complement : Library_Graph_Vertex_Id;
4163 Spec_Vertex : Library_Graph_Vertex_Id;
4164 Total_Strong_Preds : Natural;
4165 Total_Weak_Preds : Natural;
4168 pragma Assert (Present (G));
4169 pragma Assert (Present (Vertex));
4171 Total_Strong_Preds := Pending_Strong_Predecessors (G, Vertex);
4172 Total_Weak_Preds := Pending_Weak_Predecessors (G, Vertex);
4174 -- Assume that there is no complementary vertex that needs to be
4177 Complement := No_Library_Graph_Vertex;
4178 Spec_Vertex := No_Library_Graph_Vertex;
4180 if Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then
4181 Complement := Proper_Spec (G, Vertex);
4182 Spec_Vertex := Complement;
4184 elsif Is_Spec_With_Elaborate_Body (G, Vertex) then
4185 Complement := Proper_Body (G, Vertex);
4186 Spec_Vertex := Vertex;
4189 -- The vertex is part of an Elaborate_Body pair. Take into account
4190 -- the strong and weak predecessors of the complementary vertex.
4192 if Present (Complement) then
4193 Total_Strong_Preds :=
4194 Pending_Strong_Predecessors (G, Complement) + Total_Strong_Preds;
4196 Pending_Weak_Predecessors (G, Complement) + Total_Weak_Preds;
4198 -- The body of an Elaborate_Body pair is the successor of a strong
4199 -- edge where the predecessor is the spec. This edge must not be
4200 -- considered for elaboration purposes because the pair is treated
4201 -- as one vertex. Account for the edge only when the spec has not
4202 -- been elaborated yet.
4204 if not In_Elaboration_Order (G, Spec_Vertex) then
4205 Total_Strong_Preds := Total_Strong_Preds - 1;
4209 Strong_Preds := Total_Strong_Preds;
4210 Weak_Preds := Total_Weak_Preds;
4211 end Pending_Predecessors_For_Elaboration;
4213 ---------------------------------
4214 -- Pending_Strong_Predecessors --
4215 ---------------------------------
4217 function Pending_Strong_Predecessors
4219 Comp : Component_Id) return Natural
4222 pragma Assert (Present (G));
4223 pragma Assert (Present (Comp));
4225 return Get_Component_Attributes (G, Comp).Pending_Strong_Predecessors;
4226 end Pending_Strong_Predecessors;
4228 ---------------------------------
4229 -- Pending_Strong_Predecessors --
4230 ---------------------------------
4232 function Pending_Strong_Predecessors
4234 Vertex : Library_Graph_Vertex_Id) return Natural
4237 pragma Assert (Present (G));
4238 pragma Assert (Present (Vertex));
4240 return Get_LGV_Attributes (G, Vertex).Pending_Strong_Predecessors;
4241 end Pending_Strong_Predecessors;
4243 -------------------------------
4244 -- Pending_Weak_Predecessors --
4245 -------------------------------
4247 function Pending_Weak_Predecessors
4249 Comp : Component_Id) return Natural
4252 pragma Assert (Present (G));
4253 pragma Assert (Present (Comp));
4255 return Get_Component_Attributes (G, Comp).Pending_Weak_Predecessors;
4256 end Pending_Weak_Predecessors;
4258 -------------------------------
4259 -- Pending_Weak_Predecessors --
4260 -------------------------------
4262 function Pending_Weak_Predecessors
4264 Vertex : Library_Graph_Vertex_Id) return Natural
4267 pragma Assert (Present (G));
4268 pragma Assert (Present (Vertex));
4270 return Get_LGV_Attributes (G, Vertex).Pending_Weak_Predecessors;
4271 end Pending_Weak_Predecessors;
4279 Cycle : Library_Graph_Cycle_Id;
4280 Compared_To : Library_Graph_Cycle_Id) return Precedence_Kind
4282 pragma Assert (Present (G));
4283 pragma Assert (Present (Cycle));
4284 pragma Assert (Present (Compared_To));
4286 Comp_Invs : constant Natural :=
4287 Invocation_Edge_Count (G, Compared_To);
4288 Comp_Len : constant Natural := Length (G, Compared_To);
4289 Cycle_Invs : constant Natural := Invocation_Edge_Count (G, Cycle);
4290 Cycle_Len : constant Natural := Length (G, Cycle);
4291 Kind_Prec : constant Precedence_Kind :=
4293 (Kind => Kind (G, Cycle),
4294 Compared_To => Kind (G, Compared_To));
4297 if Kind_Prec = Higher_Precedence
4299 Kind_Prec = Lower_Precedence
4303 -- Otherwise both cycles have the same precedence based on their
4304 -- kind. Prefer a cycle with fewer invocation edges.
4306 elsif Cycle_Invs < Comp_Invs then
4307 return Higher_Precedence;
4309 elsif Cycle_Invs > Comp_Invs then
4310 return Lower_Precedence;
4312 -- Otherwise both cycles have the same number of invocation edges.
4313 -- Prefer a cycle with a smaller length.
4315 elsif Cycle_Len < Comp_Len then
4316 return Higher_Precedence;
4318 elsif Cycle_Len > Comp_Len then
4319 return Lower_Precedence;
4322 return Equal_Precedence;
4331 (Kind : Library_Graph_Cycle_Kind;
4332 Compared_To : Library_Graph_Cycle_Kind) return Precedence_Kind
4334 Comp_Pos : constant Integer :=
4335 Library_Graph_Cycle_Kind'Pos (Compared_To);
4336 Kind_Pos : constant Integer := Library_Graph_Cycle_Kind'Pos (Kind);
4339 -- A lower ordinal indicates higher precedence
4341 if Kind_Pos < Comp_Pos then
4342 return Higher_Precedence;
4344 elsif Kind_Pos > Comp_Pos then
4345 return Lower_Precedence;
4348 return Equal_Precedence;
4358 Edge : Library_Graph_Edge_Id;
4359 Compared_To : Library_Graph_Edge_Id) return Precedence_Kind
4361 pragma Assert (Present (G));
4362 pragma Assert (Present (Edge));
4363 pragma Assert (Present (Compared_To));
4365 Kind_Prec : constant Precedence_Kind :=
4367 (Kind => Cycle_Kind_Of (G, Edge),
4368 Compared_To => Cycle_Kind_Of (G, Compared_To));
4371 if Kind_Prec = Higher_Precedence
4373 Kind_Prec = Lower_Precedence
4377 -- Otherwise both edges have the same precedence based on their cycle
4378 -- kinds. Prefer an edge whose successor has higher precedence.
4384 Vertex => Successor (G, Edge),
4385 Compared_To => Successor (G, Compared_To));
4395 Vertex : Library_Graph_Vertex_Id;
4396 Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind
4399 pragma Assert (Present (G));
4400 pragma Assert (Present (Vertex));
4401 pragma Assert (Present (Compared_To));
4403 -- Use lexicographical order to determine precedence and ensure
4404 -- deterministic behavior.
4406 if Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then
4407 return Higher_Precedence;
4409 return Lower_Precedence;
4417 function Predecessor
4419 Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
4422 pragma Assert (Present (G));
4423 pragma Assert (Present (Edge));
4425 return DG.Source_Vertex (G.Graph, Edge);
4432 function Present (G : Library_Graph) return Boolean is
4441 function Proper_Body
4443 Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
4446 pragma Assert (Present (G));
4447 pragma Assert (Present (Vertex));
4449 -- When the vertex denotes a spec with a completing body, return the
4452 if Is_Spec_With_Body (G, Vertex) then
4453 return Corresponding_Item (G, Vertex);
4455 -- Otherwise the vertex must be a body
4458 pragma Assert (Is_Body (G, Vertex));
4467 function Proper_Spec
4469 Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
4472 pragma Assert (Present (G));
4473 pragma Assert (Present (Vertex));
4475 -- When the vertex denotes a body that completes a spec, return the
4478 if Is_Body_With_Spec (G, Vertex) then
4479 return Corresponding_Item (G, Vertex);
4481 -- Otherwise the vertex must denote a spec
4484 pragma Assert (Is_Spec (G, Vertex));
4489 ----------------------------------
4490 -- Remove_Vertex_And_Complement --
4491 ----------------------------------
4493 procedure Remove_Vertex_And_Complement
4495 Vertex : Library_Graph_Vertex_Id;
4496 Set : LGV_Sets.Membership_Set;
4497 Do_Complement : Boolean)
4499 pragma Assert (Present (G));
4500 pragma Assert (Present (Vertex));
4501 pragma Assert (LGV_Sets.Present (Set));
4503 Complement : constant Library_Graph_Vertex_Id :=
4504 Complementary_Vertex
4507 Force_Complement => Do_Complement);
4510 LGV_Sets.Delete (Set, Vertex);
4512 if Present (Complement) then
4513 LGV_Sets.Delete (Set, Complement);
4515 end Remove_Vertex_And_Complement;
4517 -----------------------------------------
4518 -- Same_Library_Graph_Cycle_Attributes --
4519 -----------------------------------------
4521 function Same_Library_Graph_Cycle_Attributes
4522 (Left : Library_Graph_Cycle_Attributes;
4523 Right : Library_Graph_Cycle_Attributes) return Boolean
4526 -- Two cycles are the same when
4528 -- * They are of the same kind
4529 -- * They have the same number of invocation edges in their paths
4530 -- * Their paths are the same length
4531 -- * The edges comprising their paths are the same
4534 Left.Invocation_Edge_Count = Right.Invocation_Edge_Count
4535 and then Left.Kind = Right.Kind
4536 and then LGE_Lists.Equal (Left.Path, Right.Path);
4537 end Same_Library_Graph_Cycle_Attributes;
4539 ------------------------------
4540 -- Set_Component_Attributes --
4541 ------------------------------
4543 procedure Set_Component_Attributes
4545 Comp : Component_Id;
4546 Val : Component_Attributes)
4549 pragma Assert (Present (G));
4550 pragma Assert (Present (Comp));
4552 Component_Tables.Put (G.Component_Attributes, Comp, Val);
4553 end Set_Component_Attributes;
4555 ----------------------------
4556 -- Set_Corresponding_Item --
4557 ----------------------------
4559 procedure Set_Corresponding_Item
4561 Vertex : Library_Graph_Vertex_Id;
4562 Val : Library_Graph_Vertex_Id)
4564 Attrs : Library_Graph_Vertex_Attributes;
4567 pragma Assert (Present (G));
4568 pragma Assert (Present (Vertex));
4570 Attrs := Get_LGV_Attributes (G, Vertex);
4571 Attrs.Corresponding_Item := Val;
4572 Set_LGV_Attributes (G, Vertex, Attrs);
4573 end Set_Corresponding_Item;
4575 ------------------------------
4576 -- Set_Corresponding_Vertex --
4577 ------------------------------
4579 procedure Set_Corresponding_Vertex
4582 Val : Library_Graph_Vertex_Id)
4585 pragma Assert (Present (G));
4586 pragma Assert (Present (U_Id));
4588 Unit_Tables.Put (G.Unit_To_Vertex, U_Id, Val);
4589 end Set_Corresponding_Vertex;
4591 ------------------------------
4592 -- Set_In_Elaboration_Order --
4593 ------------------------------
4595 procedure Set_In_Elaboration_Order
4597 Vertex : Library_Graph_Vertex_Id;
4598 Val : Boolean := True)
4600 Attrs : Library_Graph_Vertex_Attributes;
4603 pragma Assert (Present (G));
4604 pragma Assert (Present (Vertex));
4606 Attrs := Get_LGV_Attributes (G, Vertex);
4607 Attrs.In_Elaboration_Order := Val;
4608 Set_LGV_Attributes (G, Vertex, Attrs);
4609 end Set_In_Elaboration_Order;
4611 ---------------------------
4612 -- Set_Is_Recorded_Cycle --
4613 ---------------------------
4615 procedure Set_Is_Recorded_Cycle
4617 Attrs : Library_Graph_Cycle_Attributes;
4618 Val : Boolean := True)
4621 pragma Assert (Present (G));
4624 RC_Sets.Insert (G.Recorded_Cycles, Attrs);
4626 RC_Sets.Delete (G.Recorded_Cycles, Attrs);
4628 end Set_Is_Recorded_Cycle;
4630 --------------------------
4631 -- Set_Is_Recorded_Edge --
4632 --------------------------
4634 procedure Set_Is_Recorded_Edge
4636 Rel : Predecessor_Successor_Relation;
4637 Val : Boolean := True)
4640 pragma Assert (Present (G));
4641 pragma Assert (Present (Rel.Predecessor));
4642 pragma Assert (Present (Rel.Successor));
4645 RE_Sets.Insert (G.Recorded_Edges, Rel);
4647 RE_Sets.Delete (G.Recorded_Edges, Rel);
4649 end Set_Is_Recorded_Edge;
4651 ------------------------
4652 -- Set_LGC_Attributes --
4653 ------------------------
4655 procedure Set_LGC_Attributes
4657 Cycle : Library_Graph_Cycle_Id;
4658 Val : Library_Graph_Cycle_Attributes)
4661 pragma Assert (Present (G));
4662 pragma Assert (Present (Cycle));
4664 LGC_Tables.Put (G.Cycle_Attributes, Cycle, Val);
4665 end Set_LGC_Attributes;
4667 ------------------------
4668 -- Set_LGE_Attributes --
4669 ------------------------
4671 procedure Set_LGE_Attributes
4673 Edge : Library_Graph_Edge_Id;
4674 Val : Library_Graph_Edge_Attributes)
4677 pragma Assert (Present (G));
4678 pragma Assert (Present (Edge));
4680 LGE_Tables.Put (G.Edge_Attributes, Edge, Val);
4681 end Set_LGE_Attributes;
4683 ------------------------
4684 -- Set_LGV_Attributes --
4685 ------------------------
4687 procedure Set_LGV_Attributes
4689 Vertex : Library_Graph_Vertex_Id;
4690 Val : Library_Graph_Vertex_Attributes)
4693 pragma Assert (Present (G));
4694 pragma Assert (Present (Vertex));
4696 LGV_Tables.Put (G.Vertex_Attributes, Vertex, Val);
4697 end Set_LGV_Attributes;
4705 Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
4708 pragma Assert (Present (G));
4709 pragma Assert (Present (Edge));
4711 return DG.Destination_Vertex (G.Graph, Edge);
4718 procedure Trace_Cycle
4720 Cycle : Library_Graph_Cycle_Id;
4721 Indent : Indentation_Level)
4723 Attr_Indent : constant Indentation_Level :=
4724 Indent + Nested_Indentation;
4725 Edge_Indent : constant Indentation_Level :=
4726 Attr_Indent + Nested_Indentation;
4728 Edge : Library_Graph_Edge_Id;
4729 Iter : Edges_Of_Cycle_Iterator;
4732 pragma Assert (Present (G));
4733 pragma Assert (Present (Cycle));
4735 -- Nothing to do when switch -d_T (output elaboration order and cycle
4736 -- detection trace information) is not in effect.
4738 if not Debug_Flag_Underscore_TT then
4743 Write_Str ("cycle (Cycle_Id_");
4744 Write_Int (Int (Cycle));
4748 Indent_By (Attr_Indent);
4749 Write_Str ("kind = ");
4750 Write_Str (Kind (G, Cycle)'Img);
4753 Indent_By (Attr_Indent);
4754 Write_Str ("invocation edges = ");
4755 Write_Int (Int (Invocation_Edge_Count (G, Cycle)));
4758 Indent_By (Attr_Indent);
4759 Write_Str ("length: ");
4760 Write_Int (Int (Length (G, Cycle)));
4763 Iter := Iterate_Edges_Of_Cycle (G, Cycle);
4764 while Has_Next (Iter) loop
4767 Indent_By (Edge_Indent);
4768 Write_Str ("library graph edge (Edge_");
4769 Write_Int (Int (Edge));
4779 procedure Trace_Edge
4781 Edge : Library_Graph_Edge_Id;
4782 Indent : Indentation_Level)
4784 pragma Assert (Present (G));
4785 pragma Assert (Present (Edge));
4787 Attr_Indent : constant Indentation_Level :=
4788 Indent + Nested_Indentation;
4790 Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
4791 Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
4794 -- Nothing to do when switch -d_T (output elaboration order and cycle
4795 -- detection trace information) is not in effect.
4797 if not Debug_Flag_Underscore_TT then
4802 Write_Str ("library graph edge (Edge_");
4803 Write_Int (Int (Edge));
4807 Indent_By (Attr_Indent);
4808 Write_Str ("kind = ");
4809 Write_Str (Kind (G, Edge)'Img);
4812 Indent_By (Attr_Indent);
4813 Write_Str ("Predecessor (Vertex_");
4814 Write_Int (Int (Pred));
4815 Write_Str (") name = ");
4816 Write_Name (Name (G, Pred));
4819 Indent_By (Attr_Indent);
4820 Write_Str ("Successor (Vertex_");
4821 Write_Int (Int (Succ));
4822 Write_Str (") name = ");
4823 Write_Name (Name (G, Succ));
4831 procedure Trace_Eol is
4833 -- Nothing to do when switch -d_T (output elaboration order and cycle
4834 -- detection trace information) is not in effect.
4836 if not Debug_Flag_Underscore_TT then
4847 procedure Trace_Vertex
4849 Vertex : Library_Graph_Vertex_Id;
4850 Indent : Indentation_Level)
4852 Attr_Indent : constant Indentation_Level :=
4853 Indent + Nested_Indentation;
4856 pragma Assert (Present (G));
4857 pragma Assert (Present (Vertex));
4859 -- Nothing to do when switch -d_T (output elaboration order and cycle
4860 -- detection trace information) is not in effect.
4862 if not Debug_Flag_Underscore_TT then
4867 Write_Str ("library graph vertex (Vertex_");
4868 Write_Int (Int (Vertex));
4872 Indent_By (Attr_Indent);
4873 Write_Str ("Component (Comp_Id_");
4874 Write_Int (Int (Component (G, Vertex)));
4878 Indent_By (Attr_Indent);
4879 Write_Str ("Unit (U_Id_");
4880 Write_Int (Int (Unit (G, Vertex)));
4881 Write_Str (") name = ");
4882 Write_Name (Name (G, Vertex));
4892 Vertex : Library_Graph_Vertex_Id) return Unit_Id
4895 pragma Assert (Present (G));
4896 pragma Assert (Present (Vertex));
4898 return Get_LGV_Attributes (G, Vertex).Unit;
4901 ---------------------------------
4902 -- Update_Pending_Predecessors --
4903 ---------------------------------
4905 procedure Update_Pending_Predecessors
4906 (Strong_Predecessors : in out Natural;
4907 Weak_Predecessors : in out Natural;
4908 Update_Weak : Boolean;
4913 Weak_Predecessors := Weak_Predecessors + Value;
4915 Strong_Predecessors := Strong_Predecessors + Value;
4917 end Update_Pending_Predecessors;
4919 -----------------------------------------------
4920 -- Update_Pending_Predecessors_Of_Components --
4921 -----------------------------------------------
4923 procedure Update_Pending_Predecessors_Of_Components
4926 Edge : Library_Graph_Edge_Id;
4927 Iter : All_Edge_Iterator;
4930 pragma Assert (Present (G));
4932 Iter := Iterate_All_Edges (G);
4933 while Has_Next (Iter) loop
4936 Update_Pending_Predecessors_Of_Components (G, Edge);
4938 end Update_Pending_Predecessors_Of_Components;
4940 -----------------------------------------------
4941 -- Update_Pending_Predecessors_Of_Components --
4942 -----------------------------------------------
4944 procedure Update_Pending_Predecessors_Of_Components
4946 Edge : Library_Graph_Edge_Id)
4948 pragma Assert (Present (G));
4949 pragma Assert (Present (Edge));
4951 Pred_Comp : constant Component_Id :=
4952 Component (G, Predecessor (G, Edge));
4953 Succ_Comp : constant Component_Id :=
4954 Component (G, Successor (G, Edge));
4956 pragma Assert (Present (Pred_Comp));
4957 pragma Assert (Present (Succ_Comp));
4960 -- The edge links a successor and a predecessor coming from two
4961 -- different SCCs. This indicates that the SCC of the successor
4962 -- must wait on another predecessor until it can be elaborated.
4964 if Pred_Comp /= Succ_Comp then
4965 Increment_Pending_Predecessors
4970 end Update_Pending_Predecessors_Of_Components;
4977 function Present (Edge : Invocation_Graph_Edge_Id) return Boolean is
4979 return Edge /= No_Invocation_Graph_Edge;
4986 function Present (Vertex : Invocation_Graph_Vertex_Id) return Boolean is
4988 return Vertex /= No_Invocation_Graph_Vertex;
4995 function Present (Cycle : Library_Graph_Cycle_Id) return Boolean is
4997 return Cycle /= No_Library_Graph_Cycle;
5004 function Present (Edge : Library_Graph_Edge_Id) return Boolean is
5006 return Edge /= No_Library_Graph_Edge;
5013 function Present (Vertex : Library_Graph_Vertex_Id) return Boolean is
5015 return Vertex /= No_Library_Graph_Vertex;
5018 --------------------------
5019 -- Sequence_Next_Edge --
5020 --------------------------
5022 IGE_Sequencer : Invocation_Graph_Edge_Id := First_Invocation_Graph_Edge;
5023 -- The counter for invocation graph edges. Do not directly manipulate its
5026 function Sequence_Next_Edge return Invocation_Graph_Edge_Id is
5027 Edge : constant Invocation_Graph_Edge_Id := IGE_Sequencer;
5030 IGE_Sequencer := IGE_Sequencer + 1;
5032 end Sequence_Next_Edge;
5034 --------------------------
5035 -- Sequence_Next_Vertex --
5036 --------------------------
5038 IGV_Sequencer : Invocation_Graph_Vertex_Id := First_Invocation_Graph_Vertex;
5039 -- The counter for invocation graph vertices. Do not directly manipulate
5042 function Sequence_Next_Vertex return Invocation_Graph_Vertex_Id is
5043 Vertex : constant Invocation_Graph_Vertex_Id := IGV_Sequencer;
5046 IGV_Sequencer := IGV_Sequencer + 1;
5048 end Sequence_Next_Vertex;
5050 --------------------------
5051 -- Sequence_Next_Cycle --
5052 --------------------------
5054 LGC_Sequencer : Library_Graph_Cycle_Id := First_Library_Graph_Cycle;
5055 -- The counter for library graph cycles. Do not directly manipulate its
5058 function Sequence_Next_Cycle return Library_Graph_Cycle_Id is
5059 Cycle : constant Library_Graph_Cycle_Id := LGC_Sequencer;
5062 LGC_Sequencer := LGC_Sequencer + 1;
5064 end Sequence_Next_Cycle;
5066 --------------------------
5067 -- Sequence_Next_Edge --
5068 --------------------------
5070 LGE_Sequencer : Library_Graph_Edge_Id := First_Library_Graph_Edge;
5071 -- The counter for library graph edges. Do not directly manipulate its
5074 function Sequence_Next_Edge return Library_Graph_Edge_Id is
5075 Edge : constant Library_Graph_Edge_Id := LGE_Sequencer;
5078 LGE_Sequencer := LGE_Sequencer + 1;
5080 end Sequence_Next_Edge;
5082 --------------------------
5083 -- Sequence_Next_Vertex --
5084 --------------------------
5086 LGV_Sequencer : Library_Graph_Vertex_Id := First_Library_Graph_Vertex;
5087 -- The counter for library graph vertices. Do not directly manipulate its
5090 function Sequence_Next_Vertex return Library_Graph_Vertex_Id is
5091 Vertex : constant Library_Graph_Vertex_Id := LGV_Sequencer;
5094 LGV_Sequencer := LGV_Sequencer + 1;
5096 end Sequence_Next_Vertex;