OSDN Git Service

* config/pa/fptr.c: Update license header.
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-tree.ads
index d32fcb1..470e0a8 100644 (file)
@@ -6,9 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---                            $Revision: 1.9 $
---                                                                          --
---             Copyright (C) 2001 Free Software Foundation, Inc.            --
+--          Copyright (C) 2001-2007, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
+-- Boston, MA 02110-1301, USA.                                              --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
---  This package defines the structure of the Project File tree.
+--  This package defines the structure of the Project File tree
 
-with GNAT.HTable;
+with GNAT.Dynamic_HTables;
+with GNAT.Dynamic_Tables;
 
 with Prj.Attr; use Prj.Attr;
-with Prj.Com;  use Prj.Com;
-with Types;    use Types;
-with Table;
 
 package Prj.Tree is
 
+   type Project_Node_Tree_Data;
+   type Project_Node_Tree_Ref is access all Project_Node_Tree_Data;
+   --  Type to designate a project node tree, so that several project node
+   --  trees can coexist in memory.
+
    Project_Nodes_Initial   : constant := 1_000;
-   --  Initial number of nodes in table Tree_Private_Part.Project_Nodes
    Project_Nodes_Increment : constant := 100;
+   --  Allocation parameters for initializing and extending number
+   --  of nodes in table Tree_Private_Part.Project_Nodes
 
    Project_Node_Low_Bound  : constant := 0;
-   Project_Node_High_Bound : constant := 099_999_999; -- In practice, infinite
+   Project_Node_High_Bound : constant := 099_999_999;
+   --  Range of values for project node id's (in practice infinite)
 
    type Project_Node_Id is range
      Project_Node_Low_Bound .. Project_Node_High_Bound;
    --  The index of table Tree_Private_Part.Project_Nodes
 
-   Empty_Node    : constant Project_Node_Id := Project_Node_Low_Bound;
+   Empty_Node : constant Project_Node_Id := Project_Node_Low_Bound;
    --  Designates no node in table Project_Nodes
-   First_Node_Id : constant Project_Node_Id := Project_Node_Low_Bound;
 
-   subtype Variable_Node_Id       is Project_Node_Id;
-   --  Used to designate a node whose expected kind is
+   First_Node_Id : constant Project_Node_Id := Project_Node_Low_Bound + 1;
+
+   subtype Variable_Node_Id is Project_Node_Id;
+   --  Used to designate a node whose expected kind is one of
    --  N_Typed_Variable_Declaration, N_Variable_Declaration or
    --  N_Variable_Reference.
+
    subtype Package_Declaration_Id is Project_Node_Id;
-   --  Used to designate a node whose expected kind is
-   --  N_Project_Declaration.
+   --  Used to designate a node whose expected kind is N_Proect_Declaration
 
    type Project_Node_Kind is
      (N_Project,
@@ -78,234 +82,487 @@ package Prj.Tree is
       N_External_Value,
       N_Attribute_Reference,
       N_Case_Construction,
-      N_Case_Item);
-   --  Each node in the tree is of a Project_Node_Kind
-   --  For the signification of the fields in each node of a
-   --  Project_Node_Kind, look at package Tree_Private_Part.
-
-   procedure Initialize;
+      N_Case_Item,
+      N_Comment_Zones,
+      N_Comment);
+   --  Each node in the tree is of a Project_Node_Kind. For the signification
+   --  of the fields in each node of Project_Node_Kind, look at package
+   --  Tree_Private_Part.
+
+   procedure Initialize (Tree : Project_Node_Tree_Ref);
    --  Initialize the Project File tree: empty the Project_Nodes table
    --  and reset the Projects_Htable.
 
    function Default_Project_Node
