]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ada/bindo-graphs.adb
[Ada] New algorithm for Elaboration order v4.0
[thirdparty/gcc.git] / gcc / ada / bindo-graphs.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- B I N D O . G R A P H S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2019, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
25
26 with Ada.Unchecked_Deallocation;
27
28 with Butil; use Butil;
29 with Debug; use Debug;
30 with Output; use Output;
31
32 with Bindo.Writers;
33 use Bindo.Writers;
34
35 package body Bindo.Graphs is
36
37 -----------------------
38 -- Local subprograms --
39 -----------------------
40
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
44
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
48
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
52
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
56
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
60
61 -----------------------------------
62 -- Destroy_Invocation_Graph_Edge --
63 -----------------------------------
64
65 procedure Destroy_Invocation_Graph_Edge
66 (Edge : in out Invocation_Graph_Edge_Id)
67 is
68 pragma Unreferenced (Edge);
69 begin
70 null;
71 end Destroy_Invocation_Graph_Edge;
72
73 ---------------------------------
74 -- Destroy_Library_Graph_Cycle --
75 ---------------------------------
76
77 procedure Destroy_Library_Graph_Cycle
78 (Cycle : in out Library_Graph_Cycle_Id)
79 is
80 pragma Unreferenced (Cycle);
81 begin
82 null;
83 end Destroy_Library_Graph_Cycle;
84
85 --------------------------------
86 -- Destroy_Library_Graph_Edge --
87 --------------------------------
88
89 procedure Destroy_Library_Graph_Edge
90 (Edge : in out Library_Graph_Edge_Id)
91 is
92 pragma Unreferenced (Edge);
93 begin
94 null;
95 end Destroy_Library_Graph_Edge;
96
97 --------------------------------
98 -- Hash_Invocation_Graph_Edge --
99 --------------------------------
100
101 function Hash_Invocation_Graph_Edge
102 (Edge : Invocation_Graph_Edge_Id) return Bucket_Range_Type
103 is
104 begin
105 pragma Assert (Present (Edge));
106
107 return Bucket_Range_Type (Edge);
108 end Hash_Invocation_Graph_Edge;
109
110 ----------------------------------
111 -- Hash_Invocation_Graph_Vertex --
112 ----------------------------------
113
114 function Hash_Invocation_Graph_Vertex
115 (Vertex : Invocation_Graph_Vertex_Id) return Bucket_Range_Type
116 is
117 begin
118 pragma Assert (Present (Vertex));
119
120 return Bucket_Range_Type (Vertex);
121 end Hash_Invocation_Graph_Vertex;
122
123 ------------------------------
124 -- Hash_Library_Graph_Cycle --
125 ------------------------------
126
127 function Hash_Library_Graph_Cycle
128 (Cycle : Library_Graph_Cycle_Id) return Bucket_Range_Type
129 is
130 begin
131 pragma Assert (Present (Cycle));
132
133 return Bucket_Range_Type (Cycle);
134 end Hash_Library_Graph_Cycle;
135
136 -----------------------------
137 -- Hash_Library_Graph_Edge --
138 -----------------------------
139
140 function Hash_Library_Graph_Edge
141 (Edge : Library_Graph_Edge_Id) return Bucket_Range_Type
142 is
143 begin
144 pragma Assert (Present (Edge));
145
146 return Bucket_Range_Type (Edge);
147 end Hash_Library_Graph_Edge;
148
149 -------------------------------
150 -- Hash_Library_Graph_Vertex --
151 -------------------------------
152
153 function Hash_Library_Graph_Vertex
154 (Vertex : Library_Graph_Vertex_Id) return Bucket_Range_Type
155 is
156 begin
157 pragma Assert (Present (Vertex));
158
159 return Bucket_Range_Type (Vertex);
160 end Hash_Library_Graph_Vertex;
161
162 -----------------------
163 -- Invocation_Graphs --
164 -----------------------
165
166 package body Invocation_Graphs is
167
168 -----------------------
169 -- Local subprograms --
170 -----------------------
171
172 procedure Free is
173 new Ada.Unchecked_Deallocation
174 (Invocation_Graph_Attributes, Invocation_Graph);
175
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
182
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
189
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
195 -- one.
196
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.
203
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.
210
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
216
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
223
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.
231
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
238
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
245 -- Val.
246
247 --------------
248 -- Add_Edge --
249 --------------
250
251 procedure Add_Edge
252 (G : Invocation_Graph;
253 Source : Invocation_Graph_Vertex_Id;
254 Target : Invocation_Graph_Vertex_Id;
255 IR_Id : Invocation_Relation_Id)
256 is
257 pragma Assert (Present (G));
258 pragma Assert (Present (Source));
259 pragma Assert (Present (Target));
260 pragma Assert (Present (IR_Id));
261
262 Rel : constant Source_Target_Relation :=
263 (Source => Source,
264 Target => Target);
265
266 Edge : Invocation_Graph_Edge_Id;
267
268 begin
269 -- Nothing to do when the source and target are already related by an
270 -- edge.
271
272 if Is_Existing_Source_Target_Relation (G, Rel) then
273 return;
274 end if;
275
276 Edge := Sequence_Next_Edge;
277
278 -- Add the edge to the underlying graph
279
280 DG.Add_Edge
281 (G => G.Graph,
282 E => Edge,
283 Source => Source,
284 Destination => Target);
285
286 -- Build and save the attributes of the edge
287
288 Set_IGE_Attributes
289 (G => G,
290 Edge => Edge,
291 Val => (Relation => IR_Id));
292
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.
295
296 Set_Is_Existing_Source_Target_Relation (G, Rel);
297
298 -- Update the edge statistics
299
300 Increment_Invocation_Graph_Edge_Count (G, Kind (IR_Id));
301 end Add_Edge;
302
303 ----------------
304 -- Add_Vertex --
305 ----------------
306
307 procedure Add_Vertex
308 (G : Invocation_Graph;
309 IC_Id : Invocation_Construct_Id;
310 Body_Vertex : Library_Graph_Vertex_Id;
311 Spec_Vertex : Library_Graph_Vertex_Id)
312 is
313 pragma Assert (Present (G));
314 pragma Assert (Present (IC_Id));
315 pragma Assert (Present (Body_Vertex));
316 pragma Assert (Present (Spec_Vertex));
317
318 Construct_Signature : constant Invocation_Signature_Id :=
319 Signature (IC_Id);
320 Vertex : Invocation_Graph_Vertex_Id;
321
322 begin
323 -- Nothing to do when the construct already has a vertex
324
325 if Present (Corresponding_Vertex (G, Construct_Signature)) then
326 return;
327 end if;
328
329 Vertex := Sequence_Next_Vertex;
330
331 -- Add the vertex to the underlying graph
332
333 DG.Add_Vertex (G.Graph, Vertex);
334
335 -- Build and save the attributes of the vertex
336
337 Set_IGV_Attributes
338 (G => G,
339 Vertex => Vertex,
340 Val => (Body_Vertex => Body_Vertex,
341 Construct => IC_Id,
342 Spec_Vertex => Spec_Vertex));
343
344 -- Associate the construct with its corresponding vertex
345
346 Set_Corresponding_Vertex (G, Construct_Signature, Vertex);
347
348 -- Save the vertex for later processing when it denotes a spec or
349 -- body elaboration procedure.
350
351 if Is_Elaboration_Root (G, Vertex) then
352 Save_Elaboration_Root (G, Vertex);
353 end if;
354 end Add_Vertex;
355
356 -----------------
357 -- Body_Vertex --
358 -----------------
359
360 function Body_Vertex
361 (G : Invocation_Graph;
362 Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
363 is
364 begin
365 pragma Assert (Present (G));
366 pragma Assert (Present (Vertex));
367
368 return Get_IGV_Attributes (G, Vertex).Body_Vertex;
369 end Body_Vertex;
370
371 ------------
372 -- Column --
373 ------------
374
375 function Column
376 (G : Invocation_Graph;
377 Vertex : Invocation_Graph_Vertex_Id) return Nat
378 is
379 begin
380 pragma Assert (Present (G));
381 pragma Assert (Present (Vertex));
382
383 return Column (Signature (Construct (G, Vertex)));
384 end Column;
385
386 ---------------
387 -- Construct --
388 ---------------
389
390 function Construct
391 (G : Invocation_Graph;
392 Vertex : Invocation_Graph_Vertex_Id) return Invocation_Construct_Id
393 is
394 begin
395 pragma Assert (Present (G));
396 pragma Assert (Present (Vertex));
397
398 return Get_IGV_Attributes (G, Vertex).Construct;
399 end Construct;
400
401 --------------------------
402 -- Corresponding_Vertex --
403 --------------------------
404
405 function Corresponding_Vertex
406 (G : Invocation_Graph;
407 IS_Id : Invocation_Signature_Id) return Invocation_Graph_Vertex_Id
408 is
409 begin
410 pragma Assert (Present (G));
411 pragma Assert (Present (IS_Id));
412
413 return Signature_Tables.Get (G.Signature_To_Vertex, IS_Id);
414 end Corresponding_Vertex;
415
416 ------------
417 -- Create --
418 ------------
419
420 function Create
421 (Initial_Vertices : Positive;
422 Initial_Edges : Positive) return Invocation_Graph
423 is
424 G : constant Invocation_Graph := new Invocation_Graph_Attributes;
425
426 begin
427 G.Edge_Attributes := IGE_Tables.Create (Initial_Edges);
428 G.Graph :=
429 DG.Create
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);
436
437 return G;
438 end Create;
439
440 -------------
441 -- Destroy --
442 -------------
443
444 procedure Destroy (G : in out Invocation_Graph) is
445 begin
446 pragma Assert (Present (G));
447
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);
454
455 Free (G);
456 end Destroy;
457
458 -----------------------------------
459 -- Destroy_Invocation_Graph_Edge --
460 -----------------------------------
461
462 procedure Destroy_Invocation_Graph_Edge
463 (Edge : in out Invocation_Graph_Edge_Id)
464 is
465 pragma Unreferenced (Edge);
466 begin
467 null;
468 end Destroy_Invocation_Graph_Edge;
469
470 ----------------------------------------------
471 -- Destroy_Invocation_Graph_Edge_Attributes --
472 ----------------------------------------------
473
474 procedure Destroy_Invocation_Graph_Edge_Attributes
475 (Attrs : in out Invocation_Graph_Edge_Attributes)
476 is
477 pragma Unreferenced (Attrs);
478 begin
479 null;
480 end Destroy_Invocation_Graph_Edge_Attributes;
481
482 -------------------------------------
483 -- Destroy_Invocation_Graph_Vertex --
484 -------------------------------------
485
486 procedure Destroy_Invocation_Graph_Vertex
487 (Vertex : in out Invocation_Graph_Vertex_Id)
488 is
489 pragma Unreferenced (Vertex);
490 begin
491 null;
492 end Destroy_Invocation_Graph_Vertex;
493
494 ------------------------------------------------
495 -- Destroy_Invocation_Graph_Vertex_Attributes --
496 ------------------------------------------------
497
498 procedure Destroy_Invocation_Graph_Vertex_Attributes
499 (Attrs : in out Invocation_Graph_Vertex_Attributes)
500 is
501 pragma Unreferenced (Attrs);
502 begin
503 null;
504 end Destroy_Invocation_Graph_Vertex_Attributes;
505
506 -----------
507 -- Extra --
508 -----------
509
510 function Extra
511 (G : Invocation_Graph;
512 Edge : Invocation_Graph_Edge_Id) return Name_Id
513 is
514 begin
515 pragma Assert (Present (G));
516 pragma Assert (Present (Edge));
517
518 return Extra (Relation (G, Edge));
519 end Extra;
520
521 ------------------------
522 -- Get_IGE_Attributes --
523 ------------------------
524
525 function Get_IGE_Attributes
526 (G : Invocation_Graph;
527 Edge : Invocation_Graph_Edge_Id)
528 return Invocation_Graph_Edge_Attributes
529 is
530 begin
531 pragma Assert (Present (G));
532 pragma Assert (Present (Edge));
533
534 return IGE_Tables.Get (G.Edge_Attributes, Edge);
535 end Get_IGE_Attributes;
536
537 ------------------------
538 -- Get_IGV_Attributes --
539 ------------------------
540
541 function Get_IGV_Attributes
542 (G : Invocation_Graph;
543 Vertex : Invocation_Graph_Vertex_Id)
544 return Invocation_Graph_Vertex_Attributes
545 is
546 begin
547 pragma Assert (Present (G));
548 pragma Assert (Present (Vertex));
549
550 return IGV_Tables.Get (G.Vertex_Attributes, Vertex);
551 end Get_IGV_Attributes;
552
553 --------------
554 -- Has_Next --
555 --------------
556
557 function Has_Next (Iter : All_Edge_Iterator) return Boolean is
558 begin
559 return DG.Has_Next (DG.All_Edge_Iterator (Iter));
560 end Has_Next;
561
562 --------------
563 -- Has_Next --
564 --------------
565
566 function Has_Next (Iter : All_Vertex_Iterator) return Boolean is
567 begin
568 return DG.Has_Next (DG.All_Vertex_Iterator (Iter));
569 end Has_Next;
570
571 --------------
572 -- Has_Next --
573 --------------
574
575 function Has_Next (Iter : Edges_To_Targets_Iterator) return Boolean is
576 begin
577 return DG.Has_Next (DG.Outgoing_Edge_Iterator (Iter));
578 end Has_Next;
579
580 --------------
581 -- Has_Next --
582 --------------
583
584 function Has_Next (Iter : Elaboration_Root_Iterator) return Boolean is
585 begin
586 return IGV_Sets.Has_Next (IGV_Sets.Iterator (Iter));
587 end Has_Next;
588
589 -------------------------------
590 -- Hash_Invocation_Signature --
591 -------------------------------
592
593 function Hash_Invocation_Signature
594 (IS_Id : Invocation_Signature_Id) return Bucket_Range_Type
595 is
596 begin
597 pragma Assert (Present (IS_Id));
598
599 return Bucket_Range_Type (IS_Id);
600 end Hash_Invocation_Signature;
601
602 ---------------------------------
603 -- Hash_Source_Target_Relation --
604 ---------------------------------
605
606 function Hash_Source_Target_Relation
607 (Rel : Source_Target_Relation) return Bucket_Range_Type
608 is
609 begin
610 pragma Assert (Present (Rel.Source));
611 pragma Assert (Present (Rel.Target));
612
613 return
614 Hash_Two_Keys
615 (Bucket_Range_Type (Rel.Source),
616 Bucket_Range_Type (Rel.Target));
617 end Hash_Source_Target_Relation;
618
619 -------------------------------------------
620 -- Increment_Invocation_Graph_Edge_Count --
621 -------------------------------------------
622
623 procedure Increment_Invocation_Graph_Edge_Count
624 (G : Invocation_Graph;
625 Kind : Invocation_Kind)
626 is
627 pragma Assert (Present (G));
628
629 Count : Natural renames G.Counts (Kind);
630
631 begin
632 Count := Count + 1;
633 end Increment_Invocation_Graph_Edge_Count;
634
635 ---------------------------------
636 -- Invocation_Graph_Edge_Count --
637 ---------------------------------
638
639 function Invocation_Graph_Edge_Count
640 (G : Invocation_Graph;
641 Kind : Invocation_Kind) return Natural
642 is
643 begin
644 pragma Assert (Present (G));
645
646 return G.Counts (Kind);
647 end Invocation_Graph_Edge_Count;
648
649 -------------------------
650 -- Is_Elaboration_Root --
651 -------------------------
652
653 function Is_Elaboration_Root
654 (G : Invocation_Graph;
655 Vertex : Invocation_Graph_Vertex_Id) return Boolean
656 is
657 pragma Assert (Present (G));
658 pragma Assert (Present (Vertex));
659
660 Vertex_Kind : constant Invocation_Construct_Kind :=
661 Kind (Construct (G, Vertex));
662
663 begin
664 return
665 Vertex_Kind = Elaborate_Body_Procedure
666 or else
667 Vertex_Kind = Elaborate_Spec_Procedure;
668 end Is_Elaboration_Root;
669
670 ----------------------------------------
671 -- Is_Existing_Source_Target_Relation --
672 ----------------------------------------
673
674 function Is_Existing_Source_Target_Relation
675 (G : Invocation_Graph;
676 Rel : Source_Target_Relation) return Boolean
677 is
678 begin
679 pragma Assert (Present (G));
680
681 return Relation_Sets.Contains (G.Relations, Rel);
682 end Is_Existing_Source_Target_Relation;
683
684 -----------------------
685 -- Iterate_All_Edges --
686 -----------------------
687
688 function Iterate_All_Edges
689 (G : Invocation_Graph) return All_Edge_Iterator
690 is
691 begin
692 pragma Assert (Present (G));
693
694 return All_Edge_Iterator (DG.Iterate_All_Edges (G.Graph));
695 end Iterate_All_Edges;
696
697 --------------------------
698 -- Iterate_All_Vertices --
699 --------------------------
700
701 function Iterate_All_Vertices
702 (G : Invocation_Graph) return All_Vertex_Iterator
703 is
704 begin
705 pragma Assert (Present (G));
706
707 return All_Vertex_Iterator (DG.Iterate_All_Vertices (G.Graph));
708 end Iterate_All_Vertices;
709
710 ------------------------------
711 -- Iterate_Edges_To_Targets --
712 ------------------------------
713
714 function Iterate_Edges_To_Targets
715 (G : Invocation_Graph;
716 Vertex : Invocation_Graph_Vertex_Id) return Edges_To_Targets_Iterator
717 is
718 begin
719 pragma Assert (Present (G));
720 pragma Assert (Present (Vertex));
721
722 return
723 Edges_To_Targets_Iterator
724 (DG.Iterate_Outgoing_Edges (G.Graph, Vertex));
725 end Iterate_Edges_To_Targets;
726
727 -------------------------------
728 -- Iterate_Elaboration_Roots --
729 -------------------------------
730
731 function Iterate_Elaboration_Roots
732 (G : Invocation_Graph) return Elaboration_Root_Iterator
733 is
734 begin
735 pragma Assert (Present (G));
736
737 return Elaboration_Root_Iterator (IGV_Sets.Iterate (G.Roots));
738 end Iterate_Elaboration_Roots;
739
740 ----------
741 -- Kind --
742 ----------
743
744 function Kind
745 (G : Invocation_Graph;
746 Edge : Invocation_Graph_Edge_Id) return Invocation_Kind
747 is
748 begin
749 pragma Assert (Present (G));
750 pragma Assert (Present (Edge));
751
752 return Kind (Relation (G, Edge));
753 end Kind;
754
755 ----------
756 -- Line --
757 ----------
758
759 function Line
760 (G : Invocation_Graph;
761 Vertex : Invocation_Graph_Vertex_Id) return Nat
762 is
763 begin
764 pragma Assert (Present (G));
765 pragma Assert (Present (Vertex));
766
767 return Line (Signature (Construct (G, Vertex)));
768 end Line;
769
770 ----------
771 -- Name --
772 ----------
773
774 function Name
775 (G : Invocation_Graph;
776 Vertex : Invocation_Graph_Vertex_Id) return Name_Id
777 is
778 begin
779 pragma Assert (Present (G));
780 pragma Assert (Present (Vertex));
781
782 return Name (Signature (Construct (G, Vertex)));
783 end Name;
784
785 ----------
786 -- Next --
787 ----------
788
789 procedure Next
790 (Iter : in out All_Edge_Iterator;
791 Edge : out Invocation_Graph_Edge_Id)
792 is
793 begin
794 DG.Next (DG.All_Edge_Iterator (Iter), Edge);
795 end Next;
796
797 ----------
798 -- Next --
799 ----------
800
801 procedure Next
802 (Iter : in out All_Vertex_Iterator;
803 Vertex : out Invocation_Graph_Vertex_Id)
804 is
805 begin
806 DG.Next (DG.All_Vertex_Iterator (Iter), Vertex);
807 end Next;
808
809 ----------
810 -- Next --
811 ----------
812
813 procedure Next
814 (Iter : in out Edges_To_Targets_Iterator;
815 Edge : out Invocation_Graph_Edge_Id)
816 is
817 begin
818 DG.Next (DG.Outgoing_Edge_Iterator (Iter), Edge);
819 end Next;
820
821 ----------
822 -- Next --
823 ----------
824
825 procedure Next
826 (Iter : in out Elaboration_Root_Iterator;
827 Root : out Invocation_Graph_Vertex_Id)
828 is
829 begin
830 IGV_Sets.Next (IGV_Sets.Iterator (Iter), Root);
831 end Next;
832
833 ---------------------
834 -- Number_Of_Edges --
835 ---------------------
836
837 function Number_Of_Edges (G : Invocation_Graph) return Natural is
838 begin
839 pragma Assert (Present (G));
840
841 return DG.Number_Of_Edges (G.Graph);
842 end Number_Of_Edges;
843
844 --------------------------------
845 -- Number_Of_Edges_To_Targets --
846 --------------------------------
847
848 function Number_Of_Edges_To_Targets
849 (G : Invocation_Graph;
850 Vertex : Invocation_Graph_Vertex_Id) return Natural
851 is
852 begin
853 pragma Assert (Present (G));
854 pragma Assert (Present (Vertex));
855
856 return DG.Number_Of_Outgoing_Edges (G.Graph, Vertex);
857 end Number_Of_Edges_To_Targets;
858
859 ---------------------------------
860 -- Number_Of_Elaboration_Roots --
861 ---------------------------------
862
863 function Number_Of_Elaboration_Roots
864 (G : Invocation_Graph) return Natural
865 is
866 begin
867 pragma Assert (Present (G));
868
869 return IGV_Sets.Size (G.Roots);
870 end Number_Of_Elaboration_Roots;
871
872 ------------------------
873 -- Number_Of_Vertices --
874 ------------------------
875
876 function Number_Of_Vertices (G : Invocation_Graph) return Natural is
877 begin
878 pragma Assert (Present (G));
879
880 return DG.Number_Of_Vertices (G.Graph);
881 end Number_Of_Vertices;
882
883 -------------
884 -- Present --
885 -------------
886
887 function Present (G : Invocation_Graph) return Boolean is
888 begin
889 return G /= Nil;
890 end Present;
891
892 --------------
893 -- Relation --
894 --------------
895
896 function Relation
897 (G : Invocation_Graph;
898 Edge : Invocation_Graph_Edge_Id) return Invocation_Relation_Id
899 is
900 begin
901 pragma Assert (Present (G));
902 pragma Assert (Present (Edge));
903
904 return Get_IGE_Attributes (G, Edge).Relation;
905 end Relation;
906
907 ---------------------------
908 -- Save_Elaboration_Root --
909 ---------------------------
910
911 procedure Save_Elaboration_Root
912 (G : Invocation_Graph;
913 Root : Invocation_Graph_Vertex_Id)
914 is
915 begin
916 pragma Assert (Present (G));
917 pragma Assert (Present (Root));
918
919 IGV_Sets.Insert (G.Roots, Root);
920 end Save_Elaboration_Root;
921
922 ------------------------------
923 -- Set_Corresponding_Vertex --
924 ------------------------------
925
926 procedure Set_Corresponding_Vertex
927 (G : Invocation_Graph;
928 IS_Id : Invocation_Signature_Id;
929 Vertex : Invocation_Graph_Vertex_Id)
930 is
931 begin
932 pragma Assert (Present (G));
933 pragma Assert (Present (IS_Id));
934 pragma Assert (Present (Vertex));
935
936 Signature_Tables.Put (G.Signature_To_Vertex, IS_Id, Vertex);
937 end Set_Corresponding_Vertex;
938
939 --------------------------------------------
940 -- Set_Is_Existing_Source_Target_Relation --
941 --------------------------------------------
942
943 procedure Set_Is_Existing_Source_Target_Relation
944 (G : Invocation_Graph;
945 Rel : Source_Target_Relation;
946 Val : Boolean := True)
947 is
948 begin
949 pragma Assert (Present (G));
950 pragma Assert (Present (Rel.Source));
951 pragma Assert (Present (Rel.Target));
952
953 if Val then
954 Relation_Sets.Insert (G.Relations, Rel);
955 else
956 Relation_Sets.Delete (G.Relations, Rel);
957 end if;
958 end Set_Is_Existing_Source_Target_Relation;
959
960 ------------------------
961 -- Set_IGE_Attributes --
962 ------------------------
963
964 procedure Set_IGE_Attributes
965 (G : Invocation_Graph;
966 Edge : Invocation_Graph_Edge_Id;
967 Val : Invocation_Graph_Edge_Attributes)
968 is
969 begin
970 pragma Assert (Present (G));
971 pragma Assert (Present (Edge));
972
973 IGE_Tables.Put (G.Edge_Attributes, Edge, Val);
974 end Set_IGE_Attributes;
975
976 ------------------------
977 -- Set_IGV_Attributes --
978 ------------------------
979
980 procedure Set_IGV_Attributes
981 (G : Invocation_Graph;
982 Vertex : Invocation_Graph_Vertex_Id;
983 Val : Invocation_Graph_Vertex_Attributes)
984 is
985 begin
986 pragma Assert (Present (G));
987 pragma Assert (Present (Vertex));
988
989 IGV_Tables.Put (G.Vertex_Attributes, Vertex, Val);
990 end Set_IGV_Attributes;
991
992 -----------------
993 -- Spec_Vertex --
994 -----------------
995
996 function Spec_Vertex
997 (G : Invocation_Graph;
998 Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
999 is
1000 begin
1001 pragma Assert (Present (G));
1002 pragma Assert (Present (Vertex));
1003
1004 return Get_IGV_Attributes (G, Vertex).Spec_Vertex;
1005 end Spec_Vertex;
1006
1007 ------------
1008 -- Target --
1009 ------------
1010
1011 function Target
1012 (G : Invocation_Graph;
1013 Edge : Invocation_Graph_Edge_Id) return Invocation_Graph_Vertex_Id
1014 is
1015 begin
1016 pragma Assert (Present (G));
1017 pragma Assert (Present (Edge));
1018
1019 return DG.Destination_Vertex (G.Graph, Edge);
1020 end Target;
1021 end Invocation_Graphs;
1022
1023 --------------------
1024 -- Library_Graphs --
1025 --------------------
1026
1027 package body Library_Graphs is
1028
1029 -----------------------
1030 -- Local subprograms --
1031 -----------------------
1032
1033 procedure Add_Body_Before_Spec_Edge
1034 (G : Library_Graph;
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.
1041
1042 procedure Add_Body_Before_Spec_Edges
1043 (G : Library_Graph;
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.
1049
1050 procedure Add_Cycle
1051 (G : Library_Graph;
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
1058 -- for tracing.
1059
1060 function Add_Edge_With_Return
1061 (G : Library_Graph;
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.
1070
1071 procedure Add_Vertex_And_Complement
1072 (G : Library_Graph;
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.
1080
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
1086
1087 function Cycle_Kind_Of
1088 (G : Library_Graph;
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.
1093
1094 procedure Decrement_Library_Graph_Edge_Count
1095 (G : Library_Graph;
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
1099
1100 procedure Delete_Body_Before_Spec_Edges
1101 (G : Library_Graph;
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
1106 -- successor.
1107
1108 procedure Delete_Edge
1109 (G : Library_Graph;
1110 Edge : Library_Graph_Edge_Id);
1111 pragma Inline (Delete_Edge);
1112 -- Delete edge Edge from library graph G
1113
1114 procedure Find_All_Cycles_Through_Vertex
1115 (G : Library_Graph;
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.
1134
1135 procedure Find_All_Cycles_With_Edge
1136 (G : Library_Graph;
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.
1148
1149 function Find_First_Lower_Precedence_Cycle
1150 (G : Library_Graph;
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.
1156
1157 procedure Free is
1158 new Ada.Unchecked_Deallocation
1159 (Library_Graph_Attributes, Library_Graph);
1160
1161 function Get_Component_Attributes
1162 (G : Library_Graph;
1163 Comp : Component_Id) return Component_Attributes;
1164 pragma Inline (Get_Component_Attributes);
1165 -- Obtain the attributes of component Comp of library graph G
1166
1167 function Get_LGC_Attributes
1168 (G : Library_Graph;
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
1172
1173 function Get_LGE_Attributes
1174 (G : Library_Graph;
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
1179
1180 function Get_LGV_Attributes
1181 (G : Library_Graph;
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
1186
1187 function Has_Elaborate_Body
1188 (G : Library_Graph;
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.
1193
1194 function Highest_Precedence_Edge
1195 (G : Library_Graph;
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
1200 -- library graph G.
1201
1202 procedure Increment_Library_Graph_Edge_Count
1203 (G : Library_Graph;
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
1207
1208 procedure Increment_Pending_Predecessors
1209 (G : Library_Graph;
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.
1216
1217 procedure Increment_Pending_Predecessors
1218 (G : Library_Graph;
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.
1225
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.
1230
1231 procedure Insert_And_Sort
1232 (G : Library_Graph;
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.
1237
1238 function Is_Cycle_Initiating_Edge
1239 (G : Library_Graph;
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
1243
1244 function Is_Cyclic_Edge
1245 (G : Library_Graph;
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
1249 -- cycle.
1250
1251 function Is_Cyclic_Elaborate_All_Edge
1252 (G : Library_Graph;
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.
1257
1258 function Is_Cyclic_Elaborate_Body_Edge
1259 (G : Library_Graph;
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.
1265
1266 function Is_Cyclic_Elaborate_Edge
1267 (G : Library_Graph;
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.
1272
1273 function Is_Cyclic_Forced_Edge
1274 (G : Library_Graph;
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.
1279
1280 function Is_Cyclic_Invocation_Edge
1281 (G : Library_Graph;
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.
1286
1287 function Is_Cyclic_With_Edge
1288 (G : Library_Graph;
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
1293 -- and predecessor.
1294
1295 function Is_Recorded_Cycle
1296 (G : Library_Graph;
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.
1301
1302 function Is_Recorded_Edge
1303 (G : Library_Graph;
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.
1308
1309 function Links_Vertices_In_Same_Component
1310 (G : Library_Graph;
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.
1315
1316 function Maximum_Invocation_Edge_Count
1317 (G : Library_Graph;
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.
1323
1324 procedure Normalize_And_Add_Cycle
1325 (G : Library_Graph;
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.
1336
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
1342 -- Sig_Edge.
1343
1344 function Path
1345 (G : Library_Graph;
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
1349 -- graph G.
1350
1351 function Precedence
1352 (G : Library_Graph;
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.
1358
1359 function Precedence
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
1364 -- Compared_To.
1365
1366 function Precedence
1367 (G : Library_Graph;
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.
1373
1374 function Precedence
1375 (G : Library_Graph;
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.
1381
1382 procedure Remove_Vertex_And_Complement
1383 (G : Library_Graph;
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.
1391
1392 procedure Set_Component_Attributes
1393 (G : Library_Graph;
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
1398
1399 procedure Set_Corresponding_Vertex
1400 (G : Library_Graph;
1401 U_Id : Unit_Id;
1402 Val : Library_Graph_Vertex_Id);
1403 pragma Inline (Set_Corresponding_Vertex);
1404 -- Associate vertex Val of library graph G with unit U_Id
1405
1406 procedure Set_Is_Recorded_Cycle
1407 (G : Library_Graph;
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.
1413
1414 procedure Set_Is_Recorded_Edge
1415 (G : Library_Graph;
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.
1421
1422 procedure Set_LGC_Attributes
1423 (G : Library_Graph;
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
1428
1429 procedure Set_LGE_Attributes
1430 (G : Library_Graph;
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
1435
1436 procedure Set_LGV_Attributes
1437 (G : Library_Graph;
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
1442
1443 procedure Trace_Cycle
1444 (G : Library_Graph;
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.
1450
1451 procedure Trace_Edge
1452 (G : Library_Graph;
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.
1458
1459 procedure Trace_Eol;
1460 pragma Inline (Trace_Eol);
1461 -- Write an end-of-line to standard output
1462
1463 procedure Trace_Vertex
1464 (G : Library_Graph;
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.
1470
1471 procedure Update_Pending_Predecessors
1472 (Strong_Predecessors : in out Natural;
1473 Weak_Predecessors : in out Natural;
1474 Update_Weak : Boolean;
1475 Value : Integer);
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.
1480
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.
1485
1486 procedure Update_Pending_Predecessors_Of_Components
1487 (G : Library_Graph;
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.
1493
1494 -------------------------------
1495 -- Add_Body_Before_Spec_Edge --
1496 -------------------------------
1497
1498 procedure Add_Body_Before_Spec_Edge
1499 (G : Library_Graph;
1500 Vertex : Library_Graph_Vertex_Id;
1501 Edges : LGE_Lists.Doubly_Linked_List)
1502 is
1503 Edge : Library_Graph_Edge_Id;
1504
1505 begin
1506 pragma Assert (Present (G));
1507 pragma Assert (Present (Vertex));
1508 pragma Assert (LGE_Lists.Present (Edges));
1509
1510 -- A vertex requires a special Body_Before_Spec edge to its
1511 -- Corresponding_Item when it either denotes a
1512 --
1513 -- * Body that completes a previous spec
1514 --
1515 -- * Spec with a completing body
1516 --
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.
1520 --
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.
1526
1527 -- Assume that that no Body_Before_Spec is necessary
1528
1529 Edge := No_Library_Graph_Edge;
1530
1531 -- A body that completes a previous spec
1532
1533 if Is_Body_With_Spec (G, Vertex) then
1534 Edge :=
1535 Add_Edge_With_Return
1536 (G => G,
1537 Pred => Vertex, -- body
1538 Succ => Corresponding_Item (G, Vertex), -- spec
1539 Kind => Body_Before_Spec_Edge);
1540
1541 -- A spec with a completing body
1542
1543 elsif Is_Spec_With_Body (G, Vertex) then
1544 Edge :=
1545 Add_Edge_With_Return
1546 (G => G,
1547 Pred => Corresponding_Item (G, Vertex), -- body
1548 Succ => Vertex, -- spec
1549 Kind => Body_Before_Spec_Edge);
1550 end if;
1551
1552 if Present (Edge) then
1553 LGE_Lists.Append (Edges, Edge);
1554 end if;
1555 end Add_Body_Before_Spec_Edge;
1556
1557 --------------------------------
1558 -- Add_Body_Before_Spec_Edges --
1559 --------------------------------
1560
1561 procedure Add_Body_Before_Spec_Edges
1562 (G : Library_Graph;
1563 Edges : LGE_Lists.Doubly_Linked_List)
1564 is
1565 Iter : Elaborable_Units_Iterator;
1566 U_Id : Unit_Id;
1567
1568 begin
1569 pragma Assert (Present (G));
1570 pragma Assert (LGE_Lists.Present (Edges));
1571
1572 Iter := Iterate_Elaborable_Units;
1573 while Has_Next (Iter) loop
1574 Next (Iter, U_Id);
1575
1576 Add_Body_Before_Spec_Edge
1577 (G => G,
1578 Vertex => Corresponding_Vertex (G, U_Id),
1579 Edges => Edges);
1580 end loop;
1581 end Add_Body_Before_Spec_Edges;
1582
1583 ---------------
1584 -- Add_Cycle --
1585 ---------------
1586
1587 procedure Add_Cycle
1588 (G : Library_Graph;
1589 Attrs : Library_Graph_Cycle_Attributes;
1590 Indent : Indentation_Level)
1591 is
1592 Cycle : Library_Graph_Cycle_Id;
1593
1594 begin
1595 pragma Assert (Present (G));
1596
1597 -- Nothing to do when the cycle has already been recorded, possibly
1598 -- in a rotated form.
1599
1600 if Is_Recorded_Cycle (G, Attrs) then
1601 return;
1602 end if;
1603
1604 -- Mark the cycle as recorded. This prevents further attempts to add
1605 -- rotations of the same cycle.
1606
1607 Set_Is_Recorded_Cycle (G, Attrs);
1608
1609 -- Save the attributes of the cycle
1610
1611 Cycle := Sequence_Next_Cycle;
1612 Set_LGC_Attributes (G, Cycle, Attrs);
1613
1614 Trace_Cycle (G, Cycle, Indent);
1615
1616 -- Insert the cycle in the list of all cycle based on its precedence
1617
1618 Insert_And_Sort (G, Cycle);
1619 end Add_Cycle;
1620
1621 --------------
1622 -- Add_Edge --
1623 --------------
1624
1625 procedure Add_Edge
1626 (G : Library_Graph;
1627 Pred : Library_Graph_Vertex_Id;
1628 Succ : Library_Graph_Vertex_Id;
1629 Kind : Library_Graph_Edge_Kind)
1630 is
1631 Edge : Library_Graph_Edge_Id;
1632 pragma Unreferenced (Edge);
1633
1634 begin
1635 pragma Assert (Present (G));
1636 pragma Assert (Present (Pred));
1637 pragma Assert (Present (Succ));
1638 pragma Assert (Kind /= No_Edge);
1639
1640 Edge :=
1641 Add_Edge_With_Return
1642 (G => G,
1643 Pred => Pred,
1644 Succ => Succ,
1645 Kind => Kind);
1646 end Add_Edge;
1647
1648 --------------------------
1649 -- Add_Edge_With_Return --
1650 --------------------------
1651
1652 function Add_Edge_With_Return
1653 (G : Library_Graph;
1654 Pred : Library_Graph_Vertex_Id;
1655 Succ : Library_Graph_Vertex_Id;
1656 Kind : Library_Graph_Edge_Kind) return Library_Graph_Edge_Id
1657 is
1658 pragma Assert (Present (G));
1659 pragma Assert (Present (Pred));
1660 pragma Assert (Present (Succ));
1661 pragma Assert (Kind /= No_Edge);
1662
1663 Rel : constant Predecessor_Successor_Relation :=
1664 (Predecessor => Pred,
1665 Successor => Succ);
1666
1667 Edge : Library_Graph_Edge_Id;
1668
1669 begin
1670 -- Nothing to do when the predecessor and successor are already
1671 -- related by an edge.
1672
1673 if Is_Recorded_Edge (G, Rel) then
1674 return No_Library_Graph_Edge;
1675 end if;
1676
1677 Edge := Sequence_Next_Edge;
1678
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.
1682
1683 DG.Add_Edge
1684 (G => G.Graph,
1685 E => Edge,
1686 Source => Pred,
1687 Destination => Succ);
1688
1689 -- Construct and save the attributes of the edge
1690
1691 Set_LGE_Attributes
1692 (G => G,
1693 Edge => Edge,
1694 Val => (Kind => Kind));
1695
1696 -- Mark the predecessor and successor as related by the new edge.
1697 -- This prevents all further attempts to link the same predecessor
1698 -- and successor.
1699
1700 Set_Is_Recorded_Edge (G, Rel);
1701
1702 -- Update the number of pending predecessors the successor must wait
1703 -- on before it is elaborated.
1704
1705 Increment_Pending_Predecessors
1706 (G => G,
1707 Vertex => Succ,
1708 Edge => Edge);
1709
1710 -- Update the edge statistics
1711
1712 Increment_Library_Graph_Edge_Count (G, Kind);
1713
1714 return Edge;
1715 end Add_Edge_With_Return;
1716
1717 ----------------
1718 -- Add_Vertex --
1719 ----------------
1720
1721 procedure Add_Vertex
1722 (G : Library_Graph;
1723 U_Id : Unit_Id)
1724 is
1725 Vertex : Library_Graph_Vertex_Id;
1726
1727 begin
1728 pragma Assert (Present (G));
1729 pragma Assert (Present (U_Id));
1730
1731 -- Nothing to do when the unit already has a vertex
1732
1733 if Present (Corresponding_Vertex (G, U_Id)) then
1734 return;
1735 end if;
1736
1737 Vertex := Sequence_Next_Vertex;
1738
1739 -- Add the vertex to the underlying graph
1740
1741 DG.Add_Vertex (G.Graph, Vertex);
1742
1743 -- Construct and save the attributes of the vertex
1744
1745 Set_LGV_Attributes
1746 (G => G,
1747 Vertex => Vertex,
1748 Val =>
1749 (Corresponding_Item => No_Library_Graph_Vertex,
1750 In_Elaboration_Order => False,
1751 Pending_Strong_Predecessors => 0,
1752 Pending_Weak_Predecessors => 0,
1753 Unit => U_Id));
1754
1755 -- Associate the unit with its corresponding vertex
1756
1757 Set_Corresponding_Vertex (G, U_Id, Vertex);
1758 end Add_Vertex;
1759
1760 -------------------------------
1761 -- Add_Vertex_And_Complement --
1762 -------------------------------
1763
1764 procedure Add_Vertex_And_Complement
1765 (G : Library_Graph;
1766 Vertex : Library_Graph_Vertex_Id;
1767 Set : LGV_Sets.Membership_Set;
1768 Do_Complement : Boolean)
1769 is
1770 pragma Assert (Present (G));
1771 pragma Assert (Present (Vertex));
1772 pragma Assert (LGV_Sets.Present (Set));
1773
1774 Complement : constant Library_Graph_Vertex_Id :=
1775 Complementary_Vertex
1776 (G => G,
1777 Vertex => Vertex,
1778 Force_Complement => Do_Complement);
1779
1780 begin
1781 LGV_Sets.Insert (Set, Vertex);
1782
1783 if Present (Complement) then
1784 LGV_Sets.Insert (Set, Complement);
1785 end if;
1786 end Add_Vertex_And_Complement;
1787
1788 --------------------------
1789 -- Complementary_Vertex --
1790 --------------------------
1791
1792 function Complementary_Vertex
1793 (G : Library_Graph;
1794 Vertex : Library_Graph_Vertex_Id;
1795 Force_Complement : Boolean) return Library_Graph_Vertex_Id
1796 is
1797 Complement : Library_Graph_Vertex_Id;
1798
1799 begin
1800 pragma Assert (Present (G));
1801 pragma Assert (Present (Vertex));
1802
1803 -- Assume that there is no complementary vertex
1804
1805 Complement := No_Library_Graph_Vertex;
1806
1807 -- The caller requests the complement explicitly
1808
1809 if Force_Complement then
1810 Complement := Corresponding_Item (G, Vertex);
1811
1812 -- The vertex is a completing body of a spec subject to pragma
1813 -- Elaborate_Body. The complementary vertex is the spec.
1814
1815 elsif Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then
1816 Complement := Proper_Spec (G, Vertex);
1817
1818 -- The vertex is a spec subject to pragma Elaborate_Body. The
1819 -- complementary vertex is the body.
1820
1821 elsif Is_Spec_With_Elaborate_Body (G, Vertex) then
1822 Complement := Proper_Body (G, Vertex);
1823 end if;
1824
1825 return Complement;
1826 end Complementary_Vertex;
1827
1828 ---------------
1829 -- Component --
1830 ---------------
1831
1832 function Component
1833 (G : Library_Graph;
1834 Vertex : Library_Graph_Vertex_Id) return Component_Id
1835 is
1836 begin
1837 pragma Assert (Present (G));
1838 pragma Assert (Present (Vertex));
1839
1840 return DG.Component (G.Graph, Vertex);
1841 end Component;
1842
1843 ------------------------------------
1844 -- Contains_Weak_Static_Successor --
1845 ------------------------------------
1846
1847 function Contains_Weak_Static_Successor
1848 (G : Library_Graph;
1849 Cycle : Library_Graph_Cycle_Id) return Boolean
1850 is
1851 Edge : Library_Graph_Edge_Id;
1852 Iter : Edges_Of_Cycle_Iterator;
1853 Seen : Boolean;
1854
1855 begin
1856 pragma Assert (Present (G));
1857 pragma Assert (Present (Cycle));
1858
1859 -- Assume that no weak static successor has been seen
1860
1861 Seen := False;
1862
1863 -- IMPORTANT:
1864 --
1865 -- * The iteration must run to completion in order to unlock the
1866 -- edges of the cycle.
1867
1868 Iter := Iterate_Edges_Of_Cycle (G, Cycle);
1869 while Has_Next (Iter) loop
1870 Next (Iter, Edge);
1871
1872 if not Seen
1873 and then Is_Invocation_Edge (G, Edge)
1874 and then not Is_Dynamically_Elaborated (G, Successor (G, Edge))
1875 then
1876 Seen := True;
1877 end if;
1878 end loop;
1879
1880 return Seen;
1881 end Contains_Weak_Static_Successor;
1882
1883 ---------------------
1884 -- Copy_Cycle_Path --
1885 ---------------------
1886
1887 function Copy_Cycle_Path
1888 (Cycle_Path : LGE_Lists.Doubly_Linked_List)
1889 return LGE_Lists.Doubly_Linked_List
1890 is
1891 Edge : Library_Graph_Edge_Id;
1892 Iter : LGE_Lists.Iterator;
1893 Path : LGE_Lists.Doubly_Linked_List;
1894
1895 begin
1896 pragma Assert (LGE_Lists.Present (Cycle_Path));
1897
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);
1902
1903 LGE_Lists.Append (Path, Edge);
1904 end loop;
1905
1906 return Path;
1907 end Copy_Cycle_Path;
1908
1909 ------------------------
1910 -- Corresponding_Item --
1911 ------------------------
1912
1913 function Corresponding_Item
1914 (G : Library_Graph;
1915 Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
1916 is
1917 begin
1918 pragma Assert (Present (G));
1919 pragma Assert (Present (Vertex));
1920
1921 return Get_LGV_Attributes (G, Vertex).Corresponding_Item;
1922 end Corresponding_Item;
1923
1924 --------------------------
1925 -- Corresponding_Vertex --
1926 --------------------------
1927
1928 function Corresponding_Vertex
1929 (G : Library_Graph;
1930 U_Id : Unit_Id) return Library_Graph_Vertex_Id
1931 is
1932 begin
1933 pragma Assert (Present (G));
1934 pragma Assert (Present (U_Id));
1935
1936 return Unit_Tables.Get (G.Unit_To_Vertex, U_Id);
1937 end Corresponding_Vertex;
1938
1939 ------------
1940 -- Create --
1941 ------------
1942
1943 function Create
1944 (Initial_Vertices : Positive;
1945 Initial_Edges : Positive) return Library_Graph
1946 is
1947 G : constant Library_Graph := new Library_Graph_Attributes;
1948
1949 begin
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);
1954 G.Graph :=
1955 DG.Create
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);
1962
1963 return G;
1964 end Create;
1965
1966 -------------------
1967 -- Cycle_Kind_Of --
1968 -------------------
1969
1970 function Cycle_Kind_Of
1971 (G : Library_Graph;
1972 Edge : Library_Graph_Edge_Id) return Library_Graph_Cycle_Kind
1973 is
1974 pragma Assert (Present (G));
1975 pragma Assert (Present (Edge));
1976
1977 begin
1978 if Is_Cyclic_Elaborate_All_Edge (G, Edge) then
1979 return Elaborate_All_Cycle;
1980
1981 elsif Is_Cyclic_Elaborate_Body_Edge (G, Edge) then
1982 return Elaborate_Body_Cycle;
1983
1984 elsif Is_Cyclic_Elaborate_Edge (G, Edge) then
1985 return Elaborate_Cycle;
1986
1987 elsif Is_Cyclic_Forced_Edge (G, Edge) then
1988 return Forced_Cycle;
1989
1990 elsif Is_Cyclic_Invocation_Edge (G, Edge) then
1991 return Invocation_Cycle;
1992
1993 else
1994 return No_Cycle_Kind;
1995 end if;
1996 end Cycle_Kind_Of;
1997
1998 ----------------------------------------
1999 -- Decrement_Library_Graph_Edge_Count --
2000 ----------------------------------------
2001
2002 procedure Decrement_Library_Graph_Edge_Count
2003 (G : Library_Graph;
2004 Kind : Library_Graph_Edge_Kind)
2005 is
2006 pragma Assert (Present (G));
2007
2008 Count : Natural renames G.Counts (Kind);
2009
2010 begin
2011 Count := Count - 1;
2012 end Decrement_Library_Graph_Edge_Count;
2013
2014 ------------------------------------
2015 -- Decrement_Pending_Predecessors --
2016 ------------------------------------
2017
2018 procedure Decrement_Pending_Predecessors
2019 (G : Library_Graph;
2020 Comp : Component_Id;
2021 Edge : Library_Graph_Edge_Id)
2022 is
2023 Attrs : Component_Attributes;
2024
2025 begin
2026 pragma Assert (Present (G));
2027 pragma Assert (Present (Comp));
2028
2029 Attrs := Get_Component_Attributes (G, Comp);
2030
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),
2035 Value => -1);
2036
2037 Set_Component_Attributes (G, Comp, Attrs);
2038 end Decrement_Pending_Predecessors;
2039
2040 ------------------------------------
2041 -- Decrement_Pending_Predecessors --
2042 ------------------------------------
2043
2044 procedure Decrement_Pending_Predecessors
2045 (G : Library_Graph;
2046 Vertex : Library_Graph_Vertex_Id;
2047 Edge : Library_Graph_Edge_Id)
2048 is
2049 Attrs : Library_Graph_Vertex_Attributes;
2050
2051 begin
2052 pragma Assert (Present (G));
2053 pragma Assert (Present (Vertex));
2054
2055 Attrs := Get_LGV_Attributes (G, Vertex);
2056
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),
2061 Value => -1);
2062
2063 Set_LGV_Attributes (G, Vertex, Attrs);
2064 end Decrement_Pending_Predecessors;
2065
2066 -----------------------------------
2067 -- Delete_Body_Before_Spec_Edges --
2068 -----------------------------------
2069
2070 procedure Delete_Body_Before_Spec_Edges
2071 (G : Library_Graph;
2072 Edges : LGE_Lists.Doubly_Linked_List)
2073 is
2074 Edge : Library_Graph_Edge_Id;
2075 Iter : LGE_Lists.Iterator;
2076
2077 begin
2078 pragma Assert (Present (G));
2079 pragma Assert (LGE_Lists.Present (Edges));
2080
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);
2085
2086 Delete_Edge (G, Edge);
2087 end loop;
2088 end Delete_Body_Before_Spec_Edges;
2089
2090 -----------------
2091 -- Delete_Edge --
2092 -----------------
2093
2094 procedure Delete_Edge
2095 (G : Library_Graph;
2096 Edge : Library_Graph_Edge_Id)
2097 is
2098 pragma Assert (Present (G));
2099 pragma Assert (Present (Edge));
2100
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,
2105 Successor => Succ);
2106
2107 begin
2108 -- Update the edge statistics
2109
2110 Decrement_Library_Graph_Edge_Count (G, Kind (G, Edge));
2111
2112 -- Update the number of pending predecessors the successor must wait
2113 -- on before it is elaborated.
2114
2115 Decrement_Pending_Predecessors
2116 (G => G,
2117 Vertex => Succ,
2118 Edge => Edge);
2119
2120 -- Delete the link between the predecessor and successor. This allows
2121 -- for further attempts to link the same predecessor and successor.
2122
2123 RE_Sets.Delete (G.Recorded_Edges, Rel);
2124
2125 -- Delete the attributes of the edge
2126
2127 LGE_Tables.Delete (G.Edge_Attributes, Edge);
2128
2129 -- Delete the edge from the underlying graph
2130
2131 DG.Delete_Edge (G.Graph, Edge);
2132 end Delete_Edge;
2133
2134 -------------
2135 -- Destroy --
2136 -------------
2137
2138 procedure Destroy (G : in out Library_Graph) is
2139 begin
2140 pragma Assert (Present (G));
2141
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);
2151
2152 Free (G);
2153 end Destroy;
2154
2155 ----------------------------------
2156 -- Destroy_Component_Attributes --
2157 ----------------------------------
2158
2159 procedure Destroy_Component_Attributes
2160 (Attrs : in out Component_Attributes)
2161 is
2162 pragma Unreferenced (Attrs);
2163 begin
2164 null;
2165 end Destroy_Component_Attributes;
2166
2167 --------------------------------------------
2168 -- Destroy_Library_Graph_Cycle_Attributes --
2169 --------------------------------------------
2170
2171 procedure Destroy_Library_Graph_Cycle_Attributes
2172 (Attrs : in out Library_Graph_Cycle_Attributes)
2173 is
2174 begin
2175 LGE_Lists.Destroy (Attrs.Path);
2176 end Destroy_Library_Graph_Cycle_Attributes;
2177
2178 -------------------------------------------
2179 -- Destroy_Library_Graph_Edge_Attributes --
2180 -------------------------------------------
2181
2182 procedure Destroy_Library_Graph_Edge_Attributes
2183 (Attrs : in out Library_Graph_Edge_Attributes)
2184 is
2185 pragma Unreferenced (Attrs);
2186 begin
2187 null;
2188 end Destroy_Library_Graph_Edge_Attributes;
2189
2190 ----------------------------------
2191 -- Destroy_Library_Graph_Vertex --
2192 ----------------------------------
2193
2194 procedure Destroy_Library_Graph_Vertex
2195 (Vertex : in out Library_Graph_Vertex_Id)
2196 is
2197 pragma Unreferenced (Vertex);
2198 begin
2199 null;
2200 end Destroy_Library_Graph_Vertex;
2201
2202 ---------------------------------------------
2203 -- Destroy_Library_Graph_Vertex_Attributes --
2204 ---------------------------------------------
2205
2206 procedure Destroy_Library_Graph_Vertex_Attributes
2207 (Attrs : in out Library_Graph_Vertex_Attributes)
2208 is
2209 pragma Unreferenced (Attrs);
2210 begin
2211 null;
2212 end Destroy_Library_Graph_Vertex_Attributes;
2213
2214 ---------------
2215 -- File_Name --
2216 ---------------
2217
2218 function File_Name
2219 (G : Library_Graph;
2220 Vertex : Library_Graph_Vertex_Id) return File_Name_Type
2221 is
2222 begin
2223 pragma Assert (Present (G));
2224 pragma Assert (Present (Vertex));
2225
2226 return File_Name (Unit (G, Vertex));
2227 end File_Name;
2228
2229 ------------------------------------
2230 -- Find_All_Cycles_Through_Vertex --
2231 ------------------------------------
2232
2233 procedure Find_All_Cycles_Through_Vertex
2234 (G : Library_Graph;
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)
2243 is
2244 Edge_Indent : constant Indentation_Level :=
2245 Indent + Nested_Indentation;
2246
2247 Iter : Edges_To_Successors_Iterator;
2248 Next_Edge : Library_Graph_Edge_Id;
2249
2250 begin
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));
2256
2257 -- Nothing to do when there is no vertex
2258
2259 if not Present (Vertex) then
2260 return;
2261 end if;
2262
2263 Trace_Vertex (G, Vertex, Indent);
2264
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.
2268
2269 if LGV_Sets.Contains (End_Vertices, Vertex) then
2270 Normalize_And_Add_Cycle
2271 (G => G,
2272 Most_Significant_Edge => Most_Significant_Edge,
2273 Invocation_Edge_Count => Invocation_Edge_Count,
2274 Cycle_Path => Cycle_Path,
2275 Indent => Indent + Nested_Indentation);
2276
2277 -- Otherwise extend the search for a cycle only when the vertex has
2278 -- not been visited yet.
2279
2280 elsif not LGV_Sets.Contains (Visited_Vertices, Vertex) then
2281
2282 -- Prepare for vertex backtracking
2283
2284 LGV_Sets.Insert (Visited_Vertices, Vertex);
2285
2286 -- Extend the search via all edges to successors of the vertex
2287
2288 Iter := Iterate_Edges_To_Successors (G, Vertex);
2289 while Has_Next (Iter) loop
2290 Next (Iter, Next_Edge);
2291
2292 if Is_Cyclic_Edge (G, Next_Edge) then
2293 Trace_Edge (G, Next_Edge, Edge_Indent);
2294
2295 -- Prepare for edge backtracking. Prepending ensures that
2296 -- final ordering of edges can be traversed from successor
2297 -- to predecessor.
2298
2299 LGE_Lists.Prepend (Cycle_Path, Next_Edge);
2300
2301 -- Extend the search via the successor of the next edge
2302
2303 Find_All_Cycles_Through_Vertex
2304 (G => G,
2305 Vertex => Successor (G, Next_Edge),
2306 End_Vertices => End_Vertices,
2307
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.
2311
2312 Most_Significant_Edge =>
2313 Highest_Precedence_Edge
2314 (G => G,
2315 Left => Next_Edge,
2316 Right => Most_Significant_Edge),
2317
2318 -- The next edge may be an invocation edge, in which case
2319 -- the count of invocation edges increases by one.
2320
2321 Invocation_Edge_Count =>
2322 Maximum_Invocation_Edge_Count
2323 (G => G,
2324 Edge => Next_Edge,
2325 Count => Invocation_Edge_Count),
2326 Spec_And_Body_Together => Spec_And_Body_Together,
2327 Cycle_Path => Cycle_Path,
2328 Visited_Vertices => Visited_Vertices,
2329 Indent => Indent);
2330
2331 -- Backtrack the edge
2332
2333 LGE_Lists.Delete_First (Cycle_Path);
2334 end if;
2335 end loop;
2336
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.
2340
2341 Find_All_Cycles_Through_Vertex
2342 (G => G,
2343 Vertex =>
2344 Complementary_Vertex
2345 (G => G,
2346 Vertex => 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,
2354 Indent => Indent);
2355
2356 -- Backtrack the vertex
2357
2358 LGV_Sets.Delete (Visited_Vertices, Vertex);
2359 end if;
2360 end Find_All_Cycles_Through_Vertex;
2361
2362 -------------------------------
2363 -- Find_All_Cycles_With_Edge --
2364 -------------------------------
2365
2366 procedure Find_All_Cycles_With_Edge
2367 (G : Library_Graph;
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)
2373 is
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));
2378
2379 Pred : constant Library_Graph_Vertex_Id :=
2380 Predecessor (G, Initial_Edge);
2381 Succ : constant Library_Graph_Vertex_Id :=
2382 Successor (G, Initial_Edge);
2383
2384 End_Vertices : LGV_Sets.Membership_Set;
2385
2386 begin
2387 Trace_Edge (G, Initial_Edge, Indent);
2388
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.
2392
2393 End_Vertices := LGV_Sets.Create (2);
2394 Add_Vertex_And_Complement
2395 (G => G,
2396 Vertex => Pred,
2397 Set => End_Vertices,
2398 Do_Complement => Spec_And_Body_Together);
2399
2400 -- Prepare for edge backtracking
2401 --
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
2406 -- for diagnostics.
2407
2408 LGE_Lists.Prepend (Cycle_Path, Initial_Edge);
2409
2410 -- Prepare for vertex backtracking
2411 --
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
2415 -- recursion.
2416
2417 Add_Vertex_And_Complement
2418 (G => G,
2419 Vertex => Pred,
2420 Set => Visited_Vertices,
2421 Do_Complement => Spec_And_Body_Together);
2422
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.
2426
2427 Find_All_Cycles_Through_Vertex
2428 (G => G,
2429 Vertex => Succ,
2430 End_Vertices => End_Vertices,
2431 Most_Significant_Edge => Initial_Edge,
2432 Invocation_Edge_Count =>
2433 Maximum_Invocation_Edge_Count
2434 (G => G,
2435 Edge => Initial_Edge,
2436 Count => 0),
2437 Spec_And_Body_Together => Spec_And_Body_Together,
2438 Cycle_Path => Cycle_Path,
2439 Visited_Vertices => Visited_Vertices,
2440 Indent => Indent + Nested_Indentation);
2441
2442 -- Backtrack the edge
2443
2444 LGE_Lists.Delete_First (Cycle_Path);
2445
2446 -- Backtrack the predecessor, along with the complement vertex in the
2447 -- Elaborate_All and Elaborate_Body cases.
2448
2449 Remove_Vertex_And_Complement
2450 (G => G,
2451 Vertex => Pred,
2452 Set => Visited_Vertices,
2453 Do_Complement => Spec_And_Body_Together);
2454
2455 LGV_Sets.Destroy (End_Vertices);
2456 end Find_All_Cycles_With_Edge;
2457
2458 ---------------------
2459 -- Find_Components --
2460 ---------------------
2461
2462 procedure Find_Components (G : Library_Graph) is
2463 Edges : LGE_Lists.Doubly_Linked_List;
2464
2465 begin
2466 pragma Assert (Present (G));
2467
2468 -- Initialize or reinitialize the components of the graph
2469
2470 Initialize_Components (G);
2471
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.
2476
2477 Edges := LGE_Lists.Create;
2478 Add_Body_Before_Spec_Edges (G, Edges);
2479
2480 DG.Find_Components (G.Graph);
2481
2482 -- Remove the special edges that link a predecessor body with a
2483 -- successor spec because they cause unresolvable circularities.
2484
2485 Delete_Body_Before_Spec_Edges (G, Edges);
2486 LGE_Lists.Destroy (Edges);
2487
2488 -- Update the number of predecessors various components must wait on
2489 -- before they can be elaborated.
2490
2491 Update_Pending_Predecessors_Of_Components (G);
2492 end Find_Components;
2493
2494 -----------------
2495 -- Find_Cycles --
2496 -----------------
2497
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;
2503
2504 begin
2505 pragma Assert (Present (G));
2506
2507 -- Use a list of edges to describe the path of a cycle
2508
2509 Cycle_Path := LGE_Lists.Create;
2510
2511 -- Use a set of visited vertices to prevent infinite traversal of the
2512 -- graph.
2513
2514 Visited_Vertices := LGV_Sets.Create (Number_Of_Vertices (G));
2515
2516 -- Inspect all edges, trying to find an edge that links two vertices
2517 -- in the same component.
2518
2519 Iter := Iterate_All_Edges (G);
2520 while Has_Next (Iter) loop
2521 Next (Iter, Edge);
2522
2523 -- Find all cycles involving the current edge. Duplicate cycles in
2524 -- the forms of rotations are not saved for diagnostic purposes.
2525
2526 if Is_Cycle_Initiating_Edge (G, Edge) then
2527 Find_All_Cycles_With_Edge
2528 (G => G,
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);
2534
2535 Trace_Eol;
2536 end if;
2537 end loop;
2538
2539 LGE_Lists.Destroy (Cycle_Path);
2540 LGV_Sets.Destroy (Visited_Vertices);
2541 end Find_Cycles;
2542
2543 ---------------------------------------
2544 -- Find_First_Lower_Precedence_Cycle --
2545 ---------------------------------------
2546
2547 function Find_First_Lower_Precedence_Cycle
2548 (G : Library_Graph;
2549 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Id
2550 is
2551 Current_Cycle : Library_Graph_Cycle_Id;
2552 Iter : All_Cycle_Iterator;
2553 Lesser_Cycle : Library_Graph_Cycle_Id;
2554
2555 begin
2556 pragma Assert (Present (G));
2557 pragma Assert (Present (Cycle));
2558
2559 -- Assume that there is no lesser cycle
2560
2561 Lesser_Cycle := No_Library_Graph_Cycle;
2562
2563 -- Find a cycle with a slightly lower precedence than the input
2564 -- cycle.
2565 --
2566 -- IMPORTANT:
2567 --
2568 -- * The iterator must run to completion in order to unlock the
2569 -- list of all cycles.
2570
2571 Iter := Iterate_All_Cycles (G);
2572 while Has_Next (Iter) loop
2573 Next (Iter, Current_Cycle);
2574
2575 if not Present (Lesser_Cycle)
2576 and then Precedence
2577 (G => G,
2578 Cycle => Cycle,
2579 Compared_To => Current_Cycle) = Higher_Precedence
2580 then
2581 Lesser_Cycle := Current_Cycle;
2582 end if;
2583 end loop;
2584
2585 return Lesser_Cycle;
2586 end Find_First_Lower_Precedence_Cycle;
2587
2588 ------------------------------
2589 -- Get_Component_Attributes --
2590 ------------------------------
2591
2592 function Get_Component_Attributes
2593 (G : Library_Graph;
2594 Comp : Component_Id) return Component_Attributes
2595 is
2596 begin
2597 pragma Assert (Present (G));
2598 pragma Assert (Present (Comp));
2599
2600 return Component_Tables.Get (G.Component_Attributes, Comp);
2601 end Get_Component_Attributes;
2602
2603 ------------------------
2604 -- Get_LGC_Attributes --
2605 ------------------------
2606
2607 function Get_LGC_Attributes
2608 (G : Library_Graph;
2609 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Attributes
2610 is
2611 begin
2612 pragma Assert (Present (G));
2613 pragma Assert (Present (Cycle));
2614
2615 return LGC_Tables.Get (G.Cycle_Attributes, Cycle);
2616 end Get_LGC_Attributes;
2617
2618 ------------------------
2619 -- Get_LGE_Attributes --
2620 ------------------------
2621
2622 function Get_LGE_Attributes
2623 (G : Library_Graph;
2624 Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Attributes
2625 is
2626 begin
2627 pragma Assert (Present (G));
2628 pragma Assert (Present (Edge));
2629
2630 return LGE_Tables.Get (G.Edge_Attributes, Edge);
2631 end Get_LGE_Attributes;
2632
2633 ------------------------
2634 -- Get_LGV_Attributes --
2635 ------------------------
2636
2637 function Get_LGV_Attributes
2638 (G : Library_Graph;
2639 Vertex : Library_Graph_Vertex_Id)
2640 return Library_Graph_Vertex_Attributes
2641 is
2642 begin
2643 pragma Assert (Present (G));
2644 pragma Assert (Present (Vertex));
2645
2646 return LGV_Tables.Get (G.Vertex_Attributes, Vertex);
2647 end Get_LGV_Attributes;
2648
2649 -----------------------------
2650 -- Has_Elaborate_All_Cycle --
2651 -----------------------------
2652
2653 function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean is
2654 Edge : Library_Graph_Edge_Id;
2655 Iter : All_Edge_Iterator;
2656 Seen : Boolean;
2657
2658 begin
2659 pragma Assert (Present (G));
2660
2661 -- Assume that no cyclic Elaborate_All edge has been seen
2662
2663 Seen := False;
2664
2665 -- IMPORTANT:
2666 --
2667 -- * The iteration must run to completion in order to unlock the
2668 -- graph.
2669
2670 Iter := Iterate_All_Edges (G);
2671 while Has_Next (Iter) loop
2672 Next (Iter, Edge);
2673
2674 if not Seen and then Is_Cyclic_Elaborate_All_Edge (G, Edge) then
2675 Seen := True;
2676 end if;
2677 end loop;
2678
2679 return Seen;
2680 end Has_Elaborate_All_Cycle;
2681
2682 ------------------------
2683 -- Has_Elaborate_Body --
2684 ------------------------
2685
2686 function Has_Elaborate_Body
2687 (G : Library_Graph;
2688 Vertex : Library_Graph_Vertex_Id) return Boolean
2689 is
2690 pragma Assert (Present (G));
2691 pragma Assert (Present (Vertex));
2692
2693 U_Id : constant Unit_Id := Unit (G, Vertex);
2694 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
2695
2696 begin
2697 -- Treat the spec and body as decoupled when switch -d_b (ignore the
2698 -- effects of pragma Elaborate_Body) is in effect.
2699
2700 return U_Rec.Elaborate_Body and not Debug_Flag_Underscore_B;
2701 end Has_Elaborate_Body;
2702
2703 --------------
2704 -- Has_Next --
2705 --------------
2706
2707 function Has_Next (Iter : All_Cycle_Iterator) return Boolean is
2708 begin
2709 return LGC_Lists.Has_Next (LGC_Lists.Iterator (Iter));
2710 end Has_Next;
2711
2712 --------------
2713 -- Has_Next --
2714 --------------
2715
2716 function Has_Next (Iter : All_Edge_Iterator) return Boolean is
2717 begin
2718 return DG.Has_Next (DG.All_Edge_Iterator (Iter));
2719 end Has_Next;
2720
2721 --------------
2722 -- Has_Next --
2723 --------------
2724
2725 function Has_Next (Iter : All_Vertex_Iterator) return Boolean is
2726 begin
2727 return DG.Has_Next (DG.All_Vertex_Iterator (Iter));
2728 end Has_Next;
2729
2730 --------------
2731 -- Has_Next --
2732 --------------
2733
2734 function Has_Next (Iter : Component_Iterator) return Boolean is
2735 begin
2736 return DG.Has_Next (DG.Component_Iterator (Iter));
2737 end Has_Next;
2738
2739 --------------
2740 -- Has_Next --
2741 --------------
2742
2743 function Has_Next (Iter : Component_Vertex_Iterator) return Boolean is
2744 begin
2745 return DG.Has_Next (DG.Component_Vertex_Iterator (Iter));
2746 end Has_Next;
2747
2748 --------------
2749 -- Has_Next --
2750 --------------
2751
2752 function Has_Next (Iter : Edges_Of_Cycle_Iterator) return Boolean is
2753 begin
2754 return LGE_Lists.Has_Next (LGE_Lists.Iterator (Iter));
2755 end Has_Next;
2756
2757 --------------
2758 -- Has_Next --
2759 --------------
2760
2761 function Has_Next (Iter : Edges_To_Successors_Iterator) return Boolean is
2762 begin
2763 return DG.Has_Next (DG.Outgoing_Edge_Iterator (Iter));
2764 end Has_Next;
2765
2766 -----------------------------------------
2767 -- Hash_Library_Graph_Cycle_Attributes --
2768 -----------------------------------------
2769
2770 function Hash_Library_Graph_Cycle_Attributes
2771 (Attrs : Library_Graph_Cycle_Attributes) return Bucket_Range_Type
2772 is
2773 Edge : Library_Graph_Edge_Id;
2774 Hash : Bucket_Range_Type;
2775 Iter : LGE_Lists.Iterator;
2776
2777 begin
2778 pragma Assert (LGE_Lists.Present (Attrs.Path));
2779
2780 -- The hash is obtained in the following manner:
2781 --
2782 -- (((edge1 * 31) + edge2) * 31) + edgeN
2783
2784 Hash := 0;
2785 Iter := LGE_Lists.Iterate (Attrs.Path);
2786 while LGE_Lists.Has_Next (Iter) loop
2787 LGE_Lists.Next (Iter, Edge);
2788
2789 Hash := (Hash * 31) + Bucket_Range_Type (Edge);
2790 end loop;
2791
2792 return Hash;
2793 end Hash_Library_Graph_Cycle_Attributes;
2794
2795 -----------------------------------------
2796 -- Hash_Predecessor_Successor_Relation --
2797 -----------------------------------------
2798
2799 function Hash_Predecessor_Successor_Relation
2800 (Rel : Predecessor_Successor_Relation) return Bucket_Range_Type
2801 is
2802 begin
2803 pragma Assert (Present (Rel.Predecessor));
2804 pragma Assert (Present (Rel.Successor));
2805
2806 return
2807 Hash_Two_Keys
2808 (Bucket_Range_Type (Rel.Predecessor),
2809 Bucket_Range_Type (Rel.Successor));
2810 end Hash_Predecessor_Successor_Relation;
2811
2812 ------------------------------
2813 -- Highest_Precedence_Cycle --
2814 ------------------------------
2815
2816 function Highest_Precedence_Cycle
2817 (G : Library_Graph) return Library_Graph_Cycle_Id
2818 is
2819 begin
2820 pragma Assert (Present (G));
2821 pragma Assert (LGC_Lists.Present (G.Cycles));
2822
2823 if LGC_Lists.Is_Empty (G.Cycles) then
2824 return No_Library_Graph_Cycle;
2825
2826 -- The highest precedence cycle is always the first in the list of
2827 -- all cycles.
2828
2829 else
2830 return LGC_Lists.First (G.Cycles);
2831 end if;
2832 end Highest_Precedence_Cycle;
2833
2834 -----------------------------
2835 -- Highest_Precedence_Edge --
2836 -----------------------------
2837
2838 function Highest_Precedence_Edge
2839 (G : Library_Graph;
2840 Left : Library_Graph_Edge_Id;
2841 Right : Library_Graph_Edge_Id) return Library_Graph_Edge_Id
2842 is
2843 Edge_Prec : Precedence_Kind;
2844
2845 begin
2846 pragma Assert (Present (G));
2847
2848 -- Both edges are available, pick the one with highest precedence
2849
2850 if Present (Left) and then Present (Right) then
2851 Edge_Prec :=
2852 Precedence
2853 (G => G,
2854 Edge => Left,
2855 Compared_To => Right);
2856
2857 if Edge_Prec = Higher_Precedence then
2858 return Left;
2859
2860 -- The precedence rules for edges are such that no two edges can
2861 -- ever have the same precedence.
2862
2863 else
2864 pragma Assert (Edge_Prec = Lower_Precedence);
2865 return Right;
2866 end if;
2867
2868 -- Otherwise at least one edge must be present
2869
2870 elsif Present (Left) then
2871 return Left;
2872
2873 else
2874 pragma Assert (Present (Right));
2875
2876 return Right;
2877 end if;
2878 end Highest_Precedence_Edge;
2879
2880 --------------------------
2881 -- In_Elaboration_Order --
2882 --------------------------
2883
2884 function In_Elaboration_Order
2885 (G : Library_Graph;
2886 Vertex : Library_Graph_Vertex_Id) return Boolean
2887 is
2888 begin
2889 pragma Assert (Present (G));
2890 pragma Assert (Present (Vertex));
2891
2892 return Get_LGV_Attributes (G, Vertex).In_Elaboration_Order;
2893 end In_Elaboration_Order;
2894
2895 -----------------------
2896 -- In_Same_Component --
2897 -----------------------
2898
2899 function In_Same_Component
2900 (G : Library_Graph;
2901 Left : Library_Graph_Vertex_Id;
2902 Right : Library_Graph_Vertex_Id) return Boolean
2903 is
2904 begin
2905 pragma Assert (Present (G));
2906 pragma Assert (Present (Left));
2907 pragma Assert (Present (Right));
2908
2909 return Component (G, Left) = Component (G, Right);
2910 end In_Same_Component;
2911
2912 ----------------------------------------
2913 -- Increment_Library_Graph_Edge_Count --
2914 ----------------------------------------
2915
2916 procedure Increment_Library_Graph_Edge_Count
2917 (G : Library_Graph;
2918 Kind : Library_Graph_Edge_Kind)
2919 is
2920 pragma Assert (Present (G));
2921
2922 Count : Natural renames G.Counts (Kind);
2923
2924 begin
2925 Count := Count + 1;
2926 end Increment_Library_Graph_Edge_Count;
2927
2928 ------------------------------------
2929 -- Increment_Pending_Predecessors --
2930 ------------------------------------
2931
2932 procedure Increment_Pending_Predecessors
2933 (G : Library_Graph;
2934 Comp : Component_Id;
2935 Edge : Library_Graph_Edge_Id)
2936 is
2937 Attrs : Component_Attributes;
2938
2939 begin
2940 pragma Assert (Present (G));
2941 pragma Assert (Present (Comp));
2942
2943 Attrs := Get_Component_Attributes (G, Comp);
2944
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),
2949 Value => 1);
2950
2951 Set_Component_Attributes (G, Comp, Attrs);
2952 end Increment_Pending_Predecessors;
2953
2954 ------------------------------------
2955 -- Increment_Pending_Predecessors --
2956 ------------------------------------
2957
2958 procedure Increment_Pending_Predecessors
2959 (G : Library_Graph;
2960 Vertex : Library_Graph_Vertex_Id;
2961 Edge : Library_Graph_Edge_Id)
2962 is
2963 Attrs : Library_Graph_Vertex_Attributes;
2964
2965 begin
2966 pragma Assert (Present (G));
2967 pragma Assert (Present (Vertex));
2968
2969 Attrs := Get_LGV_Attributes (G, Vertex);
2970
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),
2975 Value => 1);
2976
2977 Set_LGV_Attributes (G, Vertex, Attrs);
2978 end Increment_Pending_Predecessors;
2979
2980 ---------------------------
2981 -- Initialize_Components --
2982 ---------------------------
2983
2984 procedure Initialize_Components (G : Library_Graph) is
2985 begin
2986 pragma Assert (Present (G));
2987
2988 -- The graph already contains a set of components. Reinitialize
2989 -- them in order to accommodate the new set of components about to
2990 -- be computed.
2991
2992 if Number_Of_Components (G) > 0 then
2993 Component_Tables.Destroy (G.Component_Attributes);
2994
2995 G.Component_Attributes :=
2996 Component_Tables.Create (Number_Of_Vertices (G));
2997 end if;
2998 end Initialize_Components;
2999
3000 ---------------------
3001 -- Insert_And_Sort --
3002 ---------------------
3003
3004 procedure Insert_And_Sort
3005 (G : Library_Graph;
3006 Cycle : Library_Graph_Cycle_Id)
3007 is
3008 Lesser_Cycle : Library_Graph_Cycle_Id;
3009
3010 begin
3011 pragma Assert (Present (G));
3012 pragma Assert (Present (Cycle));
3013 pragma Assert (LGC_Lists.Present (G.Cycles));
3014
3015 -- The input cycle is the first to be inserted
3016
3017 if LGC_Lists.Is_Empty (G.Cycles) then
3018 LGC_Lists.Prepend (G.Cycles, Cycle);
3019
3020 -- Otherwise the list of all cycles contains at least one cycle.
3021 -- Insert the input cycle based on its precedence.
3022
3023 else
3024 Lesser_Cycle := Find_First_Lower_Precedence_Cycle (G, Cycle);
3025
3026 -- The list contains at least one cycle, and the input cycle has a
3027 -- higher precedence compared to some cycle in the list.
3028
3029 if Present (Lesser_Cycle) then
3030 LGC_Lists.Insert_Before
3031 (L => G.Cycles,
3032 Before => Lesser_Cycle,
3033 Elem => Cycle);
3034
3035 -- Otherwise the input cycle has the lowest precedence among all
3036 -- cycles.
3037
3038 else
3039 LGC_Lists.Append (G.Cycles, Cycle);
3040 end if;
3041 end if;
3042 end Insert_And_Sort;
3043
3044 ---------------------------
3045 -- Invocation_Edge_Count --
3046 ---------------------------
3047
3048 function Invocation_Edge_Count
3049 (G : Library_Graph;
3050 Cycle : Library_Graph_Cycle_Id) return Natural
3051 is
3052 begin
3053 pragma Assert (Present (G));
3054 pragma Assert (Present (Cycle));
3055
3056 return Get_LGC_Attributes (G, Cycle).Invocation_Edge_Count;
3057 end Invocation_Edge_Count;
3058
3059 -------------------------------
3060 -- Invocation_Graph_Encoding --
3061 -------------------------------
3062
3063 function Invocation_Graph_Encoding
3064 (G : Library_Graph;
3065 Vertex : Library_Graph_Vertex_Id)
3066 return Invocation_Graph_Encoding_Kind
3067 is
3068 begin
3069 pragma Assert (Present (G));
3070 pragma Assert (Present (Vertex));
3071
3072 return Invocation_Graph_Encoding (Unit (G, Vertex));
3073 end Invocation_Graph_Encoding;
3074
3075 -------------
3076 -- Is_Body --
3077 -------------
3078
3079 function Is_Body
3080 (G : Library_Graph;
3081 Vertex : Library_Graph_Vertex_Id) return Boolean
3082 is
3083 pragma Assert (Present (G));
3084 pragma Assert (Present (Vertex));
3085
3086 U_Id : constant Unit_Id := Unit (G, Vertex);
3087 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3088
3089 begin
3090 return U_Rec.Utype = Is_Body or else U_Rec.Utype = Is_Body_Only;
3091 end Is_Body;
3092
3093 -----------------------------------------
3094 -- Is_Body_Of_Spec_With_Elaborate_Body --
3095 -----------------------------------------
3096
3097 function Is_Body_Of_Spec_With_Elaborate_Body
3098 (G : Library_Graph;
3099 Vertex : Library_Graph_Vertex_Id) return Boolean
3100 is
3101 begin
3102 pragma Assert (Present (G));
3103 pragma Assert (Present (Vertex));
3104
3105 if Is_Body_With_Spec (G, Vertex) then
3106 return
3107 Is_Spec_With_Elaborate_Body
3108 (G => G,
3109 Vertex => Proper_Spec (G, Vertex));
3110 end if;
3111
3112 return False;
3113 end Is_Body_Of_Spec_With_Elaborate_Body;
3114
3115 -----------------------
3116 -- Is_Body_With_Spec --
3117 -----------------------
3118
3119 function Is_Body_With_Spec
3120 (G : Library_Graph;
3121 Vertex : Library_Graph_Vertex_Id) return Boolean
3122 is
3123 pragma Assert (Present (G));
3124 pragma Assert (Present (Vertex));
3125
3126 U_Id : constant Unit_Id := Unit (G, Vertex);
3127 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3128
3129 begin
3130 return U_Rec.Utype = Is_Body;
3131 end Is_Body_With_Spec;
3132
3133 ------------------------------
3134 -- Is_Cycle_Initiating_Edge --
3135 ------------------------------
3136
3137 function Is_Cycle_Initiating_Edge
3138 (G : Library_Graph;
3139 Edge : Library_Graph_Edge_Id) return Boolean
3140 is
3141 begin
3142 pragma Assert (Present (G));
3143 pragma Assert (Present (Edge));
3144
3145 return
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;
3152
3153 --------------------
3154 -- Is_Cyclic_Edge --
3155 --------------------
3156
3157 function Is_Cyclic_Edge
3158 (G : Library_Graph;
3159 Edge : Library_Graph_Edge_Id) return Boolean
3160 is
3161 begin
3162 pragma Assert (Present (G));
3163 pragma Assert (Present (Edge));
3164
3165 return
3166 Is_Cycle_Initiating_Edge (G, Edge)
3167 or else Is_Cyclic_With_Edge (G, Edge);
3168 end Is_Cyclic_Edge;
3169
3170 ----------------------------------
3171 -- Is_Cyclic_Elaborate_All_Edge --
3172 ----------------------------------
3173
3174 function Is_Cyclic_Elaborate_All_Edge
3175 (G : Library_Graph;
3176 Edge : Library_Graph_Edge_Id) return Boolean
3177 is
3178 begin
3179 pragma Assert (Present (G));
3180 pragma Assert (Present (Edge));
3181
3182 return
3183 Is_Elaborate_All_Edge (G, Edge)
3184 and then Links_Vertices_In_Same_Component (G, Edge);
3185 end Is_Cyclic_Elaborate_All_Edge;
3186
3187 -----------------------------------
3188 -- Is_Cyclic_Elaborate_Body_Edge --
3189 -----------------------------------
3190
3191 function Is_Cyclic_Elaborate_Body_Edge
3192 (G : Library_Graph;
3193 Edge : Library_Graph_Edge_Id) return Boolean
3194 is
3195 begin
3196 pragma Assert (Present (G));
3197 pragma Assert (Present (Edge));
3198
3199 return
3200 Is_Elaborate_Body_Edge (G, Edge)
3201 and then Links_Vertices_In_Same_Component (G, Edge);
3202 end Is_Cyclic_Elaborate_Body_Edge;
3203
3204 ------------------------------
3205 -- Is_Cyclic_Elaborate_Edge --
3206 ------------------------------
3207
3208 function Is_Cyclic_Elaborate_Edge
3209 (G : Library_Graph;
3210 Edge : Library_Graph_Edge_Id) return Boolean
3211 is
3212 begin
3213 pragma Assert (Present (G));
3214 pragma Assert (Present (Edge));
3215
3216 return
3217 Is_Elaborate_Edge (G, Edge)
3218 and then Links_Vertices_In_Same_Component (G, Edge);
3219 end Is_Cyclic_Elaborate_Edge;
3220
3221 ---------------------------
3222 -- Is_Cyclic_Forced_Edge --
3223 ---------------------------
3224
3225 function Is_Cyclic_Forced_Edge
3226 (G : Library_Graph;
3227 Edge : Library_Graph_Edge_Id) return Boolean
3228 is
3229 begin
3230 pragma Assert (Present (G));
3231 pragma Assert (Present (Edge));
3232
3233 return
3234 Is_Forced_Edge (G, Edge)
3235 and then Links_Vertices_In_Same_Component (G, Edge);
3236 end Is_Cyclic_Forced_Edge;
3237
3238 -------------------------------
3239 -- Is_Cyclic_Invocation_Edge --
3240 -------------------------------
3241
3242 function Is_Cyclic_Invocation_Edge
3243 (G : Library_Graph;
3244 Edge : Library_Graph_Edge_Id) return Boolean
3245 is
3246 begin
3247 pragma Assert (Present (G));
3248 pragma Assert (Present (Edge));
3249
3250 return
3251 Is_Invocation_Edge (G, Edge)
3252 and then Links_Vertices_In_Same_Component (G, Edge);
3253 end Is_Cyclic_Invocation_Edge;
3254
3255 -------------------------
3256 -- Is_Cyclic_With_Edge --
3257 -------------------------
3258
3259 function Is_Cyclic_With_Edge
3260 (G : Library_Graph;
3261 Edge : Library_Graph_Edge_Id) return Boolean
3262 is
3263 begin
3264 pragma Assert (Present (G));
3265 pragma Assert (Present (Edge));
3266
3267 -- Ignore Elaborate_Body edges because they also appear as with
3268 -- edges, but have special successors.
3269
3270 return
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;
3275
3276 -------------------------------
3277 -- Is_Dynamically_Elaborated --
3278 -------------------------------
3279
3280 function Is_Dynamically_Elaborated
3281 (G : Library_Graph;
3282 Vertex : Library_Graph_Vertex_Id) return Boolean
3283 is
3284 begin
3285 pragma Assert (Present (G));
3286 pragma Assert (Present (Vertex));
3287
3288 return Is_Dynamically_Elaborated (Unit (G, Vertex));
3289 end Is_Dynamically_Elaborated;
3290
3291 -----------------------------
3292 -- Is_Elaborable_Component --
3293 -----------------------------
3294
3295 function Is_Elaborable_Component
3296 (G : Library_Graph;
3297 Comp : Component_Id) return Boolean
3298 is
3299 begin
3300 pragma Assert (Present (G));
3301 pragma Assert (Present (Comp));
3302
3303 -- A component is elaborable when:
3304 --
3305 -- * It is not waiting on strong predecessors, and
3306 -- * It is not waiting on weak predecessors
3307
3308 return
3309 Pending_Strong_Predecessors (G, Comp) = 0
3310 and then Pending_Weak_Predecessors (G, Comp) = 0;
3311 end Is_Elaborable_Component;
3312
3313 --------------------------
3314 -- Is_Elaborable_Vertex --
3315 --------------------------
3316
3317 function Is_Elaborable_Vertex
3318 (G : Library_Graph;
3319 Vertex : Library_Graph_Vertex_Id) return Boolean
3320 is
3321 pragma Assert (Present (G));
3322 pragma Assert (Present (Vertex));
3323
3324 Complement : constant Library_Graph_Vertex_Id :=
3325 Complementary_Vertex
3326 (G => G,
3327 Vertex => Vertex,
3328 Force_Complement => False);
3329
3330 Strong_Preds : Natural;
3331 Weak_Preds : Natural;
3332
3333 begin
3334 -- A vertex is elaborable when:
3335 --
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
3342
3343 if In_Elaboration_Order (G, Vertex) then
3344 return False;
3345
3346 elsif Present (Complement)
3347 and then In_Elaboration_Order (G, Complement)
3348 then
3349 return False;
3350
3351 elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then
3352 return False;
3353 end if;
3354
3355 Pending_Predecessors_For_Elaboration
3356 (G => G,
3357 Vertex => Vertex,
3358 Strong_Preds => Strong_Preds,
3359 Weak_Preds => Weak_Preds);
3360
3361 return Strong_Preds = 0 and then Weak_Preds = 0;
3362 end Is_Elaborable_Vertex;
3363
3364 ---------------------------
3365 -- Is_Elaborate_All_Edge --
3366 ---------------------------
3367
3368 function Is_Elaborate_All_Edge
3369 (G : Library_Graph;
3370 Edge : Library_Graph_Edge_Id) return Boolean
3371 is
3372 begin
3373 pragma Assert (Present (G));
3374 pragma Assert (Present (Edge));
3375
3376 return Kind (G, Edge) = Elaborate_All_Edge;
3377 end Is_Elaborate_All_Edge;
3378
3379 ----------------------------
3380 -- Is_Elaborate_Body_Edge --
3381 ----------------------------
3382
3383 function Is_Elaborate_Body_Edge
3384 (G : Library_Graph;
3385 Edge : Library_Graph_Edge_Id) return Boolean
3386 is
3387 pragma Assert (Present (G));
3388 pragma Assert (Present (Edge));
3389
3390 Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
3391
3392 begin
3393 return
3394 Kind (G, Edge) = With_Edge
3395 and then
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;
3399
3400 -----------------------
3401 -- Is_Elaborate_Edge --
3402 -----------------------
3403
3404 function Is_Elaborate_Edge
3405 (G : Library_Graph;
3406 Edge : Library_Graph_Edge_Id) return Boolean
3407 is
3408 begin
3409 pragma Assert (Present (G));
3410 pragma Assert (Present (Edge));
3411
3412 return Kind (G, Edge) = Elaborate_Edge;
3413 end Is_Elaborate_Edge;
3414
3415 ----------------------------
3416 -- Is_Elaborate_Body_Pair --
3417 ----------------------------
3418
3419 function Is_Elaborate_Body_Pair
3420 (G : Library_Graph;
3421 Spec_Vertex : Library_Graph_Vertex_Id;
3422 Body_Vertex : Library_Graph_Vertex_Id) return Boolean
3423 is
3424 begin
3425 pragma Assert (Present (G));
3426 pragma Assert (Present (Spec_Vertex));
3427 pragma Assert (Present (Body_Vertex));
3428
3429 return
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;
3434
3435 --------------------
3436 -- Is_Forced_Edge --
3437 --------------------
3438
3439 function Is_Forced_Edge
3440 (G : Library_Graph;
3441 Edge : Library_Graph_Edge_Id) return Boolean
3442 is
3443 begin
3444 pragma Assert (Present (G));
3445 pragma Assert (Present (Edge));
3446
3447 return Kind (G, Edge) = Forced_Edge;
3448 end Is_Forced_Edge;
3449
3450 ----------------------
3451 -- Is_Internal_Unit --
3452 ----------------------
3453
3454 function Is_Internal_Unit
3455 (G : Library_Graph;
3456 Vertex : Library_Graph_Vertex_Id) return Boolean
3457 is
3458 begin
3459 pragma Assert (Present (G));
3460 pragma Assert (Present (Vertex));
3461
3462 return Is_Internal_Unit (Unit (G, Vertex));
3463 end Is_Internal_Unit;
3464
3465 ------------------------
3466 -- Is_Invocation_Edge --
3467 ------------------------
3468
3469 function Is_Invocation_Edge
3470 (G : Library_Graph;
3471 Edge : Library_Graph_Edge_Id) return Boolean
3472 is
3473 begin
3474 pragma Assert (Present (G));
3475 pragma Assert (Present (Edge));
3476
3477 return Kind (G, Edge) = Invocation_Edge;
3478 end Is_Invocation_Edge;
3479
3480 ------------------------
3481 -- Is_Predefined_Unit --
3482 ------------------------
3483
3484 function Is_Predefined_Unit
3485 (G : Library_Graph;
3486 Vertex : Library_Graph_Vertex_Id) return Boolean
3487 is
3488 begin
3489 pragma Assert (Present (G));
3490 pragma Assert (Present (Vertex));
3491
3492 return Is_Predefined_Unit (Unit (G, Vertex));
3493 end Is_Predefined_Unit;
3494
3495 ---------------------------
3496 -- Is_Preelaborated_Unit --
3497 ---------------------------
3498
3499 function Is_Preelaborated_Unit
3500 (G : Library_Graph;
3501 Vertex : Library_Graph_Vertex_Id) return Boolean
3502 is
3503 pragma Assert (Present (G));
3504 pragma Assert (Present (Vertex));
3505
3506 U_Id : constant Unit_Id := Unit (G, Vertex);
3507 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3508
3509 begin
3510 return U_Rec.Preelab or else U_Rec.Pure;
3511 end Is_Preelaborated_Unit;
3512
3513 -----------------------
3514 -- Is_Recorded_Cycle --
3515 -----------------------
3516
3517 function Is_Recorded_Cycle
3518 (G : Library_Graph;
3519 Attrs : Library_Graph_Cycle_Attributes) return Boolean
3520 is
3521 begin
3522 pragma Assert (Present (G));
3523
3524 return RC_Sets.Contains (G.Recorded_Cycles, Attrs);
3525 end Is_Recorded_Cycle;
3526
3527 ----------------------
3528 -- Is_Recorded_Edge --
3529 ----------------------
3530
3531 function Is_Recorded_Edge
3532 (G : Library_Graph;
3533 Rel : Predecessor_Successor_Relation) return Boolean
3534 is
3535 begin
3536 pragma Assert (Present (G));
3537 pragma Assert (Present (Rel.Predecessor));
3538 pragma Assert (Present (Rel.Successor));
3539
3540 return RE_Sets.Contains (G.Recorded_Edges, Rel);
3541 end Is_Recorded_Edge;
3542
3543 -------------
3544 -- Is_Spec --
3545 -------------
3546
3547 function Is_Spec
3548 (G : Library_Graph;
3549 Vertex : Library_Graph_Vertex_Id) return Boolean
3550 is
3551 pragma Assert (Present (G));
3552 pragma Assert (Present (Vertex));
3553
3554 U_Id : constant Unit_Id := Unit (G, Vertex);
3555 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3556
3557 begin
3558 return U_Rec.Utype = Is_Spec or else U_Rec.Utype = Is_Spec_Only;
3559 end Is_Spec;
3560
3561 -----------------------
3562 -- Is_Spec_With_Body --
3563 -----------------------
3564
3565 function Is_Spec_With_Body
3566 (G : Library_Graph;
3567 Vertex : Library_Graph_Vertex_Id) return Boolean
3568 is
3569 pragma Assert (Present (G));
3570 pragma Assert (Present (Vertex));
3571
3572 U_Id : constant Unit_Id := Unit (G, Vertex);
3573 U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
3574
3575 begin
3576 return U_Rec.Utype = Is_Spec;
3577 end Is_Spec_With_Body;
3578
3579 ---------------------------------
3580 -- Is_Spec_With_Elaborate_Body --
3581 ---------------------------------
3582
3583 function Is_Spec_With_Elaborate_Body
3584 (G : Library_Graph;
3585 Vertex : Library_Graph_Vertex_Id) return Boolean
3586 is
3587 begin
3588 pragma Assert (Present (G));
3589 pragma Assert (Present (Vertex));
3590
3591 return
3592 Is_Spec_With_Body (G, Vertex)
3593 and then Has_Elaborate_Body (G, Vertex);
3594 end Is_Spec_With_Elaborate_Body;
3595
3596 ---------------------------------
3597 -- Is_Weakly_Elaborable_Vertex --
3598 ----------------------------------
3599
3600 function Is_Weakly_Elaborable_Vertex
3601 (G : Library_Graph;
3602 Vertex : Library_Graph_Vertex_Id) return Boolean
3603 is
3604 pragma Assert (Present (G));
3605 pragma Assert (Present (Vertex));
3606
3607 Complement : constant Library_Graph_Vertex_Id :=
3608 Complementary_Vertex
3609 (G => G,
3610 Vertex => Vertex,
3611 Force_Complement => False);
3612
3613 Strong_Preds : Natural;
3614 Weak_Preds : Natural;
3615
3616 begin
3617 -- A vertex is weakly elaborable when:
3618 --
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
3625
3626 if In_Elaboration_Order (G, Vertex) then
3627 return False;
3628
3629 elsif Present (Complement)
3630 and then In_Elaboration_Order (G, Complement)
3631 then
3632 return False;
3633
3634 elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then
3635 return False;
3636 end if;
3637
3638 Pending_Predecessors_For_Elaboration
3639 (G => G,
3640 Vertex => Vertex,
3641 Strong_Preds => Strong_Preds,
3642 Weak_Preds => Weak_Preds);
3643
3644 return Strong_Preds = 0 and then Weak_Preds >= 1;
3645 end Is_Weakly_Elaborable_Vertex;
3646
3647 ------------------
3648 -- Is_With_Edge --
3649 ------------------
3650
3651 function Is_With_Edge
3652 (G : Library_Graph;
3653 Edge : Library_Graph_Edge_Id) return Boolean
3654 is
3655 begin
3656 pragma Assert (Present (G));
3657 pragma Assert (Present (Edge));
3658
3659 return Kind (G, Edge) = With_Edge;
3660 end Is_With_Edge;
3661
3662 ------------------------
3663 -- Iterate_All_Cycles --
3664 ------------------------
3665
3666 function Iterate_All_Cycles
3667 (G : Library_Graph) return All_Cycle_Iterator
3668 is
3669 begin
3670 pragma Assert (Present (G));
3671
3672 return All_Cycle_Iterator (LGC_Lists.Iterate (G.Cycles));
3673 end Iterate_All_Cycles;
3674
3675 -----------------------
3676 -- Iterate_All_Edges --
3677 -----------------------
3678
3679 function Iterate_All_Edges
3680 (G : Library_Graph) return All_Edge_Iterator
3681 is
3682 begin
3683 pragma Assert (Present (G));
3684
3685 return All_Edge_Iterator (DG.Iterate_All_Edges (G.Graph));
3686 end Iterate_All_Edges;
3687
3688 --------------------------
3689 -- Iterate_All_Vertices --
3690 --------------------------
3691
3692 function Iterate_All_Vertices
3693 (G : Library_Graph) return All_Vertex_Iterator
3694 is
3695 begin
3696 pragma Assert (Present (G));
3697
3698 return All_Vertex_Iterator (DG.Iterate_All_Vertices (G.Graph));
3699 end Iterate_All_Vertices;
3700
3701 ------------------------
3702 -- Iterate_Components --
3703 ------------------------
3704
3705 function Iterate_Components
3706 (G : Library_Graph) return Component_Iterator
3707 is
3708 begin
3709 pragma Assert (Present (G));
3710
3711 return Component_Iterator (DG.Iterate_Components (G.Graph));
3712 end Iterate_Components;
3713
3714 --------------------------------
3715 -- Iterate_Component_Vertices --
3716 --------------------------------
3717
3718 function Iterate_Component_Vertices
3719 (G : Library_Graph;
3720 Comp : Component_Id) return Component_Vertex_Iterator
3721 is
3722 begin
3723 pragma Assert (Present (G));
3724 pragma Assert (Present (Comp));
3725
3726 return
3727 Component_Vertex_Iterator
3728 (DG.Iterate_Component_Vertices (G.Graph, Comp));
3729 end Iterate_Component_Vertices;
3730
3731 ----------------------------
3732 -- Iterate_Edges_Of_Cycle --
3733 ----------------------------
3734
3735 function Iterate_Edges_Of_Cycle
3736 (G : Library_Graph;
3737 Cycle : Library_Graph_Cycle_Id) return Edges_Of_Cycle_Iterator
3738 is
3739 begin
3740 pragma Assert (Present (G));
3741 pragma Assert (Present (Cycle));
3742
3743 return Edges_Of_Cycle_Iterator (LGE_Lists.Iterate (Path (G, Cycle)));
3744 end Iterate_Edges_Of_Cycle;
3745
3746 ---------------------------------
3747 -- Iterate_Edges_To_Successors --
3748 ---------------------------------
3749
3750 function Iterate_Edges_To_Successors
3751 (G : Library_Graph;
3752 Vertex : Library_Graph_Vertex_Id) return Edges_To_Successors_Iterator
3753 is
3754 begin
3755 pragma Assert (Present (G));
3756 pragma Assert (Present (Vertex));
3757
3758 return
3759 Edges_To_Successors_Iterator
3760 (DG.Iterate_Outgoing_Edges (G.Graph, Vertex));
3761 end Iterate_Edges_To_Successors;
3762
3763 ----------
3764 -- Kind --
3765 ----------
3766
3767 function Kind
3768 (G : Library_Graph;
3769 Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Kind
3770 is
3771 begin
3772 pragma Assert (Present (G));
3773 pragma Assert (Present (Cycle));
3774
3775 return Get_LGC_Attributes (G, Cycle).Kind;
3776 end Kind;
3777
3778 ----------
3779 -- Kind --
3780 ----------
3781
3782 function Kind
3783 (G : Library_Graph;
3784 Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Kind
3785 is
3786 begin
3787 pragma Assert (Present (G));
3788 pragma Assert (Present (Edge));
3789
3790 return Get_LGE_Attributes (G, Edge).Kind;
3791 end Kind;
3792
3793 ------------
3794 -- Length --
3795 ------------
3796
3797 function Length
3798 (G : Library_Graph;
3799 Cycle : Library_Graph_Cycle_Id) return Natural
3800 is
3801 begin
3802 pragma Assert (Present (G));
3803 pragma Assert (Present (Cycle));
3804
3805 return LGE_Lists.Size (Path (G, Cycle));
3806 end Length;
3807
3808 ------------------------------
3809 -- Library_Graph_Edge_Count --
3810 ------------------------------
3811
3812 function Library_Graph_Edge_Count
3813 (G : Library_Graph;
3814 Kind : Library_Graph_Edge_Kind) return Natural
3815 is
3816 begin
3817 pragma Assert (Present (G));
3818
3819 return G.Counts (Kind);
3820 end Library_Graph_Edge_Count;
3821
3822 --------------------------------------
3823 -- Links_Vertices_In_Same_Component --
3824 --------------------------------------
3825
3826 function Links_Vertices_In_Same_Component
3827 (G : Library_Graph;
3828 Edge : Library_Graph_Edge_Id) return Boolean
3829 is
3830 begin
3831 pragma Assert (Present (G));
3832 pragma Assert (Present (Edge));
3833
3834 -- An edge is part of a cycle when both the successor and predecessor
3835 -- reside in the same component.
3836
3837 return
3838 In_Same_Component
3839 (G => G,
3840 Left => Predecessor (G, Edge),
3841 Right => Successor (G, Edge));
3842 end Links_Vertices_In_Same_Component;
3843
3844 -----------------------------------
3845 -- Maximum_Invocation_Edge_Count --
3846 -----------------------------------
3847
3848 function Maximum_Invocation_Edge_Count
3849 (G : Library_Graph;
3850 Edge : Library_Graph_Edge_Id;
3851 Count : Natural) return Natural
3852 is
3853 New_Count : Natural;
3854
3855 begin
3856 pragma Assert (Present (G));
3857
3858 New_Count := Count;
3859
3860 if Present (Edge) and then Is_Invocation_Edge (G, Edge) then
3861 New_Count := New_Count + 1;
3862 end if;
3863
3864 return New_Count;
3865 end Maximum_Invocation_Edge_Count;
3866
3867 ----------
3868 -- Name --
3869 ----------
3870
3871 function Name
3872 (G : Library_Graph;
3873 Vertex : Library_Graph_Vertex_Id) return Unit_Name_Type
3874 is
3875 begin
3876 pragma Assert (Present (G));
3877 pragma Assert (Present (Vertex));
3878
3879 return Name (Unit (G, Vertex));
3880 end Name;
3881
3882 -----------------------
3883 -- Needs_Elaboration --
3884 -----------------------
3885
3886 function Needs_Elaboration
3887 (G : Library_Graph;
3888 Vertex : Library_Graph_Vertex_Id) return Boolean
3889 is
3890 begin
3891 pragma Assert (Present (G));
3892 pragma Assert (Present (Vertex));
3893
3894 return Needs_Elaboration (Unit (G, Vertex));
3895 end Needs_Elaboration;
3896
3897 ----------
3898 -- Next --
3899 ----------
3900
3901 procedure Next
3902 (Iter : in out All_Cycle_Iterator;
3903 Cycle : out Library_Graph_Cycle_Id)
3904 is
3905 begin
3906 LGC_Lists.Next (LGC_Lists.Iterator (Iter), Cycle);
3907 end Next;
3908
3909 ----------
3910 -- Next --
3911 ----------
3912
3913 procedure Next
3914 (Iter : in out All_Edge_Iterator;
3915 Edge : out Library_Graph_Edge_Id)
3916 is
3917 begin
3918 DG.Next (DG.All_Edge_Iterator (Iter), Edge);
3919 end Next;
3920
3921 ----------
3922 -- Next --
3923 ----------
3924
3925 procedure Next
3926 (Iter : in out All_Vertex_Iterator;
3927 Vertex : out Library_Graph_Vertex_Id)
3928 is
3929 begin
3930 DG.Next (DG.All_Vertex_Iterator (Iter), Vertex);
3931 end Next;
3932
3933 ----------
3934 -- Next --
3935 ----------
3936
3937 procedure Next
3938 (Iter : in out Edges_Of_Cycle_Iterator;
3939 Edge : out Library_Graph_Edge_Id)
3940 is
3941 begin
3942 LGE_Lists.Next (LGE_Lists.Iterator (Iter), Edge);
3943 end Next;
3944
3945 ----------
3946 -- Next --
3947 ----------
3948
3949 procedure Next
3950 (Iter : in out Component_Iterator;
3951 Comp : out Component_Id)
3952 is
3953 begin
3954 DG.Next (DG.Component_Iterator (Iter), Comp);
3955 end Next;
3956
3957 ----------
3958 -- Next --
3959 ----------
3960
3961 procedure Next
3962 (Iter : in out Edges_To_Successors_Iterator;
3963 Edge : out Library_Graph_Edge_Id)
3964 is
3965 begin
3966 DG.Next (DG.Outgoing_Edge_Iterator (Iter), Edge);
3967 end Next;
3968
3969 ----------
3970 -- Next --
3971 ----------
3972
3973 procedure Next
3974 (Iter : in out Component_Vertex_Iterator;
3975 Vertex : out Library_Graph_Vertex_Id)
3976 is
3977 begin
3978 DG.Next (DG.Component_Vertex_Iterator (Iter), Vertex);
3979 end Next;
3980
3981 -----------------------------
3982 -- Normalize_And_Add_Cycle --
3983 -----------------------------
3984
3985 procedure Normalize_And_Add_Cycle
3986 (G : Library_Graph;
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)
3991 is
3992 Path : LGE_Lists.Doubly_Linked_List;
3993
3994 begin
3995 pragma Assert (Present (G));
3996 pragma Assert (Present (Most_Significant_Edge));
3997 pragma Assert (LGE_Lists.Present (Cycle_Path));
3998
3999 -- Replicate the path of the cycle in order to avoid sharing lists
4000
4001 Path := Copy_Cycle_Path (Cycle_Path);
4002
4003 -- Normalize the path of the cycle such that its most significant
4004 -- edge is the first in the list of edges.
4005
4006 Normalize_Cycle_Path
4007 (Cycle_Path => Path,
4008 Most_Significant_Edge => Most_Significant_Edge);
4009
4010 -- Save the cycle for diagnostic purposes. Its kind is determined by
4011 -- its most significant edge.
4012
4013 Add_Cycle
4014 (G => G,
4015 Attrs =>
4016 (Invocation_Edge_Count => Invocation_Edge_Count,
4017 Kind =>
4018 Cycle_Kind_Of
4019 (G => G,
4020 Edge => Most_Significant_Edge),
4021 Path => Path),
4022 Indent => Indent);
4023 end Normalize_And_Add_Cycle;
4024
4025 --------------------------
4026 -- Normalize_Cycle_Path --
4027 --------------------------
4028
4029 procedure Normalize_Cycle_Path
4030 (Cycle_Path : LGE_Lists.Doubly_Linked_List;
4031 Most_Significant_Edge : Library_Graph_Edge_Id)
4032 is
4033 Edge : Library_Graph_Edge_Id;
4034
4035 begin
4036 pragma Assert (LGE_Lists.Present (Cycle_Path));
4037 pragma Assert (Present (Most_Significant_Edge));
4038
4039 -- Perform at most |Cycle_Path| rotations in case the cycle is
4040 -- malformed and the significant edge does not appear within.
4041
4042 for Rotation in 1 .. LGE_Lists.Size (Cycle_Path) loop
4043 Edge := LGE_Lists.First (Cycle_Path);
4044
4045 -- The cycle is already rotated such that the most significant
4046 -- edge is first.
4047
4048 if Edge = Most_Significant_Edge then
4049 return;
4050
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
4053 -- the path.
4054
4055 else
4056 LGE_Lists.Delete_First (Cycle_Path);
4057 LGE_Lists.Append (Cycle_Path, Edge);
4058 end if;
4059 end loop;
4060
4061 pragma Assert (False);
4062 end Normalize_Cycle_Path;
4063
4064 ----------------------------------
4065 -- Number_Of_Component_Vertices --
4066 ----------------------------------
4067
4068 function Number_Of_Component_Vertices
4069 (G : Library_Graph;
4070 Comp : Component_Id) return Natural
4071 is
4072 begin
4073 pragma Assert (Present (G));
4074 pragma Assert (Present (Comp));
4075
4076 return DG.Number_Of_Component_Vertices (G.Graph, Comp);
4077 end Number_Of_Component_Vertices;
4078
4079 --------------------------
4080 -- Number_Of_Components --
4081 --------------------------
4082
4083 function Number_Of_Components (G : Library_Graph) return Natural is
4084 begin
4085 pragma Assert (Present (G));
4086
4087 return DG.Number_Of_Components (G.Graph);
4088 end Number_Of_Components;
4089
4090 ----------------------
4091 -- Number_Of_Cycles --
4092 ----------------------
4093
4094 function Number_Of_Cycles (G : Library_Graph) return Natural is
4095 begin
4096 pragma Assert (Present (G));
4097
4098 return LGC_Lists.Size (G.Cycles);
4099 end Number_Of_Cycles;
4100
4101 ---------------------
4102 -- Number_Of_Edges --
4103 ---------------------
4104
4105 function Number_Of_Edges (G : Library_Graph) return Natural is
4106 begin
4107 pragma Assert (Present (G));
4108
4109 return DG.Number_Of_Edges (G.Graph);
4110 end Number_Of_Edges;
4111
4112 -----------------------------------
4113 -- Number_Of_Edges_To_Successors --
4114 -----------------------------------
4115
4116 function Number_Of_Edges_To_Successors
4117 (G : Library_Graph;
4118 Vertex : Library_Graph_Vertex_Id) return Natural
4119 is
4120 begin
4121 pragma Assert (Present (G));
4122
4123 return DG.Number_Of_Outgoing_Edges (G.Graph, Vertex);
4124 end Number_Of_Edges_To_Successors;
4125
4126 ------------------------
4127 -- Number_Of_Vertices --
4128 ------------------------
4129
4130 function Number_Of_Vertices (G : Library_Graph) return Natural is
4131 begin
4132 pragma Assert (Present (G));
4133
4134 return DG.Number_Of_Vertices (G.Graph);
4135 end Number_Of_Vertices;
4136
4137 ----------
4138 -- Path --
4139 ----------
4140
4141 function Path
4142 (G : Library_Graph;
4143 Cycle : Library_Graph_Cycle_Id) return LGE_Lists.Doubly_Linked_List
4144 is
4145 begin
4146 pragma Assert (Present (G));
4147 pragma Assert (Present (Cycle));
4148
4149 return Get_LGC_Attributes (G, Cycle).Path;
4150 end Path;
4151
4152 ------------------------------------------
4153 -- Pending_Predecessors_For_Elaboration --
4154 ------------------------------------------
4155
4156 procedure Pending_Predecessors_For_Elaboration
4157 (G : Library_Graph;
4158 Vertex : Library_Graph_Vertex_Id;
4159 Strong_Preds : out Natural;
4160 Weak_Preds : out Natural)
4161 is
4162 Complement : Library_Graph_Vertex_Id;
4163 Spec_Vertex : Library_Graph_Vertex_Id;
4164 Total_Strong_Preds : Natural;
4165 Total_Weak_Preds : Natural;
4166
4167 begin
4168 pragma Assert (Present (G));
4169 pragma Assert (Present (Vertex));
4170
4171 Total_Strong_Preds := Pending_Strong_Predecessors (G, Vertex);
4172 Total_Weak_Preds := Pending_Weak_Predecessors (G, Vertex);
4173
4174 -- Assume that there is no complementary vertex that needs to be
4175 -- examined.
4176
4177 Complement := No_Library_Graph_Vertex;
4178 Spec_Vertex := No_Library_Graph_Vertex;
4179
4180 if Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then
4181 Complement := Proper_Spec (G, Vertex);
4182 Spec_Vertex := Complement;
4183
4184 elsif Is_Spec_With_Elaborate_Body (G, Vertex) then
4185 Complement := Proper_Body (G, Vertex);
4186 Spec_Vertex := Vertex;
4187 end if;
4188
4189 -- The vertex is part of an Elaborate_Body pair. Take into account
4190 -- the strong and weak predecessors of the complementary vertex.
4191
4192 if Present (Complement) then
4193 Total_Strong_Preds :=
4194 Pending_Strong_Predecessors (G, Complement) + Total_Strong_Preds;
4195 Total_Weak_Preds :=
4196 Pending_Weak_Predecessors (G, Complement) + Total_Weak_Preds;
4197
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.
4203
4204 if not In_Elaboration_Order (G, Spec_Vertex) then
4205 Total_Strong_Preds := Total_Strong_Preds - 1;
4206 end if;
4207 end if;
4208
4209 Strong_Preds := Total_Strong_Preds;
4210 Weak_Preds := Total_Weak_Preds;
4211 end Pending_Predecessors_For_Elaboration;
4212
4213 ---------------------------------
4214 -- Pending_Strong_Predecessors --
4215 ---------------------------------
4216
4217 function Pending_Strong_Predecessors
4218 (G : Library_Graph;
4219 Comp : Component_Id) return Natural
4220 is
4221 begin
4222 pragma Assert (Present (G));
4223 pragma Assert (Present (Comp));
4224
4225 return Get_Component_Attributes (G, Comp).Pending_Strong_Predecessors;
4226 end Pending_Strong_Predecessors;
4227
4228 ---------------------------------
4229 -- Pending_Strong_Predecessors --
4230 ---------------------------------
4231
4232 function Pending_Strong_Predecessors
4233 (G : Library_Graph;
4234 Vertex : Library_Graph_Vertex_Id) return Natural
4235 is
4236 begin
4237 pragma Assert (Present (G));
4238 pragma Assert (Present (Vertex));
4239
4240 return Get_LGV_Attributes (G, Vertex).Pending_Strong_Predecessors;
4241 end Pending_Strong_Predecessors;
4242
4243 -------------------------------
4244 -- Pending_Weak_Predecessors --
4245 -------------------------------
4246
4247 function Pending_Weak_Predecessors
4248 (G : Library_Graph;
4249 Comp : Component_Id) return Natural
4250 is
4251 begin
4252 pragma Assert (Present (G));
4253 pragma Assert (Present (Comp));
4254
4255 return Get_Component_Attributes (G, Comp).Pending_Weak_Predecessors;
4256 end Pending_Weak_Predecessors;
4257
4258 -------------------------------
4259 -- Pending_Weak_Predecessors --
4260 -------------------------------
4261
4262 function Pending_Weak_Predecessors
4263 (G : Library_Graph;
4264 Vertex : Library_Graph_Vertex_Id) return Natural
4265 is
4266 begin
4267 pragma Assert (Present (G));
4268 pragma Assert (Present (Vertex));
4269
4270 return Get_LGV_Attributes (G, Vertex).Pending_Weak_Predecessors;
4271 end Pending_Weak_Predecessors;
4272
4273 ----------------
4274 -- Precedence --
4275 ----------------
4276
4277 function Precedence
4278 (G : Library_Graph;
4279 Cycle : Library_Graph_Cycle_Id;
4280 Compared_To : Library_Graph_Cycle_Id) return Precedence_Kind
4281 is
4282 pragma Assert (Present (G));
4283 pragma Assert (Present (Cycle));
4284 pragma Assert (Present (Compared_To));
4285
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 :=
4292 Precedence
4293 (Kind => Kind (G, Cycle),
4294 Compared_To => Kind (G, Compared_To));
4295
4296 begin
4297 if Kind_Prec = Higher_Precedence
4298 or else
4299 Kind_Prec = Lower_Precedence
4300 then
4301 return Kind_Prec;
4302
4303 -- Otherwise both cycles have the same precedence based on their
4304 -- kind. Prefer a cycle with fewer invocation edges.
4305
4306 elsif Cycle_Invs < Comp_Invs then
4307 return Higher_Precedence;
4308
4309 elsif Cycle_Invs > Comp_Invs then
4310 return Lower_Precedence;
4311
4312 -- Otherwise both cycles have the same number of invocation edges.
4313 -- Prefer a cycle with a smaller length.
4314
4315 elsif Cycle_Len < Comp_Len then
4316 return Higher_Precedence;
4317
4318 elsif Cycle_Len > Comp_Len then
4319 return Lower_Precedence;
4320
4321 else
4322 return Equal_Precedence;
4323 end if;
4324 end Precedence;
4325
4326 ----------------
4327 -- Precedence --
4328 ----------------
4329
4330 function Precedence
4331 (Kind : Library_Graph_Cycle_Kind;
4332 Compared_To : Library_Graph_Cycle_Kind) return Precedence_Kind
4333 is
4334 Comp_Pos : constant Integer :=
4335 Library_Graph_Cycle_Kind'Pos (Compared_To);
4336 Kind_Pos : constant Integer := Library_Graph_Cycle_Kind'Pos (Kind);
4337
4338 begin
4339 -- A lower ordinal indicates higher precedence
4340
4341 if Kind_Pos < Comp_Pos then
4342 return Higher_Precedence;
4343
4344 elsif Kind_Pos > Comp_Pos then
4345 return Lower_Precedence;
4346
4347 else
4348 return Equal_Precedence;
4349 end if;
4350 end Precedence;
4351
4352 ----------------
4353 -- Precedence --
4354 ----------------
4355
4356 function Precedence
4357 (G : Library_Graph;
4358 Edge : Library_Graph_Edge_Id;
4359 Compared_To : Library_Graph_Edge_Id) return Precedence_Kind
4360 is
4361 pragma Assert (Present (G));
4362 pragma Assert (Present (Edge));
4363 pragma Assert (Present (Compared_To));
4364
4365 Kind_Prec : constant Precedence_Kind :=
4366 Precedence
4367 (Kind => Cycle_Kind_Of (G, Edge),
4368 Compared_To => Cycle_Kind_Of (G, Compared_To));
4369
4370 begin
4371 if Kind_Prec = Higher_Precedence
4372 or else
4373 Kind_Prec = Lower_Precedence
4374 then
4375 return Kind_Prec;
4376
4377 -- Otherwise both edges have the same precedence based on their cycle
4378 -- kinds. Prefer an edge whose successor has higher precedence.
4379
4380 else
4381 return
4382 Precedence
4383 (G => G,
4384 Vertex => Successor (G, Edge),
4385 Compared_To => Successor (G, Compared_To));
4386 end if;
4387 end Precedence;
4388
4389 ----------------
4390 -- Precedence --
4391 ----------------
4392
4393 function Precedence
4394 (G : Library_Graph;
4395 Vertex : Library_Graph_Vertex_Id;
4396 Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind
4397 is
4398 begin
4399 pragma Assert (Present (G));
4400 pragma Assert (Present (Vertex));
4401 pragma Assert (Present (Compared_To));
4402
4403 -- Use lexicographical order to determine precedence and ensure
4404 -- deterministic behavior.
4405
4406 if Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then
4407 return Higher_Precedence;
4408 else
4409 return Lower_Precedence;
4410 end if;
4411 end Precedence;
4412
4413 -----------------
4414 -- Predecessor --
4415 -----------------
4416
4417 function Predecessor
4418 (G : Library_Graph;
4419 Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
4420 is
4421 begin
4422 pragma Assert (Present (G));
4423 pragma Assert (Present (Edge));
4424
4425 return DG.Source_Vertex (G.Graph, Edge);
4426 end Predecessor;
4427
4428 -------------
4429 -- Present --
4430 -------------
4431
4432 function Present (G : Library_Graph) return Boolean is
4433 begin
4434 return G /= Nil;
4435 end Present;
4436
4437 -----------------
4438 -- Proper_Body --
4439 -----------------
4440
4441 function Proper_Body
4442 (G : Library_Graph;
4443 Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
4444 is
4445 begin
4446 pragma Assert (Present (G));
4447 pragma Assert (Present (Vertex));
4448
4449 -- When the vertex denotes a spec with a completing body, return the
4450 -- body.
4451
4452 if Is_Spec_With_Body (G, Vertex) then
4453 return Corresponding_Item (G, Vertex);
4454
4455 -- Otherwise the vertex must be a body
4456
4457 else
4458 pragma Assert (Is_Body (G, Vertex));
4459 return Vertex;
4460 end if;
4461 end Proper_Body;
4462
4463 -----------------
4464 -- Proper_Spec --
4465 -----------------
4466
4467 function Proper_Spec
4468 (G : Library_Graph;
4469 Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
4470 is
4471 begin
4472 pragma Assert (Present (G));
4473 pragma Assert (Present (Vertex));
4474
4475 -- When the vertex denotes a body that completes a spec, return the
4476 -- spec.
4477
4478 if Is_Body_With_Spec (G, Vertex) then
4479 return Corresponding_Item (G, Vertex);
4480
4481 -- Otherwise the vertex must denote a spec
4482
4483 else
4484 pragma Assert (Is_Spec (G, Vertex));
4485 return Vertex;
4486 end if;
4487 end Proper_Spec;
4488
4489 ----------------------------------
4490 -- Remove_Vertex_And_Complement --
4491 ----------------------------------
4492
4493 procedure Remove_Vertex_And_Complement
4494 (G : Library_Graph;
4495 Vertex : Library_Graph_Vertex_Id;
4496 Set : LGV_Sets.Membership_Set;
4497 Do_Complement : Boolean)
4498 is
4499 pragma Assert (Present (G));
4500 pragma Assert (Present (Vertex));
4501 pragma Assert (LGV_Sets.Present (Set));
4502
4503 Complement : constant Library_Graph_Vertex_Id :=
4504 Complementary_Vertex
4505 (G => G,
4506 Vertex => Vertex,
4507 Force_Complement => Do_Complement);
4508
4509 begin
4510 LGV_Sets.Delete (Set, Vertex);
4511
4512 if Present (Complement) then
4513 LGV_Sets.Delete (Set, Complement);
4514 end if;
4515 end Remove_Vertex_And_Complement;
4516
4517 -----------------------------------------
4518 -- Same_Library_Graph_Cycle_Attributes --
4519 -----------------------------------------
4520
4521 function Same_Library_Graph_Cycle_Attributes
4522 (Left : Library_Graph_Cycle_Attributes;
4523 Right : Library_Graph_Cycle_Attributes) return Boolean
4524 is
4525 begin
4526 -- Two cycles are the same when
4527 --
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
4532
4533 return
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;
4538
4539 ------------------------------
4540 -- Set_Component_Attributes --
4541 ------------------------------
4542
4543 procedure Set_Component_Attributes
4544 (G : Library_Graph;
4545 Comp : Component_Id;
4546 Val : Component_Attributes)
4547 is
4548 begin
4549 pragma Assert (Present (G));
4550 pragma Assert (Present (Comp));
4551
4552 Component_Tables.Put (G.Component_Attributes, Comp, Val);
4553 end Set_Component_Attributes;
4554
4555 ----------------------------
4556 -- Set_Corresponding_Item --
4557 ----------------------------
4558
4559 procedure Set_Corresponding_Item
4560 (G : Library_Graph;
4561 Vertex : Library_Graph_Vertex_Id;
4562 Val : Library_Graph_Vertex_Id)
4563 is
4564 Attrs : Library_Graph_Vertex_Attributes;
4565
4566 begin
4567 pragma Assert (Present (G));
4568 pragma Assert (Present (Vertex));
4569
4570 Attrs := Get_LGV_Attributes (G, Vertex);
4571 Attrs.Corresponding_Item := Val;
4572 Set_LGV_Attributes (G, Vertex, Attrs);
4573 end Set_Corresponding_Item;
4574
4575 ------------------------------
4576 -- Set_Corresponding_Vertex --
4577 ------------------------------
4578
4579 procedure Set_Corresponding_Vertex
4580 (G : Library_Graph;
4581 U_Id : Unit_Id;
4582 Val : Library_Graph_Vertex_Id)
4583 is
4584 begin
4585 pragma Assert (Present (G));
4586 pragma Assert (Present (U_Id));
4587
4588 Unit_Tables.Put (G.Unit_To_Vertex, U_Id, Val);
4589 end Set_Corresponding_Vertex;
4590
4591 ------------------------------
4592 -- Set_In_Elaboration_Order --
4593 ------------------------------
4594
4595 procedure Set_In_Elaboration_Order
4596 (G : Library_Graph;
4597 Vertex : Library_Graph_Vertex_Id;
4598 Val : Boolean := True)
4599 is
4600 Attrs : Library_Graph_Vertex_Attributes;
4601
4602 begin
4603 pragma Assert (Present (G));
4604 pragma Assert (Present (Vertex));
4605
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;
4610
4611 ---------------------------
4612 -- Set_Is_Recorded_Cycle --
4613 ---------------------------
4614
4615 procedure Set_Is_Recorded_Cycle
4616 (G : Library_Graph;
4617 Attrs : Library_Graph_Cycle_Attributes;
4618 Val : Boolean := True)
4619 is
4620 begin
4621 pragma Assert (Present (G));
4622
4623 if Val then
4624 RC_Sets.Insert (G.Recorded_Cycles, Attrs);
4625 else
4626 RC_Sets.Delete (G.Recorded_Cycles, Attrs);
4627 end if;
4628 end Set_Is_Recorded_Cycle;
4629
4630 --------------------------
4631 -- Set_Is_Recorded_Edge --
4632 --------------------------
4633
4634 procedure Set_Is_Recorded_Edge
4635 (G : Library_Graph;
4636 Rel : Predecessor_Successor_Relation;
4637 Val : Boolean := True)
4638 is
4639 begin
4640 pragma Assert (Present (G));
4641 pragma Assert (Present (Rel.Predecessor));
4642 pragma Assert (Present (Rel.Successor));
4643
4644 if Val then
4645 RE_Sets.Insert (G.Recorded_Edges, Rel);
4646 else
4647 RE_Sets.Delete (G.Recorded_Edges, Rel);
4648 end if;
4649 end Set_Is_Recorded_Edge;
4650
4651 ------------------------
4652 -- Set_LGC_Attributes --
4653 ------------------------
4654
4655 procedure Set_LGC_Attributes
4656 (G : Library_Graph;
4657 Cycle : Library_Graph_Cycle_Id;
4658 Val : Library_Graph_Cycle_Attributes)
4659 is
4660 begin
4661 pragma Assert (Present (G));
4662 pragma Assert (Present (Cycle));
4663
4664 LGC_Tables.Put (G.Cycle_Attributes, Cycle, Val);
4665 end Set_LGC_Attributes;
4666
4667 ------------------------
4668 -- Set_LGE_Attributes --
4669 ------------------------
4670
4671 procedure Set_LGE_Attributes
4672 (G : Library_Graph;
4673 Edge : Library_Graph_Edge_Id;
4674 Val : Library_Graph_Edge_Attributes)
4675 is
4676 begin
4677 pragma Assert (Present (G));
4678 pragma Assert (Present (Edge));
4679
4680 LGE_Tables.Put (G.Edge_Attributes, Edge, Val);
4681 end Set_LGE_Attributes;
4682
4683 ------------------------
4684 -- Set_LGV_Attributes --
4685 ------------------------
4686
4687 procedure Set_LGV_Attributes
4688 (G : Library_Graph;
4689 Vertex : Library_Graph_Vertex_Id;
4690 Val : Library_Graph_Vertex_Attributes)
4691 is
4692 begin
4693 pragma Assert (Present (G));
4694 pragma Assert (Present (Vertex));
4695
4696 LGV_Tables.Put (G.Vertex_Attributes, Vertex, Val);
4697 end Set_LGV_Attributes;
4698
4699 ---------------
4700 -- Successor --
4701 ---------------
4702
4703 function Successor
4704 (G : Library_Graph;
4705 Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
4706 is
4707 begin
4708 pragma Assert (Present (G));
4709 pragma Assert (Present (Edge));
4710
4711 return DG.Destination_Vertex (G.Graph, Edge);
4712 end Successor;
4713
4714 -----------------
4715 -- Trace_Cycle --
4716 -----------------
4717
4718 procedure Trace_Cycle
4719 (G : Library_Graph;
4720 Cycle : Library_Graph_Cycle_Id;
4721 Indent : Indentation_Level)
4722 is
4723 Attr_Indent : constant Indentation_Level :=
4724 Indent + Nested_Indentation;
4725 Edge_Indent : constant Indentation_Level :=
4726 Attr_Indent + Nested_Indentation;
4727
4728 Edge : Library_Graph_Edge_Id;
4729 Iter : Edges_Of_Cycle_Iterator;
4730
4731 begin
4732 pragma Assert (Present (G));
4733 pragma Assert (Present (Cycle));
4734
4735 -- Nothing to do when switch -d_T (output elaboration order and cycle
4736 -- detection trace information) is not in effect.
4737
4738 if not Debug_Flag_Underscore_TT then
4739 return;
4740 end if;
4741
4742 Indent_By (Indent);
4743 Write_Str ("cycle (Cycle_Id_");
4744 Write_Int (Int (Cycle));
4745 Write_Str (")");
4746 Write_Eol;
4747
4748 Indent_By (Attr_Indent);
4749 Write_Str ("kind = ");
4750 Write_Str (Kind (G, Cycle)'Img);
4751 Write_Eol;
4752
4753 Indent_By (Attr_Indent);
4754 Write_Str ("invocation edges = ");
4755 Write_Int (Int (Invocation_Edge_Count (G, Cycle)));
4756 Write_Eol;
4757
4758 Indent_By (Attr_Indent);
4759 Write_Str ("length: ");
4760 Write_Int (Int (Length (G, Cycle)));
4761 Write_Eol;
4762
4763 Iter := Iterate_Edges_Of_Cycle (G, Cycle);
4764 while Has_Next (Iter) loop
4765 Next (Iter, Edge);
4766
4767 Indent_By (Edge_Indent);
4768 Write_Str ("library graph edge (Edge_");
4769 Write_Int (Int (Edge));
4770 Write_Str (")");
4771 Write_Eol;
4772 end loop;
4773 end Trace_Cycle;
4774
4775 ----------------
4776 -- Trace_Edge --
4777 ----------------
4778
4779 procedure Trace_Edge
4780 (G : Library_Graph;
4781 Edge : Library_Graph_Edge_Id;
4782 Indent : Indentation_Level)
4783 is
4784 pragma Assert (Present (G));
4785 pragma Assert (Present (Edge));
4786
4787 Attr_Indent : constant Indentation_Level :=
4788 Indent + Nested_Indentation;
4789
4790 Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
4791 Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
4792
4793 begin
4794 -- Nothing to do when switch -d_T (output elaboration order and cycle
4795 -- detection trace information) is not in effect.
4796
4797 if not Debug_Flag_Underscore_TT then
4798 return;
4799 end if;
4800
4801 Indent_By (Indent);
4802 Write_Str ("library graph edge (Edge_");
4803 Write_Int (Int (Edge));
4804 Write_Str (")");
4805 Write_Eol;
4806
4807 Indent_By (Attr_Indent);
4808 Write_Str ("kind = ");
4809 Write_Str (Kind (G, Edge)'Img);
4810 Write_Eol;
4811
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));
4817 Write_Eol;
4818
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));
4824 Write_Eol;
4825 end Trace_Edge;
4826
4827 ---------------
4828 -- Trace_Eol --
4829 ---------------
4830
4831 procedure Trace_Eol is
4832 begin
4833 -- Nothing to do when switch -d_T (output elaboration order and cycle
4834 -- detection trace information) is not in effect.
4835
4836 if not Debug_Flag_Underscore_TT then
4837 return;
4838 end if;
4839
4840 Write_Eol;
4841 end Trace_Eol;
4842
4843 ------------------
4844 -- Trace_Vertex --
4845 ------------------
4846
4847 procedure Trace_Vertex
4848 (G : Library_Graph;
4849 Vertex : Library_Graph_Vertex_Id;
4850 Indent : Indentation_Level)
4851 is
4852 Attr_Indent : constant Indentation_Level :=
4853 Indent + Nested_Indentation;
4854
4855 begin
4856 pragma Assert (Present (G));
4857 pragma Assert (Present (Vertex));
4858
4859 -- Nothing to do when switch -d_T (output elaboration order and cycle
4860 -- detection trace information) is not in effect.
4861
4862 if not Debug_Flag_Underscore_TT then
4863 return;
4864 end if;
4865
4866 Indent_By (Indent);
4867 Write_Str ("library graph vertex (Vertex_");
4868 Write_Int (Int (Vertex));
4869 Write_Str (")");
4870 Write_Eol;
4871
4872 Indent_By (Attr_Indent);
4873 Write_Str ("Component (Comp_Id_");
4874 Write_Int (Int (Component (G, Vertex)));
4875 Write_Str (")");
4876 Write_Eol;
4877
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));
4883 Write_Eol;
4884 end Trace_Vertex;
4885
4886 ----------
4887 -- Unit --
4888 ----------
4889
4890 function Unit
4891 (G : Library_Graph;
4892 Vertex : Library_Graph_Vertex_Id) return Unit_Id
4893 is
4894 begin
4895 pragma Assert (Present (G));
4896 pragma Assert (Present (Vertex));
4897
4898 return Get_LGV_Attributes (G, Vertex).Unit;
4899 end Unit;
4900
4901 ---------------------------------
4902 -- Update_Pending_Predecessors --
4903 ---------------------------------
4904
4905 procedure Update_Pending_Predecessors
4906 (Strong_Predecessors : in out Natural;
4907 Weak_Predecessors : in out Natural;
4908 Update_Weak : Boolean;
4909 Value : Integer)
4910 is
4911 begin
4912 if Update_Weak then
4913 Weak_Predecessors := Weak_Predecessors + Value;
4914 else
4915 Strong_Predecessors := Strong_Predecessors + Value;
4916 end if;
4917 end Update_Pending_Predecessors;
4918
4919 -----------------------------------------------
4920 -- Update_Pending_Predecessors_Of_Components --
4921 -----------------------------------------------
4922
4923 procedure Update_Pending_Predecessors_Of_Components
4924 (G : Library_Graph)
4925 is
4926 Edge : Library_Graph_Edge_Id;
4927 Iter : All_Edge_Iterator;
4928
4929 begin
4930 pragma Assert (Present (G));
4931
4932 Iter := Iterate_All_Edges (G);
4933 while Has_Next (Iter) loop
4934 Next (Iter, Edge);
4935
4936 Update_Pending_Predecessors_Of_Components (G, Edge);
4937 end loop;
4938 end Update_Pending_Predecessors_Of_Components;
4939
4940 -----------------------------------------------
4941 -- Update_Pending_Predecessors_Of_Components --
4942 -----------------------------------------------
4943
4944 procedure Update_Pending_Predecessors_Of_Components
4945 (G : Library_Graph;
4946 Edge : Library_Graph_Edge_Id)
4947 is
4948 pragma Assert (Present (G));
4949 pragma Assert (Present (Edge));
4950
4951 Pred_Comp : constant Component_Id :=
4952 Component (G, Predecessor (G, Edge));
4953 Succ_Comp : constant Component_Id :=
4954 Component (G, Successor (G, Edge));
4955
4956 pragma Assert (Present (Pred_Comp));
4957 pragma Assert (Present (Succ_Comp));
4958
4959 begin
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.
4963
4964 if Pred_Comp /= Succ_Comp then
4965 Increment_Pending_Predecessors
4966 (G => G,
4967 Comp => Succ_Comp,
4968 Edge => Edge);
4969 end if;
4970 end Update_Pending_Predecessors_Of_Components;
4971 end Library_Graphs;
4972
4973 -------------
4974 -- Present --
4975 -------------
4976
4977 function Present (Edge : Invocation_Graph_Edge_Id) return Boolean is
4978 begin
4979 return Edge /= No_Invocation_Graph_Edge;
4980 end Present;
4981
4982 -------------
4983 -- Present --
4984 -------------
4985
4986 function Present (Vertex : Invocation_Graph_Vertex_Id) return Boolean is
4987 begin
4988 return Vertex /= No_Invocation_Graph_Vertex;
4989 end Present;
4990
4991 -------------
4992 -- Present --
4993 -------------
4994
4995 function Present (Cycle : Library_Graph_Cycle_Id) return Boolean is
4996 begin
4997 return Cycle /= No_Library_Graph_Cycle;
4998 end Present;
4999
5000 -------------
5001 -- Present --
5002 -------------
5003
5004 function Present (Edge : Library_Graph_Edge_Id) return Boolean is
5005 begin
5006 return Edge /= No_Library_Graph_Edge;
5007 end Present;
5008
5009 -------------
5010 -- Present --
5011 -------------
5012
5013 function Present (Vertex : Library_Graph_Vertex_Id) return Boolean is
5014 begin
5015 return Vertex /= No_Library_Graph_Vertex;
5016 end Present;
5017
5018 --------------------------
5019 -- Sequence_Next_Edge --
5020 --------------------------
5021
5022 IGE_Sequencer : Invocation_Graph_Edge_Id := First_Invocation_Graph_Edge;
5023 -- The counter for invocation graph edges. Do not directly manipulate its
5024 -- value.
5025
5026 function Sequence_Next_Edge return Invocation_Graph_Edge_Id is
5027 Edge : constant Invocation_Graph_Edge_Id := IGE_Sequencer;
5028
5029 begin
5030 IGE_Sequencer := IGE_Sequencer + 1;
5031 return Edge;
5032 end Sequence_Next_Edge;
5033
5034 --------------------------
5035 -- Sequence_Next_Vertex --
5036 --------------------------
5037
5038 IGV_Sequencer : Invocation_Graph_Vertex_Id := First_Invocation_Graph_Vertex;
5039 -- The counter for invocation graph vertices. Do not directly manipulate
5040 -- its value.
5041
5042 function Sequence_Next_Vertex return Invocation_Graph_Vertex_Id is
5043 Vertex : constant Invocation_Graph_Vertex_Id := IGV_Sequencer;
5044
5045 begin
5046 IGV_Sequencer := IGV_Sequencer + 1;
5047 return Vertex;
5048 end Sequence_Next_Vertex;
5049
5050 --------------------------
5051 -- Sequence_Next_Cycle --
5052 --------------------------
5053
5054 LGC_Sequencer : Library_Graph_Cycle_Id := First_Library_Graph_Cycle;
5055 -- The counter for library graph cycles. Do not directly manipulate its
5056 -- value.
5057
5058 function Sequence_Next_Cycle return Library_Graph_Cycle_Id is
5059 Cycle : constant Library_Graph_Cycle_Id := LGC_Sequencer;
5060
5061 begin
5062 LGC_Sequencer := LGC_Sequencer + 1;
5063 return Cycle;
5064 end Sequence_Next_Cycle;
5065
5066 --------------------------
5067 -- Sequence_Next_Edge --
5068 --------------------------
5069
5070 LGE_Sequencer : Library_Graph_Edge_Id := First_Library_Graph_Edge;
5071 -- The counter for library graph edges. Do not directly manipulate its
5072 -- value.
5073
5074 function Sequence_Next_Edge return Library_Graph_Edge_Id is
5075 Edge : constant Library_Graph_Edge_Id := LGE_Sequencer;
5076
5077 begin
5078 LGE_Sequencer := LGE_Sequencer + 1;
5079 return Edge;
5080 end Sequence_Next_Edge;
5081
5082 --------------------------
5083 -- Sequence_Next_Vertex --
5084 --------------------------
5085
5086 LGV_Sequencer : Library_Graph_Vertex_Id := First_Library_Graph_Vertex;
5087 -- The counter for library graph vertices. Do not directly manipulate its
5088 -- value.
5089
5090 function Sequence_Next_Vertex return Library_Graph_Vertex_Id is
5091 Vertex : constant Library_Graph_Vertex_Id := LGV_Sequencer;
5092
5093 begin
5094 LGV_Sequencer := LGV_Sequencer + 1;
5095 return Vertex;
5096 end Sequence_Next_Vertex;
5097
5098 end Bindo.Graphs;