1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 -- 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
30 with Atree
; use Atree
;
31 with Debug
; use Debug
;
32 with Output
; use Output
;
33 with Sinfo
; use Sinfo
;
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
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
60 -- Pointer to parent of list. Empty if list has no parent
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
;
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
;
144 end Allocate_List_Tables
;
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
161 procedure Append_Debug
is
164 Write_Str
("Append node ");
165 Write_Int
(Int
(Node
));
166 Write_Str
(" to list ");
167 Write_Int
(Int
(To
));
172 -- Start of processing for Append
175 pragma Assert
(not Is_List_Member
(Node
));
181 pragma Debug
(Append_Debug
);
184 Set_First
(To
, Node
);
191 Nodes
.Table
(Node
).In_List
:= True;
193 Set_Next
(Node
, Empty
);
195 Set_List_Link
(Node
, To
);
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
214 Write_Str
("Append list ");
215 Write_Int
(Int
(List
));
216 Write_Str
(" to list ");
217 Write_Int
(Int
(To
));
220 end Append_List_Debug
;
222 -- Start of processing for Append_List
225 if Is_Empty_List
(List
) then
230 L
: constant Node_Or_Entity_Id
:= Last
(To
);
231 F
: constant Node_Or_Entity_Id
:= First
(List
);
232 N
: Node_Or_Entity_Id
;
235 pragma Debug
(Append_List_Debug
);
239 Set_List_Link
(N
, To
);
251 Set_Last
(To
, Last
(List
));
253 Set_First
(List
, Empty
);
254 Set_Last
(List
, Empty
);
263 procedure Append_List_To
(To
: List_Id
; List
: List_Id
) is
265 Append_List
(List
, To
);
272 procedure Append_New
(Node
: Node_Or_Entity_Id
; To
: in out List_Id
) is
285 procedure Append_New_To
(To
: in out List_Id
; Node
: Node_Or_Entity_Id
) is
287 Append_New
(Node
, To
);
294 procedure Append_To
(To
: List_Id
; Node
: Node_Or_Entity_Id
) is
303 function First
(List
: List_Id
) return Node_Or_Entity_Id
is
305 if List
= No_List
then
308 pragma Assert
(List
<= Lists
.Last
);
309 return Lists
.Table
(List
).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
);
320 if Nkind
(N
) /= N_Pragma
322 Nkind
(N
) /= N_Null_Statement
326 return Next_Non_Pragma
(N
);
328 end First_Non_Pragma
;
334 procedure Initialize
is
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
);
352 function In_Same_List
(N1
, N2
: Node_Or_Entity_Id
) return Boolean is
354 return List_Containing
(N1
) = List_Containing
(N2
);
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
376 Write_Str
("Insert node");
377 Write_Int
(Int
(Node
));
378 Write_Str
(" after node ");
379 Write_Int
(Int
(After
));
382 end Insert_After_Debug
;
384 -- Start of processing for Insert_After
388 (Is_List_Member
(After
) and then not Is_List_Member
(Node
));
394 pragma Debug
(Insert_After_Debug
);
397 Before
: constant Node_Or_Entity_Id
:= Next
(After
);
398 LC
: constant List_Id
:= List_Containing
(After
);
401 if Present
(Before
) then
402 Set_Prev
(Before
, Node
);
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
);
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
436 Write_Str
("Insert node");
437 Write_Int
(Int
(Node
));
438 Write_Str
(" before node ");
439 Write_Int
(Int
(Before
));
442 end Insert_Before_Debug
;
444 -- Start of processing for Insert_Before
448 (Is_List_Member
(Before
) and then not Is_List_Member
(Node
));
454 pragma Debug
(Insert_Before_Debug
);
457 After
: constant Node_Or_Entity_Id
:= Prev
(Before
);
458 LC
: constant List_Id
:= List_Containing
(Before
);
461 if Present
(After
) then
462 Set_Next
(After
, Node
);
464 Set_First
(LC
, Node
);
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
);
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
494 Write_Str
("Insert list ");
495 Write_Int
(Int
(List
));
496 Write_Str
(" after node ");
497 Write_Int
(Int
(After
));
500 end Insert_List_After_Debug
;
502 -- Start of processing for Insert_List_After
505 pragma Assert
(Is_List_Member
(After
));
507 if Is_Empty_List
(List
) then
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
;
519 pragma Debug
(Insert_List_After_Debug
);
523 Set_List_Link
(N
, LC
);
528 if Present
(Before
) then
529 Set_Prev
(Before
, L
);
536 Set_Next
(L
, Before
);
538 Set_First
(List
, Empty
);
539 Set_Last
(List
, Empty
);
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
561 Write_Str
("Insert list ");
562 Write_Int
(Int
(List
));
563 Write_Str
(" before node ");
564 Write_Int
(Int
(Before
));
567 end Insert_List_Before_Debug
;
569 -- Start of processing for Insert_List_Before
572 pragma Assert
(Is_List_Member
(Before
));
574 if Is_Empty_List
(List
) then
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
;
586 pragma Debug
(Insert_List_Before_Debug
);
590 Set_List_Link
(N
, LC
);
595 if Present
(After
) then
601 Set_Prev
(Before
, L
);
603 Set_Next
(L
, Before
);
605 Set_First
(List
, Empty
);
606 Set_Last
(List
, Empty
);
609 end Insert_List_Before
;
615 function Is_Empty_List
(List
: List_Id
) return Boolean is
617 return First
(List
) = Empty
;
624 function Is_List_Member
(Node
: Node_Or_Entity_Id
) return Boolean is
626 return Nodes
.Table
(Node
).In_List
;
629 -----------------------
630 -- Is_Non_Empty_List --
631 -----------------------
633 function Is_Non_Empty_List
(List
: List_Id
) return Boolean is
635 return First
(List
) /= Empty
;
636 end Is_Non_Empty_List
;
642 function Last
(List
: List_Id
) return Node_Or_Entity_Id
is
644 pragma Assert
(List
<= Lists
.Last
);
645 return Lists
.Table
(List
).Last
;
652 function Last_List_Id
return List_Id
is
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
);
664 if Nkind
(N
) /= N_Pragma
then
667 return Prev_Non_Pragma
(N
);
671 ---------------------
672 -- List_Containing --
673 ---------------------
675 function List_Containing
(Node
: Node_Or_Entity_Id
) return List_Id
is
677 pragma Assert
(Is_List_Member
(Node
));
678 return List_Id
(Nodes
.Table
(Node
).Link
);
685 function List_Length
(List
: List_Id
) return Nat
is
687 Node
: Node_Or_Entity_Id
;
691 Node
:= First
(List
);
692 while Present
(Node
) loop
693 Result
:= Result
+ 1;
704 function Lists_Address
return System
.Address
is
706 return Lists
.Table
(First_List_Id
)'Address;
716 Lists
.Locked
:= True;
718 Prev_Node
.Locked
:= True;
720 Next_Node
.Locked
:= True;
727 procedure Lock_Lists
is
729 pragma Assert
(not Locked
);
737 function New_Copy_List
(List
: List_Id
) return List_Id
is
739 E
: Node_Or_Entity_Id
;
742 if List
= No_List
then
749 while Present
(E
) loop
750 Append
(New_Copy
(E
), NL
);
758 ----------------------------
759 -- New_Copy_List_Original --
760 ----------------------------
762 function New_Copy_List_Original
(List
: List_Id
) return List_Id
is
764 E
: Node_Or_Entity_Id
;
767 if List
= No_List
then
774 while Present
(E
) loop
775 if Comes_From_Source
(E
) then
776 Append
(New_Copy
(E
), NL
);
784 end New_Copy_List_Original
;
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
800 procedure New_List_Debug
is
803 Write_Str
("Allocate new list, returned ID = ");
804 Write_Int
(Int
(Lists
.Last
));
809 -- Start of processing for New_List
812 Lists
.Increment_Last
;
815 List
: constant List_Id
:= Lists
.Last
;
818 Set_Parent
(List
, Empty
);
819 Set_First
(List
, Empty
);
820 Set_Last
(List
, Empty
);
822 pragma Debug
(New_List_Debug
);
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
841 procedure New_List_Debug
is
844 Write_Str
("Allocate new list, returned ID = ");
845 Write_Int
(Int
(Lists
.Last
));
850 -- Start of processing for New_List
857 pragma Assert
(not Is_List_Member
(Node
));
859 Lists
.Increment_Last
;
862 List
: constant List_Id
:= Lists
.Last
;
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
);
880 (Node1
: Node_Or_Entity_Id
;
881 Node2
: Node_Or_Entity_Id
) return List_Id
883 L
: constant List_Id
:= New_List
(Node1
);
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
);
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
);
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
);
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
);
953 function Next
(Node
: Node_Or_Entity_Id
) return Node_Or_Entity_Id
is
955 pragma Assert
(Is_List_Member
(Node
));
956 return Next_Node
.Table
(Node
);
959 procedure Next
(Node
: in out Node_Or_Entity_Id
) is
964 -----------------------
965 -- Next_Node_Address --
966 -----------------------
968 function Next_Node_Address
return System
.Address
is
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
;
986 exit when Nkind
(N
) not in N_Pragma | N_Null_Statement
;
992 procedure Next_Non_Pragma
(Node
: in out Node_Or_Entity_Id
) is
994 Node
:= Next_Non_Pragma
(Node
);
1001 function No
(List
: List_Id
) return Boolean is
1003 return List
= No_List
;
1010 function Num_Lists
return Nat
is
1012 return Int
(Lists
.Last
) - Int
(Lists
.First
) + 1;
1019 function Parent
(List
: List_Id
) return Node_Or_Entity_Id
is
1021 pragma Assert
(List
<= Lists
.Last
);
1022 return Lists
.Table
(List
).Parent
;
1029 function Pick
(List
: List_Id
; Index
: Pos
) return Node_Or_Entity_Id
is
1030 Elmt
: Node_Or_Entity_Id
;
1033 Elmt
:= First
(List
);
1034 for J
in 1 .. Index
- 1 loop
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
1056 procedure Prepend_Debug
is
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
));
1067 -- Start of processing for Prepend_Debug
1070 pragma Assert
(not Is_List_Member
(Node
));
1072 if Node
= Error
then
1076 pragma Debug
(Prepend_Debug
);
1079 Set_Last
(To
, Node
);
1084 Set_First
(To
, Node
);
1086 Nodes
.Table
(Node
).In_List
:= True;
1089 Set_Prev
(Node
, Empty
);
1090 Set_List_Link
(Node
, To
);
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
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
));
1116 end Prepend_List_Debug
;
1118 -- Start of processing for Prepend_List
1121 if Is_Empty_List
(List
) then
1126 F
: constant Node_Or_Entity_Id
:= First
(To
);
1127 L
: constant Node_Or_Entity_Id
:= Last
(List
);
1128 N
: Node_Or_Entity_Id
;
1131 pragma Debug
(Prepend_List_Debug
);
1135 Set_List_Link
(N
, To
);
1147 Set_First
(To
, First
(List
));
1149 Set_First
(List
, Empty
);
1150 Set_Last
(List
, Empty
);
1155 ---------------------
1156 -- Prepend_List_To --
1157 ---------------------
1159 procedure Prepend_List_To
(To
: List_Id
; List
: List_Id
) is
1161 Prepend_List
(List
, To
);
1162 end Prepend_List_To
;
1168 procedure Prepend_New
(Node
: Node_Or_Entity_Id
; To
: in out List_Id
) is
1177 --------------------
1178 -- Prepend_New_To --
1179 --------------------
1181 procedure Prepend_New_To
(To
: in out List_Id
; Node
: Node_Or_Entity_Id
) is
1183 Prepend_New
(Node
, To
);
1190 procedure Prepend_To
(To
: List_Id
; Node
: Node_Or_Entity_Id
) is
1199 function Present
(List
: List_Id
) return Boolean is
1201 return List
/= No_List
;
1208 function Prev
(Node
: Node_Or_Entity_Id
) return Node_Or_Entity_Id
is
1210 pragma Assert
(Is_List_Member
(Node
));
1211 return Prev_Node
.Table
(Node
);
1214 procedure Prev
(Node
: in out Node_Or_Entity_Id
) is
1216 Node
:= Prev
(Node
);
1219 -----------------------
1220 -- Prev_Node_Address --
1221 -----------------------
1223 function Prev_Node_Address
return System
.Address
is
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
;
1241 exit when Nkind
(N
) /= N_Pragma
;
1245 end Prev_Non_Pragma
;
1247 procedure Prev_Non_Pragma
(Node
: in out Node_Or_Entity_Id
) is
1249 Node
:= Prev_Non_Pragma
(Node
);
1250 end Prev_Non_Pragma
;
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
1269 procedure Remove_Debug
is
1271 if Debug_Flag_N
then
1272 Write_Str
("Remove node ");
1273 Write_Int
(Int
(Node
));
1278 -- Start of processing for Remove
1281 pragma Debug
(Remove_Debug
);
1284 Set_First
(Lst
, Nxt
);
1286 Set_Next
(Prv
, Nxt
);
1290 Set_Last
(Lst
, Prv
);
1292 Set_Prev
(Nxt
, Prv
);
1295 Nodes
.Table
(Node
).In_List
:= False;
1296 Set_Parent
(Node
, Empty
);
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
1316 if Debug_Flag_N
then
1317 Write_Str
("Remove head of list ");
1318 Write_Int
(Int
(List
));
1321 end Remove_Head_Debug
;
1323 -- Start of processing for Remove_Head
1326 pragma Debug
(Remove_Head_Debug
);
1328 if Frst
= Empty
then
1333 Nxt
: constant Node_Or_Entity_Id
:= Next
(Frst
);
1336 Set_First
(List
, Nxt
);
1339 Set_Last
(List
, Empty
);
1341 Set_Prev
(Nxt
, Empty
);
1344 Nodes
.Table
(Frst
).In_List
:= False;
1345 Set_Parent
(Frst
, Empty
);
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
1370 if Debug_Flag_N
then
1371 Write_Str
("Remove next node after ");
1372 Write_Int
(Int
(Node
));
1375 end Remove_Next_Debug
;
1377 -- Start of processing for Remove_Next
1380 if Present
(Nxt
) then
1382 Nxt2
: constant Node_Or_Entity_Id
:= Next
(Nxt
);
1383 LC
: constant List_Id
:= List_Containing
(Node
);
1386 pragma Debug
(Remove_Next_Debug
);
1387 Set_Next
(Node
, Nxt2
);
1390 Set_Last
(LC
, Node
);
1392 Set_Prev
(Nxt2
, Node
);
1395 Nodes
.Table
(Nxt
).In_List
:= False;
1396 Set_Parent
(Nxt
, Empty
);
1407 procedure Set_First
(List
: List_Id
; To
: Node_Or_Entity_Id
) is
1409 pragma Assert
(not Locked
);
1410 Lists
.Table
(List
).First
:= To
;
1417 procedure Set_Last
(List
: List_Id
; To
: Node_Or_Entity_Id
) is
1419 pragma Assert
(not Locked
);
1420 Lists
.Table
(List
).Last
:= To
;
1427 procedure Set_List_Link
(Node
: Node_Or_Entity_Id
; To
: List_Id
) is
1429 pragma Assert
(not Locked
);
1430 Nodes
.Table
(Node
).Link
:= Union_Id
(To
);
1437 procedure Set_Next
(Node
: Node_Or_Entity_Id
; To
: Node_Or_Entity_Id
) is
1439 pragma Assert
(not Locked
);
1440 Next_Node
.Table
(Node
) := To
;
1447 procedure Set_Parent
(List
: List_Id
; Node
: Node_Or_Entity_Id
) is
1449 pragma Assert
(not Locked
);
1450 pragma Assert
(List
<= Lists
.Last
);
1451 Lists
.Table
(List
).Parent
:= Node
;
1458 procedure Set_Prev
(Node
: Node_Or_Entity_Id
; To
: Node_Or_Entity_Id
) is
1460 pragma Assert
(not Locked
);
1461 Prev_Node
.Table
(Node
) := To
;
1470 Lists
.Locked
:= False;
1471 Prev_Node
.Locked
:= False;
1472 Next_Node
.Locked
:= False;
1479 procedure Unlock_Lists
is
1481 pragma Assert
(Locked
);