-     (Of_Kind       : Project_Node_Kind;
-      And_Expr_Kind : Variable_Kind := Undefined)
-     return Project_Node_Id;
-   --  Returns a Project_Node_Record with the specified Kind and
-   --  Expr_Kind; all the other components have default nil values.
+     (In_Tree       : Project_Node_Tree_Ref;
+      Of_Kind       : Project_Node_Kind;
+      And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id;
+   --  Returns a Project_Node_Record with the specified Kind and Expr_Kind. All
+   --  the other components have default nil values.
+
+   function Hash (N : Project_Node_Id) return Header_Num;
+   --  Used for hash tables where the key is a Project_Node_Id
+
+   function Imported_Or_Extended_Project_Of
+     (Project   : Project_Node_Id;
+      In_Tree   : Project_Node_Tree_Ref;
+      With_Name : Name_Id) return Project_Node_Id;
+   --  Return the node of a project imported or extended by project Project and
+   --  whose name is With_Name. Return Empty_Node if there is no such project.
+
+   --------------
+   -- Comments --
+   --------------
+
+   type Comment_State is private;
+   --  A type to store the values of several global variables related to
+   --  comments.
+
+   procedure Save (S : out Comment_State);
+   --  Save in variable S the comment state. Called before scanning a new
+   --  project file.
+
+   procedure Restore (S : Comment_State);
+   --  Restore the comment state to a previously saved value. Called after
+   --  scanning a project file.
+
+   procedure Reset_State;
+   --  Set the comment state to its initial value. Called before scanning a
+   --  new project file.
+
+   function There_Are_Unkept_Comments return Boolean;
+   --  Indicates that some of the comments in a project file could not be
+   --  stored in the parse tree.
+
+   procedure Set_Previous_Line_Node (To : Project_Node_Id);
+   --  Indicate the node on the previous line. If there are comments
+   --  immediately following this line, then they should be associated with
+   --  this node.
+
+   procedure Set_Previous_End_Node (To : Project_Node_Id);
+   --  Indicate that on the previous line the "end" belongs to node To.
+   --  If there are comments immediately following this "end" line, they
+   --  should be associated with this node.
+
+   procedure Set_End_Of_Line (To : Project_Node_Id);
+   --  Indicate the node on the current line. If there is an end of line
+   --  comment, then it should be associated with this node.
+
+   procedure Set_Next_End_Node (To : Project_Node_Id);
+   --  Put node To on the top of the end node stack. When an END line is found
+   --  with this node on the top of the end node stack, the comments, if any,
+   --  immediately preceding this "end" line will be associated with this node.
+
+   procedure Remove_Next_End_Node;
+   --  Remove the top of the end node stack
+
+   ------------------------
+   -- Comment Processing --
+   ------------------------
+
+   type Comment_Data is record
+      Value                     : Name_Id := No_Name;
+      Follows_Empty_Line        : Boolean := False;
+      Is_Followed_By_Empty_Line : Boolean := False;
+   end record;
+   --  Component type for Comments Table below
+
+   package Comments is new Table.Table
+     (Table_Component_Type => Comment_Data,
+      Table_Index_Type     => Natural,
+      Table_Low_Bound      => 1,
+      Table_Initial        => 10,
+      Table_Increment      => 100,
+      Table_Name           => "Prj.Tree.Comments");
+   --  A table to store the comments that may be stored is the tree
+
+   procedure Scan (In_Tree : Project_Node_Tree_Ref);
+   --  Scan the tokens and accumulate comments
+
+   type Comment_Location is
+     (Before, After, Before_End, After_End, End_Of_Line);
+   --  Used in call to Add_Comments below
+
+   procedure Add_Comments
+     (To      : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      Where   : Comment_Location);
+   --  Add comments to this node
 
    ----------------------
    -- Access Functions --
    ----------------------
 
    --  The following query functions are part of the abstract interface
-   --  of the Project File tree
+   --  of the Project File tree. They provide access to fields of a project.
+
+   --  In the following, there are "valid if" comments, but no indication
+   --  of what happens if they are called with invalid arguments ???
 
-   function Name_Of (Node : Project_Node_Id) return Name_Id;
+   function Name_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id;
+   pragma Inline (Name_Of);
    --  Valid for all non empty nodes. May return No_Name for nodes that have
    --  no names.
 
-   function Kind_Of (Node : Project_Node_Id) return Project_Node_Kind;
+   function Kind_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind;
+   pragma Inline (Kind_Of);
    --  Valid for all non empty nodes
 
-   function Location_Of (Node : Project_Node_Id) return Source_Ptr;
+   function Location_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Source_Ptr;
+   pragma Inline (Location_Of);
    --  Valid for all non empty nodes
 
-   function Directory_Of (Node : Project_Node_Id) return Name_Id;
-   --  Only valid for N_Project nodes.
+   function First_Comment_After
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   --  Valid only for N_Comment_Zones nodes
+
+   function First_Comment_After_End
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   --  Valid only for N_Comment_Zones nodes
+
+   function First_Comment_Before
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   --  Valid only for N_Comment_Zones nodes
+
+   function First_Comment_Before_End
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   --  Valid only for N_Comment_Zones nodes
+
+   function Next_Comment
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   --  Valid only for N_Comment nodes
+
+   function End_Of_Line_Comment
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id;
+   --  Valid only for non empty nodes
+
+   function Follows_Empty_Line
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean;
+   --  Valid only for N_Comment nodes
+
+   function Is_Followed_By_Empty_Line
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean;
+   --  Valid only for N_Comment nodes
+
+   function Project_File_Includes_Unkept_Comments
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
+      return Boolean;
+   --  Valid only for N_Project nodes
+
+   function Directory_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
+   pragma Inline (Directory_Of);
+   --  Only valid for N_Project nodes
 
-   function Expression_Kind_Of (Node : Project_Node_Id) return Variable_Kind;
+   function Expression_Kind_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Variable_Kind;
+   pragma Inline (Expression_Kind_Of);
    --  Only valid for N_Literal_String, N_Attribute_Declaration,
    --  N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression,
    --  N_Term, N_Variable_Reference or N_Attribute_Reference nodes.
 
+   function Is_Extending_All
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean;
+   pragma Inline (Is_Extending_All);
+   --  Only valid for N_Project and N_With_Clause
+
+   function Is_Not_Last_In_List
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean;
+   pragma Inline (Is_Not_Last_In_List);
+   --  Only valid for N_With_Clause
+
    function First_Variable_Of
-     (Node  : Project_Node_Id)
-      return Variable_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id;
+   pragma Inline (First_Variable_Of);
    --  Only valid for N_Project or N_Package_Declaration nodes
 
    function First_Package_Of
-     (Node  : Project_Node_Id)
-      return  Package_Declaration_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id;
+   pragma Inline (First_Package_Of);
    --  Only valid for N_Project nodes
 
-   function Package_Id_Of (Node  : Project_Node_Id) return Package_Node_Id;
+   function Package_Id_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Package_Node_Id;
+   pragma Inline (Package_Id_Of);
    --  Only valid for N_Package_Declaration nodes
 
-   function Path_Name_Of (Node  : Project_Node_Id) return Name_Id;
-   --  Only valid for N_Project and N_With_Clause nodes.
-
-   function String_Value_Of (Node  : Project_Node_Id) return String_Id;
-   --  Only valid for N_With_Clause or N_Literal_String nodes.
+   function Path_Name_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
+   pragma Inline (Path_Name_Of);
+   --  Only valid for N_Project and N_With_Clause nodes
+
+   function String_Value_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id;
+   pragma Inline (String_Value_Of);
+   --  Only valid for N_With_Clause, N_Literal_String nodes or N_Comment.
+   --  For a N_With_Clause created automatically for a virtual extending
+   --  project, No_Name is returned.
+
+   function Source_Index_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Int;
+   pragma Inline (Source_Index_Of);
+   --  Only valid for N_Literal_String and N_Attribute_Declaration nodes
 
    function First_With_Clause_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_With_Clause_Of);
    --  Only valid for N_Project nodes
 
    function Project_Declaration_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Project_Declaration_Of);
    --  Only valid for N_Project nodes
 
