Add hppa-openbsd target
[official-gcc.git] / gcc / ada / nlists.adb
blobb2d6382f7d8d32712eba1c1a658f361e50bebc67
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- N L I S T S --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
29 -- --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
32 -- --
33 ------------------------------------------------------------------------------
35 -- WARNING: There is a C version of this package. Any changes to this source
36 -- file must be properly reflected in the corresponding C header a-nlists.h
38 with Alloc;
39 with Atree; use Atree;
40 with Debug; use Debug;
41 with Output; use Output;
42 with Sinfo; use Sinfo;
43 with Table;
45 package body Nlists is
47 use Atree_Private_Part;
48 -- Get access to Nodes table
50 ----------------------------------
51 -- Implementation of Node Lists --
52 ----------------------------------
54 -- A node list is represented by a list header which contains
55 -- three fields:
57 type List_Header is record
58 First : Node_Id;
59 -- Pointer to first node in list. Empty if list is empty
61 Last : Node_Id;
62 -- Pointer to last node in list. Empty if list is empty
64 Parent : Node_Id;
65 -- Pointer to parent of list. Empty if list has no parent
66 end record;
68 -- The node lists are stored in a table indexed by List_Id values
70 package Lists is new Table.Table (
71 Table_Component_Type => List_Header,
72 Table_Index_Type => List_Id,
73 Table_Low_Bound => First_List_Id,
74 Table_Initial => Alloc.Lists_Initial,
75 Table_Increment => Alloc.Lists_Increment,
76 Table_Name => "Lists");
78 -- The nodes in the list all have the In_List flag set, and their Link
79 -- fields (which otherwise point to the parent) contain the List_Id of
80 -- the list header giving immediate access to the list containing the
81 -- node, and its parent and first and last elements.
83 -- Two auxiliary tables, indexed by Node_Id values and built in parallel
84 -- with the main nodes table and always having the same size contain the
85 -- list link values that allow locating the previous and next node in a
86 -- list. The entries in these tables are valid only if the In_List flag
87 -- is set in the corresponding node. Next_Node is Empty at the end of a
88 -- list and Prev_Node is Empty at the start of a list.
90 package Next_Node is new Table.Table (
91 Table_Component_Type => Node_Id,
92 Table_Index_Type => Node_Id,
93 Table_Low_Bound => First_Node_Id,
94 Table_Initial => Alloc.Orig_Nodes_Initial,
95 Table_Increment => Alloc.Orig_Nodes_Increment,
96 Table_Name => "Next_Node");
98 package Prev_Node is new Table.Table (
99 Table_Component_Type => Node_Id,
100 Table_Index_Type => Node_Id,
101 Table_Low_Bound => First_Node_Id,
102 Table_Initial => Alloc.Orig_Nodes_Initial,
103 Table_Increment => Alloc.Orig_Nodes_Increment,
104 Table_Name => "Prev_Node");
106 -----------------------
107 -- Local Subprograms --
108 -----------------------
110 procedure Prepend_Debug (Node : Node_Id; To : List_Id);
111 pragma Inline (Prepend_Debug);
112 -- Output debug information if Debug_Flag_N set
114 procedure Remove_Next_Debug (Node : Node_Id);
115 pragma Inline (Remove_Next_Debug);
116 -- Output debug information if Debug_Flag_N set
118 procedure Set_First (List : List_Id; To : Node_Id);
119 pragma Inline (Set_First);
120 -- Sets First field of list header List to reference To
122 procedure Set_Last (List : List_Id; To : Node_Id);
123 pragma Inline (Set_Last);
124 -- Sets Last field of list header List to reference To
126 procedure Set_List_Link (Node : Node_Id; To : List_Id);
127 pragma Inline (Set_List_Link);
128 -- Sets list link of Node to list header To
130 procedure Set_Next (Node : Node_Id; To : Node_Id);
131 pragma Inline (Set_Next);
132 -- Sets the Next_Node pointer for Node to reference To
134 procedure Set_Prev (Node : Node_Id; To : Node_Id);
135 pragma Inline (Set_Prev);
136 -- Sets the Prev_Node pointer for Node to reference To
138 --------------------------
139 -- Allocate_List_Tables --
140 --------------------------
142 procedure Allocate_List_Tables (N : Node_Id) is
143 begin
144 Next_Node.Set_Last (N);
145 Prev_Node.Set_Last (N);
146 end Allocate_List_Tables;
148 ------------
149 -- Append --
150 ------------
152 procedure Append (Node : Node_Id; To : List_Id) is
153 L : constant Node_Id := Last (To);
155 procedure Append_Debug;
156 pragma Inline (Append_Debug);
157 -- Output debug information if Debug_Flag_N set
159 procedure Append_Debug is
160 begin
161 if Debug_Flag_N then
162 Write_Str ("Append node ");
163 Write_Int (Int (Node));
164 Write_Str (" to list ");
165 Write_Int (Int (To));
166 Write_Eol;
167 end if;
168 end Append_Debug;
170 -- Start of processing for Append
172 begin
173 pragma Assert (not Is_List_Member (Node));
175 if Node = Error then
176 return;
177 end if;
179 pragma Debug (Append_Debug);
181 if No (L) then
182 Set_First (To, Node);
183 else
184 Set_Next (L, Node);
185 end if;
187 Set_Last (To, Node);
189 Nodes.Table (Node).In_List := True;
191 Set_Next (Node, Empty);
192 Set_Prev (Node, L);
193 Set_List_Link (Node, To);
194 end Append;
196 -----------------
197 -- Append_List --
198 -----------------
200 procedure Append_List (List : List_Id; To : List_Id) is
202 procedure Append_List_Debug;
203 pragma Inline (Append_List_Debug);
204 -- Output debug information if Debug_Flag_N set
206 procedure Append_List_Debug is
207 begin
208 if Debug_Flag_N then
209 Write_Str ("Append list ");
210 Write_Int (Int (List));
211 Write_Str (" to list ");
212 Write_Int (Int (To));
213 Write_Eol;
214 end if;
215 end Append_List_Debug;
217 -- Start of processing for Append_List
219 begin
220 if Is_Empty_List (List) then
221 return;
223 else
224 declare
225 L : constant Node_Id := Last (To);
226 F : constant Node_Id := First (List);
227 N : Node_Id;
229 begin
230 pragma Debug (Append_List_Debug);
232 N := F;
233 loop
234 Set_List_Link (N, To);
235 N := Next (N);
236 exit when No (N);
237 end loop;
239 if No (L) then
240 Set_First (To, F);
241 else
242 Set_Next (L, F);
243 end if;
245 Set_Prev (F, L);
246 Set_Last (To, Last (List));
248 Set_First (List, Empty);
249 Set_Last (List, Empty);
250 end;
251 end if;
252 end Append_List;
254 --------------------
255 -- Append_List_To --
256 --------------------
258 procedure Append_List_To (To : List_Id; List : List_Id) is
259 begin
260 Append_List (List, To);
261 end Append_List_To;
263 ---------------
264 -- Append_To --
265 ---------------
267 procedure Append_To (To : List_Id; Node : Node_Id) is
268 begin
269 Append (Node, To);
270 end Append_To;
272 -----------------
273 -- Delete_List --
274 -----------------
276 procedure Delete_List (L : List_Id) is
277 N : Node_Id;
279 begin
280 while Is_Non_Empty_List (L) loop
281 N := Remove_Head (L);
282 Delete_Tree (N);
283 end loop;
285 -- Should recycle list header???
286 end Delete_List;
288 -----------
289 -- First --
290 -----------
292 -- This subprogram is deliberately placed early on, out of alphabetical
293 -- order, so that it can be properly inlined from within this unit.
295 function First (List : List_Id) return Node_Id is
296 begin
297 if List = No_List then
298 return Empty;
299 else
300 pragma Assert (List in First_List_Id .. Lists.Last);
301 return Lists.Table (List).First;
302 end if;
303 end First;
305 ----------------------
306 -- First_Non_Pragma --
307 ----------------------
309 function First_Non_Pragma (List : List_Id) return Node_Id is
310 N : constant Node_Id := First (List);
312 begin
313 if Nkind (N) /= N_Pragma
314 and then
315 Nkind (N) /= N_Null_Statement
316 then
317 return N;
318 else
319 return Next_Non_Pragma (N);
320 end if;
321 end First_Non_Pragma;
323 ----------------
324 -- Initialize --
325 ----------------
327 procedure Initialize is
328 E : constant List_Id := Error_List;
330 begin
331 Lists.Init;
332 Next_Node.Init;
333 Prev_Node.Init;
335 -- Allocate Error_List list header
337 Lists.Increment_Last;
338 Set_Parent (E, Empty);
339 Set_First (E, Empty);
340 Set_Last (E, Empty);
341 end Initialize;
343 ------------------
344 -- Insert_After --
345 ------------------
347 procedure Insert_After (After : Node_Id; Node : Node_Id) is
349 procedure Insert_After_Debug;
350 pragma Inline (Insert_After_Debug);
351 -- Output debug information if Debug_Flag_N set
353 procedure Insert_After_Debug is
354 begin
355 if Debug_Flag_N then
356 Write_Str ("Insert node");
357 Write_Int (Int (Node));
358 Write_Str (" after node ");
359 Write_Int (Int (After));
360 Write_Eol;
361 end if;
362 end Insert_After_Debug;
364 -- Start of processing for Insert_After
366 begin
367 pragma Assert
368 (Is_List_Member (After) and then not Is_List_Member (Node));
370 if Node = Error then
371 return;
372 end if;
374 pragma Debug (Insert_After_Debug);
376 declare
377 Before : constant Node_Id := Next (After);
378 LC : constant List_Id := List_Containing (After);
380 begin
381 if Present (Before) then
382 Set_Prev (Before, Node);
383 else
384 Set_Last (LC, Node);
385 end if;
387 Set_Next (After, Node);
389 Nodes.Table (Node).In_List := True;
391 Set_Prev (Node, After);
392 Set_Next (Node, Before);
393 Set_List_Link (Node, LC);
394 end;
395 end Insert_After;
397 -------------------
398 -- Insert_Before --
399 -------------------
401 procedure Insert_Before (Before : Node_Id; Node : Node_Id) is
403 procedure Insert_Before_Debug;
404 pragma Inline (Insert_Before_Debug);
405 -- Output debug information if Debug_Flag_N set
407 procedure Insert_Before_Debug is
408 begin
409 if Debug_Flag_N then
410 Write_Str ("Insert node");
411 Write_Int (Int (Node));
412 Write_Str (" before node ");
413 Write_Int (Int (Before));
414 Write_Eol;
415 end if;
416 end Insert_Before_Debug;
418 -- Start of processing for Insert_Before
420 begin
421 pragma Assert
422 (Is_List_Member (Before) and then not Is_List_Member (Node));
424 if Node = Error then
425 return;
426 end if;
428 pragma Debug (Insert_Before_Debug);
430 declare
431 After : constant Node_Id := Prev (Before);
432 LC : constant List_Id := List_Containing (Before);
434 begin
435 if Present (After) then
436 Set_Next (After, Node);
437 else
438 Set_First (LC, Node);
439 end if;
441 Set_Prev (Before, Node);
443 Nodes.Table (Node).In_List := True;
445 Set_Prev (Node, After);
446 Set_Next (Node, Before);
447 Set_List_Link (Node, LC);
448 end;
449 end Insert_Before;
451 -----------------------
452 -- Insert_List_After --
453 -----------------------
455 procedure Insert_List_After (After : Node_Id; List : List_Id) is
457 procedure Insert_List_After_Debug;
458 pragma Inline (Insert_List_After_Debug);
459 -- Output debug information if Debug_Flag_N set
461 procedure Insert_List_After_Debug is
462 begin
463 if Debug_Flag_N then
464 Write_Str ("Insert list ");
465 Write_Int (Int (List));
466 Write_Str (" after node ");
467 Write_Int (Int (After));
468 Write_Eol;
469 end if;
470 end Insert_List_After_Debug;
472 -- Start of processing for Insert_List_After
474 begin
475 pragma Assert (Is_List_Member (After));
477 if Is_Empty_List (List) then
478 return;
480 else
481 declare
482 Before : constant Node_Id := Next (After);
483 LC : constant List_Id := List_Containing (After);
484 F : constant Node_Id := First (List);
485 L : constant Node_Id := Last (List);
486 N : Node_Id;
488 begin
489 pragma Debug (Insert_List_After_Debug);
491 N := F;
492 loop
493 Set_List_Link (N, LC);
494 exit when N = L;
495 N := Next (N);
496 end loop;
498 if Present (Before) then
499 Set_Prev (Before, L);
500 else
501 Set_Last (LC, L);
502 end if;
504 Set_Next (After, F);
505 Set_Prev (F, After);
506 Set_Next (L, Before);
508 Set_First (List, Empty);
509 Set_Last (List, Empty);
510 end;
511 end if;
512 end Insert_List_After;
514 ------------------------
515 -- Insert_List_Before --
516 ------------------------
518 procedure Insert_List_Before (Before : Node_Id; List : List_Id) is
520 procedure Insert_List_Before_Debug;
521 pragma Inline (Insert_List_Before_Debug);
522 -- Output debug information if Debug_Flag_N set
524 procedure Insert_List_Before_Debug is
525 begin
526 if Debug_Flag_N then
527 Write_Str ("Insert list ");
528 Write_Int (Int (List));
529 Write_Str (" before node ");
530 Write_Int (Int (Before));
531 Write_Eol;
532 end if;
533 end Insert_List_Before_Debug;
535 -- Start of prodcessing for Insert_List_Before
537 begin
538 pragma Assert (Is_List_Member (Before));
540 if Is_Empty_List (List) then
541 return;
543 else
544 declare
545 After : constant Node_Id := Prev (Before);
546 LC : constant List_Id := List_Containing (Before);
547 F : constant Node_Id := First (List);
548 L : constant Node_Id := Last (List);
549 N : Node_Id;
551 begin
552 pragma Debug (Insert_List_Before_Debug);
554 N := F;
555 loop
556 Set_List_Link (N, LC);
557 exit when N = L;
558 N := Next (N);
559 end loop;
561 if Present (After) then
562 Set_Next (After, F);
563 else
564 Set_First (LC, F);
565 end if;
567 Set_Prev (Before, L);
568 Set_Prev (F, After);
569 Set_Next (L, Before);
571 Set_First (List, Empty);
572 Set_Last (List, Empty);
573 end;
574 end if;
575 end Insert_List_Before;
577 -------------------
578 -- Is_Empty_List --
579 -------------------
581 function Is_Empty_List (List : List_Id) return Boolean is
582 begin
583 return First (List) = Empty;
584 end Is_Empty_List;
586 --------------------
587 -- Is_List_Member --
588 --------------------
590 function Is_List_Member (Node : Node_Id) return Boolean is
591 begin
592 return Nodes.Table (Node).In_List;
593 end Is_List_Member;
595 -----------------------
596 -- Is_Non_Empty_List --
597 -----------------------
599 function Is_Non_Empty_List (List : List_Id) return Boolean is
600 begin
601 return List /= No_List and then First (List) /= Empty;
602 end Is_Non_Empty_List;
604 ----------
605 -- Last --
606 ----------
608 -- This subprogram is deliberately placed early on, out of alphabetical
609 -- order, so that it can be properly inlined from within this unit.
611 function Last (List : List_Id) return Node_Id is
612 begin
613 pragma Assert (List in First_List_Id .. Lists.Last);
614 return Lists.Table (List).Last;
615 end Last;
617 ------------------
618 -- Last_List_Id --
619 ------------------
621 function Last_List_Id return List_Id is
622 begin
623 return Lists.Last;
624 end Last_List_Id;
626 ---------------------
627 -- Last_Non_Pragma --
628 ---------------------
630 function Last_Non_Pragma (List : List_Id) return Node_Id is
631 N : constant Node_Id := Last (List);
633 begin
634 if Nkind (N) /= N_Pragma then
635 return N;
636 else
637 return Prev_Non_Pragma (N);
638 end if;
639 end Last_Non_Pragma;
641 ---------------------
642 -- List_Containing --
643 ---------------------
645 function List_Containing (Node : Node_Id) return List_Id is
646 begin
647 pragma Assert (Is_List_Member (Node));
648 return List_Id (Nodes.Table (Node).Link);
649 end List_Containing;
651 -----------------
652 -- List_Length --
653 -----------------
655 function List_Length (List : List_Id) return Nat is
656 Result : Nat;
657 Node : Node_Id;
659 begin
660 Result := 0;
661 Node := First (List);
662 while Present (Node) loop
663 Result := Result + 1;
664 Node := Next (Node);
665 end loop;
667 return Result;
668 end List_Length;
670 -------------------
671 -- Lists_Address --
672 -------------------
674 function Lists_Address return System.Address is
675 begin
676 return Lists.Table (First_List_Id)'Address;
677 end Lists_Address;
679 ----------
680 -- Lock --
681 ----------
683 procedure Lock is
684 begin
685 Lists.Locked := True;
686 Lists.Release;
688 Prev_Node.Locked := True;
689 Next_Node.Locked := True;
691 Prev_Node.Release;
692 Next_Node.Release;
693 end Lock;
695 -------------------
696 -- New_Copy_List --
697 -------------------
699 function New_Copy_List (List : List_Id) return List_Id is
700 NL : List_Id;
701 E : Node_Id;
703 begin
704 if List = No_List then
705 return No_List;
707 else
708 NL := New_List;
709 E := First (List);
711 while Present (E) loop
712 Append (New_Copy (E), NL);
713 E := Next (E);
714 end loop;
716 return NL;
717 end if;
718 end New_Copy_List;
720 ----------------------------
721 -- New_Copy_List_Original --
722 ----------------------------
724 function New_Copy_List_Original (List : List_Id) return List_Id is
725 NL : List_Id;
726 E : Node_Id;
728 begin
729 if List = No_List then
730 return No_List;
732 else
733 NL := New_List;
734 E := First (List);
736 while Present (E) loop
737 if Comes_From_Source (E) then
738 Append (New_Copy (E), NL);
739 end if;
741 E := Next (E);
742 end loop;
744 return NL;
745 end if;
746 end New_Copy_List_Original;
748 ------------------------
749 -- New_Copy_List_Tree --
750 ------------------------
752 function New_Copy_List_Tree (List : List_Id) return List_Id is
753 NL : List_Id;
754 E : Node_Id;
756 begin
757 if List = No_List then
758 return No_List;
760 else
761 NL := New_List;
762 E := First (List);
764 while Present (E) loop
765 Append (New_Copy_Tree (E), NL);
766 E := Next (E);
767 end loop;
769 return NL;
770 end if;
771 end New_Copy_List_Tree;
773 --------------
774 -- New_List --
775 --------------
777 function New_List return List_Id is
779 procedure New_List_Debug;
780 pragma Inline (New_List_Debug);
781 -- Output debugging information if Debug_Flag_N is set
783 procedure New_List_Debug is
784 begin
785 if Debug_Flag_N then
786 Write_Str ("Allocate new list, returned ID = ");
787 Write_Int (Int (Lists.Last));
788 Write_Eol;
789 end if;
790 end New_List_Debug;
792 -- Start of processing for New_List
794 begin
795 Lists.Increment_Last;
797 declare
798 List : constant List_Id := Lists.Last;
800 begin
801 Set_Parent (List, Empty);
802 Set_First (List, Empty);
803 Set_Last (List, Empty);
805 pragma Debug (New_List_Debug);
806 return (List);
807 end;
808 end New_List;
810 -- Since the one argument case is common, we optimize to build the right
811 -- list directly, rather than first building an empty list and then doing
812 -- the insertion, which results in some unnecessary work.
814 function New_List (Node : Node_Id) return List_Id is
816 procedure New_List_Debug;
817 pragma Inline (New_List_Debug);
818 -- Output debugging information if Debug_Flag_N is set
820 procedure New_List_Debug is
821 begin
822 if Debug_Flag_N then
823 Write_Str ("Allocate new list, returned ID = ");
824 Write_Int (Int (Lists.Last));
825 Write_Eol;
826 end if;
827 end New_List_Debug;
829 -- Start of processing for New_List
831 begin
832 if Node = Error then
833 return New_List;
835 else
836 pragma Assert (not Is_List_Member (Node));
838 Lists.Increment_Last;
840 declare
841 List : constant List_Id := Lists.Last;
843 begin
844 Set_Parent (List, Empty);
845 Set_First (List, Node);
846 Set_Last (List, Node);
848 Nodes.Table (Node).In_List := True;
849 Set_List_Link (Node, List);
850 Set_Prev (Node, Empty);
851 Set_Next (Node, Empty);
852 pragma Debug (New_List_Debug);
853 return List;
854 end;
855 end if;
856 end New_List;
858 function New_List (Node1, Node2 : Node_Id) return List_Id is
859 L : constant List_Id := New_List (Node1);
861 begin
862 Append (Node2, L);
863 return L;
864 end New_List;
866 function New_List (Node1, Node2, Node3 : Node_Id) return List_Id is
867 L : constant List_Id := New_List (Node1);
869 begin
870 Append (Node2, L);
871 Append (Node3, L);
872 return L;
873 end New_List;
875 function New_List (Node1, Node2, Node3, Node4 : Node_Id) return List_Id is
876 L : constant List_Id := New_List (Node1);
878 begin
879 Append (Node2, L);
880 Append (Node3, L);
881 Append (Node4, L);
882 return L;
883 end New_List;
885 function New_List
886 (Node1 : Node_Id;
887 Node2 : Node_Id;
888 Node3 : Node_Id;
889 Node4 : Node_Id;
890 Node5 : Node_Id)
891 return List_Id
893 L : constant List_Id := New_List (Node1);
895 begin
896 Append (Node2, L);
897 Append (Node3, L);
898 Append (Node4, L);
899 Append (Node5, L);
900 return L;
901 end New_List;
903 function New_List
904 (Node1 : Node_Id;
905 Node2 : Node_Id;
906 Node3 : Node_Id;
907 Node4 : Node_Id;
908 Node5 : Node_Id;
909 Node6 : Node_Id)
910 return List_Id
912 L : constant List_Id := New_List (Node1);
914 begin
915 Append (Node2, L);
916 Append (Node3, L);
917 Append (Node4, L);
918 Append (Node5, L);
919 Append (Node6, L);
920 return L;
921 end New_List;
923 ----------
924 -- Next --
925 ----------
927 -- This subprogram is deliberately placed early on, out of alphabetical
928 -- order, so that it can be properly inlined from within this unit.
930 function Next (Node : Node_Id) return Node_Id is
931 begin
932 pragma Assert (Is_List_Member (Node));
933 return Next_Node.Table (Node);
934 end Next;
936 procedure Next (Node : in out Node_Id) is
937 begin
938 Node := Next (Node);
939 end Next;
941 -----------------------
942 -- Next_Node_Address --
943 -----------------------
945 function Next_Node_Address return System.Address is
946 begin
947 return Next_Node.Table (First_Node_Id)'Address;
948 end Next_Node_Address;
950 ---------------------
951 -- Next_Non_Pragma --
952 ---------------------
954 function Next_Non_Pragma (Node : Node_Id) return Node_Id is
955 N : Node_Id;
957 begin
958 N := Node;
959 loop
960 N := Next (N);
961 exit when Nkind (N) /= N_Pragma
962 and then
963 Nkind (N) /= N_Null_Statement;
964 end loop;
966 return N;
967 end Next_Non_Pragma;
969 procedure Next_Non_Pragma (Node : in out Node_Id) is
970 begin
971 Node := Next_Non_Pragma (Node);
972 end Next_Non_Pragma;
974 --------
975 -- No --
976 --------
978 -- This subprogram is deliberately placed early on, out of alphabetical
979 -- order, so that it can be properly inlined from within this unit.
981 function No (List : List_Id) return Boolean is
982 begin
983 return List = No_List;
984 end No;
986 ---------------
987 -- Num_Lists --
988 ---------------
990 function Num_Lists return Nat is
991 begin
992 return Int (Lists.Last) - Int (Lists.First) + 1;
993 end Num_Lists;
995 -------
996 -- p --
997 -------
999 function p (U : Union_Id) return Node_Id is
1000 begin
1001 if U in Node_Range then
1002 return Parent (Node_Id (U));
1004 elsif U in List_Range then
1005 return Parent (List_Id (U));
1007 else
1008 return 99_999_999;
1009 end if;
1010 end p;
1012 ------------
1013 -- Parent --
1014 ------------
1016 function Parent (List : List_Id) return Node_Id is
1017 begin
1018 pragma Assert (List in First_List_Id .. Lists.Last);
1019 return Lists.Table (List).Parent;
1020 end Parent;
1022 ----------
1023 -- Pick --
1024 ----------
1026 function Pick (List : List_Id; Index : Pos) return Node_Id is
1027 Elmt : Node_Id;
1029 begin
1030 Elmt := First (List);
1031 for J in 1 .. Index - 1 loop
1032 Elmt := Next (Elmt);
1033 end loop;
1035 return Elmt;
1036 end Pick;
1038 -------------
1039 -- Prepend --
1040 -------------
1042 procedure Prepend (Node : Node_Id; To : List_Id) is
1043 F : constant Node_Id := First (To);
1045 begin
1046 pragma Assert (not Is_List_Member (Node));
1048 if Node = Error then
1049 return;
1050 end if;
1052 pragma Debug (Prepend_Debug (Node, To));
1054 if No (F) then
1055 Set_Last (To, Node);
1056 else
1057 Set_Prev (F, Node);
1058 end if;
1060 Set_First (To, Node);
1062 Nodes.Table (Node).In_List := True;
1064 Set_Next (Node, F);
1065 Set_Prev (Node, Empty);
1066 Set_List_Link (Node, To);
1067 end Prepend;
1069 -------------------
1070 -- Prepend_Debug --
1071 -------------------
1073 procedure Prepend_Debug (Node : Node_Id; To : List_Id) is
1074 begin
1075 if Debug_Flag_N then
1076 Write_Str ("Prepend node ");
1077 Write_Int (Int (Node));
1078 Write_Str (" to list ");
1079 Write_Int (Int (To));
1080 Write_Eol;
1081 end if;
1082 end Prepend_Debug;
1084 ----------------
1085 -- Prepend_To --
1086 ----------------
1088 procedure Prepend_To (To : List_Id; Node : Node_Id) is
1089 begin
1090 Prepend (Node, To);
1091 end Prepend_To;
1093 -------------
1094 -- Present --
1095 -------------
1097 function Present (List : List_Id) return Boolean is
1098 begin
1099 return List /= No_List;
1100 end Present;
1102 ----------
1103 -- Prev --
1104 ----------
1106 -- This subprogram is deliberately placed early on, out of alphabetical
1107 -- order, so that it can be properly inlined from within this unit.
1109 function Prev (Node : Node_Id) return Node_Id is
1110 begin
1111 pragma Assert (Is_List_Member (Node));
1112 return Prev_Node.Table (Node);
1113 end Prev;
1115 procedure Prev (Node : in out Node_Id) is
1116 begin
1117 Node := Prev (Node);
1118 end Prev;
1120 -----------------------
1121 -- Prev_Node_Address --
1122 -----------------------
1124 function Prev_Node_Address return System.Address is
1125 begin
1126 return Prev_Node.Table (First_Node_Id)'Address;
1127 end Prev_Node_Address;
1129 ---------------------
1130 -- Prev_Non_Pragma --
1131 ---------------------
1133 function Prev_Non_Pragma (Node : Node_Id) return Node_Id is
1134 N : Node_Id;
1136 begin
1137 N := Node;
1138 loop
1139 N := Prev (N);
1140 exit when Nkind (N) /= N_Pragma;
1141 end loop;
1143 return N;
1144 end Prev_Non_Pragma;
1146 procedure Prev_Non_Pragma (Node : in out Node_Id) is
1147 begin
1148 Node := Prev_Non_Pragma (Node);
1149 end Prev_Non_Pragma;
1151 ------------
1152 -- Remove --
1153 ------------
1155 procedure Remove (Node : Node_Id) is
1156 Lst : constant List_Id := List_Containing (Node);
1157 Prv : constant Node_Id := Prev (Node);
1158 Nxt : constant Node_Id := Next (Node);
1160 procedure Remove_Debug;
1161 pragma Inline (Remove_Debug);
1162 -- Output debug information if Debug_Flag_N set
1164 procedure Remove_Debug is
1165 begin
1166 if Debug_Flag_N then
1167 Write_Str ("Remove node ");
1168 Write_Int (Int (Node));
1169 Write_Eol;
1170 end if;
1171 end Remove_Debug;
1173 -- Start of processing for Remove
1175 begin
1176 pragma Debug (Remove_Debug);
1178 if No (Prv) then
1179 Set_First (Lst, Nxt);
1180 else
1181 Set_Next (Prv, Nxt);
1182 end if;
1184 if No (Nxt) then
1185 Set_Last (Lst, Prv);
1186 else
1187 Set_Prev (Nxt, Prv);
1188 end if;
1190 Nodes.Table (Node).In_List := False;
1191 Set_Parent (Node, Empty);
1192 end Remove;
1194 -----------------
1195 -- Remove_Head --
1196 -----------------
1198 function Remove_Head (List : List_Id) return Node_Id is
1199 Frst : constant Node_Id := First (List);
1201 procedure Remove_Head_Debug;
1202 pragma Inline (Remove_Head_Debug);
1203 -- Output debug information if Debug_Flag_N set
1205 procedure Remove_Head_Debug is
1206 begin
1207 if Debug_Flag_N then
1208 Write_Str ("Remove head of list ");
1209 Write_Int (Int (List));
1210 Write_Eol;
1211 end if;
1212 end Remove_Head_Debug;
1214 -- Start of processing for Remove_Head
1216 begin
1217 pragma Debug (Remove_Head_Debug);
1219 if Frst = Empty then
1220 return Empty;
1222 else
1223 declare
1224 Nxt : constant Node_Id := Next (Frst);
1226 begin
1227 Set_First (List, Nxt);
1229 if No (Nxt) then
1230 Set_Last (List, Empty);
1231 else
1232 Set_Prev (Nxt, Empty);
1233 end if;
1235 Nodes.Table (Frst).In_List := False;
1236 Set_Parent (Frst, Empty);
1237 return Frst;
1238 end;
1239 end if;
1240 end Remove_Head;
1242 -----------------
1243 -- Remove_Next --
1244 -----------------
1246 function Remove_Next (Node : Node_Id) return Node_Id is
1247 Nxt : constant Node_Id := Next (Node);
1249 begin
1250 if Present (Nxt) then
1251 declare
1252 Nxt2 : constant Node_Id := Next (Nxt);
1253 LC : constant List_Id := List_Containing (Node);
1255 begin
1256 pragma Debug (Remove_Next_Debug (Node));
1257 Set_Next (Node, Nxt2);
1259 if No (Nxt2) then
1260 Set_Last (LC, Node);
1261 else
1262 Set_Prev (Nxt2, Node);
1263 end if;
1265 Nodes.Table (Nxt).In_List := False;
1266 Set_Parent (Nxt, Empty);
1267 end;
1268 end if;
1270 return Nxt;
1271 end Remove_Next;
1273 -----------------------
1274 -- Remove_Next_Debug --
1275 -----------------------
1277 procedure Remove_Next_Debug (Node : Node_Id) is
1278 begin
1279 if Debug_Flag_N then
1280 Write_Str ("Remove next node after ");
1281 Write_Int (Int (Node));
1282 Write_Eol;
1283 end if;
1284 end Remove_Next_Debug;
1286 ---------------
1287 -- Set_First --
1288 ---------------
1290 -- This subprogram is deliberately placed early on, out of alphabetical
1291 -- order, so that it can be properly inlined from within this unit.
1293 procedure Set_First (List : List_Id; To : Node_Id) is
1294 begin
1295 Lists.Table (List).First := To;
1296 end Set_First;
1298 --------------
1299 -- Set_Last --
1300 --------------
1302 -- This subprogram is deliberately placed early on, out of alphabetical
1303 -- order, so that it can be properly inlined from within this unit.
1305 procedure Set_Last (List : List_Id; To : Node_Id) is
1306 begin
1307 Lists.Table (List).Last := To;
1308 end Set_Last;
1310 -------------------
1311 -- Set_List_Link --
1312 -------------------
1314 -- This subprogram is deliberately placed early on, out of alphabetical
1315 -- order, so that it can be properly inlined from within this unit.
1317 procedure Set_List_Link (Node : Node_Id; To : List_Id) is
1318 begin
1319 Nodes.Table (Node).Link := Union_Id (To);
1320 end Set_List_Link;
1322 --------------
1323 -- Set_Next --
1324 --------------
1326 -- This subprogram is deliberately placed early on, out of alphabetical
1327 -- order, so that it can be properly inlined from within this unit.
1329 procedure Set_Next (Node : Node_Id; To : Node_Id) is
1330 begin
1331 Next_Node.Table (Node) := To;
1332 end Set_Next;
1334 ----------------
1335 -- Set_Parent --
1336 ----------------
1338 procedure Set_Parent (List : List_Id; Node : Node_Id) is
1339 begin
1340 pragma Assert (List in First_List_Id .. Lists.Last);
1341 Lists.Table (List).Parent := Node;
1342 end Set_Parent;
1344 --------------
1345 -- Set_Prev --
1346 --------------
1348 -- This subprogram is deliberately placed early on, out of alphabetical
1349 -- order, so that it can be properly inlined from within this unit.
1351 procedure Set_Prev (Node : Node_Id; To : Node_Id) is
1352 begin
1353 Prev_Node.Table (Node) := To;
1354 end Set_Prev;
1356 ---------------
1357 -- Tree_Read --
1358 ---------------
1360 procedure Tree_Read is
1361 begin
1362 Lists.Tree_Read;
1363 Next_Node.Tree_Read;
1364 Prev_Node.Tree_Read;
1365 end Tree_Read;
1367 ----------------
1368 -- Tree_Write --
1369 ----------------
1371 procedure Tree_Write is
1372 begin
1373 Lists.Tree_Write;
1374 Next_Node.Tree_Write;
1375 Prev_Node.Tree_Write;
1376 end Tree_Write;
1378 end Nlists;