Add mi_thunk support for vcalls on hppa.
[official-gcc.git] / gcc / ada / nlists.adb
blob02859c7128b94fcc33e35b4c692928f4bcac7534
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- N L I S T S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2020, 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 ------------------------------------------------------------------------------
26 -- WARNING: There is a C version of this package. Any changes to this source
27 -- file must be properly reflected in the corresponding C header a-nlists.h
29 with Alloc;
30 with Atree; use Atree;
31 with Debug; use Debug;
32 with Output; use Output;
33 with Sinfo; use Sinfo;
34 with Table;
36 package body Nlists is
37 Locked : Boolean := False;
38 -- Compiling with assertions enabled, list contents modifications are
39 -- permitted only when this switch is set to False; compiling without
40 -- assertions this lock has no effect.
42 use Atree_Private_Part;
43 -- Get access to Nodes table
45 ----------------------------------
46 -- Implementation of Node Lists --
47 ----------------------------------
49 -- A node list is represented by a list header which contains
50 -- three fields:
52 type List_Header is record
53 First : Node_Or_Entity_Id;
54 -- Pointer to first node in list. Empty if list is empty
56 Last : Node_Or_Entity_Id;
57 -- Pointer to last node in list. Empty if list is empty
59 Parent : Node_Id;
60 -- Pointer to parent of list. Empty if list has no parent
61 end record;
63 -- The node lists are stored in a table indexed by List_Id values
65 package Lists is new Table.Table (
66 Table_Component_Type => List_Header,
67 Table_Index_Type => List_Id'Base,
68 Table_Low_Bound => First_List_Id,
69 Table_Initial => Alloc.Lists_Initial,
70 Table_Increment => Alloc.Lists_Increment,
71 Table_Name => "Lists");
73 -- The nodes in the list all have the In_List flag set, and their Link
74 -- fields (which otherwise point to the parent) contain the List_Id of
75 -- the list header giving immediate access to the list containing the
76 -- node, and its parent and first and last elements.
78 -- Two auxiliary tables, indexed by Node_Id values and built in parallel
79 -- with the main nodes table and always having the same size contain the
80 -- list link values that allow locating the previous and next node in a
81 -- list. The entries in these tables are valid only if the In_List flag
82 -- is set in the corresponding node. Next_Node is Empty at the end of a
83 -- list and Prev_Node is Empty at the start of a list.
85 package Next_Node is new Table.Table (
86 Table_Component_Type => Node_Or_Entity_Id,
87 Table_Index_Type => Node_Or_Entity_Id'Base,
88 Table_Low_Bound => First_Node_Id,
89 Table_Initial => Alloc.Nodes_Initial,
90 Table_Increment => Alloc.Nodes_Increment,
91 Release_Threshold => Alloc.Nodes_Release_Threshold,
92 Table_Name => "Next_Node");
94 package Prev_Node is new Table.Table (
95 Table_Component_Type => Node_Or_Entity_Id,
96 Table_Index_Type => Node_Or_Entity_Id'Base,
97 Table_Low_Bound => First_Node_Id,
98 Table_Initial => Alloc.Nodes_Initial,
99 Table_Increment => Alloc.Nodes_Increment,
100 Table_Name => "Prev_Node");
102 -----------------------
103 -- Local Subprograms --
104 -----------------------
106 procedure Set_First (List : List_Id; To : Node_Or_Entity_Id);
107 pragma Inline (Set_First);
108 -- Sets First field of list header List to reference To
110 procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id);
111 pragma Inline (Set_Last);
112 -- Sets Last field of list header List to reference To
114 procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id);
115 pragma Inline (Set_List_Link);
116 -- Sets list link of Node to list header To
118 procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id);
119 pragma Inline (Set_Next);
120 -- Sets the Next_Node pointer for Node to reference To
122 procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id);
123 pragma Inline (Set_Prev);
124 -- Sets the Prev_Node pointer for Node to reference To
126 --------------------------
127 -- Allocate_List_Tables --
128 --------------------------
130 procedure Allocate_List_Tables (N : Node_Or_Entity_Id) is
131 Old_Last : constant Node_Or_Entity_Id'Base := Next_Node.Last;
133 begin
134 pragma Assert (N >= Old_Last);
135 Next_Node.Set_Last (N);
136 Prev_Node.Set_Last (N);
138 -- Make sure we have no uninitialized junk in any new entries added.
140 for J in Old_Last + 1 .. N loop
141 Next_Node.Table (J) := Empty;
142 Prev_Node.Table (J) := Empty;
143 end loop;
144 end Allocate_List_Tables;
146 ------------
147 -- Append --
148 ------------
150 procedure Append (Node : Node_Or_Entity_Id; To : List_Id) is
151 L : constant Node_Or_Entity_Id := Last (To);
153 procedure Append_Debug;
154 pragma Inline (Append_Debug);
155 -- Output debug information if Debug_Flag_N set
157 ------------------
158 -- Append_Debug --
159 ------------------
161 procedure Append_Debug is
162 begin
163 if Debug_Flag_N then
164 Write_Str ("Append node ");
165 Write_Int (Int (Node));
166 Write_Str (" to list ");
167 Write_Int (Int (To));
168 Write_Eol;
169 end if;
170 end Append_Debug;
172 -- Start of processing for Append
174 begin
175 pragma Assert (not Is_List_Member (Node));
177 if Node = Error then
178 return;
179 end if;
181 pragma Debug (Append_Debug);
183 if No (L) then
184 Set_First (To, Node);
185 else
186 Set_Next (L, Node);
187 end if;
189 Set_Last (To, Node);
191 Nodes.Table (Node).In_List := True;
193 Set_Next (Node, Empty);
194 Set_Prev (Node, L);
195 Set_List_Link (Node, To);
196 end Append;
198 -----------------
199 -- Append_List --
200 -----------------
202 procedure Append_List (List : List_Id; To : List_Id) is
203 procedure Append_List_Debug;
204 pragma Inline (Append_List_Debug);
205 -- Output debug information if Debug_Flag_N set
207 -----------------------
208 -- Append_List_Debug --
209 -----------------------
211 procedure Append_List_Debug is
212 begin
213 if Debug_Flag_N then
214 Write_Str ("Append list ");
215 Write_Int (Int (List));
216 Write_Str (" to list ");
217 Write_Int (Int (To));
218 Write_Eol;
219 end if;
220 end Append_List_Debug;
222 -- Start of processing for Append_List
224 begin
225 if Is_Empty_List (List) then
226 return;
228 else
229 declare
230 L : constant Node_Or_Entity_Id := Last (To);
231 F : constant Node_Or_Entity_Id := First (List);
232 N : Node_Or_Entity_Id;
234 begin
235 pragma Debug (Append_List_Debug);
237 N := F;
238 loop
239 Set_List_Link (N, To);
240 Next (N);
241 exit when No (N);
242 end loop;
244 if No (L) then
245 Set_First (To, F);
246 else
247 Set_Next (L, F);
248 end if;
250 Set_Prev (F, L);
251 Set_Last (To, Last (List));
253 Set_First (List, Empty);
254 Set_Last (List, Empty);
255 end;
256 end if;
257 end Append_List;
259 --------------------
260 -- Append_List_To --
261 --------------------
263 procedure Append_List_To (To : List_Id; List : List_Id) is
264 begin
265 Append_List (List, To);
266 end Append_List_To;
268 ----------------
269 -- Append_New --
270 ----------------
272 procedure Append_New (Node : Node_Or_Entity_Id; To : in out List_Id) is
273 begin
274 if No (To) then
275 To := New_List;
276 end if;
278 Append (Node, To);
279 end Append_New;
281 -------------------
282 -- Append_New_To --
283 -------------------
285 procedure Append_New_To (To : in out List_Id; Node : Node_Or_Entity_Id) is
286 begin
287 Append_New (Node, To);
288 end Append_New_To;
290 ---------------
291 -- Append_To --
292 ---------------
294 procedure Append_To (To : List_Id; Node : Node_Or_Entity_Id) is
295 begin
296 Append (Node, To);
297 end Append_To;
299 -----------
300 -- First --
301 -----------
303 function First (List : List_Id) return Node_Or_Entity_Id is
304 begin
305 if List = No_List then
306 return Empty;
307 else
308 pragma Assert (List <= Lists.Last);
309 return Lists.Table (List).First;
310 end if;
311 end First;
313 ----------------------
314 -- First_Non_Pragma --
315 ----------------------
317 function First_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is
318 N : constant Node_Or_Entity_Id := First (List);
319 begin
320 if Nkind (N) /= N_Pragma
321 and then
322 Nkind (N) /= N_Null_Statement
323 then
324 return N;
325 else
326 return Next_Non_Pragma (N);
327 end if;
328 end First_Non_Pragma;
330 ----------------
331 -- Initialize --
332 ----------------
334 procedure Initialize is
335 begin
336 Lists.Init;
337 Next_Node.Init;
338 Prev_Node.Init;
340 -- Allocate Error_List list header
342 Lists.Increment_Last;
343 Set_Parent (Error_List, Empty);
344 Set_First (Error_List, Empty);
345 Set_Last (Error_List, Empty);
346 end Initialize;
348 ------------------
349 -- In_Same_List --
350 ------------------
352 function In_Same_List (N1, N2 : Node_Or_Entity_Id) return Boolean is
353 begin
354 return List_Containing (N1) = List_Containing (N2);
355 end In_Same_List;
357 ------------------
358 -- Insert_After --
359 ------------------
361 procedure Insert_After
362 (After : Node_Or_Entity_Id;
363 Node : Node_Or_Entity_Id)
365 procedure Insert_After_Debug;
366 pragma Inline (Insert_After_Debug);
367 -- Output debug information if Debug_Flag_N set
369 ------------------------
370 -- Insert_After_Debug --
371 ------------------------
373 procedure Insert_After_Debug is
374 begin
375 if Debug_Flag_N then
376 Write_Str ("Insert node");
377 Write_Int (Int (Node));
378 Write_Str (" after node ");
379 Write_Int (Int (After));
380 Write_Eol;
381 end if;
382 end Insert_After_Debug;
384 -- Start of processing for Insert_After
386 begin
387 pragma Assert
388 (Is_List_Member (After) and then not Is_List_Member (Node));
390 if Node = Error then
391 return;
392 end if;
394 pragma Debug (Insert_After_Debug);
396 declare
397 Before : constant Node_Or_Entity_Id := Next (After);
398 LC : constant List_Id := List_Containing (After);
400 begin
401 if Present (Before) then
402 Set_Prev (Before, Node);
403 else
404 Set_Last (LC, Node);
405 end if;
407 Set_Next (After, Node);
409 Nodes.Table (Node).In_List := True;
411 Set_Prev (Node, After);
412 Set_Next (Node, Before);
413 Set_List_Link (Node, LC);
414 end;
415 end Insert_After;
417 -------------------
418 -- Insert_Before --
419 -------------------
421 procedure Insert_Before
422 (Before : Node_Or_Entity_Id;
423 Node : Node_Or_Entity_Id)
425 procedure Insert_Before_Debug;
426 pragma Inline (Insert_Before_Debug);
427 -- Output debug information if Debug_Flag_N set
429 -------------------------
430 -- Insert_Before_Debug --
431 -------------------------
433 procedure Insert_Before_Debug is
434 begin
435 if Debug_Flag_N then
436 Write_Str ("Insert node");
437 Write_Int (Int (Node));
438 Write_Str (" before node ");
439 Write_Int (Int (Before));
440 Write_Eol;
441 end if;
442 end Insert_Before_Debug;
444 -- Start of processing for Insert_Before
446 begin
447 pragma Assert
448 (Is_List_Member (Before) and then not Is_List_Member (Node));
450 if Node = Error then
451 return;
452 end if;
454 pragma Debug (Insert_Before_Debug);
456 declare
457 After : constant Node_Or_Entity_Id := Prev (Before);
458 LC : constant List_Id := List_Containing (Before);
460 begin
461 if Present (After) then
462 Set_Next (After, Node);
463 else
464 Set_First (LC, Node);
465 end if;
467 Set_Prev (Before, Node);
469 Nodes.Table (Node).In_List := True;
471 Set_Prev (Node, After);
472 Set_Next (Node, Before);
473 Set_List_Link (Node, LC);
474 end;
475 end Insert_Before;
477 -----------------------
478 -- Insert_List_After --
479 -----------------------
481 procedure Insert_List_After (After : Node_Or_Entity_Id; List : List_Id) is
483 procedure Insert_List_After_Debug;
484 pragma Inline (Insert_List_After_Debug);
485 -- Output debug information if Debug_Flag_N set
487 -----------------------------
488 -- Insert_List_After_Debug --
489 -----------------------------
491 procedure Insert_List_After_Debug is
492 begin
493 if Debug_Flag_N then
494 Write_Str ("Insert list ");
495 Write_Int (Int (List));
496 Write_Str (" after node ");
497 Write_Int (Int (After));
498 Write_Eol;
499 end if;
500 end Insert_List_After_Debug;
502 -- Start of processing for Insert_List_After
504 begin
505 pragma Assert (Is_List_Member (After));
507 if Is_Empty_List (List) then
508 return;
510 else
511 declare
512 Before : constant Node_Or_Entity_Id := Next (After);
513 LC : constant List_Id := List_Containing (After);
514 F : constant Node_Or_Entity_Id := First (List);
515 L : constant Node_Or_Entity_Id := Last (List);
516 N : Node_Or_Entity_Id;
518 begin
519 pragma Debug (Insert_List_After_Debug);
521 N := F;
522 loop
523 Set_List_Link (N, LC);
524 exit when N = L;
525 Next (N);
526 end loop;
528 if Present (Before) then
529 Set_Prev (Before, L);
530 else
531 Set_Last (LC, L);
532 end if;
534 Set_Next (After, F);
535 Set_Prev (F, After);
536 Set_Next (L, Before);
538 Set_First (List, Empty);
539 Set_Last (List, Empty);
540 end;
541 end if;
542 end Insert_List_After;
544 ------------------------
545 -- Insert_List_Before --
546 ------------------------
548 procedure Insert_List_Before (Before : Node_Or_Entity_Id; List : List_Id) is
550 procedure Insert_List_Before_Debug;
551 pragma Inline (Insert_List_Before_Debug);
552 -- Output debug information if Debug_Flag_N set
554 ------------------------------
555 -- Insert_List_Before_Debug --
556 ------------------------------
558 procedure Insert_List_Before_Debug is
559 begin
560 if Debug_Flag_N then
561 Write_Str ("Insert list ");
562 Write_Int (Int (List));
563 Write_Str (" before node ");
564 Write_Int (Int (Before));
565 Write_Eol;
566 end if;
567 end Insert_List_Before_Debug;
569 -- Start of processing for Insert_List_Before
571 begin
572 pragma Assert (Is_List_Member (Before));
574 if Is_Empty_List (List) then
575 return;
577 else
578 declare
579 After : constant Node_Or_Entity_Id := Prev (Before);
580 LC : constant List_Id := List_Containing (Before);
581 F : constant Node_Or_Entity_Id := First (List);
582 L : constant Node_Or_Entity_Id := Last (List);
583 N : Node_Or_Entity_Id;
585 begin
586 pragma Debug (Insert_List_Before_Debug);
588 N := F;
589 loop
590 Set_List_Link (N, LC);
591 exit when N = L;
592 Next (N);
593 end loop;
595 if Present (After) then
596 Set_Next (After, F);
597 else
598 Set_First (LC, F);
599 end if;
601 Set_Prev (Before, L);
602 Set_Prev (F, After);
603 Set_Next (L, Before);
605 Set_First (List, Empty);
606 Set_Last (List, Empty);
607 end;
608 end if;
609 end Insert_List_Before;
611 -------------------
612 -- Is_Empty_List --
613 -------------------
615 function Is_Empty_List (List : List_Id) return Boolean is
616 begin
617 return First (List) = Empty;
618 end Is_Empty_List;
620 --------------------
621 -- Is_List_Member --
622 --------------------
624 function Is_List_Member (Node : Node_Or_Entity_Id) return Boolean is
625 begin
626 return Nodes.Table (Node).In_List;
627 end Is_List_Member;
629 -----------------------
630 -- Is_Non_Empty_List --
631 -----------------------
633 function Is_Non_Empty_List (List : List_Id) return Boolean is
634 begin
635 return First (List) /= Empty;
636 end Is_Non_Empty_List;
638 ----------
639 -- Last --
640 ----------
642 function Last (List : List_Id) return Node_Or_Entity_Id is
643 begin
644 pragma Assert (List <= Lists.Last);
645 return Lists.Table (List).Last;
646 end Last;
648 ------------------
649 -- Last_List_Id --
650 ------------------
652 function Last_List_Id return List_Id is
653 begin
654 return Lists.Last;
655 end Last_List_Id;
657 ---------------------
658 -- Last_Non_Pragma --
659 ---------------------
661 function Last_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is
662 N : constant Node_Or_Entity_Id := Last (List);
663 begin
664 if Nkind (N) /= N_Pragma then
665 return N;
666 else
667 return Prev_Non_Pragma (N);
668 end if;
669 end Last_Non_Pragma;
671 ---------------------
672 -- List_Containing --
673 ---------------------
675 function List_Containing (Node : Node_Or_Entity_Id) return List_Id is
676 begin
677 pragma Assert (Is_List_Member (Node));
678 return List_Id (Nodes.Table (Node).Link);
679 end List_Containing;
681 -----------------
682 -- List_Length --
683 -----------------
685 function List_Length (List : List_Id) return Nat is
686 Result : Nat;
687 Node : Node_Or_Entity_Id;
689 begin
690 Result := 0;
691 Node := First (List);
692 while Present (Node) loop
693 Result := Result + 1;
694 Next (Node);
695 end loop;
697 return Result;
698 end List_Length;
700 -------------------
701 -- Lists_Address --
702 -------------------
704 function Lists_Address return System.Address is
705 begin
706 return Lists.Table (First_List_Id)'Address;
707 end Lists_Address;
709 ----------
710 -- Lock --
711 ----------
713 procedure Lock is
714 begin
715 Lists.Release;
716 Lists.Locked := True;
717 Prev_Node.Release;
718 Prev_Node.Locked := True;
719 Next_Node.Release;
720 Next_Node.Locked := True;
721 end Lock;
723 ----------------
724 -- Lock_Lists --
725 ----------------
727 procedure Lock_Lists is
728 begin
729 pragma Assert (not Locked);
730 Locked := True;
731 end Lock_Lists;
733 -------------------
734 -- New_Copy_List --
735 -------------------
737 function New_Copy_List (List : List_Id) return List_Id is
738 NL : List_Id;
739 E : Node_Or_Entity_Id;
741 begin
742 if List = No_List then
743 return No_List;
745 else
746 NL := New_List;
747 E := First (List);
749 while Present (E) loop
750 Append (New_Copy (E), NL);
751 Next (E);
752 end loop;
754 return NL;
755 end if;
756 end New_Copy_List;
758 ----------------------------
759 -- New_Copy_List_Original --
760 ----------------------------
762 function New_Copy_List_Original (List : List_Id) return List_Id is
763 NL : List_Id;
764 E : Node_Or_Entity_Id;
766 begin
767 if List = No_List then
768 return No_List;
770 else
771 NL := New_List;
773 E := First (List);
774 while Present (E) loop
775 if Comes_From_Source (E) then
776 Append (New_Copy (E), NL);
777 end if;
779 Next (E);
780 end loop;
782 return NL;
783 end if;
784 end New_Copy_List_Original;
786 --------------
787 -- New_List --
788 --------------
790 function New_List return List_Id is
792 procedure New_List_Debug;
793 pragma Inline (New_List_Debug);
794 -- Output debugging information if Debug_Flag_N is set
796 --------------------
797 -- New_List_Debug --
798 --------------------
800 procedure New_List_Debug is
801 begin
802 if Debug_Flag_N then
803 Write_Str ("Allocate new list, returned ID = ");
804 Write_Int (Int (Lists.Last));
805 Write_Eol;
806 end if;
807 end New_List_Debug;
809 -- Start of processing for New_List
811 begin
812 Lists.Increment_Last;
814 declare
815 List : constant List_Id := Lists.Last;
817 begin
818 Set_Parent (List, Empty);
819 Set_First (List, Empty);
820 Set_Last (List, Empty);
822 pragma Debug (New_List_Debug);
823 return (List);
824 end;
825 end New_List;
827 -- Since the one argument case is common, we optimize to build the right
828 -- list directly, rather than first building an empty list and then doing
829 -- the insertion, which results in some unnecessary work.
831 function New_List (Node : Node_Or_Entity_Id) return List_Id is
833 procedure New_List_Debug;
834 pragma Inline (New_List_Debug);
835 -- Output debugging information if Debug_Flag_N is set
837 --------------------
838 -- New_List_Debug --
839 --------------------
841 procedure New_List_Debug is
842 begin
843 if Debug_Flag_N then
844 Write_Str ("Allocate new list, returned ID = ");
845 Write_Int (Int (Lists.Last));
846 Write_Eol;
847 end if;
848 end New_List_Debug;
850 -- Start of processing for New_List
852 begin
853 if Node = Error then
854 return New_List;
856 else
857 pragma Assert (not Is_List_Member (Node));
859 Lists.Increment_Last;
861 declare
862 List : constant List_Id := Lists.Last;
864 begin
865 Set_Parent (List, Empty);
866 Set_First (List, Node);
867 Set_Last (List, Node);
869 Nodes.Table (Node).In_List := True;
870 Set_List_Link (Node, List);
871 Set_Prev (Node, Empty);
872 Set_Next (Node, Empty);
873 pragma Debug (New_List_Debug);
874 return List;
875 end;
876 end if;
877 end New_List;
879 function New_List
880 (Node1 : Node_Or_Entity_Id;
881 Node2 : Node_Or_Entity_Id) return List_Id
883 L : constant List_Id := New_List (Node1);
884 begin
885 Append (Node2, L);
886 return L;
887 end New_List;
889 function New_List
890 (Node1 : Node_Or_Entity_Id;
891 Node2 : Node_Or_Entity_Id;
892 Node3 : Node_Or_Entity_Id) return List_Id
894 L : constant List_Id := New_List (Node1);
895 begin
896 Append (Node2, L);
897 Append (Node3, L);
898 return L;
899 end New_List;
901 function New_List
902 (Node1 : Node_Or_Entity_Id;
903 Node2 : Node_Or_Entity_Id;
904 Node3 : Node_Or_Entity_Id;
905 Node4 : Node_Or_Entity_Id) return List_Id
907 L : constant List_Id := New_List (Node1);
908 begin
909 Append (Node2, L);
910 Append (Node3, L);
911 Append (Node4, L);
912 return L;
913 end New_List;
915 function New_List
916 (Node1 : Node_Or_Entity_Id;
917 Node2 : Node_Or_Entity_Id;
918 Node3 : Node_Or_Entity_Id;
919 Node4 : Node_Or_Entity_Id;
920 Node5 : Node_Or_Entity_Id) return List_Id
922 L : constant List_Id := New_List (Node1);
923 begin
924 Append (Node2, L);
925 Append (Node3, L);
926 Append (Node4, L);
927 Append (Node5, L);
928 return L;
929 end New_List;
931 function New_List
932 (Node1 : Node_Or_Entity_Id;
933 Node2 : Node_Or_Entity_Id;
934 Node3 : Node_Or_Entity_Id;
935 Node4 : Node_Or_Entity_Id;
936 Node5 : Node_Or_Entity_Id;
937 Node6 : Node_Or_Entity_Id) return List_Id
939 L : constant List_Id := New_List (Node1);
940 begin
941 Append (Node2, L);
942 Append (Node3, L);
943 Append (Node4, L);
944 Append (Node5, L);
945 Append (Node6, L);
946 return L;
947 end New_List;
949 ----------
950 -- Next --
951 ----------
953 function Next (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is
954 begin
955 pragma Assert (Is_List_Member (Node));
956 return Next_Node.Table (Node);
957 end Next;
959 procedure Next (Node : in out Node_Or_Entity_Id) is
960 begin
961 Node := Next (Node);
962 end Next;
964 -----------------------
965 -- Next_Node_Address --
966 -----------------------
968 function Next_Node_Address return System.Address is
969 begin
970 return Next_Node.Table (First_Node_Id)'Address;
971 end Next_Node_Address;
973 ---------------------
974 -- Next_Non_Pragma --
975 ---------------------
977 function Next_Non_Pragma
978 (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
980 N : Node_Or_Entity_Id;
982 begin
983 N := Node;
984 loop
985 Next (N);
986 exit when Nkind (N) not in N_Pragma | N_Null_Statement;
987 end loop;
989 return N;
990 end Next_Non_Pragma;
992 procedure Next_Non_Pragma (Node : in out Node_Or_Entity_Id) is
993 begin
994 Node := Next_Non_Pragma (Node);
995 end Next_Non_Pragma;
997 --------
998 -- No --
999 --------
1001 function No (List : List_Id) return Boolean is
1002 begin
1003 return List = No_List;
1004 end No;
1006 ---------------
1007 -- Num_Lists --
1008 ---------------
1010 function Num_Lists return Nat is
1011 begin
1012 return Int (Lists.Last) - Int (Lists.First) + 1;
1013 end Num_Lists;
1015 ------------
1016 -- Parent --
1017 ------------
1019 function Parent (List : List_Id) return Node_Or_Entity_Id is
1020 begin
1021 pragma Assert (List <= Lists.Last);
1022 return Lists.Table (List).Parent;
1023 end Parent;
1025 ----------
1026 -- Pick --
1027 ----------
1029 function Pick (List : List_Id; Index : Pos) return Node_Or_Entity_Id is
1030 Elmt : Node_Or_Entity_Id;
1032 begin
1033 Elmt := First (List);
1034 for J in 1 .. Index - 1 loop
1035 Next (Elmt);
1036 end loop;
1038 return Elmt;
1039 end Pick;
1041 -------------
1042 -- Prepend --
1043 -------------
1045 procedure Prepend (Node : Node_Or_Entity_Id; To : List_Id) is
1046 F : constant Node_Or_Entity_Id := First (To);
1048 procedure Prepend_Debug;
1049 pragma Inline (Prepend_Debug);
1050 -- Output debug information if Debug_Flag_N set
1052 -------------------
1053 -- Prepend_Debug --
1054 -------------------
1056 procedure Prepend_Debug is
1057 begin
1058 if Debug_Flag_N then
1059 Write_Str ("Prepend node ");
1060 Write_Int (Int (Node));
1061 Write_Str (" to list ");
1062 Write_Int (Int (To));
1063 Write_Eol;
1064 end if;
1065 end Prepend_Debug;
1067 -- Start of processing for Prepend_Debug
1069 begin
1070 pragma Assert (not Is_List_Member (Node));
1072 if Node = Error then
1073 return;
1074 end if;
1076 pragma Debug (Prepend_Debug);
1078 if No (F) then
1079 Set_Last (To, Node);
1080 else
1081 Set_Prev (F, Node);
1082 end if;
1084 Set_First (To, Node);
1086 Nodes.Table (Node).In_List := True;
1088 Set_Next (Node, F);
1089 Set_Prev (Node, Empty);
1090 Set_List_Link (Node, To);
1091 end Prepend;
1093 ------------------
1094 -- Prepend_List --
1095 ------------------
1097 procedure Prepend_List (List : List_Id; To : List_Id) is
1099 procedure Prepend_List_Debug;
1100 pragma Inline (Prepend_List_Debug);
1101 -- Output debug information if Debug_Flag_N set
1103 ------------------------
1104 -- Prepend_List_Debug --
1105 ------------------------
1107 procedure Prepend_List_Debug is
1108 begin
1109 if Debug_Flag_N then
1110 Write_Str ("Prepend list ");
1111 Write_Int (Int (List));
1112 Write_Str (" to list ");
1113 Write_Int (Int (To));
1114 Write_Eol;
1115 end if;
1116 end Prepend_List_Debug;
1118 -- Start of processing for Prepend_List
1120 begin
1121 if Is_Empty_List (List) then
1122 return;
1124 else
1125 declare
1126 F : constant Node_Or_Entity_Id := First (To);
1127 L : constant Node_Or_Entity_Id := Last (List);
1128 N : Node_Or_Entity_Id;
1130 begin
1131 pragma Debug (Prepend_List_Debug);
1133 N := L;
1134 loop
1135 Set_List_Link (N, To);
1136 N := Prev (N);
1137 exit when No (N);
1138 end loop;
1140 if No (F) then
1141 Set_Last (To, L);
1142 else
1143 Set_Next (L, F);
1144 end if;
1146 Set_Prev (F, L);
1147 Set_First (To, First (List));
1149 Set_First (List, Empty);
1150 Set_Last (List, Empty);
1151 end;
1152 end if;
1153 end Prepend_List;
1155 ---------------------
1156 -- Prepend_List_To --
1157 ---------------------
1159 procedure Prepend_List_To (To : List_Id; List : List_Id) is
1160 begin
1161 Prepend_List (List, To);
1162 end Prepend_List_To;
1164 -----------------
1165 -- Prepend_New --
1166 -----------------
1168 procedure Prepend_New (Node : Node_Or_Entity_Id; To : in out List_Id) is
1169 begin
1170 if No (To) then
1171 To := New_List;
1172 end if;
1174 Prepend (Node, To);
1175 end Prepend_New;
1177 --------------------
1178 -- Prepend_New_To --
1179 --------------------
1181 procedure Prepend_New_To (To : in out List_Id; Node : Node_Or_Entity_Id) is
1182 begin
1183 Prepend_New (Node, To);
1184 end Prepend_New_To;
1186 ----------------
1187 -- Prepend_To --
1188 ----------------
1190 procedure Prepend_To (To : List_Id; Node : Node_Or_Entity_Id) is
1191 begin
1192 Prepend (Node, To);
1193 end Prepend_To;
1195 -------------
1196 -- Present --
1197 -------------
1199 function Present (List : List_Id) return Boolean is
1200 begin
1201 return List /= No_List;
1202 end Present;
1204 ----------
1205 -- Prev --
1206 ----------
1208 function Prev (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is
1209 begin
1210 pragma Assert (Is_List_Member (Node));
1211 return Prev_Node.Table (Node);
1212 end Prev;
1214 procedure Prev (Node : in out Node_Or_Entity_Id) is
1215 begin
1216 Node := Prev (Node);
1217 end Prev;
1219 -----------------------
1220 -- Prev_Node_Address --
1221 -----------------------
1223 function Prev_Node_Address return System.Address is
1224 begin
1225 return Prev_Node.Table (First_Node_Id)'Address;
1226 end Prev_Node_Address;
1228 ---------------------
1229 -- Prev_Non_Pragma --
1230 ---------------------
1232 function Prev_Non_Pragma
1233 (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
1235 N : Node_Or_Entity_Id;
1237 begin
1238 N := Node;
1239 loop
1240 N := Prev (N);
1241 exit when Nkind (N) /= N_Pragma;
1242 end loop;
1244 return N;
1245 end Prev_Non_Pragma;
1247 procedure Prev_Non_Pragma (Node : in out Node_Or_Entity_Id) is
1248 begin
1249 Node := Prev_Non_Pragma (Node);
1250 end Prev_Non_Pragma;
1252 ------------
1253 -- Remove --
1254 ------------
1256 procedure Remove (Node : Node_Or_Entity_Id) is
1257 Lst : constant List_Id := List_Containing (Node);
1258 Prv : constant Node_Or_Entity_Id := Prev (Node);
1259 Nxt : constant Node_Or_Entity_Id := Next (Node);
1261 procedure Remove_Debug;
1262 pragma Inline (Remove_Debug);
1263 -- Output debug information if Debug_Flag_N set
1265 ------------------
1266 -- Remove_Debug --
1267 ------------------
1269 procedure Remove_Debug is
1270 begin
1271 if Debug_Flag_N then
1272 Write_Str ("Remove node ");
1273 Write_Int (Int (Node));
1274 Write_Eol;
1275 end if;
1276 end Remove_Debug;
1278 -- Start of processing for Remove
1280 begin
1281 pragma Debug (Remove_Debug);
1283 if No (Prv) then
1284 Set_First (Lst, Nxt);
1285 else
1286 Set_Next (Prv, Nxt);
1287 end if;
1289 if No (Nxt) then
1290 Set_Last (Lst, Prv);
1291 else
1292 Set_Prev (Nxt, Prv);
1293 end if;
1295 Nodes.Table (Node).In_List := False;
1296 Set_Parent (Node, Empty);
1297 end Remove;
1299 -----------------
1300 -- Remove_Head --
1301 -----------------
1303 function Remove_Head (List : List_Id) return Node_Or_Entity_Id is
1304 Frst : constant Node_Or_Entity_Id := First (List);
1306 procedure Remove_Head_Debug;
1307 pragma Inline (Remove_Head_Debug);
1308 -- Output debug information if Debug_Flag_N set
1310 -----------------------
1311 -- Remove_Head_Debug --
1312 -----------------------
1314 procedure Remove_Head_Debug is
1315 begin
1316 if Debug_Flag_N then
1317 Write_Str ("Remove head of list ");
1318 Write_Int (Int (List));
1319 Write_Eol;
1320 end if;
1321 end Remove_Head_Debug;
1323 -- Start of processing for Remove_Head
1325 begin
1326 pragma Debug (Remove_Head_Debug);
1328 if Frst = Empty then
1329 return Empty;
1331 else
1332 declare
1333 Nxt : constant Node_Or_Entity_Id := Next (Frst);
1335 begin
1336 Set_First (List, Nxt);
1338 if No (Nxt) then
1339 Set_Last (List, Empty);
1340 else
1341 Set_Prev (Nxt, Empty);
1342 end if;
1344 Nodes.Table (Frst).In_List := False;
1345 Set_Parent (Frst, Empty);
1346 return Frst;
1347 end;
1348 end if;
1349 end Remove_Head;
1351 -----------------
1352 -- Remove_Next --
1353 -----------------
1355 function Remove_Next
1356 (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
1358 Nxt : constant Node_Or_Entity_Id := Next (Node);
1360 procedure Remove_Next_Debug;
1361 pragma Inline (Remove_Next_Debug);
1362 -- Output debug information if Debug_Flag_N set
1364 -----------------------
1365 -- Remove_Next_Debug --
1366 -----------------------
1368 procedure Remove_Next_Debug is
1369 begin
1370 if Debug_Flag_N then
1371 Write_Str ("Remove next node after ");
1372 Write_Int (Int (Node));
1373 Write_Eol;
1374 end if;
1375 end Remove_Next_Debug;
1377 -- Start of processing for Remove_Next
1379 begin
1380 if Present (Nxt) then
1381 declare
1382 Nxt2 : constant Node_Or_Entity_Id := Next (Nxt);
1383 LC : constant List_Id := List_Containing (Node);
1385 begin
1386 pragma Debug (Remove_Next_Debug);
1387 Set_Next (Node, Nxt2);
1389 if No (Nxt2) then
1390 Set_Last (LC, Node);
1391 else
1392 Set_Prev (Nxt2, Node);
1393 end if;
1395 Nodes.Table (Nxt).In_List := False;
1396 Set_Parent (Nxt, Empty);
1397 end;
1398 end if;
1400 return Nxt;
1401 end Remove_Next;
1403 ---------------
1404 -- Set_First --
1405 ---------------
1407 procedure Set_First (List : List_Id; To : Node_Or_Entity_Id) is
1408 begin
1409 pragma Assert (not Locked);
1410 Lists.Table (List).First := To;
1411 end Set_First;
1413 --------------
1414 -- Set_Last --
1415 --------------
1417 procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id) is
1418 begin
1419 pragma Assert (not Locked);
1420 Lists.Table (List).Last := To;
1421 end Set_Last;
1423 -------------------
1424 -- Set_List_Link --
1425 -------------------
1427 procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id) is
1428 begin
1429 pragma Assert (not Locked);
1430 Nodes.Table (Node).Link := Union_Id (To);
1431 end Set_List_Link;
1433 --------------
1434 -- Set_Next --
1435 --------------
1437 procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is
1438 begin
1439 pragma Assert (not Locked);
1440 Next_Node.Table (Node) := To;
1441 end Set_Next;
1443 ----------------
1444 -- Set_Parent --
1445 ----------------
1447 procedure Set_Parent (List : List_Id; Node : Node_Or_Entity_Id) is
1448 begin
1449 pragma Assert (not Locked);
1450 pragma Assert (List <= Lists.Last);
1451 Lists.Table (List).Parent := Node;
1452 end Set_Parent;
1454 --------------
1455 -- Set_Prev --
1456 --------------
1458 procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is
1459 begin
1460 pragma Assert (not Locked);
1461 Prev_Node.Table (Node) := To;
1462 end Set_Prev;
1464 ------------
1465 -- Unlock --
1466 ------------
1468 procedure Unlock is
1469 begin
1470 Lists.Locked := False;
1471 Prev_Node.Locked := False;
1472 Next_Node.Locked := False;
1473 end Unlock;
1475 ------------------
1476 -- Unlock_Lists --
1477 ------------------
1479 procedure Unlock_Lists is
1480 begin
1481 pragma Assert (Locked);
1482 Locked := False;
1483 end Unlock_Lists;
1485 end Nlists;