* gcc.c-torture/execute/20020307-1.c: New test.
[official-gcc.git] / gcc / ada / nlists.adb
blob5e8fe695b9d8deb85857982808bab1feff6c24f8
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- N L I S T S --
6 -- --
7 -- B o d y --
8 -- --
9 -- $Revision: 1.35 $ --
10 -- --
11 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
23 -- --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
30 -- --
31 -- GNAT was originally developed by the GNAT team at New York University. --
32 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
33 -- --
34 ------------------------------------------------------------------------------
36 -- WARNING: There is a C version of this package. Any changes to this source
37 -- file must be properly reflected in the corresponding C header a-nlists.h
39 with Alloc;
40 with Atree; use Atree;
41 with Debug; use Debug;
42 with Output; use Output;
43 with Sinfo; use Sinfo;
44 with Table;
46 package body Nlists is
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
56 -- three fields:
58 type List_Header is record
59 First : Node_Id;
60 -- Pointer to first node in list. Empty if list is empty
62 Last : Node_Id;
63 -- Pointer to last node in list. Empty if list is empty
65 Parent : Node_Id;
66 -- Pointer to parent of list. Empty if list has no parent
67 end record;
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,
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_Id,
93 Table_Index_Type => Node_Id,
94 Table_Low_Bound => First_Node_Id,
95 Table_Initial => Alloc.Orig_Nodes_Initial,
96 Table_Increment => Alloc.Orig_Nodes_Increment,
97 Table_Name => "Next_Node");
99 package Prev_Node is new Table.Table (
100 Table_Component_Type => Node_Id,
101 Table_Index_Type => Node_Id,
102 Table_Low_Bound => First_Node_Id,
103 Table_Initial => Alloc.Orig_Nodes_Initial,
104 Table_Increment => Alloc.Orig_Nodes_Increment,
105 Table_Name => "Prev_Node");
107 -----------------------
108 -- Local Subprograms --
109 -----------------------
111 procedure Prepend_Debug (Node : Node_Id; To : List_Id);
112 pragma Inline (Prepend_Debug);
113 -- Output debug information if Debug_Flag_N set
115 procedure Remove_Next_Debug (Node : Node_Id);
116 pragma Inline (Remove_Next_Debug);
117 -- Output debug information if Debug_Flag_N set
119 procedure Set_First (List : List_Id; To : Node_Id);
120 pragma Inline (Set_First);
121 -- Sets First field of list header List to reference To
123 procedure Set_Last (List : List_Id; To : Node_Id);
124 pragma Inline (Set_Last);
125 -- Sets Last field of list header List to reference To
127 procedure Set_List_Link (Node : Node_Id; To : List_Id);
128 pragma Inline (Set_List_Link);
129 -- Sets list link of Node to list header To
131 procedure Set_Next (Node : Node_Id; To : Node_Id);
132 pragma Inline (Set_Next);
133 -- Sets the Next_Node pointer for Node to reference To
135 procedure Set_Prev (Node : Node_Id; To : Node_Id);
136 pragma Inline (Set_Prev);
137 -- Sets the Prev_Node pointer for Node to reference To
139 --------------------------
140 -- Allocate_List_Tables --
141 --------------------------
143 procedure Allocate_List_Tables (N : Node_Id) is
144 begin
145 Next_Node.Set_Last (N);
146 Prev_Node.Set_Last (N);
147 end Allocate_List_Tables;
149 ------------
150 -- Append --
151 ------------
153 procedure Append (Node : Node_Id; To : List_Id) is
154 L : constant Node_Id := Last (To);
156 procedure Append_Debug;
157 pragma Inline (Append_Debug);
158 -- Output debug information if Debug_Flag_N set
160 procedure Append_Debug is
161 begin
162 if Debug_Flag_N then
163 Write_Str ("Append node ");
164 Write_Int (Int (Node));
165 Write_Str (" to list ");
166 Write_Int (Int (To));
167 Write_Eol;
168 end if;
169 end Append_Debug;
171 -- Start of processing for Append
173 begin
174 pragma Assert (not Is_List_Member (Node));
176 if Node = Error then
177 return;
178 end if;
180 pragma Debug (Append_Debug);
182 if No (L) then
183 Set_First (To, Node);
184 else
185 Set_Next (L, Node);
186 end if;
188 Set_Last (To, Node);
190 Nodes.Table (Node).In_List := True;
192 Set_Next (Node, Empty);
193 Set_Prev (Node, L);
194 Set_List_Link (Node, To);
195 end Append;
197 -----------------
198 -- Append_List --
199 -----------------
201 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 procedure Append_List_Debug is
208 begin
209 if Debug_Flag_N then
210 Write_Str ("Append list ");
211 Write_Int (Int (List));
212 Write_Str (" to list ");
213 Write_Int (Int (To));
214 Write_Eol;
215 end if;
216 end Append_List_Debug;
218 -- Start of processing for Append_List
220 begin
221 if Is_Empty_List (List) then
222 return;
224 else
225 declare
226 L : constant Node_Id := Last (To);
227 F : constant Node_Id := First (List);
228 N : Node_Id;
230 begin
231 pragma Debug (Append_List_Debug);
233 N := F;
234 loop
235 Set_List_Link (N, To);
236 N := Next (N);
237 exit when No (N);
238 end loop;
240 if No (L) then
241 Set_First (To, F);
242 else
243 Set_Next (L, F);
244 end if;
246 Set_Prev (F, L);
247 Set_Last (To, Last (List));
249 Set_First (List, Empty);
250 Set_Last (List, Empty);
251 end;
252 end if;
253 end Append_List;
255 --------------------
256 -- Append_List_To --
257 --------------------
259 procedure Append_List_To (To : List_Id; List : List_Id) is
260 begin
261 Append_List (List, To);
262 end Append_List_To;
264 ---------------
265 -- Append_To --
266 ---------------
268 procedure Append_To (To : List_Id; Node : Node_Id) is
269 begin
270 Append (Node, To);
271 end Append_To;
273 -----------------
274 -- Delete_List --
275 -----------------
277 procedure Delete_List (L : List_Id) is
278 N : Node_Id;
280 begin
281 while Is_Non_Empty_List (L) loop
282 N := Remove_Head (L);
283 Delete_Tree (N);
284 end loop;
286 -- Should recycle list header???
287 end Delete_List;
289 -----------
290 -- First --
291 -----------
293 -- This subprogram is deliberately placed early on, out of alphabetical
294 -- order, so that it can be properly inlined from within this unit.
296 function First (List : List_Id) return Node_Id is
297 begin
298 if List = No_List then
299 return Empty;
300 else
301 pragma Assert (List in First_List_Id .. Lists.Last);
302 return Lists.Table (List).First;
303 end if;
304 end First;
306 ----------------------
307 -- First_Non_Pragma --
308 ----------------------
310 function First_Non_Pragma (List : List_Id) return Node_Id is
311 N : constant Node_Id := First (List);
313 begin
314 if Nkind (N) /= N_Pragma
315 and then
316 Nkind (N) /= N_Null_Statement
317 then
318 return N;
319 else
320 return Next_Non_Pragma (N);
321 end if;
322 end First_Non_Pragma;
324 ----------------
325 -- Initialize --
326 ----------------
328 procedure Initialize is
329 E : constant List_Id := Error_List;
331 begin
332 Lists.Init;
333 Next_Node.Init;
334 Prev_Node.Init;
336 -- Allocate Error_List list header
338 Lists.Increment_Last;
339 Set_Parent (E, Empty);
340 Set_First (E, Empty);
341 Set_Last (E, Empty);
342 end Initialize;
344 ------------------
345 -- Insert_After --
346 ------------------
348 procedure Insert_After (After : Node_Id; Node : Node_Id) is
350 procedure Insert_After_Debug;
351 pragma Inline (Insert_After_Debug);
352 -- Output debug information if Debug_Flag_N set
354 procedure Insert_After_Debug is
355 begin
356 if Debug_Flag_N then
357 Write_Str ("Insert node");
358 Write_Int (Int (Node));
359 Write_Str (" after node ");
360 Write_Int (Int (After));
361 Write_Eol;
362 end if;
363 end Insert_After_Debug;
365 -- Start of processing for Insert_After
367 begin
368 pragma Assert
369 (Is_List_Member (After) and then not Is_List_Member (Node));
371 if Node = Error then
372 return;
373 end if;
375 pragma Debug (Insert_After_Debug);
377 declare
378 Before : constant Node_Id := Next (After);
379 LC : constant List_Id := List_Containing (After);
381 begin
382 if Present (Before) then
383 Set_Prev (Before, Node);
384 else
385 Set_Last (LC, Node);
386 end if;
388 Set_Next (After, Node);
390 Nodes.Table (Node).In_List := True;
392 Set_Prev (Node, After);
393 Set_Next (Node, Before);
394 Set_List_Link (Node, LC);
395 end;
396 end Insert_After;
398 -------------------
399 -- Insert_Before --
400 -------------------
402 procedure Insert_Before (Before : Node_Id; Node : Node_Id) is
404 procedure Insert_Before_Debug;
405 pragma Inline (Insert_Before_Debug);
406 -- Output debug information if Debug_Flag_N set
408 procedure Insert_Before_Debug is
409 begin
410 if Debug_Flag_N then
411 Write_Str ("Insert node");
412 Write_Int (Int (Node));
413 Write_Str (" before node ");
414 Write_Int (Int (Before));
415 Write_Eol;
416 end if;
417 end Insert_Before_Debug;
419 -- Start of processing for Insert_Before
421 begin
422 pragma Assert
423 (Is_List_Member (Before) and then not Is_List_Member (Node));
425 if Node = Error then
426 return;
427 end if;
429 pragma Debug (Insert_Before_Debug);
431 declare
432 After : constant Node_Id := Prev (Before);
433 LC : constant List_Id := List_Containing (Before);
435 begin
436 if Present (After) then
437 Set_Next (After, Node);
438 else
439 Set_First (LC, Node);
440 end if;
442 Set_Prev (Before, Node);
444 Nodes.Table (Node).In_List := True;
446 Set_Prev (Node, After);
447 Set_Next (Node, Before);
448 Set_List_Link (Node, LC);
449 end;
450 end Insert_Before;
452 -----------------------
453 -- Insert_List_After --
454 -----------------------
456 procedure Insert_List_After (After : Node_Id; List : List_Id) is
458 procedure Insert_List_After_Debug;
459 pragma Inline (Insert_List_After_Debug);
460 -- Output debug information if Debug_Flag_N set
462 procedure Insert_List_After_Debug is
463 begin
464 if Debug_Flag_N then
465 Write_Str ("Insert list ");
466 Write_Int (Int (List));
467 Write_Str (" after node ");
468 Write_Int (Int (After));
469 Write_Eol;
470 end if;
471 end Insert_List_After_Debug;
473 -- Start of processing for Insert_List_After
475 begin
476 pragma Assert (Is_List_Member (After));
478 if Is_Empty_List (List) then
479 return;
481 else
482 declare
483 Before : constant Node_Id := Next (After);
484 LC : constant List_Id := List_Containing (After);
485 F : constant Node_Id := First (List);
486 L : constant Node_Id := Last (List);
487 N : Node_Id;
489 begin
490 pragma Debug (Insert_List_After_Debug);
492 N := F;
493 loop
494 Set_List_Link (N, LC);
495 exit when N = L;
496 N := Next (N);
497 end loop;
499 if Present (Before) then
500 Set_Prev (Before, L);
501 else
502 Set_Last (LC, L);
503 end if;
505 Set_Next (After, F);
506 Set_Prev (F, After);
507 Set_Next (L, Before);
509 Set_First (List, Empty);
510 Set_Last (List, Empty);
511 end;
512 end if;
513 end Insert_List_After;
515 ------------------------
516 -- Insert_List_Before --
517 ------------------------
519 procedure Insert_List_Before (Before : Node_Id; List : List_Id) is
521 procedure Insert_List_Before_Debug;
522 pragma Inline (Insert_List_Before_Debug);
523 -- Output debug information if Debug_Flag_N set
525 procedure Insert_List_Before_Debug is
526 begin
527 if Debug_Flag_N then
528 Write_Str ("Insert list ");
529 Write_Int (Int (List));
530 Write_Str (" before node ");
531 Write_Int (Int (Before));
532 Write_Eol;
533 end if;
534 end Insert_List_Before_Debug;
536 -- Start of prodcessing for Insert_List_Before
538 begin
539 pragma Assert (Is_List_Member (Before));
541 if Is_Empty_List (List) then
542 return;
544 else
545 declare
546 After : constant Node_Id := Prev (Before);
547 LC : constant List_Id := List_Containing (Before);
548 F : constant Node_Id := First (List);
549 L : constant Node_Id := Last (List);
550 N : Node_Id;
552 begin
553 pragma Debug (Insert_List_Before_Debug);
555 N := F;
556 loop
557 Set_List_Link (N, LC);
558 exit when N = L;
559 N := Next (N);
560 end loop;
562 if Present (After) then
563 Set_Next (After, F);
564 else
565 Set_First (LC, F);
566 end if;
568 Set_Prev (Before, L);
569 Set_Prev (F, After);
570 Set_Next (L, Before);
572 Set_First (List, Empty);
573 Set_Last (List, Empty);
574 end;
575 end if;
576 end Insert_List_Before;
578 -------------------
579 -- Is_Empty_List --
580 -------------------
582 function Is_Empty_List (List : List_Id) return Boolean is
583 begin
584 return First (List) = Empty;
585 end Is_Empty_List;
587 --------------------
588 -- Is_List_Member --
589 --------------------
591 function Is_List_Member (Node : Node_Id) return Boolean is
592 begin
593 return Nodes.Table (Node).In_List;
594 end Is_List_Member;
596 -----------------------
597 -- Is_Non_Empty_List --
598 -----------------------
600 function Is_Non_Empty_List (List : List_Id) return Boolean is
601 begin
602 return List /= No_List and then First (List) /= Empty;
603 end Is_Non_Empty_List;
605 ----------
606 -- Last --
607 ----------
609 -- This subprogram is deliberately placed early on, out of alphabetical
610 -- order, so that it can be properly inlined from within this unit.
612 function Last (List : List_Id) return Node_Id is
613 begin
614 pragma Assert (List in First_List_Id .. Lists.Last);
615 return Lists.Table (List).Last;
616 end Last;
618 ------------------
619 -- Last_List_Id --
620 ------------------
622 function Last_List_Id return List_Id is
623 begin
624 return Lists.Last;
625 end Last_List_Id;
627 ---------------------
628 -- Last_Non_Pragma --
629 ---------------------
631 function Last_Non_Pragma (List : List_Id) return Node_Id is
632 N : constant Node_Id := Last (List);
634 begin
635 if Nkind (N) /= N_Pragma then
636 return N;
637 else
638 return Prev_Non_Pragma (N);
639 end if;
640 end Last_Non_Pragma;
642 ---------------------
643 -- List_Containing --
644 ---------------------
646 function List_Containing (Node : Node_Id) return List_Id is
647 begin
648 pragma Assert (Is_List_Member (Node));
649 return List_Id (Nodes.Table (Node).Link);
650 end List_Containing;
652 -----------------
653 -- List_Length --
654 -----------------
656 function List_Length (List : List_Id) return Nat is
657 Result : Nat;
658 Node : Node_Id;
660 begin
661 Result := 0;
662 Node := First (List);
663 while Present (Node) loop
664 Result := Result + 1;
665 Node := Next (Node);
666 end loop;
668 return Result;
669 end List_Length;
671 -------------------
672 -- Lists_Address --
673 -------------------
675 function Lists_Address return System.Address is
676 begin
677 return Lists.Table (First_List_Id)'Address;
678 end Lists_Address;
680 ----------
681 -- Lock --
682 ----------
684 procedure Lock is
685 begin
686 Lists.Locked := True;
687 Lists.Release;
689 Prev_Node.Locked := True;
690 Next_Node.Locked := True;
692 Prev_Node.Release;
693 Next_Node.Release;
694 end Lock;
696 -------------------
697 -- New_Copy_List --
698 -------------------
700 function New_Copy_List (List : List_Id) return List_Id is
701 NL : List_Id;
702 E : Node_Id;
704 begin
705 if List = No_List then
706 return No_List;
708 else
709 NL := New_List;
710 E := First (List);
712 while Present (E) loop
713 Append (New_Copy (E), NL);
714 E := Next (E);
715 end loop;
717 return NL;
718 end if;
719 end New_Copy_List;
721 ----------------------------
722 -- New_Copy_List_Original --
723 ----------------------------
725 function New_Copy_List_Original (List : List_Id) return List_Id is
726 NL : List_Id;
727 E : Node_Id;
729 begin
730 if List = No_List then
731 return No_List;
733 else
734 NL := New_List;
735 E := First (List);
737 while Present (E) loop
738 if Comes_From_Source (E) then
739 Append (New_Copy (E), NL);
740 end if;
742 E := Next (E);
743 end loop;
745 return NL;
746 end if;
747 end New_Copy_List_Original;
749 ------------------------
750 -- New_Copy_List_Tree --
751 ------------------------
753 function New_Copy_List_Tree (List : List_Id) return List_Id is
754 NL : List_Id;
755 E : Node_Id;
757 begin
758 if List = No_List then
759 return No_List;
761 else
762 NL := New_List;
763 E := First (List);
765 while Present (E) loop
766 Append (New_Copy_Tree (E), NL);
767 E := Next (E);
768 end loop;
770 return NL;
771 end if;
772 end New_Copy_List_Tree;
774 --------------
775 -- New_List --
776 --------------
778 function New_List return List_Id is
780 procedure New_List_Debug;
781 pragma Inline (New_List_Debug);
782 -- Output debugging information if Debug_Flag_N is set
784 procedure New_List_Debug is
785 begin
786 if Debug_Flag_N then
787 Write_Str ("Allocate new list, returned ID = ");
788 Write_Int (Int (Lists.Last));
789 Write_Eol;
790 end if;
791 end New_List_Debug;
793 -- Start of processing for New_List
795 begin
796 Lists.Increment_Last;
798 declare
799 List : constant List_Id := Lists.Last;
801 begin
802 Set_Parent (List, Empty);
803 Set_First (List, Empty);
804 Set_Last (List, Empty);
806 pragma Debug (New_List_Debug);
807 return (List);
808 end;
809 end New_List;
811 -- Since the one argument case is common, we optimize to build the right
812 -- list directly, rather than first building an empty list and then doing
813 -- the insertion, which results in some unnecessary work.
815 function New_List (Node : Node_Id) return List_Id is
817 procedure New_List_Debug;
818 pragma Inline (New_List_Debug);
819 -- Output debugging information if Debug_Flag_N is set
821 procedure New_List_Debug is
822 begin
823 if Debug_Flag_N then
824 Write_Str ("Allocate new list, returned ID = ");
825 Write_Int (Int (Lists.Last));
826 Write_Eol;
827 end if;
828 end New_List_Debug;
830 -- Start of processing for New_List
832 begin
833 if Node = Error then
834 return New_List;
836 else
837 pragma Assert (not Is_List_Member (Node));
839 Lists.Increment_Last;
841 declare
842 List : constant List_Id := Lists.Last;
844 begin
845 Set_Parent (List, Empty);
846 Set_First (List, Node);
847 Set_Last (List, Node);
849 Nodes.Table (Node).In_List := True;
850 Set_List_Link (Node, List);
851 Set_Prev (Node, Empty);
852 Set_Next (Node, Empty);
853 pragma Debug (New_List_Debug);
854 return List;
855 end;
856 end if;
857 end New_List;
859 function New_List (Node1, Node2 : Node_Id) return List_Id is
860 L : constant List_Id := New_List (Node1);
862 begin
863 Append (Node2, L);
864 return L;
865 end New_List;
867 function New_List (Node1, Node2, Node3 : Node_Id) return List_Id is
868 L : constant List_Id := New_List (Node1);
870 begin
871 Append (Node2, L);
872 Append (Node3, L);
873 return L;
874 end New_List;
876 function New_List (Node1, Node2, Node3, Node4 : Node_Id) return List_Id is
877 L : constant List_Id := New_List (Node1);
879 begin
880 Append (Node2, L);
881 Append (Node3, L);
882 Append (Node4, L);
883 return L;
884 end New_List;
886 function New_List
887 (Node1 : Node_Id;
888 Node2 : Node_Id;
889 Node3 : Node_Id;
890 Node4 : Node_Id;
891 Node5 : Node_Id)
892 return List_Id
894 L : constant List_Id := New_List (Node1);
896 begin
897 Append (Node2, L);
898 Append (Node3, L);
899 Append (Node4, L);
900 Append (Node5, L);
901 return L;
902 end New_List;
904 function New_List
905 (Node1 : Node_Id;
906 Node2 : Node_Id;
907 Node3 : Node_Id;
908 Node4 : Node_Id;
909 Node5 : Node_Id;
910 Node6 : Node_Id)
911 return List_Id
913 L : constant List_Id := New_List (Node1);
915 begin
916 Append (Node2, L);
917 Append (Node3, L);
918 Append (Node4, L);
919 Append (Node5, L);
920 Append (Node6, L);
921 return L;
922 end New_List;
924 ----------
925 -- Next --
926 ----------
928 -- This subprogram is deliberately placed early on, out of alphabetical
929 -- order, so that it can be properly inlined from within this unit.
931 function Next (Node : Node_Id) return Node_Id is
932 begin
933 pragma Assert (Is_List_Member (Node));
934 return Next_Node.Table (Node);
935 end Next;
937 procedure Next (Node : in out Node_Id) is
938 begin
939 Node := Next (Node);
940 end Next;
942 -----------------------
943 -- Next_Node_Address --
944 -----------------------
946 function Next_Node_Address return System.Address is
947 begin
948 return Next_Node.Table (First_Node_Id)'Address;
949 end Next_Node_Address;
951 ---------------------
952 -- Next_Non_Pragma --
953 ---------------------
955 function Next_Non_Pragma (Node : Node_Id) return Node_Id is
956 N : Node_Id;
958 begin
959 N := Node;
960 loop
961 N := Next (N);
962 exit when Nkind (N) /= N_Pragma
963 and then
964 Nkind (N) /= N_Null_Statement;
965 end loop;
967 return N;
968 end Next_Non_Pragma;
970 procedure Next_Non_Pragma (Node : in out Node_Id) is
971 begin
972 Node := Next_Non_Pragma (Node);
973 end Next_Non_Pragma;
975 --------
976 -- No --
977 --------
979 -- This subprogram is deliberately placed early on, out of alphabetical
980 -- order, so that it can be properly inlined from within this unit.
982 function No (List : List_Id) return Boolean is
983 begin
984 return List = No_List;
985 end No;
987 ---------------
988 -- Num_Lists --
989 ---------------
991 function Num_Lists return Nat is
992 begin
993 return Int (Lists.Last) - Int (Lists.First) + 1;
994 end Num_Lists;
996 -------
997 -- p --
998 -------
1000 function p (U : Union_Id) return Node_Id is
1001 begin
1002 if U in Node_Range then
1003 return Parent (Node_Id (U));
1005 elsif U in List_Range then
1006 return Parent (List_Id (U));
1008 else
1009 return 99_999_999;
1010 end if;
1011 end p;
1013 ------------
1014 -- Parent --
1015 ------------
1017 function Parent (List : List_Id) return Node_Id is
1018 begin
1019 pragma Assert (List in First_List_Id .. Lists.Last);
1020 return Lists.Table (List).Parent;
1021 end Parent;
1023 ----------
1024 -- Pick --
1025 ----------
1027 function Pick (List : List_Id; Index : Pos) return Node_Id is
1028 Elmt : Node_Id;
1030 begin
1031 Elmt := First (List);
1032 for J in 1 .. Index - 1 loop
1033 Elmt := Next (Elmt);
1034 end loop;
1036 return Elmt;
1037 end Pick;
1039 -------------
1040 -- Prepend --
1041 -------------
1043 procedure Prepend (Node : Node_Id; To : List_Id) is
1044 F : constant Node_Id := First (To);
1046 begin
1047 pragma Assert (not Is_List_Member (Node));
1049 if Node = Error then
1050 return;
1051 end if;
1053 pragma Debug (Prepend_Debug (Node, To));
1055 if No (F) then
1056 Set_Last (To, Node);
1057 else
1058 Set_Prev (F, Node);
1059 end if;
1061 Set_First (To, Node);
1063 Nodes.Table (Node).In_List := True;
1065 Set_Next (Node, F);
1066 Set_Prev (Node, Empty);
1067 Set_List_Link (Node, To);
1068 end Prepend;
1070 -------------------
1071 -- Prepend_Debug --
1072 -------------------
1074 procedure Prepend_Debug (Node : Node_Id; To : List_Id) is
1075 begin
1076 if Debug_Flag_N then
1077 Write_Str ("Prepend node ");
1078 Write_Int (Int (Node));
1079 Write_Str (" to list ");
1080 Write_Int (Int (To));
1081 Write_Eol;
1082 end if;
1083 end Prepend_Debug;
1085 ----------------
1086 -- Prepend_To --
1087 ----------------
1089 procedure Prepend_To (To : List_Id; Node : Node_Id) is
1090 begin
1091 Prepend (Node, To);
1092 end Prepend_To;
1094 -------------
1095 -- Present --
1096 -------------
1098 function Present (List : List_Id) return Boolean is
1099 begin
1100 return List /= No_List;
1101 end Present;
1103 ----------
1104 -- Prev --
1105 ----------
1107 -- This subprogram is deliberately placed early on, out of alphabetical
1108 -- order, so that it can be properly inlined from within this unit.
1110 function Prev (Node : Node_Id) return Node_Id is
1111 begin
1112 pragma Assert (Is_List_Member (Node));
1113 return Prev_Node.Table (Node);
1114 end Prev;
1116 procedure Prev (Node : in out Node_Id) is
1117 begin
1118 Node := Prev (Node);
1119 end Prev;
1121 -----------------------
1122 -- Prev_Node_Address --
1123 -----------------------
1125 function Prev_Node_Address return System.Address is
1126 begin
1127 return Prev_Node.Table (First_Node_Id)'Address;
1128 end Prev_Node_Address;
1130 ---------------------
1131 -- Prev_Non_Pragma --
1132 ---------------------
1134 function Prev_Non_Pragma (Node : Node_Id) return Node_Id is
1135 N : Node_Id;
1137 begin
1138 N := Node;
1139 loop
1140 N := Prev (N);
1141 exit when Nkind (N) /= N_Pragma;
1142 end loop;
1144 return N;
1145 end Prev_Non_Pragma;
1147 procedure Prev_Non_Pragma (Node : in out Node_Id) is
1148 begin
1149 Node := Prev_Non_Pragma (Node);
1150 end Prev_Non_Pragma;
1152 ------------
1153 -- Remove --
1154 ------------
1156 procedure Remove (Node : Node_Id) is
1157 Lst : constant List_Id := List_Containing (Node);
1158 Prv : constant Node_Id := Prev (Node);
1159 Nxt : constant Node_Id := Next (Node);
1161 procedure Remove_Debug;
1162 pragma Inline (Remove_Debug);
1163 -- Output debug information if Debug_Flag_N set
1165 procedure Remove_Debug is
1166 begin
1167 if Debug_Flag_N then
1168 Write_Str ("Remove node ");
1169 Write_Int (Int (Node));
1170 Write_Eol;
1171 end if;
1172 end Remove_Debug;
1174 -- Start of processing for Remove
1176 begin
1177 pragma Debug (Remove_Debug);
1179 if No (Prv) then
1180 Set_First (Lst, Nxt);
1181 else
1182 Set_Next (Prv, Nxt);
1183 end if;
1185 if No (Nxt) then
1186 Set_Last (Lst, Prv);
1187 else
1188 Set_Prev (Nxt, Prv);
1189 end if;
1191 Nodes.Table (Node).In_List := False;
1192 Set_Parent (Node, Empty);
1193 end Remove;
1195 -----------------
1196 -- Remove_Head --
1197 -----------------
1199 function Remove_Head (List : List_Id) return Node_Id is
1200 Frst : constant Node_Id := First (List);
1202 procedure Remove_Head_Debug;
1203 pragma Inline (Remove_Head_Debug);
1204 -- Output debug information if Debug_Flag_N set
1206 procedure Remove_Head_Debug is
1207 begin
1208 if Debug_Flag_N then
1209 Write_Str ("Remove head of list ");
1210 Write_Int (Int (List));
1211 Write_Eol;
1212 end if;
1213 end Remove_Head_Debug;
1215 -- Start of processing for Remove_Head
1217 begin
1218 pragma Debug (Remove_Head_Debug);
1220 if Frst = Empty then
1221 return Empty;
1223 else
1224 declare
1225 Nxt : constant Node_Id := Next (Frst);
1227 begin
1228 Set_First (List, Nxt);
1230 if No (Nxt) then
1231 Set_Last (List, Empty);
1232 else
1233 Set_Prev (Nxt, Empty);
1234 end if;
1236 Nodes.Table (Frst).In_List := False;
1237 Set_Parent (Frst, Empty);
1238 return Frst;
1239 end;
1240 end if;
1241 end Remove_Head;
1243 -----------------
1244 -- Remove_Next --
1245 -----------------
1247 function Remove_Next (Node : Node_Id) return Node_Id is
1248 Nxt : constant Node_Id := Next (Node);
1250 begin
1251 if Present (Nxt) then
1252 declare
1253 Nxt2 : constant Node_Id := Next (Nxt);
1254 LC : constant List_Id := List_Containing (Node);
1256 begin
1257 pragma Debug (Remove_Next_Debug (Node));
1258 Set_Next (Node, Nxt2);
1260 if No (Nxt2) then
1261 Set_Last (LC, Node);
1262 else
1263 Set_Prev (Nxt2, Node);
1264 end if;
1266 Nodes.Table (Nxt).In_List := False;
1267 Set_Parent (Nxt, Empty);
1268 end;
1269 end if;
1271 return Nxt;
1272 end Remove_Next;
1274 -----------------------
1275 -- Remove_Next_Debug --
1276 -----------------------
1278 procedure Remove_Next_Debug (Node : Node_Id) is
1279 begin
1280 if Debug_Flag_N then
1281 Write_Str ("Remove next node after ");
1282 Write_Int (Int (Node));
1283 Write_Eol;
1284 end if;
1285 end Remove_Next_Debug;
1287 ---------------
1288 -- Set_First --
1289 ---------------
1291 -- This subprogram is deliberately placed early on, out of alphabetical
1292 -- order, so that it can be properly inlined from within this unit.
1294 procedure Set_First (List : List_Id; To : Node_Id) is
1295 begin
1296 Lists.Table (List).First := To;
1297 end Set_First;
1299 --------------
1300 -- Set_Last --
1301 --------------
1303 -- This subprogram is deliberately placed early on, out of alphabetical
1304 -- order, so that it can be properly inlined from within this unit.
1306 procedure Set_Last (List : List_Id; To : Node_Id) is
1307 begin
1308 Lists.Table (List).Last := To;
1309 end Set_Last;
1311 -------------------
1312 -- Set_List_Link --
1313 -------------------
1315 -- This subprogram is deliberately placed early on, out of alphabetical
1316 -- order, so that it can be properly inlined from within this unit.
1318 procedure Set_List_Link (Node : Node_Id; To : List_Id) is
1319 begin
1320 Nodes.Table (Node).Link := Union_Id (To);
1321 end Set_List_Link;
1323 --------------
1324 -- Set_Next --
1325 --------------
1327 -- This subprogram is deliberately placed early on, out of alphabetical
1328 -- order, so that it can be properly inlined from within this unit.
1330 procedure Set_Next (Node : Node_Id; To : Node_Id) is
1331 begin
1332 Next_Node.Table (Node) := To;
1333 end Set_Next;
1335 ----------------
1336 -- Set_Parent --
1337 ----------------
1339 procedure Set_Parent (List : List_Id; Node : Node_Id) is
1340 begin
1341 pragma Assert (List in First_List_Id .. Lists.Last);
1342 Lists.Table (List).Parent := Node;
1343 end Set_Parent;
1345 --------------
1346 -- Set_Prev --
1347 --------------
1349 -- This subprogram is deliberately placed early on, out of alphabetical
1350 -- order, so that it can be properly inlined from within this unit.
1352 procedure Set_Prev (Node : Node_Id; To : Node_Id) is
1353 begin
1354 Prev_Node.Table (Node) := To;
1355 end Set_Prev;
1357 ---------------
1358 -- Tree_Read --
1359 ---------------
1361 procedure Tree_Read is
1362 begin
1363 Lists.Tree_Read;
1364 Next_Node.Tree_Read;
1365 Prev_Node.Tree_Read;
1366 end Tree_Read;
1368 ----------------
1369 -- Tree_Write --
1370 ----------------
1372 procedure Tree_Write is
1373 begin
1374 Lists.Tree_Write;
1375 Next_Node.Tree_Write;
1376 Prev_Node.Tree_Write;
1377 end Tree_Write;
1379 end Nlists;