+   function Extending_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Extending_Project_Of);
+   --  Only valid for N_Project_Declaration nodes
+
    function First_String_Type_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_String_Type_Of);
    --  Only valid for N_Project nodes
 
-   function Modified_Project_Path_Of
-     (Node  : Project_Node_Id)
-      return  String_Id;
+   function Extended_Project_Path_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
+   pragma Inline (Extended_Project_Path_Of);
    --  Only valid for N_With_Clause nodes
 
    function Project_Node_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
-   --  Only valid for N_Project nodes
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Project_Node_Of);
+   --  Only valid for N_With_Clause, N_Variable_Reference and
+   --  N_Attribute_Reference nodes.
+
+   function Non_Limited_Project_Node_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Non_Limited_Project_Node_Of);
+   --  Only valid for N_With_Clause nodes. Returns Empty_Node for limited
+   --  imported project files, otherwise returns the same result as
+   --  Project_Node_Of.
 
    function Next_With_Clause_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_With_Clause_Of);
    --  Only valid for N_With_Clause nodes
 
    function First_Declarative_Item_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_Declarative_Item_Of);
    --  Only valid for N_With_Clause nodes
 
-   function Modified_Project_Of
-     (Node  : Project_Node_Id)
-      return Project_Node_Id;
-   --  Only valid for N_With_Clause nodes
+   function Extended_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Extended_Project_Of);
+   --  Only valid for N_Project_Declaration nodes
 
    function Current_Item_Node
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Current_Item_Node);
    --  Only valid for N_Declarative_Item nodes
 
    function Next_Declarative_Item
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Declarative_Item);
    --  Only valid for N_Declarative_Item node
 
    function Project_Of_Renamed_Package_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Project_Of_Renamed_Package_Of);
    --  Only valid for N_Package_Declaration nodes.
    --  May return Empty_Node.
 
    function Next_Package_In_Project
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Package_In_Project);
    --  Only valid for N_Package_Declaration nodes
 
    function First_Literal_String
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_Literal_String);
    --  Only valid for N_String_Type_Declaration nodes
 
    function Next_String_Type
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_String_Type);
    --  Only valid for N_String_Type_Declaration nodes
 
    function Next_Literal_String
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Literal_String);
    --  Only valid for N_Literal_String nodes
 
    function Expression_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Expression_Of);
    --  Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration
    --  or N_Variable_Declaration nodes
 
