OSDN Git Service

2009-04-24 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-nmsc.adb
index 4b28224..7c3677b 100644 (file)
@@ -72,9 +72,10 @@ package body Prj.Nmsc is
       Except   : Boolean := False;
       Found    : Boolean := False;
    end record;
-   --  Information about file names found in string list attribute
-   --  Source_Files or in a source list file, stored in hash table
+   --  Information about file names found in string list attribute:
+   --  Source_Files or in a source list file, stored in hash table.
    --  Source_Names, used by procedure Get_Path_Names_And_Record_Sources.
+   --  Except is set to True if source is a naming exception in the project.
 
    No_Name_Location : constant Name_Location :=
                         (Name     => No_File,
@@ -217,19 +218,16 @@ package body Prj.Nmsc is
 
    procedure Load_Naming_Exceptions
      (Project : Project_Id;
-      In_Tree : Project_Tree_Ref;
-      Data    : in out Project_Data);
+      In_Tree : Project_Tree_Ref);
    --  All source files in Data.First_Source are considered as naming
    --  exceptions, and copied into the Source_Names and Unit_Exceptions tables
    --  as appropriate.
 
    procedure Add_Source
      (Id                  : out Source_Id;
-      Data                : in out Project_Data;
       In_Tree             : Project_Tree_Ref;
       Project             : Project_Id;
-      Lang                : Name_Id;
-      Lang_Id             : Language_Index;
+      Lang_Id             : Language_Ptr;
       Kind                : Source_Kind;
       File_Name           : File_Name_Type;
       Display_File        : File_Name_Type;
@@ -361,13 +359,6 @@ package body Prj.Nmsc is
    --  Find the path names of the source files in the Source_Names table
    --  in the source directories and record those that are Ada sources.
 
-   function Get_Language_Processing_From_Lang
-     (In_Tree : Project_Tree_Ref;
-      Data    : Project_Data;
-      Lang    : Name_List_Index) return Language_Index;
-   --  Return the language_processing description associated for the given
-   --  language.
-
    function Compute_Directory_Last (Dir : String) return Natural;
    --  Return the index of the last significant character in Dir. This is used
    --  to avoid duplicate '/' (slash) characters at the end of directory names.
@@ -433,7 +424,7 @@ package body Prj.Nmsc is
       Data                  : in out Project_Data;
       File_Name             : File_Name_Type;
       Alternate_Languages   : out Alternate_Language_Id;
-      Language              : out Language_Index;
+      Language              : out Language_Ptr;
       Language_Name         : out Name_Id;
       Display_Language_Name : out Name_Id;
       Unit                  : out Name_Id;
@@ -496,7 +487,8 @@ package body Prj.Nmsc is
       Spec_Suffix     : File_Name_Type;
       Casing          : Casing_Type;
       Kind            : out Source_Kind;
-      Unit            : out Name_Id);
+      Unit            : out Name_Id;
+      In_Tree         : Project_Tree_Ref);
    --  Check whether the file matches the naming scheme. If it does,
    --  compute its unit name. If Unit is set to No_Name on exit, none of the
    --  other out parameters are relevant.
@@ -587,10 +579,7 @@ package body Prj.Nmsc is
 
    procedure Remove_Source
      (Id          : Source_Id;
-      Replaced_By : Source_Id;
-      Project     : Project_Id;
-      Data        : in out Project_Data;
-      In_Tree     : Project_Tree_Ref);
+      Replaced_By : Source_Id);
    --  ??? needs comment
 
    procedure Report_No_Sources
@@ -693,11 +682,9 @@ package body Prj.Nmsc is
 
    procedure Add_Source
      (Id                  : out Source_Id;
-      Data                : in out Project_Data;
       In_Tree             : Project_Tree_Ref;
       Project             : Project_Id;
-      Lang                : Name_Id;
-      Lang_Id             : Language_Index;
+      Lang_Id             : Language_Ptr;
       Kind                : Source_Kind;
       File_Name           : File_Name_Type;
       Display_File        : File_Name_Type;
@@ -711,66 +698,60 @@ package body Prj.Nmsc is
       Index               : Int       := 0;
       Source_To_Replace   : Source_Id := No_Source)
    is
-      Source   : constant Source_Id := Data.Last_Source;
-      Src_Data : Source_Data := No_Source_Data;
-      Config   : constant Language_Config :=
-                   In_Tree.Languages_Data.Table (Lang_Id).Config;
+      Config   : constant Language_Config := Lang_Id.Config;
 
    begin
-      --  This is a new source so create an entry for it in the Sources table
-
-      Source_Data_Table.Increment_Last (In_Tree.Sources);
-      Id := Source_Data_Table.Last (In_Tree.Sources);
+      Id := new Source_Data;
 
       if Current_Verbosity = High then
