OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [nlists.adb] - Blame information for rev 750

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                               N L I S T S                                --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2010, 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 3,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
17
--                                                                          --
18
-- As a special exception under Section 7 of GPL version 3, you are granted --
19
-- additional permissions described in the GCC Runtime Library Exception,   --
20
-- version 3.1, as published by the Free Software Foundation.               --
21
--                                                                          --
22
-- You should have received a copy of the GNU General Public License and    --
23
-- a copy of the GCC Runtime Library Exception along with this program;     --
24
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25
-- <http://www.gnu.org/licenses/>.                                          --
26
--                                                                          --
27
-- GNAT was originally developed  by the GNAT team at  New York University. --
28
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29
--                                                                          --
30
------------------------------------------------------------------------------
31
 
32
--  WARNING: There is a C version of this package. Any changes to this source
33
--  file must be properly reflected in the corresponding C header a-nlists.h
34
 
35
with Alloc;
36
with Atree;  use Atree;
37
with Debug;  use Debug;
38
with Output; use Output;
39
with Sinfo;  use Sinfo;
40
with Table;
41
 
42
package body Nlists is
43
 
44
   use Atree_Private_Part;
45
   --  Get access to Nodes table
46
 
47
   ----------------------------------
48
   -- Implementation of Node Lists --
49
   ----------------------------------
50
 
51
   --  A node list is represented by a list header which contains
52
   --  three fields:
53
 
54
   type List_Header is record
55
      First : Node_Or_Entity_Id;
56
      --  Pointer to first node in list. Empty if list is empty
57
 
58
      Last : Node_Or_Entity_Id;
59
      --  Pointer to last node in list. Empty if list is empty
60
 
61
      Parent : Node_Id;
62
      --  Pointer to parent of list. Empty if list has no parent
63
   end record;
64
 
65
   --  The node lists are stored in a table indexed by List_Id values
66
 
67
   package Lists is new Table.Table (
68
     Table_Component_Type => List_Header,
69
     Table_Index_Type     => List_Id'Base,
70
     Table_Low_Bound      => First_List_Id,
71
     Table_Initial        => Alloc.Lists_Initial,
72
     Table_Increment      => Alloc.Lists_Increment,
73
     Table_Name           => "Lists");
74
 
75
   --  The nodes in the list all have the In_List flag set, and their Link
76
   --  fields (which otherwise point to the parent) contain the List_Id of
77
   --  the list header giving immediate access to the list containing the
78
   --  node, and its parent and first and last elements.
79
 
80
   --  Two auxiliary tables, indexed by Node_Id values and built in parallel
81
   --  with the main nodes table and always having the same size contain the
82
   --  list link values that allow locating the previous and next node in a
83
   --  list. The entries in these tables are valid only if the In_List flag
84
   --  is set in the corresponding node. Next_Node is Empty at the end of a
85
   --  list and Prev_Node is Empty at the start of a list.
86
 
87
   package Next_Node is new Table.Table (
88
      Table_Component_Type => Node_Or_Entity_Id,
89
      Table_Index_Type     => Node_Or_Entity_Id'Base,
90
      Table_Low_Bound      => First_Node_Id,
91
      Table_Initial        => Alloc.Orig_Nodes_Initial,
92
      Table_Increment      => Alloc.Orig_Nodes_Increment,
93
      Table_Name           => "Next_Node");
94
 
95
   package Prev_Node is new Table.Table (
96
      Table_Component_Type => Node_Or_Entity_Id,
97
      Table_Index_Type     => Node_Or_Entity_Id'Base,
98
      Table_Low_Bound      => First_Node_Id,
99
      Table_Initial        => Alloc.Orig_Nodes_Initial,
100
      Table_Increment      => Alloc.Orig_Nodes_Increment,
101
      Table_Name           => "Prev_Node");
102
 
103
   -----------------------
104
   -- Local Subprograms --
105
   -----------------------
106
 
107
   procedure Set_First (List : List_Id; To : Node_Or_Entity_Id);
108
   pragma Inline (Set_First);
109
   --  Sets First field of list header List to reference To
110
 
111
   procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id);
112
   pragma Inline (Set_Last);
113
   --  Sets Last field of list header List to reference To
114
 
115
   procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id);
116
   pragma Inline (Set_List_Link);
117
   --  Sets list link of Node to list header To
118
 
119
   procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id);
120
   pragma Inline (Set_Next);
121
   --  Sets the Next_Node pointer for Node to reference To
122
 
123
   procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id);
124
   pragma Inline (Set_Prev);
125
   --  Sets the Prev_Node pointer for Node to reference To
126
 
127
   --------------------------
128
   -- Allocate_List_Tables --
129
   --------------------------
130
 
131
   procedure Allocate_List_Tables (N : Node_Or_Entity_Id) is
132
      Old_Last : constant Node_Or_Entity_Id'Base := Next_Node.Last;
133
 
134
   begin
135
      pragma Assert (N >= Old_Last);
136
      Next_Node.Set_Last (N);
137
      Prev_Node.Set_Last (N);
138
 
139
      --  Make sure we have no uninitialized junk in any new entires added.
140
      --  This ensures that Tree_Gen will not write out any uninitialized junk.
141
 
142
      for J in Old_Last + 1 .. N loop
143
         Next_Node.Table (J) := Empty;
144
         Prev_Node.Table (J) := Empty;
145
      end loop;
146
   end Allocate_List_Tables;
147
 
148
   ------------
149
   -- Append --
150
   ------------