+   function Associative_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
+      return  Project_Node_Id;
+   pragma Inline (Associative_Project_Of);
+   --  Only valid for N_Attribute_Declaration nodes
+
+   function Associative_Package_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
+      return  Project_Node_Id;
+   pragma Inline (Associative_Package_Of);
+   --  Only valid for N_Attribute_Declaration nodes
+
    function Value_Is_Valid
      (For_Typed_Variable : Project_Node_Id;
-      Value              : String_Id)
-      return               Boolean;
+      In_Tree            : Project_Node_Tree_Ref;
+      Value              : Name_Id) return Boolean;
+   pragma Inline (Value_Is_Valid);
    --  Only valid for N_Typed_Variable_Declaration. Returns True if Value is
    --  in the list of allowed strings for For_Typed_Variable. False otherwise.
 
    function Associative_Array_Index_Of
-     (Node  : Project_Node_Id)
-      return  String_Id;
-   --  Only valid for N_Attribute_Declaration.
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id;
+   pragma Inline (Associative_Array_Index_Of);
+   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference.
    --  Returns No_String for non associative array attributes.
 
    function Next_Variable
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Variable);
    --  Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration
    --  nodes.
 
    function First_Term
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_Term);
    --  Only valid for N_Expression nodes
 
    function Next_Expression_In_List
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Expression_In_List);
    --  Only valid for N_Expression nodes
 
    function Current_Term
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Current_Term);
    --  Only valid for N_Term nodes
 
    function Next_Term
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Term);
    --  Only valid for N_Term nodes
 
    function First_Expression_In_List
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_Expression_In_List);
    --  Only valid for N_Literal_String_List nodes
 
    function Package_Node_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Package_Node_Of);
    --  Only valid for N_Variable_Reference or N_Attribute_Reference nodes.
    --  May return Empty_Node.
 
    function String_Type_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (String_Type_Of);
    --  Only valid for N_Variable_Reference or N_Typed_Variable_Declaration
    --  nodes.
 
    function External_Reference_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (External_Reference_Of);
    --  Only valid for N_External_Value nodes
 
    function External_Default_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (External_Default_Of);
    --  Only valid for N_External_Value nodes
 
    function Case_Variable_Reference_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Case_Variable_Reference_Of);
    --  Only valid for N_Case_Construction nodes
 
    function First_Case_Item_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_Case_Item_Of);
    --  Only valid for N_Case_Construction nodes
 
    function First_Choice_Of
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
-   --  Only valid for N_Case_Item nodes
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (First_Choice_Of);
+   --  Return the first choice in a N_Case_Item, or Empty_Node if
+   --  this is when others.
 
    function Next_Case_Item
