OSDN Git Service

2005-06-15 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-tree.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P R J . T R E E                             --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --             Copyright (C) 2001-2005 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 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 with Prj.Err;
28
29 package body Prj.Tree is
30
31    Node_With_Comments : constant array (Project_Node_Kind) of Boolean :=
32      (N_Project                    => True,
33       N_With_Clause                => True,
34       N_Project_Declaration        => False,
35       N_Declarative_Item           => False,
36       N_Package_Declaration        => True,
37       N_String_Type_Declaration    => True,
38       N_Literal_String             => False,
39       N_Attribute_Declaration      => True,
40       N_Typed_Variable_Declaration => True,
41       N_Variable_Declaration       => True,
42       N_Expression                 => False,
43       N_Term                       => False,
44       N_Literal_String_List        => False,
45       N_Variable_Reference         => False,
46       N_External_Value             => False,
47       N_Attribute_Reference        => False,
48       N_Case_Construction          => True,
49       N_Case_Item                  => True,
50       N_Comment_Zones              => True,
51       N_Comment                    => True);
52    --  Indicates the kinds of node that may have associated comments
53
54    package Next_End_Nodes is new Table.Table
55      (Table_Component_Type => Project_Node_Id,
56       Table_Index_Type     => Natural,
57       Table_Low_Bound      => 1,
58       Table_Initial        => 10,
59       Table_Increment      => 100,
60       Table_Name           => "Next_End_Nodes");
61    --  A stack of nodes to indicates to what node the next "end" is associated
62
63    use Tree_Private_Part;
64
65    End_Of_Line_Node   : Project_Node_Id := Empty_Node;
66    --  The node an end of line comment may be associated with
67
68    Previous_Line_Node : Project_Node_Id := Empty_Node;
69    --  The node an immediately following comment may be associated with
70
71    Previous_End_Node  : Project_Node_Id := Empty_Node;
72    --  The node comments immediately following an "end" line may be
73    --  associated with.
74
75    Unkept_Comments    : Boolean := False;
76    --  Set to True when some comments may not be associated with any node
77
78    function Comment_Zones_Of
79      (Node    : Project_Node_Id;
80       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
81    --  Returns the ID of the N_Comment_Zones node associated with node Node.
82    --  If there is not already an N_Comment_Zones node, create one and
83    --  associate it with node Node.
84
85    ------------------
86    -- Add_Comments --
87    ------------------
88
89    procedure Add_Comments
90      (To       : Project_Node_Id;
91       In_Tree  : Project_Node_Tree_Ref;
92       Where    : Comment_Location) is
93       Zone     : Project_Node_Id := Empty_Node;
94       Previous : Project_Node_Id := Empty_Node;
95
96    begin
97       pragma Assert
98         (To /= Empty_Node
99           and then
100          In_Tree.Project_Nodes.Table (To).Kind /= N_Comment);
101
102       Zone := In_Tree.Project_Nodes.Table (To).Comments;
103
104       if Zone = Empty_Node then
105
106          --  Create new N_Comment_Zones node
107
108          Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
109          In_Tree.Project_Nodes.Table
110            (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
111            (Kind             => N_Comment_Zones,
112             Expr_Kind        => Undefined,
113             Location         => No_Location,
114             Directory        => No_Name,
115             Variables        => Empty_Node,
116             Packages         => Empty_Node,
117             Pkg_Id           => Empty_Package,
118             Name             => No_Name,
119             Src_Index        => 0,
120             Path_Name        => No_Name,
121             Value            => No_Name,
122             Field1           => Empty_Node,
123             Field2           => Empty_Node,
124             Field3           => Empty_Node,
125             Flag1            => False,
126             Flag2            => False,
127             Comments         => Empty_Node);
128
129          Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
130          In_Tree.Project_Nodes.Table (To).Comments := Zone;
131       end if;
132
133       if Where = End_Of_Line then
134          In_Tree.Project_Nodes.Table (Zone).Value := Comments.Table (1).Value;
135
136       else
137          --  Get each comments in the Comments table and link them to node To
138
139          for J in 1 .. Comments.Last loop
140
141             --  Create new N_Comment node
142
143             if (Where = After or else Where = After_End) and then
144               Token /= Tok_EOF and then
145               Comments.Table (J).Follows_Empty_Line
146             then
147                Comments.Table (1 .. Comments.Last - J + 1) :=
148                  Comments.Table (J .. Comments.Last);
149                Comments.Set_Last (Comments.Last - J + 1);
150                return;
151             end if;
152
153             Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
154             In_Tree.Project_Nodes.Table
155               (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
156               (Kind             => N_Comment,
157                Expr_Kind        => Undefined,
158                Flag1            => Comments.Table (J).Follows_Empty_Line,
159                Flag2            =>
160                  Comments.Table (J).Is_Followed_By_Empty_Line,
161                Location         => No_Location,
162                Directory        => No_Name,
163                Variables        => Empty_Node,
164                Packages         => Empty_Node,
165                Pkg_Id           => Empty_Package,
166                Name             => No_Name,
167                Src_Index        => 0,
168                Path_Name        => No_Name,
169                Value            => Comments.Table (J).Value,
170                Field1           => Empty_Node,
171                Field2           => Empty_Node,
172                Field3           => Empty_Node,
173                Comments         => Empty_Node);
174
175             --  If this is the first comment, put it in the right field of
176             --  the node Zone.
177
178             if Previous = Empty_Node then
179                case Where is
180                   when Before =>
181                      In_Tree.Project_Nodes.Table (Zone).Field1 :=
182                        Project_Node_Table.Last (In_Tree.Project_Nodes);
183
184                   when After =>
185                      In_Tree.Project_Nodes.Table (Zone).Field2 :=
186                        Project_Node_Table.Last (In_Tree.Project_Nodes);
187
188                   when Before_End =>
189                      In_Tree.Project_Nodes.Table (Zone).Field3 :=
190                        Project_Node_Table.Last (In_Tree.Project_Nodes);
191
192                   when After_End =>
193                      In_Tree.Project_Nodes.Table (Zone).Comments :=
194                        Project_Node_Table.Last (In_Tree.Project_Nodes);
195
196                   when End_Of_Line =>
197                      null;
198                end case;
199
200             else
201                --  When it is not the first, link it to the previous one
202
203                In_Tree.Project_Nodes.Table (Previous).Comments :=
204                  Project_Node_Table.Last (In_Tree.Project_Nodes);
205             end if;
206
207             --  This node becomes the previous one for the next comment, if
208             --  there is one.
209
210             Previous := Project_Node_Table.Last (In_Tree.Project_Nodes);
211          end loop;
212       end if;
213
214       --  Empty the Comments table, so that there is no risk to link the same
215       --  comments to another node.
216
217       Comments.Set_Last (0);
218    end Add_Comments;
219
220    --------------------------------
221    -- Associative_Array_Index_Of --
222    --------------------------------
223
224    function Associative_Array_Index_Of
225      (Node    : Project_Node_Id;
226       In_Tree : Project_Node_Tree_Ref) return Name_Id
227    is
228    begin
229       pragma Assert
230         (Node /= Empty_Node
231           and then
232             (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
233                or else
234              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
235       return In_Tree.Project_Nodes.Table (Node).Value;
236    end Associative_Array_Index_Of;
237
238    ----------------------------
239    -- Associative_Package_Of --
240    ----------------------------
241
242    function Associative_Package_Of
243      (Node    : Project_Node_Id;
244       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
245    is
246    begin
247       pragma Assert
248         (Node /= Empty_Node
249           and then
250           (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
251       return In_Tree.Project_Nodes.Table (Node).Field3;
252    end Associative_Package_Of;
253
254    ----------------------------
255    -- Associative_Project_Of --
256    ----------------------------
257
258    function Associative_Project_Of
259      (Node    : Project_Node_Id;
260       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
261    is
262    begin
263       pragma Assert
264         (Node /= Empty_Node
265           and then
266           (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
267       return In_Tree.Project_Nodes.Table (Node).Field2;
268    end Associative_Project_Of;
269
270    ----------------------
271    -- Case_Insensitive --
272    ----------------------
273
274    function Case_Insensitive
275      (Node    : Project_Node_Id;
276       In_Tree : Project_Node_Tree_Ref) return Boolean is
277    begin
278       pragma Assert
279         (Node /= Empty_Node
280           and then
281             (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
282                or else
283              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
284       return In_Tree.Project_Nodes.Table (Node).Flag1;
285    end Case_Insensitive;
286
287    --------------------------------
288    -- Case_Variable_Reference_Of --
289    --------------------------------
290
291    function Case_Variable_Reference_Of
292      (Node    : Project_Node_Id;
293       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
294    is
295    begin
296       pragma Assert
297         (Node /= Empty_Node
298           and then
299             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
300       return In_Tree.Project_Nodes.Table (Node).Field1;
301    end Case_Variable_Reference_Of;
302
303    ----------------------
304    -- Comment_Zones_Of --
305    ----------------------
306
307    function Comment_Zones_Of
308      (Node    : Project_Node_Id;
309       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
310    is
311       Zone : Project_Node_Id;
312
313    begin
314       pragma Assert (Node /= Empty_Node);
315       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
316
317       --  If there is not already an N_Comment_Zones associated, create a new
318       --  one and associate it with node Node.
319
320       if Zone = Empty_Node then
321          Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
322          Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
323          In_Tree.Project_Nodes.Table (Zone) :=
324         (Kind             => N_Comment_Zones,
325          Location         => No_Location,
326          Directory        => No_Name,
327          Expr_Kind        => Undefined,
328          Variables        => Empty_Node,
329          Packages         => Empty_Node,
330          Pkg_Id           => Empty_Package,
331          Name             => No_Name,
332          Src_Index        => 0,
333          Path_Name        => No_Name,
334          Value            => No_Name,
335          Field1           => Empty_Node,
336          Field2           => Empty_Node,
337          Field3           => Empty_Node,
338          Flag1            => False,
339          Flag2            => False,
340          Comments         => Empty_Node);
341          In_Tree.Project_Nodes.Table (Node).Comments := Zone;
342       end if;
343
344       return Zone;
345    end Comment_Zones_Of;
346
347    -----------------------
348    -- Current_Item_Node --
349    -----------------------
350
351    function Current_Item_Node
352      (Node    : Project_Node_Id;
353       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
354    is
355    begin
356       pragma Assert
357         (Node /= Empty_Node
358           and then
359             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
360       return In_Tree.Project_Nodes.Table (Node).Field1;
361    end Current_Item_Node;
362
363    ------------------
364    -- Current_Term --
365    ------------------
366
367    function Current_Term
368      (Node    : Project_Node_Id;
369       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
370    is
371    begin
372       pragma Assert
373         (Node /= Empty_Node
374           and then
375             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
376       return In_Tree.Project_Nodes.Table (Node).Field1;
377    end Current_Term;
378
379    --------------------------
380    -- Default_Project_Node --
381    --------------------------
382
383    function Default_Project_Node
384      (In_Tree       : Project_Node_Tree_Ref;
385       Of_Kind       : Project_Node_Kind;
386       And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id
387    is
388       Result   : Project_Node_Id;
389       Zone     : Project_Node_Id;
390       Previous : Project_Node_Id;
391
392    begin
393       --  Create new node with specified kind and expression kind
394
395       Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
396       In_Tree.Project_Nodes.Table
397         (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
398         (Kind             => Of_Kind,
399          Location         => No_Location,
400          Directory        => No_Name,
401          Expr_Kind        => And_Expr_Kind,
402          Variables        => Empty_Node,
403          Packages         => Empty_Node,
404          Pkg_Id           => Empty_Package,
405          Name             => No_Name,
406          Src_Index        => 0,
407          Path_Name        => No_Name,
408          Value            => No_Name,
409          Field1           => Empty_Node,
410          Field2           => Empty_Node,
411          Field3           => Empty_Node,
412          Flag1            => False,
413          Flag2            => False,
414          Comments         => Empty_Node);
415
416       --  Save the new node for the returned value
417
418       Result := Project_Node_Table.Last (In_Tree.Project_Nodes);
419
420       if Comments.Last > 0 then
421
422          --  If this is not a node with comments, then set the flag
423
424          if not Node_With_Comments (Of_Kind) then
425             Unkept_Comments := True;
426
427          elsif Of_Kind /= N_Comment and then Of_Kind /= N_Comment_Zones then
428
429             Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
430             In_Tree.Project_Nodes.Table
431               (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
432               (Kind             => N_Comment_Zones,
433                Expr_Kind        => Undefined,
434                Location         => No_Location,
435                Directory        => No_Name,
436                Variables        => Empty_Node,
437                Packages         => Empty_Node,
438                Pkg_Id           => Empty_Package,
439                Name             => No_Name,
440                Src_Index        => 0,
441                Path_Name        => No_Name,
442                Value            => No_Name,
443                Field1           => Empty_Node,
444                Field2           => Empty_Node,
445                Field3           => Empty_Node,
446                Flag1            => False,
447                Flag2            => False,
448                Comments         => Empty_Node);
449
450             Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
451             In_Tree.Project_Nodes.Table (Result).Comments := Zone;
452             Previous := Empty_Node;
453
454             for J in 1 .. Comments.Last loop
455
456                --  Create a new N_Comment node
457
458                Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
459                In_Tree.Project_Nodes.Table
460                  (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
461                  (Kind             => N_Comment,
462                   Expr_Kind        => Undefined,
463                   Flag1            => Comments.Table (J).Follows_Empty_Line,
464                   Flag2            =>
465                     Comments.Table (J).Is_Followed_By_Empty_Line,
466                   Location         => No_Location,
467                   Directory        => No_Name,
468                   Variables        => Empty_Node,
469                   Packages         => Empty_Node,
470                   Pkg_Id           => Empty_Package,
471                   Name             => No_Name,
472                   Src_Index        => 0,
473                   Path_Name        => No_Name,
474                   Value            => Comments.Table (J).Value,
475                   Field1           => Empty_Node,
476                   Field2           => Empty_Node,
477                   Field3           => Empty_Node,
478                   Comments         => Empty_Node);
479
480                --  Link it to the N_Comment_Zones node, if it is the first,
481                --  otherwise to the previous one.
482
483                if Previous = Empty_Node then
484                   In_Tree.Project_Nodes.Table (Zone).Field1 :=
485                     Project_Node_Table.Last (In_Tree.Project_Nodes);
486
487                else
488                   In_Tree.Project_Nodes.Table (Previous).Comments :=
489                     Project_Node_Table.Last (In_Tree.Project_Nodes);
490                end if;
491
492                --  This new node will be the previous one for the next
493                --  N_Comment node, if there is one.
494
495                Previous := Project_Node_Table.Last (In_Tree.Project_Nodes);
496             end loop;
497
498             --  Empty the Comments table after all comments have been processed
499
500             Comments.Set_Last (0);
501          end if;
502       end if;
503
504       return Result;
505    end Default_Project_Node;
506
507    ------------------
508    -- Directory_Of --
509    ------------------
510
511    function Directory_Of
512      (Node    : Project_Node_Id;
513       In_Tree : Project_Node_Tree_Ref) return Name_Id is
514    begin
515       pragma Assert
516         (Node /= Empty_Node
517           and then
518             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
519       return In_Tree.Project_Nodes.Table (Node).Directory;
520    end Directory_Of;
521
522    -------------------------
523    -- End_Of_Line_Comment --
524    -------------------------
525
526    function End_Of_Line_Comment
527      (Node    : Project_Node_Id;
528       In_Tree : Project_Node_Tree_Ref) return Name_Id is
529       Zone : Project_Node_Id := Empty_Node;
530
531    begin
532       pragma Assert (Node /= Empty_Node);
533       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
534
535       if Zone = Empty_Node then
536          return No_Name;
537       else
538          return In_Tree.Project_Nodes.Table (Zone).Value;
539       end if;
540    end End_Of_Line_Comment;
541
542    ------------------------
543    -- Expression_Kind_Of --
544    ------------------------
545
546    function Expression_Kind_Of
547      (Node    : Project_Node_Id;
548       In_Tree : Project_Node_Tree_Ref) return Variable_Kind is
549    begin
550       pragma Assert
551         (Node /= Empty_Node
552            and then
553              (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
554                 or else
555               In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
556                 or else
557               In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration
558                 or else
559               In_Tree.Project_Nodes.Table (Node).Kind =
560                        N_Typed_Variable_Declaration
561                 or else
562               In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration
563                 or else
564               In_Tree.Project_Nodes.Table (Node).Kind = N_Expression
565                 or else
566               In_Tree.Project_Nodes.Table (Node).Kind = N_Term
567                 or else
568               In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
569                 or else
570               In_Tree.Project_Nodes.Table (Node).Kind =
571                         N_Attribute_Reference));
572
573       return In_Tree.Project_Nodes.Table (Node).Expr_Kind;
574    end Expression_Kind_Of;
575
576    -------------------
577    -- Expression_Of --
578    -------------------
579
580    function Expression_Of
581      (Node    : Project_Node_Id;
582       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
583    is
584    begin
585       pragma Assert
586         (Node /= Empty_Node
587           and then
588            (In_Tree.Project_Nodes.Table (Node).Kind =
589               N_Attribute_Declaration
590                or else
591             In_Tree.Project_Nodes.Table (Node).Kind =
592               N_Typed_Variable_Declaration
593                or else
594             In_Tree.Project_Nodes.Table (Node).Kind =
595               N_Variable_Declaration));
596
597       return In_Tree.Project_Nodes.Table (Node).Field1;
598    end Expression_Of;
599
600    -------------------------
601    -- Extended_Project_Of --
602    -------------------------
603
604    function Extended_Project_Of
605      (Node    : Project_Node_Id;
606       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
607    is
608    begin
609       pragma Assert
610         (Node /= Empty_Node
611           and then
612             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
613       return In_Tree.Project_Nodes.Table (Node).Field2;
614    end Extended_Project_Of;
615
616    ------------------------------
617    -- Extended_Project_Path_Of --
618    ------------------------------
619
620    function Extended_Project_Path_Of
621      (Node    : Project_Node_Id;
622       In_Tree : Project_Node_Tree_Ref) return Name_Id
623    is
624    begin
625       pragma Assert
626         (Node /= Empty_Node
627           and then
628             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
629       return In_Tree.Project_Nodes.Table (Node).Value;
630    end Extended_Project_Path_Of;
631
632    --------------------------
633    -- Extending_Project_Of --
634    --------------------------
635    function Extending_Project_Of
636      (Node    : Project_Node_Id;
637       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
638    is
639    begin
640       pragma Assert
641         (Node /= Empty_Node
642           and then
643             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
644       return In_Tree.Project_Nodes.Table (Node).Field3;
645    end Extending_Project_Of;
646
647    ---------------------------
648    -- External_Reference_Of --
649    ---------------------------
650
651    function External_Reference_Of
652      (Node    : Project_Node_Id;
653       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
654    is
655    begin
656       pragma Assert
657         (Node /= Empty_Node
658           and then
659             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
660       return In_Tree.Project_Nodes.Table (Node).Field1;
661    end External_Reference_Of;
662
663    -------------------------
664    -- External_Default_Of --
665    -------------------------
666
667    function External_Default_Of
668      (Node    : Project_Node_Id;
669       In_Tree : Project_Node_Tree_Ref)
670       return Project_Node_Id
671    is
672    begin
673       pragma Assert
674         (Node /= Empty_Node
675           and then
676             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
677       return In_Tree.Project_Nodes.Table (Node).Field2;
678    end External_Default_Of;
679
680    ------------------------
681    -- First_Case_Item_Of --
682    ------------------------
683
684    function First_Case_Item_Of
685      (Node    : Project_Node_Id;
686       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
687    is
688    begin
689       pragma Assert
690         (Node /= Empty_Node
691           and then
692             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
693       return In_Tree.Project_Nodes.Table (Node).Field2;
694    end First_Case_Item_Of;
695
696    ---------------------
697    -- First_Choice_Of --
698    ---------------------
699
700    function First_Choice_Of
701      (Node    : Project_Node_Id;
702       In_Tree : Project_Node_Tree_Ref)
703       return Project_Node_Id
704    is
705    begin
706       pragma Assert
707         (Node /= Empty_Node
708           and then
709             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
710       return In_Tree.Project_Nodes.Table (Node).Field1;
711    end First_Choice_Of;
712
713    -------------------------
714    -- First_Comment_After --
715    -------------------------
716
717    function First_Comment_After
718      (Node    : Project_Node_Id;
719       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
720    is
721       Zone : Project_Node_Id := Empty_Node;
722    begin
723       pragma Assert (Node /= Empty_Node);
724       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
725
726       if Zone = Empty_Node then
727          return Empty_Node;
728
729       else
730          return In_Tree.Project_Nodes.Table (Zone).Field2;
731       end if;
732    end First_Comment_After;
733
734    -----------------------------
735    -- First_Comment_After_End --
736    -----------------------------
737
738    function First_Comment_After_End
739      (Node    : Project_Node_Id;
740       In_Tree : Project_Node_Tree_Ref)
741       return Project_Node_Id
742    is
743       Zone : Project_Node_Id := Empty_Node;
744
745    begin
746       pragma Assert (Node /= Empty_Node);
747       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
748
749       if Zone = Empty_Node then
750          return Empty_Node;
751
752       else
753          return In_Tree.Project_Nodes.Table (Zone).Comments;
754       end if;
755    end First_Comment_After_End;
756
757    --------------------------
758    -- First_Comment_Before --
759    --------------------------
760
761    function First_Comment_Before
762      (Node    : Project_Node_Id;
763       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
764    is
765       Zone : Project_Node_Id := Empty_Node;
766
767    begin
768       pragma Assert (Node /= Empty_Node);
769       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
770
771       if Zone = Empty_Node then
772          return Empty_Node;
773
774       else
775          return In_Tree.Project_Nodes.Table (Zone).Field1;
776       end if;
777    end First_Comment_Before;
778
779    ------------------------------
780    -- First_Comment_Before_End --
781    ------------------------------
782
783    function First_Comment_Before_End
784      (Node    : Project_Node_Id;
785       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
786    is
787       Zone : Project_Node_Id := Empty_Node;
788
789    begin
790       pragma Assert (Node /= Empty_Node);
791       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
792
793       if Zone = Empty_Node then
794          return Empty_Node;
795
796       else
797          return In_Tree.Project_Nodes.Table (Zone).Field3;
798       end if;
799    end First_Comment_Before_End;
800
801    -------------------------------
802    -- First_Declarative_Item_Of --
803    -------------------------------
804
805    function First_Declarative_Item_Of
806      (Node    : Project_Node_Id;
807       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
808    is
809    begin
810       pragma Assert
811         (Node /= Empty_Node
812           and then
813             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration
814                or else
815              In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item
816                or else
817              In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
818
819       if In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration then
820          return In_Tree.Project_Nodes.Table (Node).Field1;
821       else
822          return In_Tree.Project_Nodes.Table (Node).Field2;
823       end if;
824    end First_Declarative_Item_Of;
825
826    ------------------------------
827    -- First_Expression_In_List --
828    ------------------------------
829
830    function First_Expression_In_List
831      (Node    : Project_Node_Id;
832       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
833    is
834    begin
835       pragma Assert
836         (Node /= Empty_Node
837           and then
838             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List);
839       return In_Tree.Project_Nodes.Table (Node).Field1;
840    end First_Expression_In_List;
841
842    --------------------------
843    -- First_Literal_String --
844    --------------------------
845
846    function First_Literal_String
847      (Node    : Project_Node_Id;
848       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
849    is
850    begin
851       pragma Assert
852         (Node /= Empty_Node
853           and then
854          In_Tree.Project_Nodes.Table (Node).Kind =
855            N_String_Type_Declaration);
856       return In_Tree.Project_Nodes.Table (Node).Field1;
857    end First_Literal_String;
858
859    ----------------------
860    -- First_Package_Of --
861    ----------------------
862
863    function First_Package_Of
864      (Node    : Project_Node_Id;
865       In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id
866    is
867    begin
868       pragma Assert
869         (Node /= Empty_Node
870           and then
871             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
872       return In_Tree.Project_Nodes.Table (Node).Packages;
873    end First_Package_Of;
874
875    --------------------------
876    -- First_String_Type_Of --
877    --------------------------
878
879    function First_String_Type_Of
880      (Node    : Project_Node_Id;
881       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
882    is
883    begin
884       pragma Assert
885         (Node /= Empty_Node
886           and then
887             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
888       return In_Tree.Project_Nodes.Table (Node).Field3;
889    end First_String_Type_Of;
890
891    ----------------
892    -- First_Term --
893    ----------------
894
895    function First_Term
896      (Node    : Project_Node_Id;
897       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
898    is
899    begin
900       pragma Assert
901         (Node /= Empty_Node
902           and then
903             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
904       return In_Tree.Project_Nodes.Table (Node).Field1;
905    end First_Term;
906
907    -----------------------
908    -- First_Variable_Of --
909    -----------------------
910
911    function First_Variable_Of
912      (Node    : Project_Node_Id;
913       In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id
914    is
915    begin
916       pragma Assert
917         (Node /= Empty_Node
918           and then
919             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
920                or else
921              In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
922
923       return In_Tree.Project_Nodes.Table (Node).Variables;
924    end First_Variable_Of;
925
926    --------------------------
927    -- First_With_Clause_Of --
928    --------------------------
929
930    function First_With_Clause_Of
931      (Node    : Project_Node_Id;
932       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
933    is
934    begin
935       pragma Assert
936         (Node /= Empty_Node
937           and then
938             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
939       return In_Tree.Project_Nodes.Table (Node).Field1;
940    end First_With_Clause_Of;
941
942    ------------------------
943    -- Follows_Empty_Line --
944    ------------------------
945
946    function Follows_Empty_Line
947      (Node    : Project_Node_Id;
948       In_Tree : Project_Node_Tree_Ref) return Boolean is
949    begin
950       pragma Assert
951         (Node /= Empty_Node
952          and then
953          In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
954       return In_Tree.Project_Nodes.Table (Node).Flag1;
955    end Follows_Empty_Line;
956
957    ----------
958    -- Hash --
959    ----------
960
961    function Hash (N : Project_Node_Id) return Header_Num is
962    begin
963       return Header_Num (N mod Project_Node_Id (Header_Num'Last));
964    end Hash;
965
966    ----------------
967    -- Initialize --
968    ----------------
969
970    procedure Initialize (Tree : Project_Node_Tree_Ref) is
971    begin
972       Project_Node_Table.Init (Tree.Project_Nodes);
973       Projects_Htable.Reset (Tree.Projects_HT);
974    end Initialize;
975
976    -------------------------------
977    -- Is_Followed_By_Empty_Line --
978    -------------------------------
979
980    function Is_Followed_By_Empty_Line
981      (Node    : Project_Node_Id;
982       In_Tree : Project_Node_Tree_Ref) return Boolean
983    is
984    begin
985       pragma Assert
986         (Node /= Empty_Node
987           and then
988             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
989       return In_Tree.Project_Nodes.Table (Node).Flag2;
990    end Is_Followed_By_Empty_Line;
991
992    ----------------------
993    -- Is_Extending_All --
994    ----------------------
995
996    function Is_Extending_All
997      (Node    : Project_Node_Id;
998       In_Tree : Project_Node_Tree_Ref) return Boolean is
999    begin
1000       pragma Assert
1001         (Node /= Empty_Node
1002           and then
1003            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
1004               or else
1005             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
1006       return In_Tree.Project_Nodes.Table (Node).Flag2;
1007    end Is_Extending_All;
1008
1009    -------------------------------------
1010    -- Imported_Or_Extended_Project_Of --
1011    -------------------------------------
1012
1013    function Imported_Or_Extended_Project_Of
1014      (Project   : Project_Node_Id;
1015       In_Tree   : Project_Node_Tree_Ref;
1016       With_Name : Name_Id) return Project_Node_Id
1017    is
1018       With_Clause : Project_Node_Id :=
1019         First_With_Clause_Of (Project, In_Tree);
1020       Result      : Project_Node_Id := Empty_Node;
1021
1022    begin
1023       --  First check all the imported projects
1024
1025       while With_Clause /= Empty_Node loop
1026
1027          --  Only non limited imported project may be used as prefix
1028          --  of variable or attributes.
1029
1030          Result := Non_Limited_Project_Node_Of (With_Clause, In_Tree);
1031          exit when Result /= Empty_Node
1032            and then Name_Of (Result, In_Tree) = With_Name;
1033          With_Clause := Next_With_Clause_Of (With_Clause, In_Tree);
1034       end loop;
1035
1036       --  If it is not an imported project, it might be the imported project
1037
1038       if With_Clause = Empty_Node then
1039          Result :=
1040            Extended_Project_Of
1041              (Project_Declaration_Of (Project, In_Tree), In_Tree);
1042
1043          if Result /= Empty_Node
1044            and then Name_Of (Result, In_Tree) /= With_Name
1045          then
1046             Result := Empty_Node;
1047          end if;
1048       end if;
1049
1050       return Result;
1051    end Imported_Or_Extended_Project_Of;
1052
1053    -------------
1054    -- Kind_Of --
1055    -------------
1056
1057    function Kind_Of
1058      (Node    : Project_Node_Id;
1059       In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind is
1060    begin
1061       pragma Assert (Node /= Empty_Node);
1062       return In_Tree.Project_Nodes.Table (Node).Kind;
1063    end Kind_Of;
1064
1065    -----------------
1066    -- Location_Of --
1067    -----------------
1068
1069    function Location_Of
1070      (Node    : Project_Node_Id;
1071       In_Tree : Project_Node_Tree_Ref) return Source_Ptr is
1072    begin
1073       pragma Assert (Node /= Empty_Node);
1074       return In_Tree.Project_Nodes.Table (Node).Location;
1075    end Location_Of;
1076
1077    -------------
1078    -- Name_Of --
1079    -------------
1080
1081    function Name_Of
1082      (Node    : Project_Node_Id;
1083       In_Tree : Project_Node_Tree_Ref) return Name_Id is
1084    begin
1085       pragma Assert (Node /= Empty_Node);
1086       return In_Tree.Project_Nodes.Table (Node).Name;
1087    end Name_Of;
1088
1089    --------------------
1090    -- Next_Case_Item --
1091    --------------------
1092
1093    function Next_Case_Item
1094      (Node    : Project_Node_Id;
1095       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1096    is
1097    begin
1098       pragma Assert
1099         (Node /= Empty_Node
1100           and then
1101             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
1102       return In_Tree.Project_Nodes.Table (Node).Field3;
1103    end Next_Case_Item;
1104
1105    ------------------
1106    -- Next_Comment --
1107    ------------------
1108
1109    function Next_Comment
1110      (Node    : Project_Node_Id;
1111       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is
1112    begin
1113       pragma Assert
1114         (Node /= Empty_Node
1115           and then
1116             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
1117       return In_Tree.Project_Nodes.Table (Node).Comments;
1118    end Next_Comment;
1119
1120    ---------------------------
1121    -- Next_Declarative_Item --
1122    ---------------------------
1123
1124    function Next_Declarative_Item
1125      (Node    : Project_Node_Id;
1126       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1127    is
1128    begin
1129       pragma Assert
1130         (Node /= Empty_Node
1131           and then
1132             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
1133       return In_Tree.Project_Nodes.Table (Node).Field2;
1134    end Next_Declarative_Item;
1135
1136    -----------------------------
1137    -- Next_Expression_In_List --
1138    -----------------------------
1139
1140    function Next_Expression_In_List
1141      (Node    : Project_Node_Id;
1142       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1143    is
1144    begin
1145       pragma Assert
1146         (Node /= Empty_Node
1147           and then
1148             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
1149       return In_Tree.Project_Nodes.Table (Node).Field2;
1150    end Next_Expression_In_List;
1151
1152    -------------------------
1153    -- Next_Literal_String --
1154    -------------------------
1155
1156    function Next_Literal_String
1157      (Node    : Project_Node_Id;
1158       In_Tree : Project_Node_Tree_Ref)
1159       return Project_Node_Id
1160    is
1161    begin
1162       pragma Assert
1163         (Node /= Empty_Node
1164           and then
1165             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String);
1166       return In_Tree.Project_Nodes.Table (Node).Field1;
1167    end Next_Literal_String;
1168
1169    -----------------------------
1170    -- Next_Package_In_Project --
1171    -----------------------------
1172
1173    function Next_Package_In_Project
1174      (Node    : Project_Node_Id;
1175       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1176    is
1177    begin
1178       pragma Assert
1179         (Node /= Empty_Node
1180           and then
1181             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
1182       return In_Tree.Project_Nodes.Table (Node).Field3;
1183    end Next_Package_In_Project;
1184
1185    ----------------------
1186    -- Next_String_Type --
1187    ----------------------
1188
1189    function Next_String_Type
1190      (Node    : Project_Node_Id;
1191       In_Tree : Project_Node_Tree_Ref)
1192       return Project_Node_Id
1193    is
1194    begin
1195       pragma Assert
1196         (Node /= Empty_Node
1197           and then
1198          In_Tree.Project_Nodes.Table (Node).Kind =
1199            N_String_Type_Declaration);
1200       return In_Tree.Project_Nodes.Table (Node).Field2;
1201    end Next_String_Type;
1202
1203    ---------------
1204    -- Next_Term --
1205    ---------------
1206
1207    function Next_Term
1208      (Node    : Project_Node_Id;
1209       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1210    is
1211    begin
1212       pragma Assert
1213         (Node /= Empty_Node
1214           and then
1215             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
1216       return In_Tree.Project_Nodes.Table (Node).Field2;
1217    end Next_Term;
1218
1219    -------------------
1220    -- Next_Variable --
1221    -------------------
1222
1223    function Next_Variable
1224      (Node    : Project_Node_Id;
1225       In_Tree : Project_Node_Tree_Ref)
1226       return Project_Node_Id
1227    is
1228    begin
1229       pragma Assert
1230         (Node /= Empty_Node
1231           and then
1232            (In_Tree.Project_Nodes.Table (Node).Kind =
1233               N_Typed_Variable_Declaration
1234                or else
1235             In_Tree.Project_Nodes.Table (Node).Kind =
1236               N_Variable_Declaration));
1237
1238       return In_Tree.Project_Nodes.Table (Node).Field3;
1239    end Next_Variable;
1240
1241    -------------------------
1242    -- Next_With_Clause_Of --
1243    -------------------------
1244
1245    function Next_With_Clause_Of
1246      (Node    : Project_Node_Id;
1247       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1248    is
1249    begin
1250       pragma Assert
1251         (Node /= Empty_Node
1252           and then
1253             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
1254       return In_Tree.Project_Nodes.Table (Node).Field2;
1255    end Next_With_Clause_Of;
1256
1257    ---------------------------------
1258    -- Non_Limited_Project_Node_Of --
1259    ---------------------------------
1260
1261    function Non_Limited_Project_Node_Of
1262      (Node    : Project_Node_Id;
1263       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1264    is
1265    begin
1266       pragma Assert
1267         (Node /= Empty_Node
1268           and then
1269            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
1270       return In_Tree.Project_Nodes.Table (Node).Field3;
1271    end Non_Limited_Project_Node_Of;
1272
1273    -------------------
1274    -- Package_Id_Of --
1275    -------------------
1276
1277    function Package_Id_Of
1278      (Node    : Project_Node_Id;
1279       In_Tree : Project_Node_Tree_Ref) return Package_Node_Id
1280    is
1281    begin
1282       pragma Assert
1283         (Node /= Empty_Node
1284           and then
1285             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
1286       return In_Tree.Project_Nodes.Table (Node).Pkg_Id;
1287    end Package_Id_Of;
1288
1289    ---------------------
1290    -- Package_Node_Of --
1291    ---------------------
1292
1293    function Package_Node_Of
1294      (Node    : Project_Node_Id;
1295       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1296    is
1297    begin
1298       pragma Assert
1299         (Node /= Empty_Node
1300           and then
1301             (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
1302                or else
1303              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
1304       return In_Tree.Project_Nodes.Table (Node).Field2;
1305    end Package_Node_Of;
1306
1307    ------------------
1308    -- Path_Name_Of --
1309    ------------------
1310
1311    function Path_Name_Of
1312      (Node    : Project_Node_Id;
1313       In_Tree : Project_Node_Tree_Ref) return Name_Id
1314    is
1315    begin
1316       pragma Assert
1317         (Node /= Empty_Node
1318           and then
1319             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
1320                or else
1321              In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
1322       return In_Tree.Project_Nodes.Table (Node).Path_Name;
1323    end Path_Name_Of;
1324
1325    ----------------------------
1326    -- Project_Declaration_Of --
1327    ----------------------------
1328
1329    function Project_Declaration_Of
1330      (Node    : Project_Node_Id;
1331       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1332    is
1333    begin
1334       pragma Assert
1335         (Node /= Empty_Node
1336           and then
1337             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
1338       return In_Tree.Project_Nodes.Table (Node).Field2;
1339    end Project_Declaration_Of;
1340
1341    -------------------------------------------
1342    -- Project_File_Includes_Unkept_Comments --
1343    -------------------------------------------
1344
1345    function Project_File_Includes_Unkept_Comments
1346      (Node    : Project_Node_Id;
1347       In_Tree : Project_Node_Tree_Ref) return Boolean
1348    is
1349       Declaration : constant Project_Node_Id :=
1350                       Project_Declaration_Of (Node, In_Tree);
1351    begin
1352       return In_Tree.Project_Nodes.Table (Declaration).Flag1;
1353    end Project_File_Includes_Unkept_Comments;
1354
1355    ---------------------
1356    -- Project_Node_Of --
1357    ---------------------
1358
1359    function Project_Node_Of
1360      (Node    : Project_Node_Id;
1361       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1362    is
1363    begin
1364       pragma Assert
1365         (Node /= Empty_Node
1366           and then
1367            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
1368               or else
1369             In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
1370               or else
1371             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
1372       return In_Tree.Project_Nodes.Table (Node).Field1;
1373    end Project_Node_Of;
1374
1375    -----------------------------------
1376    -- Project_Of_Renamed_Package_Of --
1377    -----------------------------------
1378
1379    function Project_Of_Renamed_Package_Of
1380      (Node    : Project_Node_Id;
1381       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
1382    is
1383    begin
1384       pragma Assert
1385         (Node /= Empty_Node
1386           and then
1387             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
1388       return In_Tree.Project_Nodes.Table (Node).Field1;
1389    end Project_Of_Renamed_Package_Of;
1390
1391    --------------------------
1392    -- Remove_Next_End_Node --
1393    --------------------------
1394
1395    procedure Remove_Next_End_Node is
1396    begin
1397       Next_End_Nodes.Decrement_Last;
1398    end Remove_Next_End_Node;
1399
1400    -----------------
1401    -- Reset_State --
1402    -----------------
1403
1404    procedure Reset_State is
1405    begin
1406       End_Of_Line_Node   := Empty_Node;
1407       Previous_Line_Node := Empty_Node;
1408       Previous_End_Node  := Empty_Node;
1409       Unkept_Comments    := False;
1410       Comments.Set_Last (0);
1411    end Reset_State;
1412
1413    -------------
1414    -- Restore --
1415    -------------
1416
1417    procedure Restore (S : in Comment_State) is
1418    begin
1419       End_Of_Line_Node   := S.End_Of_Line_Node;
1420       Previous_Line_Node := S.Previous_Line_Node;
1421       Previous_End_Node  := S.Previous_End_Node;
1422       Next_End_Nodes.Set_Last (0);
1423       Unkept_Comments    := S.Unkept_Comments;
1424
1425       Comments.Set_Last (0);
1426
1427       for J in S.Comments'Range loop
1428          Comments.Increment_Last;
1429          Comments.Table (Comments.Last) := S.Comments (J);
1430       end loop;
1431    end Restore;
1432
1433    ----------
1434    -- Save --
1435    ----------
1436
1437    procedure Save (S : out Comment_State) is
1438       Cmts : constant Comments_Ptr := new Comment_Array (1 .. Comments.Last);
1439
1440    begin
1441       for J in 1 .. Comments.Last loop
1442          Cmts (J) := Comments.Table (J);
1443       end loop;
1444
1445       S :=
1446         (End_Of_Line_Node   => End_Of_Line_Node,
1447          Previous_Line_Node => Previous_Line_Node,
1448          Previous_End_Node  => Previous_End_Node,
1449          Unkept_Comments    => Unkept_Comments,
1450          Comments           => Cmts);
1451    end Save;
1452
1453    ----------
1454    -- Scan --
1455    ----------
1456
1457    procedure Scan (In_Tree : Project_Node_Tree_Ref) is
1458       Empty_Line : Boolean := False;
1459
1460    begin
1461       --  If there are comments, then they will not be kept. Set the flag and
1462       --  clear the comments.
1463
1464       if Comments.Last > 0 then
1465          Unkept_Comments := True;
1466          Comments.Set_Last (0);
1467       end if;
1468
1469       --  Loop until a token other that End_Of_Line or Comment is found
1470
1471       loop
1472          Prj.Err.Scanner.Scan;
1473
1474          case Token is
1475             when Tok_End_Of_Line =>
1476                if Prev_Token = Tok_End_Of_Line then
1477                   Empty_Line := True;
1478
1479                   if Comments.Last > 0 then
1480                      Comments.Table (Comments.Last).Is_Followed_By_Empty_Line
1481                      := True;
1482                   end if;
1483                end if;
1484
1485             when Tok_Comment =>
1486                --  If this is a line comment, add it to the comment table
1487
1488                if Prev_Token = Tok_End_Of_Line
1489                  or else Prev_Token = No_Token
1490                then
1491                   Comments.Increment_Last;
1492                   Comments.Table (Comments.Last) :=
1493                     (Value                     => Comment_Id,
1494                      Follows_Empty_Line        => Empty_Line,
1495                      Is_Followed_By_Empty_Line => False);
1496
1497                --  Otherwise, it is an end of line comment. If there is
1498                --  an end of line node specified, associate the comment with
1499                --  this node.
1500
1501                elsif End_Of_Line_Node /= Empty_Node then
1502                   declare
1503                      Zones : constant Project_Node_Id :=
1504                                Comment_Zones_Of (End_Of_Line_Node, In_Tree);
1505                   begin
1506                      In_Tree.Project_Nodes.Table (Zones).Value := Comment_Id;
1507                   end;
1508
1509                --  Otherwise, this end of line node cannot be kept
1510
1511                else
1512                   Unkept_Comments := True;
1513                   Comments.Set_Last (0);
1514                end if;
1515
1516                Empty_Line := False;
1517
1518             when others =>
1519                --  If there are comments, where the first comment is not
1520                --  following an empty line, put the initial uninterrupted
1521                --  comment zone with the node of the preceding line (either
1522                --  a Previous_Line or a Previous_End node), if any.
1523
1524                if Comments.Last > 0 and then
1525                  not Comments.Table (1).Follows_Empty_Line then
1526                   if Previous_Line_Node /= Empty_Node then
1527                      Add_Comments
1528                        (To      => Previous_Line_Node,
1529                         Where   => After,
1530                         In_Tree => In_Tree);
1531
1532                   elsif Previous_End_Node /= Empty_Node then
1533                      Add_Comments
1534                        (To      => Previous_End_Node,
1535                         Where   => After_End,
1536                         In_Tree => In_Tree);
1537                   end if;
1538                end if;
1539
1540                --  If there are still comments and the token is "end", then
1541                --  put these comments with the Next_End node, if any;
1542                --  otherwise, these comments cannot be kept. Always clear
1543                --  the comments.
1544
1545                if Comments.Last > 0 and then Token = Tok_End then
1546                   if Next_End_Nodes.Last > 0 then
1547                      Add_Comments
1548                        (To      => Next_End_Nodes.Table (Next_End_Nodes.Last),
1549                         Where   => Before_End,
1550                         In_Tree => In_Tree);
1551
1552                   else
1553                      Unkept_Comments := True;
1554                   end if;
1555
1556                   Comments.Set_Last (0);
1557                end if;
1558
1559                --  Reset the End_Of_Line, Previous_Line and Previous_End nodes
1560                --  so that they are not used again.
1561
1562                End_Of_Line_Node   := Empty_Node;
1563                Previous_Line_Node := Empty_Node;
1564                Previous_End_Node  := Empty_Node;
1565
1566                --  And return
1567
1568                exit;
1569          end case;
1570       end loop;
1571    end Scan;
1572
1573    ------------------------------------
1574    -- Set_Associative_Array_Index_Of --
1575    ------------------------------------
1576
1577    procedure Set_Associative_Array_Index_Of
1578      (Node    : Project_Node_Id;
1579       In_Tree : Project_Node_Tree_Ref;
1580       To      : Name_Id)
1581    is
1582    begin
1583       pragma Assert
1584         (Node /= Empty_Node
1585           and then
1586             (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
1587                or else
1588              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
1589       In_Tree.Project_Nodes.Table (Node).Value := To;
1590    end Set_Associative_Array_Index_Of;
1591
1592    --------------------------------
1593    -- Set_Associative_Package_Of --
1594    --------------------------------
1595
1596    procedure Set_Associative_Package_Of
1597      (Node    : Project_Node_Id;
1598       In_Tree : Project_Node_Tree_Ref;
1599       To      : Project_Node_Id)
1600    is
1601    begin
1602       pragma Assert
1603          (Node /= Empty_Node
1604           and then
1605             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration);
1606       In_Tree.Project_Nodes.Table (Node).Field3 := To;
1607    end Set_Associative_Package_Of;
1608
1609    --------------------------------
1610    -- Set_Associative_Project_Of --
1611    --------------------------------
1612
1613    procedure Set_Associative_Project_Of
1614      (Node    : Project_Node_Id;
1615       In_Tree : Project_Node_Tree_Ref;
1616       To      : Project_Node_Id)
1617    is
1618    begin
1619       pragma Assert
1620         (Node /= Empty_Node
1621           and then
1622            (In_Tree.Project_Nodes.Table (Node).Kind =
1623               N_Attribute_Declaration));
1624       In_Tree.Project_Nodes.Table (Node).Field2 := To;
1625    end Set_Associative_Project_Of;
1626
1627    --------------------------
1628    -- Set_Case_Insensitive --
1629    --------------------------
1630
1631    procedure Set_Case_Insensitive
1632      (Node    : Project_Node_Id;
1633       In_Tree : Project_Node_Tree_Ref;
1634       To      : Boolean)
1635    is
1636    begin
1637       pragma Assert
1638         (Node /= Empty_Node
1639           and then
1640            (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
1641                or else
1642             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
1643       In_Tree.Project_Nodes.Table (Node).Flag1 := To;
1644    end Set_Case_Insensitive;
1645
1646    ------------------------------------
1647    -- Set_Case_Variable_Reference_Of --
1648    ------------------------------------
1649
1650    procedure Set_Case_Variable_Reference_Of
1651      (Node    : Project_Node_Id;
1652       In_Tree : Project_Node_Tree_Ref;
1653       To      : Project_Node_Id)
1654    is
1655    begin
1656       pragma Assert
1657         (Node /= Empty_Node
1658           and then
1659             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
1660       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1661    end Set_Case_Variable_Reference_Of;
1662
1663    ---------------------------
1664    -- Set_Current_Item_Node --
1665    ---------------------------
1666
1667    procedure Set_Current_Item_Node
1668      (Node    : Project_Node_Id;
1669       In_Tree : Project_Node_Tree_Ref;
1670       To      : Project_Node_Id)
1671    is
1672    begin
1673       pragma Assert
1674         (Node /= Empty_Node
1675           and then
1676             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
1677       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1678    end Set_Current_Item_Node;
1679
1680    ----------------------
1681    -- Set_Current_Term --
1682    ----------------------
1683
1684    procedure Set_Current_Term
1685      (Node    : Project_Node_Id;
1686       In_Tree : Project_Node_Tree_Ref;
1687       To      : Project_Node_Id)
1688    is
1689    begin
1690       pragma Assert
1691         (Node /= Empty_Node
1692           and then
1693             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
1694       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1695    end Set_Current_Term;
1696
1697    ----------------------
1698    -- Set_Directory_Of --
1699    ----------------------
1700
1701    procedure Set_Directory_Of
1702      (Node    : Project_Node_Id;
1703       In_Tree : Project_Node_Tree_Ref;
1704       To      : Name_Id)
1705    is
1706    begin
1707       pragma Assert
1708         (Node /= Empty_Node
1709           and then
1710             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
1711       In_Tree.Project_Nodes.Table (Node).Directory := To;
1712    end Set_Directory_Of;
1713
1714    ---------------------
1715    -- Set_End_Of_Line --
1716    ---------------------
1717
1718    procedure Set_End_Of_Line (To : Project_Node_Id) is
1719    begin
1720       End_Of_Line_Node := To;
1721    end Set_End_Of_Line;
1722
1723    ----------------------------
1724    -- Set_Expression_Kind_Of --
1725    ----------------------------
1726
1727    procedure Set_Expression_Kind_Of
1728      (Node    : Project_Node_Id;
1729       In_Tree : Project_Node_Tree_Ref;
1730       To      : Variable_Kind)
1731    is
1732    begin
1733       pragma Assert
1734         (Node /= Empty_Node
1735            and then
1736              (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
1737                 or else
1738               In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
1739                 or else
1740               In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration
1741                 or else
1742               In_Tree.Project_Nodes.Table (Node).Kind =
1743                 N_Typed_Variable_Declaration
1744                 or else
1745               In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration
1746                 or else
1747               In_Tree.Project_Nodes.Table (Node).Kind = N_Expression
1748                 or else
1749               In_Tree.Project_Nodes.Table (Node).Kind = N_Term
1750                 or else
1751               In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
1752                 or else
1753               In_Tree.Project_Nodes.Table (Node).Kind =
1754                 N_Attribute_Reference));
1755       In_Tree.Project_Nodes.Table (Node).Expr_Kind := To;
1756    end Set_Expression_Kind_Of;
1757
1758    -----------------------
1759    -- Set_Expression_Of --
1760    -----------------------
1761
1762    procedure Set_Expression_Of
1763      (Node    : Project_Node_Id;
1764       In_Tree : Project_Node_Tree_Ref;
1765       To      : Project_Node_Id)
1766    is
1767    begin
1768       pragma Assert
1769         (Node /= Empty_Node
1770           and then
1771            (In_Tree.Project_Nodes.Table (Node).Kind =
1772               N_Attribute_Declaration
1773                or else
1774             In_Tree.Project_Nodes.Table (Node).Kind =
1775               N_Typed_Variable_Declaration
1776                or else
1777             In_Tree.Project_Nodes.Table (Node).Kind =
1778               N_Variable_Declaration));
1779       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1780    end Set_Expression_Of;
1781
1782    -------------------------------
1783    -- Set_External_Reference_Of --
1784    -------------------------------
1785
1786    procedure Set_External_Reference_Of
1787      (Node    : Project_Node_Id;
1788       In_Tree : Project_Node_Tree_Ref;
1789       To      : Project_Node_Id)
1790    is
1791    begin
1792       pragma Assert
1793         (Node /= Empty_Node
1794           and then
1795             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
1796       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1797    end Set_External_Reference_Of;
1798
1799    -----------------------------
1800    -- Set_External_Default_Of --
1801    -----------------------------
1802
1803    procedure Set_External_Default_Of
1804      (Node    : Project_Node_Id;
1805       In_Tree : Project_Node_Tree_Ref;
1806       To      : Project_Node_Id)
1807    is
1808    begin
1809       pragma Assert
1810         (Node /= Empty_Node
1811           and then
1812             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
1813       In_Tree.Project_Nodes.Table (Node).Field2 := To;
1814    end Set_External_Default_Of;
1815
1816    ----------------------------
1817    -- Set_First_Case_Item_Of --
1818    ----------------------------
1819
1820    procedure Set_First_Case_Item_Of
1821      (Node    : Project_Node_Id;
1822       In_Tree : Project_Node_Tree_Ref;
1823       To      : Project_Node_Id)
1824    is
1825    begin
1826       pragma Assert
1827         (Node /= Empty_Node
1828           and then
1829             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
1830       In_Tree.Project_Nodes.Table (Node).Field2 := To;
1831    end Set_First_Case_Item_Of;
1832
1833    -------------------------
1834    -- Set_First_Choice_Of --
1835    -------------------------
1836
1837    procedure Set_First_Choice_Of
1838      (Node    : Project_Node_Id;
1839       In_Tree : Project_Node_Tree_Ref;
1840       To      : Project_Node_Id)
1841    is
1842    begin
1843       pragma Assert
1844         (Node /= Empty_Node
1845           and then
1846             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
1847       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1848    end Set_First_Choice_Of;
1849
1850    -----------------------------
1851    -- Set_First_Comment_After --
1852    -----------------------------
1853
1854    procedure Set_First_Comment_After
1855      (Node    : Project_Node_Id;
1856       In_Tree : Project_Node_Tree_Ref;
1857       To      : Project_Node_Id)
1858    is
1859       Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
1860    begin
1861       In_Tree.Project_Nodes.Table (Zone).Field2 := To;
1862    end Set_First_Comment_After;
1863
1864    ---------------------------------
1865    -- Set_First_Comment_After_End --
1866    ---------------------------------
1867
1868    procedure Set_First_Comment_After_End
1869      (Node    : Project_Node_Id;
1870       In_Tree : Project_Node_Tree_Ref;
1871       To      : Project_Node_Id)
1872    is
1873       Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
1874    begin
1875       In_Tree.Project_Nodes.Table (Zone).Comments := To;
1876    end Set_First_Comment_After_End;
1877
1878    ------------------------------
1879    -- Set_First_Comment_Before --
1880    ------------------------------
1881
1882    procedure Set_First_Comment_Before
1883      (Node    : Project_Node_Id;
1884       In_Tree : Project_Node_Tree_Ref;
1885       To      : Project_Node_Id)
1886
1887    is
1888       Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
1889    begin
1890       In_Tree.Project_Nodes.Table (Zone).Field1 := To;
1891    end Set_First_Comment_Before;
1892
1893    ----------------------------------
1894    -- Set_First_Comment_Before_End --
1895    ----------------------------------
1896
1897    procedure Set_First_Comment_Before_End
1898      (Node    : Project_Node_Id;
1899       In_Tree : Project_Node_Tree_Ref;
1900       To      : Project_Node_Id)
1901    is
1902       Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
1903    begin
1904       In_Tree.Project_Nodes.Table (Zone).Field2 := To;
1905    end Set_First_Comment_Before_End;
1906
1907    ------------------------
1908    -- Set_Next_Case_Item --
1909    ------------------------
1910
1911    procedure Set_Next_Case_Item
1912      (Node    : Project_Node_Id;
1913       In_Tree : Project_Node_Tree_Ref;
1914       To      : Project_Node_Id)
1915    is
1916    begin
1917       pragma Assert
1918         (Node /= Empty_Node
1919           and then
1920             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
1921       In_Tree.Project_Nodes.Table (Node).Field3 := To;
1922    end Set_Next_Case_Item;
1923
1924    ----------------------
1925    -- Set_Next_Comment --
1926    ----------------------
1927
1928    procedure Set_Next_Comment
1929      (Node    : Project_Node_Id;
1930       In_Tree : Project_Node_Tree_Ref;
1931       To      : Project_Node_Id)
1932    is
1933    begin
1934       pragma Assert
1935         (Node /= Empty_Node
1936           and then
1937             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
1938       In_Tree.Project_Nodes.Table (Node).Comments := To;
1939    end Set_Next_Comment;
1940
1941    -----------------------------------
1942    -- Set_First_Declarative_Item_Of --
1943    -----------------------------------
1944
1945    procedure Set_First_Declarative_Item_Of
1946      (Node    : Project_Node_Id;
1947       In_Tree : Project_Node_Tree_Ref;
1948       To      : Project_Node_Id)
1949    is
1950    begin
1951       pragma Assert
1952         (Node /= Empty_Node
1953           and then
1954             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration
1955                or else
1956              In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item
1957                or else
1958              In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
1959
1960       if In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration then
1961          In_Tree.Project_Nodes.Table (Node).Field1 := To;
1962       else
1963          In_Tree.Project_Nodes.Table (Node).Field2 := To;
1964       end if;
1965    end Set_First_Declarative_Item_Of;
1966
1967    ----------------------------------
1968    -- Set_First_Expression_In_List --
1969    ----------------------------------
1970
1971    procedure Set_First_Expression_In_List
1972      (Node    : Project_Node_Id;
1973       In_Tree : Project_Node_Tree_Ref;
1974       To      : Project_Node_Id)
1975    is
1976    begin
1977       pragma Assert
1978         (Node /= Empty_Node
1979           and then
1980             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List);
1981       In_Tree.Project_Nodes.Table (Node).Field1 := To;
1982    end Set_First_Expression_In_List;
1983
1984    ------------------------------
1985    -- Set_First_Literal_String --
1986    ------------------------------
1987
1988    procedure Set_First_Literal_String
1989      (Node    : Project_Node_Id;
1990       In_Tree : Project_Node_Tree_Ref;
1991       To      : Project_Node_Id)
1992    is
1993    begin
1994       pragma Assert
1995         (Node /= Empty_Node
1996           and then
1997          In_Tree.Project_Nodes.Table (Node).Kind =
1998            N_String_Type_Declaration);
1999       In_Tree.Project_Nodes.Table (Node).Field1 := To;
2000    end Set_First_Literal_String;
2001
2002    --------------------------
2003    -- Set_First_Package_Of --
2004    --------------------------
2005
2006    procedure Set_First_Package_Of
2007      (Node    : Project_Node_Id;
2008       In_Tree : Project_Node_Tree_Ref;
2009       To      : Package_Declaration_Id)
2010    is
2011    begin
2012       pragma Assert
2013         (Node /= Empty_Node
2014           and then
2015             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
2016       In_Tree.Project_Nodes.Table (Node).Packages := To;
2017    end Set_First_Package_Of;
2018
2019    ------------------------------
2020    -- Set_First_String_Type_Of --
2021    ------------------------------
2022
2023    procedure Set_First_String_Type_Of
2024      (Node    : Project_Node_Id;
2025       In_Tree : Project_Node_Tree_Ref;
2026       To      : Project_Node_Id)
2027    is
2028    begin
2029       pragma Assert
2030         (Node /= Empty_Node
2031           and then
2032             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
2033       In_Tree.Project_Nodes.Table (Node).Field3 := To;
2034    end Set_First_String_Type_Of;
2035
2036    --------------------
2037    -- Set_First_Term --
2038    --------------------
2039
2040    procedure Set_First_Term
2041      (Node    : Project_Node_Id;
2042       In_Tree : Project_Node_Tree_Ref;
2043       To      : Project_Node_Id)
2044    is
2045    begin
2046       pragma Assert
2047         (Node /= Empty_Node
2048           and then
2049             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
2050       In_Tree.Project_Nodes.Table (Node).Field1 := To;
2051    end Set_First_Term;
2052
2053    ---------------------------
2054    -- Set_First_Variable_Of --
2055    ---------------------------
2056
2057    procedure Set_First_Variable_Of
2058      (Node    : Project_Node_Id;
2059       In_Tree : Project_Node_Tree_Ref;
2060       To      : Variable_Node_Id)
2061    is
2062    begin
2063       pragma Assert
2064         (Node /= Empty_Node
2065           and then
2066             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
2067                or else
2068              In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
2069       In_Tree.Project_Nodes.Table (Node).Variables := To;
2070    end Set_First_Variable_Of;
2071
2072    ------------------------------
2073    -- Set_First_With_Clause_Of --
2074    ------------------------------
2075
2076    procedure Set_First_With_Clause_Of
2077      (Node    : Project_Node_Id;
2078       In_Tree : Project_Node_Tree_Ref;
2079       To      : Project_Node_Id)
2080    is
2081    begin
2082       pragma Assert
2083         (Node /= Empty_Node
2084           and then
2085             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
2086       In_Tree.Project_Nodes.Table (Node).Field1 := To;
2087    end Set_First_With_Clause_Of;
2088
2089    --------------------------
2090    -- Set_Is_Extending_All --
2091    --------------------------
2092
2093    procedure Set_Is_Extending_All
2094      (Node    : Project_Node_Id;
2095       In_Tree : Project_Node_Tree_Ref)
2096    is
2097    begin
2098       pragma Assert
2099         (Node /= Empty_Node
2100           and then
2101             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
2102                or else
2103              In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
2104       In_Tree.Project_Nodes.Table (Node).Flag2 := True;
2105    end Set_Is_Extending_All;
2106
2107    -----------------
2108    -- Set_Kind_Of --
2109    -----------------
2110
2111    procedure Set_Kind_Of
2112      (Node    : Project_Node_Id;
2113       In_Tree : Project_Node_Tree_Ref;
2114       To      : Project_Node_Kind)
2115    is
2116    begin
2117       pragma Assert (Node /= Empty_Node);
2118       In_Tree.Project_Nodes.Table (Node).Kind := To;
2119    end Set_Kind_Of;
2120
2121    ---------------------
2122    -- Set_Location_Of --
2123    ---------------------
2124
2125    procedure Set_Location_Of
2126      (Node    : Project_Node_Id;
2127       In_Tree : Project_Node_Tree_Ref;
2128       To      : Source_Ptr)
2129    is
2130    begin
2131       pragma Assert (Node /= Empty_Node);
2132       In_Tree.Project_Nodes.Table (Node).Location := To;
2133    end Set_Location_Of;
2134
2135    -----------------------------
2136    -- Set_Extended_Project_Of --
2137    -----------------------------
2138
2139    procedure Set_Extended_Project_Of
2140      (Node    : Project_Node_Id;
2141       In_Tree : Project_Node_Tree_Ref;
2142       To      : Project_Node_Id)
2143    is
2144    begin
2145       pragma Assert
2146         (Node /= Empty_Node
2147           and then
2148             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
2149       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2150    end Set_Extended_Project_Of;
2151
2152    ----------------------------------
2153    -- Set_Extended_Project_Path_Of --
2154    ----------------------------------
2155
2156    procedure Set_Extended_Project_Path_Of
2157      (Node    : Project_Node_Id;
2158       In_Tree : Project_Node_Tree_Ref;
2159       To      : Name_Id)
2160    is
2161    begin
2162       pragma Assert
2163         (Node /= Empty_Node
2164           and then
2165             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
2166       In_Tree.Project_Nodes.Table (Node).Value := To;
2167    end Set_Extended_Project_Path_Of;
2168
2169    ------------------------------
2170    -- Set_Extending_Project_Of --
2171    ------------------------------
2172
2173    procedure Set_Extending_Project_Of
2174      (Node    : Project_Node_Id;
2175       In_Tree : Project_Node_Tree_Ref;
2176       To      : Project_Node_Id)
2177    is
2178    begin
2179       pragma Assert
2180         (Node /= Empty_Node
2181           and then
2182             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
2183       In_Tree.Project_Nodes.Table (Node).Field3 := To;
2184    end Set_Extending_Project_Of;
2185
2186    -----------------
2187    -- Set_Name_Of --
2188    -----------------
2189
2190    procedure Set_Name_Of
2191      (Node    : Project_Node_Id;
2192       In_Tree : Project_Node_Tree_Ref;
2193       To      : Name_Id)
2194    is
2195    begin
2196       pragma Assert (Node /= Empty_Node);
2197       In_Tree.Project_Nodes.Table (Node).Name := To;
2198    end Set_Name_Of;
2199
2200    -------------------------------
2201    -- Set_Next_Declarative_Item --
2202    -------------------------------
2203
2204    procedure Set_Next_Declarative_Item
2205      (Node    : Project_Node_Id;
2206       In_Tree : Project_Node_Tree_Ref;
2207       To      : Project_Node_Id)
2208    is
2209    begin
2210       pragma Assert
2211         (Node /= Empty_Node
2212           and then
2213             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
2214       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2215    end Set_Next_Declarative_Item;
2216
2217    -----------------------
2218    -- Set_Next_End_Node --
2219    -----------------------
2220
2221    procedure Set_Next_End_Node (To : Project_Node_Id) is
2222    begin
2223       Next_End_Nodes.Increment_Last;
2224       Next_End_Nodes.Table (Next_End_Nodes.Last) := To;
2225    end Set_Next_End_Node;
2226
2227    ---------------------------------
2228    -- Set_Next_Expression_In_List --
2229    ---------------------------------
2230
2231    procedure Set_Next_Expression_In_List
2232      (Node    : Project_Node_Id;
2233       In_Tree : Project_Node_Tree_Ref;
2234       To      : Project_Node_Id)
2235    is
2236    begin
2237       pragma Assert
2238         (Node /= Empty_Node
2239           and then
2240             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
2241       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2242    end Set_Next_Expression_In_List;
2243
2244    -----------------------------
2245    -- Set_Next_Literal_String --
2246    -----------------------------
2247
2248    procedure Set_Next_Literal_String
2249      (Node    : Project_Node_Id;
2250       In_Tree : Project_Node_Tree_Ref;
2251       To      : Project_Node_Id)
2252    is
2253    begin
2254       pragma Assert
2255         (Node /= Empty_Node
2256           and then
2257             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String);
2258       In_Tree.Project_Nodes.Table (Node).Field1 := To;
2259    end Set_Next_Literal_String;
2260
2261    ---------------------------------
2262    -- Set_Next_Package_In_Project --
2263    ---------------------------------
2264
2265    procedure Set_Next_Package_In_Project
2266      (Node    : Project_Node_Id;
2267       In_Tree : Project_Node_Tree_Ref;
2268       To      : Project_Node_Id)
2269    is
2270    begin
2271       pragma Assert
2272         (Node /= Empty_Node
2273           and then
2274             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
2275       In_Tree.Project_Nodes.Table (Node).Field3 := To;
2276    end Set_Next_Package_In_Project;
2277
2278    --------------------------
2279    -- Set_Next_String_Type --
2280    --------------------------
2281
2282    procedure Set_Next_String_Type
2283      (Node    : Project_Node_Id;
2284       In_Tree : Project_Node_Tree_Ref;
2285       To      : Project_Node_Id)
2286    is
2287    begin
2288       pragma Assert
2289         (Node /= Empty_Node
2290           and then
2291          In_Tree.Project_Nodes.Table (Node).Kind =
2292            N_String_Type_Declaration);
2293       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2294    end Set_Next_String_Type;
2295
2296    -------------------
2297    -- Set_Next_Term --
2298    -------------------
2299
2300    procedure Set_Next_Term
2301      (Node    : Project_Node_Id;
2302       In_Tree : Project_Node_Tree_Ref;
2303       To      : Project_Node_Id)
2304    is
2305    begin
2306       pragma Assert
2307         (Node /= Empty_Node
2308           and then
2309             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
2310       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2311    end Set_Next_Term;
2312
2313    -----------------------
2314    -- Set_Next_Variable --
2315    -----------------------
2316
2317    procedure Set_Next_Variable
2318      (Node    : Project_Node_Id;
2319       In_Tree : Project_Node_Tree_Ref;
2320       To      : Project_Node_Id)
2321    is
2322    begin
2323       pragma Assert
2324         (Node /= Empty_Node
2325           and then
2326            (In_Tree.Project_Nodes.Table (Node).Kind =
2327               N_Typed_Variable_Declaration
2328                or else
2329             In_Tree.Project_Nodes.Table (Node).Kind =
2330               N_Variable_Declaration));
2331       In_Tree.Project_Nodes.Table (Node).Field3 := To;
2332    end Set_Next_Variable;
2333
2334    -----------------------------
2335    -- Set_Next_With_Clause_Of --
2336    -----------------------------
2337
2338    procedure Set_Next_With_Clause_Of
2339      (Node    : Project_Node_Id;
2340       In_Tree : Project_Node_Tree_Ref;
2341       To      : Project_Node_Id)
2342    is
2343    begin
2344       pragma Assert
2345         (Node /= Empty_Node
2346           and then
2347             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
2348       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2349    end Set_Next_With_Clause_Of;
2350
2351    -----------------------
2352    -- Set_Package_Id_Of --
2353    -----------------------
2354
2355    procedure Set_Package_Id_Of
2356      (Node    : Project_Node_Id;
2357       In_Tree : Project_Node_Tree_Ref;
2358       To      : Package_Node_Id)
2359    is
2360    begin
2361       pragma Assert
2362         (Node /= Empty_Node
2363           and then
2364             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
2365       In_Tree.Project_Nodes.Table (Node).Pkg_Id := To;
2366    end Set_Package_Id_Of;
2367
2368    -------------------------
2369    -- Set_Package_Node_Of --
2370    -------------------------
2371
2372    procedure Set_Package_Node_Of
2373      (Node    : Project_Node_Id;
2374       In_Tree : Project_Node_Tree_Ref;
2375       To      : Project_Node_Id)
2376    is
2377    begin
2378       pragma Assert
2379         (Node /= Empty_Node
2380           and then
2381             (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
2382                or else
2383              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
2384       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2385    end Set_Package_Node_Of;
2386
2387    ----------------------
2388    -- Set_Path_Name_Of --
2389    ----------------------
2390
2391    procedure Set_Path_Name_Of
2392      (Node    : Project_Node_Id;
2393       In_Tree : Project_Node_Tree_Ref;
2394       To      : Name_Id)
2395    is
2396    begin
2397       pragma Assert
2398         (Node /= Empty_Node
2399           and then
2400             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
2401                or else
2402              In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
2403       In_Tree.Project_Nodes.Table (Node).Path_Name := To;
2404    end Set_Path_Name_Of;
2405
2406    ---------------------------
2407    -- Set_Previous_End_Node --
2408    ---------------------------
2409    procedure Set_Previous_End_Node (To : Project_Node_Id) is
2410    begin
2411       Previous_End_Node := To;
2412    end Set_Previous_End_Node;
2413
2414    ----------------------------
2415    -- Set_Previous_Line_Node --
2416    ----------------------------
2417
2418    procedure Set_Previous_Line_Node (To : Project_Node_Id) is
2419    begin
2420       Previous_Line_Node := To;
2421    end Set_Previous_Line_Node;
2422
2423    --------------------------------
2424    -- Set_Project_Declaration_Of --
2425    --------------------------------
2426
2427    procedure Set_Project_Declaration_Of
2428      (Node    : Project_Node_Id;
2429       In_Tree : Project_Node_Tree_Ref;
2430       To      : Project_Node_Id)
2431    is
2432    begin
2433       pragma Assert
2434         (Node /= Empty_Node
2435          and then
2436            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
2437       In_Tree.Project_Nodes.Table (Node).Field2 := To;
2438    end Set_Project_Declaration_Of;
2439
2440    -----------------------------------------------
2441    -- Set_Project_File_Includes_Unkept_Comments --
2442    -----------------------------------------------
2443
2444    procedure Set_Project_File_Includes_Unkept_Comments
2445      (Node    : Project_Node_Id;
2446       In_Tree : Project_Node_Tree_Ref;
2447       To      : Boolean)
2448    is
2449       Declaration : constant Project_Node_Id :=
2450                       Project_Declaration_Of (Node, In_Tree);
2451    begin
2452       In_Tree.Project_Nodes.Table (Declaration).Flag1 := To;
2453    end Set_Project_File_Includes_Unkept_Comments;
2454
2455    -------------------------
2456    -- Set_Project_Node_Of --
2457    -------------------------
2458
2459    procedure Set_Project_Node_Of
2460      (Node         : Project_Node_Id;
2461       In_Tree      : Project_Node_Tree_Ref;
2462       To           : Project_Node_Id;
2463       Limited_With : Boolean := False)
2464    is
2465    begin
2466       pragma Assert
2467         (Node /= Empty_Node
2468           and then
2469             (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
2470                or else
2471              In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
2472                or else
2473              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
2474       In_Tree.Project_Nodes.Table (Node).Field1 := To;
2475
2476       if In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
2477         and then not Limited_With
2478       then
2479          In_Tree.Project_Nodes.Table (Node).Field3 := To;
2480       end if;
2481    end Set_Project_Node_Of;
2482
2483    ---------------------------------------
2484    -- Set_Project_Of_Renamed_Package_Of --
2485    ---------------------------------------
2486
2487    procedure Set_Project_Of_Renamed_Package_Of
2488      (Node    : Project_Node_Id;
2489       In_Tree : Project_Node_Tree_Ref;
2490       To      : Project_Node_Id)
2491    is
2492    begin
2493       pragma Assert
2494         (Node /= Empty_Node
2495           and then
2496             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
2497       In_Tree.Project_Nodes.Table (Node).Field1 := To;
2498    end Set_Project_Of_Renamed_Package_Of;
2499
2500    -------------------------
2501    -- Set_Source_Index_Of --
2502    -------------------------
2503
2504    procedure Set_Source_Index_Of
2505      (Node    : Project_Node_Id;
2506       In_Tree : Project_Node_Tree_Ref;
2507       To      : Int)
2508    is
2509    begin
2510       pragma Assert
2511         (Node /= Empty_Node
2512           and then
2513            (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
2514             or else
2515             In_Tree.Project_Nodes.Table (Node).Kind =
2516               N_Attribute_Declaration));
2517       In_Tree.Project_Nodes.Table (Node).Src_Index := To;
2518    end Set_Source_Index_Of;
2519
2520    ------------------------
2521    -- Set_String_Type_Of --
2522    ------------------------
2523
2524    procedure Set_String_Type_Of
2525      (Node    : Project_Node_Id;
2526       In_Tree : Project_Node_Tree_Ref;
2527       To      : Project_Node_Id)
2528    is
2529    begin
2530       pragma Assert
2531         (Node /= Empty_Node
2532           and then
2533            (In_Tree.Project_Nodes.Table (Node).Kind =
2534               N_Variable_Reference
2535                or else
2536             In_Tree.Project_Nodes.Table (Node).Kind =
2537               N_Typed_Variable_Declaration)
2538           and then
2539             In_Tree.Project_Nodes.Table (To).Kind = N_String_Type_Declaration);
2540
2541       if In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference then
2542          In_Tree.Project_Nodes.Table (Node).Field3 := To;
2543       else
2544          In_Tree.Project_Nodes.Table (Node).Field2 := To;
2545       end if;
2546    end Set_String_Type_Of;
2547
2548    -------------------------
2549    -- Set_String_Value_Of --
2550    -------------------------
2551
2552    procedure Set_String_Value_Of
2553      (Node    : Project_Node_Id;
2554       In_Tree : Project_Node_Tree_Ref;
2555       To      : Name_Id)
2556    is
2557    begin
2558       pragma Assert
2559         (Node /= Empty_Node
2560           and then
2561             (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
2562                or else
2563              In_Tree.Project_Nodes.Table (Node).Kind = N_Comment
2564                or else
2565              In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String));
2566       In_Tree.Project_Nodes.Table (Node).Value := To;
2567    end Set_String_Value_Of;
2568
2569    ---------------------
2570    -- Source_Index_Of --
2571    ---------------------
2572
2573    function Source_Index_Of
2574      (Node    : Project_Node_Id;
2575       In_Tree : Project_Node_Tree_Ref) return Int
2576    is
2577    begin
2578       pragma Assert
2579         (Node /= Empty_Node
2580           and then
2581             (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
2582               or else
2583              In_Tree.Project_Nodes.Table (Node).Kind =
2584                N_Attribute_Declaration));
2585       return In_Tree.Project_Nodes.Table (Node).Src_Index;
2586    end Source_Index_Of;
2587
2588    --------------------
2589    -- String_Type_Of --
2590    --------------------
2591
2592    function String_Type_Of
2593      (Node    : Project_Node_Id;
2594       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
2595    is
2596    begin
2597       pragma Assert
2598         (Node /= Empty_Node
2599           and then
2600            (In_Tree.Project_Nodes.Table (Node).Kind =
2601               N_Variable_Reference
2602                or else
2603             In_Tree.Project_Nodes.Table (Node).Kind =
2604               N_Typed_Variable_Declaration));
2605
2606       if In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference then
2607          return In_Tree.Project_Nodes.Table (Node).Field3;
2608       else
2609          return In_Tree.Project_Nodes.Table (Node).Field2;
2610       end if;
2611    end String_Type_Of;
2612
2613    ---------------------
2614    -- String_Value_Of --
2615    ---------------------
2616
2617    function String_Value_Of
2618      (Node    : Project_Node_Id;
2619       In_Tree : Project_Node_Tree_Ref) return Name_Id
2620    is
2621    begin
2622       pragma Assert
2623         (Node /= Empty_Node
2624           and then
2625            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
2626               or else
2627             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment
2628                or else
2629             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String));
2630       return In_Tree.Project_Nodes.Table (Node).Value;
2631    end String_Value_Of;
2632
2633    --------------------
2634    -- Value_Is_Valid --
2635    --------------------
2636
2637    function Value_Is_Valid
2638      (For_Typed_Variable : Project_Node_Id;
2639       In_Tree            : Project_Node_Tree_Ref;
2640       Value              : Name_Id) return Boolean
2641    is
2642    begin
2643       pragma Assert
2644         (For_Typed_Variable /= Empty_Node
2645           and then
2646            (In_Tree.Project_Nodes.Table (For_Typed_Variable).Kind =
2647                                      N_Typed_Variable_Declaration));
2648
2649       declare
2650          Current_String : Project_Node_Id :=
2651                             First_Literal_String
2652                               (String_Type_Of (For_Typed_Variable, In_Tree),
2653                                In_Tree);
2654
2655       begin
2656          while Current_String /= Empty_Node
2657            and then
2658              String_Value_Of (Current_String, In_Tree) /= Value
2659          loop
2660             Current_String :=
2661               Next_Literal_String (Current_String, In_Tree);
2662          end loop;
2663
2664          return Current_String /= Empty_Node;
2665       end;
2666
2667    end Value_Is_Valid;
2668
2669    -------------------------------
2670    -- There_Are_Unkept_Comments --
2671    -------------------------------
2672
2673    function There_Are_Unkept_Comments return Boolean is
2674    begin
2675       return Unkept_Comments;
2676    end There_Are_Unkept_Comments;
2677
2678 end Prj.Tree;