151
 
152
   procedure Append (Node : Node_Or_Entity_Id; To : List_Id) is
153
      L : constant Node_Or_Entity_Id := Last (To);
154
 
155
      procedure Append_Debug;
156
      pragma Inline (Append_Debug);
157
      --  Output debug information if Debug_Flag_N set
158
 
159
      ------------------
160
      -- Append_Debug --
161
      ------------------
162
 
163
      procedure Append_Debug is
164
      begin
165
         if Debug_Flag_N then
166
            Write_Str ("Append node ");
167
            Write_Int (Int (Node));
168
            Write_Str (" to list ");
169
            Write_Int (Int (To));
170
            Write_Eol;
171
         end if;
172
      end Append_Debug;
173
 
174
   --  Start of processing for Append
175
 
176
   begin
177
      pragma Assert (not Is_List_Member (Node));
178
 
179
      if Node = Error then
180
         return;
181
      end if;
182
 
183
      pragma Debug (Append_Debug);
184
 
185
      if No (L) then
186
         Set_First (To, Node);
187
      else
188
         Set_Next (L, Node);
189
      end if;
190
 
191
      Set_Last (To, Node);
192
 
193
      Nodes.Table (Node).In_List := True;
194
 
195
      Set_Next      (Node, Empty);
196
      Set_Prev      (Node, L);
197
      Set_List_Link (Node, To);
198
   end Append;
199
 
200
   -----------------
201
   -- Append_List --
202
   -----------------
203
 
204
   procedure Append_List (List : List_Id; To : List_Id) is
205
 
206
      procedure Append_List_Debug;
207
      pragma Inline (Append_List_Debug);
208
      --  Output debug information if Debug_Flag_N set
209
 
210
      -----------------------
211
      -- Append_List_Debug --
212
      -----------------------
213
 
214
      procedure Append_List_Debug is
215
      begin
216
         if Debug_Flag_N then
217
            Write_Str ("Append list ");
218
            Write_Int (Int (List));
219
            Write_Str (" to list ");
220
            Write_Int (Int (To));
221
            Write_Eol;
222
         end if;
223
      end Append_List_Debug;
224
 
225
   --  Start of processing for Append_List
226
 
227
   begin
228
      if Is_Empty_List (List) then
229
         return;
230
 
231
      else
232
         declare
233
            L : constant Node_Or_Entity_Id := Last (To);
234
            F : constant Node_Or_Entity_Id := First (List);
235
            N : Node_Or_Entity_Id;
236
 
237
         begin
238
            pragma Debug (Append_List_Debug);
239
 
240
            N := F;
241
            loop
242
               Set_List_Link (N, To);
243
               N := Next (N);
244
               exit when No (N);
245
            end loop;
246
 
247
            if No (L) then
248
               Set_First (To, F);
249
            else
250
               Set_Next (L, F);
251
            end if;
252
 
253
            Set_Prev (F, L);
254
            Set_Last (To, Last (List));
255
 
256
            Set_First (List, Empty);
257
            Set_Last  (List, Empty);
258
         end;
259
      end if;
260
   end Append_List;
261
 
262
   --------------------
263
   -- Append_List_To --
264
   --------------------
265
 
266
   procedure Append_List_To (To : List_Id; List : List_Id) is
267
   begin
268
      Append_List (List, To);
269
   end Append_List_To;
270
 
271
   ---------------
272
   -- Append_To --
273
   ---------------
274
 
275
   procedure Append_To (To : List_Id; Node : Node_Or_Entity_Id) is
276
   begin
277
      Append (Node, To);
278
   end Append_To;
279
 
280
   -----------
281
   -- First --
282
   -----------
283
 
284
   function First (List : List_Id) return Node_Or_Entity_Id is
285
   begin
286
      if List = No_List then
287
         return Empty;
288
      else
289
         pragma Assert (List <= Lists.Last);
290
         return Lists.Table (List).First;
291
      end if;
292
   end First;
293
 
294
   ----------------------
295
   -- First_Non_Pragma --
296
   ----------------------
297
 
298
   function First_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is
299
      N : constant Node_Or_Entity_Id := First (List);
300
   begin
301
      if Nkind (N) /= N_Pragma
302
           and then
303
         Nkind (N) /= N_Null_Statement
304
      then
305
         return N;
306
      else
307
         return Next_Non_Pragma (N);
308
      end if;
309
   end First_Non_Pragma;
310
 
311
   ----------------
312
   -- Initialize --
313
   ----------------
314
 
315
   procedure Initialize is
316
      E : constant List_Id := Error_List;
317
 
318
   begin
319
      Lists.Init;
320
      Next_Node.Init;
321
      Prev_Node.Init;
322
 
323
      --  Allocate Error_List list header
324
 
325
      Lists.Increment_Last;
326
      Set_Parent (E, Empty);
327
      Set_First  (E, Empty);
328
      Set_Last   (E, Empty);
329
   end Initialize;
330
 
331
   ------------------
332
   -- In_Same_List --
333
   ------------------
334
 
335
   function In_Same_List (N1, N2 : Node_Or_Entity_Id) return Boolean is
336
   begin
337
      return List_Containing (N1) = List_Containing (N2);
338
   end In_Same_List;
339
 
340
   ------------------
341
   -- Insert_After --
342
   ------------------
343
 
344
   procedure Insert_After
345
     (After : Node_Or_Entity_Id;
346
      Node  : Node_Or_Entity_Id)
347
   is
348
      procedure Insert_After_Debug;