-     (Node  : Project_Node_Id)
-      return  Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
+   pragma Inline (Next_Case_Item);
    --  Only valid for N_Case_Item nodes
 
+   function Case_Insensitive
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean;
+   --  Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes
+
    --------------------
    -- Set Procedures --
    --------------------
@@ -317,168 +574,325 @@ package Prj.Tree is
    --  nodes as the corresponding query function above.
 
    procedure Set_Name_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Name_Id);
+   pragma Inline (Set_Name_Of);
 
    procedure Set_Kind_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Kind);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Kind);
+   pragma Inline (Set_Kind_Of);
 
    procedure Set_Location_Of
-     (Node : Project_Node_Id;
-      To   : Source_Ptr);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Source_Ptr);
+   pragma Inline (Set_Location_Of);
+
+   procedure Set_First_Comment_After
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Comment_After);
+
+   procedure Set_First_Comment_After_End
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Comment_After_End);
+
+   procedure Set_First_Comment_Before
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Comment_Before);
+
+   procedure Set_First_Comment_Before_End
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Comment_Before_End);
+
+   procedure Set_Next_Comment
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Comment);
+
+   procedure Set_Project_File_Includes_Unkept_Comments
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Boolean);
 
    procedure Set_Directory_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Path_Name_Type);
+   pragma Inline (Set_Directory_Of);
 
    procedure Set_Expression_Kind_Of
-     (Node : Project_Node_Id;
-      To   : Variable_Kind);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Variable_Kind);
+   pragma Inline (Set_Expression_Kind_Of);
+
+   procedure Set_Is_Extending_All
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref);
+   pragma Inline (Set_Is_Extending_All);
+
+   procedure Set_Is_Not_Last_In_List
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref);
+   pragma Inline (Set_Is_Not_Last_In_List);
 
    procedure Set_First_Variable_Of
-     (Node : Project_Node_Id;
-      To   : Variable_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Variable_Node_Id);
+   pragma Inline (Set_First_Variable_Of);
 
    procedure Set_First_Package_Of
-     (Node : Project_Node_Id;
-      To   : Package_Declaration_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Package_Declaration_Id);
+   pragma Inline (Set_First_Package_Of);
 
    procedure Set_Package_Id_Of
-     (Node : Project_Node_Id;
-      To   : Package_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Package_Node_Id);
+   pragma Inline (Set_Package_Id_Of);
 
    procedure Set_Path_Name_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Path_Name_Type);
+   pragma Inline (Set_Path_Name_Of);
 
    procedure Set_String_Value_Of
-     (Node : Project_Node_Id;
-      To   : String_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Name_Id);
+   pragma Inline (Set_String_Value_Of);
 
    procedure Set_First_With_Clause_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_With_Clause_Of);
 
    procedure Set_Project_Declaration_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Project_Declaration_Of);
+
+   procedure Set_Extending_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Extending_Project_Of);
 
    procedure Set_First_String_Type_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_String_Type_Of);
 
-   procedure Set_Modified_Project_Path_Of
-     (Node : Project_Node_Id;
-      To   : String_Id);
+   procedure Set_Extended_Project_Path_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Path_Name_Type);
+   pragma Inline (Set_Extended_Project_Path_Of);
 
    procedure Set_Project_Node_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node         : Project_Node_Id;
+      In_Tree      : Project_Node_Tree_Ref;
+      To           : Project_Node_Id;
+      Limited_With : Boolean := False);
+   pragma Inline (Set_Project_Node_Of);
 
    procedure Set_Next_With_Clause_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_With_Clause_Of);
 
    procedure Set_First_Declarative_Item_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Declarative_Item_Of);
 
-   procedure Set_Modified_Project_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+   procedure Set_Extended_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Extended_Project_Of);
 
    procedure Set_Current_Item_Node
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Current_Item_Node);
 
    procedure Set_Next_Declarative_Item
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Declarative_Item);
 
    procedure Set_Project_Of_Renamed_Package_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Project_Of_Renamed_Package_Of);
 
    procedure Set_Next_Package_In_Project
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Package_In_Project);
 
    procedure Set_First_Literal_String
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Literal_String);
 
    procedure Set_Next_String_Type
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_String_Type);
 
    procedure Set_Next_Literal_String
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Literal_String);
 
    procedure Set_Expression_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Expression_Of);