-         Write_Str ("Adding source #");
-         Write_Str (Id'Img);
-         Write_Str (", File : ");
+         Write_Str ("Adding source File: ");
          Write_Str (Get_Name_String (File_Name));
 
          if Lang_Kind = Unit_Based then
-            Write_Str (", Unit : ");
-            Write_Str (Get_Name_String (Unit));
+            Write_Str (" Unit: ");
+            --  ??? in gprclean, it seems we sometimes pass an empty Unit name
+            --  (see test extended_projects)
+            if Unit /= No_Name then
+               Write_Str (Get_Name_String (Unit));
+            end if;
+            Write_Str (" Kind: ");
+            Write_Str (Source_Kind'Image (Kind));
          end if;
 
          Write_Eol;
       end if;
 
-      Src_Data.Project             := Project;
-      Src_Data.Language            := Lang_Id;
-      Src_Data.Lang_Kind           := Lang_Kind;
-      Src_Data.Compiled            := In_Tree.Languages_Data.Table
-                                        (Lang_Id).Config.Compiler_Driver /=
-                                                              Empty_File_Name;
-      Src_Data.Kind                := Kind;
-      Src_Data.Alternate_Languages := Alternate_Languages;
-      Src_Data.Other_Part          := Other_Part;
+      Id.Project             := Project;
+      Id.Language            := Lang_Id;
+      Id.Lang_Kind           := Lang_Kind;
+      Id.Compiled            := Lang_Id.Config.Compiler_Driver /=
+                                                             Empty_File_Name;
+      Id.Kind                := Kind;
+      Id.Alternate_Languages := Alternate_Languages;
+      Id.Other_Part          := Other_Part;
 
-      Src_Data.Object_Exists := Config.Object_Generated;
-      Src_Data.Object_Linked := Config.Objects_Linked;
+      Id.Object_Exists       := Config.Object_Generated;
+      Id.Object_Linked       := Config.Objects_Linked;
 
       if Other_Part /= No_Source then
-         In_Tree.Sources.Table (Other_Part).Other_Part := Id;
+         Other_Part.Other_Part := Id;
       end if;
 
-      Src_Data.Unit                := Unit;
-      Src_Data.Index               := Index;
-      Src_Data.File                := File_Name;
-      Src_Data.Display_File        := Display_File;
-      Src_Data.Dependency          := In_Tree.Languages_Data.Table
-                                        (Lang_Id).Config.Dependency_Kind;
-      Src_Data.Dep_Name            := Dependency_Name
-                                        (File_Name, Src_Data.Dependency);
-      Src_Data.Naming_Exception    := Naming_Exception;
-
-      if Src_Data.Compiled and then Src_Data.Object_Exists then
-         Src_Data.Object   :=
-           Object_Name (File_Name, Config.Object_File_Suffix);
-         Src_Data.Switches := Switches_Name (File_Name);
+      Id.Unit                := Unit;
+      Id.Index               := Index;
+      Id.File                := File_Name;
+      Id.Display_File        := Display_File;
+      Id.Dependency          := Lang_Id.Config.Dependency_Kind;
+      Id.Dep_Name            := Dependency_Name (File_Name, Id.Dependency);
+      Id.Naming_Exception    := Naming_Exception;
+
+      if Id.Compiled and then Id.Object_Exists then
+         Id.Object   := Object_Name (File_Name, Config.Object_File_Suffix);
+         Id.Switches := Switches_Name (File_Name);
       end if;
 
       if Path /= No_Path then
-         Src_Data.Path := (Path, Display_Path);
+         Id.Path := (Path, Display_Path);
          Source_Paths_Htable.Set (In_Tree.Source_Paths_HT, Path, Id);
       end if;
 
@@ -781,31 +762,13 @@ package body Prj.Nmsc is
          Unit_Sources_Htable.Set (In_Tree.Unit_Sources_HT, Unit, Id);
       end if;
 
-      --  Add the source to the global list
-
-      Src_Data.Next_In_Sources := In_Tree.First_Source;
-      In_Tree.First_Source := Id;
-
-      --  Add the source to the project list
-
-      if Source = No_Source then
-         Data.First_Source := Id;
-      else
-         In_Tree.Sources.Table (Source).Next_In_Project := Id;
-      end if;
-
-      Data.Last_Source := Id;
-
       --  Add the source to the language list
 
-      Src_Data.Next_In_Lang :=
-        In_Tree.Languages_Data.Table (Lang_Id).First_Source;
-      In_Tree.Languages_Data.Table (Lang_Id).First_Source := Id;
-
-      In_Tree.Sources.Table (Id) := Src_Data;
+      Id.Next_In_Lang := Lang_Id.First_Source;
+      Lang_Id.First_Source := Id;
 
       if Source_To_Replace /= No_Source then
-         Remove_Source (Source_To_Replace, Id, Project, Data, In_Tree);
+         Remove_Source (Source_To_Replace, Id);
       end if;
    end Add_Source;
 
@@ -856,7 +819,7 @@ package body Prj.Nmsc is
       When_No_Sources : Error_Warning;
       Current_Dir     : String)
    is
-      Data      : Project_Data := In_Tree.Projects.Table (Project);
+      Data      : Project_Data renames In_Tree.Projects.Table (Project);
       Extending : Boolean := False;
 
    begin
@@ -934,52 +897,54 @@ package body Prj.Nmsc is
                (not Extending)
          then
             declare
-               Language      : Language_Index;
+               Language      : Language_Ptr;
                Source        : Source_Id;
                Alt_Lang      : Alternate_Language_Id;
                Alt_Lang_Data : Alternate_Language_Data;
                Continuation  : Boolean := False;
+               Iter          : Source_Iterator;
 
             begin
-               Language := Data.First_Language_Processing;
+               Language := Data.Languages;
                while Language /= No_Language_Index loop
-                  Source := Data.First_Source;
-                  Source_Loop : while Source /= No_Source loop
-                     declare
-                        Src_Data : Source_Data renames
-                                     In_Tree.Sources.Table (Source);
 
-                     begin
-                        exit Source_Loop when Src_Data.Language = Language;
+                  --  If there are no sources for this language, check whether
+                  --  there are sources for which this is an alternate
+                  --  language.
 
-                        Alt_Lang := Src_Data.Alternate_Languages;
+                  if Language.First_Source = No_Source then
+                     Iter := For_Each_Source (In_Tree => In_Tree,
+                                              Project => Project);
+                     Source_Loop : loop
+                        Source := Element (Iter);
+                        exit Source_Loop when Source = No_Source
+                          or else Source.Language = Language;
+
+                        Alt_Lang := Source.Alternate_Languages;
 
                         Alternate_Loop :
                         while Alt_Lang /= No_Alternate_Language loop
-                           Alt_Lang_Data :=
-                             In_Tree.Alt_Langs.Table (Alt_Lang);
+                           Alt_Lang_Data := In_Tree.Alt_Langs.Table (Alt_Lang);
                            exit Source_Loop
                            when Alt_Lang_Data.Language = Language;
                            Alt_Lang := Alt_Lang_Data.Next;
                         end loop Alternate_Loop;
 
-                        Source := Src_Data.Next_In_Project;
-                     end;
-                  end loop Source_Loop;
+                        Next (Iter);
+                     end loop Source_Loop;
 
-                  if Source = No_Source then
-                     Report_No_Sources
-                       (Project,
-                        Get_Name_String
-                          (In_Tree.Languages_Data.Table
-                             (Language).Display_Name),
-                        In_Tree,
-                        Data.Location,
-                        Continuation);
-                     Continuation := True;
+                     if Source = No_Source then
+                        Report_No_Sources
+                          (Project,
+                           Get_Name_String (Language.Display_Name),
+                           In_Tree,
+                           Data.Location,
+                           Continuation);
+                        Continuation := True;
+                     end if;
                   end if;
 
-                  Language := In_Tree.Languages_Data.Table (Language).Next;
+                  Language := Language.Next;
                end loop;
             end;
          end if;
@@ -1208,18 +1173,15 @@ package body Prj.Nmsc is
       Casing          : Casing_Type    := All_Lower_Case;
       Separate_Suffix : File_Name_Type := No_File;
 
-      Lang_Index : Language_Index := No_Language_Index;
+      Lang_Index : Language_Ptr := No_Language_Index;
       --  The index of the language data being checked
 
-      Prev_Index : Language_Index := No_Language_Index;
+      Prev_Index : Language_Ptr := No_Language_Index;
       --  The index of the previous language
 
       Current_Language : Name_Id := No_Name;
       --  The name of the language
 
-      Lang_Data : Language_Data;
-      --  The data of the language being checked
-
       procedure Get_Language_Index_Of (Language : Name_Id);
       --  Get the language index of Language, if Language is one of the
       --  languages of the project.
@@ -1248,12 +1210,10 @@ package body Prj.Nmsc is
          --  Nothing to do if the language is the same as the current language
 
          if Current_Language /= Real_Language then
-            Lang_Index := Data.First_Language_Processing;
+            Lang_Index := Data.Languages;
             while Lang_Index /= No_Language_Index loop
-               exit when In_Tree.Languages_Data.Table (Lang_Index).Name =
-                 Real_Language;
-               Lang_Index :=
-                 In_Tree.Languages_Data.Table (Lang_Index).Next;
+               exit when Lang_Index.Name = Real_Language;
+               Lang_Index := Lang_Index.Next;
             end loop;
 
             if Lang_Index = No_Language_Index then
@@ -1324,14 +1284,12 @@ package body Prj.Nmsc is
 
                            --  Attribute Driver (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Binder_Driver :=
+                           Lang_Index.Config.Binder_Driver :=
                              File_Name_Type (Element.Value.Value);
 
                         when Name_Required_Switches =>
                            Put (Into_List =>
-                                In_Tree.Languages_Data.Table
-                                  (Lang_Index).Config.Binder_Required_Switches,
+                                   Lang_Index.Config.Binder_Required_Switches,
                                 From_List => Element.Value.Values,
                                 In_Tree   => In_Tree);
 
@@ -1339,24 +1297,21 @@ package body Prj.Nmsc is
 
                            --  Attribute Prefix (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Binder_Prefix :=
+                           Lang_Index.Config.Binder_Prefix :=
                              Element.Value.Value;
 
                         when Name_Objects_Path =>
 
                            --  Attribute Objects_Path (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Objects_Path :=
+                           Lang_Index.Config.Objects_Path :=
                              Element.Value.Value;
 
                         when Name_Objects_Path_File =>
 
                            --  Attribute Objects_Path (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Objects_Path_File :=
+                           Lang_Index.Config.Objects_Path_File :=
                              Element.Value.Value;
 
                         when others =>
@@ -1437,20 +1392,15 @@ package body Prj.Nmsc is
 
                            --  Attribute Dependency_Switches (<language>)
 
-                           if In_Tree.Languages_Data.Table
-                               (Lang_Index).Config.Dependency_Kind = None
-                           then
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Dependency_Kind :=
-                                  Makefile;
+                           if Lang_Index.Config.Dependency_Kind = None then
+                              Lang_Index.Config.Dependency_Kind := Makefile;
                            end if;
 
                            List := Element.Value.Values;
 
                            if List /= Nil_String then
                               Put (Into_List =>
-                                     In_Tree.Languages_Data.Table
-                                       (Lang_Index).Config.Dependency_Option,
+                                     Lang_Index.Config.Dependency_Option,
                                    From_List => List,
                                    In_Tree   => In_Tree);
                            end if;
@@ -1459,20 +1409,15 @@ package body Prj.Nmsc is
 
                            --  Attribute Dependency_Driver (<language>)
 
-                           if In_Tree.Languages_Data.Table
-                               (Lang_Index).Config.Dependency_Kind = None
-                           then
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Dependency_Kind :=
-                                  Makefile;
+                           if Lang_Index.Config.Dependency_Kind = None then
+                              Lang_Index.Config.Dependency_Kind := Makefile;
                            end if;
 
                            List := Element.Value.Values;
 
                            if List /= Nil_String then
                               Put (Into_List =>
-                                     In_Tree.Languages_Data.Table
-                                       (Lang_Index).Config.Compute_Dependency,
+                                     Lang_Index.Config.Compute_Dependency,
                                    From_List => List,
                                    In_Tree   => In_Tree);
                            end if;
@@ -1492,8 +1437,7 @@ package body Prj.Nmsc is
                            end if;
 
                            Put (Into_List =>
-                                In_Tree.Languages_Data.Table
-                                  (Lang_Index).Config.Include_Option,
+                                  Lang_Index.Config.Include_Option,
                                 From_List => List,
                                 In_Tree   => In_Tree);
 
@@ -1501,16 +1445,14 @@ package body Prj.Nmsc is
 
                            --  Attribute Include_Path (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Include_Path :=
+                           Lang_Index.Config.Include_Path :=
                              Element.Value.Value;
 
                         when Name_Include_Path_File =>
 
                            --  Attribute Include_Path_File (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Include_Path_File :=
+                           Lang_Index.Config.Include_Path_File :=
                                Element.Value.Value;
 
                         when Name_Driver =>
@@ -1519,22 +1461,18 @@ package body Prj.Nmsc is
 
                            Get_Name_String (Element.Value.Value);
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Compiler_Driver :=
+                           Lang_Index.Config.Compiler_Driver :=
                                File_Name_Type (Element.Value.Value);
 
                         when Name_Required_Switches =>
                            Put (Into_List =>
-                                In_Tree.Languages_Data.Table
-                                  (Lang_Index).Config.
-                                    Compiler_Required_Switches,
+                                  Lang_Index.Config.Compiler_Required_Switches,
                                 From_List => Element.Value.Values,
                                 In_Tree   => In_Tree);
 
                         when Name_Path_Syntax =>
                            begin
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Path_Syntax :=
+                              Lang_Index.Config.Path_Syntax :=
                                   Path_Syntax_Kind'Value
                                     (Get_Name_String (Element.Value.Value));
 
@@ -1555,8 +1493,7 @@ package body Prj.Nmsc is
                                  Element.Value.Location);
 
                            else
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Object_File_Suffix :=
+                              Lang_Index.Config.Object_File_Suffix :=
                                 Element.Value.Value;
                            end if;
 
@@ -1575,8 +1512,7 @@ package body Prj.Nmsc is
                            end if;
 
                            Put (Into_List =>
-                                In_Tree.Languages_Data.Table
-                                  (Lang_Index).Config.Compilation_PIC_Option,
+                                  Lang_Index.Config.Compilation_PIC_Option,
                                 From_List => List,
                                 In_Tree   => In_Tree);
 
@@ -1595,8 +1531,7 @@ package body Prj.Nmsc is
                            end if;
 
                            Put (Into_List =>
-                                In_Tree.Languages_Data.Table
-                                  (Lang_Index).Config.Mapping_File_Switches,
+                                  Lang_Index.Config.Mapping_File_Switches,
                                 From_List => List,
                                 In_Tree   => In_Tree);
 
@@ -1604,17 +1539,15 @@ package body Prj.Nmsc is
 
                            --  Attribute Mapping_Spec_Suffix (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Mapping_Spec_Suffix :=
-                               File_Name_Type (Element.Value.Value);
+                           Lang_Index.Config.Mapping_Spec_Suffix :=
+                             File_Name_Type (Element.Value.Value);
 
                         when Name_Mapping_Body_Suffix =>
 
                            --  Attribute Mapping_Body_Suffix (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Mapping_Body_Suffix :=
-                               File_Name_Type (Element.Value.Value);
+                           Lang_Index.Config.Mapping_Body_Suffix :=
+                             File_Name_Type (Element.Value.Value);
 
                         when Name_Config_File_Switches =>
 
@@ -1631,8 +1564,7 @@ package body Prj.Nmsc is
                            end if;
 
                            Put (Into_List =>
-                                  In_Tree.Languages_Data.Table
-                                    (Lang_Index).Config.Config_File_Switches,
+                                  Lang_Index.Config.Config_File_Switches,
                                 From_List => List,
                                 In_Tree   => In_Tree);
 
@@ -1640,50 +1572,44 @@ package body Prj.Nmsc is
 
                            --  Attribute Objects_Path (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Objects_Path :=
-                               Element.Value.Value;
+                           Lang_Index.Config.Objects_Path :=
+                             Element.Value.Value;
 
                         when Name_Objects_Path_File =>
 
                            --  Attribute Objects_Path_File (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Objects_Path_File :=
-                               Element.Value.Value;
+                           Lang_Index.Config.Objects_Path_File :=
+                             Element.Value.Value;
 
                         when Name_Config_Body_File_Name =>
 
                            --  Attribute Config_Body_File_Name (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Config_Body :=
-                               Element.Value.Value;
+                           Lang_Index.Config.Config_Body :=
+                             Element.Value.Value;
 
                         when Name_Config_Body_File_Name_Pattern =>
 
                            --  Attribute Config_Body_File_Name_Pattern
                            --  (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Config_Body_Pattern :=
-                               Element.Value.Value;
+                           Lang_Index.Config.Config_Body_Pattern :=
+                             Element.Value.Value;
 
                         when Name_Config_Spec_File_Name =>
 
                            --  Attribute Config_Spec_File_Name (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Config_Spec :=
-                               Element.Value.Value;
+                           Lang_Index.Config.Config_Spec :=
+                             Element.Value.Value;
 
                         when Name_Config_Spec_File_Name_Pattern =>
 
                            --  Attribute Config_Spec_File_Name_Pattern
                            --  (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Config_Spec_Pattern :=
+                           Lang_Index.Config.Config_Spec_Pattern :=
                              Element.Value.Value;
 
                         when Name_Config_File_Unique =>
@@ -1691,10 +1617,9 @@ package body Prj.Nmsc is
                            --  Attribute Config_File_Unique (<language>)
 
                            begin
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Config_File_Unique :=
-                                  Boolean'Value
-                                    (Get_Name_String (Element.Value.Value));
+                              Lang_Index.Config.Config_File_Unique :=
+                                Boolean'Value
+                                  (Get_Name_String (Element.Value.Value));
                            exception
                               when Constraint_Error =>
                                  Error_Msg
@@ -1795,21 +1720,18 @@ package body Prj.Nmsc is
 
                            --  Attribute Spec_Suffix (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Naming_Data.Spec_Suffix :=
-                               File_Name_Type (Element.Value.Value);
+                           Lang_Index.Config.Naming_Data.Spec_Suffix :=
+                             File_Name_Type (Element.Value.Value);
 
                         when Name_Implementation_Suffix | Name_Body_Suffix =>
 
                            --  Attribute Body_Suffix (<language>)
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Naming_Data.Body_Suffix :=
-                               File_Name_Type (Element.Value.Value);
+                           Lang_Index.Config.Naming_Data.Body_Suffix :=
+                             File_Name_Type (Element.Value.Value);
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Naming_Data.Separate_Suffix :=
-                               File_Name_Type (Element.Value.Value);
+                           Lang_Index.Config.Naming_Data.Separate_Suffix :=
+                             File_Name_Type (Element.Value.Value);
 
                         when others =>
                            null;
@@ -2316,8 +2238,7 @@ package body Prj.Nmsc is
                         if List /= Nil_String then
                            Put
                              (Into_List  =>
-                                In_Tree.Languages_Data.Table (Lang_Index).
-                                  Config.Include_Compatible_Languages,
+                                Lang_Index.Config.Include_Compatible_Languages,
                               From_List  => List,
                               In_Tree    => In_Tree,
                               Lower_Case => True);
@@ -2327,32 +2248,28 @@ package body Prj.Nmsc is
 
                         --  Attribute Toolchain_Description (<language>)
 
-                        In_Tree.Languages_Data.Table
-                          (Lang_Index).Config.Toolchain_Description :=
+                        Lang_Index.Config.Toolchain_Description :=
                           Element.Value.Value;
 
                      when Name_Toolchain_Version =>
 
                         --  Attribute Toolchain_Version (<language>)
 
-                        In_Tree.Languages_Data.Table
-                          (Lang_Index).Config.Toolchain_Version :=
+                        Lang_Index.Config.Toolchain_Version :=
                           Element.Value.Value;
 
                      when Name_Runtime_Library_Dir =>
 
                         --  Attribute Runtime_Library_Dir (<language>)
 
-                        In_Tree.Languages_Data.Table
-                          (Lang_Index).Config.Runtime_Library_Dir :=
+                        Lang_Index.Config.Runtime_Library_Dir :=
                           Element.Value.Value;
 
                      when Name_Runtime_Source_Dir =>
 
                         --  Attribute Runtime_Library_Dir (<language>)
 
-                        In_Tree.Languages_Data.Table
-                          (Lang_Index).Config.Runtime_Source_Dir :=
+                        Lang_Index.Config.Runtime_Source_Dir :=
                           Element.Value.Value;
 
                      when Name_Object_Generated =>
@@ -2365,15 +2282,13 @@ package body Prj.Nmsc is
                              Boolean'Value
                                (Get_Name_String (Element.Value.Value));
 
-                           In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Object_Generated := Value;
+                           Lang_Index.Config.Object_Generated := Value;
 
                            --  If no object is generated, no object may be
                            --  linked.
 
                            if not Value then
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Objects_Linked := False;
+                              Lang_Index.Config.Objects_Linked := False;
                            end if;
 
                         exception
@@ -2400,12 +2315,8 @@ package body Prj.Nmsc is
                            --  No change if Object_Generated is False, as this
                            --  forces Objects_Linked to be False too.
 
-                           if In_Tree.Languages_Data.Table
-                             (Lang_Index).Config.Object_Generated
-                           then
-                              In_Tree.Languages_Data.Table
-                                (Lang_Index).Config.Objects_Linked :=
-                                Value;
+                           if Lang_Index.Config.Object_Generated then
+                              Lang_Index.Config.Objects_Linked := Value;
                            end if;
 
                         exception
@@ -2438,27 +2349,21 @@ package body Prj.Nmsc is
       --  For unit based languages, set Casing, Dot_Replacement and
       --  Separate_Suffix in Naming_Data.
 
-      Lang_Index := Data.First_Language_Processing;
+      Lang_Index := Data.Languages;
       while Lang_Index /= No_Language_Index loop
-         if In_Tree.Languages_Data.Table
-           (Lang_Index).Name = Name_Ada
-         then
-            In_Tree.Languages_Data.Table
-              (Lang_Index).Config.Naming_Data.Casing := Casing;
-            In_Tree.Languages_Data.Table
-              (Lang_Index).Config.Naming_Data.Dot_Replacement :=
-              Dot_Replacement;
+         if Lang_Index.Name = Name_Ada then
+            Lang_Index.Config.Naming_Data.Casing := Casing;
+            Lang_Index.Config.Naming_Data.Dot_Replacement := Dot_Replacement;
 
             if Separate_Suffix /= No_File then
-               In_Tree.Languages_Data.Table
-                 (Lang_Index).Config.Naming_Data.Separate_Suffix :=
+               Lang_Index.Config.Naming_Data.Separate_Suffix :=
                  Separate_Suffix;
             end if;
 
             exit;
          end if;
 
-         Lang_Index := In_Tree.Languages_Data.Table (Lang_Index).Next;
+         Lang_Index := Lang_Index.Next;
       end loop;
 
       --  Give empty names to various prefixes/suffixes, if they have not
@@ -2476,15 +2381,13 @@ package body Prj.Nmsc is
          Data.Config.Shared_Lib_Suffix := Empty_File;
       end if;
 
-      Lang_Index := Data.First_Language_Processing;
+      Lang_Index := Data.Languages;
       while Lang_Index /= No_Language_Index loop
-         Lang_Data := In_Tree.Languages_Data.Table (Lang_Index);
-
-         Current_Language := Lang_Data.Display_Name;
+         Current_Language := Lang_Index.Display_Name;
 
          --  For all languages, Compiler_Driver needs to be specified
 
-         if Lang_Data.Config.Compiler_Driver = No_File then
+         if Lang_Index.Config.Compiler_Driver = No_File then
             Error_Msg_Name_1 := Current_Language;
             Error_Msg
               (Project,
@@ -2493,21 +2396,19 @@ package body Prj.Nmsc is
                ", ignoring all its sources",
                No_Location);
 
-            if Lang_Index = Data.First_Language_Processing then
-               Data.First_Language_Processing :=
-                 Lang_Data.Next;
+            if Lang_Index = Data.Languages then
+               Data.Languages := Lang_Index.Next;
             else
-               In_Tree.Languages_Data.Table (Prev_Index).Next :=
-                 Lang_Data.Next;
+               Prev_Index.Next := Lang_Index.Next;
             end if;
 
-         elsif Lang_Data.Name = Name_Ada then
+         elsif Lang_Index.Name = Name_Ada then
             Prev_Index := Lang_Index;
 
             --  For unit based languages, Dot_Replacement, Spec_Suffix and
             --  Body_Suffix need to be specified.
 
-            if Lang_Data.Config.Naming_Data.Dot_Replacement = No_File then
+            if Lang_Index.Config.Naming_Data.Dot_Replacement = No_File then
                Error_Msg
                  (Project,
                   In_Tree,
@@ -2515,7 +2416,7 @@ package body Prj.Nmsc is
                   No_Location);
             end if;
 
-            if Lang_Data.Config.Naming_Data.Spec_Suffix = No_File then
+            if Lang_Index.Config.Naming_Data.Spec_Suffix = No_File then
                Error_Msg
                  (Project,
                   In_Tree,
@@ -2523,7 +2424,7 @@ package body Prj.Nmsc is
                   No_Location);
             end if;
 
-            if Lang_Data.Config.Naming_Data.Body_Suffix = No_File then
+            if Lang_Index.Config.Naming_Data.Body_Suffix = No_File then
                Error_Msg
                  (Project,
                   In_Tree,
@@ -2537,8 +2438,8 @@ package body Prj.Nmsc is
             --  For file based languages, either Spec_Suffix or Body_Suffix
             --  need to be specified.
 
-            if Lang_Data.Config.Naming_Data.Spec_Suffix = No_File and then
-              Lang_Data.Config.Naming_Data.Body_Suffix = No_File
+            if Lang_Index.Config.Naming_Data.Spec_Suffix = No_File and then
+              Lang_Index.Config.Naming_Data.Body_Suffix = No_File
             then
                Error_Msg_Name_1 := Current_Language;
                Error_Msg
@@ -2549,7 +2450,7 @@ package body Prj.Nmsc is
             end if;
          end if;
 
-         Lang_Index := Lang_Data.Next;
+         Lang_Index := Lang_Index.Next;
       end loop;
    end Check_Configuration;
 
@@ -2616,14 +2517,12 @@ package body Prj.Nmsc is
                         Data.Decl.Attributes,
                         In_Tree);
 
-      List    : String_List_Id;
-      Element : String_Element;
-      Name    : File_Name_Type;
-
-      Source   : Source_Id;
-
+      List      : String_List_Id;
+      Element   : String_Element;
+      Name      : File_Name_Type;
+      Iter      : Source_Iterator;
+      Source    : Source_Id;
       Project_2 : Project_Id;
-      Data_2     : Project_Data;
 
    begin
       if not Interfaces.Default then
@@ -2632,24 +2531,17 @@ package body Prj.Nmsc is
          --  later for the sources in the Interfaces list.
 
          Project_2 := Project;
-         Data_2    := Data;
-         loop
-            Source := Data_2.First_Source;
-            while Source /= No_Source loop
-               declare
-                  Src_Data : Source_Data renames
-                               In_Tree.Sources.Table (Source);
-               begin
-                  Src_Data.In_Interfaces := False;
-                  Source := Src_Data.Next_In_Project;
-               end;
-            end loop;
-
-            Project_2 := Data_2.Extends;
+         while Project_2 /= No_Project loop
+            Iter := For_Each_Source (In_Tree, Project_2);
 
-            exit when Project_2 = No_Project;
+            loop
+               Source := Prj.Element (Iter);
+               exit when Source = No_Source;
+               Source.In_Interfaces := False;
+               Next (Iter);
+            end loop;
 
-            Data_2 := In_Tree.Projects.Table (Project_2);
+            Project_2 := In_Tree.Projects.Table (Project_2).Extends;
          end loop;
 
          List := Interfaces.Values;
@@ -2658,48 +2550,37 @@ package body Prj.Nmsc is
             Name := Canonical_Case_File_Name (Element.Value);
 
             Project_2 := Project;
-            Data_2 := Data;
             Big_Loop :
-            loop
-               Source := Data_2.First_Source;
-               while Source /= No_Source loop
-                  declare
-                     Src_Data : Source_Data renames
-                                  In_Tree.Sources.Table (Source);
+            while Project_2 /= No_Project loop
+               Iter := For_Each_Source (In_Tree, Project_2);
 
-                  begin
-                     if Src_Data.File = Name then
-                        if not Src_Data.Locally_Removed then
-                           Src_Data.In_Interfaces := True;
-                           Src_Data.Declared_In_Interfaces := True;
-
-                           if Src_Data.Other_Part /= No_Source then
-                              In_Tree.Sources.Table
-                                (Src_Data.Other_Part).In_Interfaces := True;
-                              In_Tree.Sources.Table
-                                (Src_Data.Other_Part).Declared_In_Interfaces :=
-                                  True;
-                           end if;
+               loop
+                  Source := Prj.Element (Iter);
+                  exit when Source = No_Source;
 
-                           if Current_Verbosity = High then
-                              Write_Str ("   interface: ");
-                              Write_Line
-                                (Get_Name_String (Src_Data.Path.Name));
-                           end if;
+                  if Source.File = Name then
+                     if not Source.Locally_Removed then
+                        Source.In_Interfaces := True;
+                        Source.Declared_In_Interfaces := True;
+
+                        if Source.Other_Part /= No_Source then
+                           Source.Other_Part.In_Interfaces := True;
+                           Source.Other_Part.Declared_In_Interfaces := True;
                         end if;
 
-                        exit Big_Loop;
+                        if Current_Verbosity = High then
+                           Write_Str ("   interface: ");
+                           Write_Line (Get_Name_String (Source.Path.Name));
+                        end if;
                      end if;
 
-                     Source := Src_Data.Next_In_Project;
-                  end;
-               end loop;
-
-               Project_2 := Data_2.Extends;
+                     exit Big_Loop;
+                  end if;
 
-               exit Big_Loop when Project_2 = No_Project;
+                  Next (Iter);
+               end loop;
 
-               Data_2 := In_Tree.Projects.Table (Project_2);
+               Project_2 := In_Tree.Projects.Table (Project_2).Extends;
             end loop Big_Loop;
 
             if Source = No_Source then
@@ -2724,19 +2605,16 @@ package body Prj.Nmsc is
            In_Tree.Projects.Table (Data.Extends).Interfaces_Defined;
 
          if Data.Interfaces_Defined then
-            Source := Data.First_Source;
-            while Source /= No_Source loop
-               declare
-                  Src_Data : Source_Data renames
-                               In_Tree.Sources.Table (Source);
+            Iter := For_Each_Source (In_Tree, Project);
+            loop
+               Source := Prj.Element (Iter);
+               exit when Source = No_Source;
 
-               begin
-                  if not Src_Data.Declared_In_Interfaces then
-                     Src_Data.In_Interfaces := False;
-                  end if;
+               if not Source.Declared_In_Interfaces then
+                  Source.In_Interfaces := False;
+               end if;
 
-                  Source := Src_Data.Next_In_Project;
-               end;
+               Next (Iter);
             end loop;
          end if;
       end if;
@@ -2823,10 +2701,10 @@ package body Prj.Nmsc is
       --  Check attributes common to Ada_Only and Multi_Lang modes
 
       procedure Process_Exceptions_File_Based
-        (Lang_Id : Language_Index;
+        (Lang_Id : Language_Ptr;
          Kind    : Source_Kind);
       procedure Process_Exceptions_Unit_Based
-        (Lang_Id : Language_Index;
+        (Lang_Id : Language_Ptr;
          Kind    : Source_Kind);
       --  In Multi_Lang mode, process the naming exceptions for the two types
       --  of languages we can have.
@@ -2908,8 +2786,10 @@ package body Prj.Nmsc is
             end;
          end if;
 
-         Write_Attr
-           ("Dot_Replacement", Get_Name_String (Dot_Replacement));
+         if Dot_Replacement /= No_File then
+            Write_Attr
+              ("Dot_Replacement", Get_Name_String (Dot_Replacement));
+         end if;
 
          Casing_Defined := False;
 
@@ -2977,17 +2857,17 @@ package body Prj.Nmsc is
       -----------------------------------
 
       procedure Process_Exceptions_File_Based
-        (Lang_Id        : Language_Index;
-         Kind           : Source_Kind)
+        (Lang_Id : Language_Ptr;
+         Kind    : Source_Kind)
       is
-         Lang           : constant Name_Id :=
-                            In_Tree.Languages_Data.Table (Lang_Id).Name;
+         Lang           : constant Name_Id := Lang_Id.Name;
          Exceptions     : Array_Element_Id;
          Exception_List : Variable_Value;
          Element_Id     : String_List_Id;
          Element        : String_Element;
          File_Name      : File_Name_Type;
          Source         : Source_Id;
+         Iter           : Source_Iterator;
 
       begin
          case Kind is
@@ -3017,20 +2897,18 @@ package body Prj.Nmsc is
                Element   := In_Tree.String_Elements.Table (Element_Id);
                File_Name := Canonical_Case_File_Name (Element.Value);
 
-               Source := Data.First_Source;
-               while Source /= No_Source
-                 and then In_Tree.Sources.Table (Source).File /= File_Name
+               Iter := For_Each_Source (In_Tree, Project);
                loop
-                  Source := In_Tree.Sources.Table (Source).Next_In_Project;
+                  Source := Prj.Element (Iter);
+                  exit when Source = No_Source or else Source.File = File_Name;
+                  Next (Iter);
                end loop;
 
                if Source = No_Source then
                   Add_Source
                     (Id               => Source,
-                     Data             => Data,
                      In_Tree          => In_Tree,
                      Project          => Project,
-                     Lang             => Lang,
                      Lang_Id          => Lang_Id,
                      Kind             => Kind,
                      File_Name        => File_Name,
@@ -3042,14 +2920,14 @@ package body Prj.Nmsc is
                   --  Check if the file name is already recorded for another
                   --  language or another kind.
 
-                  if In_Tree.Sources.Table (Source).Language /= Lang_Id then
+                  if Source.Language /= Lang_Id then
                      Error_Msg
                        (Project,
                         In_Tree,
                         "the same file cannot be a source of two languages",
                         Element.Location);
 
-                  elsif In_Tree.Sources.Table (Source).Kind /= Kind then
+                  elsif Source.Kind /= Kind then
                      Error_Msg
                        (Project,
                         In_Tree,
@@ -3073,11 +2951,10 @@ package body Prj.Nmsc is
       -----------------------------------
 
       procedure Process_Exceptions_Unit_Based
-        (Lang_Id        : Language_Index;
-         Kind           : Source_Kind)
+        (Lang_Id : Language_Ptr;
+         Kind    : Source_Kind)
       is
-         Lang              : constant Name_Id :=
-                              In_Tree.Languages_Data.Table (Lang_Id).Name;
+         Lang              : constant Name_Id := Lang_Id.Name;
          Exceptions        : Array_Element_Id;
          Element           : Array_Element;
          Unit              : Name_Id;
@@ -3087,6 +2964,7 @@ package body Prj.Nmsc is
          Source_To_Replace : Source_Id := No_Source;
          Other_Project     : Project_Id;
          Other_Part        : Source_Id := No_Source;
+         Iter              : Source_Iterator;
 
       begin
          case Kind is
@@ -3147,37 +3025,34 @@ package body Prj.Nmsc is
 
                --  Check if the source already exists
 
-               Source := In_Tree.First_Source;
                Source_To_Replace := No_Source;
+               Iter := For_Each_Source (In_Tree);
 
-               while Source /= No_Source and then
-                 (In_Tree.Sources.Table (Source).Unit /= Unit or else
-                  In_Tree.Sources.Table (Source).Index /= Index)
                loop
-                  Source := In_Tree.Sources.Table (Source).Next_In_Sources;
+                  Source := Prj.Element (Iter);
+                  exit when Source = No_Source
+                    or else (Source.Unit = Unit and then Source.Index = Index);
+                  Next (Iter);
                end loop;
 
                if Source /= No_Source then
-                  if In_Tree.Sources.Table (Source).Kind /= Kind then
+                  if Source.Kind /= Kind then
                      Other_Part := Source;
 
                      loop
-                        Source :=
-                          In_Tree.Sources.Table (Source).Next_In_Sources;
+                        Next (Iter);
+                        Source := Prj.Element (Iter);
 
                         exit when Source = No_Source or else
-                          (In_Tree.Sources.Table (Source).Unit = Unit
-                           and then
-                           In_Tree.Sources.Table (Source).Index = Index);
+                          (Source.Unit = Unit and then Source.Index = Index);
                      end loop;
                   end if;
 
                   if Source /= No_Source then
-                     Other_Project := In_Tree.Sources.Table (Source).Project;
+                     Other_Project := Source.Project;
 
                      if Is_Extending (Project, Other_Project, In_Tree) then
-                        Other_Part :=
-                          In_Tree.Sources.Table (Source).Other_Part;
+                        Other_Part := Source.Other_Part;
 
                         --  Record the source to be removed
 
@@ -3200,10 +3075,8 @@ package body Prj.Nmsc is
                if Source = No_Source then
                   Add_Source
                     (Id           => Source,
-                     Data         => Data,
                      In_Tree      => In_Tree,
                      Project      => Project,
-                     Lang         => Lang,
                      Lang_Id      => Lang_Id,
                      Kind         => Kind,
                      File_Name    => File_Name,
@@ -3264,7 +3137,7 @@ package body Prj.Nmsc is
 
          Write_Attr ("Body_Suffix", Get_Name_String (Body_Suffix));
 
-         --  We'll need the dot replacement below, so compute it now.
+         --  We'll need the dot replacement below, so compute it now
 
          Check_Common
            (Dot_Replacement => Data.Naming.Dot_Replacement,
@@ -3360,7 +3233,7 @@ package body Prj.Nmsc is
          Separate_Suffix : File_Name_Type := No_File;
          Casing          : Casing_Type    := All_Lower_Case;
          Casing_Defined  : Boolean;
-         Lang_Id         : Language_Index;
+         Lang_Id         : Language_Ptr;
          Sep_Suffix_Loc  : Source_Ptr;
          Suffix          : Variable_Value;
          Lang            : Name_Id;
@@ -3382,38 +3255,33 @@ package body Prj.Nmsc is
            or else Casing_Defined
            or else Separate_Suffix /= No_File
          then
-            Lang_Id := Data.First_Language_Processing;
+            Lang_Id := Data.Languages;
             while Lang_Id /= No_Language_Index loop
-               if In_Tree.Languages_Data.
-                    Table (Lang_Id).Config.Kind = Unit_Based
-               then
+               if Lang_Id.Config.Kind = Unit_Based then
                   if Dot_Replacement /= No_File then
-                     In_Tree.Languages_Data.Table
-                       (Lang_Id).Config.Naming_Data.Dot_Replacement :=
+                     Lang_Id.Config.Naming_Data.Dot_Replacement :=
                          Dot_Replacement;
                   end if;
 
                   if Casing_Defined then
-                     In_Tree.Languages_Data.Table
-                       (Lang_Id).Config.Naming_Data.Casing := Casing;
+                     Lang_Id.Config.Naming_Data.Casing := Casing;
                   end if;
 
                   if Separate_Suffix /= No_File then
-                     In_Tree.Languages_Data.Table
-                       (Lang_Id).Config.Naming_Data.Separate_Suffix :=
+                     Lang_Id.Config.Naming_Data.Separate_Suffix :=
                          Separate_Suffix;
                   end if;
                end if;
 
-               Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
+               Lang_Id := Lang_Id.Next;
             end loop;
          end if;
 
          --  Next, get the spec and body suffixes
 
-         Lang_Id := Data.First_Language_Processing;
+         Lang_Id := Data.Languages;
          while Lang_Id /= No_Language_Index loop
-            Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
+            Lang := Lang_Id.Name;
 
             --  Spec_Suffix
 
@@ -3432,8 +3300,7 @@ package body Prj.Nmsc is
             end if;
 
             if Suffix /= Nil_Variable_Value then
-               In_Tree.Languages_Data.Table (Lang_Id).
-                 Config.Naming_Data.Spec_Suffix :=
+               Lang_Id.Config.Naming_Data.Spec_Suffix :=
                    File_Name_Type (Suffix.Value);
             end if;
 
@@ -3454,8 +3321,7 @@ package body Prj.Nmsc is
             end if;
 
             if Suffix /= Nil_Variable_Value then
-               In_Tree.Languages_Data.Table (Lang_Id).
-                 Config.Naming_Data.Body_Suffix :=
+               Lang_Id.Config.Naming_Data.Body_Suffix :=
                    File_Name_Type (Suffix.Value);
             end if;
 
@@ -3465,15 +3331,15 @@ package body Prj.Nmsc is
             --  Check_Common, but we access the attributes from the project
             --  files slightly differently apparently.
 
-            Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
+            Lang_Id := Lang_Id.Next;
          end loop;
 
          --  Get the naming exceptions for all languages
 
          for Kind in Spec .. Impl loop
-            Lang_Id := Data.First_Language_Processing;
+            Lang_Id := Data.Languages;
             while Lang_Id /= No_Language_Index loop
-               case In_Tree.Languages_Data.Table (Lang_Id).Config.Kind is
+               case Lang_Id.Config.Kind is
                when File_Based =>
                   Process_Exceptions_File_Based (Lang_Id, Kind);
 
@@ -3481,7 +3347,7 @@ package body Prj.Nmsc is
                   Process_Exceptions_Unit_Based (Lang_Id, Kind);
                end case;
 
-               Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
+               Lang_Id := Lang_Id.Next;
             end loop;
          end loop;
       end Check_Naming_Multi_Lang;
@@ -3561,6 +3427,7 @@ package body Prj.Nmsc is
       procedure Check_Library (Proj : Project_Id; Extends : Boolean) is
          Proj_Data : Project_Data;
          Src_Id    : Source_Id;
+         Iter      : Source_Iterator;
 
       begin
          if Proj /= No_Project then
@@ -3572,15 +3439,13 @@ package body Prj.Nmsc is
                --  have no sources. However, header files from non-Ada
                --  languages are OK, as there is nothing to compile.
 
-               Src_Id := Proj_Data.First_Source;
-               while Src_Id /= No_Source loop
-                  declare
-                     Src : Source_Data renames In_Tree.Sources.Table (Src_Id);
-                  begin
-                     exit when Src.Lang_Kind /= File_Based
-                       or else Src.Kind /= Spec;
-                     Src_Id := Src.Next_In_Project;
-                  end;
+               Iter := For_Each_Source (In_Tree, Proj);
+               loop
+                  Src_Id := Prj.Element (Iter);
+                  exit when Src_Id = No_Source
+                    or else Src_Id.Lang_Kind /= File_Based
+                    or else Src_Id.Kind /= Spec;
+                  Next (Iter);
                end loop;
 
                if Src_Id /= No_Source then
@@ -3598,7 +3463,9 @@ package body Prj.Nmsc is
                         Continuation := Continuation_String'Access;
                      end if;
 
-                  elsif Data.Library_Kind /= Static then
+                  elsif (not Unchecked_Shared_Lib_Imports)
+                        and then Data.Library_Kind /= Static
+                  then
                      Error_Msg
                        (Project, In_Tree,
                         Continuation.all &
@@ -3622,17 +3489,18 @@ package body Prj.Nmsc is
                      "shared library project %% cannot extend static " &
                      "library project %%",
                      Data.Location);
+                  Continuation := Continuation_String'Access;
 
-               else
+               elsif not Unchecked_Shared_Lib_Imports then
                   Error_Msg
                     (Project, In_Tree,
                      Continuation.all &
                      "shared library project %% cannot import static " &
                      "library project %%",
                      Data.Location);
+                  Continuation := Continuation_String'Access;
                end if;
 
-               Continuation := Continuation_String'Access;
             end if;
          end if;
       end Check_Library;
@@ -4470,14 +4338,15 @@ package body Prj.Nmsc is
       Def_Lang_Id : Name_Id;
 
    begin
-      Data.First_Language_Processing := No_Language_Index;
+      Data.Languages := No_Language_Index;
       Languages :=
         Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes, In_Tree);
       Def_Lang :=
         Prj.Util.Value_Of
           (Name_Default_Language, Data.Decl.Attributes, In_Tree);
-      Data.Ada_Sources_Present   := Data.Source_Dirs /= Nil_String;
-      Data.Other_Sources_Present := Data.Source_Dirs /= Nil_String;
+
+      --  Shouldn't these be set to False by default, and only set to True when
+      --  we actually find some source file???
 
       if Data.Source_Dirs /= Nil_String then
 
@@ -4485,23 +4354,10 @@ package body Prj.Nmsc is
 
          if Languages.Default then
 
-            --  Attribute Languages is not specified. So, it defaults to
-            --  a project of the default language only.
-
-            Name_List_Table.Increment_Last (In_Tree.Name_Lists);
-            Data.Languages := Name_List_Table.Last (In_Tree.Name_Lists);
-
             --  In Ada_Only mode, the default language is Ada
 
             if Get_Mode = Ada_Only then
-               In_Tree.Name_Lists.Table (Data.Languages) :=
-                 (Name => Name_Ada, Next => No_Name_List);
-
-               --  Attribute Languages is not specified. So, it defaults to
-               --  a project of language Ada only. No sources of languages
-               --  other than Ada
-
-               Data.Other_Sources_Present := False;
+               Def_Lang_Id := Name_Ada;
 
             else
                --  Fail if there is no default language defined
@@ -4523,37 +4379,22 @@ package body Prj.Nmsc is
                   To_Lower (Name_Buffer (1 .. Name_Len));
                   Def_Lang_Id := Name_Find;
                end if;
+            end if;
 
-               if Def_Lang_Id /=  No_Name then
-                  In_Tree.Name_Lists.Table (Data.Languages) :=
-                    (Name => Def_Lang_Id, Next => No_Name_List);
-
-                  Language_Data_Table.Increment_Last (In_Tree.Languages_Data);
-
-                  Data.First_Language_Processing :=
-                    Language_Data_Table.Last (In_Tree.Languages_Data);
-                  In_Tree.Languages_Data.Table
-                    (Data.First_Language_Processing) := No_Language_Data;
-                  In_Tree.Languages_Data.Table
-                    (Data.First_Language_Processing).Name := Def_Lang_Id;
-                  Get_Name_String (Def_Lang_Id);
-                  Name_Buffer (1) := GNAT.Case_Util.To_Upper (Name_Buffer (1));
-                  In_Tree.Languages_Data.Table
-                    (Data.First_Language_Processing).Display_Name := Name_Find;
-
-                  if Def_Lang_Id = Name_Ada then
-                     In_Tree.Languages_Data.Table
-                       (Data.First_Language_Processing).Config.Kind :=
-                         Unit_Based;
-                     In_Tree.Languages_Data.Table
-                       (Data.First_Language_Processing).Config.
-                         Dependency_Kind := ALI_File;
-
-                  else
-                     In_Tree.Languages_Data.Table
-                       (Data.First_Language_Processing).Config.Kind :=
-                         File_Based;
-                  end if;
+            if Def_Lang_Id /= No_Name then
+               Data.Languages :=
+                 new Language_Data'(No_Language_Data);
+               Data.Languages.Name := Def_Lang_Id;
+               Get_Name_String (Def_Lang_Id);
+               Name_Buffer (1) := GNAT.Case_Util.To_Upper (Name_Buffer (1));
+               Data.Languages.Display_Name := Name_Find;
+
+               if Def_Lang_Id = Name_Ada then
+                  Data.Languages.Config.Kind := Unit_Based;
+                  Data.Languages.Config.Dependency_Kind :=
+                    ALI_File;
+               else
+                  Data.Languages.Config.Kind := File_Based;
                end if;
             end if;
 
@@ -4562,16 +4403,10 @@ package body Prj.Nmsc is
                Current           : String_List_Id := Languages.Values;
                Element           : String_Element;
                Lang_Name         : Name_Id;
-               Index             : Language_Index;
-               Lang_Data         : Language_Data;
-               NL_Id             : Name_List_Index := No_Name_List;
+               Index             : Language_Ptr;
+               NL_Id             : Language_Ptr;
 
             begin
-               --  Assume there are no language declared
-
-               Data.Ada_Sources_Present := False;
-               Data.Other_Sources_Present := False;
-
                --  If there are no languages declared, there are no sources
 
                if Current = Nil_String then
@@ -4590,72 +4425,36 @@ package body Prj.Nmsc is
                   --  Languages.
 
                   while Current /= Nil_String loop
-                     Element :=
-                       In_Tree.String_Elements.Table (Current);
+                     Element := In_Tree.String_Elements.Table (Current);
                      Get_Name_String (Element.Value);
                      To_Lower (Name_Buffer (1 .. Name_Len));
                      Lang_Name := Name_Find;
 
+                     --  If the language was not already specified (duplicates
+                     --  are simply ignored).
+
                      NL_Id := Data.Languages;
-                     while NL_Id /= No_Name_List loop
-                        exit when
-                          Lang_Name = In_Tree.Name_Lists.Table (NL_Id).Name;
-                        NL_Id := In_Tree.Name_Lists.Table (NL_Id).Next;
+                     while NL_Id /= No_Language_Index loop
+                        exit when Lang_Name = NL_Id.Name;
+                        NL_Id := NL_Id.Next;
                      end loop;
 
-                     if NL_Id = No_Name_List then
-                        Name_List_Table.Increment_Last (In_Tree.Name_Lists);
+                     if NL_Id = No_Language_Index then
+                        Index := new Language_Data'(No_Language_Data);
+                        Index.Name := Lang_Name;
+                        Index.Display_Name := Element.Value;
+                        Index.Next := Data.Languages;
 
-                        if Data.Languages = No_Name_List then
-                           Data.Languages :=
-                             Name_List_Table.Last (In_Tree.Name_Lists);
+                        if Lang_Name = Name_Ada then
+                           Index.Config.Kind := Unit_Based;
+                           Index.Config.Dependency_Kind := ALI_File;
 
                         else
-                           NL_Id := Data.Languages;
-                           while In_Tree.Name_Lists.Table (NL_Id).Next /=
-                                   No_Name_List
-                           loop
-                              NL_Id := In_Tree.Name_Lists.Table (NL_Id).Next;
-                           end loop;
-
-                           In_Tree.Name_Lists.Table (NL_Id).Next :=
-                             Name_List_Table.Last (In_Tree.Name_Lists);
+                           Index.Config.Kind := File_Based;
+                           Index.Config.Dependency_Kind := None;
                         end if;
 
-                        NL_Id := Name_List_Table.Last (In_Tree.Name_Lists);
-                        In_Tree.Name_Lists.Table (NL_Id) :=
-                          (Lang_Name, No_Name_List);
-
-                        if Get_Mode = Ada_Only then
-                           --  Check for language Ada
-
-                           if Lang_Name = Name_Ada then
-                              Data.Ada_Sources_Present := True;
-
-                           else
-                              Data.Other_Sources_Present := True;
-                           end if;
-
-                        else
-                           Language_Data_Table.Increment_Last
-                                                 (In_Tree.Languages_Data);
-                           Index :=
-                             Language_Data_Table.Last (In_Tree.Languages_Data);
-                           Lang_Data.Name := Lang_Name;
-                           Lang_Data.Display_Name := Element.Value;
-                           Lang_Data.Next := Data.First_Language_Processing;
-
-                           if Lang_Name = Name_Ada then
-                              Lang_Data.Config.Kind := Unit_Based;
-                              Lang_Data.Config.Dependency_Kind := ALI_File;
-                           else
-                              Lang_Data.Config.Kind := File_Based;
-                              Lang_Data.Config.Dependency_Kind := None;
-                           end if;
-
-                           In_Tree.Languages_Data.Table (Index) := Lang_Data;
-                           Data.First_Language_Processing := Index;
-                        end if;
+                        Data.Languages := Index;
                      end if;
 
                      Current := Element.Next;
@@ -4750,6 +4549,7 @@ package body Prj.Nmsc is
       OK                  : Boolean := True;
       Source              : Source_Id;
       Next_Proj           : Project_Id;
+      Iter                : Source_Iterator;
 
    begin
       if Get_Mode = Multi_Language then
@@ -4869,8 +4669,8 @@ package body Prj.Nmsc is
                               Project, In_Tree, Extending)
                            then
                               --  There is a body for this unit.
-                              --  If there is no spec, we need to check
-                              --  that it is not a subunit.
+                              --  If there is no spec, we need to check that it
+                              --  is not a subunit.
 
                               if The_Unit_Data.File_Names
                                 (Specification).Name = No_File
@@ -4898,9 +4698,8 @@ package body Prj.Nmsc is
                                  end;
                               end if;
 
-                              --  The unit is not a subunit, so we add
-                              --  to the Interface ALIs the ALI file
-                              --  corresponding to the body.
+                              --  The unit is not a subunit, so we add the
+                              --  ALI file for its body to the Interface ALIs.
 
                               Add_ALI_For
                                 (The_Unit_Data.File_Names (Body_Part).Name);
@@ -4914,18 +4713,18 @@ package body Prj.Nmsc is
                            end if;
 
                         elsif The_Unit_Data.File_Names
-                          (Specification).Name /= No_File
+                                (Specification).Name /= No_File
                           and then The_Unit_Data.File_Names
-                            (Specification).Path.Name /= Slash
+                                     (Specification).Path.Name /= Slash
                           and then Check_Project
-                            (The_Unit_Data.File_Names
-                                 (Specification).Project,
-                             Project, In_Tree, Extending)
+                                     (The_Unit_Data.File_Names
+                                        (Specification).Project,
+                                      Project, In_Tree, Extending)
 
                         then
-                           --  The unit is part of the project, it has
-                           --  a spec, but no body. We add to the Interface
-                           --  ALIs the ALI file corresponding to the spec.
+                           --  The unit is part of the project, it has a spec,
+                           --  but no body. We add the ALI for its spec to the
+                           --  Interface ALIs.
 
                            Add_ALI_For
                              (The_Unit_Data.File_Names (Specification).Name);
@@ -4943,45 +4742,40 @@ package body Prj.Nmsc is
                      --  Multi_Language mode
 
                      Next_Proj := Data.Extends;
-                     Source := Data.First_Source;
+
+                     Iter := For_Each_Source (In_Tree, Project);
 
                      loop
-                        while Source /= No_Source and then
-                              In_Tree.Sources.Table (Source).Unit /= Unit
+                        while Prj.Element (Iter) /= No_Source and then
+                           Prj.Element (Iter).Unit /= Unit
                         loop
-                           Source :=
-                             In_Tree.Sources.Table (Source).Next_In_Project;
+                           Next (Iter);
                         end loop;
 
+                        Source := Prj.Element (Iter);
                         exit when Source /= No_Source or else
                                   Next_Proj = No_Project;
 
-                        Source :=
-                          In_Tree.Projects.Table (Next_Proj).First_Source;
+                        Iter := For_Each_Source (In_Tree, Next_Proj);
                         Next_Proj :=
                           In_Tree.Projects.Table (Next_Proj).Extends;
                      end loop;
 
                      if Source /= No_Source then
-                        if In_Tree.Sources.Table (Source).Kind = Sep then
+                        if Source.Kind = Sep then
                            Source := No_Source;
 
-                        elsif In_Tree.Sources.Table (Source).Kind = Spec
-                          and then
-                          In_Tree.Sources.Table (Source).Other_Part /=
-                          No_Source
+                        elsif Source.Kind = Spec
+                          and then Source.Other_Part /= No_Source
                         then
-                           Source := In_Tree.Sources.Table (Source).Other_Part;
+                           Source := Source.Other_Part;
                         end if;
                      end if;
 
                      if Source /= No_Source then
-                        if In_Tree.Sources.Table (Source).Project /= Project
+                        if Source.Project /= Project
                           and then
-                            not Is_Extending
-                              (Project,
-                               In_Tree.Sources.Table (Source).Project,
-                               In_Tree)
+                            not Is_Extending (Project, Source.Project, In_Tree)
                         then
                            Source := No_Source;
                         end if;
@@ -4995,11 +4789,10 @@ package body Prj.Nmsc is
                                 (Interfaces).Location);
 
                      else
-                        if In_Tree.Sources.Table (Source).Kind = Spec and then
-                          In_Tree.Sources.Table (Source).Other_Part /=
-                            No_Source
+                        if Source.Kind = Spec and then
+                          Source.Other_Part /= No_Source
                         then
-                           Source := In_Tree.Sources.Table (Source).Other_Part;
+                           Source := Source.Other_Part;
                         end if;
 
                         String_Element_Table.Increment_Last
@@ -5007,11 +4800,9 @@ package body Prj.Nmsc is
                         In_Tree.String_Elements.Table
                           (String_Element_Table.Last
                              (In_Tree.String_Elements)) :=
-                          (Value         =>
-                             Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
+                          (Value         => Name_Id (Source.Dep_Name),
                            Index         => 0,
-                           Display_Value =>
-                             Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
+                           Display_Value => Name_Id (Source.Dep_Name),
                            Location      =>
                              In_Tree.String_Elements.Table
                                (Interfaces).Location,
@@ -5056,7 +4847,7 @@ package body Prj.Nmsc is
 
                   else
                      --  Library_Auto_Init cannot be "true" if auto init is not
-                     --  supported
+                     --  supported.
 
                      Error_Msg
                        (Project, In_Tree,
@@ -6603,7 +6394,8 @@ package body Prj.Nmsc is
       Spec_Suffix     : File_Name_Type;
       Casing          : Casing_Type;
       Kind            : out Source_Kind;
-      Unit            : out Name_Id)
+      Unit            : out Name_Id;
+      In_Tree         : Project_Tree_Ref)
    is
       Filename : constant String := Get_Name_String (File_Name);
       Last     : Integer := Filename'Last;
@@ -6759,7 +6551,7 @@ package body Prj.Nmsc is
                   --  If it is potentially a run time source, disable filling
                   --  of the mapping file to avoid warnings.
 
-                  Set_Mapping_File_Initial_State_To_Empty;
+                  Set_Mapping_File_Initial_State_To_Empty (In_Tree);
                end if;
             end if;
          end;
@@ -6868,7 +6660,8 @@ package body Prj.Nmsc is
             Spec_Suffix     => Spec_Suffix_Id_Of (In_Tree, Name_Ada, Naming),
             Casing          => Naming.Casing,
             Kind            => Kind,
-            Unit            => Unit_Name);
+            Unit            => Unit_Name,
+            In_Tree         => In_Tree);
 
          case Kind is
             when Spec       => Unit_Kind := Specification;
@@ -7276,13 +7069,9 @@ package body Prj.Nmsc is
             Name     : File_Name_Type;
 
          begin
-            if Get_Mode = Ada_Only then
-               Data.Ada_Sources_Present := Current /= Nil_String;
-            end if;
-
             if Get_Mode = Multi_Language then
                if Current = Nil_String then
-                  Data.First_Language_Processing := No_Language_Index;
+                  Data.Languages := No_Language_Index;
 
                   --  This project contains no source. For projects that
                   --  don't extend other projects, this also means that
@@ -7417,32 +7206,30 @@ package body Prj.Nmsc is
 
          declare
             Source : Source_Id;
+            Iter   : Source_Iterator;
 
          begin
-            Source := Data.First_Source;
-            while Source /= No_Source loop
-               declare
-                  Src_Data : Source_Data renames
-                               In_Tree.Sources.Table (Source);
-
-               begin
-                  if Src_Data.Naming_Exception
-                    and then Src_Data.Path = No_Path_Information
-                  then
-                     if Src_Data.Unit /= No_Name then
-                        Error_Msg_Name_1 := Name_Id (Src_Data.Display_File);
-                        Error_Msg_Name_2 := Name_Id (Src_Data.Unit);
-                        Error_Msg
-                          (Project, In_Tree,
-                           "source file %% for unit %% not found",
-                           No_Location);
-                     end if;
+            Iter := For_Each_Source (In_Tree, Project);
+            loop
+               Source := Prj.Element (Iter);
+               exit when Source = No_Source;
 
-                     Remove_Source (Source, No_Source, Project, Data, In_Tree);
+               if Source.Naming_Exception
+                 and then Source.Path = No_Path_Information
+               then
+                  if Source.Unit /= No_Name then
+                     Error_Msg_Name_1 := Name_Id (Source.Display_File);
+                     Error_Msg_Name_2 := Name_Id (Source.Unit);
+                     Error_Msg
+                       (Project, In_Tree,
+                        "source file %% for unit %% not found",
+                        No_Location);
                   end if;
 
-                  Source := Src_Data.Next_In_Project;
-               end;
+                  Remove_Source (Source, No_Source);
+               end if;
+
+               Next (Iter);
             end loop;
          end;
 
@@ -7474,7 +7261,7 @@ package body Prj.Nmsc is
       then
          --  We should have found at least one source, if not report an error
 
-         if Data.Ada_Sources = Nil_String then
+         if not Has_Ada_Sources (Data) then
             Report_No_Sources
               (Project, "Ada", In_Tree, Source_List_File.Location);
          end if;
@@ -7615,31 +7402,6 @@ package body Prj.Nmsc is
       end loop;
    end Get_Path_Names_And_Record_Ada_Sources;
 
-   ---------------------------------------
-   -- Get_Language_Processing_From_Lang --
-   ---------------------------------------
-
-   function Get_Language_Processing_From_Lang
-     (In_Tree : Project_Tree_Ref;
-      Data    : Project_Data;
-      Lang    : Name_List_Index) return Language_Index
-   is
-      Name     : constant Name_Id := In_Tree.Name_Lists.Table (Lang).Name;
-      Language : Language_Index;
-
-   begin
-      Language := Data.First_Language_Processing;
-      while Language /= No_Language_Index loop
-         if In_Tree.Languages_Data.Table (Language).Name = Name then
-            return Language;
-         end if;
-
-         Language := In_Tree.Languages_Data.Table (Language).Next;
-      end loop;
-
-      return No_Language_Index;
-   end Get_Language_Processing_From_Lang;
-
    -------------------------------
    -- Check_File_Naming_Schemes --
    -------------------------------
@@ -7649,7 +7411,7 @@ package body Prj.Nmsc is
       Data                  : in out Project_Data;
       File_Name             : File_Name_Type;
       Alternate_Languages   : out Alternate_Language_Id;
-      Language              : out Language_Index;
+      Language              : out Language_Ptr;
       Language_Name         : out Name_Id;
       Display_Language_Name : out Name_Id;
       Unit                  : out Name_Id;
@@ -7658,8 +7420,7 @@ package body Prj.Nmsc is
    is
       Filename : constant String := Get_Name_String (File_Name);
       Config   : Language_Config;
-      Lang     : Name_List_Index;
-      Tmp_Lang : Language_Index;
+      Tmp_Lang : Language_Ptr;
 
       Header_File : Boolean := False;
       --  True if we found at least one language for which the file is a header
@@ -7729,10 +7490,9 @@ package body Prj.Nmsc is
       Lang_Kind             := File_Based;
       Kind                  := Spec;
 
-      Lang := Data.Languages;
-      while Lang /= No_Name_List loop
-         Language_Name := In_Tree.Name_Lists.Table (Lang).Name;
-         Tmp_Lang := Get_Language_Processing_From_Lang (In_Tree, Data, Lang);
+      Tmp_Lang := Data.Languages;
+      while Tmp_Lang /= No_Language_Index loop
+         Language_Name := Tmp_Lang.Name;
 
          if Current_Verbosity = High then
             Write_Line
@@ -7741,42 +7501,40 @@ package body Prj.Nmsc is
                & " Header_File=" & Header_File'Img);
          end if;
 
-         if Tmp_Lang /= No_Language_Index then
-            Display_Language_Name :=
-              In_Tree.Languages_Data.Table (Tmp_Lang).Display_Name;
-            Config := In_Tree.Languages_Data.Table (Tmp_Lang).Config;
-            Lang_Kind := Config.Kind;
-
-            case Config.Kind is
-               when File_Based =>
-                  Check_File_Based_Lang;
-                  exit when Kind = Impl;
-
-               when Unit_Based =>
-
-                  --  We know it belongs to a least a file_based language, no
-                  --  need to check unit-based ones.
-
-                  if not Header_File then
-                     Compute_Unit_Name
-                       (File_Name       => File_Name,
-                        Dot_Replacement => Config.Naming_Data.Dot_Replacement,
-                        Separate_Suffix => Config.Naming_Data.Separate_Suffix,
-                        Body_Suffix     => Config.Naming_Data.Body_Suffix,
-                        Spec_Suffix     => Config.Naming_Data.Spec_Suffix,
-                        Casing          => Config.Naming_Data.Casing,
-                        Kind            => Kind,
-                        Unit            => Unit);
-
-                     if Unit /= No_Name then
-                        Language    := Tmp_Lang;
-                        exit;
-                     end if;
+         Display_Language_Name := Tmp_Lang.Display_Name;
+         Config := Tmp_Lang.Config;
+         Lang_Kind := Config.Kind;
+
+         case Config.Kind is
+            when File_Based =>
+               Check_File_Based_Lang;
+               exit when Kind = Impl;
+
+            when Unit_Based =>
+
+               --  We know it belongs to a least a file_based language, no
+               --  need to check unit-based ones.
+
+               if not Header_File then
+                  Compute_Unit_Name
+                    (File_Name       => File_Name,
+                     Dot_Replacement => Config.Naming_Data.Dot_Replacement,
+                     Separate_Suffix => Config.Naming_Data.Separate_Suffix,
+                     Body_Suffix     => Config.Naming_Data.Body_Suffix,
+                     Spec_Suffix     => Config.Naming_Data.Spec_Suffix,
+                     Casing          => Config.Naming_Data.Casing,
+                     Kind            => Kind,
+                     Unit            => Unit,
+                     In_Tree         => In_Tree);
+
+                  if Unit /= No_Name then
+                     Language    := Tmp_Lang;
+                     exit;
                   end if;
-            end case;
-         end if;
+               end if;
+         end case;
 
-         Lang := In_Tree.Name_Lists.Table (Lang).Next;
+         Tmp_Lang := Tmp_Lang.Next;
       end loop;
 
       if Language = No_Language_Index
@@ -7812,7 +7570,7 @@ package body Prj.Nmsc is
       Display_Path_Id   : Path_Name_Type;
       Check_Name        : Boolean := False;
       Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
-      Language          : Language_Index;
+      Language          : Language_Ptr;
       Source            : Source_Id;
       Other_Part        : Source_Id;
       Add_Src           : Boolean;
@@ -7824,6 +7582,7 @@ package body Prj.Nmsc is
       Display_Language_Name : Name_Id;
       Lang_Kind             : Language_Kind;
       Kind                  : Source_Kind := Spec;
+      Iter                  : Source_Iterator;
 
    begin
       Name_Len := Display_Path'Length;
@@ -7863,8 +7622,7 @@ package body Prj.Nmsc is
                Check_Name := True;
 
             else
-               In_Tree.Sources.Table (Name_Loc.Source).Path :=
-                 (Path_Id, Display_Path_Id);
+               Name_Loc.Source.Path := (Path_Id, Display_Path_Id);
 
                Source_Paths_Htable.Set
                  (In_Tree.Source_Paths_HT,
@@ -7873,15 +7631,14 @@ package body Prj.Nmsc is
 
                --  Check if this is a subunit
 
-               if In_Tree.Sources.Table (Name_Loc.Source).Unit /= No_Name
-                 and then
-                   In_Tree.Sources.Table (Name_Loc.Source).Kind = Impl
+               if Name_Loc.Source.Unit /= No_Name
+                 and then Name_Loc.Source.Kind = Impl
                then
                   Src_Ind := Sinput.P.Load_Project_File
                     (Get_Name_String (Path_Id));
 
                   if Sinput.P.Source_File_Is_Subunit (Src_Ind) then
-                     In_Tree.Sources.Table (Name_Loc.Source).Kind := Sep;
+                     Name_Loc.Source.Kind := Sep;
                   end if;
                end if;
             end if;
@@ -7919,106 +7676,100 @@ package body Prj.Nmsc is
          else
             --  Check if the same file name or unit is used in the prj tree
 
-            Source := In_Tree.First_Source;
+            Iter := For_Each_Source (In_Tree);
             Add_Src := True;
-            while Source /= No_Source loop
-               declare
-                  Src_Data : Source_Data renames
-                               In_Tree.Sources.Table (Source);
-
-               begin
-                  if Unit /= No_Name
-                    and then Src_Data.Unit = Unit
-                    and then
-                      ((Src_Data.Kind = Spec and then Kind = Impl)
-                         or else
-                       (Src_Data.Kind = Impl and then Kind = Spec))
-                  then
-                     Other_Part := Source;
+            loop
+               Source := Prj.Element (Iter);
+               exit when Source = No_Source;
 
-                  elsif (Unit /= No_Name
-                         and then Src_Data.Unit = Unit
-                         and then
-                           (Src_Data.Kind = Kind
-                             or else
-                               (Src_Data.Kind = Sep  and then Kind = Impl)
-                             or else
-                               (Src_Data.Kind = Impl and then Kind = Sep)))
+               if Unit /= No_Name
+                 and then Source.Unit = Unit
+                 and then
+                   ((Source.Kind = Spec and then Kind = Impl)
                     or else
-                      (Unit = No_Name and then Src_Data.File = File_Name)
-                  then
-                     --  Duplication of file/unit in same project is only
-                     --  allowed if order of source directories is known.
-
-                     if Project = Src_Data.Project then
-                        if Data.Known_Order_Of_Source_Dirs then
-                           Add_Src := False;
-
-                        elsif Unit /= No_Name then
-                           Error_Msg_Name_1 := Unit;
-                           Error_Msg
-                             (Project, In_Tree, "duplicate unit %%",
-                              No_Location);
-                           Add_Src := False;
-
-                        else
-                           Error_Msg_File_1 := File_Name;
-                           Error_Msg
-                             (Project, In_Tree, "duplicate source file name {",
-                              No_Location);
-                           Add_Src := False;
-                        end if;
-
-                        --  Do not allow the same unit name in different
-                        --  projects, except if one is extending the other.
+                      (Source.Kind = Impl and then Kind = Spec))
+               then
+                  Other_Part := Source;
 
-                        --  For a file based language, the same file name
-                        --  replaces a file in a project being extended, but
-                        --  it is allowed to have the same file name in
-                        --  unrelated projects.
+               elsif (Unit /= No_Name
+                      and then Source.Unit = Unit
+                      and then
+                        (Source.Kind = Kind
+                         or else
+                           (Source.Kind = Sep  and then Kind = Impl)
+                         or else
+                           (Source.Kind = Impl and then Kind = Sep)))
+                 or else
+                   (Unit = No_Name and then Source.File = File_Name)
+               then
+                  --  Duplication of file/unit in same project is only
+                  --  allowed if order of source directories is known.
 
-                     elsif Is_Extending
-                       (Project, Src_Data.Project, In_Tree)
-                     then
-                        Source_To_Replace := Source;
+                  if Project = Source.Project then
+                     if Data.Known_Order_Of_Source_Dirs then
+                        Add_Src := False;
 
-                     elsif Unit /= No_Name
-                       and then not Src_Data.Locally_Removed
-                     then
+                     elsif Unit /= No_Name then
                         Error_Msg_Name_1 := Unit;
                         Error_Msg
-                          (Project, In_Tree,
-                           "unit %% cannot belong to several projects",
+                          (Project, In_Tree, "duplicate unit %%",
                            No_Location);
+                        Add_Src := False;
 
-                        Error_Msg_Name_1 :=
-                          In_Tree.Projects.Table (Project).Name;
-                        Error_Msg_Name_2 := Name_Id (Display_Path_Id);
-                        Error_Msg
-                          (Project, In_Tree, "\  project %%, %%", No_Location);
-
-                        Error_Msg_Name_1 :=
-                          In_Tree.Projects.Table (Src_Data.Project).Name;
-                        Error_Msg_Name_2 :=
-                          Name_Id (Src_Data.Path.Display_Name);
+                     else
+                        Error_Msg_File_1 := File_Name;
                         Error_Msg
-                          (Project, In_Tree, "\  project %%, %%", No_Location);
-
+                          (Project, In_Tree, "duplicate source file name {",
+                           No_Location);
                         Add_Src := False;
                      end if;
+
+                     --  Do not allow the same unit name in different
+                     --  projects, except if one is extending the other.
+
+                     --  For a file based language, the same file name
+                     --  replaces a file in a project being extended, but
+                     --  it is allowed to have the same file name in
+                     --  unrelated projects.
+
+                  elsif Is_Extending
+                    (Project, Source.Project, In_Tree)
+                  then
+                     Source_To_Replace := Source;
+
+                  elsif Unit /= No_Name
+                    and then not Source.Locally_Removed
+                  then
+                     Error_Msg_Name_1 := Unit;
+                     Error_Msg
+                       (Project, In_Tree,
+                        "unit %% cannot belong to several projects",
+                        No_Location);
+
+                     Error_Msg_Name_1 :=
+                       In_Tree.Projects.Table (Project).Name;
+                     Error_Msg_Name_2 := Name_Id (Display_Path_Id);
+                     Error_Msg
+                       (Project, In_Tree, "\  project %%, %%", No_Location);
+
+                     Error_Msg_Name_1 :=
+                       In_Tree.Projects.Table (Source.Project).Name;
+                     Error_Msg_Name_2 := Name_Id (Source.Path.Display_Name);
+                     Error_Msg
+                       (Project, In_Tree, "\  project %%, %%", No_Location);
+
+                     Add_Src := False;
                   end if;
+               end if;
 
-                  Source := Src_Data.Next_In_Sources;
-               end;
+               Next (Iter);
             end loop;
 
             if Add_Src then
                Add_Source
                  (Id                  => Source,
-                  Data                => Data,
                   In_Tree             => In_Tree,
                   Project             => Project,
-                  Lang                => Language_Name,
                   Lang_Id             => Language,
                   Lang_Kind           => Lang_Kind,
                   Kind                => Kind,
@@ -8171,25 +7922,23 @@ package body Prj.Nmsc is
 
    procedure Load_Naming_Exceptions
      (Project : Project_Id;
-      In_Tree : Project_Tree_Ref;
-      Data    : in out Project_Data)
+      In_Tree : Project_Tree_Ref)
    is
       Source : Source_Id;
-      File   : File_Name_Type;
-      Unit   : Name_Id;
+      Iter   : Source_Iterator;
 
    begin
       Unit_Exceptions.Reset;
 
-      Source := Data.First_Source;
-      while Source /= No_Source loop
-         File := In_Tree.Sources.Table (Source).File;
-         Unit := In_Tree.Sources.Table (Source).Unit;
+      Iter := For_Each_Source (In_Tree, Project);
+      loop
+         Source := Prj.Element (Iter);
+         exit when Source = No_Source;
 
          --  An excluded file cannot also be an exception file name
 
-         if Excluded_Sources_Htable.Get (File) /= No_File_Found then
-            Error_Msg_File_1 := File;
+         if Excluded_Sources_Htable.Get (Source.File) /= No_File_Found then
+            Error_Msg_File_1 := Source.File;
             Error_Msg
               (Project, In_Tree,
                "{ cannot be both excluded and an exception file name",
@@ -8197,42 +7946,41 @@ package body Prj.Nmsc is
          end if;
 
          if Current_Verbosity = High then
-            Write_Str ("Naming exception: Putting source #");
-            Write_Str (Source'Img);
-            Write_Str (", file ");
-            Write_Str (Get_Name_String (File));
+            Write_Str ("Naming exception: Putting source file ");
+            Write_Str (Get_Name_String (Source.File));
             Write_Line (" in Source_Names");
          end if;
 
          Source_Names.Set
-           (K => File,
+           (K => Source.File,
             E => Name_Location'
-              (Name     => File,
+              (Name     => Source.File,
                Location => No_Location,
                Source   => Source,
-               Except   => Unit /= No_Name,
+               Except   => Source.Unit /= No_Name,
                Found    => False));
 
          --  If this is an Ada exception, record in table Unit_Exceptions
 
-         if Unit /= No_Name then
+         if Source.Unit /= No_Name then
             declare
-               Unit_Except : Unit_Exception := Unit_Exceptions.Get (Unit);
+               Unit_Except : Unit_Exception :=
+                                Unit_Exceptions.Get (Source.Unit);
 
             begin
-               Unit_Except.Name := Unit;
+               Unit_Except.Name := Source.Unit;
 
-               if In_Tree.Sources.Table (Source).Kind = Spec then
-                  Unit_Except.Spec := File;
+               if Source.Kind = Spec then
+                  Unit_Except.Spec := Source.File;
                else
-                  Unit_Except.Impl := File;
+                  Unit_Except.Impl := Source.File;
                end if;
 
-               Unit_Exceptions.Set (Unit, Unit_Except);
+               Unit_Exceptions.Set (Source.Unit, Unit_Except);
             end;
          end if;
 
-         Source := In_Tree.Sources.Table (Source).Next_In_Project;
+         Next (Iter);
       end loop;
    end Load_Naming_Exceptions;
 
@@ -8246,6 +7994,8 @@ package body Prj.Nmsc is
       Data        : in out Project_Data;
       Current_Dir : String)
    is
+      Iter : Source_Iterator;
+
       procedure Process_Sources_In_Multi_Language_Mode;
       --  Find all source files when in multi language mode
 
@@ -8293,8 +8043,8 @@ package body Prj.Nmsc is
                end if;
 
                if Source /= No_Source then
-                  In_Tree.Sources.Table (Source).Locally_Removed := True;
-                  In_Tree.Sources.Table (Source).In_Interfaces := False;
+                  Source.Locally_Removed := True;
+                  Source.In_Interfaces := False;
                end if;
 
                if Current_Verbosity = High then
@@ -8341,16 +8091,17 @@ package body Prj.Nmsc is
                end loop For_Each_Unit;
 
             when Multi_Language =>
-               Source := In_Tree.First_Source;
-               while Source /= No_Source loop
-                  if In_Tree.Sources.Table (Source).File = Excluded.File then
-                     Exclude
-                       (In_Tree.Sources.Table (Source).Project,
-                        No_Unit_Index, Specification);
+               Iter := For_Each_Source (In_Tree);
+               loop
+                  Source := Prj.Element (Iter);
+                  exit when Source = No_Source;
+
+                  if Source.File = Excluded.File then
+                     Exclude (Source.Project, No_Unit_Index, Specification);
                      exit;
                   end if;
 
-                  Source := In_Tree.Sources.Table (Source).Next_In_Sources;
+                  Next (Iter);
                end loop;
 
                OK := OK or Excluded.Found;
@@ -8371,6 +8122,7 @@ package body Prj.Nmsc is
       --------------------------------------------
 
       procedure Process_Sources_In_Multi_Language_Mode is
+         Iter : Source_Iterator;
       begin
          --  Check that two sources of this project do not have the same object
          --  file name.
@@ -8379,7 +8131,7 @@ package body Prj.Nmsc is
             Src_Id      : Source_Id;
             Source_Name : File_Name_Type;
 
-            procedure Check_Object (Src_Data : Source_Data);
+            procedure Check_Object (Src : Source_Id);
             --  Check if object file name of the current source is already in
             --  hash table Object_File_Names. If it is, report an error. If it
             --  is not, put it there with the file name of the current source.
@@ -8388,12 +8140,12 @@ package body Prj.Nmsc is
             -- Check_Object --
             ------------------
 
-            procedure Check_Object (Src_Data : Source_Data) is
+            procedure Check_Object (Src : Source_Id) is
             begin
-               Source_Name := Object_File_Names.Get (Src_Data.Object);
+               Source_Name := Object_File_Names.Get (Src.Object);
 
                if Source_Name /= No_File then
-                  Error_Msg_File_1 := Src_Data.File;
+                  Error_Msg_File_1 := Src.File;
                   Error_Msg_File_2 := Source_Name;
                   Error_Msg
                     (Project,
@@ -8402,7 +8154,7 @@ package body Prj.Nmsc is
                      No_Location);
 
                else
-                  Object_File_Names.Set (Src_Data.Object, Src_Data.File);
+                  Object_File_Names.Set (Src.Object, Src.File);
                end if;
             end Check_Object;
 
@@ -8410,60 +8162,56 @@ package body Prj.Nmsc is
 
          begin
             Object_File_Names.Reset;
-            Src_Id := In_Tree.First_Source;
-            while Src_Id /= No_Source loop
-               declare
-                  Src_Data : Source_Data renames
-                               In_Tree.Sources.Table (Src_Id);
-
-               begin
-                  if Src_Data.Compiled and then Src_Data.Object_Exists
-                    and then Is_Extending (Project, Src_Data.Project, In_Tree)
-                  then
-                     if Src_Data.Unit = No_Name then
-                        if Src_Data.Kind = Impl then
-                           Check_Object (Src_Data);
-                        end if;
+            Iter := For_Each_Source (In_Tree);
+            loop
+               Src_Id := Prj.Element (Iter);
+               exit when Src_Id = No_Source;
 
-                     else
-                        case Src_Data.Kind is
-                           when Spec =>
-                              if Src_Data.Other_Part = No_Source then
-                                 Check_Object (Src_Data);
-                              end if;
+               if Src_Id.Compiled and then Src_Id.Object_Exists
+                 and then Is_Extending (Project, Src_Id.Project, In_Tree)
+               then
+                  if Src_Id.Unit = No_Name then
+                     if Src_Id.Kind = Impl then
+                        Check_Object (Src_Id);
+                     end if;
 
-                           when Sep =>
-                              null;
+                  else
+                     case Src_Id.Kind is
+                        when Spec =>
+                           if Src_Id.Other_Part = No_Source then
+                              Check_Object (Src_Id);
+                           end if;
 
-                           when Impl =>
-                              if Src_Data.Other_Part /= No_Source then
-                                 Check_Object (Src_Data);
+                        when Sep =>
+                           null;
 
-                              else
-                                 --  Check if it is a subunit
+                        when Impl =>
+                           if Src_Id.Other_Part /= No_Source then
+                              Check_Object (Src_Id);
 
-                                 declare
-                                    Src_Ind : constant Source_File_Index :=
-                                                Sinput.P.Load_Project_File
-                                                 (Get_Name_String
-                                                   (Src_Data.Path.Name));
-                                 begin
-                                    if Sinput.P.Source_File_Is_Subunit
-                                      (Src_Ind)
-                                    then
-                                       In_Tree.Sources.Table (Src_Id).Kind :=
-                                         Sep;
-                                    else
-                                       Check_Object (Src_Data);
-                                    end if;
-                                 end;
-                              end if;
-                        end case;
-                     end if;
+                           else
+                              --  Check if it is a subunit
+
+                              declare
+                                 Src_Ind : constant Source_File_Index :=
+                                   Sinput.P.Load_Project_File
+                                     (Get_Name_String
+                                          (Src_Id.Path.Name));
+                              begin
+                                 if Sinput.P.Source_File_Is_Subunit
+                                   (Src_Ind)
+                                 then
+                                    Src_Id.Kind := Sep;
+                                 else
+                                    Check_Object (Src_Id);
+                                 end if;
+                              end;
+                           end if;
+                     end case;
                   end if;
+               end if;
 
-                  Src_Id := Src_Data.Next_In_Sources;
-               end;
+               Next (Iter);
             end loop;
          end Check_Object_File_Names;
       end Process_Sources_In_Multi_Language_Mode;
@@ -8474,12 +8222,12 @@ package body Prj.Nmsc is
       Source_Names.Reset;
       Find_Excluded_Sources (Project, In_Tree, Data);
 
-      if (Get_Mode = Ada_Only and then Is_A_Language (In_Tree, Data, Name_Ada))
+      if (Get_Mode = Ada_Only and then Is_A_Language (Data, Name_Ada))
         or else (Get_Mode = Multi_Language
-                  and then Data.First_Language_Processing /= No_Language_Index)
+                  and then Data.Languages /= No_Language_Index)
       then
          if Get_Mode = Multi_Language then
-            Load_Naming_Exceptions (Project, In_Tree, Data);
+            Load_Naming_Exceptions (Project, In_Tree);
          end if;
 
          Find_Explicit_Sources (Current_Dir, Project, In_Tree, Data);
@@ -8862,108 +8610,32 @@ package body Prj.Nmsc is
 
    procedure Remove_Source
      (Id          : Source_Id;
-      Replaced_By : Source_Id;
-      Project     : Project_Id;
-      Data        : in out Project_Data;
-      In_Tree     : Project_Tree_Ref)
+      Replaced_By : Source_Id)
    is
-      Src_Data : constant Source_Data := In_Tree.Sources.Table (Id);
       Source   : Source_Id;
 
    begin
       if Current_Verbosity = High then
-         Write_Str ("Removing source #");
-         Write_Line (Id'Img);
+         Write_Str ("Removing source ");
+         Write_Line (Get_Name_String (Id.File));
       end if;
 
       if Replaced_By /= No_Source then
-         In_Tree.Sources.Table (Id).Replaced_By := Replaced_By;
-         In_Tree.Sources.Table (Replaced_By).Declared_In_Interfaces :=
-           In_Tree.Sources.Table (Id).Declared_In_Interfaces;
-      end if;
-
-      --  Remove the source from the global source list
-
-      Source := In_Tree.First_Source;
-
-      if Source = Id then
-         In_Tree.First_Source := Src_Data.Next_In_Sources;
-
-      else
-         while In_Tree.Sources.Table (Source).Next_In_Sources /= Id loop
-            Source := In_Tree.Sources.Table (Source).Next_In_Sources;
-         end loop;
-
-         In_Tree.Sources.Table (Source).Next_In_Sources :=
-           Src_Data.Next_In_Sources;
-      end if;
-
-      --  Remove the source from the project list
-
-      if Src_Data.Project = Project then
-         Source := Data.First_Source;
-
-         if Source = Id then
-            Data.First_Source := Src_Data.Next_In_Project;
-
-            if Src_Data.Next_In_Project = No_Source then
-               Data.Last_Source := No_Source;
-            end if;
-
-         else
-            while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
-               Source := In_Tree.Sources.Table (Source).Next_In_Project;
-            end loop;
-
-            In_Tree.Sources.Table (Source).Next_In_Project :=
-              Src_Data.Next_In_Project;
-
-            if Src_Data.Next_In_Project = No_Source then
-               In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
-            end if;
-         end if;
-
-      else
-         Source := In_Tree.Projects.Table (Src_Data.Project).First_Source;
-
-         if Source = Id then
-            In_Tree.Projects.Table (Src_Data.Project).First_Source :=
-              Src_Data.Next_In_Project;
-
-            if Src_Data.Next_In_Project = No_Source then
-               In_Tree.Projects.Table (Src_Data.Project).Last_Source :=
-                 No_Source;
-            end if;
-
-         else
-            while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
-               Source := In_Tree.Sources.Table (Source).Next_In_Project;
-            end loop;
-
-            In_Tree.Sources.Table (Source).Next_In_Project :=
-              Src_Data.Next_In_Project;
-
-            if Src_Data.Next_In_Project = No_Source then
-               In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
-            end if;
-         end if;
+         Id.Replaced_By := Replaced_By;
+         Replaced_By.Declared_In_Interfaces := Id.Declared_In_Interfaces;
       end if;
 
-      --  Remove source from the language list
-
-      Source := In_Tree.Languages_Data.Table (Src_Data.Language).First_Source;
+      Source := Id.Language.First_Source;
 
       if Source = Id then
-         In_Tree.Languages_Data.Table (Src_Data.Language).First_Source :=
-           Src_Data.Next_In_Lang;
+         Id.Language.First_Source := Id.Next_In_Lang;
 
       else
-         while In_Tree.Sources.Table (Source).Next_In_Lang /= Id loop
-            Source := In_Tree.Sources.Table (Source).Next_In_Lang;
+         while Source.Next_In_Lang /= Id loop
+            Source := Source.Next_In_Lang;
          end loop;
 
-         In_Tree.Sources.Table (Source).Next_In_Lang :=
-           Src_Data.Next_In_Lang;
+         Source.Next_In_Lang := Id.Next_In_Lang;
       end if;
    end Remove_Source;