349
      pragma Inline (Insert_After_Debug);
350
      --  Output debug information if Debug_Flag_N set
351
 
352
      ------------------------
353
      -- Insert_After_Debug --
354
      ------------------------
355
 
356
      procedure Insert_After_Debug is
357
      begin
358
         if Debug_Flag_N then
359
            Write_Str ("Insert node");
360
            Write_Int (Int (Node));
361
            Write_Str (" after node ");
362
            Write_Int (Int (After));
363
            Write_Eol;
364
         end if;
365
      end Insert_After_Debug;
366
 
367
   --  Start of processing for Insert_After
368
 
369
   begin
370
      pragma Assert
371
        (Is_List_Member (After) and then not Is_List_Member (Node));
372
 
373
      if Node = Error then
374
         return;
375
      end if;
376
 
377
      pragma Debug (Insert_After_Debug);
378
 
379
      declare
380
         Before : constant Node_Or_Entity_Id := Next (After);
381
         LC     : constant List_Id           := List_Containing (After);
382
 
383
      begin
384
         if Present (Before) then
385
            Set_Prev (Before, Node);
386
         else
387
            Set_Last (LC, Node);
388
         end if;
389
 
390
         Set_Next (After, Node);
391
 
392
         Nodes.Table (Node).In_List := True;
393
 
394
         Set_Prev      (Node, After);
395
         Set_Next      (Node, Before);
396
         Set_List_Link (Node, LC);
397
      end;
398
   end Insert_After;
399
 
400
   -------------------
401
   -- Insert_Before --
402
   -------------------
403
 
404
   procedure Insert_Before
405
     (Before : Node_Or_Entity_Id;
406
      Node   : Node_Or_Entity_Id)
407
   is
408
      procedure Insert_Before_Debug;
409
      pragma Inline (Insert_Before_Debug);
410
      --  Output debug information if Debug_Flag_N set
411
 
412
      -------------------------
413
      -- Insert_Before_Debug --
414
      -------------------------
415
 
416
      procedure Insert_Before_Debug is
417
      begin
418
         if Debug_Flag_N then
419
            Write_Str ("Insert node");
420
            Write_Int (Int (Node));
421
            Write_Str (" before node ");
422
            Write_Int (Int (Before));
423
            Write_Eol;
424
         end if;
425
      end Insert_Before_Debug;
426
 
427
   --  Start of processing for Insert_Before
428
 
429
   begin
430
      pragma Assert
431
        (Is_List_Member (Before) and then not Is_List_Member (Node));
432
 
433
      if Node = Error then
434
         return;
435
      end if;
436
 
437
      pragma Debug (Insert_Before_Debug);
438
 
439
      declare
440
         After : constant Node_Or_Entity_Id := Prev (Before);
441
         LC    : constant List_Id           := List_Containing (Before);
442
 
443
      begin
444
         if Present (After) then
445
            Set_Next (After, Node);
446
         else
447
            Set_First (LC, Node);
448
         end if;
449
 
450
         Set_Prev (Before, Node);
451
 
452
         Nodes.Table (Node).In_List := True;
453
 
454
         Set_Prev      (Node, After);
455
         Set_Next      (Node, Before);
456
         Set_List_Link (Node, LC);
457
      end;
458
   end Insert_Before;
459
 
460
   -----------------------
461
   -- Insert_List_After --
462
   -----------------------
463
 
464
   procedure Insert_List_After (After : Node_Or_Entity_Id; List : List_Id) is
465
 
466
      procedure Insert_List_After_Debug;
467
      pragma Inline (Insert_List_After_Debug);
468
      --  Output debug information if Debug_Flag_N set
469
 
470
      -----------------------------
471
      -- Insert_List_After_Debug --
472
      -----------------------------
473
 
474
      procedure Insert_List_After_Debug is
475
      begin
476
         if Debug_Flag_N then
477
            Write_Str ("Insert list ");
478
            Write_Int (Int (List));
479
            Write_Str (" after node ");
480
            Write_Int (Int (After));
481
            Write_Eol;
482
         end if;
483
      end Insert_List_After_Debug;
484
 
485
   --  Start of processing for Insert_List_After
486
 
487
   begin
488
      pragma Assert (Is_List_Member (After));
489
 
490
      if Is_Empty_List (List) then
491
         return;
492
 
493
      else
494
         declare
495
            Before : constant Node_Or_Entity_Id := Next (After);
496
            LC     : constant List_Id           := List_Containing (After);
497
            F      : constant Node_Or_Entity_Id := First (List);
498
            L      : constant Node_Or_Entity_Id := Last (List);
499
            N      : Node_Or_Entity_Id;
500
 
501
         begin
502
            pragma Debug (Insert_List_After_Debug);
503
 
504
            N := F;
505
            loop
506
               Set_List_Link (N, LC);
507
               exit when N = L;
508
               N := Next (N);
509
            end loop;
510
 
511
            if Present (Before) then
512
               Set_Prev (Before, L);
513
            else
514
               Set_Last (LC, L);
515
            end if;
516
 
517
            Set_Next (After, F);
518
            Set_Prev (F, After);
519
            Set_Next (L, Before);
520
 
521
            Set_First (List, Empty);
522
            Set_Last  (List, Empty);
523
         end;
524
      end if;
525
   end Insert_List_After;
526
 
527
   ------------------------
528
   -- Insert_List_Before --
529
   ------------------------
530
 
531
   procedure Insert_List_Before (Before : Node_Or_Entity_Id; List : List_Id) is