+
+   procedure Set_Associative_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Associative_Project_Of);
+
+   procedure Set_Associative_Package_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Associative_Package_Of);
 
    procedure Set_Associative_Array_Index_Of
-     (Node : Project_Node_Id;
-      To   : String_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Name_Id);
+   pragma Inline (Set_Associative_Array_Index_Of);
 
    procedure Set_Next_Variable
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Variable);
 
    procedure Set_First_Term
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Term);
 
    procedure Set_Next_Expression_In_List
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Expression_In_List);
 
    procedure Set_Current_Term
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Current_Term);
 
    procedure Set_Next_Term
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Term);
 
    procedure Set_First_Expression_In_List
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Expression_In_List);
 
    procedure Set_Package_Node_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Package_Node_Of);
+
+   procedure Set_Source_Index_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Int);
+   pragma Inline (Set_Source_Index_Of);
 
    procedure Set_String_Type_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_String_Type_Of);
 
    procedure Set_External_Reference_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_External_Reference_Of);
 
    procedure Set_External_Default_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_External_Default_Of);
 
    procedure Set_Case_Variable_Reference_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Case_Variable_Reference_Of);
 
    procedure Set_First_Case_Item_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Case_Item_Of);
 
    procedure Set_First_Choice_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_First_Choice_Of);
 
    procedure Set_Next_Case_Item
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id);
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id);
+   pragma Inline (Set_Next_Case_Item);
+
+   procedure Set_Case_Insensitive
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Boolean);
 
    -------------------------------
    -- Restricted Access Section --
@@ -486,48 +900,96 @@ package Prj.Tree is
 
    package Tree_Private_Part is
 
-      --  This is conceptually in the private part.
-      --  However, for efficiency, some packages are accessing it directly.
+      --  This is conceptually in the private part
+
+      --  However, for efficiency, some packages are accessing it directly
 
       type Project_Node_Record is record
 
-         Kind        : Project_Node_Kind;
+         Kind : Project_Node_Kind;
 
-         Location    : Source_Ptr    := No_Location;
+         Location : Source_Ptr := No_Location;
 
-         Directory   : Name_Id       := No_Name;
+         Directory : Path_Name_Type := No_Path;
          --  Only for N_Project
 
-         Expr_Kind   : Variable_Kind := Undefined;
+         Expr_Kind : Variable_Kind := Undefined;
          --  See below for what Project_Node_Kind it is used
 
-         Variables   : Variable_Node_Id := Empty_Node;
+         Variables : Variable_Node_Id := Empty_Node;
          --  First variable in a project or a package
 
-         Packages    : Package_Declaration_Id := Empty_Node;
+         Packages : Package_Declaration_Id := Empty_Node;
          --  First package declaration in a project
 
-         Pkg_Id      : Package_Node_Id := Empty_Package;
-         --  Only use in Package_Declaration
-
-         Name        : Name_Id         := No_Name;
+         Pkg_Id : Package_Node_Id := Empty_Package;
+         --  Only used for N_Package_Declaration
+         --  The component Pkg_Id is an entry into the table Package_Attributes
+         --  (in Prj.Attr). It is used to indicate all the attributes of the
+         --  package with their characteristics.
+         --
+         --  The tables Prj.Attr.Attributes and Prj.Attr.Package_Attributes
+         --  are built once and for all through a call (from Prj.Initialize)
+         --  to procedure Prj.Attr.Initialize. It is never modified after that.
+
+         Name : Name_Id := No_Name;
          --  See below for what Project_Node_Kind it is used
 
-         Path_Name   : Name_Id         := No_Name;
+         Src_Index : Int := 0;
+         --  Index of a unit in a multi-unit source.
+         --  Onli for some N_Attribute_Declaration and N_Literal_String.
+
+         Path_Name : Path_Name_Type := No_Path;
          --  See below for what Project_Node_Kind it is used
 
-         Value       : String_Id       := No_String;
+         Value : Name_Id := No_Name;
          --  See below for what Project_Node_Kind it is used
 
