1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 -- WARNING: There is a C version of this package. Any changes to this source
33 -- file must be properly reflected in the corresponding C header a-nlists.h
36 with Atree; use Atree;
37 with Debug; use Debug;
38 with Output; use Output;
39 with Sinfo; use Sinfo;
42 package body Nlists is
43 Locked : Boolean := False;
44 -- Compiling with assertions enabled, list contents modifications are
45 -- permitted only when this switch is set to False; compiling without
46 -- assertions this lock has no effect.
48 use Atree_Private_Part;
49 -- Get access to Nodes table
51 ----------------------------------
52 -- Implementation of Node Lists --
53 ----------------------------------
55 -- A node list is represented by a list header which contains
58 type List_Header is record
59 First : Node_Or_Entity_Id;
60 -- Pointer to first node in list. Empty if list is empty
62 Last : Node_Or_Entity_Id;
63 -- Pointer to last node in list. Empty if list is empty
66 -- Pointer to parent of list. Empty if list has no parent
69 -- The node lists are stored in a table indexed by List_Id values
71 package Lists is new Table.Table (
72 Table_Component_Type => List_Header,
73 Table_Index_Type => List_Id'Base,
74 Table_Low_Bound => First_List_Id,
75 Table_Initial => Alloc.Lists_Initial,
76 Table_Increment => Alloc.Lists_Increment,
77 Table_Name => "Lists");
79 -- The nodes in the list all have the In_List flag set, and their Link
80 -- fields (which otherwise point to the parent) contain the List_Id of
81 -- the list header giving immediate access to the list containing the
82 -- node, and its parent and first and last elements.
84 -- Two auxiliary tables, indexed by Node_Id values and built in parallel
85 -- with the main nodes table and always having the same size contain the
86 -- list link values that allow locating the previous and next node in a
87 -- list. The entries in these tables are valid only if the In_List flag
88 -- is set in the corresponding node. Next_Node is Empty at the end of a
89 -- list and Prev_Node is Empty at the start of a list.
91 package Next_Node is new Table.Table (
92 Table_Component_Type => Node_Or_Entity_Id,
93 Table_Index_Type => Node_Or_Entity_Id'Base,
94 Table_Low_Bound => First_Node_Id,
95 Table_Initial => Alloc.Nodes_Initial,
96 Table_Increment => Alloc.Nodes_Increment,
97 Release_Threshold => Alloc.Nodes_Release_Threshold,
98 Table_Name => "Next_Node");
100 package Prev_Node is new Table.Table (
101 Table_Component_Type => Node_Or_Entity_Id,
102 Table_Index_Type => Node_Or_Entity_Id'Base,
103 Table_Low_Bound => First_Node_Id,
104 Table_Initial => Alloc.Nodes_Initial,
105 Table_Increment => Alloc.Nodes_Increment,
106 Table_Name => "Prev_Node");
108 -----------------------
109 -- Local Subprograms --
110 -----------------------
112 procedure Set_First (List : List_Id; To : Node_Or_Entity_Id);
113 pragma Inline (Set_First);
114 -- Sets First field of list header List to reference To
116 procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id);
117 pragma Inline (Set_Last);
118 -- Sets Last field of list header List to reference To
120 procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id);
121 pragma Inline (Set_List_Link);
122 -- Sets list link of Node to list header To
124 procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id);
125 pragma Inline (Set_Next);
126 -- Sets the Next_Node pointer for Node to reference To
128 procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id);
129 pragma Inline (Set_Prev);
130 -- Sets the Prev_Node pointer for Node to reference To
132 --------------------------
133 -- Allocate_List_Tables --
134 --------------------------
136 procedure Allocate_List_Tables (N : Node_Or_Entity_Id) is
137 Old_Last : constant Node_Or_Entity_Id'Base := Next_Node.Last;
140 pragma Assert (N >= Old_Last);
141 Next_Node.Set_Last (N);
142 Prev_Node.Set_Last (N);
144 -- Make sure we have no uninitialized junk in any new entires added.
145 -- This ensures that Tree_Gen will not write out any uninitialized junk.
147 for J in Old_Last + 1 .. N loop
148 Next_Node.Table (J) := Empty;
149 Prev_Node.Table (J) := Empty;
151 end Allocate_List_Tables;
157 procedure Append (Node : Node_Or_Entity_Id; To : List_Id) is
158 L : constant Node_Or_Entity_Id := Last (To);
160 procedure Append_Debug;
161 pragma Inline (Append_Debug);
162 -- Output debug information if Debug_Flag_N set
168 procedure Append_Debug is
171 Write_Str ("Append node ");
172 Write_Int (Int (Node));
173 Write_Str (" to list ");
174 Write_Int (Int (To));
179 -- Start of processing for Append
182 pragma Assert (not Is_List_Member (Node));
188 pragma Debug (Append_Debug);
191 Set_First (To, Node);
198 Nodes.Table (Node).In_List := True;
200 Set_Next (Node, Empty);
202 Set_List_Link (Node, To);
209 procedure Append_List (List : List_Id; To : List_Id) is
210 procedure Append_List_Debug;
211 pragma Inline (Append_List_Debug);
212 -- Output debug information if Debug_Flag_N set
214 -----------------------
215 -- Append_List_Debug --
216 -----------------------
218 procedure Append_List_Debug is
221 Write_Str ("Append list ");
222 Write_Int (Int (List));
223 Write_Str (" to list ");
224 Write_Int (Int (To));
227 end Append_List_Debug;
229 -- Start of processing for Append_List
232 if Is_Empty_List (List) then
237 L : constant Node_Or_Entity_Id := Last (To);
238 F : constant Node_Or_Entity_Id := First (List);
239 N : Node_Or_Entity_Id;
242 pragma Debug (Append_List_Debug);
246 Set_List_Link (N, To);
258 Set_Last (To, Last (List));
260 Set_First (List, Empty);
261 Set_Last (List, Empty);
270 procedure Append_List_To (To : List_Id; List : List_Id) is
272 Append_List (List, To);
279 procedure Append_New (Node : Node_Or_Entity_Id; To : in out List_Id) is
292 procedure Append_New_To (To : in out List_Id; Node : Node_Or_Entity_Id) is
294 Append_New (Node, To);
301 procedure Append_To (To : List_Id; Node : Node_Or_Entity_Id) is
310 function First (List : List_Id) return Node_Or_Entity_Id is
312 if List = No_List then
315 pragma Assert (List <= Lists.Last);
316 return Lists.Table (List).First;
320 ----------------------
321 -- First_Non_Pragma --
322 ----------------------
324 function First_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is
325 N : constant Node_Or_Entity_Id := First (List);
327 if Nkind (N) /= N_Pragma
329 Nkind (N) /= N_Null_Statement
333 return Next_Non_Pragma (N);
335 end First_Non_Pragma;
341 procedure Initialize is
342 E : constant List_Id := Error_List;
349 -- Allocate Error_List list header
351 Lists.Increment_Last;
352 Set_Parent (E, Empty);
353 Set_First (E, Empty);
361 function In_Same_List (N1, N2 : Node_Or_Entity_Id) return Boolean is
363 return List_Containing (N1) = List_Containing (N2);
370 procedure Insert_After
371 (After : Node_Or_Entity_Id;
372 Node : Node_Or_Entity_Id)
374 procedure Insert_After_Debug;
375 pragma Inline (Insert_After_Debug);
376 -- Output debug information if Debug_Flag_N set
378 ------------------------
379 -- Insert_After_Debug --
380 ------------------------
382 procedure Insert_After_Debug is
385 Write_Str ("Insert node");
386 Write_Int (Int (Node));
387 Write_Str (" after node ");
388 Write_Int (Int (After));
391 end Insert_After_Debug;
393 -- Start of processing for Insert_After
397 (Is_List_Member (After) and then not Is_List_Member (Node));
403 pragma Debug (Insert_After_Debug);
406 Before : constant Node_Or_Entity_Id := Next (After);
407 LC : constant List_Id := List_Containing (After);
410 if Present (Before) then
411 Set_Prev (Before, Node);
416 Set_Next (After, Node);
418 Nodes.Table (Node).In_List := True;
420 Set_Prev (Node, After);
421 Set_Next (Node, Before);
422 Set_List_Link (Node, LC);
430 procedure Insert_Before
431 (Before : Node_Or_Entity_Id;
432 Node : Node_Or_Entity_Id)
434 procedure Insert_Before_Debug;
435 pragma Inline (Insert_Before_Debug);
436 -- Output debug information if Debug_Flag_N set
438 -------------------------
439 -- Insert_Before_Debug --
440 -------------------------
442 procedure Insert_Before_Debug is
445 Write_Str ("Insert node");
446 Write_Int (Int (Node));
447 Write_Str (" before node ");
448 Write_Int (Int (Before));
451 end Insert_Before_Debug;
453 -- Start of processing for Insert_Before
457 (Is_List_Member (Before) and then not Is_List_Member (Node));
463 pragma Debug (Insert_Before_Debug);
466 After : constant Node_Or_Entity_Id := Prev (Before);
467 LC : constant List_Id := List_Containing (Before);
470 if Present (After) then
471 Set_Next (After, Node);
473 Set_First (LC, Node);
476 Set_Prev (Before, Node);
478 Nodes.Table (Node).In_List := True;
480 Set_Prev (Node, After);
481 Set_Next (Node, Before);
482 Set_List_Link (Node, LC);
486 -----------------------
487 -- Insert_List_After --
488 -----------------------
490 procedure Insert_List_After (After : Node_Or_Entity_Id; List : List_Id) is
492 procedure Insert_List_After_Debug;
493 pragma Inline (Insert_List_After_Debug);
494 -- Output debug information if Debug_Flag_N set
496 -----------------------------
497 -- Insert_List_After_Debug --
498 -----------------------------
500 procedure Insert_List_After_Debug is
503 Write_Str ("Insert list ");
504 Write_Int (Int (List));
505 Write_Str (" after node ");
506 Write_Int (Int (After));
509 end Insert_List_After_Debug;
511 -- Start of processing for Insert_List_After
514 pragma Assert (Is_List_Member (After));
516 if Is_Empty_List (List) then
521 Before : constant Node_Or_Entity_Id := Next (After);
522 LC : constant List_Id := List_Containing (After);
523 F : constant Node_Or_Entity_Id := First (List);
524 L : constant Node_Or_Entity_Id := Last (List);
525 N : Node_Or_Entity_Id;
528 pragma Debug (Insert_List_After_Debug);
532 Set_List_Link (N, LC);
537 if Present (Before) then
538 Set_Prev (Before, L);
545 Set_Next (L, Before);
547 Set_First (List, Empty);
548 Set_Last (List, Empty);
551 end Insert_List_After;
553 ------------------------
554 -- Insert_List_Before --
555 ------------------------
557 procedure Insert_List_Before (Before : Node_Or_Entity_Id; List : List_Id) is
559 procedure Insert_List_Before_Debug;
560 pragma Inline (Insert_List_Before_Debug);
561 -- Output debug information if Debug_Flag_N set
563 ------------------------------
564 -- Insert_List_Before_Debug --
565 ------------------------------
567 procedure Insert_List_Before_Debug is
570 Write_Str ("Insert list ");
571 Write_Int (Int (List));
572 Write_Str (" before node ");
573 Write_Int (Int (Before));
576 end Insert_List_Before_Debug;
578 -- Start of processing for Insert_List_Before
581 pragma Assert (Is_List_Member (Before));
583 if Is_Empty_List (List) then
588 After : constant Node_Or_Entity_Id := Prev (Before);
589 LC : constant List_Id := List_Containing (Before);
590 F : constant Node_Or_Entity_Id := First (List);
591 L : constant Node_Or_Entity_Id := Last (List);
592 N : Node_Or_Entity_Id;
595 pragma Debug (Insert_List_Before_Debug);
599 Set_List_Link (N, LC);
604 if Present (After) then
610 Set_Prev (Before, L);
612 Set_Next (L, Before);
614 Set_First (List, Empty);
615 Set_Last (List, Empty);
618 end Insert_List_Before;
624 function Is_Empty_List (List : List_Id) return Boolean is
626 return First (List) = Empty;
633 function Is_List_Member (Node : Node_Or_Entity_Id) return Boolean is
635 return Nodes.Table (Node).In_List;
638 -----------------------
639 -- Is_Non_Empty_List --
640 -----------------------
642 function Is_Non_Empty_List (List : List_Id) return Boolean is
644 return First (List) /= Empty;
645 end Is_Non_Empty_List;
651 function Last (List : List_Id) return Node_Or_Entity_Id is
653 pragma Assert (List <= Lists.Last);
654 return Lists.Table (List).Last;
661 function Last_List_Id return List_Id is
666 ---------------------
667 -- Last_Non_Pragma --
668 ---------------------
670 function Last_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is
671 N : constant Node_Or_Entity_Id := Last (List);
673 if Nkind (N) /= N_Pragma then
676 return Prev_Non_Pragma (N);
680 ---------------------
681 -- List_Containing --
682 ---------------------
684 function List_Containing (Node : Node_Or_Entity_Id) return List_Id is
686 pragma Assert (Is_List_Member (Node));
687 return List_Id (Nodes.Table (Node).Link);
694 function List_Length (List : List_Id) return Nat is
696 Node : Node_Or_Entity_Id;
700 Node := First (List);
701 while Present (Node) loop
702 Result := Result + 1;
713 function Lists_Address return System.Address is
715 return Lists.Table (First_List_Id)'Address;
725 Lists.Locked := True;
727 Prev_Node.Locked := True;
729 Next_Node.Locked := True;
736 procedure Lock_Lists is
738 pragma Assert (not Locked);
746 function New_Copy_List (List : List_Id) return List_Id is
748 E : Node_Or_Entity_Id;
751 if List = No_List then
758 while Present (E) loop
759 Append (New_Copy (E), NL);
767 ----------------------------
768 -- New_Copy_List_Original --
769 ----------------------------
771 function New_Copy_List_Original (List : List_Id) return List_Id is
773 E : Node_Or_Entity_Id;
776 if List = No_List then
783 while Present (E) loop
784 if Comes_From_Source (E) then
785 Append (New_Copy (E), NL);
793 end New_Copy_List_Original;
799 function New_List return List_Id is
801 procedure New_List_Debug;
802 pragma Inline (New_List_Debug);
803 -- Output debugging information if Debug_Flag_N is set
809 procedure New_List_Debug is
812 Write_Str ("Allocate new list, returned ID = ");
813 Write_Int (Int (Lists.Last));
818 -- Start of processing for New_List
821 Lists.Increment_Last;
824 List : constant List_Id := Lists.Last;
827 Set_Parent (List, Empty);
828 Set_First (List, Empty);
829 Set_Last (List, Empty);
831 pragma Debug (New_List_Debug);
836 -- Since the one argument case is common, we optimize to build the right
837 -- list directly, rather than first building an empty list and then doing
838 -- the insertion, which results in some unnecessary work.
840 function New_List (Node : Node_Or_Entity_Id) return List_Id is
842 procedure New_List_Debug;
843 pragma Inline (New_List_Debug);
844 -- Output debugging information if Debug_Flag_N is set
850 procedure New_List_Debug is
853 Write_Str ("Allocate new list, returned ID = ");
854 Write_Int (Int (Lists.Last));
859 -- Start of processing for New_List
866 pragma Assert (not Is_List_Member (Node));
868 Lists.Increment_Last;
871 List : constant List_Id := Lists.Last;
874 Set_Parent (List, Empty);
875 Set_First (List, Node);
876 Set_Last (List, Node);
878 Nodes.Table (Node).In_List := True;
879 Set_List_Link (Node, List);
880 Set_Prev (Node, Empty);
881 Set_Next (Node, Empty);
882 pragma Debug (New_List_Debug);
889 (Node1 : Node_Or_Entity_Id;
890 Node2 : Node_Or_Entity_Id) return List_Id
892 L : constant List_Id := New_List (Node1);
899 (Node1 : Node_Or_Entity_Id;
900 Node2 : Node_Or_Entity_Id;
901 Node3 : Node_Or_Entity_Id) return List_Id
903 L : constant List_Id := New_List (Node1);
911 (Node1 : Node_Or_Entity_Id;
912 Node2 : Node_Or_Entity_Id;
913 Node3 : Node_Or_Entity_Id;
914 Node4 : Node_Or_Entity_Id) return List_Id
916 L : constant List_Id := New_List (Node1);
925 (Node1 : Node_Or_Entity_Id;
926 Node2 : Node_Or_Entity_Id;
927 Node3 : Node_Or_Entity_Id;
928 Node4 : Node_Or_Entity_Id;
929 Node5 : Node_Or_Entity_Id) return List_Id
931 L : constant List_Id := New_List (Node1);
941 (Node1 : Node_Or_Entity_Id;
942 Node2 : Node_Or_Entity_Id;
943 Node3 : Node_Or_Entity_Id;
944 Node4 : Node_Or_Entity_Id;
945 Node5 : Node_Or_Entity_Id;
946 Node6 : Node_Or_Entity_Id) return List_Id
948 L : constant List_Id := New_List (Node1);
962 function Next (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is
964 pragma Assert (Is_List_Member (Node));
965 return Next_Node.Table (Node);
968 procedure Next (Node : in out Node_Or_Entity_Id) is
973 -----------------------
974 -- Next_Node_Address --
975 -----------------------
977 function Next_Node_Address return System.Address is
979 return Next_Node.Table (First_Node_Id)'Address;
980 end Next_Node_Address;
982 ---------------------
983 -- Next_Non_Pragma --
984 ---------------------
986 function Next_Non_Pragma
987 (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
989 N : Node_Or_Entity_Id;
995 exit when not Nkind_In (N, N_Pragma, N_Null_Statement);
1001 procedure Next_Non_Pragma (Node : in out Node_Or_Entity_Id) is
1003 Node := Next_Non_Pragma (Node);
1004 end Next_Non_Pragma;
1010 function No (List : List_Id) return Boolean is
1012 return List = No_List;
1019 function Num_Lists return Nat is
1021 return Int (Lists.Last) - Int (Lists.First) + 1;
1028 function Parent (List : List_Id) return Node_Or_Entity_Id is
1030 pragma Assert (List <= Lists.Last);
1031 return Lists.Table (List).Parent;
1038 function Pick (List : List_Id; Index : Pos) return Node_Or_Entity_Id is
1039 Elmt : Node_Or_Entity_Id;
1042 Elmt := First (List);
1043 for J in 1 .. Index - 1 loop
1044 Elmt := Next (Elmt);
1054 procedure Prepend (Node : Node_Or_Entity_Id; To : List_Id) is
1055 F : constant Node_Or_Entity_Id := First (To);
1057 procedure Prepend_Debug;
1058 pragma Inline (Prepend_Debug);
1059 -- Output debug information if Debug_Flag_N set
1065 procedure Prepend_Debug is
1067 if Debug_Flag_N then
1068 Write_Str ("Prepend node ");
1069 Write_Int (Int (Node));
1070 Write_Str (" to list ");
1071 Write_Int (Int (To));
1076 -- Start of processing for Prepend_Debug
1079 pragma Assert (not Is_List_Member (Node));
1081 if Node = Error then
1085 pragma Debug (Prepend_Debug);
1088 Set_Last (To, Node);
1093 Set_First (To, Node);
1095 Nodes.Table (Node).In_List := True;
1098 Set_Prev (Node, Empty);
1099 Set_List_Link (Node, To);
1106 procedure Prepend_List (List : List_Id; To : List_Id) is
1108 procedure Prepend_List_Debug;
1109 pragma Inline (Prepend_List_Debug);
1110 -- Output debug information if Debug_Flag_N set
1112 ------------------------
1113 -- Prepend_List_Debug --
1114 ------------------------
1116 procedure Prepend_List_Debug is
1118 if Debug_Flag_N then
1119 Write_Str ("Prepend list ");
1120 Write_Int (Int (List));
1121 Write_Str (" to list ");
1122 Write_Int (Int (To));
1125 end Prepend_List_Debug;
1127 -- Start of processing for Prepend_List
1130 if Is_Empty_List (List) then
1135 F : constant Node_Or_Entity_Id := First (To);
1136 L : constant Node_Or_Entity_Id := Last (List);
1137 N : Node_Or_Entity_Id;
1140 pragma Debug (Prepend_List_Debug);
1144 Set_List_Link (N, To);
1156 Set_First (To, First (List));
1158 Set_First (List, Empty);
1159 Set_Last (List, Empty);
1164 ---------------------
1165 -- Prepend_List_To --
1166 ---------------------
1168 procedure Prepend_List_To (To : List_Id; List : List_Id) is
1170 Prepend_List (List, To);
1171 end Prepend_List_To;
1177 procedure Prepend_New (Node : Node_Or_Entity_Id; To : in out List_Id) is
1186 --------------------
1187 -- Prepend_New_To --
1188 --------------------
1190 procedure Prepend_New_To (To : in out List_Id; Node : Node_Or_Entity_Id) is
1192 Prepend_New (Node, To);
1199 procedure Prepend_To (To : List_Id; Node : Node_Or_Entity_Id) is
1208 function Present (List : List_Id) return Boolean is
1210 return List /= No_List;
1217 function Prev (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is
1219 pragma Assert (Is_List_Member (Node));
1220 return Prev_Node.Table (Node);
1223 procedure Prev (Node : in out Node_Or_Entity_Id) is
1225 Node := Prev (Node);
1228 -----------------------
1229 -- Prev_Node_Address --
1230 -----------------------
1232 function Prev_Node_Address return System.Address is
1234 return Prev_Node.Table (First_Node_Id)'Address;
1235 end Prev_Node_Address;
1237 ---------------------
1238 -- Prev_Non_Pragma --
1239 ---------------------
1241 function Prev_Non_Pragma
1242 (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
1244 N : Node_Or_Entity_Id;
1250 exit when Nkind (N) /= N_Pragma;
1254 end Prev_Non_Pragma;
1256 procedure Prev_Non_Pragma (Node : in out Node_Or_Entity_Id) is
1258 Node := Prev_Non_Pragma (Node);
1259 end Prev_Non_Pragma;
1265 procedure Remove (Node : Node_Or_Entity_Id) is
1266 Lst : constant List_Id := List_Containing (Node);
1267 Prv : constant Node_Or_Entity_Id := Prev (Node);
1268 Nxt : constant Node_Or_Entity_Id := Next (Node);
1270 procedure Remove_Debug;
1271 pragma Inline (Remove_Debug);
1272 -- Output debug information if Debug_Flag_N set
1278 procedure Remove_Debug is
1280 if Debug_Flag_N then
1281 Write_Str ("Remove node ");
1282 Write_Int (Int (Node));
1287 -- Start of processing for Remove
1290 pragma Debug (Remove_Debug);
1293 Set_First (Lst, Nxt);
1295 Set_Next (Prv, Nxt);
1299 Set_Last (Lst, Prv);
1301 Set_Prev (Nxt, Prv);
1304 Nodes.Table (Node).In_List := False;
1305 Set_Parent (Node, Empty);
1312 function Remove_Head (List : List_Id) return Node_Or_Entity_Id is
1313 Frst : constant Node_Or_Entity_Id := First (List);
1315 procedure Remove_Head_Debug;
1316 pragma Inline (Remove_Head_Debug);
1317 -- Output debug information if Debug_Flag_N set
1319 -----------------------
1320 -- Remove_Head_Debug --
1321 -----------------------
1323 procedure Remove_Head_Debug is
1325 if Debug_Flag_N then
1326 Write_Str ("Remove head of list ");
1327 Write_Int (Int (List));
1330 end Remove_Head_Debug;
1332 -- Start of processing for Remove_Head
1335 pragma Debug (Remove_Head_Debug);
1337 if Frst = Empty then
1342 Nxt : constant Node_Or_Entity_Id := Next (Frst);
1345 Set_First (List, Nxt);
1348 Set_Last (List, Empty);
1350 Set_Prev (Nxt, Empty);
1353 Nodes.Table (Frst).In_List := False;
1354 Set_Parent (Frst, Empty);
1364 function Remove_Next
1365 (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
1367 Nxt : constant Node_Or_Entity_Id := Next (Node);
1369 procedure Remove_Next_Debug;
1370 pragma Inline (Remove_Next_Debug);
1371 -- Output debug information if Debug_Flag_N set
1373 -----------------------
1374 -- Remove_Next_Debug --
1375 -----------------------
1377 procedure Remove_Next_Debug is
1379 if Debug_Flag_N then
1380 Write_Str ("Remove next node after ");
1381 Write_Int (Int (Node));
1384 end Remove_Next_Debug;
1386 -- Start of processing for Remove_Next
1389 if Present (Nxt) then
1391 Nxt2 : constant Node_Or_Entity_Id := Next (Nxt);
1392 LC : constant List_Id := List_Containing (Node);
1395 pragma Debug (Remove_Next_Debug);
1396 Set_Next (Node, Nxt2);
1399 Set_Last (LC, Node);
1401 Set_Prev (Nxt2, Node);
1404 Nodes.Table (Nxt).In_List := False;
1405 Set_Parent (Nxt, Empty);
1416 procedure Set_First (List : List_Id; To : Node_Or_Entity_Id) is
1418 pragma Assert (not Locked);
1419 Lists.Table (List).First := To;
1426 procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id) is
1428 pragma Assert (not Locked);
1429 Lists.Table (List).Last := To;
1436 procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id) is
1438 pragma Assert (not Locked);
1439 Nodes.Table (Node).Link := Union_Id (To);
1446 procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is
1448 pragma Assert (not Locked);
1449 Next_Node.Table (Node) := To;
1456 procedure Set_Parent (List : List_Id; Node : Node_Or_Entity_Id) is
1458 pragma Assert (not Locked);
1459 pragma Assert (List <= Lists.Last);
1460 Lists.Table (List).Parent := Node;
1467 procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is
1469 pragma Assert (not Locked);
1470 Prev_Node.Table (Node) := To;
1477 procedure Tree_Read is
1479 pragma Assert (not Locked);
1481 Next_Node.Tree_Read;
1482 Prev_Node.Tree_Read;
1489 procedure Tree_Write is
1492 Next_Node.Tree_Write;
1493 Prev_Node.Tree_Write;
1502 Lists.Locked := False;
1503 Prev_Node.Locked := False;
1504 Next_Node.Locked := False;
1511 procedure Unlock_Lists is
1513 pragma Assert (Locked);