532
 
533
      procedure Insert_List_Before_Debug;
534
      pragma Inline (Insert_List_Before_Debug);
535
      --  Output debug information if Debug_Flag_N set
536
 
537
      ------------------------------
538
      -- Insert_List_Before_Debug --
539
      ------------------------------
540
 
541
      procedure Insert_List_Before_Debug is
542
      begin
543
         if Debug_Flag_N then
544
            Write_Str ("Insert list ");
545
            Write_Int (Int (List));
546
            Write_Str (" before node ");
547
            Write_Int (Int (Before));
548
            Write_Eol;
549
         end if;
550
      end Insert_List_Before_Debug;
551
 
552
   --  Start of processing for Insert_List_Before
553
 
554
   begin
555
      pragma Assert (Is_List_Member (Before));
556
 
557
      if Is_Empty_List (List) then
558
         return;
559
 
560
      else
561
         declare
562
            After : constant Node_Or_Entity_Id := Prev (Before);
563
            LC    : constant List_Id           := List_Containing (Before);
564
            F     : constant Node_Or_Entity_Id := First (List);
565
            L     : constant Node_Or_Entity_Id := Last (List);
566
            N     : Node_Or_Entity_Id;
567
 
568
         begin
569
            pragma Debug (Insert_List_Before_Debug);
570
 
571
            N := F;
572
            loop
573
               Set_List_Link (N, LC);
574
               exit when N = L;
575
               N := Next (N);
576
            end loop;
577
 
578
            if Present (After) then
579
               Set_Next (After, F);
580
            else
581
               Set_First (LC, F);
582
            end if;
583
 
584
            Set_Prev (Before, L);
585
            Set_Prev (F, After);
586
            Set_Next (L, Before);
587
 
588
            Set_First (List, Empty);
589
            Set_Last  (List, Empty);
590
         end;
591
      end if;
592
   end Insert_List_Before;
593
 
594
   -------------------
595
   -- Is_Empty_List --
596
   -------------------
597
 
598
   function Is_Empty_List (List : List_Id) return Boolean is
599
   begin
600
      return First (List) = Empty;
601
   end Is_Empty_List;
602
 
603
   --------------------
604
   -- Is_List_Member --
605
   --------------------
606
 
607
   function Is_List_Member (Node : Node_Or_Entity_Id) return Boolean is
608
   begin
609
      return Nodes.Table (Node).In_List;
610
   end Is_List_Member;
611
 
612
   -----------------------
613
   -- Is_Non_Empty_List --
614
   -----------------------
615
 
616
   function Is_Non_Empty_List (List : List_Id) return Boolean is
617
   begin
618
      return First (List) /= Empty;
619
   end Is_Non_Empty_List;
620
 
621
   ----------
622
   -- Last --
623
   ----------
624
 
625
   function Last (List : List_Id) return Node_Or_Entity_Id is
626
   begin
627
      pragma Assert (List <= Lists.Last);
628
      return Lists.Table (List).Last;
629
   end Last;
630
 
631
   ------------------
632
   -- Last_List_Id --
633
   ------------------
634
 
635
   function Last_List_Id return List_Id is
636
   begin
637
      return Lists.Last;
638
   end Last_List_Id;
639
 
640
   ---------------------
641
   -- Last_Non_Pragma --
642
   ---------------------
643
 
644
   function Last_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is
645
      N : constant Node_Or_Entity_Id := Last (List);
646
   begin
647
      if Nkind (N) /= N_Pragma then
648
         return N;
649
      else
650
         return Prev_Non_Pragma (N);
651
      end if;
652
   end Last_Non_Pragma;
653
 
654
   ---------------------
655
   -- List_Containing --
656
   ---------------------
657
 
658
   function List_Containing (Node : Node_Or_Entity_Id) return List_Id is
659
   begin
660
      pragma Assert (Is_List_Member (Node));
661
      return List_Id (Nodes.Table (Node).Link);
662
   end List_Containing;
663
 
664
   -----------------
665
   -- List_Length --
666
   -----------------
667
 
668
   function List_Length (List : List_Id) return Nat is
669
      Result : Nat;
670
      Node   : Node_Or_Entity_Id;
671
 
672
   begin
673
      Result := 0;
674
      Node := First (List);
675
      while Present (Node) loop
676
         Result := Result + 1;
677
         Node := Next (Node);
678
      end loop;
679
 
680
      return Result;
681
   end List_Length;
682
 
683
   -------------------
684
   -- Lists_Address --
685
   -------------------
686
 
687
   function Lists_Address return System.Address is
688
   begin
689
      return Lists.Table (First_List_Id)'Address;
690
   end Lists_Address;
691
 
692
   ----------
693
   -- Lock --
694
   ----------
695
 
696
   procedure Lock is
697
   begin
698
      Lists.Locked := True;
699
      Lists.Release;
700
 
701
      Prev_Node.Locked := True;
702
      Next_Node.Locked := True;
703
 
704
      Prev_Node.Release;
705
      Next_Node.Release;
706
   end Lock;
707
 
708
   -------------------
709
   -- New_Copy_List --
710
   -------------------
711
 
712
   function New_Copy_List (List : List_Id) return List_Id is
713
      NL : List_Id;
714
      E  : Node_Or_Entity_Id;
715
 
716
   begin
717
      if List = No_List then
718
         return No_List;
719
 
720
      else
721
         NL := New_List;
722
         E := First (List);
723
 
724
         while Present (E) loop
725
            Append (New_Copy (E), NL);