-         Field1      : Project_Node_Id := Empty_Node;
+         Field1 : Project_Node_Id := Empty_Node;
          --  See below the meaning for each Project_Node_Kind
 
-         Field2      : Project_Node_Id := Empty_Node;
+         Field2 : Project_Node_Id := Empty_Node;
          --  See below the meaning for each Project_Node_Kind
 
-         Field3      : Project_Node_Id := Empty_Node;
+         Field3 : Project_Node_Id := Empty_Node;
          --  See below the meaning for each Project_Node_Kind
 
+         Flag1 : Boolean := False;
+         --  This flag is significant only for:
+         --    N_Attribute_Declaration and N_Atribute_Reference
+         --      It indicates for an associative array attribute, that the
+         --      index is case insensitive.
+         --    N_Comment - it indicates that the comment is preceded by an
+         --                empty line.
+         --    N_Project - it indicates that there are comments in the project
+         --                source that cannot be kept in the tree.
+         --    N_Project_Declaration
+         --              - it indicates that there are unkept comments in the
+         --                project.
+         --    N_With_Clause
+         --              - it indicates that this is not the last with in a
+         --                with clause. It is set for "A", but not for "B" in
+         --                    with "B";
+         --                  and
+         --                    with "A", "B";
+
+         Flag2 : Boolean := False;
+         --  This flag is significant only for:
+         --    N_Project - it indicates that the project "extends all" another
+         --                project.
+         --    N_Comment - it indicates that the comment is followed by an
+         --                empty line.
+         --    N_With_Clause
+         --              - it indicates that the originally imported project
+         --                is an extending all project.
+
+         Comments : Project_Node_Id := Empty_Node;
+         --  For nodes other that N_Comment_Zones or N_Comment, designates the
+         --  comment zones associated with the node.
+         --  for N_Comment_Zones, designates the comment after the "end" of
+         --  the construct.
+         --  For N_Comment, designates the next comment, if any.
+
       end record;
 
       --  type Project_Node_Kind is
@@ -539,7 +1001,7 @@ package Prj.Tree is
       --    --  Field1:    first with clause
       --    --  Field2:    project declaration
       --    --  Field3:    first string type
-      --    --  Value:     modified project path name (if any)
+      --    --  Value:     extended project path name (if any)
 
       --    N_With_Clause,
       --    --  Name:      imported project name
@@ -547,7 +1009,7 @@ package Prj.Tree is
       --    --  Expr_Kind: Undefined
       --    --  Field1:    project node
       --    --  Field2:    next with clause
-      --    --  Field3:    not used
+      --    --  Field3:    project node or empty if "limited with"
       --    --  Value:     literal string withed
 
       --    N_Project_Declaration,
@@ -555,8 +1017,8 @@ package Prj.Tree is
       --    --  Path_Name: not used
       --    --  Expr_Kind: Undefined
       --    --  Field1:    first declarative item
-      --    --  Field2:    modified project
-      --    --  Field3:    not used
+      --    --  Field2:    extended project
+      --    --  Field3:    extending project
       --    --  Value:     not used
 
       --    N_Declarative_Item,
@@ -600,8 +1062,8 @@ package Prj.Tree is
       --    --  Path_Name: not used
       --    --  Expr_Kind: attribute kind
       --    --  Field1:    expression
-      --    --  Field2:    not used
-      --    --  Field3:    not used
+      --    --  Field2:    project of full associative array
+      --    --  Field3:    package of full associative array
       --    --  Value:     associative array index
       --    --             (if an associative array element)
 
@@ -682,7 +1144,8 @@ package Prj.Tree is
       --    --  Field1:    project
       --    --  Field2:    package (if attribute of a package)
       --    --  Field3:    not used
-      --    --  Value:     not used
+      --    --  Value:     associative array index
+      --    --             (if an associative array element)
 
       --    N_Case_Construction,
       --    --  Name:      not used
@@ -693,38 +1156,69 @@ package Prj.Tree is
       --    --  Field3:    not used
       --    --  Value:     not used
 
-      --    N_Case_Item);
+      --    N_Case_Item
       --    --  Name:      not used
       --    --  Path_Name: not used
       --    --  Expr_Kind: not used
