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-2014, 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   --  behavior 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 Display_Name_Of
273     (Node    : Project_Node_Id;
274      In_Tree : Project_Node_Tree_Ref) return Name_Id;
275   pragma Inline (Display_Name_Of);
276   --  Valid only for N_Project node. Returns the display name of the project.
277
278   function Kind_Of
279     (Node    : Project_Node_Id;
280      In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind;
281   pragma Inline (Kind_Of);
282   --  Valid for all non empty nodes
283
284   function Location_Of
285     (Node    : Project_Node_Id;
286      In_Tree : Project_Node_Tree_Ref) return Source_Ptr;
287   pragma Inline (Location_Of);
288   --  Valid for all non empty nodes
289
290   function First_Comment_After
291     (Node    : Project_Node_Id;
292      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
293   --  Valid only for N_Comment_Zones nodes
294
295   function First_Comment_After_End
296     (Node    : Project_Node_Id;
297      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
298   --  Valid only for N_Comment_Zones nodes
299
300   function First_Comment_Before
301     (Node    : Project_Node_Id;
302      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
303   --  Valid only for N_Comment_Zones nodes
304
305   function First_Comment_Before_End
306     (Node    : Project_Node_Id;
307      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
308   --  Valid only for N_Comment_Zones nodes
309
310   function Next_Comment
311     (Node    : Project_Node_Id;
312      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
313   --  Valid only for N_Comment nodes
314
315   function End_Of_Line_Comment
316     (Node    : Project_Node_Id;
317      In_Tree : Project_Node_Tree_Ref) return Name_Id;
318   --  Valid only for non empty nodes
319
320   function Follows_Empty_Line
321     (Node    : Project_Node_Id;
322      In_Tree : Project_Node_Tree_Ref) return Boolean;
323   --  Valid only for N_Comment nodes
324
325   function Is_Followed_By_Empty_Line
326     (Node    : Project_Node_Id;
327      In_Tree : Project_Node_Tree_Ref) return Boolean;
328   --  Valid only for N_Comment nodes
329
330   function Parent_Project_Of
331     (Node    : Project_Node_Id;
332      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
333   pragma Inline (Parent_Project_Of);
334   --  Valid only for N_Project nodes
335
336   function Project_File_Includes_Unkept_Comments
337     (Node    : Project_Node_Id;
338      In_Tree : Project_Node_Tree_Ref) return Boolean;
339   --  Valid only for N_Project nodes
340
341   function Directory_Of
342     (Node    : Project_Node_Id;
343      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
344   pragma Inline (Directory_Of);
345   --  Returns the directory that contains the project file. This always ends
346   --  with a directory separator. Only valid for N_Project nodes.
347
348   function Expression_Kind_Of
349     (Node    : Project_Node_Id;
350      In_Tree : Project_Node_Tree_Ref) return Variable_Kind;
351   pragma Inline (Expression_Kind_Of);
352   --  Only valid for N_Literal_String, N_Attribute_Declaration,
353   --  N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression,
354   --  N_Term, N_Variable_Reference, N_Attribute_Reference nodes or
355   --  N_External_Value.
356
357   function Is_Extending_All
358     (Node    : Project_Node_Id;
359      In_Tree : Project_Node_Tree_Ref) return Boolean;
360   pragma Inline (Is_Extending_All);
361   --  Only valid for N_Project and N_With_Clause
362
363   function Is_Not_Last_In_List
364     (Node    : Project_Node_Id;
365      In_Tree : Project_Node_Tree_Ref) return Boolean;
366   pragma Inline (Is_Not_Last_In_List);
367   --  Only valid for N_With_Clause
368
369   function First_Variable_Of
370     (Node    : Project_Node_Id;
371      In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id;
372   pragma Inline (First_Variable_Of);
373   --  Only valid for N_Project or N_Package_Declaration nodes
374
375   function First_Package_Of
376     (Node    : Project_Node_Id;
377      In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id;
378   pragma Inline (First_Package_Of);
379   --  Only valid for N_Project nodes
380
381   function Package_Id_Of
382     (Node    : Project_Node_Id;
383      In_Tree : Project_Node_Tree_Ref) return Package_Node_Id;
384   pragma Inline (Package_Id_Of);
385   --  Only valid for N_Package_Declaration nodes
386
387   function Path_Name_Of
388     (Node    : Project_Node_Id;
389      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
390   pragma Inline (Path_Name_Of);
391   --  Only valid for N_Project and N_With_Clause nodes
392
393   function String_Value_Of
394     (Node    : Project_Node_Id;
395      In_Tree : Project_Node_Tree_Ref) return Name_Id;
396   pragma Inline (String_Value_Of);
397   --  Only valid for N_With_Clause, N_Literal_String nodes or N_Comment.
398   --  For a N_With_Clause created automatically for a virtual extending
399   --  project, No_Name is returned.
400
401   function Source_Index_Of
402     (Node    : Project_Node_Id;
403      In_Tree : Project_Node_Tree_Ref) return Int;
404   pragma Inline (Source_Index_Of);
405   --  Only valid for N_Literal_String and N_Attribute_Declaration nodes
406
407   function First_With_Clause_Of
408     (Node    : Project_Node_Id;
409      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
410   pragma Inline (First_With_Clause_Of);
411   --  Only valid for N_Project nodes
412
413   function Project_Declaration_Of
414     (Node    : Project_Node_Id;
415      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
416   pragma Inline (Project_Declaration_Of);
417   --  Only valid for N_Project nodes
418
419   function Project_Qualifier_Of
420     (Node    : Project_Node_Id;
421      In_Tree : Project_Node_Tree_Ref) return Project_Qualifier;
422   pragma Inline (Project_Qualifier_Of);
423   --  Only valid for N_Project nodes
424
425   function Extending_Project_Of
426     (Node    : Project_Node_Id;
427      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
428   pragma Inline (Extending_Project_Of);
429   --  Only valid for N_Project_Declaration nodes
430
431   function First_String_Type_Of
432     (Node    : Project_Node_Id;
433      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
434   pragma Inline (First_String_Type_Of);
435   --  Only valid for N_Project nodes
436
437   function Extended_Project_Path_Of
438     (Node    : Project_Node_Id;
439      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
440   pragma Inline (Extended_Project_Path_Of);
441   --  Only valid for N_With_Clause nodes
442
443   function Project_Node_Of
444     (Node    : Project_Node_Id;
445      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
446   pragma Inline (Project_Node_Of);
447   --  Only valid for N_With_Clause, N_Variable_Reference and
448   --  N_Attribute_Reference nodes.
449
450   function Non_Limited_Project_Node_Of
451     (Node    : Project_Node_Id;
452      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
453   pragma Inline (Non_Limited_Project_Node_Of);
454   --  Only valid for N_With_Clause nodes. Returns Empty_Node for limited
455   --  imported project files, otherwise returns the same result as
456   --  Project_Node_Of.
457
458   function Next_With_Clause_Of
459     (Node    : Project_Node_Id;
460      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
461   pragma Inline (Next_With_Clause_Of);
462   --  Only valid for N_With_Clause nodes
463
464   function First_Declarative_Item_Of
465     (Node    : Project_Node_Id;
466      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
467   pragma Inline (First_Declarative_Item_Of);
468   --  Only valid for N_Project_Declaration, N_Case_Item and
469   --  N_Package_Declaration.
470
471   function Extended_Project_Of
472     (Node    : Project_Node_Id;
473      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
474   pragma Inline (Extended_Project_Of);
475   --  Only valid for N_Project_Declaration nodes
476
477   function Current_Item_Node
478     (Node    : Project_Node_Id;
479      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
480   pragma Inline (Current_Item_Node);
481   --  Only valid for N_Declarative_Item nodes
482
483   function Next_Declarative_Item
484     (Node    : Project_Node_Id;
485      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
486   pragma Inline (Next_Declarative_Item);
487   --  Only valid for N_Declarative_Item node
488
489   function Project_Of_Renamed_Package_Of
490     (Node    : Project_Node_Id;
491      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
492   pragma Inline (Project_Of_Renamed_Package_Of);
493   --  Only valid for N_Package_Declaration nodes. May return Empty_Node.
494
495   function Next_Package_In_Project
496     (Node    : Project_Node_Id;
497      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
498   pragma Inline (Next_Package_In_Project);
499   --  Only valid for N_Package_Declaration nodes
500
501   function First_Literal_String
502     (Node    : Project_Node_Id;
503      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
504   pragma Inline (First_Literal_String);
505   --  Only valid for N_String_Type_Declaration nodes
506
507   function Next_String_Type
508     (Node    : Project_Node_Id;
509      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
510   pragma Inline (Next_String_Type);
511   --  Only valid for N_String_Type_Declaration nodes
512
513   function Next_Literal_String
514     (Node    : Project_Node_Id;
515      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
516   pragma Inline (Next_Literal_String);
517   --  Only valid for N_Literal_String nodes
518
519   function Expression_Of
520     (Node    : Project_Node_Id;
521      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
522   pragma Inline (Expression_Of);
523   --  Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration
524   --  or N_Variable_Declaration nodes
525
526   function Associative_Project_Of
527     (Node    : Project_Node_Id;
528      In_Tree : Project_Node_Tree_Ref)
529      return  Project_Node_Id;
530   pragma Inline (Associative_Project_Of);
531   --  Only valid for N_Attribute_Declaration nodes
532
533   function Associative_Package_Of
534     (Node    : Project_Node_Id;
535      In_Tree : Project_Node_Tree_Ref)
536      return  Project_Node_Id;
537   pragma Inline (Associative_Package_Of);
538   --  Only valid for N_Attribute_Declaration nodes
539
540   function Value_Is_Valid
541     (For_Typed_Variable : Project_Node_Id;
542      In_Tree            : Project_Node_Tree_Ref;
543      Value              : Name_Id) return Boolean;
544   pragma Inline (Value_Is_Valid);
545   --  Only valid for N_Typed_Variable_Declaration. Returns True if Value is
546   --  in the list of allowed strings for For_Typed_Variable. False otherwise.
547
548   function Associative_Array_Index_Of
549     (Node    : Project_Node_Id;
550      In_Tree : Project_Node_Tree_Ref) return Name_Id;
551   pragma Inline (Associative_Array_Index_Of);
552   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference.
553   --  Returns No_Name for non associative array attributes.
554
555   function Next_Variable
556     (Node    : Project_Node_Id;
557      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
558   pragma Inline (Next_Variable);
559   --  Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration
560   --  nodes.
561
562   function First_Term
563     (Node    : Project_Node_Id;
564      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
565   pragma Inline (First_Term);
566   --  Only valid for N_Expression nodes
567
568   function Next_Expression_In_List
569     (Node    : Project_Node_Id;
570      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
571   pragma Inline (Next_Expression_In_List);
572   --  Only valid for N_Expression nodes
573
574   function Current_Term
575     (Node    : Project_Node_Id;
576      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
577   pragma Inline (Current_Term);
578   --  Only valid for N_Term nodes
579
580   function Next_Term
581     (Node    : Project_Node_Id;
582      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
583   pragma Inline (Next_Term);
584   --  Only valid for N_Term nodes
585
586   function First_Expression_In_List
587     (Node    : Project_Node_Id;
588      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
589   pragma Inline (First_Expression_In_List);
590   --  Only valid for N_Literal_String_List nodes
591
592   function Package_Node_Of
593     (Node    : Project_Node_Id;
594      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
595   pragma Inline (Package_Node_Of);
596   --  Only valid for N_Variable_Reference or N_Attribute_Reference nodes.
597   --  May return Empty_Node.
598
599   function Default_Of
600     (Node    : Project_Node_Id;
601      In_Tree : Project_Node_Tree_Ref) return Attribute_Default_Value;
602   pragma Inline (Default_Of);
603   --  Only valid for N_Attribute_Reference nodes
604
605   function String_Type_Of
606     (Node    : Project_Node_Id;
607      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
608   pragma Inline (String_Type_Of);
609   --  Only valid for N_Variable_Reference or N_Typed_Variable_Declaration
610   --  nodes.
611
612   function External_Reference_Of
613     (Node    : Project_Node_Id;
614      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
615   pragma Inline (External_Reference_Of);
616   --  Only valid for N_External_Value nodes
617
618   function External_Default_Of
619     (Node    : Project_Node_Id;
620      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
621   pragma Inline (External_Default_Of);
622   --  Only valid for N_External_Value nodes
623
624   function Case_Variable_Reference_Of
625     (Node    : Project_Node_Id;
626      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
627   pragma Inline (Case_Variable_Reference_Of);
628   --  Only valid for N_Case_Construction nodes
629
630   function First_Case_Item_Of
631     (Node    : Project_Node_Id;
632      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
633   pragma Inline (First_Case_Item_Of);
634   --  Only valid for N_Case_Construction nodes
635
636   function First_Choice_Of
637     (Node    : Project_Node_Id;
638      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
639   pragma Inline (First_Choice_Of);
640   --  Only valid for N_Case_Item nodes. Return the first choice in a
641   --  N_Case_Item, or Empty_Node if this is when others.
642
643   function Next_Case_Item
644     (Node    : Project_Node_Id;
645      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
646   pragma Inline (Next_Case_Item);
647   --  Only valid for N_Case_Item nodes
648
649   function Case_Insensitive
650     (Node    : Project_Node_Id;
651      In_Tree : Project_Node_Tree_Ref) return Boolean;
652   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes
653
654   -----------------------
655   -- Create procedures --
656   -----------------------
657   --  The following procedures are used to edit a project file tree. They are
658   --  slightly higher-level than the Set_* procedures below
659
660   function Create_Project
661     (In_Tree        : Project_Node_Tree_Ref;
662      Name           : Name_Id;
663      Full_Path      : Path_Name_Type;
664      Is_Config_File : Boolean := False) return Project_Node_Id;
665   --  Create a new node for a project and register it in the tree so that it
666   --  can be retrieved later on.
667
668   function Create_Package
669     (Tree    : Project_Node_Tree_Ref;
670      Project : Project_Node_Id;
671      Pkg     : String) return Project_Node_Id;
672   --  Create a new package in Project. If the package already exists, it is
673   --  returned. The name of the package *must* be lower-cases, or none of its
674   --  attributes will be recognized.
675
676   function Create_Attribute
677     (Tree       : Project_Node_Tree_Ref;
678      Prj_Or_Pkg : Project_Node_Id;
679      Name       : Name_Id;
680      Index_Name : Name_Id         := No_Name;
681      Kind       : Variable_Kind   := List;
682      At_Index   : Integer         := 0;
683      Value      : Project_Node_Id := Empty_Node) return Project_Node_Id;
684   --  Create a new attribute. The new declaration is added at the end of the
685   --  declarative item list for Prj_Or_Pkg (a project or a package), but
686   --  before any package declaration). No addition is done if Prj_Or_Pkg is
687   --  Empty_Node. If Index_Name is not "", then if creates an attribute value
688   --  for a specific index. At_Index is used for the " at <idx>" in the naming
689   --  exceptions.
690   --
691   --  To set the value of the attribute, either provide a value for Value, or
692   --  use Set_Expression_Of to set the value of the attribute (in which case
693   --  Enclose_In_Expression might be useful). The former is recommended since
694   --  it will more correctly handle cases where the index needs to be set on
695   --  the expression rather than on the index of the attribute (i.e. 'for
696   --  Specification ("unit") use "file" at 3', versus 'for Executable ("file"
697   --  at 3) use "name"'). Value must be a N_String_Literal if an index will be
698   --  added to it.
699
700   function Create_Literal_String
701     (Str  : Namet.Name_Id;
702      Tree : Project_Node_Tree_Ref) return Project_Node_Id;
703   --  Create a literal string whose value is Str
704
705   procedure Add_At_End
706     (Tree                  : Project_Node_Tree_Ref;
707      Parent                : Project_Node_Id;
708      Expr                  : Project_Node_Id;
709      Add_Before_First_Pkg  : Boolean := False;
710      Add_Before_First_Case : Boolean := False);
711   --  Add a new declarative item in the list in Parent. This new declarative
712   --  item will contain Expr (unless Expr is already a declarative item, in
713   --  which case it is added directly to the list). The new item is inserted
714   --  at the end of the list, unless Add_Before_First_Pkg is True. In the
715   --  latter case, it is added just before the first case construction is
716   --  seen, or before the first package (this assumes that all packages are
717   --  found at the end of the project, which isn't true in the general case
718   --  unless you have normalized the project to match this description).
719
720   function Enclose_In_Expression
721     (Node : Project_Node_Id;
722      Tree : Project_Node_Tree_Ref) return Project_Node_Id;
723   --  Enclose the Node inside a N_Expression node, and return this expression.
724   --  This does nothing if Node is already a N_Expression.
725
726   --------------------
727   -- Set Procedures --
728   --------------------
729
730   --  The following procedures are part of the abstract interface of the
731   --  Project File tree.
732
733   --  Foe each Set_* procedure the condition of validity is specified. If an
734   --  access function is called with invalid arguments, then exception
735   --  Assertion_Error is raised if assertions are enabled, otherwise the
736   --  behavior is not defined and may result in a crash.
737
738   --  These are very low-level, and manipulate the tree itself directly. You
739   --  should look at the Create_* procedure instead if you want to use higher
740   --  level constructs
741
742   procedure Set_Name_Of
743     (Node    : Project_Node_Id;
744      In_Tree : Project_Node_Tree_Ref;
745      To      : Name_Id);
746   pragma Inline (Set_Name_Of);
747   --  Valid for all non empty nodes
748
749   procedure Set_Display_Name_Of
750     (Node    : Project_Node_Id;
751      In_Tree : Project_Node_Tree_Ref;
752      To      : Name_Id);
753   pragma Inline (Set_Display_Name_Of);
754   --  Valid only for N_Project nodes
755
756   procedure Set_Kind_Of
757     (Node    : Project_Node_Id;
758      In_Tree : Project_Node_Tree_Ref;
759      To      : Project_Node_Kind);
760   pragma Inline (Set_Kind_Of);
761   --  Valid for all non empty nodes
762
763   procedure Set_Location_Of
764     (Node    : Project_Node_Id;
765      In_Tree : Project_Node_Tree_Ref;
766      To      : Source_Ptr);
767   pragma Inline (Set_Location_Of);
768   --  Valid for all non empty nodes
769
770   procedure Set_First_Comment_After
771     (Node    : Project_Node_Id;
772      In_Tree : Project_Node_Tree_Ref;
773      To      : Project_Node_Id);
774   pragma Inline (Set_First_Comment_After);
775   --  Valid only for N_Comment_Zones nodes
776
777   procedure Set_First_Comment_After_End
778     (Node    : Project_Node_Id;
779      In_Tree : Project_Node_Tree_Ref;
780      To      : Project_Node_Id);
781   pragma Inline (Set_First_Comment_After_End);
782   --  Valid only for N_Comment_Zones nodes
783
784   procedure Set_First_Comment_Before
785     (Node    : Project_Node_Id;
786      In_Tree : Project_Node_Tree_Ref;
787      To      : Project_Node_Id);
788   pragma Inline (Set_First_Comment_Before);
789   --  Valid only for N_Comment_Zones nodes
790
791   procedure Set_First_Comment_Before_End
792     (Node    : Project_Node_Id;
793      In_Tree : Project_Node_Tree_Ref;
794      To      : Project_Node_Id);
795   pragma Inline (Set_First_Comment_Before_End);
796   --  Valid only for N_Comment_Zones nodes
797
798   procedure Set_Next_Comment
799     (Node    : Project_Node_Id;
800      In_Tree : Project_Node_Tree_Ref;
801      To      : Project_Node_Id);
802   pragma Inline (Set_Next_Comment);
803   --  Valid only for N_Comment nodes
804
805   procedure Set_Parent_Project_Of
806     (Node    : Project_Node_Id;
807      In_Tree : Project_Node_Tree_Ref;
808      To      : Project_Node_Id);
809   --  Valid only for N_Project nodes
810
811   procedure Set_Project_File_Includes_Unkept_Comments
812     (Node    : Project_Node_Id;
813      In_Tree : Project_Node_Tree_Ref;
814      To      : Boolean);
815   --  Valid only for N_Project nodes
816
817   procedure Set_Directory_Of
818     (Node    : Project_Node_Id;
819      In_Tree : Project_Node_Tree_Ref;
820      To      : Path_Name_Type);
821   pragma Inline (Set_Directory_Of);
822   --  Valid only for N_Project nodes
823
824   procedure Set_Expression_Kind_Of
825     (Node    : Project_Node_Id;
826      In_Tree : Project_Node_Tree_Ref;
827      To      : Variable_Kind);
828   pragma Inline (Set_Expression_Kind_Of);
829   --  Only valid for N_Literal_String, N_Attribute_Declaration,
830   --  N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression,
831   --  N_Term, N_Variable_Reference, N_Attribute_Reference or N_External_Value
832   --  nodes.
833
834   procedure Set_Is_Extending_All
835     (Node    : Project_Node_Id;
836      In_Tree : Project_Node_Tree_Ref);
837   pragma Inline (Set_Is_Extending_All);
838   --  Only valid for N_Project and N_With_Clause
839
840   procedure Set_Is_Not_Last_In_List
841     (Node    : Project_Node_Id;
842      In_Tree : Project_Node_Tree_Ref);
843   pragma Inline (Set_Is_Not_Last_In_List);
844   --  Only valid for N_With_Clause
845
846   procedure Set_First_Variable_Of
847     (Node    : Project_Node_Id;
848      In_Tree : Project_Node_Tree_Ref;
849      To      : Variable_Node_Id);
850   pragma Inline (Set_First_Variable_Of);
851   --  Only valid for N_Project or N_Package_Declaration nodes
852
853   procedure Set_First_Package_Of
854     (Node    : Project_Node_Id;
855      In_Tree : Project_Node_Tree_Ref;
856      To      : Package_Declaration_Id);
857   pragma Inline (Set_First_Package_Of);
858   --  Only valid for N_Project nodes
859
860   procedure Set_Package_Id_Of
861     (Node    : Project_Node_Id;
862      In_Tree : Project_Node_Tree_Ref;
863      To      : Package_Node_Id);
864   pragma Inline (Set_Package_Id_Of);
865   --  Only valid for N_Package_Declaration nodes
866
867   procedure Set_Path_Name_Of
868     (Node    : Project_Node_Id;
869      In_Tree : Project_Node_Tree_Ref;
870      To      : Path_Name_Type);
871   pragma Inline (Set_Path_Name_Of);
872   --  Only valid for N_Project and N_With_Clause nodes
873
874   procedure Set_String_Value_Of
875     (Node    : Project_Node_Id;
876      In_Tree : Project_Node_Tree_Ref;
877      To      : Name_Id);
878   pragma Inline (Set_String_Value_Of);
879   --  Only valid for N_With_Clause, N_Literal_String nodes or N_Comment.
880
881   procedure Set_Source_Index_Of
882     (Node    : Project_Node_Id;
883      In_Tree : Project_Node_Tree_Ref;
884      To      : Int);
885   pragma Inline (Set_Source_Index_Of);
886   --  Only valid for N_Literal_String and N_Attribute_Declaration nodes. For
887   --  N_Literal_String, set the source index of the literal string. For
888   --  N_Attribute_Declaration, set the source index of the index of the
889   --  associative array element.
890
891   procedure Set_First_With_Clause_Of
892     (Node    : Project_Node_Id;
893      In_Tree : Project_Node_Tree_Ref;
894      To      : Project_Node_Id);
895   pragma Inline (Set_First_With_Clause_Of);
896   --  Only valid for N_Project nodes
897
898   procedure Set_Project_Declaration_Of
899     (Node    : Project_Node_Id;
900      In_Tree : Project_Node_Tree_Ref;
901      To      : Project_Node_Id);
902   pragma Inline (Set_Project_Declaration_Of);
903   --  Only valid for N_Project nodes
904
905   procedure Set_Project_Qualifier_Of
906     (Node    : Project_Node_Id;
907      In_Tree : Project_Node_Tree_Ref;
908      To      : Project_Qualifier);
909   pragma Inline (Set_Project_Qualifier_Of);
910   --  Only valid for N_Project nodes
911
912   procedure Set_Extending_Project_Of
913     (Node    : Project_Node_Id;
914      In_Tree : Project_Node_Tree_Ref;
915      To      : Project_Node_Id);
916   pragma Inline (Set_Extending_Project_Of);
917   --  Only valid for N_Project_Declaration nodes
918
919   procedure Set_First_String_Type_Of
920     (Node    : Project_Node_Id;
921      In_Tree : Project_Node_Tree_Ref;
922      To      : Project_Node_Id);
923   pragma Inline (Set_First_String_Type_Of);
924   --  Only valid for N_Project nodes
925
926   procedure Set_Extended_Project_Path_Of
927     (Node    : Project_Node_Id;
928      In_Tree : Project_Node_Tree_Ref;
929      To      : Path_Name_Type);
930   pragma Inline (Set_Extended_Project_Path_Of);
931   --  Only valid for N_With_Clause nodes
932
933   procedure Set_Project_Node_Of
934     (Node         : Project_Node_Id;
935      In_Tree      : Project_Node_Tree_Ref;
936      To           : Project_Node_Id;
937      Limited_With : Boolean := False);
938   pragma Inline (Set_Project_Node_Of);
939   --  Only valid for N_With_Clause, N_Variable_Reference and
940   --  N_Attribute_Reference nodes.
941
942   procedure Set_Next_With_Clause_Of
943     (Node    : Project_Node_Id;
944      In_Tree : Project_Node_Tree_Ref;
945      To      : Project_Node_Id);
946   pragma Inline (Set_Next_With_Clause_Of);
947   --  Only valid for N_With_Clause nodes
948
949   procedure Set_First_Declarative_Item_Of
950     (Node    : Project_Node_Id;
951      In_Tree : Project_Node_Tree_Ref;
952      To      : Project_Node_Id);
953   pragma Inline (Set_First_Declarative_Item_Of);
954   --  Only valid for N_Project_Declaration, N_Case_Item and
955   --  N_Package_Declaration.
956
957   procedure Set_Extended_Project_Of
958     (Node    : Project_Node_Id;
959      In_Tree : Project_Node_Tree_Ref;
960      To      : Project_Node_Id);
961   pragma Inline (Set_Extended_Project_Of);
962   --  Only valid for N_Project_Declaration nodes
963
964   procedure Set_Current_Item_Node
965     (Node    : Project_Node_Id;
966      In_Tree : Project_Node_Tree_Ref;
967      To      : Project_Node_Id);
968   pragma Inline (Set_Current_Item_Node);
969   --  Only valid for N_Declarative_Item nodes
970
971   procedure Set_Next_Declarative_Item
972     (Node    : Project_Node_Id;
973      In_Tree : Project_Node_Tree_Ref;
974      To      : Project_Node_Id);
975   pragma Inline (Set_Next_Declarative_Item);
976   --  Only valid for N_Declarative_Item node
977
978   procedure Set_Project_Of_Renamed_Package_Of
979     (Node    : Project_Node_Id;
980      In_Tree : Project_Node_Tree_Ref;
981      To      : Project_Node_Id);
982   pragma Inline (Set_Project_Of_Renamed_Package_Of);
983   --  Only valid for N_Package_Declaration nodes.
984
985   procedure Set_Next_Package_In_Project
986     (Node    : Project_Node_Id;
987      In_Tree : Project_Node_Tree_Ref;
988      To      : Project_Node_Id);
989   pragma Inline (Set_Next_Package_In_Project);
990   --  Only valid for N_Package_Declaration nodes
991
992   procedure Set_First_Literal_String
993     (Node    : Project_Node_Id;
994      In_Tree : Project_Node_Tree_Ref;
995      To      : Project_Node_Id);
996   pragma Inline (Set_First_Literal_String);
997   --  Only valid for N_String_Type_Declaration nodes
998
999   procedure Set_Next_String_Type
1000     (Node    : Project_Node_Id;
1001      In_Tree : Project_Node_Tree_Ref;
1002      To      : Project_Node_Id);
1003   pragma Inline (Set_Next_String_Type);
1004   --  Only valid for N_String_Type_Declaration nodes
1005
1006   procedure Set_Next_Literal_String
1007     (Node    : Project_Node_Id;
1008      In_Tree : Project_Node_Tree_Ref;
1009      To      : Project_Node_Id);
1010   pragma Inline (Set_Next_Literal_String);
1011   --  Only valid for N_Literal_String nodes
1012
1013   procedure Set_Expression_Of
1014     (Node    : Project_Node_Id;
1015      In_Tree : Project_Node_Tree_Ref;
1016      To      : Project_Node_Id);
1017   pragma Inline (Set_Expression_Of);
1018   --  Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration
1019   --  or N_Variable_Declaration nodes
1020
1021   procedure Set_Associative_Project_Of
1022     (Node    : Project_Node_Id;
1023      In_Tree : Project_Node_Tree_Ref;
1024      To      : Project_Node_Id);
1025   pragma Inline (Set_Associative_Project_Of);
1026   --  Only valid for N_Attribute_Declaration nodes
1027
1028   procedure Set_Associative_Package_Of
1029     (Node    : Project_Node_Id;
1030      In_Tree : Project_Node_Tree_Ref;
1031      To      : Project_Node_Id);
1032   pragma Inline (Set_Associative_Package_Of);
1033   --  Only valid for N_Attribute_Declaration nodes
1034
1035   procedure Set_Associative_Array_Index_Of
1036     (Node    : Project_Node_Id;
1037      In_Tree : Project_Node_Tree_Ref;
1038      To      : Name_Id);
1039   pragma Inline (Set_Associative_Array_Index_Of);
1040   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference.
1041
1042   procedure Set_Next_Variable
1043     (Node    : Project_Node_Id;
1044      In_Tree : Project_Node_Tree_Ref;
1045      To      : Project_Node_Id);
1046   pragma Inline (Set_Next_Variable);
1047   --  Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration
1048   --  nodes.
1049
1050   procedure Set_First_Term
1051     (Node    : Project_Node_Id;
1052      In_Tree : Project_Node_Tree_Ref;
1053      To      : Project_Node_Id);
1054   pragma Inline (Set_First_Term);
1055   --  Only valid for N_Expression nodes
1056
1057   procedure Set_Next_Expression_In_List
1058     (Node    : Project_Node_Id;
1059      In_Tree : Project_Node_Tree_Ref;
1060      To      : Project_Node_Id);
1061   pragma Inline (Set_Next_Expression_In_List);
1062   --  Only valid for N_Expression nodes
1063
1064   procedure Set_Current_Term
1065     (Node    : Project_Node_Id;
1066      In_Tree : Project_Node_Tree_Ref;
1067      To      : Project_Node_Id);
1068   pragma Inline (Set_Current_Term);
1069   --  Only valid for N_Term nodes
1070
1071   procedure Set_Next_Term
1072     (Node    : Project_Node_Id;
1073      In_Tree : Project_Node_Tree_Ref;
1074      To      : Project_Node_Id);
1075   pragma Inline (Set_Next_Term);
1076   --  Only valid for N_Term nodes
1077
1078   procedure Set_First_Expression_In_List
1079     (Node    : Project_Node_Id;
1080      In_Tree : Project_Node_Tree_Ref;
1081      To      : Project_Node_Id);
1082   pragma Inline (Set_First_Expression_In_List);
1083   --  Only valid for N_Literal_String_List nodes
1084
1085   procedure Set_Package_Node_Of
1086     (Node    : Project_Node_Id;
1087      In_Tree : Project_Node_Tree_Ref;
1088      To      : Project_Node_Id);
1089   pragma Inline (Set_Package_Node_Of);
1090   --  Only valid for N_Variable_Reference or N_Attribute_Reference nodes
1091
1092   procedure Set_Default_Of
1093     (Node    : Project_Node_Id;
1094      In_Tree : Project_Node_Tree_Ref;
1095      To      : Attribute_Default_Value);
1096   pragma Inline (Set_Default_Of);
1097   --  Only valid for N_Attribute_Reference nodes
1098
1099   procedure Set_String_Type_Of
1100     (Node    : Project_Node_Id;
1101      In_Tree : Project_Node_Tree_Ref;
1102      To      : Project_Node_Id);
1103   pragma Inline (Set_String_Type_Of);
1104   --  Only valid for N_Variable_Reference or N_Typed_Variable_Declaration
1105   --  nodes.
1106
1107   procedure Set_External_Reference_Of
1108     (Node    : Project_Node_Id;
1109      In_Tree : Project_Node_Tree_Ref;
1110      To      : Project_Node_Id);
1111   pragma Inline (Set_External_Reference_Of);
1112   --  Only valid for N_External_Value nodes
1113
1114   procedure Set_External_Default_Of
1115     (Node    : Project_Node_Id;
1116      In_Tree : Project_Node_Tree_Ref;
1117      To      : Project_Node_Id);
1118   pragma Inline (Set_External_Default_Of);
1119   --  Only valid for N_External_Value nodes
1120
1121   procedure Set_Case_Variable_Reference_Of
1122     (Node    : Project_Node_Id;
1123      In_Tree : Project_Node_Tree_Ref;
1124      To      : Project_Node_Id);
1125   pragma Inline (Set_Case_Variable_Reference_Of);
1126   --  Only valid for N_Case_Construction nodes
1127
1128   procedure Set_First_Case_Item_Of
1129     (Node    : Project_Node_Id;
1130      In_Tree : Project_Node_Tree_Ref;
1131      To      : Project_Node_Id);
1132   pragma Inline (Set_First_Case_Item_Of);
1133   --  Only valid for N_Case_Construction nodes
1134
1135   procedure Set_First_Choice_Of
1136     (Node    : Project_Node_Id;
1137      In_Tree : Project_Node_Tree_Ref;
1138      To      : Project_Node_Id);
1139   pragma Inline (Set_First_Choice_Of);
1140   --  Only valid for N_Case_Item nodes.
1141
1142   procedure Set_Next_Case_Item
1143     (Node    : Project_Node_Id;
1144      In_Tree : Project_Node_Tree_Ref;
1145      To      : Project_Node_Id);
1146   pragma Inline (Set_Next_Case_Item);
1147   --  Only valid for N_Case_Item nodes.
1148
1149   procedure Set_Case_Insensitive
1150     (Node    : Project_Node_Id;
1151      In_Tree : Project_Node_Tree_Ref;
1152      To      : Boolean);
1153   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes
1154
1155   -------------------------------
1156   -- Restricted Access Section --
1157   -------------------------------
1158
1159   package Tree_Private_Part is
1160
1161      --  This is conceptually in the private part. However, for efficiency,
1162      --  some packages are accessing it directly.
1163
1164      type Project_Node_Record is record
1165
1166         Kind : Project_Node_Kind;
1167
1168         Qualifier : Project_Qualifier := Unspecified;
1169
1170         Location : Source_Ptr := No_Location;
1171
1172         Directory : Path_Name_Type := No_Path;
1173         --  Only for N_Project
1174
1175         Display_Name : Name_Id := No_Name;
1176         --  Only for N_Project
1177
1178         Expr_Kind : Variable_Kind := Undefined;
1179         --  See below for what Project_Node_Kind it is used
1180
1181         Variables : Variable_Node_Id := Empty_Node;
1182         --  First variable in a project or a package
1183
1184         Packages : Package_Declaration_Id := Empty_Node;
1185         --  First package declaration in a project
1186
1187         Pkg_Id : Package_Node_Id := Empty_Package;
1188         --  Only used for N_Package_Declaration
1189         --
1190         --  The component Pkg_Id is an entry into the table Package_Attributes
1191         --  (in Prj.Attr). It is used to indicate all the attributes of the
1192         --  package with their characteristics.
1193         --
1194         --  The tables Prj.Attr.Attributes and Prj.Attr.Package_Attributes
1195         --  are built once and for all through a call (from Prj.Initialize)
1196         --  to procedure Prj.Attr.Initialize. It is never modified after that.
1197
1198         Name : Name_Id := No_Name;
1199         --  See below for what Project_Node_Kind it is used
1200
1201         Src_Index : Int := 0;
1202         --  Index of a unit in a multi-unit source.
1203         --  Only for some N_Attribute_Declaration and N_Literal_String.
1204
1205         Path_Name : Path_Name_Type := No_Path;
1206         --  See below for what Project_Node_Kind it is used
1207
1208         Value : Name_Id := No_Name;
1209         --  See below for what Project_Node_Kind it is used
1210
1211         Default : Attribute_Default_Value := Empty_Value;
1212         --  Only used in N_Attribute_Reference
1213
1214         Field1 : Project_Node_Id := Empty_Node;
1215         --  See below the meaning for each Project_Node_Kind
1216
1217         Field2 : Project_Node_Id := Empty_Node;
1218         --  See below the meaning for each Project_Node_Kind
1219
1220         Field3 : Project_Node_Id := Empty_Node;
1221         --  See below the meaning for each Project_Node_Kind
1222
1223         Field4 : Project_Node_Id := Empty_Node;
1224         --  See below the meaning for each Project_Node_Kind
1225
1226         Flag1 : Boolean := False;
1227         --  This flag is significant only for:
1228         --
1229         --    N_Attribute_Declaration and N_Attribute_Reference
1230         --      Indicates for an associative array attribute, that the
1231         --      index is case insensitive.
1232         --
1233         --    N_Comment
1234         --      Indicates that the comment is preceded by an empty line.
1235         --
1236         --    N_Project
1237         --      Indicates that there are comments in the project source that
1238         --      cannot be kept in the tree.
1239         --
1240         --    N_Project_Declaration
1241         --      Indicates that there are unkept comments in the project.
1242         --
1243         --    N_With_Clause
1244         --      Indicates that this is not the last with in a with clause.
1245         --      Set for "A", but not for "B" in with "B"; and with "A", "B";
1246
1247         Flag2 : Boolean := False;
1248         --  This flag is significant only for:
1249         --
1250         --    N_Project
1251         --      Indicates that the project "extends all" another project.
1252         --
1253         --    N_Comment
1254         --      Indicates that the comment is followed by an empty line.
1255         --
1256         --    N_With_Clause
1257         --      Indicates that the originally imported project is an extending
1258         --      all project.
1259
1260         Comments : Project_Node_Id := Empty_Node;
1261         --  For nodes other that N_Comment_Zones or N_Comment, designates the
1262         --  comment zones associated with the node.
1263         --
1264         --  For N_Comment_Zones, designates the comment after the "end" of
1265         --  the construct.
1266         --
1267         --  For N_Comment, designates the next comment, if any.
1268
1269      end record;
1270
1271      --  type Project_Node_Kind is
1272
1273      --   (N_Project,
1274      --    --  Name:      project name
1275      --    --  Path_Name: project path name
1276      --    --  Expr_Kind: Undefined
1277      --    --  Field1:    first with clause
1278      --    --  Field2:    project declaration
1279      --    --  Field3:    first string type
1280      --    --  Field4:    parent project, if any
1281      --    --  Value:     extended project path name (if any)
1282
1283      --    N_With_Clause,
1284      --    --  Name:      imported project name
1285      --    --  Path_Name: imported project path name
1286      --    --  Expr_Kind: Undefined
1287      --    --  Field1:    project node
1288      --    --  Field2:    next with clause
1289      --    --  Field3:    project node or empty if "limited with"
1290      --    --  Field4:    not used
1291      --    --  Value:     literal string withed
1292
1293      --    N_Project_Declaration,
1294      --    --  Name:      not used
1295      --    --  Path_Name: not used
1296      --    --  Expr_Kind: Undefined
1297      --    --  Field1:    first declarative item
1298      --    --  Field2:    extended project
1299      --    --  Field3:    extending project
1300      --    --  Field4:    not used
1301      --    --  Value:     not used
1302
1303      --    N_Declarative_Item,
1304      --    --  Name:      not used
1305      --    --  Path_Name: not used
1306      --    --  Expr_Kind: Undefined
1307      --    --  Field1:    current item node
1308      --    --  Field2:    next declarative item
1309      --    --  Field3:    not used
1310      --    --  Field4:    not used
1311      --    --  Value:     not used
1312
1313      --    N_Package_Declaration,
1314      --    --  Name:      package name
1315      --    --  Path_Name: not used
1316      --    --  Expr_Kind: Undefined
1317      --    --  Field1:    project of renamed package (if any)
1318      --    --  Field2:    first declarative item
1319      --    --  Field3:    next package in project
1320      --    --  Field4:    not used
1321      --    --  Value:     not used
1322
1323      --    N_String_Type_Declaration,
1324      --    --  Name:      type name
1325      --    --  Path_Name: not used
1326      --    --  Expr_Kind: Undefined
1327      --    --  Field1:    first literal string
1328      --    --  Field2:    next string type
1329      --    --  Field3:    not used
1330      --    --  Field4:    not used
1331      --    --  Value:     not used
1332
1333      --    N_Literal_String,
1334      --    --  Name:      not used
1335      --    --  Path_Name: not used
1336      --    --  Expr_Kind: Single
1337      --    --  Field1:    next literal string
1338      --    --  Field2:    not used
1339      --    --  Field3:    not used
1340      --    --  Field4:    not used
1341      --    --  Value:     string value
1342
1343      --    N_Attribute_Declaration,
1344      --    --  Name:      attribute name
1345      --    --  Path_Name: not used
1346      --    --  Expr_Kind: attribute kind
1347      --    --  Field1:    expression
1348      --    --  Field2:    project of full associative array
1349      --    --  Field3:    package of full associative array
1350      --    --  Field4:    not used
1351      --    --  Value:     associative array index
1352      --    --             (if an associative array element)
1353
1354      --    N_Typed_Variable_Declaration,
1355      --    --  Name:      variable name
1356      --    --  Path_Name: not used
1357      --    --  Expr_Kind: Single
1358      --    --  Field1:    expression
1359      --    --  Field2:    type of variable (N_String_Type_Declaration)
1360      --    --  Field3:    next variable
1361      --    --  Field4:    not used
1362      --    --  Value:     not used
1363
1364      --    N_Variable_Declaration,
1365      --    --  Name:      variable name
1366      --    --  Path_Name: not used
1367      --    --  Expr_Kind: variable kind
1368      --    --  Field1:    expression
1369      --    --  Field2:    not used
1370      --    --             Field3 is used for next variable, instead of Field2,
1371      --    --             so that it is the same field for
1372      --    --             N_Variable_Declaration and
1373      --    --             N_Typed_Variable_Declaration
1374      --    --  Field3:    next variable
1375      --    --  Field4:    not used
1376      --    --  Value:     not used
1377
1378      --    N_Expression,
1379      --    --  Name:      not used
1380      --    --  Path_Name: not used
1381      --    --  Expr_Kind: expression kind
1382      --    --  Field1:    first term
1383      --    --  Field2:    next expression in list
1384      --    --  Field3:    not used
1385      --    --  Value:     not used
1386
1387      --    N_Term,
1388      --    --  Name:      not used
1389      --    --  Path_Name: not used
1390      --    --  Expr_Kind: term kind
1391      --    --  Field1:    current term
1392      --    --  Field2:    next term in the expression
1393      --    --  Field3:    not used
1394      --    --  Field4:    not used
1395      --    --  Value:     not used
1396
1397      --    N_Literal_String_List,
1398      --    --  Designates a list of string expressions between brackets
1399      --    --  separated by commas. The string expressions are not necessarily
1400      --    --  literal strings.
1401      --    --  Name:      not used
1402      --    --  Path_Name: not used
1403      --    --  Expr_Kind: List
1404      --    --  Field1:    first expression
1405      --    --  Field2:    not used
1406      --    --  Field3:    not used
1407      --    --  Field4:    not used
1408      --    --  Value:     not used
1409
1410      --    N_Variable_Reference,
1411      --    --  Name:      variable name
1412      --    --  Path_Name: not used
1413      --    --  Expr_Kind: variable kind
1414      --    --  Field1:    project (if specified)
1415      --    --  Field2:    package (if specified)
1416      --    --  Field3:    type of variable (N_String_Type_Declaration), if any
1417      --    --  Field4:    not used
1418      --    --  Value:     not used
1419
1420      --    N_External_Value,
1421      --    --  Name:      not used
1422      --    --  Path_Name: not used
1423      --    --  Expr_Kind: Single
1424      --    --  Field1:    Name of the external reference (literal string)
1425      --    --  Field2:    Default (literal string)
1426      --    --  Field3:    not used
1427      --    --  Value:     not used
1428
1429      --    N_Attribute_Reference,
1430      --    --  Name:      attribute name
1431      --    --  Path_Name: not used
1432      --    --  Expr_Kind: attribute kind
1433      --    --  Field1:    project
1434      --    --  Field2:    package (if attribute of a package)
1435      --    --  Field3:    not used
1436      --    --  Field4:    not used
1437      --    --  Value:     associative array index
1438      --    --             (if an associative array element)
1439
1440      --    N_Case_Construction,
1441      --    --  Name:      not used
1442      --    --  Path_Name: not used
1443      --    --  Expr_Kind: Undefined
1444      --    --  Field1:    case variable reference
1445      --    --  Field2:    first case item
1446      --    --  Field3:    not used
1447      --    --  Field4:    not used
1448      --    --  Value:     not used
1449
1450      --    N_Case_Item
1451      --    --  Name:      not used
1452      --    --  Path_Name: not used
1453      --    --  Expr_Kind: not used
1454      --    --  Field1:    first choice (literal string), or Empty_Node
1455      --    --             for when others
1456      --    --  Field2:    first declarative item
1457      --    --  Field3:    next case item
1458      --    --  Field4:    not used
1459      --    --  Value:     not used
1460
1461      --    N_Comment_zones
1462      --    --  Name:      not used
1463      --    --  Path_Name: not used
1464      --    --  Expr_Kind: not used
1465      --    --  Field1:    comment before the construct
1466      --    --  Field2:    comment after the construct
1467      --    --  Field3:    comment before the "end" of the construct
1468      --    --  Value:     end of line comment
1469      --    --  Field4:    not used
1470      --    --  Comments:  comment after the "end" of the construct
1471
1472      --    N_Comment
1473      --    --  Name:      not used
1474      --    --  Path_Name: not used
1475      --    --  Expr_Kind: not used
1476      --    --  Field1:    not used
1477      --    --  Field2:    not used
1478      --    --  Field3:    not used
1479      --    --  Field4:    not used
1480      --    --  Value:     comment
1481      --    --  Flag1:     comment is preceded by an empty line
1482      --    --  Flag2:     comment is followed by an empty line
1483      --    --  Comments:  next comment
1484
1485      package Project_Node_Table is new
1486        GNAT.Dynamic_Tables
1487          (Table_Component_Type => Project_Node_Record,
1488           Table_Index_Type     => Project_Node_Id,
1489           Table_Low_Bound      => First_Node_Id,
1490           Table_Initial        => Project_Nodes_Initial,
1491           Table_Increment      => Project_Nodes_Increment);
1492      --  Table contains the syntactic tree of project data from project files
1493
1494      type Project_Name_And_Node is record
1495         Name : Name_Id;
1496         --  Name of the project
1497
1498         Node : Project_Node_Id;
1499         --  Node of the project in table Project_Nodes
1500
1501         Resolved_Path : Path_Name_Type;
1502         --  Resolved and canonical path of a real project file.
1503         --  No_Name in case of virtual projects.
1504
1505         Extended : Boolean;
1506         --  True when the project is being extended by another project
1507
1508         From_Extended : Boolean;
1509         --  True when the project is only imported by projects that are
1510         --  extended.
1511
1512         Proj_Qualifier : Project_Qualifier;
1513         --  The project qualifier of the project, if any
1514      end record;
1515
1516      No_Project_Name_And_Node : constant Project_Name_And_Node :=
1517        (Name           => No_Name,
1518         Node           => Empty_Node,
1519         Resolved_Path  => No_Path,
1520         Extended       => True,
1521         From_Extended  => False,
1522         Proj_Qualifier => Unspecified);
1523
1524      package Projects_Htable is new GNAT.Dynamic_HTables.Simple_HTable
1525        (Header_Num => Header_Num,
1526         Element    => Project_Name_And_Node,
1527         No_Element => No_Project_Name_And_Node,
1528         Key        => Name_Id,
1529         Hash       => Hash,
1530         Equal      => "=");
1531      --  This hash table contains a mapping of project names to project nodes.
1532      --  Note that this hash table contains only the nodes whose Kind is
1533      --  N_Project. It is used to find the node of a project from its name,
1534      --  and to verify if a project has already been parsed, knowing its name.
1535
1536   end Tree_Private_Part;
1537
1538   type Project_Node_Tree_Data is record
1539      Project_Nodes : Tree_Private_Part.Project_Node_Table.Instance;
1540      Projects_HT   : Tree_Private_Part.Projects_Htable.Instance;
1541
1542      Incomplete_With : Boolean := False;
1543      --  Set to True if the projects were loaded with the flag
1544      --  Ignore_Missing_With set to True, and there were indeed some with
1545      --  statements that could not be resolved
1546   end record;
1547
1548   procedure Free (Proj : in out Project_Node_Tree_Ref);
1549   --  Free memory used by Prj
1550
1551private
1552   type Comment_Array is array (Positive range <>) of Comment_Data;
1553   type Comments_Ptr is access Comment_Array;
1554
1555   type Comment_State is record
1556      End_Of_Line_Node   : Project_Node_Id := Empty_Node;
1557      Previous_Line_Node : Project_Node_Id := Empty_Node;
1558      Previous_End_Node  : Project_Node_Id := Empty_Node;
1559      Unkept_Comments    : Boolean := False;
1560      Comments           : Comments_Ptr := null;
1561   end record;
1562
1563end Prj.Tree;
1564