726
            E := Next (E);
727
         end loop;
728
 
729
         return NL;
730
      end if;
731
   end New_Copy_List;
732
 
733
   ----------------------------
734
   -- New_Copy_List_Original --
735
   ----------------------------
736
 
737
   function New_Copy_List_Original (List : List_Id) return List_Id is
738
      NL : List_Id;
739
      E  : Node_Or_Entity_Id;
740
 
741
   begin
742
      if List = No_List then
743
         return No_List;
744
 
745
      else
746
         NL := New_List;
747
         E := First (List);
748
 
749
         while Present (E) loop
750
            if Comes_From_Source (E) then
751
               Append (New_Copy (E), NL);
752
            end if;
753
 
754
            E := Next (E);
755
         end loop;
756
 
757
         return NL;
758
      end if;
759
   end New_Copy_List_Original;
760
 
761
   --------------
762
   -- New_List --
763
   --------------
764
 
765
   function New_List return List_Id is
766
 
767
      procedure New_List_Debug;
768
      pragma Inline (New_List_Debug);
769
      --  Output debugging information if Debug_Flag_N is set
770
 
771
      --------------------
772
      -- New_List_Debug --
773
      --------------------
774
 
775
      procedure New_List_Debug is
776
      begin
777
         if Debug_Flag_N then
778
            Write_Str ("Allocate new list, returned ID = ");
779
            Write_Int (Int (Lists.Last));
780
            Write_Eol;
781
         end if;
782
      end New_List_Debug;
783
 
784
   --  Start of processing for New_List
785
 
786
   begin
787
      Lists.Increment_Last;
788
 
789
      declare
790
         List : constant List_Id := Lists.Last;
791
 
792
      begin
793
         Set_Parent (List, Empty);
794
         Set_First  (List, Empty);
795
         Set_Last   (List, Empty);
796
 
797
         pragma Debug (New_List_Debug);
798
         return (List);
799
      end;
800
   end New_List;
801
 
802
   --  Since the one argument case is common, we optimize to build the right
803
   --  list directly, rather than first building an empty list and then doing
804
   --  the insertion, which results in some unnecessary work.
805
 
806
   function New_List (Node : Node_Or_Entity_Id) return List_Id is
807
 
808
      procedure New_List_Debug;
809
      pragma Inline (New_List_Debug);
810
      --  Output debugging information if Debug_Flag_N is set
811
 
812
      --------------------
813
      -- New_List_Debug --
814
      --------------------
815
 
816
      procedure New_List_Debug is
817
      begin
818
         if Debug_Flag_N then
819
            Write_Str ("Allocate new list, returned ID = ");
820
            Write_Int (Int (Lists.Last));
821
            Write_Eol;
822
         end if;
823
      end New_List_Debug;
824
 
825
   --  Start of processing for New_List
826
 
827
   begin
828
      if Node = Error then
829
         return New_List;
830
 
831
      else
832
         pragma Assert (not Is_List_Member (Node));
833
 
834
         Lists.Increment_Last;
835
 
836
         declare
837
            List : constant List_Id := Lists.Last;
838
 
839
         begin
840
            Set_Parent (List, Empty);
841
            Set_First  (List, Node);
842
            Set_Last   (List, Node);
843
 
844
            Nodes.Table (Node).In_List := True;
845
            Set_List_Link (Node, List);
846
            Set_Prev (Node, Empty);
847
            Set_Next (Node, Empty);
848
            pragma Debug (New_List_Debug);
849
            return List;
850
         end;
851
      end if;
852
   end New_List;
853
 
854
   function New_List
855
     (Node1 : Node_Or_Entity_Id;
856
      Node2 : Node_Or_Entity_Id) return List_Id
857
   is
858
      L : constant List_Id := New_List (Node1);
859
   begin
860
      Append (Node2, L);
861
      return L;
862
   end New_List;
863
 
864
   function New_List
865
     (Node1 : Node_Or_Entity_Id;
866
      Node2 : Node_Or_Entity_Id;
867
      Node3 : Node_Or_Entity_Id) return List_Id
868
   is
869
      L : constant List_Id := New_List (Node1);
870
   begin
871
      Append (Node2, L);
872
      Append (Node3, L);
873
      return L;
874
   end New_List;
875
 
876
   function New_List
877
     (Node1 : Node_Or_Entity_Id;
878
      Node2 : Node_Or_Entity_Id;
879
      Node3 : Node_Or_Entity_Id;
880
      Node4 : Node_Or_Entity_Id) return List_Id
881
   is
882
      L : constant List_Id := New_List (Node1);
883
   begin
884
      Append (Node2, L);
885
      Append (Node3, L);
886
      Append (Node4, L);
887
      return L;
888
   end New_List;
889
 
890
   function New_List
891
     (Node1 : Node_Or_Entity_Id;
892
      Node2 : Node_Or_Entity_Id;
893
      Node3 : Node_Or_Entity_Id;
894
      Node4 : Node_Or_Entity_Id;
895
      Node5 : Node_Or_Entity_Id) return List_Id
896
   is
897
      L : constant List_Id := New_List (Node1);
898
   begin
899
      Append (Node2, L);
900
      Append (Node3, L);
901
      Append (Node4, L);
902
      Append (Node5, L);
903
      return L;
904
   end New_List;
905
 
906
   function New_List
907
     (Node1 : Node_Or_Entity_Id;
908
      Node2 : Node_Or_Entity_Id;
909
      Node3 : Node_Or_Entity_Id;
910
      Node4 : Node_Or_Entity_Id;
911
      Node5 : Node_Or_Entity_Id;
912
      Node6 : Node_Or_Entity_Id) return List_Id