-      --    --  Field1:    first choice (literal string)
+      --    --  Field1:    first choice (literal string), or Empty_Node
+      --    --             for when others
       --    --  Field2:    first declarative item
       --    --  Field3:    next case item
       --    --  Value:     not used
 
-      package Project_Nodes is
-         new Table.Table (Table_Component_Type => Project_Node_Record,
-                          Table_Index_Type     => Project_Node_Id,
-                          Table_Low_Bound      => First_Node_Id,
-                          Table_Initial        => Project_Nodes_Initial,
-                          Table_Increment      => Project_Nodes_Increment,
-                          Table_Name           => "Project_Nodes");
+      --    N_Comment_zones
+      --    --  Name:      not used
+      --    --  Path_Name: not used
+      --    --  Expr_Kind: not used
+      --    --  Field1:    comment before the construct
+      --    --  Field2:    comment after the construct
+      --    --  Field3:    comment before the "end" of the construct
+      --    --  Value:     end of line comment
+      --    --  Comments:  comment after the "end" of the construct
+
+      --    N_Comment
+      --    --  Name:      not used
+      --    --  Path_Name: not used
+      --    --  Expr_Kind: not used
+      --    --  Field1:    not used
+      --    --  Field2:    not used
+      --    --  Field3:    not used
+      --    --  Value:     comment
+      --    --  Flag1:     comment is preceded by an empty line
+      --    --  Flag2:     comment is followed by an empty line
+      --    --  Comments:  next comment
+
+      package Project_Node_Table is
+        new GNAT.Dynamic_Tables
+          (Table_Component_Type => Project_Node_Record,
+           Table_Index_Type     => Project_Node_Id,
+           Table_Low_Bound      => First_Node_Id,
+           Table_Initial        => Project_Nodes_Initial,
+           Table_Increment      => Project_Nodes_Increment);
       --  This table contains the syntactic tree of project data
       --  from project files.
 
       type Project_Name_And_Node is record
-         Name     : Name_Id;
+         Name : Name_Id;
          --  Name of the project
-         Node     : Project_Node_Id;
+
+         Node : Project_Node_Id;
          --  Node of the project in table Project_Nodes
-         Modified : Boolean;
-         --  True when the project is being modified by another project
+
+         Canonical_Path : Path_Name_Type;
+         --  Resolved and canonical path of the project file
+
+         Extended : Boolean;
+         --  True when the project is being extended by another project
       end record;
 
       No_Project_Name_And_Node : constant Project_Name_And_Node :=
-        (Name => No_Name, Node => Empty_Node, Modified => True);
+        (Name           => No_Name,
+         Node           => Empty_Node,
+         Canonical_Path => No_Path,
+         Extended       => True);
 
-      package Projects_Htable is new GNAT.HTable.Simple_HTable
+      package Projects_Htable is new GNAT.Dynamic_HTables.Simple_HTable
         (Header_Num => Header_Num,
          Element    => Project_Name_And_Node,
          No_Element => No_Project_Name_And_Node,
@@ -733,10 +1227,31 @@ package Prj.Tree is
          Equal      => "=");
       --  This hash table contains a mapping of project names to project nodes.
       --  Note that this hash table contains only the nodes whose Kind is
-      --  N_Project. It is used to find the node of a project from its
-      --  name, and to verify if a project has already been parsed, knowing
-      --  its name.
+      --  N_Project. It is used to find the node of a project from its name,
+      --  and to verify if a project has already been parsed, knowing its name.
 
    end Tree_Private_Part;
 
+   type Project_Node_Tree_Data is record
+      Project_Nodes : Tree_Private_Part.Project_Node_Table.Instance;
+      Projects_HT   : Tree_Private_Part.Projects_Htable.Instance;
+   end record;
+   --  The data for a project node tree
+
+private
+   type Comment_Array is array (Positive range <>) of Comment_Data;
+   type Comments_Ptr is access Comment_Array;
+
+   type Comment_State is record
+      End_Of_Line_Node   : Project_Node_Id := Empty_Node;
+
+      Previous_Line_Node : Project_Node_Id := Empty_Node;
+
+      Previous_End_Node  : Project_Node_Id := Empty_Node;
+
+      Unkept_Comments    : Boolean := False;
+
+      Comments           : Comments_Ptr := null;
+   end record;
+
 end Prj.Tree;