OSDN Git Service

2010-10-05 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-tree.adb
index e2f7f2d..55f2195 100644 (file)
@@ -6,26 +6,29 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2001-2007, Free Software Foundation, Inc.         --
+--          Copyright (C) 2001-2010, 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- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- 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,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, USA.                                              --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Osint;   use Osint;
+with Prj.Env; use Prj.Env;
 with Prj.Err;
 
+with Ada.Unchecked_Deallocation;
+
 package body Prj.Tree is
 
    Node_With_Comments : constant array (Project_Node_Kind) of Boolean :=
@@ -95,36 +98,37 @@ package body Prj.Tree is
 
    begin
       pragma Assert
-        (To /= Empty_Node
-          and then
-         In_Tree.Project_Nodes.Table (To).Kind /= N_Comment);
+        (Present (To)
+          and then In_Tree.Project_Nodes.Table (To).Kind /= N_Comment);
 
       Zone := In_Tree.Project_Nodes.Table (To).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
 
          --  Create new N_Comment_Zones node
 
          Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
          In_Tree.Project_Nodes.Table
            (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
-           (Kind             => N_Comment_Zones,
-            Expr_Kind        => Undefined,
-            Location         => No_Location,
-            Directory        => No_Path,
-            Variables        => Empty_Node,
-            Packages         => Empty_Node,
-            Pkg_Id           => Empty_Package,
-            Name             => No_Name,
-            Src_Index        => 0,
-            Path_Name        => No_Path,
-            Value            => No_Name,
-            Field1           => Empty_Node,
-            Field2           => Empty_Node,
-            Field3           => Empty_Node,
-            Flag1            => False,
-            Flag2            => False,
-            Comments         => Empty_Node);
+           (Kind      => N_Comment_Zones,
+            Qualifier => Unspecified,
+            Expr_Kind => Undefined,
+            Location  => No_Location,
+            Directory => No_Path,
+            Variables => Empty_Node,
+            Packages  => Empty_Node,
+            Pkg_Id    => Empty_Package,
+            Name      => No_Name,
+            Src_Index => 0,
+            Path_Name => No_Path,
+            Value     => No_Name,
+            Field1    => Empty_Node,
+            Field2    => Empty_Node,
+            Field3    => Empty_Node,
+            Field4    => Empty_Node,
+            Flag1     => False,
+            Flag2     => False,
+            Comments  => Empty_Node);
 
          Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
          In_Tree.Project_Nodes.Table (To).Comments := Zone;
@@ -154,6 +158,7 @@ package body Prj.Tree is
             In_Tree.Project_Nodes.Table
               (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
               (Kind             => N_Comment,
+               Qualifier        => Unspecified,
                Expr_Kind        => Undefined,
                Flag1            => Comments.Table (J).Follows_Empty_Line,
                Flag2            =>
@@ -170,12 +175,13 @@ package body Prj.Tree is
                Field1           => Empty_Node,
                Field2           => Empty_Node,
                Field3           => Empty_Node,
+               Field4           => Empty_Node,
                Comments         => Empty_Node);
 
             --  If this is the first comment, put it in the right field of
             --  the node Zone.
 
-            if Previous = Empty_Node then
+            if No (Previous) then
                case Where is
                   when Before =>
                      In_Tree.Project_Nodes.Table (Zone).Field1 :=
@@ -227,7 +233,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
@@ -245,7 +251,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
           (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
       return In_Tree.Project_Nodes.Table (Node).Field3;
@@ -261,7 +267,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
           (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -276,7 +282,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
@@ -294,7 +300,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -311,17 +317,18 @@ package body Prj.Tree is
       Zone : Project_Node_Id;
 
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
       --  If there is not already an N_Comment_Zones associated, create a new
       --  one and associate it with node Node.
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
          Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
          In_Tree.Project_Nodes.Table (Zone) :=
         (Kind             => N_Comment_Zones,
+         Qualifier        => Unspecified,
          Location         => No_Location,
          Directory        => No_Path,
          Expr_Kind        => Undefined,
@@ -335,6 +342,7 @@ package body Prj.Tree is
          Field1           => Empty_Node,
          Field2           => Empty_Node,
          Field3           => Empty_Node,
+         Field4           => Empty_Node,
          Flag1            => False,
          Flag2            => False,
          Comments         => Empty_Node);
@@ -354,7 +362,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -370,7 +378,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -396,6 +404,7 @@ package body Prj.Tree is
       In_Tree.Project_Nodes.Table
         (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
         (Kind             => Of_Kind,
+         Qualifier        => Unspecified,
          Location         => No_Location,
          Directory        => No_Path,
          Expr_Kind        => And_Expr_Kind,
@@ -409,6 +418,7 @@ package body Prj.Tree is
          Field1           => Empty_Node,
          Field2           => Empty_Node,
          Field3           => Empty_Node,
+         Field4           => Empty_Node,
          Flag1            => False,
          Flag2            => False,
          Comments         => Empty_Node);
@@ -430,6 +440,7 @@ package body Prj.Tree is
             In_Tree.Project_Nodes.Table
               (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
               (Kind             => N_Comment_Zones,
+               Qualifier        => Unspecified,
                Expr_Kind        => Undefined,
                Location         => No_Location,
                Directory        => No_Path,
@@ -443,6 +454,7 @@ package body Prj.Tree is
                Field1           => Empty_Node,
                Field2           => Empty_Node,
                Field3           => Empty_Node,
+               Field4           => Empty_Node,
                Flag1            => False,
                Flag2            => False,
                Comments         => Empty_Node);
@@ -459,6 +471,7 @@ package body Prj.Tree is
                In_Tree.Project_Nodes.Table
                  (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
                  (Kind             => N_Comment,
+                  Qualifier        => Unspecified,
                   Expr_Kind        => Undefined,
                   Flag1            => Comments.Table (J).Follows_Empty_Line,
                   Flag2            =>
@@ -475,12 +488,13 @@ package body Prj.Tree is
                   Field1           => Empty_Node,
                   Field2           => Empty_Node,
                   Field3           => Empty_Node,
+                  Field4           => Empty_Node,
                   Comments         => Empty_Node);
 
                --  Link it to the N_Comment_Zones node, if it is the first,
                --  otherwise to the previous one.
 
-               if Previous = Empty_Node then
+               if No (Previous) then
                   In_Tree.Project_Nodes.Table (Zone).Field1 :=
                     Project_Node_Table.Last (In_Tree.Project_Nodes);
 
@@ -513,7 +527,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Path_Name_Type is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       return In_Tree.Project_Nodes.Table (Node).Directory;
@@ -529,10 +543,10 @@ package body Prj.Tree is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return No_Name;
       else
          return In_Tree.Project_Nodes.Table (Zone).Value;
@@ -548,7 +562,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Variable_Kind is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
            and then
              (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
                 or else
@@ -583,7 +597,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Attribute_Declaration
@@ -607,7 +621,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -623,7 +637,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       return Path_Name_Type (In_Tree.Project_Nodes.Table (Node).Value);
@@ -638,7 +652,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
       return In_Tree.Project_Nodes.Table (Node).Field3;
@@ -654,7 +668,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -671,7 +685,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -687,7 +701,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -704,7 +718,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -720,10 +734,10 @@ package body Prj.Tree is
    is
       Zone : Project_Node_Id := Empty_Node;
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
@@ -743,10 +757,10 @@ package body Prj.Tree is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
@@ -765,10 +779,10 @@ package body Prj.Tree is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
@@ -787,10 +801,10 @@ package body Prj.Tree is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
@@ -808,7 +822,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration
                or else
@@ -833,7 +847,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -849,7 +863,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
          In_Tree.Project_Nodes.Table (Node).Kind =
            N_String_Type_Declaration);
@@ -866,7 +880,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       return In_Tree.Project_Nodes.Table (Node).Packages;
@@ -882,7 +896,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       return In_Tree.Project_Nodes.Table (Node).Field3;
@@ -898,7 +912,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -914,7 +928,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
@@ -933,7 +947,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -948,7 +962,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
          and then
          In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
       return In_Tree.Project_Nodes.Table (Node).Flag1;
@@ -971,8 +985,29 @@ package body Prj.Tree is
    begin
       Project_Node_Table.Init (Tree.Project_Nodes);
       Projects_Htable.Reset (Tree.Projects_HT);
+
+      --  Do not reset the external references, in case we are reloading a
+      --  project, since we want to preserve the current environment
+      --  Name_To_Name_HTable.Reset (Tree.External_References);
    end Initialize;
 
+   ----------
+   -- Free --
+   ----------
+
+   procedure Free (Proj : in out Project_Node_Tree_Ref) is
+      procedure Unchecked_Free is new Ada.Unchecked_Deallocation
+        (Project_Node_Tree_Data, Project_Node_Tree_Ref);
+   begin
+      if Proj /= null then
+         Project_Node_Table.Free (Proj.Project_Nodes);
+         Projects_Htable.Reset (Proj.Projects_HT);
+         Name_To_Name_HTable.Reset (Proj.External_References);
+         Free (Proj.Project_Path);
+         Unchecked_Free (Proj);
+      end if;
+   end Free;
+
    -------------------------------
    -- Is_Followed_By_Empty_Line --
    -------------------------------
@@ -983,7 +1018,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
       return In_Tree.Project_Nodes.Table (Node).Flag2;
@@ -998,7 +1033,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
               or else
@@ -1015,7 +1050,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
       return In_Tree.Project_Nodes.Table (Node).Flag1;
@@ -1037,29 +1072,29 @@ package body Prj.Tree is
    begin
       --  First check all the imported projects
 
-      while With_Clause /= Empty_Node loop
+      while Present (With_Clause) loop
 
          --  Only non limited imported project may be used as prefix
          --  of variable or attributes.
 
          Result := Non_Limited_Project_Node_Of (With_Clause, In_Tree);
-         exit when Result /= Empty_Node
+         exit when Present (Result)
            and then Name_Of (Result, In_Tree) = With_Name;
          With_Clause := Next_With_Clause_Of (With_Clause, In_Tree);
       end loop;
 
-      --  If it is not an imported project, it might be the imported project
+      --  If it is not an imported project, it might be an extended project
 
-      if With_Clause = Empty_Node then
-         Result :=
-           Extended_Project_Of
-             (Project_Declaration_Of (Project, In_Tree), In_Tree);
+      if No (With_Clause) then
+         Result := Project;
+         loop
+            Result :=
+              Extended_Project_Of
+                (Project_Declaration_Of (Result, In_Tree), In_Tree);
 
-         if Result /= Empty_Node
-           and then Name_Of (Result, In_Tree) /= With_Name
-         then
-            Result := Empty_Node;
-         end if;
+            exit when No (Result)
+              or else Name_Of (Result, In_Tree) = With_Name;
+         end loop;
       end if;
 
       return Result;
@@ -1073,7 +1108,7 @@ package body Prj.Tree is
      (Node    : Project_Node_Id;
       In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind is
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       return In_Tree.Project_Nodes.Table (Node).Kind;
    end Kind_Of;
 
@@ -1085,7 +1120,7 @@ package body Prj.Tree is
      (Node    : Project_Node_Id;
       In_Tree : Project_Node_Tree_Ref) return Source_Ptr is
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       return In_Tree.Project_Nodes.Table (Node).Location;
    end Location_Of;
 
@@ -1097,7 +1132,7 @@ package body Prj.Tree is
      (Node    : Project_Node_Id;
       In_Tree : Project_Node_Tree_Ref) return Name_Id is
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       return In_Tree.Project_Nodes.Table (Node).Name;
    end Name_Of;
 
@@ -1111,7 +1146,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
       return In_Tree.Project_Nodes.Table (Node).Field3;
@@ -1126,7 +1161,7 @@ package body Prj.Tree is
       In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
       return In_Tree.Project_Nodes.Table (Node).Comments;
@@ -1142,7 +1177,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -1158,7 +1193,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -1175,7 +1210,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -1191,7 +1226,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
       return In_Tree.Project_Nodes.Table (Node).Field3;
@@ -1208,7 +1243,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
          In_Tree.Project_Nodes.Table (Node).Kind =
            N_String_Type_Declaration);
@@ -1225,7 +1260,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
       return In_Tree.Project_Nodes.Table (Node).Field2;
@@ -1242,7 +1277,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Typed_Variable_Declaration
@@ -1263,12 +1298,21 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
       return In_Tree.Project_Nodes.Table (Node).Field2;
    end Next_With_Clause_Of;
 
+   --------
+   -- No --
+   --------
+
+   function No (Node : Project_Node_Id) return Boolean is
+   begin
+      return Node = Empty_Node;
+   end No;
+
    ---------------------------------
    -- Non_Limited_Project_Node_Of --
    ---------------------------------
@@ -1279,7 +1323,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
       return In_Tree.Project_Nodes.Table (Node).Field3;
@@ -1295,7 +1339,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
       return In_Tree.Project_Nodes.Table (Node).Pkg_Id;
@@ -1311,7 +1355,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                or else
@@ -1329,7 +1373,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
@@ -1337,6 +1381,15 @@ package body Prj.Tree is
       return In_Tree.Project_Nodes.Table (Node).Path_Name;
    end Path_Name_Of;
 
+   -------------
+   -- Present --
+   -------------
+
+   function Present (Node : Project_Node_Id) return Boolean is
+   begin
+      return Node /= Empty_Node;
+   end Present;
+
    ----------------------------
    -- Project_Declaration_Of --
    ----------------------------
@@ -1347,12 +1400,44 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       return In_Tree.Project_Nodes.Table (Node).Field2;
    end Project_Declaration_Of;
 
+   --------------------------
+   -- Project_Qualifier_Of --
+   --------------------------
+
+   function Project_Qualifier_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Qualifier
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Qualifier;
+   end Project_Qualifier_Of;
+
+   -----------------------
+   -- Parent_Project_Of --
+   -----------------------
+
+   function Parent_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Field4;
+   end Parent_Project_Of;
+
    -------------------------------------------
    -- Project_File_Includes_Unkept_Comments --
    -------------------------------------------
@@ -1377,7 +1462,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
               or else
@@ -1397,7 +1482,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
       return In_Tree.Project_Nodes.Table (Node).Field1;
@@ -1425,11 +1510,14 @@ package body Prj.Tree is
       Comments.Set_Last (0);
    end Reset_State;
 
-   -------------
-   -- Restore --
-   -------------
+   ----------------------
+   -- Restore_And_Free --
+   ----------------------
+
+   procedure Restore_And_Free (S : in out Comment_State) is
+      procedure Unchecked_Free is new
+        Ada.Unchecked_Deallocation (Comment_Array, Comments_Ptr);
 
-   procedure Restore (S : Comment_State) is
    begin
       End_Of_Line_Node   := S.End_Of_Line_Node;
       Previous_Line_Node := S.Previous_Line_Node;
@@ -1443,7 +1531,9 @@ package body Prj.Tree is
          Comments.Increment_Last;
          Comments.Table (Comments.Last) := S.Comments (J);
       end loop;
-   end Restore;
+
+      Unchecked_Free (S.Comments);
+   end Restore_And_Free;
 
    ----------
    -- Save --
@@ -1513,7 +1603,7 @@ package body Prj.Tree is
                --  an end of line node specified, associate the comment with
                --  this node.
 
-               elsif End_Of_Line_Node /= Empty_Node then
+               elsif Present (End_Of_Line_Node) then
                   declare
                      Zones : constant Project_Node_Id :=
                                Comment_Zones_Of (End_Of_Line_Node, In_Tree);
@@ -1538,13 +1628,13 @@ package body Prj.Tree is
 
                if Comments.Last > 0 and then
                  not Comments.Table (1).Follows_Empty_Line then
-                  if Previous_Line_Node /= Empty_Node then
+                  if Present (Previous_Line_Node) then
                      Add_Comments
                        (To      => Previous_Line_Node,
                         Where   => After,
                         In_Tree => In_Tree);
 
-                  elsif Previous_End_Node /= Empty_Node then
+                  elsif Present (Previous_End_Node) then
                      Add_Comments
                        (To      => Previous_End_Node,
                         Where   => After_End,
@@ -1596,7 +1686,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
@@ -1615,7 +1705,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-         (Node /= Empty_Node
+         (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration);
       In_Tree.Project_Nodes.Table (Node).Field3 := To;
@@ -1632,7 +1722,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Attribute_Declaration));
@@ -1650,7 +1740,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
@@ -1669,7 +1759,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -1686,7 +1776,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -1703,7 +1793,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -1720,7 +1810,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       In_Tree.Project_Nodes.Table (Node).Directory := To;
@@ -1746,7 +1836,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
            and then
              (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
                 or else
@@ -1781,7 +1871,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Attribute_Declaration
@@ -1805,7 +1895,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -1822,7 +1912,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -1839,7 +1929,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -1856,7 +1946,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -1930,7 +2020,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
       In_Tree.Project_Nodes.Table (Node).Field3 := To;
@@ -1947,7 +2037,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
       In_Tree.Project_Nodes.Table (Node).Comments := To;
@@ -1964,7 +2054,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration
                or else
@@ -1990,7 +2080,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -2007,7 +2097,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
          In_Tree.Project_Nodes.Table (Node).Kind =
            N_String_Type_Declaration);
@@ -2025,7 +2115,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       In_Tree.Project_Nodes.Table (Node).Packages := To;
@@ -2042,7 +2132,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       In_Tree.Project_Nodes.Table (Node).Field3 := To;
@@ -2059,7 +2149,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -2076,7 +2166,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
@@ -2095,7 +2185,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -2111,7 +2201,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
@@ -2129,7 +2219,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
              In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
       In_Tree.Project_Nodes.Table (Node).Flag1 := True;
@@ -2145,7 +2235,7 @@ package body Prj.Tree is
       To      : Project_Node_Kind)
    is
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       In_Tree.Project_Nodes.Table (Node).Kind := To;
    end Set_Kind_Of;
 
@@ -2159,7 +2249,7 @@ package body Prj.Tree is
       To      : Source_Ptr)
    is
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       In_Tree.Project_Nodes.Table (Node).Location := To;
    end Set_Location_Of;
 
@@ -2174,7 +2264,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -2191,7 +2281,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       In_Tree.Project_Nodes.Table (Node).Value := Name_Id (To);
@@ -2208,7 +2298,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
       In_Tree.Project_Nodes.Table (Node).Field3 := To;
@@ -2224,7 +2314,7 @@ package body Prj.Tree is
       To      : Name_Id)
    is
    begin
-      pragma Assert (Node /= Empty_Node);
+      pragma Assert (Present (Node));
       In_Tree.Project_Nodes.Table (Node).Name := To;
    end Set_Name_Of;
 
@@ -2239,7 +2329,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -2266,7 +2356,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -2283,7 +2373,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -2300,7 +2390,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
       In_Tree.Project_Nodes.Table (Node).Field3 := To;
@@ -2317,7 +2407,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
          In_Tree.Project_Nodes.Table (Node).Kind =
            N_String_Type_Declaration);
@@ -2335,7 +2425,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -2352,7 +2442,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Typed_Variable_Declaration
@@ -2373,7 +2463,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
@@ -2390,7 +2480,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
       In_Tree.Project_Nodes.Table (Node).Pkg_Id := To;
@@ -2407,7 +2497,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                or else
@@ -2426,7 +2516,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
@@ -2462,12 +2552,44 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
          and then
            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
       In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Project_Declaration_Of;
 
+   ------------------------------
+   -- Set_Project_Qualifier_Of --
+   ------------------------------
+
+   procedure Set_Project_Qualifier_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Qualifier)
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Qualifier := To;
+   end Set_Project_Qualifier_Of;
+
+   ---------------------------
+   -- Set_Parent_Project_Of --
+   ---------------------------
+
+   procedure Set_Parent_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Field4 := To;
+   end Set_Parent_Project_Of;
+
    -----------------------------------------------
    -- Set_Project_File_Includes_Unkept_Comments --
    -----------------------------------------------
@@ -2495,7 +2617,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
                or else
@@ -2522,7 +2644,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
       In_Tree.Project_Nodes.Table (Node).Field1 := To;
@@ -2539,7 +2661,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
             or else
@@ -2559,7 +2681,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Variable_Reference
@@ -2587,7 +2709,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
                or else
@@ -2607,7 +2729,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
             (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
               or else
@@ -2626,7 +2748,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind =
               N_Variable_Reference
@@ -2651,7 +2773,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
               or else
@@ -2672,7 +2794,7 @@ package body Prj.Tree is
    is
    begin
       pragma Assert
-        (For_Typed_Variable /= Empty_Node
+        (Present (For_Typed_Variable)
           and then
            (In_Tree.Project_Nodes.Table (For_Typed_Variable).Kind =
                                      N_Typed_Variable_Declaration));
@@ -2684,7 +2806,7 @@ package body Prj.Tree is
                                In_Tree);
 
       begin
-         while Current_String /= Empty_Node
+         while Present (Current_String)
            and then
              String_Value_Of (Current_String, In_Tree) /= Value
          loop
@@ -2692,7 +2814,7 @@ package body Prj.Tree is
               Next_Literal_String (Current_String, In_Tree);
          end loop;
 
-         return Current_String /= Empty_Node;
+         return Present (Current_String);
       end;
 
    end Value_Is_Valid;
@@ -2706,4 +2828,283 @@ package body Prj.Tree is
       return Unkept_Comments;
    end There_Are_Unkept_Comments;
 
+   --------------------
+   -- Create_Project --
+   --------------------
+
+   function Create_Project
+     (In_Tree        : Project_Node_Tree_Ref;
+      Name           : Name_Id;
+      Full_Path      : Path_Name_Type;
+      Is_Config_File : Boolean := False) return Project_Node_Id
+   is
+      Project   : Project_Node_Id;
+      Qualifier : Project_Qualifier := Unspecified;
+   begin
+      Project := Default_Project_Node (In_Tree, N_Project);
+      Set_Name_Of (Project, In_Tree, Name);
+      Set_Directory_Of
+        (Project, In_Tree,
+         Path_Name_Type (Get_Directory (File_Name_Type (Full_Path))));
+      Set_Path_Name_Of (Project, In_Tree, Full_Path);
+
+      Set_Project_Declaration_Of
+        (Project, In_Tree,
+         Default_Project_Node (In_Tree, N_Project_Declaration));
+
+      if Is_Config_File then
+         Qualifier := Configuration;
+      end if;
+
+      if not Is_Config_File then
+         Prj.Tree.Tree_Private_Part.Projects_Htable.Set
+           (In_Tree.Projects_HT,
+            Name,
+            Prj.Tree.Tree_Private_Part.Project_Name_And_Node'
+              (Name           => Name,
+               Display_Name   => Name,
+               Canonical_Path => No_Path,
+               Node           => Project,
+               Extended       => False,
+               Proj_Qualifier => Qualifier));
+      end if;
+
+      return Project;
+   end Create_Project;
+
+   ----------------
+   -- Add_At_End --
+   ----------------
+
+   procedure Add_At_End
+     (Tree                  : Project_Node_Tree_Ref;
+      Parent                : Project_Node_Id;
+      Expr                  : Project_Node_Id;
+      Add_Before_First_Pkg  : Boolean := False;
+      Add_Before_First_Case : Boolean := False)
+   is
+      Real_Parent          : Project_Node_Id;
+      New_Decl, Decl, Next : Project_Node_Id;
+      Last, L              : Project_Node_Id;
+
+   begin
+      if Kind_Of (Expr, Tree) /= N_Declarative_Item then
+         New_Decl := Default_Project_Node (Tree, N_Declarative_Item);
+         Set_Current_Item_Node (New_Decl, Tree, Expr);
+      else
+         New_Decl := Expr;
+      end if;
+
+      if Kind_Of (Parent, Tree) = N_Project then
+         Real_Parent := Project_Declaration_Of (Parent, Tree);
+      else
+         Real_Parent := Parent;
+      end if;
+
+      Decl := First_Declarative_Item_Of (Real_Parent, Tree);
+
+      if Decl = Empty_Node then
+         Set_First_Declarative_Item_Of (Real_Parent, Tree, New_Decl);
+      else
+         loop
+            Next := Next_Declarative_Item (Decl, Tree);
+            exit when Next = Empty_Node
+              or else
+               (Add_Before_First_Pkg
+                 and then Kind_Of (Current_Item_Node (Next, Tree), Tree) =
+                                                        N_Package_Declaration)
+              or else
+               (Add_Before_First_Case
+                 and then Kind_Of (Current_Item_Node (Next, Tree), Tree) =
+                                                        N_Case_Construction);
+            Decl := Next;
+         end loop;
+
+         --  In case Expr is in fact a range of declarative items
+
+         Last := New_Decl;
+         loop
+            L := Next_Declarative_Item (Last, Tree);
+            exit when L = Empty_Node;
+            Last := L;
+         end loop;
+
+         --  In case Expr is in fact a range of declarative items
+
+         Last := New_Decl;
+         loop
+            L := Next_Declarative_Item (Last, Tree);
+            exit when L = Empty_Node;
+            Last := L;
+         end loop;
+
+         Set_Next_Declarative_Item (Last, Tree, Next);
+         Set_Next_Declarative_Item (Decl, Tree, New_Decl);
+      end if;
+   end Add_At_End;
+
+   ---------------------------
+   -- Create_Literal_String --
+   ---------------------------
+
+   function Create_Literal_String
+     (Str  : Namet.Name_Id;
+      Tree : Project_Node_Tree_Ref) return Project_Node_Id
+   is
+      Node : Project_Node_Id;
+   begin
+      Node := Default_Project_Node (Tree, N_Literal_String, Prj.Single);
+      Set_Next_Literal_String (Node, Tree, Empty_Node);
+      Set_String_Value_Of (Node, Tree, Str);
+      return Node;
+   end Create_Literal_String;
+
+   ---------------------------
+   -- Enclose_In_Expression --
+   ---------------------------
+
+   function Enclose_In_Expression
+     (Node : Project_Node_Id;
+      Tree : Project_Node_Tree_Ref) return Project_Node_Id
+   is
+      Expr : Project_Node_Id;
+   begin
+      if Kind_Of (Node, Tree) /= N_Expression then
+         Expr := Default_Project_Node (Tree, N_Expression, Single);
+         Set_First_Term
+           (Expr, Tree, Default_Project_Node (Tree, N_Term, Single));
+         Set_Current_Term (First_Term (Expr, Tree), Tree, Node);
+         return Expr;
+      else
+         return Node;
+      end if;
+   end Enclose_In_Expression;
+
+   --------------------
+   -- Create_Package --
+   --------------------
+
+   function Create_Package
+     (Tree    : Project_Node_Tree_Ref;
+      Project : Project_Node_Id;
+      Pkg     : String) return Project_Node_Id
+   is
+      Pack : Project_Node_Id;
+      N    : Name_Id;
+
+   begin
+      Name_Len := Pkg'Length;
+      Name_Buffer (1 .. Name_Len) := Pkg;
+      N := Name_Find;
+
+      --  Check if the package already exists
+
+      Pack := First_Package_Of (Project, Tree);
+      while Pack /= Empty_Node loop
+         if Prj.Tree.Name_Of (Pack, Tree) = N then
+            return Pack;
+         end if;
+
+         Pack := Next_Package_In_Project (Pack, Tree);
+      end loop;
+
+      --  Create the package and add it to the declarative item
+
+      Pack := Default_Project_Node (Tree, N_Package_Declaration);
+      Set_Name_Of (Pack, Tree, N);
+
+      --  Find the correct package id to use
+
+      Set_Package_Id_Of (Pack, Tree, Package_Node_Id_Of (N));
+
+      --  Add it to the list of packages
+
+      Set_Next_Package_In_Project
+        (Pack, Tree, First_Package_Of (Project, Tree));
+      Set_First_Package_Of (Project, Tree, Pack);
+
+      Add_At_End (Tree, Project_Declaration_Of (Project, Tree), Pack);
+
+      return Pack;
+   end Create_Package;
+
+   ----------------------
+   -- Create_Attribute --
+   ----------------------
+
+   function Create_Attribute
+     (Tree       : Project_Node_Tree_Ref;
+      Prj_Or_Pkg : Project_Node_Id;
+      Name       : Name_Id;
+      Index_Name : Name_Id       := No_Name;
+      Kind       : Variable_Kind := List;
+      At_Index   : Integer       := 0;
+      Value      : Project_Node_Id := Empty_Node) return Project_Node_Id
+   is
+      Node : constant Project_Node_Id :=
+               Default_Project_Node (Tree, N_Attribute_Declaration, Kind);
+
+      Case_Insensitive : Boolean;
+
+      Pkg      : Package_Node_Id;
+      Start_At : Attribute_Node_Id;
+      Expr     : Project_Node_Id;
+
+   begin
+      Set_Name_Of (Node, Tree, Name);
+
+      if Index_Name /= No_Name then
+         Set_Associative_Array_Index_Of (Node, Tree, Index_Name);
+      end if;
+
+      if Prj_Or_Pkg /= Empty_Node then
+         Add_At_End (Tree, Prj_Or_Pkg, Node);
+      end if;
+
+      --  Find out the case sensitivity of the attribute
+
+      if Prj_Or_Pkg /= Empty_Node
+        and then Kind_Of (Prj_Or_Pkg, Tree) = N_Package_Declaration
+      then
+         Pkg      := Prj.Attr.Package_Node_Id_Of (Name_Of (Prj_Or_Pkg, Tree));
+         Start_At := First_Attribute_Of (Pkg);
+      else
+         Start_At := Attribute_First;
+      end if;
+
+      Start_At := Attribute_Node_Id_Of (Name, Start_At);
+      Case_Insensitive :=
+        Attribute_Kind_Of (Start_At) = Case_Insensitive_Associative_Array;
+      Tree.Project_Nodes.Table (Node).Flag1 := Case_Insensitive;
+
+      if At_Index /= 0 then
+         if Attribute_Kind_Of (Start_At) =
+              Optional_Index_Associative_Array
+           or else Attribute_Kind_Of (Start_At) =
+              Optional_Index_Case_Insensitive_Associative_Array
+         then
+            --  Results in:   for Name ("index" at index) use "value";
+            --  This is currently only used for executables.
+
+            Set_Source_Index_Of (Node, Tree, To => Int (At_Index));
+
+         else
+            --  Results in:   for Name ("index") use "value" at index;
+
+            --  ??? This limitation makes no sense, we should be able to
+            --  set the source index on an expression.
+
+            pragma Assert (Kind_Of (Value, Tree) = N_Literal_String);
+            Set_Source_Index_Of (Value, Tree, To => Int (At_Index));
+         end if;
+      end if;
+
+      if Value /= Empty_Node then
+         Expr := Enclose_In_Expression (Value, Tree);
+         Set_Expression_Of (Node, Tree, Expr);
+      end if;
+
+      return Node;
+   end Create_Attribute;
+
 end Prj.Tree;