913
   is
914
      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;
923
 
924
   ----------
925
   -- Next --
926
   ----------
927
 
928
   function Next (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is
929
   begin
930
      pragma Assert (Is_List_Member (Node));
931
      return Next_Node.Table (Node);
932
   end Next;
933
 
934
   procedure Next (Node : in out Node_Or_Entity_Id) is
935
   begin
936
      Node := Next (Node);
937
   end Next;
938
 
939
   -----------------------
940
   -- Next_Node_Address --
941
   -----------------------
942
 
943
   function Next_Node_Address return System.Address is
944
   begin
945
      return Next_Node.Table (First_Node_Id)'Address;
946
   end Next_Node_Address;
947
 
948
   ---------------------
949
   -- Next_Non_Pragma --
950
   ---------------------
951
 
952
   function Next_Non_Pragma
953
     (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
954
   is
955
      N : Node_Or_Entity_Id;
956
 
957
   begin
958
      N := Node;
959
      loop
960
         N := Next (N);
961
         exit when not Nkind_In (N, N_Pragma, N_Null_Statement);
962
      end loop;
963
 
964
      return N;
965
   end Next_Non_Pragma;
966
 
967
   procedure Next_Non_Pragma (Node : in out Node_Or_Entity_Id) is
968
   begin
969
      Node := Next_Non_Pragma (Node);
970
   end Next_Non_Pragma;
971
 
972
   --------
973
   -- No --
974
   --------
975
 
976
   function No (List : List_Id) return Boolean is
977
   begin
978
      return List = No_List;
979
   end No;
980
 
981
   ---------------
982
   -- Num_Lists --
983
   ---------------
984
 
985
   function Num_Lists return Nat is
986
   begin
987
      return Int (Lists.Last) - Int (Lists.First) + 1;
988
   end Num_Lists;
989
 
990
   -------
991
   -- p --
992
   -------
993
 
994
   function p (U : Union_Id) return Node_Or_Entity_Id is
995
   begin
996
      if U in Node_Range then
997
         return Parent (Node_Or_Entity_Id (U));
998
      elsif U in List_Range then
999
         return Parent (List_Id (U));
1000
      else
1001
         return 99_999_999;
1002
      end if;
1003
   end p;
1004
 
1005
   ------------
1006
   -- Parent --
1007
   ------------
1008
 
1009
   function Parent (List : List_Id) return Node_Or_Entity_Id is
1010
   begin
1011
      pragma Assert (List <= Lists.Last);
1012
      return Lists.Table (List).Parent;
1013
   end Parent;
1014
 
1015
   ----------
1016
   -- Pick --
1017
   ----------
1018
 
1019
   function Pick (List : List_Id; Index : Pos) return Node_Or_Entity_Id is
1020
      Elmt : Node_Or_Entity_Id;
1021
 
1022
   begin
1023
      Elmt := First (List);
1024
      for J in 1 .. Index - 1 loop
1025
         Elmt := Next (Elmt);
1026
      end loop;
1027
 
1028
      return Elmt;
1029
   end Pick;
1030
 
1031
   -------------
1032
   -- Prepend --
1033
   -------------
1034
 
1035
   procedure Prepend (Node : Node_Or_Entity_Id; To : List_Id) is
1036
      F : constant Node_Or_Entity_Id := First (To);
1037
 
1038
      procedure Prepend_Debug;
1039
      pragma Inline (Prepend_Debug);
1040
      --  Output debug information if Debug_Flag_N set
1041
 
1042
      -------------------
1043
      -- Prepend_Debug --
1044
      -------------------
1045
 
1046
      procedure Prepend_Debug is
1047
      begin
1048
         if Debug_Flag_N then
1049
            Write_Str ("Prepend node ");
1050
            Write_Int (Int (Node));
1051
            Write_Str (" to list ");
1052
            Write_Int (Int (To));
1053
            Write_Eol;
1054
         end if;
1055
      end Prepend_Debug;
1056
 
1057
   --  Start of processing for Prepend_Debug
1058
 
1059
   begin
1060
      pragma Assert (not Is_List_Member (Node));
1061
 
1062
      if Node = Error then
1063
         return;
1064
      end if;
1065
 
1066
      pragma Debug (Prepend_Debug);
1067
 
1068
      if No (F) then
1069
         Set_Last (To, Node);
1070
      else
1071
         Set_Prev (F, Node);
1072
      end if;
1073
 
1074
      Set_First (To, Node);
1075
 
1076
      Nodes.Table (Node).In_List := True;
1077
 
1078
      Set_Next      (Node, F);
1079
      Set_Prev      (Node, Empty);
1080
      Set_List_Link (Node, To);
1081
   end Prepend;
1082
 
1083
   ------------------
1084
   -- Prepend_List --
1085
   ------------------
1086
 
1087
   procedure Prepend_List (List : List_Id; To : List_Id) is
1088
 
1089
      procedure Prepend_List_Debug;
1090
      pragma Inline (Prepend_List_Debug);
1091
      --  Output debug information if Debug_Flag_N set
1092
 
1093
      ------------------------
1094
      -- Prepend_List_Debug --
1095
      ------------------------
1096
 
1097
      procedure Prepend_List_Debug is
1098
      begin
1099
         if Debug_Flag_N then
1100
            Write_Str ("Prepend list ");
1101
            Write_Int (Int (List));
1102
            Write_Str (" to list ");
1103
            Write_Int (Int (To));
1104
            Write_Eol;
1105
         end if;
1106
      end Prepend_List_Debug;
1107
 
1108
   --  Start of processing for Prepend_List
1109
 
1110
   begin
1111
      if Is_Empty_List (List) then
1112
         return;
1113
 
1114
      else
1115
         declare
1116
            F : constant Node_Or_Entity_Id := First (To);
1117
            L : constant Node_Or_Entity_Id := Last (List);
1118
            N : Node_Or_Entity_Id;
1119
 
1120
         begin
1121
            pragma Debug (Prepend_List_Debug);
1122
 
1123
            N := L;
1124
            loop
1125
               Set_List_Link (N, To);
1126
               N := Prev (N);
1127
               exit when No (N);
1128
            end loop;
1129
 
1130
            if No (F) then
1131
               Set_Last (To, L);
1132
            else
1133
               Set_Next (L, F);
1134
            end if;
1135
 
1136
            Set_Prev (F, L);
1137
            Set_First (To, First (List));
1138
 
1139
            Set_First (List, Empty);
1140
            Set_Last  (List, Empty);
1141
         end;
1142
      end if;
1143
   end Prepend_List;
1144
 
1145
   ---------------------
1146
   -- Prepend_List_To --
1147
   ---------------------
1148
 
1149
   procedure Prepend_List_To (To : List_Id; List : List_Id) is
1150
   begin
1151
      Prepend_List (List, To);
1152
   end Prepend_List_To;
1153
 
1154
   ----------------
1155
   -- Prepend_To --
1156
   ----------------
1157
 
1158
   procedure Prepend_To (To : List_Id; Node : Node_Or_Entity_Id) is
1159
   begin
1160
      Prepend (Node, To);
1161
   end Prepend_To;
1162
 
1163
   -------------
1164
   -- Present --
1165
   -------------
1166
 
1167
   function Present (List : List_Id) return Boolean is
1168
   begin
1169
      return List /= No_List;
1170
   end Present;
1171
 
1172
   ----------
1173
   -- Prev --
1174
   ----------
1175
 
1176
   function Prev (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is
1177
   begin
1178
      pragma Assert (Is_List_Member (Node));
1179
      return Prev_Node.Table (Node);
1180
   end Prev;
1181
 
1182
   procedure Prev (Node : in out Node_Or_Entity_Id) is
1183
   begin
1184
      Node := Prev (Node);
1185
   end Prev;
1186
 
1187
   -----------------------
1188
   -- Prev_Node_Address --
1189
   -----------------------
1190
 
1191
   function Prev_Node_Address return System.Address is
1192
   begin
1193
      return Prev_Node.Table (First_Node_Id)'Address;
1194
   end Prev_Node_Address;
1195
 
1196
   ---------------------
1197
   -- Prev_Non_Pragma --
1198
   ---------------------
1199
 
1200
   function Prev_Non_Pragma
1201
     (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
1202
   is
1203
      N : Node_Or_Entity_Id;
1204
 
1205
   begin
1206
      N := Node;
1207
      loop
1208
         N := Prev (N);
1209
         exit when Nkind (N) /= N_Pragma;
1210
      end loop;
1211
 
1212
      return N;
1213
   end Prev_Non_Pragma;
1214
 
1215
   procedure Prev_Non_Pragma (Node : in out Node_Or_Entity_Id) is
1216
   begin
1217
      Node := Prev_Non_Pragma (Node);
1218
   end Prev_Non_Pragma;
1219
 
1220
   ------------
1221
   -- Remove --
1222
   ------------
1223
 
1224
   procedure Remove (Node : Node_Or_Entity_Id) is
1225
      Lst : constant List_Id           := List_Containing (Node);
1226
      Prv : constant Node_Or_Entity_Id := Prev (Node);
1227
      Nxt : constant Node_Or_Entity_Id := Next (Node);
1228
 
1229
      procedure Remove_Debug;
1230
      pragma Inline (Remove_Debug);
1231
      --  Output debug information if Debug_Flag_N set
1232
 
1233
      ------------------
1234
      -- Remove_Debug --
1235
      ------------------
1236
 
1237
      procedure Remove_Debug is
1238
      begin
1239
         if Debug_Flag_N then
1240
            Write_Str ("Remove node ");
1241
            Write_Int (Int (Node));
1242
            Write_Eol;
1243
         end if;
1244
      end Remove_Debug;
1245
 
1246
   --  Start of processing for Remove
1247
 
1248
   begin
1249
      pragma Debug (Remove_Debug);
1250
 
1251
      if No (Prv) then
1252
         Set_First (Lst, Nxt);
1253
      else
1254
         Set_Next (Prv, Nxt);
1255
      end if;
1256
 
1257
      if No (Nxt) then
1258
         Set_Last (Lst, Prv);
1259
      else
1260
         Set_Prev (Nxt, Prv);
1261
      end if;
1262
 
1263
      Nodes.Table (Node).In_List := False;
1264
      Set_Parent (Node, Empty);
1265
   end Remove;
1266
 
1267
   -----------------
1268
   -- Remove_Head --
1269
   -----------------
1270
 
1271
   function Remove_Head (List : List_Id) return Node_Or_Entity_Id is
1272
      Frst : constant Node_Or_Entity_Id := First (List);
1273
 
1274
      procedure Remove_Head_Debug;
1275
      pragma Inline (Remove_Head_Debug);
1276
      --  Output debug information if Debug_Flag_N set
1277
 
1278
      -----------------------
1279
      -- Remove_Head_Debug --
1280
      -----------------------
1281
 
1282
      procedure Remove_Head_Debug is
1283
      begin
1284
         if Debug_Flag_N then
1285
            Write_Str ("Remove head of list ");
1286
            Write_Int (Int (List));
1287
            Write_Eol;
1288
         end if;
1289
      end Remove_Head_Debug;
1290
 
1291
   --  Start of processing for Remove_Head
1292
 
1293
   begin
1294
      pragma Debug (Remove_Head_Debug);
1295
 
1296
      if Frst = Empty then
1297
         return Empty;
1298
 
1299
      else
1300
         declare
1301
            Nxt : constant Node_Or_Entity_Id := Next (Frst);
1302
 
1303
         begin
1304
            Set_First (List, Nxt);
1305
 
1306
            if No (Nxt) then
1307
               Set_Last (List, Empty);
1308
            else
1309
               Set_Prev (Nxt, Empty);
1310
            end if;
1311
 
1312
            Nodes.Table (Frst).In_List := False;
1313
            Set_Parent (Frst, Empty);
1314
            return Frst;
1315
         end;
1316
      end if;
1317
   end Remove_Head;
1318
 
1319
   -----------------
1320
   -- Remove_Next --
1321
   -----------------
1322
 
1323
   function Remove_Next
1324
     (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id
1325
   is
1326
      Nxt : constant Node_Or_Entity_Id := Next (Node);
1327
 
1328
      procedure Remove_Next_Debug;
1329
      pragma Inline (Remove_Next_Debug);
1330
      --  Output debug information if Debug_Flag_N set
1331
 
1332
      -----------------------
1333
      -- Remove_Next_Debug --
1334
      -----------------------
1335
 
1336
      procedure Remove_Next_Debug is
1337
      begin
1338
         if Debug_Flag_N then
1339
            Write_Str ("Remove next node after ");
1340
            Write_Int (Int (Node));
1341
            Write_Eol;
1342
         end if;
1343
      end Remove_Next_Debug;
1344
 
1345
   --  Start of processing for Remove_Next
1346
 
1347
   begin
1348
      if Present (Nxt) then
1349
         declare
1350
            Nxt2 : constant Node_Or_Entity_Id := Next (Nxt);
1351
            LC   : constant List_Id           := List_Containing (Node);
1352
 
1353
         begin
1354
            pragma Debug (Remove_Next_Debug);
1355
            Set_Next (Node, Nxt2);
1356
 
1357
            if No (Nxt2) then
1358
               Set_Last (LC, Node);
1359
            else
1360
               Set_Prev (Nxt2, Node);
1361
            end if;
1362
 
1363
            Nodes.Table (Nxt).In_List := False;
1364
            Set_Parent (Nxt, Empty);
1365
         end;
1366
      end if;
1367
 
1368
      return Nxt;
1369
   end Remove_Next;
1370
 
1371
   ---------------
1372
   -- Set_First --
1373
   ---------------
1374
 
1375
   procedure Set_First (List : List_Id; To : Node_Or_Entity_Id) is
1376
   begin
1377
      Lists.Table (List).First := To;
1378
   end Set_First;
1379
 
1380
   --------------
1381
   -- Set_Last --
1382
   --------------
1383
 
1384
   procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id) is
1385
   begin
1386
      Lists.Table (List).Last := To;
1387
   end Set_Last;
1388
 
1389
   -------------------
1390
   -- Set_List_Link --
1391
   -------------------
1392
 
1393
   procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id) is
1394
   begin
1395
      Nodes.Table (Node).Link := Union_Id (To);
1396
   end Set_List_Link;
1397
 
1398
   --------------
1399
   -- Set_Next --
1400
   --------------
1401
 
1402
   procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is
1403
   begin
1404
      Next_Node.Table (Node) := To;
1405
   end Set_Next;
1406
 
1407
   ----------------
1408
   -- Set_Parent --
1409
   ----------------
1410
 
1411
   procedure Set_Parent (List : List_Id; Node : Node_Or_Entity_Id) is
1412
   begin
1413
      pragma Assert (List <= Lists.Last);
1414
      Lists.Table (List).Parent := Node;
1415
   end Set_Parent;
1416
 
1417
   --------------
1418
   -- Set_Prev --
1419
   --------------
1420
 
1421
   procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is
1422
   begin
1423
      Prev_Node.Table (Node) := To;
1424
   end Set_Prev;
1425
 
1426
   ---------------
1427
   -- Tree_Read --
1428
   ---------------
1429
 
1430
   procedure Tree_Read is
1431
   begin
1432
      Lists.Tree_Read;
1433
      Next_Node.Tree_Read;
1434
      Prev_Node.Tree_Read;
1435
   end Tree_Read;
1436
 
1437
   ----------------
1438
   -- Tree_Write --
1439
   ----------------
1440
 
1441
   procedure Tree_Write is
1442
   begin
1443
      Lists.Tree_Write;
1444
      Next_Node.Tree_Write;
1445
      Prev_Node.Tree_Write;
1446
   end Tree_Write;
1447
 
1448
   ------------
1449
   -- Unlock --
1450
   ------------
1451
 
1452
   procedure Unlock is
1453
   begin
1454
      Lists.Locked := False;
1455
      Prev_Node.Locked := False;
1456
      Next_Node.Locked := False;
1457
   end Unlock;
1458
 
1459
end Nlists;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.