* sh.h (REG_CLASS_FROM_LETTER): Change to:
[official-gcc.git] / gcc / ada / nlists.adb
blob7a2d2fd407b4c9b249d3c644f3f67a08b57d1c41
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- N L I S T S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 -- WARNING: There is a C version of this package. Any changes to this source
35 -- file must be properly reflected in the corresponding C header a-nlists.h
37 with Alloc;
38 with Atree; use Atree;
39 with Debug; use Debug;
40 with Output; use Output;
41 with Sinfo; use Sinfo;
42 with Table;
44 package body Nlists is
46 use Atree_Private_Part;
47 -- Get access to Nodes table
49 ----------------------------------
50 -- Implementation of Node Lists --
51 ----------------------------------
53 -- A node list is represented by a list header which contains
54 -- three fields:
56 type List_Header is record
57 First : Node_Id;
58 -- Pointer to first node in list. Empty if list is empty
60 Last : Node_Id;
61 -- Pointer to last node in list. Empty if list is empty
63 Parent : Node_Id;
64 -- Pointer to parent of list. Empty if list has no parent
65 end record;
67 -- The node lists are stored in a table indexed by List_Id values
69 package Lists is new Table.Table (
70 Table_Component_Type => List_Header,
71 Table_Index_Type => List_Id,
72 Table_Low_Bound => First_List_Id,
73 Table_Initial => Alloc.Lists_Initial,
74 Table_Increment => Alloc.Lists_Increment,
75 Table_Name => "Lists");
77 -- The nodes in the list all have the In_List flag set, and their Link
78 -- fields (which otherwise point to the parent) contain the List_Id of
79 -- the list header giving immediate access to the list containing the
80 -- node, and its parent and first and last elements.
82 -- Two auxiliary tables, indexed by Node_Id values and built in parallel
83 -- with the main nodes table and always having the same size contain the
84 -- list link values that allow locating the previous and next node in a
85 -- list. The entries in these tables are valid only if the In_List flag
86 -- is set in the corresponding node. Next_Node is Empty at the end of a
87 -- list and Prev_Node is Empty at the start of a list.
89 package Next_Node is new Table.Table (
90 Table_Component_Type => Node_Id,
91 Table_Index_Type => Node_Id,
92 Table_Low_Bound => First_Node_Id,
93 Table_Initial => Alloc.Orig_Nodes_Initial,
94 Table_Increment => Alloc.Orig_Nodes_Increment,
95 Table_Name => "Next_Node");
97 package Prev_Node is new Table.Table (
98 Table_Component_Type => Node_Id,
99 Table_Index_Type => Node_Id,
100 Table_Low_Bound => First_Node_Id,
101 Table_Initial => Alloc.Orig_Nodes_Initial,
102 Table_Increment => Alloc.Orig_Nodes_Increment,
103 Table_Name => "Prev_Node");
105 -----------------------
106 -- Local Subprograms --
107 -----------------------
109 procedure Prepend_Debug (Node : Node_Id; To : List_Id);
110 pragma Inline (Prepend_Debug);
111 -- Output debug information if Debug_Flag_N set
113 procedure Remove_Next_Debug (Node : Node_Id);
114 pragma Inline (Remove_Next_Debug);
115 -- Output debug information if Debug_Flag_N set
117 procedure Set_First (List : List_Id; To : Node_Id);
118 pragma Inline (Set_First);
119 -- Sets First field of list header List to reference To
121 procedure Set_Last (List : List_Id; To : Node_Id);
122 pragma Inline (Set_Last);
123 -- Sets Last field of list header List to reference To
125 procedure Set_List_Link (Node : Node_Id; To : List_Id);
126 pragma Inline (Set_List_Link);
127 -- Sets list link of Node to list header To
129 procedure Set_Next (Node : Node_Id; To : Node_Id);
130 pragma Inline (Set_Next);
131 -- Sets the Next_Node pointer for Node to reference To
133 procedure Set_Prev (Node : Node_Id; To : Node_Id);
134 pragma Inline (Set_Prev);
135 -- Sets the Prev_Node pointer for Node to reference To
137 --------------------------
138 -- Allocate_List_Tables --
139 --------------------------
141 procedure Allocate_List_Tables (N : Node_Id) is
142 begin
143 Next_Node.Set_Last (N);
144 Prev_Node.Set_Last (N);
145 end Allocate_List_Tables;
147 ------------
148 -- Append --
149 ------------
151 procedure Append (Node : Node_Id; To : List_Id) is
152 L : constant Node_Id := Last (To);
154 procedure Append_Debug;
155 pragma Inline (Append_Debug);
156 -- Output debug information if Debug_Flag_N set
158 procedure Append_Debug is
159 begin
160 if Debug_Flag_N then
161 Write_Str ("Append node ");
162 Write_Int (Int (Node));
163 Write_Str (" to list ");
164 Write_Int (Int (To));
165 Write_Eol;
166 end if;
167 end Append_Debug;
169 -- Start of processing for Append
171 begin
172 pragma Assert (not Is_List_Member (Node));
174 if Node = Error then
175 return;
176 end if;
178 pragma Debug (Append_Debug);
180 if No (L) then
181 Set_First (To, Node);
182 else
183 Set_Next (L, Node);
184 end if;
186 Set_Last (To, Node);
188 Nodes.Table (Node).In_List := True;
190 Set_Next (Node, Empty);
191 Set_Prev (Node, L);
192 Set_List_Link (Node, To);
193 end Append;
195 -----------------
196 -- Append_List --
197 -----------------
199 procedure Append_List (List : List_Id; To : List_Id) is
201 procedure Append_List_Debug;
202 pragma Inline (Append_List_Debug);
203 -- Output debug information if Debug_Flag_N set
205 procedure Append_List_Debug is
206 begin
207 if Debug_Flag_N then
208 Write_Str ("Append list ");
209 Write_Int (Int (List));
210 Write_Str (" to list ");
211 Write_Int (Int (To));
212 Write_Eol;
213 end if;
214 end Append_List_Debug;
216 -- Start of processing for Append_List
218 begin
219 if Is_Empty_List (List) then
220 return;
222 else
223 declare
224 L : constant Node_Id := Last (To);
225 F : constant Node_Id := First (List);
226 N : Node_Id;
228 begin
229 pragma Debug (Append_List_Debug);
231 N := F;
232 loop
233 Set_List_Link (N, To);
234 N := Next (N);
235 exit when No (N);
236 end loop;
238 if No (L) then
239 Set_First (To, F);
240 else
241 Set_Next (L, F);
242 end if;
244 Set_Prev (F, L);
245 Set_Last (To, Last (List));
247 Set_First (List, Empty);
248 Set_Last (List, Empty);
249 end;
250 end if;
251 end Append_List;
253 --------------------
254 -- Append_List_To --
255 --------------------
257 procedure Append_List_To (To : List_Id; List : List_Id) is
258 begin
259 Append_List (List, To);
260 end Append_List_To;
262 ---------------
263 -- Append_To --
264 ---------------
266 procedure Append_To (To : List_Id; Node : Node_Id) is
267 begin
268 Append (Node, To);
269 end Append_To;
271 -----------------
272 -- Delete_List --
273 -----------------
275 procedure Delete_List (L : List_Id) is
276 N : Node_Id;
278 begin
279 while Is_Non_Empty_List (L) loop
280 N := Remove_Head (L);
281 Delete_Tree (N);
282 end loop;
284 -- Should recycle list header???
285 end Delete_List;
287 -----------
288 -- First --
289 -----------
291 -- This subprogram is deliberately placed early on, out of alphabetical
292 -- order, so that it can be properly inlined from within this unit.
294 function First (List : List_Id) return Node_Id is
295 begin
296 if List = No_List then
297 return Empty;
298 else
299 pragma Assert (List in First_List_Id .. Lists.Last);
300 return Lists.Table (List).First;
301 end if;
302 end First;
304 ----------------------
305 -- First_Non_Pragma --
306 ----------------------
308 function First_Non_Pragma (List : List_Id) return Node_Id is
309 N : constant Node_Id := First (List);
311 begin
312 if Nkind (N) /= N_Pragma
313 and then
314 Nkind (N) /= N_Null_Statement
315 then
316 return N;
317 else
318 return Next_Non_Pragma (N);
319 end if;
320 end First_Non_Pragma;
322 ----------------
323 -- Initialize --
324 ----------------
326 procedure Initialize is
327 E : constant List_Id := Error_List;
329 begin
330 Lists.Init;
331 Next_Node.Init;
332 Prev_Node.Init;
334 -- Allocate Error_List list header
336 Lists.Increment_Last;
337 Set_Parent (E, Empty);
338 Set_First (E, Empty);
339 Set_Last (E, Empty);
340 end Initialize;
342 ------------------
343 -- Insert_After --
344 ------------------
346 procedure Insert_After (After : Node_Id; Node : Node_Id) is
348 procedure Insert_After_Debug;
349 pragma Inline (Insert_After_Debug);
350 -- Output debug information if Debug_Flag_N set
352 procedure Insert_After_Debug is
353 begin
354 if Debug_Flag_N then
355 Write_Str ("Insert node");
356 Write_Int (Int (Node));
357 Write_Str (" after node ");
358 Write_Int (Int (After));
359 Write_Eol;
360 end if;
361 end Insert_After_Debug;
363 -- Start of processing for Insert_After
365 begin
366 pragma Assert
367 (Is_List_Member (After) and then not Is_List_Member (Node));
369 if Node = Error then
370 return;
371 end if;
373 pragma Debug (Insert_After_Debug);
375 declare
376 Before : constant Node_Id := Next (After);
377 LC : constant List_Id := List_Containing (After);
379 begin
380 if Present (Before) then
381 Set_Prev (Before, Node);
382 else
383 Set_Last (LC, Node);
384 end if;
386 Set_Next (After, Node);
388 Nodes.Table (Node).In_List := True;
390 Set_Prev (Node, After);
391 Set_Next (Node, Before);
392 Set_List_Link (Node, LC);
393 end;
394 end Insert_After;
396 -------------------
397 -- Insert_Before --
398 -------------------
400 procedure Insert_Before (Before : Node_Id; Node : Node_Id) is
402 procedure Insert_Before_Debug;
403 pragma Inline (Insert_Before_Debug);
404 -- Output debug information if Debug_Flag_N set
406 procedure Insert_Before_Debug is
407 begin
408 if Debug_Flag_N then
409 Write_Str ("Insert node");
410 Write_Int (Int (Node));
411 Write_Str (" before node ");
412 Write_Int (Int (Before));
413 Write_Eol;
414 end if;
415 end Insert_Before_Debug;
417 -- Start of processing for Insert_Before
419 begin
420 pragma Assert
421 (Is_List_Member (Before) and then not Is_List_Member (Node));
423 if Node = Error then
424 return;
425 end if;
427 pragma Debug (Insert_Before_Debug);
429 declare
430 After : constant Node_Id := Prev (Before);
431 LC : constant List_Id := List_Containing (Before);
433 begin
434 if Present (After) then
435 Set_Next (After, Node);
436 else
437 Set_First (LC, Node);
438 end if;
440 Set_Prev (Before, Node);
442 Nodes.Table (Node).In_List := True;
444 Set_Prev (Node, After);
445 Set_Next (Node, Before);
446 Set_List_Link (Node, LC);
447 end;
448 end Insert_Before;
450 -----------------------
451 -- Insert_List_After --
452 -----------------------
454 procedure Insert_List_After (After : Node_Id; List : List_Id) is
456 procedure Insert_List_After_Debug;
457 pragma Inline (Insert_List_After_Debug);
458 -- Output debug information if Debug_Flag_N set
460 procedure Insert_List_After_Debug is
461 begin
462 if Debug_Flag_N then
463 Write_Str ("Insert list ");
464 Write_Int (Int (List));
465 Write_Str (" after node ");
466 Write_Int (Int (After));
467 Write_Eol;
468 end if;
469 end Insert_List_After_Debug;
471 -- Start of processing for Insert_List_After
473 begin
474 pragma Assert (Is_List_Member (After));
476 if Is_Empty_List (List) then
477 return;
479 else
480 declare
481 Before : constant Node_Id := Next (After);
482 LC : constant List_Id := List_Containing (After);
483 F : constant Node_Id := First (List);
484 L : constant Node_Id := Last (List);
485 N : Node_Id;
487 begin
488 pragma Debug (Insert_List_After_Debug);
490 N := F;
491 loop
492 Set_List_Link (N, LC);
493 exit when N = L;
494 N := Next (N);
495 end loop;
497 if Present (Before) then
498 Set_Prev (Before, L);
499 else
500 Set_Last (LC, L);
501 end if;
503 Set_Next (After, F);
504 Set_Prev (F, After);
505 Set_Next (L, Before);
507 Set_First (List, Empty);
508 Set_Last (List, Empty);
509 end;
510 end if;
511 end Insert_List_After;
513 ------------------------
514 -- Insert_List_Before --
515 ------------------------
517 procedure Insert_List_Before (Before : Node_Id; List : List_Id) is
519 procedure Insert_List_Before_Debug;
520 pragma Inline (Insert_List_Before_Debug);
521 -- Output debug information if Debug_Flag_N set
523 procedure Insert_List_Before_Debug is
524 begin
525 if Debug_Flag_N then
526 Write_Str ("Insert list ");
527 Write_Int (Int (List));
528 Write_Str (" before node ");
529 Write_Int (Int (Before));
530 Write_Eol;
531 end if;
532 end Insert_List_Before_Debug;
534 -- Start of prodcessing for Insert_List_Before
536 begin
537 pragma Assert (Is_List_Member (Before));
539 if Is_Empty_List (List) then
540 return;
542 else
543 declare
544 After : constant Node_Id := Prev (Before);
545 LC : constant List_Id := List_Containing (Before);
546 F : constant Node_Id := First (List);
547 L : constant Node_Id := Last (List);
548 N : Node_Id;
550 begin
551 pragma Debug (Insert_List_Before_Debug);
553 N := F;
554 loop
555 Set_List_Link (N, LC);
556 exit when N = L;
557 N := Next (N);
558 end loop;
560 if Present (After) then
561 Set_Next (After, F);
562 else
563 Set_First (LC, F);
564 end if;
566 Set_Prev (Before, L);
567 Set_Prev (F, After);
568 Set_Next (L, Before);
570 Set_First (List, Empty);
571 Set_Last (List, Empty);
572 end;
573 end if;
574 end Insert_List_Before;
576 -------------------
577 -- Is_Empty_List --
578 -------------------
580 function Is_Empty_List (List : List_Id) return Boolean is
581 begin
582 return First (List) = Empty;
583 end Is_Empty_List;
585 --------------------
586 -- Is_List_Member --
587 --------------------
589 function Is_List_Member (Node : Node_Id) return Boolean is
590 begin
591 return Nodes.Table (Node).In_List;
592 end Is_List_Member;
594 -----------------------
595 -- Is_Non_Empty_List --
596 -----------------------
598 function Is_Non_Empty_List (List : List_Id) return Boolean is
599 begin
600 return List /= No_List and then First (List) /= Empty;
601 end Is_Non_Empty_List;
603 ----------
604 -- Last --
605 ----------
607 -- This subprogram is deliberately placed early on, out of alphabetical
608 -- order, so that it can be properly inlined from within this unit.
610 function Last (List : List_Id) return Node_Id is
611 begin
612 pragma Assert (List in First_List_Id .. Lists.Last);
613 return Lists.Table (List).Last;
614 end Last;
616 ------------------
617 -- Last_List_Id --
618 ------------------
620 function Last_List_Id return List_Id is
621 begin
622 return Lists.Last;
623 end Last_List_Id;
625 ---------------------
626 -- Last_Non_Pragma --
627 ---------------------
629 function Last_Non_Pragma (List : List_Id) return Node_Id is
630 N : constant Node_Id := Last (List);
632 begin
633 if Nkind (N) /= N_Pragma then
634 return N;
635 else
636 return Prev_Non_Pragma (N);
637 end if;
638 end Last_Non_Pragma;
640 ---------------------
641 -- List_Containing --
642 ---------------------
644 function List_Containing (Node : Node_Id) return List_Id is
645 begin
646 pragma Assert (Is_List_Member (Node));
647 return List_Id (Nodes.Table (Node).Link);
648 end List_Containing;
650 -----------------
651 -- List_Length --
652 -----------------
654 function List_Length (List : List_Id) return Nat is
655 Result : Nat;
656 Node : Node_Id;
658 begin
659 Result := 0;
660 Node := First (List);
661 while Present (Node) loop
662 Result := Result + 1;
663 Node := Next (Node);
664 end loop;
666 return Result;
667 end List_Length;
669 -------------------
670 -- Lists_Address --
671 -------------------
673 function Lists_Address return System.Address is
674 begin
675 return Lists.Table (First_List_Id)'Address;
676 end Lists_Address;
678 ----------
679 -- Lock --
680 ----------
682 procedure Lock is
683 begin
684 Lists.Locked := True;
685 Lists.Release;
687 Prev_Node.Locked := True;
688 Next_Node.Locked := True;
690 Prev_Node.Release;
691 Next_Node.Release;
692 end Lock;
694 -------------------
695 -- New_Copy_List --
696 -------------------
698 function New_Copy_List (List : List_Id) return List_Id is
699 NL : List_Id;
700 E : Node_Id;
702 begin
703 if List = No_List then
704 return No_List;
706 else
707 NL := New_List;
708 E := First (List);
710 while Present (E) loop
711 Append (New_Copy (E), NL);
712 E := Next (E);
713 end loop;
715 return NL;
716 end if;
717 end New_Copy_List;
719 ----------------------------
720 -- New_Copy_List_Original --
721 ----------------------------
723 function New_Copy_List_Original (List : List_Id) return List_Id is
724 NL : List_Id;
725 E : Node_Id;
727 begin
728 if List = No_List then
729 return No_List;
731 else
732 NL := New_List;
733 E := First (List);
735 while Present (E) loop
736 if Comes_From_Source (E) then
737 Append (New_Copy (E), NL);
738 end if;
740 E := Next (E);
741 end loop;
743 return NL;
744 end if;
745 end New_Copy_List_Original;
747 ------------------------
748 -- New_Copy_List_Tree --
749 ------------------------
751 function New_Copy_List_Tree (List : List_Id) return List_Id is
752 NL : List_Id;
753 E : Node_Id;
755 begin
756 if List = No_List then
757 return No_List;
759 else
760 NL := New_List;
761 E := First (List);
763 while Present (E) loop
764 Append (New_Copy_Tree (E), NL);
765 E := Next (E);
766 end loop;
768 return NL;
769 end if;
770 end New_Copy_List_Tree;
772 --------------
773 -- New_List --
774 --------------
776 function New_List return List_Id is
778 procedure New_List_Debug;
779 pragma Inline (New_List_Debug);
780 -- Output debugging information if Debug_Flag_N is set
782 procedure New_List_Debug is
783 begin
784 if Debug_Flag_N then
785 Write_Str ("Allocate new list, returned ID = ");
786 Write_Int (Int (Lists.Last));
787 Write_Eol;
788 end if;
789 end New_List_Debug;
791 -- Start of processing for New_List
793 begin
794 Lists.Increment_Last;
796 declare
797 List : constant List_Id := Lists.Last;
799 begin
800 Set_Parent (List, Empty);
801 Set_First (List, Empty);
802 Set_Last (List, Empty);
804 pragma Debug (New_List_Debug);
805 return (List);
806 end;
807 end New_List;
809 -- Since the one argument case is common, we optimize to build the right
810 -- list directly, rather than first building an empty list and then doing
811 -- the insertion, which results in some unnecessary work.
813 function New_List (Node : Node_Id) return List_Id is
815 procedure New_List_Debug;
816 pragma Inline (New_List_Debug);
817 -- Output debugging information if Debug_Flag_N is set
819 procedure New_List_Debug is
820 begin
821 if Debug_Flag_N then
822 Write_Str ("Allocate new list, returned ID = ");
823 Write_Int (Int (Lists.Last));
824 Write_Eol;
825 end if;
826 end New_List_Debug;
828 -- Start of processing for New_List
830 begin
831 if Node = Error then
832 return New_List;
834 else
835 pragma Assert (not Is_List_Member (Node));
837 Lists.Increment_Last;
839 declare
840 List : constant List_Id := Lists.Last;
842 begin
843 Set_Parent (List, Empty);
844 Set_First (List, Node);
845 Set_Last (List, Node);
847 Nodes.Table (Node).In_List := True;
848 Set_List_Link (Node, List);
849 Set_Prev (Node, Empty);
850 Set_Next (Node, Empty);
851 pragma Debug (New_List_Debug);
852 return List;
853 end;
854 end if;
855 end New_List;
857 function New_List (Node1, Node2 : Node_Id) return List_Id is
858 L : constant List_Id := New_List (Node1);
860 begin
861 Append (Node2, L);
862 return L;
863 end New_List;
865 function New_List (Node1, Node2, Node3 : Node_Id) return List_Id is
866 L : constant List_Id := New_List (Node1);
868 begin
869 Append (Node2, L);
870 Append (Node3, L);
871 return L;
872 end New_List;
874 function New_List (Node1, Node2, Node3, Node4 : Node_Id) return List_Id is
875 L : constant List_Id := New_List (Node1);
877 begin
878 Append (Node2, L);
879 Append (Node3, L);
880 Append (Node4, L);
881 return L;
882 end New_List;
884 function New_List
885 (Node1 : Node_Id;
886 Node2 : Node_Id;
887 Node3 : Node_Id;
888 Node4 : Node_Id;
889 Node5 : Node_Id)
890 return List_Id
892 L : constant List_Id := New_List (Node1);
894 begin
895 Append (Node2, L);
896 Append (Node3, L);
897 Append (Node4, L);
898 Append (Node5, L);
899 return L;
900 end New_List;
902 function New_List
903 (Node1 : Node_Id;
904 Node2 : Node_Id;
905 Node3 : Node_Id;
906 Node4 : Node_Id;
907 Node5 : Node_Id;
908 Node6 : Node_Id)
909 return List_Id
911 L : constant List_Id := New_List (Node1);
913 begin
914 Append (Node2, L);
915 Append (Node3, L);
916 Append (Node4, L);
917 Append (Node5, L);
918 Append (Node6, L);
919 return L;
920 end New_List;
922 ----------
923 -- Next --
924 ----------
926 -- This subprogram is deliberately placed early on, out of alphabetical
927 -- order, so that it can be properly inlined from within this unit.
929 function Next (Node : Node_Id) return Node_Id is
930 begin
931 pragma Assert (Is_List_Member (Node));
932 return Next_Node.Table (Node);
933 end Next;
935 procedure Next (Node : in out Node_Id) is
936 begin
937 Node := Next (Node);
938 end Next;
940 -----------------------
941 -- Next_Node_Address --
942 -----------------------
944 function Next_Node_Address return System.Address is
945 begin
946 return Next_Node.Table (First_Node_Id)'Address;
947 end Next_Node_Address;
949 ---------------------
950 -- Next_Non_Pragma --
951 ---------------------
953 function Next_Non_Pragma (Node : Node_Id) return Node_Id is
954 N : Node_Id;
956 begin
957 N := Node;
958 loop
959 N := Next (N);
960 exit when Nkind (N) /= N_Pragma
961 and then
962 Nkind (N) /= N_Null_Statement;
963 end loop;
965 return N;
966 end Next_Non_Pragma;
968 procedure Next_Non_Pragma (Node : in out Node_Id) is
969 begin
970 Node := Next_Non_Pragma (Node);
971 end Next_Non_Pragma;
973 --------
974 -- No --
975 --------
977 -- This subprogram is deliberately placed early on, out of alphabetical
978 -- order, so that it can be properly inlined from within this unit.
980 function No (List : List_Id) return Boolean is
981 begin
982 return List = No_List;
983 end No;
985 ---------------
986 -- Num_Lists --
987 ---------------
989 function Num_Lists return Nat is
990 begin
991 return Int (Lists.Last) - Int (Lists.First) + 1;
992 end Num_Lists;
994 -------
995 -- p --
996 -------
998 function p (U : Union_Id) return Node_Id is
999 begin
1000 if U in Node_Range then
1001 return Parent (Node_Id (U));
1003 elsif U in List_Range then
1004 return Parent (List_Id (U));
1006 else
1007 return 99_999_999;
1008 end if;
1009 end p;
1011 ------------
1012 -- Parent --
1013 ------------
1015 function Parent (List : List_Id) return Node_Id is
1016 begin
1017 pragma Assert (List in First_List_Id .. Lists.Last);
1018 return Lists.Table (List).Parent;
1019 end Parent;
1021 ----------
1022 -- Pick --
1023 ----------
1025 function Pick (List : List_Id; Index : Pos) return Node_Id is
1026 Elmt : Node_Id;
1028 begin
1029 Elmt := First (List);
1030 for J in 1 .. Index - 1 loop
1031 Elmt := Next (Elmt);
1032 end loop;
1034 return Elmt;
1035 end Pick;
1037 -------------
1038 -- Prepend --
1039 -------------
1041 procedure Prepend (Node : Node_Id; To : List_Id) is
1042 F : constant Node_Id := First (To);
1044 begin
1045 pragma Assert (not Is_List_Member (Node));
1047 if Node = Error then
1048 return;
1049 end if;
1051 pragma Debug (Prepend_Debug (Node, To));
1053 if No (F) then
1054 Set_Last (To, Node);
1055 else
1056 Set_Prev (F, Node);
1057 end if;
1059 Set_First (To, Node);
1061 Nodes.Table (Node).In_List := True;
1063 Set_Next (Node, F);
1064 Set_Prev (Node, Empty);
1065 Set_List_Link (Node, To);
1066 end Prepend;
1068 -------------------
1069 -- Prepend_Debug --
1070 -------------------
1072 procedure Prepend_Debug (Node : Node_Id; To : List_Id) is
1073 begin
1074 if Debug_Flag_N then
1075 Write_Str ("Prepend node ");
1076 Write_Int (Int (Node));
1077 Write_Str (" to list ");
1078 Write_Int (Int (To));
1079 Write_Eol;
1080 end if;
1081 end Prepend_Debug;
1083 ----------------
1084 -- Prepend_To --
1085 ----------------
1087 procedure Prepend_To (To : List_Id; Node : Node_Id) is
1088 begin
1089 Prepend (Node, To);
1090 end Prepend_To;
1092 -------------
1093 -- Present --
1094 -------------
1096 function Present (List : List_Id) return Boolean is
1097 begin
1098 return List /= No_List;
1099 end Present;
1101 ----------
1102 -- Prev --
1103 ----------
1105 -- This subprogram is deliberately placed early on, out of alphabetical
1106 -- order, so that it can be properly inlined from within this unit.
1108 function Prev (Node : Node_Id) return Node_Id is
1109 begin
1110 pragma Assert (Is_List_Member (Node));
1111 return Prev_Node.Table (Node);
1112 end Prev;
1114 procedure Prev (Node : in out Node_Id) is
1115 begin
1116 Node := Prev (Node);
1117 end Prev;
1119 -----------------------
1120 -- Prev_Node_Address --
1121 -----------------------
1123 function Prev_Node_Address return System.Address is
1124 begin
1125 return Prev_Node.Table (First_Node_Id)'Address;
1126 end Prev_Node_Address;
1128 ---------------------
1129 -- Prev_Non_Pragma --
1130 ---------------------
1132 function Prev_Non_Pragma (Node : Node_Id) return Node_Id is
1133 N : Node_Id;
1135 begin
1136 N := Node;
1137 loop
1138 N := Prev (N);
1139 exit when Nkind (N) /= N_Pragma;
1140 end loop;
1142 return N;
1143 end Prev_Non_Pragma;
1145 procedure Prev_Non_Pragma (Node : in out Node_Id) is
1146 begin
1147 Node := Prev_Non_Pragma (Node);
1148 end Prev_Non_Pragma;
1150 ------------
1151 -- Remove --
1152 ------------
1154 procedure Remove (Node : Node_Id) is
1155 Lst : constant List_Id := List_Containing (Node);
1156 Prv : constant Node_Id := Prev (Node);
1157 Nxt : constant Node_Id := Next (Node);
1159 procedure Remove_Debug;
1160 pragma Inline (Remove_Debug);
1161 -- Output debug information if Debug_Flag_N set
1163 procedure Remove_Debug is
1164 begin
1165 if Debug_Flag_N then
1166 Write_Str ("Remove node ");
1167 Write_Int (Int (Node));
1168 Write_Eol;
1169 end if;
1170 end Remove_Debug;
1172 -- Start of processing for Remove
1174 begin
1175 pragma Debug (Remove_Debug);
1177 if No (Prv) then
1178 Set_First (Lst, Nxt);
1179 else
1180 Set_Next (Prv, Nxt);
1181 end if;
1183 if No (Nxt) then
1184 Set_Last (Lst, Prv);
1185 else
1186 Set_Prev (Nxt, Prv);
1187 end if;
1189 Nodes.Table (Node).In_List := False;
1190 Set_Parent (Node, Empty);
1191 end Remove;
1193 -----------------
1194 -- Remove_Head --
1195 -----------------
1197 function Remove_Head (List : List_Id) return Node_Id is
1198 Frst : constant Node_Id := First (List);
1200 procedure Remove_Head_Debug;
1201 pragma Inline (Remove_Head_Debug);
1202 -- Output debug information if Debug_Flag_N set
1204 procedure Remove_Head_Debug is
1205 begin
1206 if Debug_Flag_N then
1207 Write_Str ("Remove head of list ");
1208 Write_Int (Int (List));
1209 Write_Eol;
1210 end if;
1211 end Remove_Head_Debug;
1213 -- Start of processing for Remove_Head
1215 begin
1216 pragma Debug (Remove_Head_Debug);
1218 if Frst = Empty then
1219 return Empty;
1221 else
1222 declare
1223 Nxt : constant Node_Id := Next (Frst);
1225 begin
1226 Set_First (List, Nxt);
1228 if No (Nxt) then
1229 Set_Last (List, Empty);
1230 else
1231 Set_Prev (Nxt, Empty);
1232 end if;
1234 Nodes.Table (Frst).In_List := False;
1235 Set_Parent (Frst, Empty);
1236 return Frst;
1237 end;
1238 end if;
1239 end Remove_Head;
1241 -----------------
1242 -- Remove_Next --
1243 -----------------
1245 function Remove_Next (Node : Node_Id) return Node_Id is
1246 Nxt : constant Node_Id := Next (Node);
1248 begin
1249 if Present (Nxt) then
1250 declare
1251 Nxt2 : constant Node_Id := Next (Nxt);
1252 LC : constant List_Id := List_Containing (Node);
1254 begin
1255 pragma Debug (Remove_Next_Debug (Node));
1256 Set_Next (Node, Nxt2);
1258 if No (Nxt2) then
1259 Set_Last (LC, Node);
1260 else
1261 Set_Prev (Nxt2, Node);
1262 end if;
1264 Nodes.Table (Nxt).In_List := False;
1265 Set_Parent (Nxt, Empty);
1266 end;
1267 end if;
1269 return Nxt;
1270 end Remove_Next;
1272 -----------------------
1273 -- Remove_Next_Debug --
1274 -----------------------
1276 procedure Remove_Next_Debug (Node : Node_Id) is
1277 begin
1278 if Debug_Flag_N then
1279 Write_Str ("Remove next node after ");
1280 Write_Int (Int (Node));
1281 Write_Eol;
1282 end if;
1283 end Remove_Next_Debug;
1285 ---------------
1286 -- Set_First --
1287 ---------------
1289 -- This subprogram is deliberately placed early on, out of alphabetical
1290 -- order, so that it can be properly inlined from within this unit.
1292 procedure Set_First (List : List_Id; To : Node_Id) is
1293 begin
1294 Lists.Table (List).First := To;
1295 end Set_First;
1297 --------------
1298 -- Set_Last --
1299 --------------
1301 -- This subprogram is deliberately placed early on, out of alphabetical
1302 -- order, so that it can be properly inlined from within this unit.
1304 procedure Set_Last (List : List_Id; To : Node_Id) is
1305 begin
1306 Lists.Table (List).Last := To;
1307 end Set_Last;
1309 -------------------
1310 -- Set_List_Link --
1311 -------------------
1313 -- This subprogram is deliberately placed early on, out of alphabetical
1314 -- order, so that it can be properly inlined from within this unit.
1316 procedure Set_List_Link (Node : Node_Id; To : List_Id) is
1317 begin
1318 Nodes.Table (Node).Link := Union_Id (To);
1319 end Set_List_Link;
1321 --------------
1322 -- Set_Next --
1323 --------------
1325 -- This subprogram is deliberately placed early on, out of alphabetical
1326 -- order, so that it can be properly inlined from within this unit.
1328 procedure Set_Next (Node : Node_Id; To : Node_Id) is
1329 begin
1330 Next_Node.Table (Node) := To;
1331 end Set_Next;
1333 ----------------
1334 -- Set_Parent --
1335 ----------------
1337 procedure Set_Parent (List : List_Id; Node : Node_Id) is
1338 begin
1339 pragma Assert (List in First_List_Id .. Lists.Last);
1340 Lists.Table (List).Parent := Node;
1341 end Set_Parent;
1343 --------------
1344 -- Set_Prev --
1345 --------------
1347 -- This subprogram is deliberately placed early on, out of alphabetical
1348 -- order, so that it can be properly inlined from within this unit.
1350 procedure Set_Prev (Node : Node_Id; To : Node_Id) is
1351 begin
1352 Prev_Node.Table (Node) := To;
1353 end Set_Prev;
1355 ---------------
1356 -- Tree_Read --
1357 ---------------
1359 procedure Tree_Read is
1360 begin
1361 Lists.Tree_Read;
1362 Next_Node.Tree_Read;
1363 Prev_Node.Tree_Read;
1364 end Tree_Read;
1366 ----------------
1367 -- Tree_Write --
1368 ----------------
1370 procedure Tree_Write is
1371 begin
1372 Lists.Tree_Write;
1373 Next_Node.Tree_Write;
1374 Prev_Node.Tree_Write;
1375 end Tree_Write;
1377 end Nlists;