1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                             P R J . T R E E                              --
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--          Copyright (C) 2001-2013, Free Software Foundation, Inc.         --
10--                                                                          --
11-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12-- terms of the  GNU General Public License as published  by the Free Soft- --
13-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE.  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 COPYING3.  If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license.          --
20--                                                                          --
21-- GNAT was originally developed  by the GNAT team at  New York University. --
22-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23--                                                                          --
24------------------------------------------------------------------------------
25
26--  This package defines the structure of the Project File tree
27
28with GNAT.Dynamic_HTables;
29with GNAT.Dynamic_Tables;
30
31with Table;
32
33with Prj.Attr; use Prj.Attr;
34with Prj.Env;
35with Prj.Ext;
36
37package Prj.Tree is
38
39   -----------------
40   -- Environment --
41   -----------------
42
43   --  The following record contains the context in which projects are parsed
44   --  and processed (finding importing project, resolving external values,..).
45
46   type Environment is record
47      External : Prj.Ext.External_References;
48      --  External references are stored in this hash table (and manipulated
49      --  through subprograms in prj-ext.ads). External references are
50      --  project-tree specific so that one can load the same tree twice but
51      --  have two views of it, for instance.
52
53      Project_Path : aliased Prj.Env.Project_Search_Path;
54      --  The project path is tree specific, since we might want to load
55      --  simultaneously multiple projects, each with its own search path, in
56      --  particular when using different compilers with different default
57      --  search directories.
58
59      Flags : Prj.Processing_Flags;
60      --  Configure errors and warnings
61   end record;
62
63   procedure Initialize
64     (Self  : out Environment;
65      Flags : Processing_Flags);
66   --  Initialize a new environment
67
68   procedure Initialize_And_Copy
69     (Self      : out Environment;
70      Copy_From : Environment);
71   --  Initialize a new environment, copying its values from Copy_From
72
73   procedure Free (Self : in out Environment);
74   --  Free the memory used by Self
75
76   procedure Override_Flags
77     (Self : in out Environment; Flags : Prj.Processing_Flags);
78   --  Override the subprogram called in case there are parsing errors. This
79   --  is needed in applications that do their own error handling, since the
80   --  error handler is likely to be a local subprogram in this case (which
81   --  can't be stored when the flags are created).
82
83   -------------------
84   -- Project nodes --
85   -------------------
86
87   type Project_Node_Tree_Data;
88   type Project_Node_Tree_Ref is access all Project_Node_Tree_Data;
89   --  Type to designate a project node tree, so that several project node
90   --  trees can coexist in memory.
91
92   Project_Nodes_Initial   : constant := 1_000;
93   Project_Nodes_Increment : constant := 100;
94   --  Allocation parameters for initializing and extending number
95   --  of nodes in table Tree_Private_Part.Project_Nodes
96
97   Project_Node_Low_Bound  : constant := 0;
98   Project_Node_High_Bound : constant := 099_999_999;
99   --  Range of values for project node id's (in practice infinite)
100
101   type Project_Node_Id is range
102     Project_Node_Low_Bound .. Project_Node_High_Bound;
103   --  The index of table Tree_Private_Part.Project_Nodes
104
105   Empty_Node : constant Project_Node_Id := Project_Node_Low_Bound;
106   --  Designates no node in table Project_Nodes
107
108   First_Node_Id : constant Project_Node_Id := Project_Node_Low_Bound + 1;
109
110   subtype Variable_Node_Id is Project_Node_Id;
111   --  Used to designate a node whose expected kind is one of
112   --  N_Typed_Variable_Declaration, N_Variable_Declaration or
113   --  N_Variable_Reference.
114
115   subtype Package_Declaration_Id is Project_Node_Id;
116   --  Used to designate a node whose expected kind is N_Project_Declaration
117
118   type Project_Node_Kind is
119     (N_Project,
120      N_With_Clause,
121      N_Project_Declaration,
122      N_Declarative_Item,
123      N_Package_Declaration,
124      N_String_Type_Declaration,
125      N_Literal_String,
126      N_Attribute_Declaration,
127      N_Typed_Variable_Declaration,
128      N_Variable_Declaration,
129      N_Expression,
130      N_Term,
131      N_Literal_String_List,
132      N_Variable_Reference,
133      N_External_Value,
134      N_Attribute_Reference,
135      N_Case_Construction,
136      N_Case_Item,
137      N_Comment_Zones,
138      N_Comment);
139   --  Each node in the tree is of a Project_Node_Kind. For the signification
140   --  of the fields in each node of Project_Node_Kind, look at package
141   --  Tree_Private_Part.
142
143   function Present (Node : Project_Node_Id) return Boolean;
144   pragma Inline (Present);
145   --  Return True if Node /= Empty_Node
146
147   function No (Node : Project_Node_Id) return Boolean;
148   pragma Inline (No);
149   --  Return True if Node = Empty_Node
150
151   procedure Initialize (Tree : Project_Node_Tree_Ref);
152   --  Initialize the Project File tree: empty the Project_Nodes table
153   --  and reset the Projects_Htable.
154
155   function Default_Project_Node
156     (In_Tree       : Project_Node_Tree_Ref;
157      Of_Kind       : Project_Node_Kind;
158      And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id;
159   --  Returns a Project_Node_Record with the specified Kind and Expr_Kind. All
160   --  the other components have default nil values.
161   --  To create a node for a project itself, see Create_Project below instead
162
163   function Hash (N : Project_Node_Id) return Header_Num;
164   --  Used for hash tables where the key is a Project_Node_Id
165
166   function Imported_Or_Extended_Project_Of
167     (Project   : Project_Node_Id;
168      In_Tree   : Project_Node_Tree_Ref;
169      With_Name : Name_Id) return Project_Node_Id;
170   --  Return the node of a project imported or extended by project Project and
171   --  whose name is With_Name. Return Empty_Node if there is no such project.
172
173   --------------
174   -- Comments --
175   --------------
176
177   type Comment_State is private;
178   --  A type to store the values of several global variables related to
179   --  comments.
180
181   procedure Save (S : out Comment_State);
182   --  Save in variable S the comment state. Called before scanning a new
183   --  project file.
184
185   procedure Restore_And_Free (S : in out Comment_State);
186   --  Restore the comment state to a previously saved value. Called after
187   --  scanning a project file. Frees the memory occupied by S
188
189   procedure Reset_State;
190   --  Set the comment state to its initial value. Called before scanning a
191   --  new project file.
192
193   function There_Are_Unkept_Comments return Boolean;
194   --  Indicates that some of the comments in a project file could not be
195   --  stored in the parse tree.
196
197   procedure Set_Previous_Line_Node (To : Project_Node_Id);
198   --  Indicate the node on the previous line. If there are comments
199   --  immediately following this line, then they should be associated with
200   --  this node.
201
202   procedure Set_Previous_End_Node (To : Project_Node_Id);
203   --  Indicate that on the previous line the "end" belongs to node To.
204   --  If there are comments immediately following this "end" line, they
205   --  should be associated with this node.
206
207   procedure Set_End_Of_Line (To : Project_Node_Id);
208   --  Indicate the node on the current line. If there is an end of line
209   --  comment, then it should be associated with this node.
210
211   procedure Set_Next_End_Node (To : Project_Node_Id);
212   --  Put node To on the top of the end node stack. When an END line is found
213   --  with this node on the top of the end node stack, the comments, if any,
214   --  immediately preceding this "end" line will be associated with this node.
215
216   procedure Remove_Next_End_Node;
217   --  Remove the top of the end node stack
218
219   ------------------------
220   -- Comment Processing --
221   ------------------------
222
223   type Comment_Data is record
224      Value                     : Name_Id := No_Name;
225      Follows_Empty_Line        : Boolean := False;
226      Is_Followed_By_Empty_Line : Boolean := False;
227   end record;
228   --  Component type for Comments Table below
229
230   package Comments is new Table.Table
231     (Table_Component_Type => Comment_Data,
232      Table_Index_Type     => Natural,
233      Table_Low_Bound      => 1,
234      Table_Initial        => 10,
235      Table_Increment      => 100,
236      Table_Name           => "Prj.Tree.Comments");
237   --  A table to store the comments that may be stored is the tree
238
239   procedure Scan (In_Tree : Project_Node_Tree_Ref);
240   --  Scan the tokens and accumulate comments
241
242   type Comment_Location is
243     (Before, After, Before_End, After_End, End_Of_Line);
244   --  Used in call to Add_Comments below
245
246   procedure Add_Comments
247     (To      : Project_Node_Id;
248      In_Tree : Project_Node_Tree_Ref;
249      Where   : Comment_Location);
250   --  Add comments to this node
251
252   ----------------------
253   -- Access Functions --
254   ----------------------
255
256   --  The following query functions are part of the abstract interface
257   --  of the Project File tree. They provide access to fields of a project.
258
259   --  The access functions should be called only with valid arguments.
260   --  For each function the condition of validity is specified. If an access
261   --  function is called with invalid arguments, then exception
262   --  Assertion_Error is raised if assertions are enabled, otherwise the
263   --  behaviour is not defined and may result in a crash.
264
265   function Name_Of
266     (Node    : Project_Node_Id;
267      In_Tree : Project_Node_Tree_Ref) return Name_Id;
268   pragma Inline (Name_Of);
269   --  Valid for all non empty nodes. May return No_Name for nodes that have
270   --  no names.
271
272   function Kind_Of
273     (Node    : Project_Node_Id;
274      In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind;
275   pragma Inline (Kind_Of);
276   --  Valid for all non empty nodes
277
278   function Location_Of
279     (Node    : Project_Node_Id;
280      In_Tree : Project_Node_Tree_Ref) return Source_Ptr;
281   pragma Inline (Location_Of);
282   --  Valid for all non empty nodes
283
284   function First_Comment_After
285     (Node    : Project_Node_Id;
286      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
287   --  Valid only for N_Comment_Zones nodes
288
289   function First_Comment_After_End
290     (Node    : Project_Node_Id;
291      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
292   --  Valid only for N_Comment_Zones nodes
293
294   function First_Comment_Before
295     (Node    : Project_Node_Id;
296      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
297   --  Valid only for N_Comment_Zones nodes
298
299   function First_Comment_Before_End
300     (Node    : Project_Node_Id;
301      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
302   --  Valid only for N_Comment_Zones nodes
303
304   function Next_Comment
305     (Node    : Project_Node_Id;
306      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
307   --  Valid only for N_Comment nodes
308
309   function End_Of_Line_Comment
310     (Node    : Project_Node_Id;
311      In_Tree : Project_Node_Tree_Ref) return Name_Id;
312   --  Valid only for non empty nodes
313
314   function Follows_Empty_Line
315     (Node    : Project_Node_Id;
316      In_Tree : Project_Node_Tree_Ref) return Boolean;
317   --  Valid only for N_Comment nodes
318
319   function Is_Followed_By_Empty_Line
320     (Node    : Project_Node_Id;
321      In_Tree : Project_Node_Tree_Ref) return Boolean;
322   --  Valid only for N_Comment nodes
323
324   function Parent_Project_Of
325     (Node    : Project_Node_Id;
326      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
327   pragma Inline (Parent_Project_Of);
328   --  Valid only for N_Project nodes
329
330   function Project_File_Includes_Unkept_Comments
331     (Node    : Project_Node_Id;
332      In_Tree : Project_Node_Tree_Ref) return Boolean;
333   --  Valid only for N_Project nodes
334
335   function Directory_Of
336     (Node    : Project_Node_Id;
337      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
338   pragma Inline (Directory_Of);
339   --  Returns the directory that contains the project file. This always ends
340   --  with a directory separator. Only valid for N_Project nodes.
341
342   function Expression_Kind_Of
343     (Node    : Project_Node_Id;
344      In_Tree : Project_Node_Tree_Ref) return Variable_Kind;
345   pragma Inline (Expression_Kind_Of);
346   --  Only valid for N_Literal_String, N_Attribute_Declaration,
347   --  N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression,
348   --  N_Term, N_Variable_Reference, N_Attribute_Reference nodes or
349   --  N_External_Value.
350
351   function Is_Extending_All
352     (Node    : Project_Node_Id;
353      In_Tree : Project_Node_Tree_Ref) return Boolean;
354   pragma Inline (Is_Extending_All);
355   --  Only valid for N_Project and N_With_Clause
356
357   function Is_Not_Last_In_List
358     (Node    : Project_Node_Id;
359      In_Tree : Project_Node_Tree_Ref) return Boolean;
360   pragma Inline (Is_Not_Last_In_List);
361   --  Only valid for N_With_Clause
362
363   function First_Variable_Of
364     (Node    : Project_Node_Id;
365      In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id;
366   pragma Inline (First_Variable_Of);
367   --  Only valid for N_Project or N_Package_Declaration nodes
368
369   function First_Package_Of
370     (Node    : Project_Node_Id;
371      In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id;
372   pragma Inline (First_Package_Of);
373   --  Only valid for N_Project nodes
374
375   function Package_Id_Of
376     (Node    : Project_Node_Id;
377      In_Tree : Project_Node_Tree_Ref) return Package_Node_Id;
378   pragma Inline (Package_Id_Of);
379   --  Only valid for N_Package_Declaration nodes
380
381   function Path_Name_Of
382     (Node    : Project_Node_Id;
383      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
384   pragma Inline (Path_Name_Of);
385   --  Only valid for N_Project and N_With_Clause nodes
386
387   function String_Value_Of
388     (Node    : Project_Node_Id;
389      In_Tree : Project_Node_Tree_Ref) return Name_Id;
390   pragma Inline (String_Value_Of);
391   --  Only valid for N_With_Clause, N_Literal_String nodes or N_Comment.
392   --  For a N_With_Clause created automatically for a virtual extending
393   --  project, No_Name is returned.
394
395   function Source_Index_Of
396     (Node    : Project_Node_Id;
397      In_Tree : Project_Node_Tree_Ref) return Int;
398   pragma Inline (Source_Index_Of);
399   --  Only valid for N_Literal_String and N_Attribute_Declaration nodes
400
401   function First_With_Clause_Of
402     (Node    : Project_Node_Id;
403      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
404   pragma Inline (First_With_Clause_Of);
405   --  Only valid for N_Project nodes
406
407   function Project_Declaration_Of
408     (Node    : Project_Node_Id;
409      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
410   pragma Inline (Project_Declaration_Of);
411   --  Only valid for N_Project nodes
412
413   function Project_Qualifier_Of
414     (Node    : Project_Node_Id;
415      In_Tree : Project_Node_Tree_Ref) return Project_Qualifier;
416   pragma Inline (Project_Qualifier_Of);
417   --  Only valid for N_Project nodes
418
419   function Extending_Project_Of
420     (Node    : Project_Node_Id;
421      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
422   pragma Inline (Extending_Project_Of);
423   --  Only valid for N_Project_Declaration nodes
424
425   function First_String_Type_Of
426     (Node    : Project_Node_Id;
427      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
428   pragma Inline (First_String_Type_Of);
429   --  Only valid for N_Project nodes
430
431   function Extended_Project_Path_Of
432     (Node    : Project_Node_Id;
433      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
434   pragma Inline (Extended_Project_Path_Of);
435   --  Only valid for N_With_Clause nodes
436
437   function Project_Node_Of
438     (Node    : Project_Node_Id;
439      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
440   pragma Inline (Project_Node_Of);
441   --  Only valid for N_With_Clause, N_Variable_Reference and
442   --  N_Attribute_Reference nodes.
443
444   function Non_Limited_Project_Node_Of
445     (Node    : Project_Node_Id;
446      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
447   pragma Inline (Non_Limited_Project_Node_Of);
448   --  Only valid for N_With_Clause nodes. Returns Empty_Node for limited
449   --  imported project files, otherwise returns the same result as
450   --  Project_Node_Of.
451
452   function Next_With_Clause_Of
453     (Node    : Project_Node_Id;
454      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
455   pragma Inline (Next_With_Clause_Of);
456   --  Only valid for N_With_Clause nodes
457
458   function First_Declarative_Item_Of
459     (Node    : Project_Node_Id;
460      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
461   pragma Inline (First_Declarative_Item_Of);
462   --  Only valid for N_Project_Declaration, N_Case_Item and
463   --  N_Package_Declaration.
464
465   function Extended_Project_Of
466     (Node    : Project_Node_Id;
467      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
468   pragma Inline (Extended_Project_Of);
469   --  Only valid for N_Project_Declaration nodes
470
471   function Current_Item_Node
472     (Node    : Project_Node_Id;
473      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
474   pragma Inline (Current_Item_Node);
475   --  Only valid for N_Declarative_Item nodes
476
477   function Next_Declarative_Item
478     (Node    : Project_Node_Id;
479      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
480   pragma Inline (Next_Declarative_Item);
481   --  Only valid for N_Declarative_Item node
482
483   function Project_Of_Renamed_Package_Of
484     (Node    : Project_Node_Id;
485      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
486   pragma Inline (Project_Of_Renamed_Package_Of);
487   --  Only valid for N_Package_Declaration nodes. May return Empty_Node.
488
489   function Next_Package_In_Project
490     (Node    : Project_Node_Id;
491      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
492   pragma Inline (Next_Package_In_Project);
493   --  Only valid for N_Package_Declaration nodes
494
495   function First_Literal_String
496     (Node    : Project_Node_Id;
497      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
498   pragma Inline (First_Literal_String);
499   --  Only valid for N_String_Type_Declaration nodes
500
501   function Next_String_Type
502     (Node    : Project_Node_Id;
503      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
504   pragma Inline (Next_String_Type);
505   --  Only valid for N_String_Type_Declaration nodes
506
507   function Next_Literal_String
508     (Node    : Project_Node_Id;
509      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
510   pragma Inline (Next_Literal_String);
511   --  Only valid for N_Literal_String nodes
512
513   function Expression_Of
514     (Node    : Project_Node_Id;
515      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
516   pragma Inline (Expression_Of);
517   --  Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration
518   --  or N_Variable_Declaration nodes
519
520   function Associative_Project_Of
521     (Node    : Project_Node_Id;
522      In_Tree : Project_Node_Tree_Ref)
523      return  Project_Node_Id;
524   pragma Inline (Associative_Project_Of);
525   --  Only valid for N_Attribute_Declaration nodes
526
527   function Associative_Package_Of
528     (Node    : Project_Node_Id;
529      In_Tree : Project_Node_Tree_Ref)
530      return  Project_Node_Id;
531   pragma Inline (Associative_Package_Of);
532   --  Only valid for N_Attribute_Declaration nodes
533
534   function Value_Is_Valid
535     (For_Typed_Variable : Project_Node_Id;
536      In_Tree            : Project_Node_Tree_Ref;
537      Value              : Name_Id) return Boolean;
538   pragma Inline (Value_Is_Valid);
539   --  Only valid for N_Typed_Variable_Declaration. Returns True if Value is
540   --  in the list of allowed strings for For_Typed_Variable. False otherwise.
541
542   function Associative_Array_Index_Of
543     (Node    : Project_Node_Id;
544      In_Tree : Project_Node_Tree_Ref) return Name_Id;
545   pragma Inline (Associative_Array_Index_Of);
546   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference.
547   --  Returns No_Name for non associative array attributes.
548
549   function Next_Variable
550     (Node    : Project_Node_Id;
551      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
552   pragma Inline (Next_Variable);
553   --  Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration
554   --  nodes.
555
556   function First_Term
557     (Node    : Project_Node_Id;
558      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
559   pragma Inline (First_Term);
560   --  Only valid for N_Expression nodes
561
562   function Next_Expression_In_List
563     (Node    : Project_Node_Id;
564      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
565   pragma Inline (Next_Expression_In_List);
566   --  Only valid for N_Expression nodes
567
568   function Current_Term
569     (Node    : Project_Node_Id;
570      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
571   pragma Inline (Current_Term);
572   --  Only valid for N_Term nodes
573
574   function Next_Term
575     (Node    : Project_Node_Id;
576      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
577   pragma Inline (Next_Term);
578   --  Only valid for N_Term nodes
579
580   function First_Expression_In_List
581     (Node    : Project_Node_Id;
582      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
583   pragma Inline (First_Expression_In_List);
584   --  Only valid for N_Literal_String_List nodes
585
586   function Package_Node_Of
587     (Node    : Project_Node_Id;
588      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
589   pragma Inline (Package_Node_Of);
590   --  Only valid for N_Variable_Reference or N_Attribute_Reference nodes.
591   --  May return Empty_Node.
592
593   function String_Type_Of
594     (Node    : Project_Node_Id;
595      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
596   pragma Inline (String_Type_Of);
597   --  Only valid for N_Variable_Reference or N_Typed_Variable_Declaration
598   --  nodes.
599
600   function External_Reference_Of
601     (Node    : Project_Node_Id;
602      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
603   pragma Inline (External_Reference_Of);
604   --  Only valid for N_External_Value nodes
605
606   function External_Default_Of
607     (Node    : Project_Node_Id;
608      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
609   pragma Inline (External_Default_Of);
610   --  Only valid for N_External_Value nodes
611
612   function Case_Variable_Reference_Of
613     (Node    : Project_Node_Id;
614      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
615   pragma Inline (Case_Variable_Reference_Of);
616   --  Only valid for N_Case_Construction nodes
617
618   function First_Case_Item_Of
619     (Node    : Project_Node_Id;
620      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
621   pragma Inline (First_Case_Item_Of);
622   --  Only valid for N_Case_Construction nodes
623
624   function First_Choice_Of
625     (Node    : Project_Node_Id;
626      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
627   pragma Inline (First_Choice_Of);
628   --  Only valid for N_Case_Item nodes. Return the first choice in a
629   --  N_Case_Item, or Empty_Node if this is when others.
630
631   function Next_Case_Item
632     (Node    : Project_Node_Id;
633      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
634   pragma Inline (Next_Case_Item);
635   --  Only valid for N_Case_Item nodes
636
637   function Case_Insensitive
638     (Node    : Project_Node_Id;
639      In_Tree : Project_Node_Tree_Ref) return Boolean;
640   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes
641
642   -----------------------
643   -- Create procedures --
644   -----------------------
645   --  The following procedures are used to edit a project file tree. They are
646   --  slightly higher-level than the Set_* procedures below
647
648   function Create_Project
649     (In_Tree        : Project_Node_Tree_Ref;
650      Name           : Name_Id;
651      Full_Path      : Path_Name_Type;
652      Is_Config_File : Boolean := False) return Project_Node_Id;
653   --  Create a new node for a project and register it in the tree so that it
654   --  can be retrieved later on.
655
656   function Create_Package
657     (Tree    : Project_Node_Tree_Ref;
658      Project : Project_Node_Id;
659      Pkg     : String) return Project_Node_Id;
660   --  Create a new package in Project. If the package already exists, it is
661   --  returned. The name of the package *must* be lower-cases, or none of its
662   --  attributes will be recognized.
663
664   function Create_Attribute
665     (Tree       : Project_Node_Tree_Ref;
666      Prj_Or_Pkg : Project_Node_Id;
667      Name       : Name_Id;
668      Index_Name : Name_Id         := No_Name;
669      Kind       : Variable_Kind   := List;
670      At_Index   : Integer         := 0;
671      Value      : Project_Node_Id := Empty_Node) return Project_Node_Id;
672   --  Create a new attribute. The new declaration is added at the end of the
673   --  declarative item list for Prj_Or_Pkg (a project or a package), but
674   --  before any package declaration). No addition is done if Prj_Or_Pkg is
675   --  Empty_Node. If Index_Name is not "", then if creates an attribute value
676   --  for a specific index. At_Index is used for the " at <idx>" in the naming
677   --  exceptions.
678   --
679   --  To set the value of the attribute, either provide a value for Value, or
680   --  use Set_Expression_Of to set the value of the attribute (in which case
681   --  Enclose_In_Expression might be useful). The former is recommended since
682   --  it will more correctly handle cases where the index needs to be set on
683   --  the expression rather than on the index of the attribute (i.e. 'for
684   --  Specification ("unit") use "file" at 3', versus 'for Executable ("file"
685   --  at 3) use "name"'). Value must be a N_String_Literal if an index will be
686   --  added to it.
687
688   function Create_Literal_String
689     (Str  : Namet.Name_Id;
690      Tree : Project_Node_Tree_Ref) return Project_Node_Id;
691   --  Create a literal string whose value is Str
692
693   procedure Add_At_End
694     (Tree                  : Project_Node_Tree_Ref;
695      Parent                : Project_Node_Id;
696      Expr                  : Project_Node_Id;
697      Add_Before_First_Pkg  : Boolean := False;
698      Add_Before_First_Case : Boolean := False);
699   --  Add a new declarative item in the list in Parent. This new declarative
700   --  item will contain Expr (unless Expr is already a declarative item, in
701   --  which case it is added directly to the list). The new item is inserted
702   --  at the end of the list, unless Add_Before_First_Pkg is True. In the
703   --  latter case, it is added just before the first case construction is
704   --  seen, or before the first package (this assumes that all packages are
705   --  found at the end of the project, which isn't true in the general case
706   --  unless you have normalized the project to match this description).
707
708   function Enclose_In_Expression
709     (Node : Project_Node_Id;
710      Tree : Project_Node_Tree_Ref) return Project_Node_Id;
711   --  Enclose the Node inside a N_Expression node, and return this expression.
712   --  This does nothing if Node is already a N_Expression.
713
714   --------------------
715   -- Set Procedures --
716   --------------------
717
718   --  The following procedures are part of the abstract interface of the
719   --  Project File tree.
720
721   --  Foe each Set_* procedure the condition of validity is specified. If an
722   --  access function is called with invalid arguments, then exception
723   --  Assertion_Error is raised if assertions are enabled, otherwise the
724   --  behaviour is not defined and may result in a crash.
725
726   --  These are very low-level, and manipulate the tree itself directly. You
727   --  should look at the Create_* procedure instead if you want to use higher
728   --  level constructs
729
730   procedure Set_Name_Of
731     (Node    : Project_Node_Id;
732      In_Tree : Project_Node_Tree_Ref;
733      To      : Name_Id);
734   pragma Inline (Set_Name_Of);
735   --  Valid for all non empty nodes.
736
737   procedure Set_Kind_Of
738     (Node    : Project_Node_Id;
739      In_Tree : Project_Node_Tree_Ref;
740      To      : Project_Node_Kind);
741   pragma Inline (Set_Kind_Of);
742   --  Valid for all non empty nodes
743
744   procedure Set_Location_Of
745     (Node    : Project_Node_Id;
746      In_Tree : Project_Node_Tree_Ref;
747      To      : Source_Ptr);
748   pragma Inline (Set_Location_Of);
749   --  Valid for all non empty nodes
750
751   procedure Set_First_Comment_After
752     (Node    : Project_Node_Id;
753      In_Tree : Project_Node_Tree_Ref;
754      To      : Project_Node_Id);
755   pragma Inline (Set_First_Comment_After);
756   --  Valid only for N_Comment_Zones nodes
757
758   procedure Set_First_Comment_After_End
759     (Node    : Project_Node_Id;
760      In_Tree : Project_Node_Tree_Ref;
761      To      : Project_Node_Id);
762   pragma Inline (Set_First_Comment_After_End);
763   --  Valid only for N_Comment_Zones nodes
764
765   procedure Set_First_Comment_Before
766     (Node    : Project_Node_Id;
767      In_Tree : Project_Node_Tree_Ref;
768      To      : Project_Node_Id);
769   pragma Inline (Set_First_Comment_Before);
770   --  Valid only for N_Comment_Zones nodes
771
772   procedure Set_First_Comment_Before_End
773     (Node    : Project_Node_Id;
774      In_Tree : Project_Node_Tree_Ref;
775      To      : Project_Node_Id);
776   pragma Inline (Set_First_Comment_Before_End);
777   --  Valid only for N_Comment_Zones nodes
778
779   procedure Set_Next_Comment
780     (Node    : Project_Node_Id;
781      In_Tree : Project_Node_Tree_Ref;
782      To      : Project_Node_Id);
783   pragma Inline (Set_Next_Comment);
784   --  Valid only for N_Comment nodes
785
786   procedure Set_Parent_Project_Of
787     (Node    : Project_Node_Id;
788      In_Tree : Project_Node_Tree_Ref;
789      To      : Project_Node_Id);
790   --  Valid only for N_Project nodes
791
792   procedure Set_Project_File_Includes_Unkept_Comments
793     (Node    : Project_Node_Id;
794      In_Tree : Project_Node_Tree_Ref;
795      To      : Boolean);
796   --  Valid only for N_Project nodes
797
798   procedure Set_Directory_Of
799     (Node    : Project_Node_Id;
800      In_Tree : Project_Node_Tree_Ref;
801      To      : Path_Name_Type);
802   pragma Inline (Set_Directory_Of);
803   --  Valid only for N_Project nodes
804
805   procedure Set_Expression_Kind_Of
806     (Node    : Project_Node_Id;
807      In_Tree : Project_Node_Tree_Ref;
808      To      : Variable_Kind);
809   pragma Inline (Set_Expression_Kind_Of);
810   --  Only valid for N_Literal_String, N_Attribute_Declaration,
811   --  N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression,
812   --  N_Term, N_Variable_Reference, N_Attribute_Reference or N_External_Value
813   --  nodes.
814
815   procedure Set_Is_Extending_All
816     (Node    : Project_Node_Id;
817      In_Tree : Project_Node_Tree_Ref);
818   pragma Inline (Set_Is_Extending_All);
819   --  Only valid for N_Project and N_With_Clause
820
821   procedure Set_Is_Not_Last_In_List
822     (Node    : Project_Node_Id;
823      In_Tree : Project_Node_Tree_Ref);
824   pragma Inline (Set_Is_Not_Last_In_List);
825   --  Only valid for N_With_Clause
826
827   procedure Set_First_Variable_Of
828     (Node    : Project_Node_Id;
829      In_Tree : Project_Node_Tree_Ref;
830      To      : Variable_Node_Id);
831   pragma Inline (Set_First_Variable_Of);
832   --  Only valid for N_Project or N_Package_Declaration nodes
833
834   procedure Set_First_Package_Of
835     (Node    : Project_Node_Id;
836      In_Tree : Project_Node_Tree_Ref;
837      To      : Package_Declaration_Id);
838   pragma Inline (Set_First_Package_Of);
839   --  Only valid for N_Project nodes
840
841   procedure Set_Package_Id_Of
842     (Node    : Project_Node_Id;
843      In_Tree : Project_Node_Tree_Ref;
844      To      : Package_Node_Id);
845   pragma Inline (Set_Package_Id_Of);
846   --  Only valid for N_Package_Declaration nodes
847
848   procedure Set_Path_Name_Of
849     (Node    : Project_Node_Id;
850      In_Tree : Project_Node_Tree_Ref;
851      To      : Path_Name_Type);
852   pragma Inline (Set_Path_Name_Of);
853   --  Only valid for N_Project and N_With_Clause nodes
854
855   procedure Set_String_Value_Of
856     (Node    : Project_Node_Id;
857      In_Tree : Project_Node_Tree_Ref;
858      To      : Name_Id);
859   pragma Inline (Set_String_Value_Of);
860   --  Only valid for N_With_Clause, N_Literal_String nodes or N_Comment.
861
862   procedure Set_Source_Index_Of
863     (Node    : Project_Node_Id;
864      In_Tree : Project_Node_Tree_Ref;
865      To      : Int);
866   pragma Inline (Set_Source_Index_Of);
867   --  Only valid for N_Literal_String and N_Attribute_Declaration nodes. For
868   --  N_Literal_String, set the source index of the literal string. For
869   --  N_Attribute_Declaration, set the source index of the index of the
870   --  associative array element.
871
872   procedure Set_First_With_Clause_Of
873     (Node    : Project_Node_Id;
874      In_Tree : Project_Node_Tree_Ref;
875      To      : Project_Node_Id);
876   pragma Inline (Set_First_With_Clause_Of);
877   --  Only valid for N_Project nodes
878
879   procedure Set_Project_Declaration_Of
880     (Node    : Project_Node_Id;
881      In_Tree : Project_Node_Tree_Ref;
882      To      : Project_Node_Id);
883   pragma Inline (Set_Project_Declaration_Of);
884   --  Only valid for N_Project nodes
885
886   procedure Set_Project_Qualifier_Of
887     (Node    : Project_Node_Id;
888      In_Tree : Project_Node_Tree_Ref;
889      To      : Project_Qualifier);
890   pragma Inline (Set_Project_Qualifier_Of);
891   --  Only valid for N_Project nodes
892
893   procedure Set_Extending_Project_Of
894     (Node    : Project_Node_Id;
895      In_Tree : Project_Node_Tree_Ref;
896      To      : Project_Node_Id);
897   pragma Inline (Set_Extending_Project_Of);
898   --  Only valid for N_Project_Declaration nodes
899
900   procedure Set_First_String_Type_Of
901     (Node    : Project_Node_Id;
902      In_Tree : Project_Node_Tree_Ref;
903      To      : Project_Node_Id);
904   pragma Inline (Set_First_String_Type_Of);
905   --  Only valid for N_Project nodes
906
907   procedure Set_Extended_Project_Path_Of
908     (Node    : Project_Node_Id;
909      In_Tree : Project_Node_Tree_Ref;
910      To      : Path_Name_Type);
911   pragma Inline (Set_Extended_Project_Path_Of);
912   --  Only valid for N_With_Clause nodes
913
914   procedure Set_Project_Node_Of
915     (Node         : Project_Node_Id;
916      In_Tree      : Project_Node_Tree_Ref;
917      To           : Project_Node_Id;
918      Limited_With : Boolean := False);
919   pragma Inline (Set_Project_Node_Of);
920   --  Only valid for N_With_Clause, N_Variable_Reference and
921   --  N_Attribute_Reference nodes.
922
923   procedure Set_Next_With_Clause_Of
924     (Node    : Project_Node_Id;
925      In_Tree : Project_Node_Tree_Ref;
926      To      : Project_Node_Id);
927   pragma Inline (Set_Next_With_Clause_Of);
928   --  Only valid for N_With_Clause nodes
929
930   procedure Set_First_Declarative_Item_Of
931     (Node    : Project_Node_Id;
932      In_Tree : Project_Node_Tree_Ref;
933      To      : Project_Node_Id);
934   pragma Inline (Set_First_Declarative_Item_Of);
935   --  Only valid for N_Project_Declaration, N_Case_Item and
936   --  N_Package_Declaration.
937
938   procedure Set_Extended_Project_Of
939     (Node    : Project_Node_Id;
940      In_Tree : Project_Node_Tree_Ref;
941      To      : Project_Node_Id);
942   pragma Inline (Set_Extended_Project_Of);
943   --  Only valid for N_Project_Declaration nodes
944
945   procedure Set_Current_Item_Node
946     (Node    : Project_Node_Id;
947      In_Tree : Project_Node_Tree_Ref;
948      To      : Project_Node_Id);
949   pragma Inline (Set_Current_Item_Node);
950   --  Only valid for N_Declarative_Item nodes
951
952   procedure Set_Next_Declarative_Item
953     (Node    : Project_Node_Id;
954      In_Tree : Project_Node_Tree_Ref;
955      To      : Project_Node_Id);
956   pragma Inline (Set_Next_Declarative_Item);
957   --  Only valid for N_Declarative_Item node
958
959   procedure Set_Project_Of_Renamed_Package_Of
960     (Node    : Project_Node_Id;
961      In_Tree : Project_Node_Tree_Ref;
962      To      : Project_Node_Id);
963   pragma Inline (Set_Project_Of_Renamed_Package_Of);
964   --  Only valid for N_Package_Declaration nodes.
965
966   procedure Set_Next_Package_In_Project
967     (Node    : Project_Node_Id;
968      In_Tree : Project_Node_Tree_Ref;
969      To      : Project_Node_Id);
970   pragma Inline (Set_Next_Package_In_Project);
971   --  Only valid for N_Package_Declaration nodes
972
973   procedure Set_First_Literal_String
974     (Node    : Project_Node_Id;
975      In_Tree : Project_Node_Tree_Ref;
976      To      : Project_Node_Id);
977   pragma Inline (Set_First_Literal_String);
978   --  Only valid for N_String_Type_Declaration nodes
979
980   procedure Set_Next_String_Type
981     (Node    : Project_Node_Id;
982      In_Tree : Project_Node_Tree_Ref;
983      To      : Project_Node_Id);
984   pragma Inline (Set_Next_String_Type);
985   --  Only valid for N_String_Type_Declaration nodes
986
987   procedure Set_Next_Literal_String
988     (Node    : Project_Node_Id;
989      In_Tree : Project_Node_Tree_Ref;
990      To      : Project_Node_Id);
991   pragma Inline (Set_Next_Literal_String);
992   --  Only valid for N_Literal_String nodes
993
994   procedure Set_Expression_Of
995     (Node    : Project_Node_Id;
996      In_Tree : Project_Node_Tree_Ref;
997      To      : Project_Node_Id);
998   pragma Inline (Set_Expression_Of);
999   --  Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration
1000   --  or N_Variable_Declaration nodes
1001
1002   procedure Set_Associative_Project_Of
1003     (Node    : Project_Node_Id;
1004      In_Tree : Project_Node_Tree_Ref;
1005      To      : Project_Node_Id);
1006   pragma Inline (Set_Associative_Project_Of);
1007   --  Only valid for N_Attribute_Declaration nodes
1008
1009   procedure Set_Associative_Package_Of
1010     (Node    : Project_Node_Id;
1011      In_Tree : Project_Node_Tree_Ref;
1012      To      : Project_Node_Id);
1013   pragma Inline (Set_Associative_Package_Of);
1014   --  Only valid for N_Attribute_Declaration nodes
1015
1016   procedure Set_Associative_Array_Index_Of
1017     (Node    : Project_Node_Id;
1018      In_Tree : Project_Node_Tree_Ref;
1019      To      : Name_Id);
1020   pragma Inline (Set_Associative_Array_Index_Of);
1021   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference.
1022
1023   procedure Set_Next_Variable
1024     (Node    : Project_Node_Id;
1025      In_Tree : Project_Node_Tree_Ref;
1026      To      : Project_Node_Id);
1027   pragma Inline (Set_Next_Variable);
1028   --  Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration
1029   --  nodes.
1030
1031   procedure Set_First_Term
1032     (Node    : Project_Node_Id;
1033      In_Tree : Project_Node_Tree_Ref;
1034      To      : Project_Node_Id);
1035   pragma Inline (Set_First_Term);
1036   --  Only valid for N_Expression nodes
1037
1038   procedure Set_Next_Expression_In_List
1039     (Node    : Project_Node_Id;
1040      In_Tree : Project_Node_Tree_Ref;
1041      To      : Project_Node_Id);
1042   pragma Inline (Set_Next_Expression_In_List);
1043   --  Only valid for N_Expression nodes
1044
1045   procedure Set_Current_Term
1046     (Node    : Project_Node_Id;
1047      In_Tree : Project_Node_Tree_Ref;
1048      To      : Project_Node_Id);
1049   pragma Inline (Set_Current_Term);
1050   --  Only valid for N_Term nodes
1051
1052   procedure Set_Next_Term
1053     (Node    : Project_Node_Id;
1054      In_Tree : Project_Node_Tree_Ref;
1055      To      : Project_Node_Id);
1056   pragma Inline (Set_Next_Term);
1057   --  Only valid for N_Term nodes
1058
1059   procedure Set_First_Expression_In_List
1060     (Node    : Project_Node_Id;
1061      In_Tree : Project_Node_Tree_Ref;
1062      To      : Project_Node_Id);
1063   pragma Inline (Set_First_Expression_In_List);
1064   --  Only valid for N_Literal_String_List nodes
1065
1066   procedure Set_Package_Node_Of
1067     (Node    : Project_Node_Id;
1068      In_Tree : Project_Node_Tree_Ref;
1069      To      : Project_Node_Id);
1070   pragma Inline (Set_Package_Node_Of);
1071   --  Only valid for N_Variable_Reference or N_Attribute_Reference nodes.
1072
1073   procedure Set_String_Type_Of
1074     (Node    : Project_Node_Id;
1075      In_Tree : Project_Node_Tree_Ref;
1076      To      : Project_Node_Id);
1077   pragma Inline (Set_String_Type_Of);
1078   --  Only valid for N_Variable_Reference or N_Typed_Variable_Declaration
1079   --  nodes.
1080
1081   procedure Set_External_Reference_Of
1082     (Node    : Project_Node_Id;
1083      In_Tree : Project_Node_Tree_Ref;
1084      To      : Project_Node_Id);
1085   pragma Inline (Set_External_Reference_Of);
1086   --  Only valid for N_External_Value nodes
1087
1088   procedure Set_External_Default_Of
1089     (Node    : Project_Node_Id;
1090      In_Tree : Project_Node_Tree_Ref;
1091      To      : Project_Node_Id);
1092   pragma Inline (Set_External_Default_Of);
1093   --  Only valid for N_External_Value nodes
1094
1095   procedure Set_Case_Variable_Reference_Of
1096     (Node    : Project_Node_Id;
1097      In_Tree : Project_Node_Tree_Ref;
1098      To      : Project_Node_Id);
1099   pragma Inline (Set_Case_Variable_Reference_Of);
1100   --  Only valid for N_Case_Construction nodes
1101
1102   procedure Set_First_Case_Item_Of
1103     (Node    : Project_Node_Id;
1104      In_Tree : Project_Node_Tree_Ref;
1105      To      : Project_Node_Id);
1106   pragma Inline (Set_First_Case_Item_Of);
1107   --  Only valid for N_Case_Construction nodes
1108
1109   procedure Set_First_Choice_Of
1110     (Node    : Project_Node_Id;
1111      In_Tree : Project_Node_Tree_Ref;
1112      To      : Project_Node_Id);
1113   pragma Inline (Set_First_Choice_Of);
1114   --  Only valid for N_Case_Item nodes.
1115
1116   procedure Set_Next_Case_Item
1117     (Node    : Project_Node_Id;
1118      In_Tree : Project_Node_Tree_Ref;
1119      To      : Project_Node_Id);
1120   pragma Inline (Set_Next_Case_Item);
1121   --  Only valid for N_Case_Item nodes.
1122
1123   procedure Set_Case_Insensitive
1124     (Node    : Project_Node_Id;
1125      In_Tree : Project_Node_Tree_Ref;
1126      To      : Boolean);
1127   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes
1128
1129   -------------------------------
1130   -- Restricted Access Section --
1131   -------------------------------
1132
1133   package Tree_Private_Part is
1134
1135      --  This is conceptually in the private part. However, for efficiency,
1136      --  some packages are accessing it directly.
1137
1138      type Project_Node_Record is record
1139
1140         Kind : Project_Node_Kind;
1141
1142         Qualifier : Project_Qualifier := Unspecified;
1143
1144         Location : Source_Ptr := No_Location;
1145
1146         Directory : Path_Name_Type := No_Path;
1147         --  Only for N_Project
1148
1149         Expr_Kind : Variable_Kind := Undefined;
1150         --  See below for what Project_Node_Kind it is used
1151
1152         Variables : Variable_Node_Id := Empty_Node;
1153         --  First variable in a project or a package
1154
1155         Packages : Package_Declaration_Id := Empty_Node;
1156         --  First package declaration in a project
1157
1158         Pkg_Id : Package_Node_Id := Empty_Package;
1159         --  Only used for N_Package_Declaration
1160         --
1161         --  The component Pkg_Id is an entry into the table Package_Attributes
1162         --  (in Prj.Attr). It is used to indicate all the attributes of the
1163         --  package with their characteristics.
1164         --
1165         --  The tables Prj.Attr.Attributes and Prj.Attr.Package_Attributes
1166         --  are built once and for all through a call (from Prj.Initialize)
1167         --  to procedure Prj.Attr.Initialize. It is never modified after that.
1168
1169         Name : Name_Id := No_Name;
1170         --  See below for what Project_Node_Kind it is used
1171
1172         Src_Index : Int := 0;
1173         --  Index of a unit in a multi-unit source.
1174         --  Only for some N_Attribute_Declaration and N_Literal_String.
1175
1176         Path_Name : Path_Name_Type := No_Path;
1177         --  See below for what Project_Node_Kind it is used
1178
1179         Value : Name_Id := No_Name;
1180         --  See below for what Project_Node_Kind it is used
1181
1182         Field1 : Project_Node_Id := Empty_Node;
1183         --  See below the meaning for each Project_Node_Kind
1184
1185         Field2 : Project_Node_Id := Empty_Node;
1186         --  See below the meaning for each Project_Node_Kind
1187
1188         Field3 : Project_Node_Id := Empty_Node;
1189         --  See below the meaning for each Project_Node_Kind
1190
1191         Field4 : Project_Node_Id := Empty_Node;
1192         --  See below the meaning for each Project_Node_Kind
1193
1194         Flag1 : Boolean := False;
1195         --  This flag is significant only for:
1196         --
1197         --    N_Attribute_Declaration and N_Attribute_Reference
1198         --      Indicates for an associative array attribute, that the
1199         --      index is case insensitive.
1200         --
1201         --    N_Comment
1202         --      Indicates that the comment is preceded by an empty line.
1203         --
1204         --    N_Project
1205         --      Indicates that there are comments in the project source that
1206         --      cannot be kept in the tree.
1207         --
1208         --    N_Project_Declaration
1209         --      Indicates that there are unkept comments in the project.
1210         --
1211         --    N_With_Clause
1212         --      Indicates that this is not the last with in a with clause.
1213         --      Set for "A", but not for "B" in with "B"; and with "A", "B";
1214
1215         Flag2 : Boolean := False;
1216         --  This flag is significant only for:
1217         --
1218         --    N_Project
1219         --      Indicates that the project "extends all" another project.
1220         --
1221         --    N_Comment
1222         --      Indicates that the comment is followed by an empty line.
1223         --
1224         --    N_With_Clause
1225         --      Indicates that the originally imported project is an extending
1226         --      all project.
1227
1228         Comments : Project_Node_Id := Empty_Node;
1229         --  For nodes other that N_Comment_Zones or N_Comment, designates the
1230         --  comment zones associated with the node.
1231         --
1232         --  For N_Comment_Zones, designates the comment after the "end" of
1233         --  the construct.
1234         --
1235         --  For N_Comment, designates the next comment, if any.
1236
1237      end record;
1238
1239      --  type Project_Node_Kind is
1240
1241      --   (N_Project,
1242      --    --  Name:      project name
1243      --    --  Path_Name: project path name
1244      --    --  Expr_Kind: Undefined
1245      --    --  Field1:    first with clause
1246      --    --  Field2:    project declaration
1247      --    --  Field3:    first string type
1248      --    --  Field4:    parent project, if any
1249      --    --  Value:     extended project path name (if any)
1250
1251      --    N_With_Clause,
1252      --    --  Name:      imported project name
1253      --    --  Path_Name: imported project path name
1254      --    --  Expr_Kind: Undefined
1255      --    --  Field1:    project node
1256      --    --  Field2:    next with clause
1257      --    --  Field3:    project node or empty if "limited with"
1258      --    --  Field4:    not used
1259      --    --  Value:     literal string withed
1260
1261      --    N_Project_Declaration,
1262      --    --  Name:      not used
1263      --    --  Path_Name: not used
1264      --    --  Expr_Kind: Undefined
1265      --    --  Field1:    first declarative item
1266      --    --  Field2:    extended project
1267      --    --  Field3:    extending project
1268      --    --  Field4:    not used
1269      --    --  Value:     not used
1270
1271      --    N_Declarative_Item,
1272      --    --  Name:      not used
1273      --    --  Path_Name: not used
1274      --    --  Expr_Kind: Undefined
1275      --    --  Field1:    current item node
1276      --    --  Field2:    next declarative item
1277      --    --  Field3:    not used
1278      --    --  Field4:    not used
1279      --    --  Value:     not used
1280
1281      --    N_Package_Declaration,
1282      --    --  Name:      package name
1283      --    --  Path_Name: not used
1284      --    --  Expr_Kind: Undefined
1285      --    --  Field1:    project of renamed package (if any)
1286      --    --  Field2:    first declarative item
1287      --    --  Field3:    next package in project
1288      --    --  Field4:    not used
1289      --    --  Value:     not used
1290
1291      --    N_String_Type_Declaration,
1292      --    --  Name:      type name
1293      --    --  Path_Name: not used
1294      --    --  Expr_Kind: Undefined
1295      --    --  Field1:    first literal string
1296      --    --  Field2:    next string type
1297      --    --  Field3:    not used
1298      --    --  Field4:    not used
1299      --    --  Value:     not used
1300
1301      --    N_Literal_String,
1302      --    --  Name:      not used
1303      --    --  Path_Name: not used
1304      --    --  Expr_Kind: Single
1305      --    --  Field1:    next literal string
1306      --    --  Field2:    not used
1307      --    --  Field3:    not used
1308      --    --  Field4:    not used
1309      --    --  Value:     string value
1310
1311      --    N_Attribute_Declaration,
1312      --    --  Name:      attribute name
1313      --    --  Path_Name: not used
1314      --    --  Expr_Kind: attribute kind
1315      --    --  Field1:    expression
1316      --    --  Field2:    project of full associative array
1317      --    --  Field3:    package of full associative array
1318      --    --  Field4:    not used
1319      --    --  Value:     associative array index
1320      --    --             (if an associative array element)
1321
1322      --    N_Typed_Variable_Declaration,
1323      --    --  Name:      variable name
1324      --    --  Path_Name: not used
1325      --    --  Expr_Kind: Single
1326      --    --  Field1:    expression
1327      --    --  Field2:    type of variable (N_String_Type_Declaration)
1328      --    --  Field3:    next variable
1329      --    --  Field4:    not used
1330      --    --  Value:     not used
1331
1332      --    N_Variable_Declaration,
1333      --    --  Name:      variable name
1334      --    --  Path_Name: not used
1335      --    --  Expr_Kind: variable kind
1336      --    --  Field1:    expression
1337      --    --  Field2:    not used
1338      --    --             Field3 is used for next variable, instead of Field2,
1339      --    --             so that it is the same field for
1340      --    --             N_Variable_Declaration and
1341      --    --             N_Typed_Variable_Declaration
1342      --    --  Field3:    next variable
1343      --    --  Field4:    not used
1344      --    --  Value:     not used
1345
1346      --    N_Expression,
1347      --    --  Name:      not used
1348      --    --  Path_Name: not used
1349      --    --  Expr_Kind: expression kind
1350      --    --  Field1:    first term
1351      --    --  Field2:    next expression in list
1352      --    --  Field3:    not used
1353      --    --  Value:     not used
1354
1355      --    N_Term,
1356      --    --  Name:      not used
1357      --    --  Path_Name: not used
1358      --    --  Expr_Kind: term kind
1359      --    --  Field1:    current term
1360      --    --  Field2:    next term in the expression
1361      --    --  Field3:    not used
1362      --    --  Field4:    not used
1363      --    --  Value:     not used
1364
1365      --    N_Literal_String_List,
1366      --    --  Designates a list of string expressions between brackets
1367      --    --  separated by commas. The string expressions are not necessarily
1368      --    --  literal strings.
1369      --    --  Name:      not used
1370      --    --  Path_Name: not used
1371      --    --  Expr_Kind: List
1372      --    --  Field1:    first expression
1373      --    --  Field2:    not used
1374      --    --  Field3:    not used
1375      --    --  Field4:    not used
1376      --    --  Value:     not used
1377
1378      --    N_Variable_Reference,
1379      --    --  Name:      variable name
1380      --    --  Path_Name: not used
1381      --    --  Expr_Kind: variable kind
1382      --    --  Field1:    project (if specified)
1383      --    --  Field2:    package (if specified)
1384      --    --  Field3:    type of variable (N_String_Type_Declaration), if any
1385      --    --  Field4:    not used
1386      --    --  Value:     not used
1387
1388      --    N_External_Value,
1389      --    --  Name:      not used
1390      --    --  Path_Name: not used
1391      --    --  Expr_Kind: Single
1392      --    --  Field1:    Name of the external reference (literal string)
1393      --    --  Field2:    Default (literal string)
1394      --    --  Field3:    not used
1395      --    --  Value:     not used
1396
1397      --    N_Attribute_Reference,
1398      --    --  Name:      attribute name
1399      --    --  Path_Name: not used
1400      --    --  Expr_Kind: attribute kind
1401      --    --  Field1:    project
1402      --    --  Field2:    package (if attribute of a package)
1403      --    --  Field3:    not used
1404      --    --  Field4:    not used
1405      --    --  Value:     associative array index
1406      --    --             (if an associative array element)
1407
1408      --    N_Case_Construction,
1409      --    --  Name:      not used
1410      --    --  Path_Name: not used
1411      --    --  Expr_Kind: Undefined
1412      --    --  Field1:    case variable reference
1413      --    --  Field2:    first case item
1414      --    --  Field3:    not used
1415      --    --  Field4:    not used
1416      --    --  Value:     not used
1417
1418      --    N_Case_Item
1419      --    --  Name:      not used
1420      --    --  Path_Name: not used
1421      --    --  Expr_Kind: not used
1422      --    --  Field1:    first choice (literal string), or Empty_Node
1423      --    --             for when others
1424      --    --  Field2:    first declarative item
1425      --    --  Field3:    next case item
1426      --    --  Field4:    not used
1427      --    --  Value:     not used
1428
1429      --    N_Comment_zones
1430      --    --  Name:      not used
1431      --    --  Path_Name: not used
1432      --    --  Expr_Kind: not used
1433      --    --  Field1:    comment before the construct
1434      --    --  Field2:    comment after the construct
1435      --    --  Field3:    comment before the "end" of the construct
1436      --    --  Value:     end of line comment
1437      --    --  Field4:    not used
1438      --    --  Comments:  comment after the "end" of the construct
1439
1440      --    N_Comment
1441      --    --  Name:      not used
1442      --    --  Path_Name: not used
1443      --    --  Expr_Kind: not used
1444      --    --  Field1:    not used
1445      --    --  Field2:    not used
1446      --    --  Field3:    not used
1447      --    --  Field4:    not used
1448      --    --  Value:     comment
1449      --    --  Flag1:     comment is preceded by an empty line
1450      --    --  Flag2:     comment is followed by an empty line
1451      --    --  Comments:  next comment
1452
1453      package Project_Node_Table is new
1454        GNAT.Dynamic_Tables
1455          (Table_Component_Type => Project_Node_Record,
1456           Table_Index_Type     => Project_Node_Id,
1457           Table_Low_Bound      => First_Node_Id,
1458           Table_Initial        => Project_Nodes_Initial,
1459           Table_Increment      => Project_Nodes_Increment);
1460      --  Table contains the syntactic tree of project data from project files
1461
1462      type Project_Name_And_Node is record
1463         Name : Name_Id;
1464         --  Name of the project
1465
1466         Display_Name : Name_Id;
1467         --  The name of the project as it appears in the .gpr file
1468
1469         Node : Project_Node_Id;
1470         --  Node of the project in table Project_Nodes
1471
1472         Resolved_Path : Path_Name_Type;
1473         --  Resolved and canonical path of a real project file.
1474         --  No_Name in case of virtual projects.
1475
1476         Extended : Boolean;
1477         --  True when the project is being extended by another project
1478
1479         From_Extended : Boolean;
1480         --  True when the project is only imported by projects that are
1481         --  extended.
1482
1483         Proj_Qualifier : Project_Qualifier;
1484         --  The project qualifier of the project, if any
1485      end record;
1486
1487      No_Project_Name_And_Node : constant Project_Name_And_Node :=
1488        (Name           => No_Name,
1489         Display_Name   => No_Name,
1490         Node           => Empty_Node,
1491         Resolved_Path  => No_Path,
1492         Extended       => True,
1493         From_Extended  => False,
1494         Proj_Qualifier => Unspecified);
1495
1496      package Projects_Htable is new GNAT.Dynamic_HTables.Simple_HTable
1497        (Header_Num => Header_Num,
1498         Element    => Project_Name_And_Node,
1499         No_Element => No_Project_Name_And_Node,
1500         Key        => Name_Id,
1501         Hash       => Hash,
1502         Equal      => "=");
1503      --  This hash table contains a mapping of project names to project nodes.
1504      --  Note that this hash table contains only the nodes whose Kind is
1505      --  N_Project. It is used to find the node of a project from its name,
1506      --  and to verify if a project has already been parsed, knowing its name.
1507
1508   end Tree_Private_Part;
1509
1510   type Project_Node_Tree_Data is record
1511      Project_Nodes : Tree_Private_Part.Project_Node_Table.Instance;
1512      Projects_HT   : Tree_Private_Part.Projects_Htable.Instance;
1513
1514      Incomplete_With : Boolean := False;
1515      --  Set to True if the projects were loaded with the flag
1516      --  Ignore_Missing_With set to True, and there were indeed some with
1517      --  statements that could not be resolved
1518   end record;
1519
1520   procedure Free (Proj : in out Project_Node_Tree_Ref);
1521   --  Free memory used by Prj
1522
1523private
1524   type Comment_Array is array (Positive range <>) of Comment_Data;
1525   type Comments_Ptr is access Comment_Array;
1526
1527   type Comment_State is record
1528      End_Of_Line_Node   : Project_Node_Id := Empty_Node;
1529      Previous_Line_Node : Project_Node_Id := Empty_Node;
1530      Previous_End_Node  : Project_Node_Id := Empty_Node;
1531      Unkept_Comments    : Boolean := False;
1532      Comments           : Comments_Ptr := null;
1533   end record;
1534
1535end Prj.Tree;
1536